khoros-aurora-sdk 26.2.2 → 26.3.1

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/build-hash.txt CHANGED
@@ -1 +1 @@
1
- b42ea22
1
+ 7d3ff26
@@ -0,0 +1,234 @@
1
+ # Clarification Questions - Generic Thread Response Collection
2
+ # KCOMM-484
3
+
4
+ type ThreadResponseCollection {
5
+ id: ID!
6
+ messageUid: Int!
7
+ boardUid: Int!
8
+ collectionType: String!
9
+ status: CollectionStatus!
10
+ questionText: String
11
+ createdBy: Int!
12
+ completedAt: String
13
+ expiresAt: String
14
+ createdAt: String!
15
+ updatedAt: String
16
+ messageTitle: String
17
+ boardName: String
18
+ authorName: String
19
+ items: [ThreadResponseItem!]!
20
+ }
21
+
22
+ type ThreadResponseItem {
23
+ id: ID!
24
+ collectionId: ID!
25
+ itemText: String!
26
+ itemType: String!
27
+ answerOptions: [String!]
28
+ isRequired: Boolean!
29
+ displayOrder: Int!
30
+ source: String!
31
+ response: ThreadResponse
32
+ }
33
+
34
+ type ThreadResponse {
35
+ id: ID!
36
+ itemId: ID!
37
+ respondentUid: Int
38
+ responseText: String
39
+ selectedOptions: [Int!]
40
+ skipped: Boolean!
41
+ moderationStatus: String!
42
+ rejectReason: String
43
+ moderatedBy: String
44
+ respondedAt: String!
45
+ }
46
+
47
+ type ClarificationGuidanceExample {
48
+ id: ID!
49
+ boardUid: Int!
50
+ exampleText: String!
51
+ isRequired: Boolean!
52
+ displayOrder: Int!
53
+ enabled: Boolean!
54
+ createdAt: String!
55
+ }
56
+
57
+ enum CollectionStatus {
58
+ PENDING
59
+ ACTIVE
60
+ COMPLETED
61
+ SKIPPED
62
+ ABANDONED
63
+ }
64
+
65
+ type ClarificationWorkflowResponse {
66
+ collection: ThreadResponseCollection
67
+ success: Boolean!
68
+ errorMessage: String
69
+ }
70
+
71
+ type ClarificationWorkflowListResponse {
72
+ collections: [ThreadResponseCollection!]!
73
+ totalCount: Int!
74
+ }
75
+
76
+ type ClarificationMetrics {
77
+ completionRate: Float!
78
+ skipRate: Float!
79
+ avgQuestionsAsked: Float!
80
+ totalWorkflows: Int!
81
+ emailPromptRate: Float!
82
+ }
83
+
84
+ type ClarificationGuidanceExampleResponse {
85
+ example: ClarificationGuidanceExample
86
+ success: Boolean!
87
+ errorMessage: String
88
+ }
89
+
90
+ type BoardClarificationSummary {
91
+ nodeId: ID!
92
+ boardUid: Int!
93
+ boardTitle: String!
94
+ conversationStyle: String!
95
+ enabled: Boolean!
96
+ }
97
+
98
+ type ClarificationSettings {
99
+ globalEnabled: Boolean!
100
+ enabled: Boolean!
101
+ maxQuestions: Int!
102
+ showInfoBanner: Boolean!
103
+ infoBannerText: String!
104
+ reminderEmailDelay: Int!
105
+ allowSkip: Boolean!
106
+ }
107
+
108
+ input ClarificationSettingsInput @validationDefaults(prefix: "clarification_settings") {
109
+ globalEnabled: Boolean @validation(key: "global_enabled")
110
+ enabled: Boolean @validation(key: "enabled")
111
+ maxQuestions: Int @validation(key: "max_questions")
112
+ showInfoBanner: Boolean @validation(key: "show_info_banner")
113
+ infoBannerText: String @validation(key: "info_banner_text")
114
+ reminderEmailDelay: Int @validation(key: "reminder_email_delay")
115
+ allowSkip: Boolean @validation(key: "allow_skip")
116
+ }
117
+
118
+ type ClarificationSettingsResult {
119
+ success: Boolean!
120
+ errorMessage: String
121
+ }
122
+
123
+ extend type Query {
124
+ "Get clarification workflow for a specific post"
125
+ clarificationWorkflow(messageUid: Int!): ClarificationWorkflowResponse
126
+
127
+ "List all clarification workflows for review queue"
128
+ clarificationWorkflows(
129
+ boardUid: Int
130
+ status: CollectionStatus
131
+ createdAfter: String
132
+ createdBefore: String
133
+ offset: Int
134
+ limit: Int
135
+ ): ClarificationWorkflowListResponse
136
+
137
+ "Get CM guidance examples for a board"
138
+ clarificationGuidanceExamples(nodeId: ID!): [ClarificationGuidanceExample!]
139
+
140
+ "Check if clarification is enabled for a board"
141
+ isClarificationEnabled(boardUid: Int!): Boolean
142
+
143
+ "Get clarification metrics for the review queue"
144
+ clarificationMetrics(boardUid: Int): ClarificationMetrics
145
+
146
+ "Get clarification settings for a board (takes GraphQL node ID like 'board:forum-name')"
147
+ clarificationSettings(nodeId: ID!): ClarificationSettings
148
+
149
+ "Get clarification enabled status for all eligible boards (Forum/Idea)"
150
+ allBoardClarificationSettings: [BoardClarificationSummary!]
151
+
152
+ "Get formatted clarification questions text for a message (used by Flow template variable resolution)"
153
+ clarificationQuestionsText(messageUid: Int!): String
154
+
155
+ "Get clarification responses for moderation dashboard"
156
+ clarificationResponsesForModeration(
157
+ status: String
158
+ rejectReason: String
159
+ boardUid: Int
160
+ offset: Int
161
+ limit: Int
162
+ ): ClarificationModerationListResponse
163
+ }
164
+
165
+ type ClarificationModerationListResponse {
166
+ responses: [ClarificationModerationItem!]!
167
+ totalCount: Int!
168
+ }
169
+
170
+ type ClarificationModerationItem {
171
+ response: ThreadResponse!
172
+ item: ThreadResponseItem!
173
+ collection: ThreadResponseCollection!
174
+ messageSubject: String
175
+ boardTitle: String
176
+ }
177
+
178
+ extend type Mutation {
179
+ "Generate clarification questions for a published post"
180
+ generateClarificationQuestions(messageUid: Int!): ClarificationWorkflowResponse
181
+
182
+ "User submits answers to clarification questions"
183
+ submitClarificationAnswers(
184
+ collectionId: ID!
185
+ answers: [ClarificationAnswerInput!]!
186
+ ): ClarificationWorkflowResponse
187
+
188
+ "User edits previously submitted clarification answers"
189
+ editClarificationAnswers(
190
+ collectionId: ID!
191
+ answers: [ClarificationAnswerInput!]!
192
+ ): ClarificationWorkflowResponse
193
+
194
+ "User skips the entire clarification step"
195
+ skipClarification(collectionId: ID!): ClarificationWorkflowResponse
196
+
197
+ "CM saves a guidance example for a board"
198
+ saveClarificationGuidanceExample(
199
+ nodeId: ID!
200
+ exampleId: ID
201
+ exampleText: String!
202
+ displayOrder: Int!
203
+ ): ClarificationGuidanceExampleResponse
204
+
205
+ "CM deletes a guidance example"
206
+ deleteClarificationGuidanceExample(exampleId: ID!): Boolean
207
+
208
+ "CM reorders guidance examples"
209
+ reorderClarificationGuidanceExamples(
210
+ nodeId: ID!
211
+ exampleIds: [ID!]!
212
+ ): [ClarificationGuidanceExample!]
213
+
214
+ "Admin resends clarification nudge email to post author"
215
+ resendClarificationNudge(collectionId: ID!): ClarificationWorkflowResponse
216
+
217
+ "Admin resets clarification status back to PENDING"
218
+ resetClarificationStatus(collectionId: ID!): ClarificationWorkflowResponse
219
+
220
+ "Admin moderates a clarification answer (approve/reject with optional reason)"
221
+ moderateClarificationAnswer(responseId: ID!, status: String!, rejectReason: String): Boolean
222
+
223
+ "Admin bulk-approves all PENDING clarification answers for a collection"
224
+ approveAllClarificationAnswers(collectionId: ID!): Boolean
225
+
226
+ "Set clarification settings for a board (takes GraphQL node ID like 'board:forum-name')"
227
+ setClarificationSettings(nodeId: ID!, settingsInput: ClarificationSettingsInput!): ClarificationSettingsResult
228
+ }
229
+
230
+ input ClarificationAnswerInput @validationDefaults(prefix: "clarification_answer") {
231
+ itemId: ID! @validation(key: "item_id")
232
+ responseText: String @validation(key: "response_text")
233
+ selectedOptions: [Int!] @ignoreValidation
234
+ }
@@ -0,0 +1,126 @@
1
+ # CLM Expert List Schema
2
+ # Provides the expertList query for Community Managers to discover top experts per topic.
3
+
4
+ """
5
+ A single entry in the top experts list for a topic.
6
+ AI profiles are always excluded from this list.
7
+ """
8
+ type ExpertListEntry {
9
+ "The user ID of the expert."
10
+ userId: Int!
11
+ "The login name of the expert."
12
+ login: String!
13
+ "The topic this expert is ranked for."
14
+ topic: String!
15
+ "The precomputed expertise score."
16
+ expertiseScore: Float!
17
+ "Number of messages posted on this topic."
18
+ messageCount: Int!
19
+ "Number of accepted solutions on this topic."
20
+ solutionCount: Int!
21
+ "Likes received on this topic."
22
+ kudosReceived: Int!
23
+ "The expert's rank name. Null if the user has no rank."
24
+ rankName: String
25
+ "The expert's rank position (lower value = higher rank). Null if unranked."
26
+ rankPosition: Int
27
+ "Whether the expert is a staff member (has a rank_position assigned)."
28
+ isStaff: Boolean!
29
+ "Total posts across all topics. Null if no tblia_expert_totals row exists for this user."
30
+ totalPosts: Int
31
+ "Total accepted solutions across all topics. Null if no tblia_expert_totals row exists."
32
+ totalSolutions: Int
33
+ "Total likes received across all topics. Null if no tblia_expert_totals row exists."
34
+ totalKudos: Int
35
+ "Contributions (posts + solutions) in the last 90 days. Null if no tblia_expert_totals row exists."
36
+ activity90d: Int
37
+ "Contributions (posts + solutions) in the last 180 days. Null if no tblia_expert_totals row exists."
38
+ activity180d: Int
39
+ }
40
+
41
+ extend type Query {
42
+ """
43
+ Returns the top experts per topic, filtered and ranked by expertise score.
44
+ AI profiles (answerEngine.aiUserId and answerEngine.kcUserId) are always excluded.
45
+ Results are limited by the clm.topExpertsPerTopic setting (default 10, max 100).
46
+ """
47
+ expertList(
48
+ "Optional topic filter. If provided, returns only experts for this topic (case-insensitive)."
49
+ topic: String
50
+ "Optional staff filter. true = staff only, false = non-staff only, null = all experts."
51
+ staffOnly: Boolean
52
+ "Optional username substring filter (case-insensitive, server-side AES-decrypted match)."
53
+ username: String
54
+ "Optional rank name filter (exact match against rank_name in tblia_expert_topics)."
55
+ rankName: String
56
+ "Optional role type filter (exact match against community role name in roles table)."
57
+ roleType: String
58
+ "Number of rows to skip before returning results. Defaults to 0."
59
+ offset: Int
60
+ "Maximum number of rows to return. Defaults to clm.topExpertsPerTopic setting."
61
+ limit: Int
62
+ ): [ExpertListEntry!]!
63
+ }
64
+
65
+ extend type Query {
66
+ """
67
+ Returns the distinct topic strings that have at least one expert record.
68
+ Used to populate the topic combobox on the CLM Experts admin page.
69
+ AI profiles are excluded from consideration (consistent with expertList).
70
+ """
71
+ expertTopics: [String!]!
72
+ }
73
+
74
+ """
75
+ A topic name and its expert count, used in Top 5 / Bottom 5 summary cards.
76
+ """
77
+ type TopicCount {
78
+ "The topic name."
79
+ topic: String!
80
+ "Number of distinct experts assigned to this topic."
81
+ expertCount: Int!
82
+ }
83
+
84
+ """
85
+ Aggregate counts for the Expert Leaderboard summary panel.
86
+ """
87
+ type ExpertStats {
88
+ "Total number of distinct expert users."
89
+ expertCount: Int!
90
+ "Total number of distinct expert topics."
91
+ topicsCount: Int!
92
+ "Average number of experts per topic (expertCount / topicsCount). Null if no topics."
93
+ avgExpertsPerTopic: Float
94
+ "Top 5 topics by expert count, descending."
95
+ topTopics: [TopicCount!]!
96
+ "Bottom 5 topics by expert count, ascending."
97
+ bottomTopics: [TopicCount!]!
98
+ "Epoch milliseconds of the last CLM build. Null if no build has run."
99
+ lastBuildTimestamp: Long
100
+ "Grand total posts across all experts, aggregated at CLM build time."
101
+ totalPosts: Int
102
+ }
103
+
104
+ extend type Query {
105
+ """
106
+ Returns aggregate expert statistics: total distinct experts and total distinct topics.
107
+ Used by the Experts Leaderboard summary panel.
108
+ """
109
+ expertStats: ExpertStats
110
+ }
111
+
112
+ extend type Query {
113
+ """
114
+ Returns distinct rank names from tblia_expert_topics.
115
+ Unranked experts (rank_name IS NULL) are excluded. AI profiles excluded.
116
+ """
117
+ expertRankNames: [String!]!
118
+ }
119
+
120
+ extend type Query {
121
+ """
122
+ Returns distinct community role names from the roles table for experts.
123
+ Only non-deleted roles held by at least one expert are returned. AI profiles excluded.
124
+ """
125
+ expertRoleTypes: [String!]!
126
+ }
@@ -1,5 +1,5 @@
1
1
  extend type Query {
2
- "Fetches a list of the messages matching the search term with subject or body or teaser or tag or attachment."
2
+ "Fetches a list of the messages matching the search term with subject or body or teaser or tag or attachment or author name."
3
3
  messageSearch(
4
4
  "The search query term to look for when searching the messages."
5
5
  searchTerm: String!
@@ -19,7 +19,7 @@ extend type Query {
19
19
  sorts: MessageSearchSorts
20
20
  ): MessageSearchResults!
21
21
 
22
- "Fetches a list of the messages matching the search term with subject or body or teaser or tag or attachment."
22
+ "Fetches a list of the messages matching the search term with subject or body or teaser or tag or attachment or author name."
23
23
  quickMessageSearch(
24
24
  "The search query term to look for when searching the messages."
25
25
  searchTerm: String!
@@ -177,6 +177,8 @@ interface MessageSearchResult implements Node {
177
177
  message: Message!
178
178
  "A list of metadata that specifies the parts of the message where a match for the searchTerm was found."
179
179
  snippet: [SearchSnippet!]
180
+ "Indicates whether this result is a promoted/featured search result."
181
+ isPromoted: Boolean
180
182
  }
181
183
  """
182
184
  Defines a quick message search result. This holds the topic message, and its associated search specific results
@@ -233,6 +235,8 @@ type TopLevelMessageSearchResult implements MessageSearchResult & Node {
233
235
  ): MessageSearchConnection
234
236
  "A list of metadata that specifies the parts of the message where a match for the searchTerm was found."
235
237
  snippet: [SearchSnippet!]
238
+ "Indicates whether this result is a promoted/featured search result."
239
+ isPromoted: Boolean
236
240
  }
237
241
 
238
242
  """
@@ -247,6 +251,8 @@ type DescendantMessageSearchResult implements MessageSearchResult & Node {
247
251
  message: Message!
248
252
  "A list of metadata that specifies the parts of the message where a match for the search term was found."
249
253
  snippet: [SearchSnippet!]
254
+ "Indicates whether this result is a promoted/featured search result."
255
+ isPromoted: Boolean
250
256
  }
251
257
 
252
258
  """
@@ -341,6 +347,8 @@ enum SearchSnippetKey {
341
347
  TEASER
342
348
  "Search snippet is for the message tag."
343
349
  TAGS
350
+ "Search snippet is for the message author name."
351
+ AUTHOR_NAME
344
352
  "This search snippet is the user login ID."
345
353
  LOGIN
346
354
  "This search snippet is for the user first name."
@@ -0,0 +1,293 @@
1
+ extend type Query {
2
+ "Returns the available template variables for RULES category email templates. These come from a static registry, not from existing templates."
3
+ rulesTemplateVariables: [EmailTemplateVariable!]!
4
+
5
+ "Fetches a list of email orchestration templates."
6
+ emailTemplates(
7
+ "Constraints to filter email templates."
8
+ constraints: EmailTemplateConstraints
9
+ "The number of results to return."
10
+ first: Int
11
+ "The cursor to return the results after."
12
+ after: String
13
+ "The last 'n' number of results to return."
14
+ last: Int
15
+ "The cursor to return the results before."
16
+ before: String
17
+ ): EmailTemplateConnection
18
+ }
19
+
20
+ """
21
+ Defines constraints that can be used to filter the email template queries.
22
+ """
23
+ input EmailTemplateConstraints {
24
+ "A search string to filter templates by name, description, or subject."
25
+ search: String
26
+ "A category to filter templates by."
27
+ category: EmailTemplateCategory
28
+ "A specific template ID to filter by. Returns only versions of this template."
29
+ templateId: String
30
+ "Sort order for the results. One of: RECENT, NAME, CATEGORY. Defaults to RECENT."
31
+ sort: EmailTemplateSort
32
+ "Filter by template type: SYSTEM or CUSTOM."
33
+ type: EmailTemplateType
34
+ "Filter by template status: ACTIVE, DRAFT, DEFAULT, or INACTIVE."
35
+ status: EmailTemplateStatus
36
+ }
37
+
38
+ "Template type filter."
39
+ enum EmailTemplateType {
40
+ SYSTEM
41
+ CUSTOM
42
+ }
43
+
44
+ "Template status filter."
45
+ enum EmailTemplateStatus {
46
+ ACTIVE
47
+ DRAFT
48
+ DEFAULT
49
+ INACTIVE
50
+ }
51
+
52
+ "Sort order for email template results."
53
+ enum EmailTemplateSort {
54
+ RECENT
55
+ NAME
56
+ CATEGORY
57
+ }
58
+
59
+ """
60
+ Defines a connection object for email orchestration templates.
61
+ """
62
+ type EmailTemplateConnection implements Connection {
63
+ "The total count of results (across all pages)."
64
+ totalCount: Int!
65
+ "The page information for the results."
66
+ pageInfo: PageInfo!
67
+ "The results (edges)."
68
+ edges: [EmailTemplateEdge!]!
69
+ "Status counts across all templates (not just the current page). Counts are grouped by template, not by version."
70
+ statusCounts: EmailTemplateStatusCounts
71
+ }
72
+
73
+ "Counts of templates grouped by their overall status."
74
+ type EmailTemplateStatusCounts {
75
+ "Total number of unique templates."
76
+ all: Int!
77
+ "Templates with a non-default ACTIVE version."
78
+ active: Int!
79
+ "Templates with only DRAFT (non-default) versions."
80
+ draft: Int!
81
+ "Templates with only the default (system) version and no overrides."
82
+ default: Int!
83
+ "Templates with no active and no draft versions."
84
+ inactive: Int!
85
+ }
86
+
87
+ """
88
+ Defines an edge for an email orchestration template.
89
+ """
90
+ type EmailTemplateEdge implements Edge {
91
+ "The cursor that can be used to get a new page of results starting after this template."
92
+ cursor: String
93
+ "The email template."
94
+ node: EmailTemplate!
95
+ }
96
+
97
+ "An individual email orchestration template."
98
+ type EmailTemplate implements Node {
99
+ "The email template ID."
100
+ id: ID!
101
+ "The unique template identifier."
102
+ templateId: String!
103
+ "The display name of the template."
104
+ displayName: String!
105
+ "The description of the template."
106
+ description: String
107
+ "The category of the template."
108
+ category: EmailTemplateCategory!
109
+ "Whether this is a system template."
110
+ isSystem: Boolean!
111
+ "Whether the latest version is the default (system-seeded) version. Default versions are read-only and serve as a fallback."
112
+ isDefaultVersion: Boolean
113
+ "The version number of the latest published version."
114
+ versionNum: Int
115
+ "The status of the latest version."
116
+ status: EmailTemplateVersionStatus
117
+ "The locale of the latest version."
118
+ locale: String
119
+ "The subject line of the latest version."
120
+ subject: String
121
+ "The HTML content of the latest version."
122
+ htmlContent: String
123
+ "The raw content JSON of the latest version, containing body blocks (text/button), preamble/postamble HTML, and send config."
124
+ contentJson: String
125
+ "The available template variables that can be inserted into subject and body text. Each variable has a name (e.g. communityTitle) and a type (text or url)."
126
+ variables: [EmailTemplateVariable!]
127
+ "The date the template was created."
128
+ createdDate: String
129
+ "The date the template was last modified."
130
+ modifiedDate: String
131
+ "The date the latest version was published."
132
+ publishedDate: String
133
+ }
134
+
135
+ """
136
+ A template variable that can be inserted into the subject or body text using {variableName} syntax.
137
+ Variables of type 'url' represent links; variables of type 'text' represent text content.
138
+ """
139
+ type EmailTemplateVariable {
140
+ "The variable name, used as {name} in template text."
141
+ name: String!
142
+ "A human-readable display name for the variable."
143
+ displayName: String
144
+ "The variable type: 'text' for text content, 'url' for links."
145
+ type: String!
146
+ "A short description of what this variable represents."
147
+ description: String
148
+ "An example value for this variable."
149
+ example: String
150
+ "Whether this is a global variable shared by all templates."
151
+ isGlobal: Boolean
152
+ "The category this variable belongs to (e.g. Global, User Events, Topic Events)."
153
+ category: String
154
+ "The subcategory within the category (e.g. Registration, Solution Accepted)."
155
+ subcategory: String
156
+ }
157
+
158
+ """
159
+ An enumeration that defines the different email template categories.
160
+ """
161
+ enum EmailTemplateCategory {
162
+ AUTHENTICATION
163
+ SUBSCRIPTION
164
+ ENGAGEMENT
165
+ MODERATION
166
+ WORKFLOW
167
+ MEMBERSHIP
168
+ EVENTS
169
+ INTEGRATION
170
+ ADMIN
171
+ RULES
172
+ }
173
+
174
+ """
175
+ An enumeration that defines the status of an email template version.
176
+ """
177
+ enum EmailTemplateVersionStatus {
178
+ DRAFT
179
+ ACTIVE
180
+ }
181
+
182
+ """
183
+ Input for creating a new custom email template.
184
+ """
185
+ input CreateEmailTemplateInput @validationDefaults(prefix: "create_email_template") {
186
+ "A unique template identifier (e.g. my-welcome-email)."
187
+ templateId: String!
188
+ "The display name shown in the admin UI."
189
+ displayName: String!
190
+ "An optional description of the template."
191
+ description: String
192
+ "The category to file the template under."
193
+ category: EmailTemplateCategory!
194
+ "The subject line for the initial version."
195
+ subject: String!
196
+ "The body blocks as a JSON string for the initial version."
197
+ body: String!
198
+ "Whether to immediately set the new template as active."
199
+ setActive: Boolean
200
+ }
201
+
202
+ extend type Mutation {
203
+ "Updates an email template's subject and body blocks. For system templates, creates a new version."
204
+ updateEmailTemplate(
205
+ "The unique template identifier."
206
+ templateId: String!
207
+ "The version number to update. If omitted, updates the latest published version."
208
+ versionNum: Int
209
+ "The updated subject line."
210
+ subject: String!
211
+ "The updated body blocks as a JSON string."
212
+ body: String!
213
+ ): UpdateEmailTemplateResult!
214
+
215
+ "Sets the active version for an email template. Only one version can be active per template."
216
+ setActiveEmailTemplateVersion(
217
+ "The unique template identifier."
218
+ templateId: String!
219
+ "The version number to set as active."
220
+ versionNum: Int!
221
+ ): UpdateEmailTemplateResult!
222
+
223
+ "Creates a new custom email template with an initial version."
224
+ createEmailTemplate(input: CreateEmailTemplateInput!): UpdateEmailTemplateResult!
225
+
226
+ "Creates a new draft version of an existing email template, copying content from a source version."
227
+ createEmailTemplateVersion(
228
+ "The unique template identifier."
229
+ templateId: String!
230
+ "The version number to copy content from."
231
+ sourceVersionNum: Int!
232
+ ): UpdateEmailTemplateResult!
233
+
234
+ """
235
+ Sends a test email for the specified template to the currently
236
+ authenticated user. Requires CAN_MANAGE_MAIL_TEMPLATES. Rate limited
237
+ per user via `rate.limit.send_test_email.*` in flood.config.
238
+ """
239
+ sendTestEmailToSelf(
240
+ "The unique template identifier."
241
+ templateId: String!
242
+ "The version number to send. If omitted, sends the active version."
243
+ versionNum: Int
244
+ ): SendTestEmailResult!
245
+
246
+ "Deletes a specific version of an email template. Cannot delete the default (system) version."
247
+ deleteEmailTemplateVersion(
248
+ "The unique template identifier."
249
+ templateId: String!
250
+ "The version number to delete."
251
+ versionNum: Int!
252
+ ): DeleteEmailTemplateVersionResult!
253
+ }
254
+
255
+ """
256
+ The result of a deleteEmailTemplateVersion mutation.
257
+ """
258
+ type DeleteEmailTemplateVersionResult {
259
+ "Whether the deletion was successful."
260
+ success: Boolean!
261
+ "Errors that occurred during deletion."
262
+ errors: [EmailTemplateError!]
263
+ }
264
+
265
+ """
266
+ The result of a sendTestEmailToSelf mutation.
267
+ """
268
+ type SendTestEmailResult {
269
+ "Whether the email was sent successfully."
270
+ success: Boolean!
271
+ "The email address the test was sent to."
272
+ recipientEmail: String
273
+ "Errors that occurred during sending."
274
+ errors: [EmailTemplateError!]
275
+ }
276
+
277
+ """
278
+ The result of an updateEmailTemplate mutation.
279
+ """
280
+ type UpdateEmailTemplateResult {
281
+ "The updated email template."
282
+ result: EmailTemplate
283
+ "Any errors that occurred during the mutation."
284
+ errors: [EmailTemplateError!]
285
+ }
286
+
287
+ """
288
+ An error that occurred during an email template mutation.
289
+ """
290
+ type EmailTemplateError {
291
+ "The error message."
292
+ message: String!
293
+ }