@epilot/sdk 2.7.10 → 2.7.11
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/LICENSE +21 -0
- package/definitions/event-catalog-runtime.json +1 -1
- package/definitions/event-catalog.json +168 -12
- package/dist/apis/access-token.cjs +6 -6
- package/dist/apis/access-token.js +1 -1
- package/dist/apis/address-suggestions.cjs +6 -6
- package/dist/apis/address-suggestions.js +1 -1
- package/dist/apis/address.cjs +6 -6
- package/dist/apis/address.js +1 -1
- package/dist/apis/ai-agents.cjs +6 -6
- package/dist/apis/ai-agents.js +1 -1
- package/dist/apis/app.cjs +6 -6
- package/dist/apis/app.js +1 -1
- package/dist/apis/audit-logs.cjs +6 -6
- package/dist/apis/audit-logs.js +1 -1
- package/dist/apis/automation.cjs +6 -6
- package/dist/apis/automation.js +1 -1
- package/dist/apis/billing.cjs +6 -6
- package/dist/apis/billing.js +1 -1
- package/dist/apis/blueprint-manifest.cjs +6 -6
- package/dist/apis/blueprint-manifest.js +1 -1
- package/dist/apis/calendar.cjs +6 -6
- package/dist/apis/calendar.js +1 -1
- package/dist/apis/configuration-hub.cjs +6 -6
- package/dist/apis/configuration-hub.js +1 -1
- package/dist/apis/consent.cjs +6 -6
- package/dist/apis/consent.js +1 -1
- package/dist/apis/customer-portal.cjs +6 -6
- package/dist/apis/customer-portal.js +1 -1
- package/dist/apis/dashboard.cjs +6 -6
- package/dist/apis/dashboard.js +1 -1
- package/dist/apis/data-governance.cjs +6 -6
- package/dist/apis/data-governance.js +1 -1
- package/dist/apis/deduplication.cjs +6 -6
- package/dist/apis/deduplication.js +1 -1
- package/dist/apis/design.cjs +6 -6
- package/dist/apis/design.js +1 -1
- package/dist/apis/document.cjs +6 -6
- package/dist/apis/document.js +1 -1
- package/dist/apis/email-settings.cjs +6 -6
- package/dist/apis/email-settings.js +1 -1
- package/dist/apis/email-template.cjs +6 -6
- package/dist/apis/email-template.js +1 -1
- package/dist/apis/entity-mapping.cjs +6 -6
- package/dist/apis/entity-mapping.js +1 -1
- package/dist/apis/entity.cjs +6 -6
- package/dist/apis/entity.js +1 -1
- package/dist/apis/environments.cjs +6 -6
- package/dist/apis/environments.js +1 -1
- package/dist/apis/event-catalog.cjs +8 -8
- package/dist/apis/event-catalog.d.cts +2 -2
- package/dist/apis/event-catalog.d.ts +2 -2
- package/dist/apis/event-catalog.js +2 -2
- package/dist/apis/file.cjs +6 -6
- package/dist/apis/file.js +1 -1
- package/dist/apis/iban.cjs +6 -6
- package/dist/apis/iban.js +1 -1
- package/dist/apis/integration-toolkit.cjs +6 -6
- package/dist/apis/integration-toolkit.js +1 -1
- package/dist/apis/journey.cjs +6 -6
- package/dist/apis/journey.js +1 -1
- package/dist/apis/kanban.cjs +6 -6
- package/dist/apis/kanban.js +1 -1
- package/dist/apis/message.cjs +6 -6
- package/dist/apis/message.js +1 -1
- package/dist/apis/metering.cjs +6 -6
- package/dist/apis/metering.js +1 -1
- package/dist/apis/notes.cjs +6 -6
- package/dist/apis/notes.js +1 -1
- package/dist/apis/notification.cjs +6 -6
- package/dist/apis/notification.js +1 -1
- package/dist/apis/organization.cjs +6 -6
- package/dist/apis/organization.js +1 -1
- package/dist/apis/partner-directory.cjs +6 -6
- package/dist/apis/partner-directory.js +1 -1
- package/dist/apis/permissions.cjs +6 -6
- package/dist/apis/permissions.js +1 -1
- package/dist/apis/pricing-tier.cjs +6 -6
- package/dist/apis/pricing-tier.js +1 -1
- package/dist/apis/pricing.cjs +6 -6
- package/dist/apis/pricing.js +1 -1
- package/dist/apis/purpose.cjs +6 -6
- package/dist/apis/purpose.js +1 -1
- package/dist/apis/query.cjs +6 -6
- package/dist/apis/query.js +1 -1
- package/dist/apis/sandbox.cjs +6 -6
- package/dist/apis/sandbox.js +1 -1
- package/dist/apis/sharing.cjs +6 -6
- package/dist/apis/sharing.js +1 -1
- package/dist/apis/submission.cjs +6 -6
- package/dist/apis/submission.js +1 -1
- package/dist/apis/target.cjs +6 -6
- package/dist/apis/target.js +1 -1
- package/dist/apis/targeting.cjs +6 -6
- package/dist/apis/targeting.js +1 -1
- package/dist/apis/template-variables.cjs +6 -6
- package/dist/apis/template-variables.js +1 -1
- package/dist/apis/user.cjs +6 -6
- package/dist/apis/user.js +1 -1
- package/dist/apis/validation-rules.cjs +6 -6
- package/dist/apis/validation-rules.js +1 -1
- package/dist/apis/webhooks.cjs +6 -6
- package/dist/apis/webhooks.js +1 -1
- package/dist/apis/workflow-definition.cjs +6 -6
- package/dist/apis/workflow-definition.js +1 -1
- package/dist/apis/workflow.cjs +6 -6
- package/dist/apis/workflow.js +1 -1
- package/dist/chunk-FDS727SL.cjs +14 -0
- package/dist/chunk-M4FO2MI4.js +14 -0
- package/dist/{chunk-PFWNKA6K.js → chunk-THI6AB4O.js} +2 -2
- package/dist/{chunk-YSMN2QWQ.cjs → chunk-XZPA2XDZ.cjs} +2 -2
- package/dist/event-catalog-3YOQ46ZW.js +7 -0
- package/dist/event-catalog-HLWUT7RM.cjs +7 -0
- package/dist/{event-catalog-runtime-N262TQ3Y.js → event-catalog-runtime-JUSLF3UR.js} +1 -1
- package/dist/{event-catalog-runtime-B2BPKQVG.cjs → event-catalog-runtime-RH7542GL.cjs} +2 -2
- package/dist/{event-catalog.d-mQJLSYUo.d.cts → event-catalog.d-CXbUn8T1.d.cts} +199 -36
- package/dist/{event-catalog.d-mQJLSYUo.d.ts → event-catalog.d-CXbUn8T1.d.ts} +199 -36
- package/dist/index.cjs +10 -10
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/js-yaml-DLCVPJ7G.js +0 -0
- package/docs/event-catalog.md +126 -13
- package/package.json +11 -12
- package/definitions/focus-pocus-runtime.json +0 -1
- package/definitions/focus-pocus.json +0 -757
- package/dist/chunk-CBDKPGO5.cjs +0 -14
- package/dist/chunk-OCMIXJWC.js +0 -14
- package/dist/event-catalog-37B6JC7G.js +0 -7
- package/dist/event-catalog-5JBHJJ2I.cjs +0 -7
|
@@ -1,757 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"openapi": "3.0.3",
|
|
3
|
-
"info": {
|
|
4
|
-
"title": "Focus Pocus API",
|
|
5
|
-
"description": "Backend service powering the achievements and mascot features in the epilot 360 portal.\nTracks user activity, evaluates achievement criteria, awards XP, and exposes the\nunified achievements feed and active challenge state.\n",
|
|
6
|
-
"version": "0.2.0",
|
|
7
|
-
"contact": {
|
|
8
|
-
"name": "epilot",
|
|
9
|
-
"email": "info@epilot.cloud",
|
|
10
|
-
"url": "https://epilot.cloud"
|
|
11
|
-
}
|
|
12
|
-
},
|
|
13
|
-
"servers": [
|
|
14
|
-
{
|
|
15
|
-
"url": "https://focus-pocus.dev.sls.epilot.io"
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
"url": "https://focus-pocus.staging.sls.epilot.io",
|
|
19
|
-
"description": "staging"
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
"url": "https://focus-pocus.sls.epilot.io",
|
|
23
|
-
"description": "prod"
|
|
24
|
-
}
|
|
25
|
-
],
|
|
26
|
-
"security": [
|
|
27
|
-
{
|
|
28
|
-
"EpilotAuth": []
|
|
29
|
-
}
|
|
30
|
-
],
|
|
31
|
-
"paths": {
|
|
32
|
-
"/v1/health": {
|
|
33
|
-
"get": {
|
|
34
|
-
"operationId": "getHealth",
|
|
35
|
-
"summary": "getHealth",
|
|
36
|
-
"description": "Liveness probe for the Focus Pocus API. Requires a valid EpilotAuth token.",
|
|
37
|
-
"tags": [
|
|
38
|
-
"Health"
|
|
39
|
-
],
|
|
40
|
-
"responses": {
|
|
41
|
-
"200": {
|
|
42
|
-
"description": "Service is healthy.",
|
|
43
|
-
"content": {
|
|
44
|
-
"application/json": {
|
|
45
|
-
"schema": {
|
|
46
|
-
"$ref": "#/components/schemas/HealthResponse"
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
"401": {
|
|
52
|
-
"$ref": "#/components/responses/Unauthorized"
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
"/v1/achievements": {
|
|
58
|
-
"get": {
|
|
59
|
-
"operationId": "listAchievements",
|
|
60
|
-
"summary": "listAchievements",
|
|
61
|
-
"description": "Unified feed for the authenticated user: returns active challenges and completed\nv1 static achievement unlocks. The `userId` is read from the EpilotAuth claim —\nno user path or query parameter is accepted. Active challenges appear first,\nfollowed by completed items sorted by `unlocked_at` descending.\nItems unlocked within the last 60 seconds have `just_unlocked: true`.\n",
|
|
62
|
-
"tags": [
|
|
63
|
-
"Achievements"
|
|
64
|
-
],
|
|
65
|
-
"responses": {
|
|
66
|
-
"200": {
|
|
67
|
-
"description": "Unified achievements feed for the authenticated user.",
|
|
68
|
-
"content": {
|
|
69
|
-
"application/json": {
|
|
70
|
-
"schema": {
|
|
71
|
-
"$ref": "#/components/schemas/AchievementFeedListResponse"
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
"401": {
|
|
77
|
-
"$ref": "#/components/responses/Unauthorized"
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
"/v1/achievements/{id}": {
|
|
83
|
-
"get": {
|
|
84
|
-
"operationId": "getAchievement",
|
|
85
|
-
"summary": "getAchievement",
|
|
86
|
-
"description": "Single user-scoped achievement or active-challenge item. Returns 404 if the id\ndoes not belong to the authenticated user.\n",
|
|
87
|
-
"tags": [
|
|
88
|
-
"Achievements"
|
|
89
|
-
],
|
|
90
|
-
"parameters": [
|
|
91
|
-
{
|
|
92
|
-
"$ref": "#/components/parameters/AchievementOrChallengeId"
|
|
93
|
-
}
|
|
94
|
-
],
|
|
95
|
-
"responses": {
|
|
96
|
-
"200": {
|
|
97
|
-
"description": "User-scoped achievement or challenge feed item.",
|
|
98
|
-
"content": {
|
|
99
|
-
"application/json": {
|
|
100
|
-
"schema": {
|
|
101
|
-
"$ref": "#/components/schemas/AchievementFeedItem"
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
"401": {
|
|
107
|
-
"$ref": "#/components/responses/Unauthorized"
|
|
108
|
-
},
|
|
109
|
-
"404": {
|
|
110
|
-
"$ref": "#/components/responses/NotFound"
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
},
|
|
115
|
-
"/v1/challenges/suggest": {
|
|
116
|
-
"get": {
|
|
117
|
-
"operationId": "getSuggestedChallenge",
|
|
118
|
-
"summary": "getSuggestedChallenge",
|
|
119
|
-
"description": "Returns a suggested challenge for the authenticated user. The suggestion is\npersisted with a 7-day TTL. Calling again with the same `(user, category)`\nwithin 24h returns the existing suggestion without creating a new row.\nReturns 204 when all candidate templates have been dismissed within the last 24h.\n",
|
|
120
|
-
"tags": [
|
|
121
|
-
"Challenges"
|
|
122
|
-
],
|
|
123
|
-
"parameters": [
|
|
124
|
-
{
|
|
125
|
-
"name": "route",
|
|
126
|
-
"in": "query",
|
|
127
|
-
"required": false,
|
|
128
|
-
"schema": {
|
|
129
|
-
"type": "string"
|
|
130
|
-
},
|
|
131
|
-
"description": "Current frontend route (page context for suggestion selection)."
|
|
132
|
-
},
|
|
133
|
-
{
|
|
134
|
-
"name": "entity_type",
|
|
135
|
-
"in": "query",
|
|
136
|
-
"required": false,
|
|
137
|
-
"schema": {
|
|
138
|
-
"type": "string"
|
|
139
|
-
},
|
|
140
|
-
"description": "Entity type currently in view (e.g. contact, opportunity)."
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
"name": "category_hint",
|
|
144
|
-
"in": "query",
|
|
145
|
-
"required": false,
|
|
146
|
-
"schema": {
|
|
147
|
-
"type": "string"
|
|
148
|
-
},
|
|
149
|
-
"description": "Caller hint for preferred challenge category."
|
|
150
|
-
}
|
|
151
|
-
],
|
|
152
|
-
"responses": {
|
|
153
|
-
"200": {
|
|
154
|
-
"description": "Suggested challenge for the authenticated user.",
|
|
155
|
-
"content": {
|
|
156
|
-
"application/json": {
|
|
157
|
-
"schema": {
|
|
158
|
-
"$ref": "#/components/schemas/ChallengeSuggested"
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
},
|
|
163
|
-
"204": {
|
|
164
|
-
"description": "No suitable challenge available (all candidates dismissed within 24h)."
|
|
165
|
-
},
|
|
166
|
-
"401": {
|
|
167
|
-
"$ref": "#/components/responses/Unauthorized"
|
|
168
|
-
},
|
|
169
|
-
"500": {
|
|
170
|
-
"description": "Internal server error.",
|
|
171
|
-
"content": {
|
|
172
|
-
"application/json": {
|
|
173
|
-
"schema": {
|
|
174
|
-
"$ref": "#/components/schemas/ErrorResponse"
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
},
|
|
182
|
-
"/v1/challenges/{id}/accept": {
|
|
183
|
-
"post": {
|
|
184
|
-
"operationId": "acceptChallenge",
|
|
185
|
-
"summary": "acceptChallenge",
|
|
186
|
-
"description": "Accept a suggested challenge. Atomically transitions the challenge from\n`suggested` to `active` using a conditional DynamoDB UpdateItem. Returns 409 if\nthe challenge has already been transitioned or the user already has\nMAX_ACTIVE_CHALLENGES (3) active challenges.\n",
|
|
187
|
-
"tags": [
|
|
188
|
-
"Challenges"
|
|
189
|
-
],
|
|
190
|
-
"parameters": [
|
|
191
|
-
{
|
|
192
|
-
"$ref": "#/components/parameters/ChallengeId"
|
|
193
|
-
}
|
|
194
|
-
],
|
|
195
|
-
"responses": {
|
|
196
|
-
"200": {
|
|
197
|
-
"description": "Challenge accepted and now active.",
|
|
198
|
-
"content": {
|
|
199
|
-
"application/json": {
|
|
200
|
-
"schema": {
|
|
201
|
-
"$ref": "#/components/schemas/ChallengeActive"
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
},
|
|
206
|
-
"401": {
|
|
207
|
-
"$ref": "#/components/responses/Unauthorized"
|
|
208
|
-
},
|
|
209
|
-
"404": {
|
|
210
|
-
"$ref": "#/components/responses/NotFound"
|
|
211
|
-
},
|
|
212
|
-
"409": {
|
|
213
|
-
"$ref": "#/components/responses/Conflict"
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
},
|
|
218
|
-
"/v1/challenges/{id}/dismiss": {
|
|
219
|
-
"post": {
|
|
220
|
-
"operationId": "dismissChallenge",
|
|
221
|
-
"summary": "dismissChallenge",
|
|
222
|
-
"description": "Dismiss a suggested challenge. Atomically transitions the challenge from\n`suggested` to `dismissed`. The challenge template is filtered from `/suggest`\nresponses for the next 24h. Returns 409 if the challenge has already been\ntransitioned (e.g. already accepted or dismissed).\n",
|
|
223
|
-
"tags": [
|
|
224
|
-
"Challenges"
|
|
225
|
-
],
|
|
226
|
-
"parameters": [
|
|
227
|
-
{
|
|
228
|
-
"$ref": "#/components/parameters/ChallengeId"
|
|
229
|
-
}
|
|
230
|
-
],
|
|
231
|
-
"responses": {
|
|
232
|
-
"204": {
|
|
233
|
-
"description": "Challenge dismissed."
|
|
234
|
-
},
|
|
235
|
-
"401": {
|
|
236
|
-
"$ref": "#/components/responses/Unauthorized"
|
|
237
|
-
},
|
|
238
|
-
"404": {
|
|
239
|
-
"$ref": "#/components/responses/NotFound"
|
|
240
|
-
},
|
|
241
|
-
"409": {
|
|
242
|
-
"$ref": "#/components/responses/Conflict"
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
},
|
|
247
|
-
"/v1/challenges/active": {
|
|
248
|
-
"get": {
|
|
249
|
-
"operationId": "listActiveChallenges",
|
|
250
|
-
"summary": "listActiveChallenges",
|
|
251
|
-
"description": "Returns all active challenges for the authenticated user. Challenges whose\ndeadline has passed are lazily expired (fire-and-forget UpdateItem) and\nexcluded from the response. The result set is bounded by MAX_ACTIVE_CHALLENGES=3.\n",
|
|
252
|
-
"tags": [
|
|
253
|
-
"Challenges"
|
|
254
|
-
],
|
|
255
|
-
"responses": {
|
|
256
|
-
"200": {
|
|
257
|
-
"description": "Active challenges for the authenticated user.",
|
|
258
|
-
"content": {
|
|
259
|
-
"application/json": {
|
|
260
|
-
"schema": {
|
|
261
|
-
"$ref": "#/components/schemas/ActiveChallengeListResponse"
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
},
|
|
266
|
-
"401": {
|
|
267
|
-
"$ref": "#/components/responses/Unauthorized"
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
},
|
|
272
|
-
"/v1/events": {
|
|
273
|
-
"post": {
|
|
274
|
-
"operationId": "postEvent",
|
|
275
|
-
"summary": "postEvent",
|
|
276
|
-
"description": "Persist-first event ingest. Accepts an activity event, writes it to the event log\nidempotently (keyed by `event_id`), and returns 202. Achievement evaluation happens\nasynchronously — no unlocks are returned in the response.\n",
|
|
277
|
-
"tags": [
|
|
278
|
-
"Events"
|
|
279
|
-
],
|
|
280
|
-
"requestBody": {
|
|
281
|
-
"required": true,
|
|
282
|
-
"content": {
|
|
283
|
-
"application/json": {
|
|
284
|
-
"schema": {
|
|
285
|
-
"$ref": "#/components/schemas/EventIngestRequest"
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
},
|
|
290
|
-
"responses": {
|
|
291
|
-
"202": {
|
|
292
|
-
"description": "Event accepted for async evaluation.",
|
|
293
|
-
"content": {
|
|
294
|
-
"application/json": {
|
|
295
|
-
"schema": {
|
|
296
|
-
"$ref": "#/components/schemas/EventAccepted"
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
},
|
|
301
|
-
"400": {
|
|
302
|
-
"$ref": "#/components/responses/BadRequest"
|
|
303
|
-
},
|
|
304
|
-
"401": {
|
|
305
|
-
"$ref": "#/components/responses/Unauthorized"
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
},
|
|
311
|
-
"components": {
|
|
312
|
-
"securitySchemes": {
|
|
313
|
-
"EpilotAuth": {
|
|
314
|
-
"type": "http",
|
|
315
|
-
"scheme": "bearer",
|
|
316
|
-
"bearerFormat": "JWT",
|
|
317
|
-
"description": "epilot JWT bearer token issued by the platform Lambda authorizer."
|
|
318
|
-
}
|
|
319
|
-
},
|
|
320
|
-
"parameters": {
|
|
321
|
-
"AchievementId": {
|
|
322
|
-
"name": "id",
|
|
323
|
-
"in": "path",
|
|
324
|
-
"required": true,
|
|
325
|
-
"schema": {
|
|
326
|
-
"type": "string",
|
|
327
|
-
"pattern": "^[a-z0-9][a-z0-9_-]{0,127}$"
|
|
328
|
-
}
|
|
329
|
-
},
|
|
330
|
-
"AchievementOrChallengeId": {
|
|
331
|
-
"name": "id",
|
|
332
|
-
"in": "path",
|
|
333
|
-
"required": true,
|
|
334
|
-
"schema": {
|
|
335
|
-
"type": "string",
|
|
336
|
-
"minLength": 1,
|
|
337
|
-
"maxLength": 128
|
|
338
|
-
},
|
|
339
|
-
"description": "Achievement id (lowercase slug) or challenge UUID. Accepts both formats because\nchallenge ids are UUIDs (uppercase hex) which the AchievementId slug pattern rejects.\n"
|
|
340
|
-
},
|
|
341
|
-
"ChallengeId": {
|
|
342
|
-
"name": "id",
|
|
343
|
-
"in": "path",
|
|
344
|
-
"required": true,
|
|
345
|
-
"schema": {
|
|
346
|
-
"type": "string",
|
|
347
|
-
"minLength": 1,
|
|
348
|
-
"maxLength": 128
|
|
349
|
-
},
|
|
350
|
-
"description": "Challenge UUID."
|
|
351
|
-
},
|
|
352
|
-
"Cursor": {
|
|
353
|
-
"name": "cursor",
|
|
354
|
-
"in": "query",
|
|
355
|
-
"required": false,
|
|
356
|
-
"schema": {
|
|
357
|
-
"type": "string"
|
|
358
|
-
}
|
|
359
|
-
},
|
|
360
|
-
"Size": {
|
|
361
|
-
"name": "size",
|
|
362
|
-
"in": "query",
|
|
363
|
-
"required": false,
|
|
364
|
-
"schema": {
|
|
365
|
-
"type": "integer",
|
|
366
|
-
"minimum": 1,
|
|
367
|
-
"maximum": 100,
|
|
368
|
-
"default": 20
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
},
|
|
372
|
-
"responses": {
|
|
373
|
-
"Unauthorized": {
|
|
374
|
-
"description": "Missing or invalid authentication.",
|
|
375
|
-
"content": {
|
|
376
|
-
"application/json": {
|
|
377
|
-
"schema": {
|
|
378
|
-
"$ref": "#/components/schemas/ErrorResponse"
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
},
|
|
383
|
-
"NotFound": {
|
|
384
|
-
"description": "Resource not found.",
|
|
385
|
-
"content": {
|
|
386
|
-
"application/json": {
|
|
387
|
-
"schema": {
|
|
388
|
-
"$ref": "#/components/schemas/ErrorResponse"
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
},
|
|
393
|
-
"BadRequest": {
|
|
394
|
-
"description": "Request validation failed.",
|
|
395
|
-
"content": {
|
|
396
|
-
"application/json": {
|
|
397
|
-
"schema": {
|
|
398
|
-
"$ref": "#/components/schemas/ErrorResponse"
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
},
|
|
403
|
-
"Conflict": {
|
|
404
|
-
"description": "Transition not allowed in current challenge state.",
|
|
405
|
-
"content": {
|
|
406
|
-
"application/json": {
|
|
407
|
-
"schema": {
|
|
408
|
-
"$ref": "#/components/schemas/ConflictError"
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
},
|
|
414
|
-
"schemas": {
|
|
415
|
-
"HealthResponse": {
|
|
416
|
-
"type": "object",
|
|
417
|
-
"required": [
|
|
418
|
-
"status",
|
|
419
|
-
"stage",
|
|
420
|
-
"service"
|
|
421
|
-
],
|
|
422
|
-
"properties": {
|
|
423
|
-
"status": {
|
|
424
|
-
"type": "string",
|
|
425
|
-
"enum": [
|
|
426
|
-
"ok"
|
|
427
|
-
]
|
|
428
|
-
},
|
|
429
|
-
"stage": {
|
|
430
|
-
"type": "string",
|
|
431
|
-
"example": "dev"
|
|
432
|
-
},
|
|
433
|
-
"service": {
|
|
434
|
-
"type": "string",
|
|
435
|
-
"example": "focus-pocus-api"
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
},
|
|
439
|
-
"ErrorResponse": {
|
|
440
|
-
"type": "object",
|
|
441
|
-
"required": [
|
|
442
|
-
"status",
|
|
443
|
-
"error"
|
|
444
|
-
],
|
|
445
|
-
"properties": {
|
|
446
|
-
"status": {
|
|
447
|
-
"type": "integer",
|
|
448
|
-
"format": "int32"
|
|
449
|
-
},
|
|
450
|
-
"error": {
|
|
451
|
-
"type": "string"
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
},
|
|
455
|
-
"ConflictError": {
|
|
456
|
-
"type": "object",
|
|
457
|
-
"required": [
|
|
458
|
-
"status",
|
|
459
|
-
"error",
|
|
460
|
-
"reason"
|
|
461
|
-
],
|
|
462
|
-
"properties": {
|
|
463
|
-
"status": {
|
|
464
|
-
"type": "integer",
|
|
465
|
-
"enum": [
|
|
466
|
-
409
|
|
467
|
-
]
|
|
468
|
-
},
|
|
469
|
-
"error": {
|
|
470
|
-
"type": "string"
|
|
471
|
-
},
|
|
472
|
-
"reason": {
|
|
473
|
-
"type": "string",
|
|
474
|
-
"enum": [
|
|
475
|
-
"already_transitioned",
|
|
476
|
-
"too_many_active",
|
|
477
|
-
"deadline_passed"
|
|
478
|
-
]
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
},
|
|
482
|
-
"ChallengeSuggested": {
|
|
483
|
-
"type": "object",
|
|
484
|
-
"required": [
|
|
485
|
-
"id",
|
|
486
|
-
"challenge_template_id",
|
|
487
|
-
"category",
|
|
488
|
-
"title",
|
|
489
|
-
"description",
|
|
490
|
-
"badge_image_url",
|
|
491
|
-
"default_duration_hours",
|
|
492
|
-
"status",
|
|
493
|
-
"suggested_at"
|
|
494
|
-
],
|
|
495
|
-
"properties": {
|
|
496
|
-
"id": {
|
|
497
|
-
"type": "string",
|
|
498
|
-
"description": "Unique suggestion-instance id (UUID)."
|
|
499
|
-
},
|
|
500
|
-
"challenge_template_id": {
|
|
501
|
-
"type": "string",
|
|
502
|
-
"description": "FK to the challenge template."
|
|
503
|
-
},
|
|
504
|
-
"category": {
|
|
505
|
-
"type": "string",
|
|
506
|
-
"description": "Open string category propagated from the template."
|
|
507
|
-
},
|
|
508
|
-
"title": {
|
|
509
|
-
"type": "string"
|
|
510
|
-
},
|
|
511
|
-
"description": {
|
|
512
|
-
"type": "string"
|
|
513
|
-
},
|
|
514
|
-
"badge_image_url": {
|
|
515
|
-
"type": "string"
|
|
516
|
-
},
|
|
517
|
-
"default_duration_hours": {
|
|
518
|
-
"type": "integer",
|
|
519
|
-
"minimum": 1,
|
|
520
|
-
"description": "How many hours the user has to complete the challenge once accepted."
|
|
521
|
-
},
|
|
522
|
-
"status": {
|
|
523
|
-
"type": "string",
|
|
524
|
-
"enum": [
|
|
525
|
-
"suggested"
|
|
526
|
-
]
|
|
527
|
-
},
|
|
528
|
-
"suggested_at": {
|
|
529
|
-
"type": "string",
|
|
530
|
-
"format": "date-time"
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
},
|
|
534
|
-
"ChallengeActive": {
|
|
535
|
-
"type": "object",
|
|
536
|
-
"required": [
|
|
537
|
-
"id",
|
|
538
|
-
"challenge_template_id",
|
|
539
|
-
"category",
|
|
540
|
-
"title",
|
|
541
|
-
"description",
|
|
542
|
-
"badge_image_url",
|
|
543
|
-
"status",
|
|
544
|
-
"accepted_at",
|
|
545
|
-
"deadline",
|
|
546
|
-
"time_remaining_ms"
|
|
547
|
-
],
|
|
548
|
-
"properties": {
|
|
549
|
-
"id": {
|
|
550
|
-
"type": "string",
|
|
551
|
-
"description": "Unique challenge-instance id (UUID)."
|
|
552
|
-
},
|
|
553
|
-
"challenge_template_id": {
|
|
554
|
-
"type": "string"
|
|
555
|
-
},
|
|
556
|
-
"category": {
|
|
557
|
-
"type": "string"
|
|
558
|
-
},
|
|
559
|
-
"title": {
|
|
560
|
-
"type": "string"
|
|
561
|
-
},
|
|
562
|
-
"description": {
|
|
563
|
-
"type": "string"
|
|
564
|
-
},
|
|
565
|
-
"badge_image_url": {
|
|
566
|
-
"type": "string"
|
|
567
|
-
},
|
|
568
|
-
"status": {
|
|
569
|
-
"type": "string",
|
|
570
|
-
"enum": [
|
|
571
|
-
"active"
|
|
572
|
-
]
|
|
573
|
-
},
|
|
574
|
-
"accepted_at": {
|
|
575
|
-
"type": "string",
|
|
576
|
-
"format": "date-time"
|
|
577
|
-
},
|
|
578
|
-
"deadline": {
|
|
579
|
-
"type": "string",
|
|
580
|
-
"format": "date-time"
|
|
581
|
-
},
|
|
582
|
-
"time_remaining_ms": {
|
|
583
|
-
"type": "integer",
|
|
584
|
-
"minimum": 0,
|
|
585
|
-
"description": "Milliseconds remaining until the deadline (clamped to >= 0)."
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
},
|
|
589
|
-
"ActiveChallengeListResponse": {
|
|
590
|
-
"type": "object",
|
|
591
|
-
"required": [
|
|
592
|
-
"results",
|
|
593
|
-
"total"
|
|
594
|
-
],
|
|
595
|
-
"properties": {
|
|
596
|
-
"results": {
|
|
597
|
-
"type": "array",
|
|
598
|
-
"items": {
|
|
599
|
-
"$ref": "#/components/schemas/ChallengeActive"
|
|
600
|
-
}
|
|
601
|
-
},
|
|
602
|
-
"total": {
|
|
603
|
-
"type": "integer",
|
|
604
|
-
"minimum": 0
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
},
|
|
608
|
-
"AchievementFeedItem": {
|
|
609
|
-
"type": "object",
|
|
610
|
-
"required": [
|
|
611
|
-
"id",
|
|
612
|
-
"category",
|
|
613
|
-
"title",
|
|
614
|
-
"description",
|
|
615
|
-
"status",
|
|
616
|
-
"just_unlocked"
|
|
617
|
-
],
|
|
618
|
-
"properties": {
|
|
619
|
-
"id": {
|
|
620
|
-
"type": "string"
|
|
621
|
-
},
|
|
622
|
-
"challenge_template_id": {
|
|
623
|
-
"type": "string",
|
|
624
|
-
"nullable": true,
|
|
625
|
-
"description": "Set for challenge-based items; null for v1 static catalog unlocks."
|
|
626
|
-
},
|
|
627
|
-
"category": {
|
|
628
|
-
"type": "string"
|
|
629
|
-
},
|
|
630
|
-
"title": {
|
|
631
|
-
"type": "string"
|
|
632
|
-
},
|
|
633
|
-
"description": {
|
|
634
|
-
"type": "string"
|
|
635
|
-
},
|
|
636
|
-
"badge_image_url": {
|
|
637
|
-
"type": "string",
|
|
638
|
-
"nullable": true
|
|
639
|
-
},
|
|
640
|
-
"icon": {
|
|
641
|
-
"type": "string",
|
|
642
|
-
"nullable": true,
|
|
643
|
-
"description": "Kept for v1 catalog unlock compatibility."
|
|
644
|
-
},
|
|
645
|
-
"status": {
|
|
646
|
-
"type": "string",
|
|
647
|
-
"enum": [
|
|
648
|
-
"active",
|
|
649
|
-
"completed",
|
|
650
|
-
"expired"
|
|
651
|
-
]
|
|
652
|
-
},
|
|
653
|
-
"accepted_at": {
|
|
654
|
-
"type": "string",
|
|
655
|
-
"format": "date-time",
|
|
656
|
-
"nullable": true
|
|
657
|
-
},
|
|
658
|
-
"deadline": {
|
|
659
|
-
"type": "string",
|
|
660
|
-
"format": "date-time",
|
|
661
|
-
"nullable": true
|
|
662
|
-
},
|
|
663
|
-
"time_remaining_ms": {
|
|
664
|
-
"type": "integer",
|
|
665
|
-
"minimum": 0,
|
|
666
|
-
"nullable": true,
|
|
667
|
-
"description": "Milliseconds remaining until the deadline; null for non-active items."
|
|
668
|
-
},
|
|
669
|
-
"unlocked_at": {
|
|
670
|
-
"type": "string",
|
|
671
|
-
"format": "date-time",
|
|
672
|
-
"nullable": true,
|
|
673
|
-
"description": "When the achievement was unlocked; null for active challenges."
|
|
674
|
-
},
|
|
675
|
-
"xp_awarded": {
|
|
676
|
-
"type": "integer",
|
|
677
|
-
"minimum": 0,
|
|
678
|
-
"nullable": true,
|
|
679
|
-
"description": "XP awarded on unlock; null for active challenges."
|
|
680
|
-
},
|
|
681
|
-
"just_unlocked": {
|
|
682
|
-
"type": "boolean",
|
|
683
|
-
"description": "True if the item was completed within the last 60 seconds."
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
},
|
|
687
|
-
"AchievementFeedListResponse": {
|
|
688
|
-
"type": "object",
|
|
689
|
-
"required": [
|
|
690
|
-
"results",
|
|
691
|
-
"total"
|
|
692
|
-
],
|
|
693
|
-
"properties": {
|
|
694
|
-
"results": {
|
|
695
|
-
"type": "array",
|
|
696
|
-
"items": {
|
|
697
|
-
"$ref": "#/components/schemas/AchievementFeedItem"
|
|
698
|
-
}
|
|
699
|
-
},
|
|
700
|
-
"total": {
|
|
701
|
-
"type": "integer",
|
|
702
|
-
"minimum": 0
|
|
703
|
-
}
|
|
704
|
-
}
|
|
705
|
-
},
|
|
706
|
-
"EventIngestRequest": {
|
|
707
|
-
"type": "object",
|
|
708
|
-
"required": [
|
|
709
|
-
"event_id",
|
|
710
|
-
"event_type",
|
|
711
|
-
"actor_user_id",
|
|
712
|
-
"occurred_at"
|
|
713
|
-
],
|
|
714
|
-
"properties": {
|
|
715
|
-
"event_id": {
|
|
716
|
-
"type": "string",
|
|
717
|
-
"minLength": 1,
|
|
718
|
-
"maxLength": 256,
|
|
719
|
-
"description": "Idempotency key — same id is rejected (already-accepted) on retry."
|
|
720
|
-
},
|
|
721
|
-
"event_type": {
|
|
722
|
-
"type": "string",
|
|
723
|
-
"minLength": 1,
|
|
724
|
-
"maxLength": 128
|
|
725
|
-
},
|
|
726
|
-
"actor_user_id": {
|
|
727
|
-
"type": "string",
|
|
728
|
-
"minLength": 1,
|
|
729
|
-
"maxLength": 128
|
|
730
|
-
},
|
|
731
|
-
"occurred_at": {
|
|
732
|
-
"type": "string",
|
|
733
|
-
"format": "date-time"
|
|
734
|
-
},
|
|
735
|
-
"properties": {
|
|
736
|
-
"type": "object",
|
|
737
|
-
"additionalProperties": true
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
},
|
|
741
|
-
"EventAccepted": {
|
|
742
|
-
"type": "object",
|
|
743
|
-
"required": [
|
|
744
|
-
"accepted"
|
|
745
|
-
],
|
|
746
|
-
"properties": {
|
|
747
|
-
"accepted": {
|
|
748
|
-
"type": "boolean",
|
|
749
|
-
"enum": [
|
|
750
|
-
true
|
|
751
|
-
]
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
}
|