@contractspec/module.learning-journey 3.7.17 → 4.0.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/README.md +3 -2
- package/dist/browser/contracts/index.js +1 -1
- package/dist/browser/contracts/journey.js +1 -0
- package/dist/browser/contracts/operations.js +1 -1
- package/dist/browser/docs/index.js +13 -12
- package/dist/browser/docs/learning-journey.docblock.js +13 -12
- package/dist/browser/engines/index.js +1 -1
- package/dist/browser/engines/xp.js +1 -1
- package/dist/browser/entities/index.js +1 -1
- package/dist/browser/entities/journey.js +1 -0
- package/dist/browser/index.js +14 -13
- package/dist/browser/learning-journey.feature.js +1 -1
- package/dist/browser/runtime/index.js +1 -0
- package/dist/browser/runtime/matchers.js +1 -0
- package/dist/browser/runtime/progress-state.js +1 -0
- package/dist/browser/runtime/snapshot.js +1 -0
- package/dist/contracts/index.d.ts +1 -1
- package/dist/contracts/index.js +1 -1
- package/dist/contracts/{onboarding.d.ts → journey.d.ts} +477 -180
- package/dist/contracts/journey.js +2 -0
- package/dist/contracts/operations.js +1 -1
- package/dist/docs/index.js +13 -12
- package/dist/docs/learning-journey.docblock.js +13 -12
- package/dist/engines/index.js +1 -1
- package/dist/engines/xp.d.ts +1 -1
- package/dist/engines/xp.js +1 -1
- package/dist/entities/index.d.ts +28 -27
- package/dist/entities/index.js +1 -1
- package/dist/entities/{onboarding.d.ts → journey.d.ts} +61 -74
- package/dist/entities/journey.js +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +14 -13
- package/dist/learning-journey.feature.js +1 -1
- package/dist/node/contracts/index.js +1 -1
- package/dist/node/contracts/journey.js +1 -0
- package/dist/node/contracts/operations.js +1 -1
- package/dist/node/docs/index.js +13 -12
- package/dist/node/docs/learning-journey.docblock.js +13 -12
- package/dist/node/engines/index.js +1 -1
- package/dist/node/engines/xp.js +1 -1
- package/dist/node/entities/index.js +1 -1
- package/dist/node/entities/journey.js +1 -0
- package/dist/node/index.js +14 -13
- package/dist/node/learning-journey.feature.js +1 -1
- package/dist/node/runtime/index.js +1 -0
- package/dist/node/runtime/matchers.js +1 -0
- package/dist/node/runtime/progress-state.js +1 -0
- package/dist/node/runtime/snapshot.js +1 -0
- package/dist/runtime/index.d.ts +3 -0
- package/dist/runtime/index.js +2 -0
- package/dist/runtime/journey-runtime.test.d.ts +1 -0
- package/dist/runtime/matchers.d.ts +20 -0
- package/dist/runtime/matchers.js +2 -0
- package/dist/runtime/progress-state.d.ts +19 -0
- package/dist/runtime/progress-state.js +2 -0
- package/dist/runtime/snapshot.d.ts +8 -0
- package/dist/runtime/snapshot.js +2 -0
- package/dist/track-spec.d.ts +118 -87
- package/package.json +86 -30
- package/dist/browser/contracts/onboarding.js +0 -1
- package/dist/browser/entities/onboarding.js +0 -1
- package/dist/contracts/onboarding.js +0 -2
- package/dist/entities/onboarding.js +0 -2
- package/dist/node/contracts/onboarding.js +0 -1
- package/dist/node/entities/onboarding.js +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contractspec/module.learning-journey",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Comprehensive learning journey engine - onboarding, LMS, flashcards, gamification, and AI personalization",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"contractspec",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@contractspec/lib.schema": "3.7.14",
|
|
32
|
-
"@contractspec/lib.contracts-spec": "5.
|
|
32
|
+
"@contractspec/lib.contracts-spec": "5.4.0",
|
|
33
33
|
"zod": "^4.3.5"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
@@ -52,6 +52,13 @@
|
|
|
52
52
|
"node": "./dist/node/contracts/index.js",
|
|
53
53
|
"default": "./dist/contracts/index.js"
|
|
54
54
|
},
|
|
55
|
+
"./contracts/journey": {
|
|
56
|
+
"types": "./dist/contracts/journey.d.ts",
|
|
57
|
+
"browser": "./dist/browser/contracts/journey.js",
|
|
58
|
+
"bun": "./dist/contracts/journey.js",
|
|
59
|
+
"node": "./dist/node/contracts/journey.js",
|
|
60
|
+
"default": "./dist/contracts/journey.js"
|
|
61
|
+
},
|
|
55
62
|
"./contracts/models": {
|
|
56
63
|
"types": "./dist/contracts/models.d.ts",
|
|
57
64
|
"browser": "./dist/browser/contracts/models.js",
|
|
@@ -59,13 +66,6 @@
|
|
|
59
66
|
"node": "./dist/node/contracts/models.js",
|
|
60
67
|
"default": "./dist/contracts/models.js"
|
|
61
68
|
},
|
|
62
|
-
"./contracts/onboarding": {
|
|
63
|
-
"types": "./dist/contracts/onboarding.d.ts",
|
|
64
|
-
"browser": "./dist/browser/contracts/onboarding.js",
|
|
65
|
-
"bun": "./dist/contracts/onboarding.js",
|
|
66
|
-
"node": "./dist/node/contracts/onboarding.js",
|
|
67
|
-
"default": "./dist/contracts/onboarding.js"
|
|
68
|
-
},
|
|
69
69
|
"./contracts/operations": {
|
|
70
70
|
"types": "./dist/contracts/operations.d.ts",
|
|
71
71
|
"browser": "./dist/browser/contracts/operations.js",
|
|
@@ -157,6 +157,13 @@
|
|
|
157
157
|
"node": "./dist/node/entities/gamification.js",
|
|
158
158
|
"default": "./dist/entities/gamification.js"
|
|
159
159
|
},
|
|
160
|
+
"./entities/journey": {
|
|
161
|
+
"types": "./dist/entities/journey.d.ts",
|
|
162
|
+
"browser": "./dist/browser/entities/journey.js",
|
|
163
|
+
"bun": "./dist/entities/journey.js",
|
|
164
|
+
"node": "./dist/node/entities/journey.js",
|
|
165
|
+
"default": "./dist/entities/journey.js"
|
|
166
|
+
},
|
|
160
167
|
"./entities/learner": {
|
|
161
168
|
"types": "./dist/entities/learner.d.ts",
|
|
162
169
|
"browser": "./dist/browser/entities/learner.js",
|
|
@@ -164,13 +171,6 @@
|
|
|
164
171
|
"node": "./dist/node/entities/learner.js",
|
|
165
172
|
"default": "./dist/entities/learner.js"
|
|
166
173
|
},
|
|
167
|
-
"./entities/onboarding": {
|
|
168
|
-
"types": "./dist/entities/onboarding.d.ts",
|
|
169
|
-
"browser": "./dist/browser/entities/onboarding.js",
|
|
170
|
-
"bun": "./dist/entities/onboarding.js",
|
|
171
|
-
"node": "./dist/node/entities/onboarding.js",
|
|
172
|
-
"default": "./dist/entities/onboarding.js"
|
|
173
|
-
},
|
|
174
174
|
"./entities/quiz": {
|
|
175
175
|
"types": "./dist/entities/quiz.d.ts",
|
|
176
176
|
"browser": "./dist/browser/entities/quiz.js",
|
|
@@ -255,6 +255,34 @@
|
|
|
255
255
|
"node": "./dist/node/learning-journey.feature.js",
|
|
256
256
|
"default": "./dist/learning-journey.feature.js"
|
|
257
257
|
},
|
|
258
|
+
"./runtime": {
|
|
259
|
+
"types": "./dist/runtime/index.d.ts",
|
|
260
|
+
"browser": "./dist/browser/runtime/index.js",
|
|
261
|
+
"bun": "./dist/runtime/index.js",
|
|
262
|
+
"node": "./dist/node/runtime/index.js",
|
|
263
|
+
"default": "./dist/runtime/index.js"
|
|
264
|
+
},
|
|
265
|
+
"./runtime/matchers": {
|
|
266
|
+
"types": "./dist/runtime/matchers.d.ts",
|
|
267
|
+
"browser": "./dist/browser/runtime/matchers.js",
|
|
268
|
+
"bun": "./dist/runtime/matchers.js",
|
|
269
|
+
"node": "./dist/node/runtime/matchers.js",
|
|
270
|
+
"default": "./dist/runtime/matchers.js"
|
|
271
|
+
},
|
|
272
|
+
"./runtime/progress-state": {
|
|
273
|
+
"types": "./dist/runtime/progress-state.d.ts",
|
|
274
|
+
"browser": "./dist/browser/runtime/progress-state.js",
|
|
275
|
+
"bun": "./dist/runtime/progress-state.js",
|
|
276
|
+
"node": "./dist/node/runtime/progress-state.js",
|
|
277
|
+
"default": "./dist/runtime/progress-state.js"
|
|
278
|
+
},
|
|
279
|
+
"./runtime/snapshot": {
|
|
280
|
+
"types": "./dist/runtime/snapshot.d.ts",
|
|
281
|
+
"browser": "./dist/browser/runtime/snapshot.js",
|
|
282
|
+
"bun": "./dist/runtime/snapshot.js",
|
|
283
|
+
"node": "./dist/node/runtime/snapshot.js",
|
|
284
|
+
"default": "./dist/runtime/snapshot.js"
|
|
285
|
+
},
|
|
258
286
|
"./track-spec": {
|
|
259
287
|
"types": "./dist/track-spec.d.ts",
|
|
260
288
|
"browser": "./dist/browser/track-spec.js",
|
|
@@ -284,6 +312,13 @@
|
|
|
284
312
|
"node": "./dist/node/contracts/index.js",
|
|
285
313
|
"default": "./dist/contracts/index.js"
|
|
286
314
|
},
|
|
315
|
+
"./contracts/journey": {
|
|
316
|
+
"types": "./dist/contracts/journey.d.ts",
|
|
317
|
+
"browser": "./dist/browser/contracts/journey.js",
|
|
318
|
+
"bun": "./dist/contracts/journey.js",
|
|
319
|
+
"node": "./dist/node/contracts/journey.js",
|
|
320
|
+
"default": "./dist/contracts/journey.js"
|
|
321
|
+
},
|
|
287
322
|
"./contracts/models": {
|
|
288
323
|
"types": "./dist/contracts/models.d.ts",
|
|
289
324
|
"browser": "./dist/browser/contracts/models.js",
|
|
@@ -291,13 +326,6 @@
|
|
|
291
326
|
"node": "./dist/node/contracts/models.js",
|
|
292
327
|
"default": "./dist/contracts/models.js"
|
|
293
328
|
},
|
|
294
|
-
"./contracts/onboarding": {
|
|
295
|
-
"types": "./dist/contracts/onboarding.d.ts",
|
|
296
|
-
"browser": "./dist/browser/contracts/onboarding.js",
|
|
297
|
-
"bun": "./dist/contracts/onboarding.js",
|
|
298
|
-
"node": "./dist/node/contracts/onboarding.js",
|
|
299
|
-
"default": "./dist/contracts/onboarding.js"
|
|
300
|
-
},
|
|
301
329
|
"./contracts/operations": {
|
|
302
330
|
"types": "./dist/contracts/operations.d.ts",
|
|
303
331
|
"browser": "./dist/browser/contracts/operations.js",
|
|
@@ -389,6 +417,13 @@
|
|
|
389
417
|
"node": "./dist/node/entities/gamification.js",
|
|
390
418
|
"default": "./dist/entities/gamification.js"
|
|
391
419
|
},
|
|
420
|
+
"./entities/journey": {
|
|
421
|
+
"types": "./dist/entities/journey.d.ts",
|
|
422
|
+
"browser": "./dist/browser/entities/journey.js",
|
|
423
|
+
"bun": "./dist/entities/journey.js",
|
|
424
|
+
"node": "./dist/node/entities/journey.js",
|
|
425
|
+
"default": "./dist/entities/journey.js"
|
|
426
|
+
},
|
|
392
427
|
"./entities/learner": {
|
|
393
428
|
"types": "./dist/entities/learner.d.ts",
|
|
394
429
|
"browser": "./dist/browser/entities/learner.js",
|
|
@@ -396,13 +431,6 @@
|
|
|
396
431
|
"node": "./dist/node/entities/learner.js",
|
|
397
432
|
"default": "./dist/entities/learner.js"
|
|
398
433
|
},
|
|
399
|
-
"./entities/onboarding": {
|
|
400
|
-
"types": "./dist/entities/onboarding.d.ts",
|
|
401
|
-
"browser": "./dist/browser/entities/onboarding.js",
|
|
402
|
-
"bun": "./dist/entities/onboarding.js",
|
|
403
|
-
"node": "./dist/node/entities/onboarding.js",
|
|
404
|
-
"default": "./dist/entities/onboarding.js"
|
|
405
|
-
},
|
|
406
434
|
"./entities/quiz": {
|
|
407
435
|
"types": "./dist/entities/quiz.d.ts",
|
|
408
436
|
"browser": "./dist/browser/entities/quiz.js",
|
|
@@ -487,6 +515,34 @@
|
|
|
487
515
|
"node": "./dist/node/learning-journey.feature.js",
|
|
488
516
|
"default": "./dist/learning-journey.feature.js"
|
|
489
517
|
},
|
|
518
|
+
"./runtime": {
|
|
519
|
+
"types": "./dist/runtime/index.d.ts",
|
|
520
|
+
"browser": "./dist/browser/runtime/index.js",
|
|
521
|
+
"bun": "./dist/runtime/index.js",
|
|
522
|
+
"node": "./dist/node/runtime/index.js",
|
|
523
|
+
"default": "./dist/runtime/index.js"
|
|
524
|
+
},
|
|
525
|
+
"./runtime/matchers": {
|
|
526
|
+
"types": "./dist/runtime/matchers.d.ts",
|
|
527
|
+
"browser": "./dist/browser/runtime/matchers.js",
|
|
528
|
+
"bun": "./dist/runtime/matchers.js",
|
|
529
|
+
"node": "./dist/node/runtime/matchers.js",
|
|
530
|
+
"default": "./dist/runtime/matchers.js"
|
|
531
|
+
},
|
|
532
|
+
"./runtime/progress-state": {
|
|
533
|
+
"types": "./dist/runtime/progress-state.d.ts",
|
|
534
|
+
"browser": "./dist/browser/runtime/progress-state.js",
|
|
535
|
+
"bun": "./dist/runtime/progress-state.js",
|
|
536
|
+
"node": "./dist/node/runtime/progress-state.js",
|
|
537
|
+
"default": "./dist/runtime/progress-state.js"
|
|
538
|
+
},
|
|
539
|
+
"./runtime/snapshot": {
|
|
540
|
+
"types": "./dist/runtime/snapshot.d.ts",
|
|
541
|
+
"browser": "./dist/browser/runtime/snapshot.js",
|
|
542
|
+
"bun": "./dist/runtime/snapshot.js",
|
|
543
|
+
"node": "./dist/node/runtime/snapshot.js",
|
|
544
|
+
"default": "./dist/runtime/snapshot.js"
|
|
545
|
+
},
|
|
490
546
|
"./track-spec": {
|
|
491
547
|
"types": "./dist/track-spec.d.ts",
|
|
492
548
|
"browser": "./dist/browser/track-spec.js",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{defineSchemaModel as s,ScalarTypeEnum as e}from"@contractspec/lib.schema";var C=s({name:"Course",description:"A learning course",fields:{id:{type:e.String_unsecure(),isOptional:!1},title:{type:e.String_unsecure(),isOptional:!1},slug:{type:e.String_unsecure(),isOptional:!1},description:{type:e.String_unsecure(),isOptional:!0},difficulty:{type:e.String_unsecure(),isOptional:!1},status:{type:e.String_unsecure(),isOptional:!1},estimatedDuration:{type:e.Int_unsecure(),isOptional:!0},thumbnailUrl:{type:e.String_unsecure(),isOptional:!0},createdAt:{type:e.DateTime(),isOptional:!1}}}),u=s({name:"Learner",description:"A learner profile",fields:{id:{type:e.String_unsecure(),isOptional:!1},userId:{type:e.String_unsecure(),isOptional:!1},displayName:{type:e.String_unsecure(),isOptional:!0},level:{type:e.Int_unsecure(),isOptional:!1},totalXp:{type:e.Int_unsecure(),isOptional:!1},currentStreak:{type:e.Int_unsecure(),isOptional:!1},longestStreak:{type:e.Int_unsecure(),isOptional:!1},createdAt:{type:e.DateTime(),isOptional:!1}}}),l=s({name:"Enrollment",description:"A course enrollment",fields:{id:{type:e.String_unsecure(),isOptional:!1},learnerId:{type:e.String_unsecure(),isOptional:!1},courseId:{type:e.String_unsecure(),isOptional:!1},status:{type:e.String_unsecure(),isOptional:!1},progress:{type:e.Int_unsecure(),isOptional:!1},startedAt:{type:e.DateTime(),isOptional:!0},completedAt:{type:e.DateTime(),isOptional:!0}}}),v=s({name:"LessonProgress",description:"Lesson progress",fields:{id:{type:e.String_unsecure(),isOptional:!1},learnerId:{type:e.String_unsecure(),isOptional:!1},lessonId:{type:e.String_unsecure(),isOptional:!1},status:{type:e.String_unsecure(),isOptional:!1},progress:{type:e.Int_unsecure(),isOptional:!1},score:{type:e.Int_unsecure(),isOptional:!0},timeSpent:{type:e.Int_unsecure(),isOptional:!1},completedAt:{type:e.DateTime(),isOptional:!0}}}),k=s({name:"Deck",description:"A flashcard deck",fields:{id:{type:e.String_unsecure(),isOptional:!1},title:{type:e.String_unsecure(),isOptional:!1},description:{type:e.String_unsecure(),isOptional:!0},cardCount:{type:e.Int_unsecure(),isOptional:!1},isPublic:{type:e.Boolean(),isOptional:!1},createdAt:{type:e.DateTime(),isOptional:!1}}}),a=s({name:"Card",description:"A flashcard",fields:{id:{type:e.String_unsecure(),isOptional:!1},deckId:{type:e.String_unsecure(),isOptional:!1},front:{type:e.String_unsecure(),isOptional:!1},back:{type:e.String_unsecure(),isOptional:!1},hints:{type:e.JSON(),isOptional:!0},isDue:{type:e.Boolean(),isOptional:!1},nextReviewAt:{type:e.DateTime(),isOptional:!0}}}),f=s({name:"Achievement",description:"An achievement",fields:{id:{type:e.String_unsecure(),isOptional:!1},key:{type:e.String_unsecure(),isOptional:!1},name:{type:e.String_unsecure(),isOptional:!1},description:{type:e.String_unsecure(),isOptional:!1},icon:{type:e.String_unsecure(),isOptional:!0},xpReward:{type:e.Int_unsecure(),isOptional:!1},unlockedAt:{type:e.DateTime(),isOptional:!0}}}),L=s({name:"EnrollInCourseInput",description:"Input for enrolling in a course",fields:{courseId:{type:e.String_unsecure(),isOptional:!1}}}),w=s({name:"CompleteLessonInput",description:"Input for completing a lesson",fields:{lessonId:{type:e.String_unsecure(),isOptional:!1},score:{type:e.Int_unsecure(),isOptional:!0},timeSpent:{type:e.Int_unsecure(),isOptional:!1}}}),G=s({name:"SubmitCardReviewInput",description:"Input for submitting a card review",fields:{cardId:{type:e.String_unsecure(),isOptional:!1},rating:{type:e.String_unsecure(),isOptional:!1},responseTimeMs:{type:e.Int_unsecure(),isOptional:!0}}}),h=s({name:"GetDueCardsInput",description:"Input for getting due cards",fields:{deckId:{type:e.String_unsecure(),isOptional:!0},limit:{type:e.Int_unsecure(),isOptional:!0}}}),B=s({name:"GetDueCardsOutput",description:"Output for getting due cards",fields:{cards:{type:a,isArray:!0,isOptional:!1},total:{type:e.Int_unsecure(),isOptional:!1}}}),X=s({name:"GetLearnerDashboardInput",description:"Input for getting learner dashboard",fields:{learnerId:{type:e.String_unsecure(),isOptional:!0}}}),j=s({name:"LearnerDashboard",description:"Learner dashboard data",fields:{learner:{type:u,isOptional:!1},currentStreak:{type:e.Int_unsecure(),isOptional:!1},dailyXpGoal:{type:e.Int_unsecure(),isOptional:!1},dailyXpProgress:{type:e.Int_unsecure(),isOptional:!1},activeEnrollments:{type:l,isArray:!0,isOptional:!1},recentAchievements:{type:f,isArray:!0,isOptional:!1},dueCardCount:{type:e.Int_unsecure(),isOptional:!1}}}),r=s({name:"SuccessOutput",description:"Generic success output",fields:{success:{type:e.Boolean(),isOptional:!1},xpEarned:{type:e.Int_unsecure(),isOptional:!0}}});var n=["modules.learning-journey"];import{defineCommand as d,defineQuery as o}from"@contractspec/lib.contracts-spec";import{defineSchemaModel as i,ScalarTypeEnum as t}from"@contractspec/lib.schema";var O=i({name:"OnboardingStepCondition",description:"Structured completion condition for onboarding steps.",fields:{eventName:{type:t.String_unsecure(),isOptional:!1},eventVersion:{type:t.String_unsecure(),isOptional:!0},sourceModule:{type:t.String_unsecure(),isOptional:!0},payloadFilter:{type:t.JSON(),isOptional:!0}}}),c=i({name:"OnboardingStep",description:"Declarative onboarding step definition.",fields:{id:{type:t.String_unsecure(),isOptional:!1},trackId:{type:t.String_unsecure(),isOptional:!1},title:{type:t.String_unsecure(),isOptional:!1},description:{type:t.String_unsecure(),isOptional:!0},instructions:{type:t.String_unsecure(),isOptional:!0},helpUrl:{type:t.String_unsecure(),isOptional:!0},order:{type:t.Int_unsecure(),isOptional:!1},completionEvent:{type:t.String_unsecure(),isOptional:!1},completionCondition:{type:O,isOptional:!0},xpReward:{type:t.Int_unsecure(),isOptional:!0},isRequired:{type:t.Boolean(),isOptional:!0},canSkip:{type:t.Boolean(),isOptional:!0},actionUrl:{type:t.String_unsecure(),isOptional:!0},actionLabel:{type:t.String_unsecure(),isOptional:!0},metadata:{type:t.JSON(),isOptional:!0}}}),_=i({name:"OnboardingTrack",description:"Onboarding track metadata and steps.",fields:{id:{type:t.String_unsecure(),isOptional:!1},productId:{type:t.String_unsecure(),isOptional:!0},name:{type:t.String_unsecure(),isOptional:!1},description:{type:t.String_unsecure(),isOptional:!0},targetUserSegment:{type:t.String_unsecure(),isOptional:!0},targetRole:{type:t.String_unsecure(),isOptional:!0},isActive:{type:t.Boolean(),isOptional:!0},isRequired:{type:t.Boolean(),isOptional:!0},canSkip:{type:t.Boolean(),isOptional:!0},totalXp:{type:t.Int_unsecure(),isOptional:!0},completionXpBonus:{type:t.Int_unsecure(),isOptional:!0},completionBadgeKey:{type:t.String_unsecure(),isOptional:!0},streakHoursWindow:{type:t.Int_unsecure(),isOptional:!0},streakBonusXp:{type:t.Int_unsecure(),isOptional:!0},metadata:{type:t.JSON(),isOptional:!0},steps:{type:c,isArray:!0,isOptional:!1}}}),I=i({name:"OnboardingStepProgress",description:"Progress for a specific onboarding step.",fields:{stepId:{type:t.String_unsecure(),isOptional:!1},status:{type:t.String_unsecure(),isOptional:!1},xpEarned:{type:t.Int_unsecure(),isOptional:!0},triggeringEvent:{type:t.String_unsecure(),isOptional:!0},eventPayload:{type:t.JSON(),isOptional:!0},completedAt:{type:t.DateTime(),isOptional:!0}}}),p=i({name:"OnboardingProgress",description:"Aggregated progress for an onboarding track.",fields:{learnerId:{type:t.String_unsecure(),isOptional:!0},trackId:{type:t.String_unsecure(),isOptional:!1},progress:{type:t.Int_unsecure(),isOptional:!1},isCompleted:{type:t.Boolean(),isOptional:!1},xpEarned:{type:t.Int_unsecure(),isOptional:!0},startedAt:{type:t.DateTime(),isOptional:!0},completedAt:{type:t.DateTime(),isOptional:!0},lastActivityAt:{type:t.DateTime(),isOptional:!0},steps:{type:I,isArray:!0,isOptional:!0}}}),g=i({name:"ListOnboardingTracksInput",description:"Filters for listing onboarding tracks.",fields:{learnerId:{type:t.String_unsecure(),isOptional:!0},productId:{type:t.String_unsecure(),isOptional:!0},trackIds:{type:t.String_unsecure(),isArray:!0,isOptional:!0},includeProgress:{type:t.Boolean(),isOptional:!0}}}),y=i({name:"ListOnboardingTracksOutput",description:"Available onboarding tracks with optional progress.",fields:{tracks:{type:_,isArray:!0,isOptional:!1},progress:{type:p,isArray:!0,isOptional:!0}}}),D=i({name:"GetOnboardingProgressInput",description:"Input for fetching onboarding progress for a track.",fields:{trackId:{type:t.String_unsecure(),isOptional:!1},learnerId:{type:t.String_unsecure(),isOptional:!0}}}),x=i({name:"RecordOnboardingEventInput",description:"Record a domain event to advance onboarding progress via completion conditions.",fields:{learnerId:{type:t.String_unsecure(),isOptional:!1},trackId:{type:t.String_unsecure(),isOptional:!0},eventName:{type:t.String_unsecure(),isOptional:!1},eventVersion:{type:t.String_unsecure(),isOptional:!0},eventPayload:{type:t.JSON(),isOptional:!0},occurredAt:{type:t.DateTime(),isOptional:!0}}}),P=o({meta:{key:"learning.onboarding.listTracks",version:"1.0.0",stability:"stable",owners:[...n],tags:["learning","onboarding","journey"],description:"List onboarding tracks available to a learner or product.",goal:"Expose track catalog for UI/API surfaces.",context:"Called when showing onboarding/learning journey catalog."},io:{input:g,output:y},policy:{auth:"user"}}),V=o({meta:{key:"learning.onboarding.getProgress",version:"1.0.0",stability:"stable",owners:[...n],tags:["learning","onboarding","journey"],description:"Fetch onboarding progress for a specific track.",goal:"Display learner progress and remaining steps.",context:"Called when rendering a track detail or widget."},io:{input:D,output:p},policy:{auth:"user"}}),Z=d({meta:{key:"learning.onboarding.recordEvent",version:"1.0.0",stability:"stable",owners:[...n],tags:["learning","onboarding","events"],description:"Record a domain event to evaluate onboarding step completion conditions.",goal:"Advance onboarding automatically from product events.",context:"Called by event bus handlers when relevant product events fire (e.g., deal.created)."},io:{input:x,output:r,errors:{TRACK_NOT_FOUND:{description:"Track not found for event routing",http:404,gqlCode:"TRACK_NOT_FOUND",when:"Track ID or routing context is invalid"},STEP_NOT_FOUND:{description:"Step not found for completion condition",http:404,gqlCode:"STEP_NOT_FOUND",when:"No step matches the incoming event"}}},policy:{auth:"user"}});export{Z as RecordOnboardingEventContract,_ as OnboardingTrackModel,I as OnboardingStepProgressModel,c as OnboardingStepModel,p as OnboardingProgressModel,P as ListOnboardingTracksContract,V as GetOnboardingProgressContract};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{defineEntity as w,defineEntityEnum as A,field as j,index as q}from"@contractspec/lib.schema";var z=A({name:"OnboardingStepStatus",values:["PENDING","IN_PROGRESS","COMPLETED","SKIPPED"],schema:"lssm_learning",description:"Status of an onboarding step."}),B=w({name:"OnboardingTrack",description:"An onboarding track for a product.",schema:"lssm_learning",map:"onboarding_track",fields:{id:j.id({description:"Unique track identifier"}),productId:j.string({description:"Product this track is for"}),name:j.string({description:"Track name"}),description:j.string({isOptional:!0,description:"Track description"}),targetUserSegment:j.string({isOptional:!0,description:"Target user segment"}),targetRole:j.string({isOptional:!0,description:"Target user role"}),welcomeTitle:j.string({isOptional:!0,description:"Welcome message title"}),welcomeMessage:j.string({isOptional:!0,description:"Welcome message"}),completionTitle:j.string({isOptional:!0,description:"Completion message title"}),completionMessage:j.string({isOptional:!0,description:"Completion message"}),isActive:j.boolean({default:!0,description:"Whether track is active"}),isRequired:j.boolean({default:!1,description:"Whether track is required"}),canSkip:j.boolean({default:!0,description:"Whether steps can be skipped"}),totalXp:j.int({default:100,description:"Total XP for completing track"}),completionXpBonus:j.int({isOptional:!0,description:"Bonus XP for completing track"}),completionBadgeKey:j.string({isOptional:!0,description:"Badge awarded on completion"}),streakHoursWindow:j.int({isOptional:!0,description:"Hours window to finish for streak bonus"}),streakBonusXp:j.int({isOptional:!0,description:"Bonus XP if completed within streak window"}),orgId:j.string({isOptional:!0,description:"Organization scope"}),metadata:j.json({isOptional:!0,description:"Additional metadata"}),createdAt:j.createdAt(),updatedAt:j.updatedAt(),steps:j.hasMany("OnboardingStep"),progress:j.hasMany("OnboardingProgress")},indexes:[q.on(["productId","isActive"]),q.on(["orgId"]),q.unique(["productId","targetUserSegment","targetRole"],{name:"onboarding_track_target"})]}),D=w({name:"OnboardingStep",description:"A step in an onboarding track.",schema:"lssm_learning",map:"onboarding_step",fields:{id:j.id({description:"Unique step identifier"}),trackId:j.foreignKey({description:"Parent track"}),title:j.string({description:"Step title"}),description:j.string({isOptional:!0,description:"Step description"}),instructions:j.string({isOptional:!0,description:"How to complete the step"}),helpUrl:j.string({isOptional:!0,description:"Link to help documentation"}),order:j.int({default:0,description:"Display order"}),triggerEvent:j.string({isOptional:!0,description:"Event that triggers step start"}),completionEvent:j.string({description:"Event that completes the step"}),completionEventVersion:j.int({isOptional:!0,description:"Version of the completion event"}),completionSourceModule:j.string({isOptional:!0,description:"Module emitting the completion event"}),completionEventFilter:j.json({isOptional:!0,description:"Filter for completion event"}),actionUrl:j.string({isOptional:!0,description:"URL to navigate to complete"}),actionLabel:j.string({isOptional:!0,description:"Action button label"}),highlightSelector:j.string({isOptional:!0,description:"CSS selector to highlight"}),tooltipPosition:j.string({isOptional:!0,description:"Tooltip position"}),xpReward:j.int({default:10,description:"XP for completing step"}),isRequired:j.boolean({default:!0,description:"Whether step is required"}),canSkip:j.boolean({default:!0,description:"Whether step can be skipped"}),metadata:j.json({isOptional:!0,description:"Additional metadata"}),createdAt:j.createdAt(),updatedAt:j.updatedAt(),track:j.belongsTo("OnboardingTrack",["trackId"],["id"],{onDelete:"Cascade"})},indexes:[q.on(["trackId","order"]),q.on(["completionEvent"])]}),F=w({name:"OnboardingProgress",description:"Tracks user progress through an onboarding track.",schema:"lssm_learning",map:"onboarding_progress",fields:{id:j.id({description:"Unique progress identifier"}),learnerId:j.foreignKey({description:"Learner"}),trackId:j.foreignKey({description:"Onboarding track"}),currentStepId:j.string({isOptional:!0,description:"Current step ID"}),completedSteps:j.json({default:"[]",description:"Array of completed step IDs"}),skippedSteps:j.json({default:"[]",description:"Array of skipped step IDs"}),progress:j.int({default:0,description:"Completion percentage (0-100)"}),isCompleted:j.boolean({default:!1,description:"Whether track is completed"}),xpEarned:j.int({default:0,description:"XP earned from track"}),startedAt:j.dateTime({description:"When user started"}),completedAt:j.dateTime({isOptional:!0,description:"When user completed"}),lastActivityAt:j.dateTime({isOptional:!0,description:"Last activity"}),isDismissed:j.boolean({default:!1,description:"Whether user dismissed onboarding"}),dismissedAt:j.dateTime({isOptional:!0,description:"When dismissed"}),metadata:j.json({isOptional:!0,description:"Additional metadata"}),createdAt:j.createdAt(),updatedAt:j.updatedAt(),learner:j.belongsTo("Learner",["learnerId"],["id"],{onDelete:"Cascade"}),track:j.belongsTo("OnboardingTrack",["trackId"],["id"],{onDelete:"Cascade"})},indexes:[q.unique(["learnerId","trackId"],{name:"onboarding_progress_unique"}),q.on(["learnerId","isCompleted"]),q.on(["trackId"])],enums:[z]}),G=w({name:"OnboardingStepCompletion",description:"Individual step completion record.",schema:"lssm_learning",map:"onboarding_step_completion",fields:{id:j.id({description:"Unique completion identifier"}),progressId:j.foreignKey({description:"Parent progress record"}),stepId:j.foreignKey({description:"Completed step"}),status:j.enum("OnboardingStepStatus",{description:"Completion status"}),xpEarned:j.int({default:0,description:"XP earned"}),triggeringEvent:j.string({isOptional:!0,description:"Event that triggered completion"}),eventPayload:j.json({isOptional:!0,description:"Event payload"}),completedAt:j.dateTime({description:"When completed"}),createdAt:j.createdAt(),progress:j.belongsTo("OnboardingProgress",["progressId"],["id"],{onDelete:"Cascade"}),step:j.belongsTo("OnboardingStep",["stepId"],["id"],{onDelete:"Cascade"})},indexes:[q.unique(["progressId","stepId"],{name:"step_completion_unique"}),q.on(["completedAt"])]}),I=[B,D,F,G],J=[z];export{J as onboardingEnums,I as onboardingEntities,B as OnboardingTrackEntity,z as OnboardingStepStatusEnum,D as OnboardingStepEntity,G as OnboardingStepCompletionEntity,F as OnboardingProgressEntity};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import{defineSchemaModel as s,ScalarTypeEnum as e}from"@contractspec/lib.schema";var C=s({name:"Course",description:"A learning course",fields:{id:{type:e.String_unsecure(),isOptional:!1},title:{type:e.String_unsecure(),isOptional:!1},slug:{type:e.String_unsecure(),isOptional:!1},description:{type:e.String_unsecure(),isOptional:!0},difficulty:{type:e.String_unsecure(),isOptional:!1},status:{type:e.String_unsecure(),isOptional:!1},estimatedDuration:{type:e.Int_unsecure(),isOptional:!0},thumbnailUrl:{type:e.String_unsecure(),isOptional:!0},createdAt:{type:e.DateTime(),isOptional:!1}}}),u=s({name:"Learner",description:"A learner profile",fields:{id:{type:e.String_unsecure(),isOptional:!1},userId:{type:e.String_unsecure(),isOptional:!1},displayName:{type:e.String_unsecure(),isOptional:!0},level:{type:e.Int_unsecure(),isOptional:!1},totalXp:{type:e.Int_unsecure(),isOptional:!1},currentStreak:{type:e.Int_unsecure(),isOptional:!1},longestStreak:{type:e.Int_unsecure(),isOptional:!1},createdAt:{type:e.DateTime(),isOptional:!1}}}),l=s({name:"Enrollment",description:"A course enrollment",fields:{id:{type:e.String_unsecure(),isOptional:!1},learnerId:{type:e.String_unsecure(),isOptional:!1},courseId:{type:e.String_unsecure(),isOptional:!1},status:{type:e.String_unsecure(),isOptional:!1},progress:{type:e.Int_unsecure(),isOptional:!1},startedAt:{type:e.DateTime(),isOptional:!0},completedAt:{type:e.DateTime(),isOptional:!0}}}),v=s({name:"LessonProgress",description:"Lesson progress",fields:{id:{type:e.String_unsecure(),isOptional:!1},learnerId:{type:e.String_unsecure(),isOptional:!1},lessonId:{type:e.String_unsecure(),isOptional:!1},status:{type:e.String_unsecure(),isOptional:!1},progress:{type:e.Int_unsecure(),isOptional:!1},score:{type:e.Int_unsecure(),isOptional:!0},timeSpent:{type:e.Int_unsecure(),isOptional:!1},completedAt:{type:e.DateTime(),isOptional:!0}}}),k=s({name:"Deck",description:"A flashcard deck",fields:{id:{type:e.String_unsecure(),isOptional:!1},title:{type:e.String_unsecure(),isOptional:!1},description:{type:e.String_unsecure(),isOptional:!0},cardCount:{type:e.Int_unsecure(),isOptional:!1},isPublic:{type:e.Boolean(),isOptional:!1},createdAt:{type:e.DateTime(),isOptional:!1}}}),a=s({name:"Card",description:"A flashcard",fields:{id:{type:e.String_unsecure(),isOptional:!1},deckId:{type:e.String_unsecure(),isOptional:!1},front:{type:e.String_unsecure(),isOptional:!1},back:{type:e.String_unsecure(),isOptional:!1},hints:{type:e.JSON(),isOptional:!0},isDue:{type:e.Boolean(),isOptional:!1},nextReviewAt:{type:e.DateTime(),isOptional:!0}}}),f=s({name:"Achievement",description:"An achievement",fields:{id:{type:e.String_unsecure(),isOptional:!1},key:{type:e.String_unsecure(),isOptional:!1},name:{type:e.String_unsecure(),isOptional:!1},description:{type:e.String_unsecure(),isOptional:!1},icon:{type:e.String_unsecure(),isOptional:!0},xpReward:{type:e.Int_unsecure(),isOptional:!1},unlockedAt:{type:e.DateTime(),isOptional:!0}}}),L=s({name:"EnrollInCourseInput",description:"Input for enrolling in a course",fields:{courseId:{type:e.String_unsecure(),isOptional:!1}}}),w=s({name:"CompleteLessonInput",description:"Input for completing a lesson",fields:{lessonId:{type:e.String_unsecure(),isOptional:!1},score:{type:e.Int_unsecure(),isOptional:!0},timeSpent:{type:e.Int_unsecure(),isOptional:!1}}}),G=s({name:"SubmitCardReviewInput",description:"Input for submitting a card review",fields:{cardId:{type:e.String_unsecure(),isOptional:!1},rating:{type:e.String_unsecure(),isOptional:!1},responseTimeMs:{type:e.Int_unsecure(),isOptional:!0}}}),h=s({name:"GetDueCardsInput",description:"Input for getting due cards",fields:{deckId:{type:e.String_unsecure(),isOptional:!0},limit:{type:e.Int_unsecure(),isOptional:!0}}}),B=s({name:"GetDueCardsOutput",description:"Output for getting due cards",fields:{cards:{type:a,isArray:!0,isOptional:!1},total:{type:e.Int_unsecure(),isOptional:!1}}}),X=s({name:"GetLearnerDashboardInput",description:"Input for getting learner dashboard",fields:{learnerId:{type:e.String_unsecure(),isOptional:!0}}}),j=s({name:"LearnerDashboard",description:"Learner dashboard data",fields:{learner:{type:u,isOptional:!1},currentStreak:{type:e.Int_unsecure(),isOptional:!1},dailyXpGoal:{type:e.Int_unsecure(),isOptional:!1},dailyXpProgress:{type:e.Int_unsecure(),isOptional:!1},activeEnrollments:{type:l,isArray:!0,isOptional:!1},recentAchievements:{type:f,isArray:!0,isOptional:!1},dueCardCount:{type:e.Int_unsecure(),isOptional:!1}}}),r=s({name:"SuccessOutput",description:"Generic success output",fields:{success:{type:e.Boolean(),isOptional:!1},xpEarned:{type:e.Int_unsecure(),isOptional:!0}}});var n=["modules.learning-journey"];import{defineCommand as d,defineQuery as o}from"@contractspec/lib.contracts-spec";import{defineSchemaModel as i,ScalarTypeEnum as t}from"@contractspec/lib.schema";var O=i({name:"OnboardingStepCondition",description:"Structured completion condition for onboarding steps.",fields:{eventName:{type:t.String_unsecure(),isOptional:!1},eventVersion:{type:t.String_unsecure(),isOptional:!0},sourceModule:{type:t.String_unsecure(),isOptional:!0},payloadFilter:{type:t.JSON(),isOptional:!0}}}),c=i({name:"OnboardingStep",description:"Declarative onboarding step definition.",fields:{id:{type:t.String_unsecure(),isOptional:!1},trackId:{type:t.String_unsecure(),isOptional:!1},title:{type:t.String_unsecure(),isOptional:!1},description:{type:t.String_unsecure(),isOptional:!0},instructions:{type:t.String_unsecure(),isOptional:!0},helpUrl:{type:t.String_unsecure(),isOptional:!0},order:{type:t.Int_unsecure(),isOptional:!1},completionEvent:{type:t.String_unsecure(),isOptional:!1},completionCondition:{type:O,isOptional:!0},xpReward:{type:t.Int_unsecure(),isOptional:!0},isRequired:{type:t.Boolean(),isOptional:!0},canSkip:{type:t.Boolean(),isOptional:!0},actionUrl:{type:t.String_unsecure(),isOptional:!0},actionLabel:{type:t.String_unsecure(),isOptional:!0},metadata:{type:t.JSON(),isOptional:!0}}}),_=i({name:"OnboardingTrack",description:"Onboarding track metadata and steps.",fields:{id:{type:t.String_unsecure(),isOptional:!1},productId:{type:t.String_unsecure(),isOptional:!0},name:{type:t.String_unsecure(),isOptional:!1},description:{type:t.String_unsecure(),isOptional:!0},targetUserSegment:{type:t.String_unsecure(),isOptional:!0},targetRole:{type:t.String_unsecure(),isOptional:!0},isActive:{type:t.Boolean(),isOptional:!0},isRequired:{type:t.Boolean(),isOptional:!0},canSkip:{type:t.Boolean(),isOptional:!0},totalXp:{type:t.Int_unsecure(),isOptional:!0},completionXpBonus:{type:t.Int_unsecure(),isOptional:!0},completionBadgeKey:{type:t.String_unsecure(),isOptional:!0},streakHoursWindow:{type:t.Int_unsecure(),isOptional:!0},streakBonusXp:{type:t.Int_unsecure(),isOptional:!0},metadata:{type:t.JSON(),isOptional:!0},steps:{type:c,isArray:!0,isOptional:!1}}}),I=i({name:"OnboardingStepProgress",description:"Progress for a specific onboarding step.",fields:{stepId:{type:t.String_unsecure(),isOptional:!1},status:{type:t.String_unsecure(),isOptional:!1},xpEarned:{type:t.Int_unsecure(),isOptional:!0},triggeringEvent:{type:t.String_unsecure(),isOptional:!0},eventPayload:{type:t.JSON(),isOptional:!0},completedAt:{type:t.DateTime(),isOptional:!0}}}),p=i({name:"OnboardingProgress",description:"Aggregated progress for an onboarding track.",fields:{learnerId:{type:t.String_unsecure(),isOptional:!0},trackId:{type:t.String_unsecure(),isOptional:!1},progress:{type:t.Int_unsecure(),isOptional:!1},isCompleted:{type:t.Boolean(),isOptional:!1},xpEarned:{type:t.Int_unsecure(),isOptional:!0},startedAt:{type:t.DateTime(),isOptional:!0},completedAt:{type:t.DateTime(),isOptional:!0},lastActivityAt:{type:t.DateTime(),isOptional:!0},steps:{type:I,isArray:!0,isOptional:!0}}}),g=i({name:"ListOnboardingTracksInput",description:"Filters for listing onboarding tracks.",fields:{learnerId:{type:t.String_unsecure(),isOptional:!0},productId:{type:t.String_unsecure(),isOptional:!0},trackIds:{type:t.String_unsecure(),isArray:!0,isOptional:!0},includeProgress:{type:t.Boolean(),isOptional:!0}}}),y=i({name:"ListOnboardingTracksOutput",description:"Available onboarding tracks with optional progress.",fields:{tracks:{type:_,isArray:!0,isOptional:!1},progress:{type:p,isArray:!0,isOptional:!0}}}),D=i({name:"GetOnboardingProgressInput",description:"Input for fetching onboarding progress for a track.",fields:{trackId:{type:t.String_unsecure(),isOptional:!1},learnerId:{type:t.String_unsecure(),isOptional:!0}}}),x=i({name:"RecordOnboardingEventInput",description:"Record a domain event to advance onboarding progress via completion conditions.",fields:{learnerId:{type:t.String_unsecure(),isOptional:!1},trackId:{type:t.String_unsecure(),isOptional:!0},eventName:{type:t.String_unsecure(),isOptional:!1},eventVersion:{type:t.String_unsecure(),isOptional:!0},eventPayload:{type:t.JSON(),isOptional:!0},occurredAt:{type:t.DateTime(),isOptional:!0}}}),P=o({meta:{key:"learning.onboarding.listTracks",version:"1.0.0",stability:"stable",owners:[...n],tags:["learning","onboarding","journey"],description:"List onboarding tracks available to a learner or product.",goal:"Expose track catalog for UI/API surfaces.",context:"Called when showing onboarding/learning journey catalog."},io:{input:g,output:y},policy:{auth:"user"}}),V=o({meta:{key:"learning.onboarding.getProgress",version:"1.0.0",stability:"stable",owners:[...n],tags:["learning","onboarding","journey"],description:"Fetch onboarding progress for a specific track.",goal:"Display learner progress and remaining steps.",context:"Called when rendering a track detail or widget."},io:{input:D,output:p},policy:{auth:"user"}}),Z=d({meta:{key:"learning.onboarding.recordEvent",version:"1.0.0",stability:"stable",owners:[...n],tags:["learning","onboarding","events"],description:"Record a domain event to evaluate onboarding step completion conditions.",goal:"Advance onboarding automatically from product events.",context:"Called by event bus handlers when relevant product events fire (e.g., deal.created)."},io:{input:x,output:r,errors:{TRACK_NOT_FOUND:{description:"Track not found for event routing",http:404,gqlCode:"TRACK_NOT_FOUND",when:"Track ID or routing context is invalid"},STEP_NOT_FOUND:{description:"Step not found for completion condition",http:404,gqlCode:"STEP_NOT_FOUND",when:"No step matches the incoming event"}}},policy:{auth:"user"}});export{Z as RecordOnboardingEventContract,_ as OnboardingTrackModel,I as OnboardingStepProgressModel,c as OnboardingStepModel,p as OnboardingProgressModel,P as ListOnboardingTracksContract,V as GetOnboardingProgressContract};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import{defineEntity as w,defineEntityEnum as A,field as j,index as q}from"@contractspec/lib.schema";var z=A({name:"OnboardingStepStatus",values:["PENDING","IN_PROGRESS","COMPLETED","SKIPPED"],schema:"lssm_learning",description:"Status of an onboarding step."}),B=w({name:"OnboardingTrack",description:"An onboarding track for a product.",schema:"lssm_learning",map:"onboarding_track",fields:{id:j.id({description:"Unique track identifier"}),productId:j.string({description:"Product this track is for"}),name:j.string({description:"Track name"}),description:j.string({isOptional:!0,description:"Track description"}),targetUserSegment:j.string({isOptional:!0,description:"Target user segment"}),targetRole:j.string({isOptional:!0,description:"Target user role"}),welcomeTitle:j.string({isOptional:!0,description:"Welcome message title"}),welcomeMessage:j.string({isOptional:!0,description:"Welcome message"}),completionTitle:j.string({isOptional:!0,description:"Completion message title"}),completionMessage:j.string({isOptional:!0,description:"Completion message"}),isActive:j.boolean({default:!0,description:"Whether track is active"}),isRequired:j.boolean({default:!1,description:"Whether track is required"}),canSkip:j.boolean({default:!0,description:"Whether steps can be skipped"}),totalXp:j.int({default:100,description:"Total XP for completing track"}),completionXpBonus:j.int({isOptional:!0,description:"Bonus XP for completing track"}),completionBadgeKey:j.string({isOptional:!0,description:"Badge awarded on completion"}),streakHoursWindow:j.int({isOptional:!0,description:"Hours window to finish for streak bonus"}),streakBonusXp:j.int({isOptional:!0,description:"Bonus XP if completed within streak window"}),orgId:j.string({isOptional:!0,description:"Organization scope"}),metadata:j.json({isOptional:!0,description:"Additional metadata"}),createdAt:j.createdAt(),updatedAt:j.updatedAt(),steps:j.hasMany("OnboardingStep"),progress:j.hasMany("OnboardingProgress")},indexes:[q.on(["productId","isActive"]),q.on(["orgId"]),q.unique(["productId","targetUserSegment","targetRole"],{name:"onboarding_track_target"})]}),D=w({name:"OnboardingStep",description:"A step in an onboarding track.",schema:"lssm_learning",map:"onboarding_step",fields:{id:j.id({description:"Unique step identifier"}),trackId:j.foreignKey({description:"Parent track"}),title:j.string({description:"Step title"}),description:j.string({isOptional:!0,description:"Step description"}),instructions:j.string({isOptional:!0,description:"How to complete the step"}),helpUrl:j.string({isOptional:!0,description:"Link to help documentation"}),order:j.int({default:0,description:"Display order"}),triggerEvent:j.string({isOptional:!0,description:"Event that triggers step start"}),completionEvent:j.string({description:"Event that completes the step"}),completionEventVersion:j.int({isOptional:!0,description:"Version of the completion event"}),completionSourceModule:j.string({isOptional:!0,description:"Module emitting the completion event"}),completionEventFilter:j.json({isOptional:!0,description:"Filter for completion event"}),actionUrl:j.string({isOptional:!0,description:"URL to navigate to complete"}),actionLabel:j.string({isOptional:!0,description:"Action button label"}),highlightSelector:j.string({isOptional:!0,description:"CSS selector to highlight"}),tooltipPosition:j.string({isOptional:!0,description:"Tooltip position"}),xpReward:j.int({default:10,description:"XP for completing step"}),isRequired:j.boolean({default:!0,description:"Whether step is required"}),canSkip:j.boolean({default:!0,description:"Whether step can be skipped"}),metadata:j.json({isOptional:!0,description:"Additional metadata"}),createdAt:j.createdAt(),updatedAt:j.updatedAt(),track:j.belongsTo("OnboardingTrack",["trackId"],["id"],{onDelete:"Cascade"})},indexes:[q.on(["trackId","order"]),q.on(["completionEvent"])]}),F=w({name:"OnboardingProgress",description:"Tracks user progress through an onboarding track.",schema:"lssm_learning",map:"onboarding_progress",fields:{id:j.id({description:"Unique progress identifier"}),learnerId:j.foreignKey({description:"Learner"}),trackId:j.foreignKey({description:"Onboarding track"}),currentStepId:j.string({isOptional:!0,description:"Current step ID"}),completedSteps:j.json({default:"[]",description:"Array of completed step IDs"}),skippedSteps:j.json({default:"[]",description:"Array of skipped step IDs"}),progress:j.int({default:0,description:"Completion percentage (0-100)"}),isCompleted:j.boolean({default:!1,description:"Whether track is completed"}),xpEarned:j.int({default:0,description:"XP earned from track"}),startedAt:j.dateTime({description:"When user started"}),completedAt:j.dateTime({isOptional:!0,description:"When user completed"}),lastActivityAt:j.dateTime({isOptional:!0,description:"Last activity"}),isDismissed:j.boolean({default:!1,description:"Whether user dismissed onboarding"}),dismissedAt:j.dateTime({isOptional:!0,description:"When dismissed"}),metadata:j.json({isOptional:!0,description:"Additional metadata"}),createdAt:j.createdAt(),updatedAt:j.updatedAt(),learner:j.belongsTo("Learner",["learnerId"],["id"],{onDelete:"Cascade"}),track:j.belongsTo("OnboardingTrack",["trackId"],["id"],{onDelete:"Cascade"})},indexes:[q.unique(["learnerId","trackId"],{name:"onboarding_progress_unique"}),q.on(["learnerId","isCompleted"]),q.on(["trackId"])],enums:[z]}),G=w({name:"OnboardingStepCompletion",description:"Individual step completion record.",schema:"lssm_learning",map:"onboarding_step_completion",fields:{id:j.id({description:"Unique completion identifier"}),progressId:j.foreignKey({description:"Parent progress record"}),stepId:j.foreignKey({description:"Completed step"}),status:j.enum("OnboardingStepStatus",{description:"Completion status"}),xpEarned:j.int({default:0,description:"XP earned"}),triggeringEvent:j.string({isOptional:!0,description:"Event that triggered completion"}),eventPayload:j.json({isOptional:!0,description:"Event payload"}),completedAt:j.dateTime({description:"When completed"}),createdAt:j.createdAt(),progress:j.belongsTo("OnboardingProgress",["progressId"],["id"],{onDelete:"Cascade"}),step:j.belongsTo("OnboardingStep",["stepId"],["id"],{onDelete:"Cascade"})},indexes:[q.unique(["progressId","stepId"],{name:"step_completion_unique"}),q.on(["completedAt"])]}),I=[B,D,F,G],J=[z];export{J as onboardingEnums,I as onboardingEntities,B as OnboardingTrackEntity,z as OnboardingStepStatusEnum,D as OnboardingStepEntity,G as OnboardingStepCompletionEntity,F as OnboardingProgressEntity};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{defineSchemaModel as s,ScalarTypeEnum as e}from"@contractspec/lib.schema";var C=s({name:"Course",description:"A learning course",fields:{id:{type:e.String_unsecure(),isOptional:!1},title:{type:e.String_unsecure(),isOptional:!1},slug:{type:e.String_unsecure(),isOptional:!1},description:{type:e.String_unsecure(),isOptional:!0},difficulty:{type:e.String_unsecure(),isOptional:!1},status:{type:e.String_unsecure(),isOptional:!1},estimatedDuration:{type:e.Int_unsecure(),isOptional:!0},thumbnailUrl:{type:e.String_unsecure(),isOptional:!0},createdAt:{type:e.DateTime(),isOptional:!1}}}),u=s({name:"Learner",description:"A learner profile",fields:{id:{type:e.String_unsecure(),isOptional:!1},userId:{type:e.String_unsecure(),isOptional:!1},displayName:{type:e.String_unsecure(),isOptional:!0},level:{type:e.Int_unsecure(),isOptional:!1},totalXp:{type:e.Int_unsecure(),isOptional:!1},currentStreak:{type:e.Int_unsecure(),isOptional:!1},longestStreak:{type:e.Int_unsecure(),isOptional:!1},createdAt:{type:e.DateTime(),isOptional:!1}}}),l=s({name:"Enrollment",description:"A course enrollment",fields:{id:{type:e.String_unsecure(),isOptional:!1},learnerId:{type:e.String_unsecure(),isOptional:!1},courseId:{type:e.String_unsecure(),isOptional:!1},status:{type:e.String_unsecure(),isOptional:!1},progress:{type:e.Int_unsecure(),isOptional:!1},startedAt:{type:e.DateTime(),isOptional:!0},completedAt:{type:e.DateTime(),isOptional:!0}}}),v=s({name:"LessonProgress",description:"Lesson progress",fields:{id:{type:e.String_unsecure(),isOptional:!1},learnerId:{type:e.String_unsecure(),isOptional:!1},lessonId:{type:e.String_unsecure(),isOptional:!1},status:{type:e.String_unsecure(),isOptional:!1},progress:{type:e.Int_unsecure(),isOptional:!1},score:{type:e.Int_unsecure(),isOptional:!0},timeSpent:{type:e.Int_unsecure(),isOptional:!1},completedAt:{type:e.DateTime(),isOptional:!0}}}),k=s({name:"Deck",description:"A flashcard deck",fields:{id:{type:e.String_unsecure(),isOptional:!1},title:{type:e.String_unsecure(),isOptional:!1},description:{type:e.String_unsecure(),isOptional:!0},cardCount:{type:e.Int_unsecure(),isOptional:!1},isPublic:{type:e.Boolean(),isOptional:!1},createdAt:{type:e.DateTime(),isOptional:!1}}}),a=s({name:"Card",description:"A flashcard",fields:{id:{type:e.String_unsecure(),isOptional:!1},deckId:{type:e.String_unsecure(),isOptional:!1},front:{type:e.String_unsecure(),isOptional:!1},back:{type:e.String_unsecure(),isOptional:!1},hints:{type:e.JSON(),isOptional:!0},isDue:{type:e.Boolean(),isOptional:!1},nextReviewAt:{type:e.DateTime(),isOptional:!0}}}),f=s({name:"Achievement",description:"An achievement",fields:{id:{type:e.String_unsecure(),isOptional:!1},key:{type:e.String_unsecure(),isOptional:!1},name:{type:e.String_unsecure(),isOptional:!1},description:{type:e.String_unsecure(),isOptional:!1},icon:{type:e.String_unsecure(),isOptional:!0},xpReward:{type:e.Int_unsecure(),isOptional:!1},unlockedAt:{type:e.DateTime(),isOptional:!0}}}),L=s({name:"EnrollInCourseInput",description:"Input for enrolling in a course",fields:{courseId:{type:e.String_unsecure(),isOptional:!1}}}),w=s({name:"CompleteLessonInput",description:"Input for completing a lesson",fields:{lessonId:{type:e.String_unsecure(),isOptional:!1},score:{type:e.Int_unsecure(),isOptional:!0},timeSpent:{type:e.Int_unsecure(),isOptional:!1}}}),G=s({name:"SubmitCardReviewInput",description:"Input for submitting a card review",fields:{cardId:{type:e.String_unsecure(),isOptional:!1},rating:{type:e.String_unsecure(),isOptional:!1},responseTimeMs:{type:e.Int_unsecure(),isOptional:!0}}}),h=s({name:"GetDueCardsInput",description:"Input for getting due cards",fields:{deckId:{type:e.String_unsecure(),isOptional:!0},limit:{type:e.Int_unsecure(),isOptional:!0}}}),B=s({name:"GetDueCardsOutput",description:"Output for getting due cards",fields:{cards:{type:a,isArray:!0,isOptional:!1},total:{type:e.Int_unsecure(),isOptional:!1}}}),X=s({name:"GetLearnerDashboardInput",description:"Input for getting learner dashboard",fields:{learnerId:{type:e.String_unsecure(),isOptional:!0}}}),j=s({name:"LearnerDashboard",description:"Learner dashboard data",fields:{learner:{type:u,isOptional:!1},currentStreak:{type:e.Int_unsecure(),isOptional:!1},dailyXpGoal:{type:e.Int_unsecure(),isOptional:!1},dailyXpProgress:{type:e.Int_unsecure(),isOptional:!1},activeEnrollments:{type:l,isArray:!0,isOptional:!1},recentAchievements:{type:f,isArray:!0,isOptional:!1},dueCardCount:{type:e.Int_unsecure(),isOptional:!1}}}),r=s({name:"SuccessOutput",description:"Generic success output",fields:{success:{type:e.Boolean(),isOptional:!1},xpEarned:{type:e.Int_unsecure(),isOptional:!0}}});var n=["modules.learning-journey"];import{defineCommand as d,defineQuery as o}from"@contractspec/lib.contracts-spec";import{defineSchemaModel as i,ScalarTypeEnum as t}from"@contractspec/lib.schema";var O=i({name:"OnboardingStepCondition",description:"Structured completion condition for onboarding steps.",fields:{eventName:{type:t.String_unsecure(),isOptional:!1},eventVersion:{type:t.String_unsecure(),isOptional:!0},sourceModule:{type:t.String_unsecure(),isOptional:!0},payloadFilter:{type:t.JSON(),isOptional:!0}}}),c=i({name:"OnboardingStep",description:"Declarative onboarding step definition.",fields:{id:{type:t.String_unsecure(),isOptional:!1},trackId:{type:t.String_unsecure(),isOptional:!1},title:{type:t.String_unsecure(),isOptional:!1},description:{type:t.String_unsecure(),isOptional:!0},instructions:{type:t.String_unsecure(),isOptional:!0},helpUrl:{type:t.String_unsecure(),isOptional:!0},order:{type:t.Int_unsecure(),isOptional:!1},completionEvent:{type:t.String_unsecure(),isOptional:!1},completionCondition:{type:O,isOptional:!0},xpReward:{type:t.Int_unsecure(),isOptional:!0},isRequired:{type:t.Boolean(),isOptional:!0},canSkip:{type:t.Boolean(),isOptional:!0},actionUrl:{type:t.String_unsecure(),isOptional:!0},actionLabel:{type:t.String_unsecure(),isOptional:!0},metadata:{type:t.JSON(),isOptional:!0}}}),_=i({name:"OnboardingTrack",description:"Onboarding track metadata and steps.",fields:{id:{type:t.String_unsecure(),isOptional:!1},productId:{type:t.String_unsecure(),isOptional:!0},name:{type:t.String_unsecure(),isOptional:!1},description:{type:t.String_unsecure(),isOptional:!0},targetUserSegment:{type:t.String_unsecure(),isOptional:!0},targetRole:{type:t.String_unsecure(),isOptional:!0},isActive:{type:t.Boolean(),isOptional:!0},isRequired:{type:t.Boolean(),isOptional:!0},canSkip:{type:t.Boolean(),isOptional:!0},totalXp:{type:t.Int_unsecure(),isOptional:!0},completionXpBonus:{type:t.Int_unsecure(),isOptional:!0},completionBadgeKey:{type:t.String_unsecure(),isOptional:!0},streakHoursWindow:{type:t.Int_unsecure(),isOptional:!0},streakBonusXp:{type:t.Int_unsecure(),isOptional:!0},metadata:{type:t.JSON(),isOptional:!0},steps:{type:c,isArray:!0,isOptional:!1}}}),I=i({name:"OnboardingStepProgress",description:"Progress for a specific onboarding step.",fields:{stepId:{type:t.String_unsecure(),isOptional:!1},status:{type:t.String_unsecure(),isOptional:!1},xpEarned:{type:t.Int_unsecure(),isOptional:!0},triggeringEvent:{type:t.String_unsecure(),isOptional:!0},eventPayload:{type:t.JSON(),isOptional:!0},completedAt:{type:t.DateTime(),isOptional:!0}}}),p=i({name:"OnboardingProgress",description:"Aggregated progress for an onboarding track.",fields:{learnerId:{type:t.String_unsecure(),isOptional:!0},trackId:{type:t.String_unsecure(),isOptional:!1},progress:{type:t.Int_unsecure(),isOptional:!1},isCompleted:{type:t.Boolean(),isOptional:!1},xpEarned:{type:t.Int_unsecure(),isOptional:!0},startedAt:{type:t.DateTime(),isOptional:!0},completedAt:{type:t.DateTime(),isOptional:!0},lastActivityAt:{type:t.DateTime(),isOptional:!0},steps:{type:I,isArray:!0,isOptional:!0}}}),g=i({name:"ListOnboardingTracksInput",description:"Filters for listing onboarding tracks.",fields:{learnerId:{type:t.String_unsecure(),isOptional:!0},productId:{type:t.String_unsecure(),isOptional:!0},trackIds:{type:t.String_unsecure(),isArray:!0,isOptional:!0},includeProgress:{type:t.Boolean(),isOptional:!0}}}),y=i({name:"ListOnboardingTracksOutput",description:"Available onboarding tracks with optional progress.",fields:{tracks:{type:_,isArray:!0,isOptional:!1},progress:{type:p,isArray:!0,isOptional:!0}}}),D=i({name:"GetOnboardingProgressInput",description:"Input for fetching onboarding progress for a track.",fields:{trackId:{type:t.String_unsecure(),isOptional:!1},learnerId:{type:t.String_unsecure(),isOptional:!0}}}),x=i({name:"RecordOnboardingEventInput",description:"Record a domain event to advance onboarding progress via completion conditions.",fields:{learnerId:{type:t.String_unsecure(),isOptional:!1},trackId:{type:t.String_unsecure(),isOptional:!0},eventName:{type:t.String_unsecure(),isOptional:!1},eventVersion:{type:t.String_unsecure(),isOptional:!0},eventPayload:{type:t.JSON(),isOptional:!0},occurredAt:{type:t.DateTime(),isOptional:!0}}}),P=o({meta:{key:"learning.onboarding.listTracks",version:"1.0.0",stability:"stable",owners:[...n],tags:["learning","onboarding","journey"],description:"List onboarding tracks available to a learner or product.",goal:"Expose track catalog for UI/API surfaces.",context:"Called when showing onboarding/learning journey catalog."},io:{input:g,output:y},policy:{auth:"user"}}),V=o({meta:{key:"learning.onboarding.getProgress",version:"1.0.0",stability:"stable",owners:[...n],tags:["learning","onboarding","journey"],description:"Fetch onboarding progress for a specific track.",goal:"Display learner progress and remaining steps.",context:"Called when rendering a track detail or widget."},io:{input:D,output:p},policy:{auth:"user"}}),Z=d({meta:{key:"learning.onboarding.recordEvent",version:"1.0.0",stability:"stable",owners:[...n],tags:["learning","onboarding","events"],description:"Record a domain event to evaluate onboarding step completion conditions.",goal:"Advance onboarding automatically from product events.",context:"Called by event bus handlers when relevant product events fire (e.g., deal.created)."},io:{input:x,output:r,errors:{TRACK_NOT_FOUND:{description:"Track not found for event routing",http:404,gqlCode:"TRACK_NOT_FOUND",when:"Track ID or routing context is invalid"},STEP_NOT_FOUND:{description:"Step not found for completion condition",http:404,gqlCode:"STEP_NOT_FOUND",when:"No step matches the incoming event"}}},policy:{auth:"user"}});export{Z as RecordOnboardingEventContract,_ as OnboardingTrackModel,I as OnboardingStepProgressModel,c as OnboardingStepModel,p as OnboardingProgressModel,P as ListOnboardingTracksContract,V as GetOnboardingProgressContract};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{defineEntity as w,defineEntityEnum as A,field as j,index as q}from"@contractspec/lib.schema";var z=A({name:"OnboardingStepStatus",values:["PENDING","IN_PROGRESS","COMPLETED","SKIPPED"],schema:"lssm_learning",description:"Status of an onboarding step."}),B=w({name:"OnboardingTrack",description:"An onboarding track for a product.",schema:"lssm_learning",map:"onboarding_track",fields:{id:j.id({description:"Unique track identifier"}),productId:j.string({description:"Product this track is for"}),name:j.string({description:"Track name"}),description:j.string({isOptional:!0,description:"Track description"}),targetUserSegment:j.string({isOptional:!0,description:"Target user segment"}),targetRole:j.string({isOptional:!0,description:"Target user role"}),welcomeTitle:j.string({isOptional:!0,description:"Welcome message title"}),welcomeMessage:j.string({isOptional:!0,description:"Welcome message"}),completionTitle:j.string({isOptional:!0,description:"Completion message title"}),completionMessage:j.string({isOptional:!0,description:"Completion message"}),isActive:j.boolean({default:!0,description:"Whether track is active"}),isRequired:j.boolean({default:!1,description:"Whether track is required"}),canSkip:j.boolean({default:!0,description:"Whether steps can be skipped"}),totalXp:j.int({default:100,description:"Total XP for completing track"}),completionXpBonus:j.int({isOptional:!0,description:"Bonus XP for completing track"}),completionBadgeKey:j.string({isOptional:!0,description:"Badge awarded on completion"}),streakHoursWindow:j.int({isOptional:!0,description:"Hours window to finish for streak bonus"}),streakBonusXp:j.int({isOptional:!0,description:"Bonus XP if completed within streak window"}),orgId:j.string({isOptional:!0,description:"Organization scope"}),metadata:j.json({isOptional:!0,description:"Additional metadata"}),createdAt:j.createdAt(),updatedAt:j.updatedAt(),steps:j.hasMany("OnboardingStep"),progress:j.hasMany("OnboardingProgress")},indexes:[q.on(["productId","isActive"]),q.on(["orgId"]),q.unique(["productId","targetUserSegment","targetRole"],{name:"onboarding_track_target"})]}),D=w({name:"OnboardingStep",description:"A step in an onboarding track.",schema:"lssm_learning",map:"onboarding_step",fields:{id:j.id({description:"Unique step identifier"}),trackId:j.foreignKey({description:"Parent track"}),title:j.string({description:"Step title"}),description:j.string({isOptional:!0,description:"Step description"}),instructions:j.string({isOptional:!0,description:"How to complete the step"}),helpUrl:j.string({isOptional:!0,description:"Link to help documentation"}),order:j.int({default:0,description:"Display order"}),triggerEvent:j.string({isOptional:!0,description:"Event that triggers step start"}),completionEvent:j.string({description:"Event that completes the step"}),completionEventVersion:j.int({isOptional:!0,description:"Version of the completion event"}),completionSourceModule:j.string({isOptional:!0,description:"Module emitting the completion event"}),completionEventFilter:j.json({isOptional:!0,description:"Filter for completion event"}),actionUrl:j.string({isOptional:!0,description:"URL to navigate to complete"}),actionLabel:j.string({isOptional:!0,description:"Action button label"}),highlightSelector:j.string({isOptional:!0,description:"CSS selector to highlight"}),tooltipPosition:j.string({isOptional:!0,description:"Tooltip position"}),xpReward:j.int({default:10,description:"XP for completing step"}),isRequired:j.boolean({default:!0,description:"Whether step is required"}),canSkip:j.boolean({default:!0,description:"Whether step can be skipped"}),metadata:j.json({isOptional:!0,description:"Additional metadata"}),createdAt:j.createdAt(),updatedAt:j.updatedAt(),track:j.belongsTo("OnboardingTrack",["trackId"],["id"],{onDelete:"Cascade"})},indexes:[q.on(["trackId","order"]),q.on(["completionEvent"])]}),F=w({name:"OnboardingProgress",description:"Tracks user progress through an onboarding track.",schema:"lssm_learning",map:"onboarding_progress",fields:{id:j.id({description:"Unique progress identifier"}),learnerId:j.foreignKey({description:"Learner"}),trackId:j.foreignKey({description:"Onboarding track"}),currentStepId:j.string({isOptional:!0,description:"Current step ID"}),completedSteps:j.json({default:"[]",description:"Array of completed step IDs"}),skippedSteps:j.json({default:"[]",description:"Array of skipped step IDs"}),progress:j.int({default:0,description:"Completion percentage (0-100)"}),isCompleted:j.boolean({default:!1,description:"Whether track is completed"}),xpEarned:j.int({default:0,description:"XP earned from track"}),startedAt:j.dateTime({description:"When user started"}),completedAt:j.dateTime({isOptional:!0,description:"When user completed"}),lastActivityAt:j.dateTime({isOptional:!0,description:"Last activity"}),isDismissed:j.boolean({default:!1,description:"Whether user dismissed onboarding"}),dismissedAt:j.dateTime({isOptional:!0,description:"When dismissed"}),metadata:j.json({isOptional:!0,description:"Additional metadata"}),createdAt:j.createdAt(),updatedAt:j.updatedAt(),learner:j.belongsTo("Learner",["learnerId"],["id"],{onDelete:"Cascade"}),track:j.belongsTo("OnboardingTrack",["trackId"],["id"],{onDelete:"Cascade"})},indexes:[q.unique(["learnerId","trackId"],{name:"onboarding_progress_unique"}),q.on(["learnerId","isCompleted"]),q.on(["trackId"])],enums:[z]}),G=w({name:"OnboardingStepCompletion",description:"Individual step completion record.",schema:"lssm_learning",map:"onboarding_step_completion",fields:{id:j.id({description:"Unique completion identifier"}),progressId:j.foreignKey({description:"Parent progress record"}),stepId:j.foreignKey({description:"Completed step"}),status:j.enum("OnboardingStepStatus",{description:"Completion status"}),xpEarned:j.int({default:0,description:"XP earned"}),triggeringEvent:j.string({isOptional:!0,description:"Event that triggered completion"}),eventPayload:j.json({isOptional:!0,description:"Event payload"}),completedAt:j.dateTime({description:"When completed"}),createdAt:j.createdAt(),progress:j.belongsTo("OnboardingProgress",["progressId"],["id"],{onDelete:"Cascade"}),step:j.belongsTo("OnboardingStep",["stepId"],["id"],{onDelete:"Cascade"})},indexes:[q.unique(["progressId","stepId"],{name:"step_completion_unique"}),q.on(["completedAt"])]}),I=[B,D,F,G],J=[z];export{J as onboardingEnums,I as onboardingEntities,B as OnboardingTrackEntity,z as OnboardingStepStatusEnum,D as OnboardingStepEntity,G as OnboardingStepCompletionEntity,F as OnboardingProgressEntity};
|