khoros-aurora-sdk 26.3.4 → 26.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/npm-publish.yml +0 -1
- package/README.md +1 -1
- package/build-hash.txt +1 -1
- package/graphql/aiAnswerLogSchema.graphqls +51 -0
- package/graphql/aiReviewModeSchema.graphqls +43 -0
- package/graphql/baseSchema.graphqls +6 -0
- package/graphql/bookmarkSchema.graphqls +192 -0
- package/graphql/clarificationSchema.graphqls +28 -0
- package/graphql/clmSchema.graphqls +79 -0
- package/graphql/emailOrchestrationSchema.graphqls +24 -3
- package/graphql/expertSuggestionSchema.graphqls +21 -3
- package/graphql/followSchema.graphqls +31 -0
- package/graphql/kudoSchema.graphqls +2 -0
- package/graphql/messageSchema.graphqls +14 -0
- package/graphql/metricSchema.graphqls +92 -0
- package/graphql/muteSchema.graphqls +74 -0
- package/graphql/notificationSchema.graphqls +210 -0
- package/graphql/pollSchema.graphqls +4 -0
- package/graphql/reactionSchema.graphqls +181 -0
- package/graphql/reactionViewerSchema.graphqls +104 -0
- package/graphql/searchSchema.graphqls +20 -0
- package/graphql/socialFeedSchema.graphqls +65 -0
- package/graphql/startDiscussionSchema.graphqls +123 -0
- package/graphql/surveysSchema.graphqls +11 -1
- package/graphql/unreadSchema.graphqls +86 -0
- package/package.json +1 -1
- package/scripts/buildGraphqlTypesCli.js +5 -5
- package/scripts/buildPluginCli.js +8 -8
- package/scripts/formatPluginCli.js +5 -5
- package/scripts/generateCli.js +10 -10
- package/scripts/initPluginCli.js +8 -8
- package/scripts/lintPluginCli.js +4 -4
- package/scripts/pluginLoggerCli.js +5 -5
- package/scripts/pluginPreviewCli.js +6 -6
- package/scripts/validatePluginCli.js +6 -6
- package/types/graphql-schema-types.ts +4586 -26
- package/types/mf/index.d.ts +4124 -27
- package/types/pkg/index.d.ts +4113 -26
|
@@ -21,7 +21,6 @@ jobs:
|
|
|
21
21
|
registry-url: https://registry.npmjs.org/
|
|
22
22
|
- name: Publish to npm
|
|
23
23
|
run: |
|
|
24
|
-
VERSION=$(npm pkg get version | tr -d '"')
|
|
25
24
|
LATEST=$(npm view khoros-aurora-sdk dist-tags.latest)
|
|
26
25
|
if [[ "${{ github.event.release.prerelease }}" == "true" ]]; then
|
|
27
26
|
tag=pre
|
package/README.md
CHANGED
|
@@ -63,7 +63,7 @@ to admin users.
|
|
|
63
63
|
|
|
64
64
|
## Allowed Dependencies for Custom React Component
|
|
65
65
|
|
|
66
|
-
The following dependencies are whitelisted and can be used for custom React Component development: react, react-bootstrap, react-hook-form, react-uid, react-dropzone, moment-timezone, @coveo/atomic-react, @coveo/atomic, @coveo/headless-react
|
|
66
|
+
The following dependencies are whitelisted and can be used for custom React Component development: react, react-bootstrap, react-hook-form, react-uid, react-dropzone, moment-timezone, @coveo/atomic-react, @coveo/atomic, @coveo/headless-react, @coveo/headless and quill-resize-image. Any additional dependencies will require approval.
|
|
67
67
|
|
|
68
68
|
## Developing a Custom Endpoint
|
|
69
69
|
|
package/build-hash.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
a95f395
|
|
@@ -19,6 +19,15 @@ extend type Query {
|
|
|
19
19
|
"The cursor to return results before."
|
|
20
20
|
before: String
|
|
21
21
|
): AiAnswerLogConnection!
|
|
22
|
+
|
|
23
|
+
"""
|
|
24
|
+
Returns the AI-generated answer preview for a message with a review mode log entry.
|
|
25
|
+
Admin-only: non-admins and missing entries both return null.
|
|
26
|
+
"""
|
|
27
|
+
reviewModeAnswerPreview(
|
|
28
|
+
"The message ID to look up (string format, parsed to int internally)."
|
|
29
|
+
messageId: String!
|
|
30
|
+
): AiAnswerLog
|
|
22
31
|
}
|
|
23
32
|
|
|
24
33
|
"""
|
|
@@ -99,6 +108,45 @@ type AiAnswerLog {
|
|
|
99
108
|
|
|
100
109
|
"Generation model used for answer creation (format: provider|model)."
|
|
101
110
|
generationModel: String
|
|
111
|
+
|
|
112
|
+
"Whether this entry was generated in review mode."
|
|
113
|
+
isReviewMode: Boolean!
|
|
114
|
+
|
|
115
|
+
"Review status (PENDING_REVIEW, REVIEWED) - null for live mode entries."
|
|
116
|
+
reviewStatus: String
|
|
117
|
+
|
|
118
|
+
"Generated answer text - null for live mode entries."
|
|
119
|
+
answerText: String
|
|
120
|
+
|
|
121
|
+
"Expert names identified by AI - always non-null, empty for live mode entries."
|
|
122
|
+
expertNames: [ExpertName!]!
|
|
123
|
+
|
|
124
|
+
"Citations used in the review mode answer - always non-null, empty for live mode entries."
|
|
125
|
+
citations: [Citation!]!
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
"""
|
|
129
|
+
A resolved expert name entry from AI-generated answer metadata.
|
|
130
|
+
"""
|
|
131
|
+
type ExpertName {
|
|
132
|
+
"User ID of the expert."
|
|
133
|
+
userId: String!
|
|
134
|
+
"Display name of the expert."
|
|
135
|
+
displayName: String!
|
|
136
|
+
"Community profile URL for the expert — null for entries written before Phase 11."
|
|
137
|
+
profileUrl: String
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
"""
|
|
141
|
+
A citation used in the AI-generated answer.
|
|
142
|
+
"""
|
|
143
|
+
type Citation {
|
|
144
|
+
"1-based citation index."
|
|
145
|
+
index: Int!
|
|
146
|
+
"Display title of the cited post."
|
|
147
|
+
title: String!
|
|
148
|
+
"URL of the cited community post."
|
|
149
|
+
url: String!
|
|
102
150
|
}
|
|
103
151
|
|
|
104
152
|
"""
|
|
@@ -142,6 +190,9 @@ input AiAnswerLogConstraints {
|
|
|
142
190
|
"Filter by whether expert card was generated."
|
|
143
191
|
expertCardGenerated: Boolean
|
|
144
192
|
|
|
193
|
+
"Filter to review mode entries (true), non-review entries (false), or all (absent)."
|
|
194
|
+
isReviewMode: Boolean
|
|
195
|
+
|
|
145
196
|
"Filter by specific no-answer reasons (matches any in the list)."
|
|
146
197
|
noAnswerReasons: [String!]
|
|
147
198
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Review mode config for a module+board pair.
|
|
3
|
+
"""
|
|
4
|
+
type AiReviewModeConfig {
|
|
5
|
+
"The AI module identifier."
|
|
6
|
+
moduleId: String!
|
|
7
|
+
"The board identifier, or null for community-level config."
|
|
8
|
+
boardId: String
|
|
9
|
+
"""
|
|
10
|
+
Effective mode resolved for this moduleId+boardId pair — always "LIVE" or
|
|
11
|
+
"REVIEW". When a board has no explicit override, this equals
|
|
12
|
+
`communityDefault`. Admin UIs should use `rawMode` to distinguish inherited
|
|
13
|
+
values from explicit overrides.
|
|
14
|
+
"""
|
|
15
|
+
mode: String!
|
|
16
|
+
"""
|
|
17
|
+
Raw board-level setting for this moduleId+boardId pair. One of "DEFAULT",
|
|
18
|
+
"LIVE", or "REVIEW":
|
|
19
|
+
- "DEFAULT" — no board-specific row exists; the effective mode is
|
|
20
|
+
inherited from `communityDefault`.
|
|
21
|
+
- "LIVE" / "REVIEW" — explicit board-level override.
|
|
22
|
+
For community-level queries (boardId == null) this mirrors `mode`.
|
|
23
|
+
"""
|
|
24
|
+
rawMode: String!
|
|
25
|
+
"Community-level default mode for this module (always present)."
|
|
26
|
+
communityDefault: String!
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
extend type Query {
|
|
30
|
+
"""
|
|
31
|
+
Returns the current review mode config for a module+board pair. Nullable so
|
|
32
|
+
that non-admin callers receive a silent null (per the read-path denial
|
|
33
|
+
convention in AiReviewModeConfigDataFetcherSupport) instead of a GraphQL
|
|
34
|
+
execution error. Admin-gated mutation uses the non-null variant and throws
|
|
35
|
+
on denial — see updateAiReviewModeConfig below.
|
|
36
|
+
"""
|
|
37
|
+
aiReviewModeConfig(moduleId: String!, boardId: String): AiReviewModeConfig
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
extend type Mutation {
|
|
41
|
+
"Updates the review mode config and returns the new state."
|
|
42
|
+
updateAiReviewModeConfig(moduleId: String!, boardId: String, mode: String!): AiReviewModeConfig!
|
|
43
|
+
}
|
|
@@ -317,6 +317,12 @@ directive @dateAsMs on FIELD
|
|
|
317
317
|
# This directive measures the length of a string field
|
|
318
318
|
directive @stringLength on FIELD
|
|
319
319
|
|
|
320
|
+
# This directive truncates a string field to a maximum character length
|
|
321
|
+
directive @truncate(
|
|
322
|
+
"The maximum character length to truncate to. 0 means no truncation."
|
|
323
|
+
length: Int!
|
|
324
|
+
) on FIELD
|
|
325
|
+
|
|
320
326
|
# This directive specifies which graph nodes to load asynchronously vs synchronously (default).
|
|
321
327
|
#
|
|
322
328
|
# For example:
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Sort order for saved messages.
|
|
3
|
+
"""
|
|
4
|
+
enum SavedMessagesSortBy {
|
|
5
|
+
"Sort by the date the message was saved (default, most recent first)"
|
|
6
|
+
SAVED_DATE
|
|
7
|
+
"Sort by the original post date of the message (newest first)"
|
|
8
|
+
POST_DATE
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
extend type Query {
|
|
12
|
+
"Fetches all saved/bookmarked messages for a user with pagination support"
|
|
13
|
+
savedMessages(
|
|
14
|
+
"The user ID to fetch saved messages for"
|
|
15
|
+
userId: String!
|
|
16
|
+
"The number of messages to return"
|
|
17
|
+
first: Int
|
|
18
|
+
"The cursor to return the results after"
|
|
19
|
+
after: String
|
|
20
|
+
"Sort order for results"
|
|
21
|
+
sortBy: SavedMessagesSortBy
|
|
22
|
+
): MessageConnection!
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
extend type Mutation {
|
|
26
|
+
"Save/bookmark a message for later reference"
|
|
27
|
+
saveMessage(messageId: String!, notes: String): SaveMessageResponse!
|
|
28
|
+
|
|
29
|
+
"Remove a saved/bookmarked message"
|
|
30
|
+
unsaveMessage(messageId: String!): UnsaveMessageResponse!
|
|
31
|
+
|
|
32
|
+
"Update personal notes on a bookmarked message"
|
|
33
|
+
updateBookmarkNote(messageId: String!, notes: String!): UpdateBookmarkNoteResponse!
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
type SaveMessageResponse {
|
|
37
|
+
success: Boolean!
|
|
38
|
+
errors: [SaveMessageError!]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
type UnsaveMessageResponse {
|
|
42
|
+
success: Boolean!
|
|
43
|
+
errors: [UnsaveMessageError!]
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
union SaveMessageError = SaveMessageFailedError | SaveMessageNotEnabledError
|
|
47
|
+
union UnsaveMessageError = UnsaveMessageFailedError | UnsaveMessageNotEnabledError
|
|
48
|
+
|
|
49
|
+
type SaveMessageFailedError implements Error {
|
|
50
|
+
message: String!
|
|
51
|
+
fields: [String]!
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
"Error when saving is attempted but the social feed feature is not enabled."
|
|
55
|
+
type SaveMessageNotEnabledError implements Error {
|
|
56
|
+
message: String!
|
|
57
|
+
fields: [String]!
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
type UnsaveMessageFailedError implements Error {
|
|
61
|
+
message: String!
|
|
62
|
+
fields: [String]!
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
"Error when unsaving is attempted but the social feed feature is not enabled."
|
|
66
|
+
type UnsaveMessageNotEnabledError implements Error {
|
|
67
|
+
message: String!
|
|
68
|
+
fields: [String]!
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
type UpdateBookmarkNoteResponse {
|
|
72
|
+
success: Boolean!
|
|
73
|
+
errors: [UpdateBookmarkNoteError!]
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
union UpdateBookmarkNoteError = UpdateBookmarkNoteFailedError | UpdateBookmarkNoteNotEnabledError
|
|
77
|
+
|
|
78
|
+
type UpdateBookmarkNoteFailedError implements Error {
|
|
79
|
+
message: String!
|
|
80
|
+
fields: [String]!
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
"Error when updating a bookmark note is attempted but the social feed feature is not enabled."
|
|
84
|
+
type UpdateBookmarkNoteNotEnabledError implements Error {
|
|
85
|
+
message: String!
|
|
86
|
+
fields: [String]!
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
extend interface Message {
|
|
90
|
+
"Whether the current user has bookmarked this message"
|
|
91
|
+
isBookmarked: Boolean!
|
|
92
|
+
"Personal note the current user attached when saving this message"
|
|
93
|
+
bookmarkNote: String
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
extend interface TopicMessage {
|
|
97
|
+
"Whether the current user has bookmarked this message"
|
|
98
|
+
isBookmarked: Boolean!
|
|
99
|
+
"Personal note the current user attached when saving this message"
|
|
100
|
+
bookmarkNote: String
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
extend interface ReplyMessage {
|
|
104
|
+
"Whether the current user has bookmarked this message"
|
|
105
|
+
isBookmarked: Boolean!
|
|
106
|
+
"Personal note the current user attached when saving this message"
|
|
107
|
+
bookmarkNote: String
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
extend interface Article {
|
|
111
|
+
"Whether the current user has bookmarked this message"
|
|
112
|
+
isBookmarked: Boolean!
|
|
113
|
+
"Personal note the current user attached when saving this message"
|
|
114
|
+
bookmarkNote: String
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
extend type ForumTopicMessage {
|
|
118
|
+
"Whether the current user has bookmarked this message"
|
|
119
|
+
isBookmarked: Boolean!
|
|
120
|
+
"Personal note the current user attached when saving this message"
|
|
121
|
+
bookmarkNote: String
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
extend type TkbTopicMessage {
|
|
125
|
+
"Whether the current user has bookmarked this message"
|
|
126
|
+
isBookmarked: Boolean!
|
|
127
|
+
"Personal note the current user attached when saving this message"
|
|
128
|
+
bookmarkNote: String
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
extend type BlogTopicMessage {
|
|
132
|
+
"Whether the current user has bookmarked this message"
|
|
133
|
+
isBookmarked: Boolean!
|
|
134
|
+
"Personal note the current user attached when saving this message"
|
|
135
|
+
bookmarkNote: String
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
extend type IdeaTopicMessage {
|
|
139
|
+
"Whether the current user has bookmarked this message"
|
|
140
|
+
isBookmarked: Boolean!
|
|
141
|
+
"Personal note the current user attached when saving this message"
|
|
142
|
+
bookmarkNote: String
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
extend type ForumReplyMessage {
|
|
146
|
+
"Whether the current user has bookmarked this message"
|
|
147
|
+
isBookmarked: Boolean!
|
|
148
|
+
"Personal note the current user attached when saving this message"
|
|
149
|
+
bookmarkNote: String
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
extend type TkbReplyMessage {
|
|
153
|
+
"Whether the current user has bookmarked this message"
|
|
154
|
+
isBookmarked: Boolean!
|
|
155
|
+
"Personal note the current user attached when saving this message"
|
|
156
|
+
bookmarkNote: String
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
extend type BlogReplyMessage {
|
|
160
|
+
"Whether the current user has bookmarked this message"
|
|
161
|
+
isBookmarked: Boolean!
|
|
162
|
+
"Personal note the current user attached when saving this message"
|
|
163
|
+
bookmarkNote: String
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
extend type IdeaReplyMessage {
|
|
167
|
+
"Whether the current user has bookmarked this message"
|
|
168
|
+
isBookmarked: Boolean!
|
|
169
|
+
"Personal note the current user attached when saving this message"
|
|
170
|
+
bookmarkNote: String
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
extend type OccasionReplyMessage {
|
|
174
|
+
"Whether the current user has bookmarked this message"
|
|
175
|
+
isBookmarked: Boolean!
|
|
176
|
+
"Personal note the current user attached when saving this message"
|
|
177
|
+
bookmarkNote: String
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
extend type AcceptedSolutionMessage {
|
|
181
|
+
"Whether the current user has bookmarked this message"
|
|
182
|
+
isBookmarked: Boolean!
|
|
183
|
+
"Personal note the current user attached when saving this message"
|
|
184
|
+
bookmarkNote: String
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
extend type OccasionTopicMessage {
|
|
188
|
+
"Whether the current user has bookmarked this message"
|
|
189
|
+
isBookmarked: Boolean!
|
|
190
|
+
"Personal note the current user attached when saving this message"
|
|
191
|
+
bookmarkNote: String
|
|
192
|
+
}
|
|
@@ -14,7 +14,9 @@ type ThreadResponseCollection {
|
|
|
14
14
|
createdAt: String!
|
|
15
15
|
updatedAt: String
|
|
16
16
|
messageTitle: String
|
|
17
|
+
messageViewHref: String
|
|
17
18
|
boardName: String
|
|
19
|
+
boardId: String
|
|
18
20
|
authorName: String
|
|
19
21
|
items: [ThreadResponseItem!]!
|
|
20
22
|
}
|
|
@@ -52,6 +54,7 @@ type ClarificationGuidanceExample {
|
|
|
52
54
|
displayOrder: Int!
|
|
53
55
|
enabled: Boolean!
|
|
54
56
|
createdAt: String!
|
|
57
|
+
isInherited: Boolean!
|
|
55
58
|
}
|
|
56
59
|
|
|
57
60
|
enum CollectionStatus {
|
|
@@ -93,6 +96,16 @@ type BoardClarificationSummary {
|
|
|
93
96
|
boardTitle: String!
|
|
94
97
|
conversationStyle: String!
|
|
95
98
|
enabled: Boolean!
|
|
99
|
+
inherited: Boolean!
|
|
100
|
+
hasOverrides: Boolean!
|
|
101
|
+
isRootFolder: Boolean!
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
type CategoryClarificationDefault {
|
|
105
|
+
nodeId: ID!
|
|
106
|
+
enabled: Boolean!
|
|
107
|
+
hasOverrides: Boolean!
|
|
108
|
+
isRootFolder: Boolean!
|
|
96
109
|
}
|
|
97
110
|
|
|
98
111
|
type ClarificationSettings {
|
|
@@ -103,6 +116,9 @@ type ClarificationSettings {
|
|
|
103
116
|
infoBannerText: String!
|
|
104
117
|
reminderEmailDelay: Int!
|
|
105
118
|
allowSkip: Boolean!
|
|
119
|
+
hasOverrides: Boolean!
|
|
120
|
+
hasAncestorOverrides: Boolean!
|
|
121
|
+
isRootFolder: Boolean!
|
|
106
122
|
}
|
|
107
123
|
|
|
108
124
|
input ClarificationSettingsInput @validationDefaults(prefix: "clarification_settings") {
|
|
@@ -149,6 +165,9 @@ extend type Query {
|
|
|
149
165
|
"Get clarification enabled status for all eligible boards (Forum/Idea)"
|
|
150
166
|
allBoardClarificationSettings: [BoardClarificationSummary!]
|
|
151
167
|
|
|
168
|
+
"Get the effective clarification default for each category/community that contains eligible boards"
|
|
169
|
+
categoryClarificationDefaults: [CategoryClarificationDefault!]
|
|
170
|
+
|
|
152
171
|
"Get formatted clarification questions text for a message (used by Flow template variable resolution)"
|
|
153
172
|
clarificationQuestionsText(messageUid: Int!): String
|
|
154
173
|
|
|
@@ -225,6 +244,15 @@ extend type Mutation {
|
|
|
225
244
|
|
|
226
245
|
"Set clarification settings for a board (takes GraphQL node ID like 'board:forum-name')"
|
|
227
246
|
setClarificationSettings(nodeId: ID!, settingsInput: ClarificationSettingsInput!): ClarificationSettingsResult
|
|
247
|
+
|
|
248
|
+
"Clear clarification overrides for a node so it falls back to parent (category/community) defaults"
|
|
249
|
+
clearClarificationSettings(nodeId: ID!): ClarificationSettingsResult
|
|
250
|
+
|
|
251
|
+
"Apply a category's clarification default to every board beneath it (clears per-board overrides)"
|
|
252
|
+
applyClarificationDefaultToBoards(nodeId: ID!): ClarificationSettingsResult
|
|
253
|
+
|
|
254
|
+
"Force a clarification on/off state across a container and every board beneath it (sets the container's own state and clears descendant enabled overrides so they inherit)"
|
|
255
|
+
applyClarificationEnabledToBoards(nodeId: ID!, enabled: Boolean!): ClarificationSettingsResult
|
|
228
256
|
}
|
|
229
257
|
|
|
230
258
|
input ClarificationAnswerInput @validationDefaults(prefix: "clarification_answer") {
|
|
@@ -36,6 +36,32 @@ type ExpertListEntry {
|
|
|
36
36
|
activity90d: Int
|
|
37
37
|
"Contributions (posts + solutions) in the last 180 days. Null if no tblia_expert_totals row exists."
|
|
38
38
|
activity180d: Int
|
|
39
|
+
"Opt-out state for this expert. Null = routable, 'USER_OPT_OUT' = user opted out, 'ADMIN_BLACKLIST' = admin blacklisted."
|
|
40
|
+
optOutState: String
|
|
41
|
+
"ISO-8601 timestamp when this row's USER_OPT_OUT is snooze-bounded; null when state is null, ADMIN_BLACKLIST, or indefinite opt-out."
|
|
42
|
+
snoozeUntil: String
|
|
43
|
+
"Reason recorded with the latest opt-out/blacklist row that drives the current state. Null when state is null."
|
|
44
|
+
latestReason: String
|
|
45
|
+
"Login (canonical) of the actor who set the current state. Null for user-driven changes or when the actor account was deleted."
|
|
46
|
+
latestActorLogin: String
|
|
47
|
+
"ISO-8601 timestamp of the latest state change. Null when state is null."
|
|
48
|
+
latestChangedAt: String
|
|
49
|
+
"Topic slugs the user is currently admin-blacklisted on. Empty string entry represents the global (all-topics) blacklist row. Empty array when the user is not admin-blacklisted."
|
|
50
|
+
blacklistedTopics: [String!]!
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
"""
|
|
54
|
+
Routing-status filter applied server-side when reading the experts leaderboard.
|
|
55
|
+
"""
|
|
56
|
+
enum RoutingStatusFilter {
|
|
57
|
+
"Include every expert regardless of opt-out / blacklist state."
|
|
58
|
+
SHOW_ALL
|
|
59
|
+
"Only experts who are routable right now (no active opt-out and no admin blacklist)."
|
|
60
|
+
ROUTABLE_ONLY
|
|
61
|
+
"Only experts who have an active user-initiated global opt-out."
|
|
62
|
+
USER_OPT_OUT_ONLY
|
|
63
|
+
"Only experts who are admin-blacklisted (globally or on this row's topic)."
|
|
64
|
+
ADMIN_BLACKLIST_ONLY
|
|
39
65
|
}
|
|
40
66
|
|
|
41
67
|
extend type Query {
|
|
@@ -59,6 +85,10 @@ extend type Query {
|
|
|
59
85
|
offset: Int
|
|
60
86
|
"Maximum number of rows to return. Defaults to clm.topExpertsPerTopic setting."
|
|
61
87
|
limit: Int
|
|
88
|
+
"When true, includes admin-blacklisted users in results. Defaults to false."
|
|
89
|
+
includeBlacklisted: Boolean = false
|
|
90
|
+
"Optional routing-status filter."
|
|
91
|
+
routingStatusFilter: RoutingStatusFilter
|
|
62
92
|
): [ExpertListEntry!]!
|
|
63
93
|
}
|
|
64
94
|
|
|
@@ -117,6 +147,32 @@ extend type Query {
|
|
|
117
147
|
expertRankNames: [String!]!
|
|
118
148
|
}
|
|
119
149
|
|
|
150
|
+
"Filter-aware aggregate counts for the experts leaderboard summary strip."
|
|
151
|
+
type ExpertStatusCountsResult {
|
|
152
|
+
"Number of routable experts (no opt-out, no blacklist, accepting routing)."
|
|
153
|
+
routable: Int!
|
|
154
|
+
"Number of experts opted out indefinitely."
|
|
155
|
+
userOptOut: Int!
|
|
156
|
+
"Number of experts who paused via the 30-day snooze (snooze_until in the future)."
|
|
157
|
+
paused30d: Int!
|
|
158
|
+
"Number of experts admin-blacklisted from routing."
|
|
159
|
+
blacklisted: Int!
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
extend type Query {
|
|
163
|
+
"""
|
|
164
|
+
Returns filter-aware status counts for the experts leaderboard summary strip.
|
|
165
|
+
Same filter args as expertList. Admin-only.
|
|
166
|
+
"""
|
|
167
|
+
expertStatusCounts(
|
|
168
|
+
topic: String
|
|
169
|
+
staffOnly: Boolean
|
|
170
|
+
username: String
|
|
171
|
+
rankName: String
|
|
172
|
+
roleType: String
|
|
173
|
+
): ExpertStatusCountsResult
|
|
174
|
+
}
|
|
175
|
+
|
|
120
176
|
extend type Query {
|
|
121
177
|
"""
|
|
122
178
|
Returns distinct community role names from the roles table for experts.
|
|
@@ -124,3 +180,26 @@ extend type Query {
|
|
|
124
180
|
"""
|
|
125
181
|
expertRoleTypes: [String!]!
|
|
126
182
|
}
|
|
183
|
+
|
|
184
|
+
"""
|
|
185
|
+
Viewer-scoped type for fields that pertain to the currently authenticated user.
|
|
186
|
+
"""
|
|
187
|
+
type Me {
|
|
188
|
+
"""
|
|
189
|
+
True if the user has appeared as an expert candidate at least once.
|
|
190
|
+
Drives whether the Expert Routing Notifications section renders in the user's settings.
|
|
191
|
+
"""
|
|
192
|
+
hasBeenExpertCandidate: Boolean!
|
|
193
|
+
"""
|
|
194
|
+
True iff the community-level opt-out feature flag (expertRouting.optOutEnabled)
|
|
195
|
+
is enabled AND the current user has been an expert candidate. The frontend uses
|
|
196
|
+
this single combined boolean to gate the Expert Routing Notifications section,
|
|
197
|
+
so it does not need to read the admin setting separately.
|
|
198
|
+
"""
|
|
199
|
+
expertRoutingOptOutAvailable: Boolean!
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
extend type Query {
|
|
203
|
+
"Returns viewer-scoped fields for the currently authenticated user."
|
|
204
|
+
me: Me
|
|
205
|
+
}
|
|
@@ -112,6 +112,8 @@ type EmailTemplate implements Node {
|
|
|
112
112
|
isDefaultVersion: Boolean
|
|
113
113
|
"The version number of the latest published version."
|
|
114
114
|
versionNum: Int
|
|
115
|
+
"An optional custom display name for this version."
|
|
116
|
+
versionDisplayName: String
|
|
115
117
|
"The status of the latest version."
|
|
116
118
|
status: EmailTemplateVersionStatus
|
|
117
119
|
"The locale of the latest version."
|
|
@@ -177,6 +179,7 @@ An enumeration that defines the status of an email template version.
|
|
|
177
179
|
enum EmailTemplateVersionStatus {
|
|
178
180
|
DRAFT
|
|
179
181
|
ACTIVE
|
|
182
|
+
INACTIVE
|
|
180
183
|
}
|
|
181
184
|
|
|
182
185
|
"""
|
|
@@ -220,15 +223,23 @@ extend type Mutation {
|
|
|
220
223
|
versionNum: Int!
|
|
221
224
|
): UpdateEmailTemplateResult!
|
|
222
225
|
|
|
226
|
+
"Marks the currently active version of an email template as inactive. The template will fall back to the default version until another version is set active."
|
|
227
|
+
setInactiveEmailTemplateVersion(
|
|
228
|
+
"The unique template identifier."
|
|
229
|
+
templateId: String!
|
|
230
|
+
"The version number to mark inactive. Must currently be ACTIVE."
|
|
231
|
+
versionNum: Int!
|
|
232
|
+
): UpdateEmailTemplateResult!
|
|
233
|
+
|
|
223
234
|
"Creates a new custom email template with an initial version."
|
|
224
235
|
createEmailTemplate(input: CreateEmailTemplateInput!): UpdateEmailTemplateResult!
|
|
225
236
|
|
|
226
|
-
"Creates a new draft version of an existing email template,
|
|
237
|
+
"Creates a new draft version of an existing email template. If sourceVersionNum is provided, copies content from that version; otherwise creates a blank version."
|
|
227
238
|
createEmailTemplateVersion(
|
|
228
239
|
"The unique template identifier."
|
|
229
240
|
templateId: String!
|
|
230
|
-
"The version number to copy content from."
|
|
231
|
-
sourceVersionNum: Int
|
|
241
|
+
"The version number to copy content from. If omitted, a blank version is created."
|
|
242
|
+
sourceVersionNum: Int
|
|
232
243
|
): UpdateEmailTemplateResult!
|
|
233
244
|
|
|
234
245
|
"""
|
|
@@ -243,6 +254,16 @@ extend type Mutation {
|
|
|
243
254
|
versionNum: Int
|
|
244
255
|
): SendTestEmailResult!
|
|
245
256
|
|
|
257
|
+
"Renames a specific version of an email template by setting a custom display name."
|
|
258
|
+
renameEmailTemplateVersion(
|
|
259
|
+
"The unique template identifier."
|
|
260
|
+
templateId: String!
|
|
261
|
+
"The version number to rename."
|
|
262
|
+
versionNum: Int!
|
|
263
|
+
"The new display name for the version. Pass null or empty string to clear."
|
|
264
|
+
displayName: String
|
|
265
|
+
): UpdateEmailTemplateResult!
|
|
266
|
+
|
|
246
267
|
"Deletes a specific version of an email template. Cannot delete the default (system) version."
|
|
247
268
|
deleteEmailTemplateVersion(
|
|
248
269
|
"The unique template identifier."
|
|
@@ -59,6 +59,15 @@ extend type TkbTopicMessage {
|
|
|
59
59
|
expertSuggestions: [ExpertSuggestion!]
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
extend type IdeaTopicMessage {
|
|
63
|
+
"""
|
|
64
|
+
AI-generated expert suggestions for this idea.
|
|
65
|
+
Only populated when the AI system cannot find a direct answer but identifies relevant experts.
|
|
66
|
+
Visible only to the post author and moderators.
|
|
67
|
+
"""
|
|
68
|
+
expertSuggestions: [ExpertSuggestion!]
|
|
69
|
+
}
|
|
70
|
+
|
|
62
71
|
extend type Mutation {
|
|
63
72
|
"""
|
|
64
73
|
Sets or updates the expert suggestions for a message.
|
|
@@ -140,11 +149,20 @@ extend type Query {
|
|
|
140
149
|
): [ExpertSuggestion!]!
|
|
141
150
|
|
|
142
151
|
"""
|
|
143
|
-
|
|
144
|
-
Returns distinct topics ordered alphabetically
|
|
152
|
+
Cursor-paginated list of topics that have expert data in the community.
|
|
153
|
+
Returns up to {@code limit} distinct topics ordered alphabetically and
|
|
154
|
+
strictly greater than {@code after}. The client requests the next page
|
|
155
|
+
by passing the last topic from the previous response as {@code after};
|
|
156
|
+
a response shorter than {@code limit} signals the end of the set.
|
|
157
|
+
{@code search} restricts results to topics with the given case-insensitive
|
|
158
|
+
prefix so typeahead and infinite scroll compose naturally.
|
|
145
159
|
"""
|
|
146
160
|
allTopics(
|
|
147
|
-
"
|
|
161
|
+
"Optional case-insensitive prefix. Empty/null returns all topics."
|
|
162
|
+
search: String
|
|
163
|
+
"Cursor: last topic from the previous page. Null or empty means start at the head."
|
|
164
|
+
after: String
|
|
165
|
+
"Page size (default: 50, max: 200)."
|
|
148
166
|
limit: Int = 50
|
|
149
167
|
): [String!]!
|
|
150
168
|
}
|
|
@@ -47,6 +47,12 @@ extend type Mutation {
|
|
|
47
47
|
nodeId: ID
|
|
48
48
|
settingsInput: FollowSettingsInput!
|
|
49
49
|
): SetSettingsResult!
|
|
50
|
+
|
|
51
|
+
"Deletes all thread follows for the current user that were auto-created by the given reaction type."
|
|
52
|
+
bulkUnfollowByReactionType(
|
|
53
|
+
"The reaction type that triggered the auto-follows to remove (e.g. 'i_need_this', 'good_question')."
|
|
54
|
+
reactionType: String!
|
|
55
|
+
): BulkUnfollowByReactionTypeResponse!
|
|
50
56
|
}
|
|
51
57
|
|
|
52
58
|
"Error when a follow is invalid."
|
|
@@ -190,6 +196,8 @@ Defines sorts that can be used to sort the follow queries.
|
|
|
190
196
|
input FollowSorts {
|
|
191
197
|
"Sort by the follow ID."
|
|
192
198
|
id: Sort
|
|
199
|
+
"Sort by last activity time."
|
|
200
|
+
lastActivityTime: Sort
|
|
193
201
|
}
|
|
194
202
|
|
|
195
203
|
"""
|
|
@@ -231,6 +239,9 @@ type Follow implements Entity & Node @restV2Mapping(field: "subscription") {
|
|
|
231
239
|
|
|
232
240
|
"The count of unread messages for a tag subscription for a user on a node"
|
|
233
241
|
unreadMessageCount: Int
|
|
242
|
+
|
|
243
|
+
"The reaction type that triggered this follow (e.g. i_need_this, good_question), or null if manually followed."
|
|
244
|
+
sourceReactionType: String
|
|
234
245
|
}
|
|
235
246
|
|
|
236
247
|
extend type User implements FollowUserAdministrative & FollowUserApplicable {
|
|
@@ -357,6 +368,10 @@ type FollowUserSettings implements Settings {
|
|
|
357
368
|
boardFollowMethod: InheritableStringSettingWithPossibleValues
|
|
358
369
|
"The setting to whether skip notifications of the read posts."
|
|
359
370
|
ignoreReadPosts: BooleanSetting
|
|
371
|
+
"The setting to auto follow threads when reacting with 'I Need This'."
|
|
372
|
+
autoFollowOnINeedThis: BooleanSetting
|
|
373
|
+
"The setting to auto follow threads when reacting with 'Good Question'."
|
|
374
|
+
autoFollowOnGoodQuestion: BooleanSetting
|
|
360
375
|
}
|
|
361
376
|
|
|
362
377
|
"Follows properties for an user."
|
|
@@ -369,6 +384,10 @@ type FollowUserProperties {
|
|
|
369
384
|
boardFollowMethod: String
|
|
370
385
|
"The setting to whether skip notifications of the read posts."
|
|
371
386
|
ignoreReadPosts: Boolean
|
|
387
|
+
"The setting to auto follow threads when reacting with 'I Need This'."
|
|
388
|
+
autoFollowOnINeedThis: Boolean
|
|
389
|
+
"The setting to auto follow threads when reacting with 'Good Question'."
|
|
390
|
+
autoFollowOnGoodQuestion: Boolean
|
|
372
391
|
}
|
|
373
392
|
|
|
374
393
|
"Follow settings."
|
|
@@ -474,6 +493,10 @@ input FollowUserSettingsInput {
|
|
|
474
493
|
boardFollowMethod: String
|
|
475
494
|
"The setting to whether skip the notifications of the read posts."
|
|
476
495
|
ignoreReadPosts: Boolean
|
|
496
|
+
"The setting to auto follow threads when reacting with 'I Need This'."
|
|
497
|
+
autoFollowOnINeedThis: Boolean
|
|
498
|
+
"The setting to auto follow threads when reacting with 'Good Question'."
|
|
499
|
+
autoFollowOnGoodQuestion: Boolean
|
|
477
500
|
}
|
|
478
501
|
|
|
479
502
|
"""
|
|
@@ -497,3 +520,11 @@ type TagFollowable {
|
|
|
497
520
|
"The node at which a tag was followed."
|
|
498
521
|
coreNode: CoreNode!
|
|
499
522
|
}
|
|
523
|
+
|
|
524
|
+
"Response to the bulkUnfollowByReactionType mutation."
|
|
525
|
+
type BulkUnfollowByReactionTypeResponse {
|
|
526
|
+
"Whether the bulk unfollow succeeded."
|
|
527
|
+
success: Boolean!
|
|
528
|
+
"The number of follows removed."
|
|
529
|
+
deletedCount: Int!
|
|
530
|
+
}
|