khoros-aurora-sdk 26.2.0 → 26.3.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/build-hash.txt +1 -1
- package/graphql/aiAnswerLogSchema.graphqls +9 -0
- package/graphql/clarificationSchema.graphqls +234 -0
- package/graphql/clmSchema.graphqls +126 -0
- package/graphql/communitySearchSchema.graphqls +10 -2
- package/graphql/emailOrchestrationSchema.graphqls +293 -0
- package/graphql/imageSchema.graphqls +3 -0
- package/graphql/mailSchema.graphqls +14 -8
- package/graphql/messageAutosaveSchema.graphqls +12 -0
- package/graphql/messageSchema.graphqls +25 -0
- package/graphql/metricGridSchema.graphqls +4 -0
- package/graphql/metricSchema.graphqls +1589 -0
- package/graphql/moderationSchema.graphqls +59 -0
- package/graphql/pollSchema.graphqls +541 -0
- package/graphql/productSchema.unreleased.graphqls +4 -4
- package/graphql/promotedSearchRuleSchema.graphqls +3 -1
- package/graphql/ruleSchema.graphqls +69 -12
- package/graphql/searchSettingsSchema.graphqls +55 -0
- package/graphql/uploadedImageSchema.graphqls +1 -0
- package/graphql/userSchema.graphqls +42 -0
- package/package.json +1 -2
- package/scripts/buildPluginCli.js +6 -6
- package/scripts/initPluginCli.js +6 -6
- package/scripts/postInstall.js +3 -3
- package/types/mf/index.d.ts +6 -8
- package/types/pkg/index.d.ts +0 -8
package/build-hash.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
5f02757
|
|
@@ -79,6 +79,15 @@ type AiAnswerLog {
|
|
|
79
79
|
"Citation coverage ratio (0.0-1.0) - citations used divided by citations provided."
|
|
80
80
|
citationCoverage: Float
|
|
81
81
|
|
|
82
|
+
"Number of KB article citations provided to the LLM."
|
|
83
|
+
sourceKbCount: Int
|
|
84
|
+
|
|
85
|
+
"Number of blog article citations provided to the LLM."
|
|
86
|
+
sourceBlogCount: Int
|
|
87
|
+
|
|
88
|
+
"Number of forum reply citations provided to the LLM."
|
|
89
|
+
sourceForumCount: Int
|
|
90
|
+
|
|
82
91
|
"Reasons why AI answer was not generated (can be multiple)."
|
|
83
92
|
noAnswerReasons: [String!]
|
|
84
93
|
|
|
@@ -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."
|