@contractspec/module.learning-journey 1.57.0 → 1.58.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.
Files changed (140) hide show
  1. package/dist/browser/contracts/index.js +578 -0
  2. package/dist/browser/contracts/models.js +193 -0
  3. package/dist/browser/contracts/onboarding.js +417 -0
  4. package/dist/browser/contracts/operations.js +326 -0
  5. package/dist/browser/contracts/shared.js +5 -0
  6. package/dist/browser/docs/index.js +124 -0
  7. package/dist/browser/docs/learning-journey.docblock.js +124 -0
  8. package/dist/browser/engines/index.js +526 -0
  9. package/dist/browser/engines/srs.js +198 -0
  10. package/dist/browser/engines/streak.js +159 -0
  11. package/dist/browser/engines/xp.js +171 -0
  12. package/dist/browser/entities/ai.js +343 -0
  13. package/dist/browser/entities/course.js +276 -0
  14. package/dist/browser/entities/flashcard.js +222 -0
  15. package/dist/browser/entities/gamification.js +340 -0
  16. package/dist/browser/entities/index.js +2136 -0
  17. package/dist/browser/entities/learner.js +329 -0
  18. package/dist/browser/entities/onboarding.js +301 -0
  19. package/dist/browser/entities/quiz.js +304 -0
  20. package/dist/browser/events.js +423 -0
  21. package/dist/browser/index.js +3833 -0
  22. package/dist/browser/learning-journey.capability.js +40 -0
  23. package/dist/browser/learning-journey.feature.js +56 -0
  24. package/dist/browser/track-spec.js +0 -0
  25. package/dist/contracts/index.d.ts +5 -5
  26. package/dist/contracts/index.d.ts.map +1 -0
  27. package/dist/contracts/index.js +578 -5
  28. package/dist/contracts/models.d.ts +426 -431
  29. package/dist/contracts/models.d.ts.map +1 -1
  30. package/dist/contracts/models.js +178 -372
  31. package/dist/contracts/onboarding.d.ts +621 -627
  32. package/dist/contracts/onboarding.d.ts.map +1 -1
  33. package/dist/contracts/onboarding.js +404 -388
  34. package/dist/contracts/operations.d.ts +243 -249
  35. package/dist/contracts/operations.d.ts.map +1 -1
  36. package/dist/contracts/operations.js +324 -148
  37. package/dist/contracts/shared.d.ts +1 -4
  38. package/dist/contracts/shared.d.ts.map +1 -1
  39. package/dist/contracts/shared.js +6 -6
  40. package/dist/docs/index.d.ts +2 -1
  41. package/dist/docs/index.d.ts.map +1 -0
  42. package/dist/docs/index.js +125 -1
  43. package/dist/docs/learning-journey.docblock.d.ts +2 -1
  44. package/dist/docs/learning-journey.docblock.d.ts.map +1 -0
  45. package/dist/docs/learning-journey.docblock.js +47 -58
  46. package/dist/engines/index.d.ts +4 -4
  47. package/dist/engines/index.d.ts.map +1 -0
  48. package/dist/engines/index.js +526 -4
  49. package/dist/engines/srs.d.ts +89 -92
  50. package/dist/engines/srs.d.ts.map +1 -1
  51. package/dist/engines/srs.js +197 -217
  52. package/dist/engines/streak.d.ts +84 -87
  53. package/dist/engines/streak.d.ts.map +1 -1
  54. package/dist/engines/streak.js +158 -192
  55. package/dist/engines/xp.d.ts +80 -83
  56. package/dist/engines/xp.d.ts.map +1 -1
  57. package/dist/engines/xp.js +170 -211
  58. package/dist/entities/ai.d.ts +199 -204
  59. package/dist/entities/ai.d.ts.map +1 -1
  60. package/dist/entities/ai.js +336 -368
  61. package/dist/entities/course.d.ts +149 -154
  62. package/dist/entities/course.d.ts.map +1 -1
  63. package/dist/entities/course.js +267 -306
  64. package/dist/entities/flashcard.d.ts +144 -149
  65. package/dist/entities/flashcard.d.ts.map +1 -1
  66. package/dist/entities/flashcard.js +217 -243
  67. package/dist/entities/gamification.d.ts +197 -202
  68. package/dist/entities/gamification.d.ts.map +1 -1
  69. package/dist/entities/gamification.js +331 -382
  70. package/dist/entities/index.d.ts +613 -618
  71. package/dist/entities/index.d.ts.map +1 -1
  72. package/dist/entities/index.js +2135 -43
  73. package/dist/entities/learner.d.ts +191 -196
  74. package/dist/entities/learner.d.ts.map +1 -1
  75. package/dist/entities/learner.js +322 -357
  76. package/dist/entities/onboarding.d.ts +164 -169
  77. package/dist/entities/onboarding.d.ts.map +1 -1
  78. package/dist/entities/onboarding.js +296 -301
  79. package/dist/entities/quiz.d.ts +184 -189
  80. package/dist/entities/quiz.d.ts.map +1 -1
  81. package/dist/entities/quiz.js +296 -361
  82. package/dist/events.d.ts +608 -614
  83. package/dist/events.d.ts.map +1 -1
  84. package/dist/events.js +421 -687
  85. package/dist/index.d.ts +8 -20
  86. package/dist/index.d.ts.map +1 -0
  87. package/dist/index.js +3834 -22
  88. package/dist/learning-journey.capability.d.ts +3 -8
  89. package/dist/learning-journey.capability.d.ts.map +1 -1
  90. package/dist/learning-journey.capability.js +41 -46
  91. package/dist/learning-journey.feature.d.ts +1 -6
  92. package/dist/learning-journey.feature.d.ts.map +1 -1
  93. package/dist/learning-journey.feature.js +55 -155
  94. package/dist/node/contracts/index.js +578 -0
  95. package/dist/node/contracts/models.js +193 -0
  96. package/dist/node/contracts/onboarding.js +417 -0
  97. package/dist/node/contracts/operations.js +326 -0
  98. package/dist/node/contracts/shared.js +5 -0
  99. package/dist/node/docs/index.js +124 -0
  100. package/dist/node/docs/learning-journey.docblock.js +124 -0
  101. package/dist/node/engines/index.js +526 -0
  102. package/dist/node/engines/srs.js +198 -0
  103. package/dist/node/engines/streak.js +159 -0
  104. package/dist/node/engines/xp.js +171 -0
  105. package/dist/node/entities/ai.js +343 -0
  106. package/dist/node/entities/course.js +276 -0
  107. package/dist/node/entities/flashcard.js +222 -0
  108. package/dist/node/entities/gamification.js +340 -0
  109. package/dist/node/entities/index.js +2136 -0
  110. package/dist/node/entities/learner.js +329 -0
  111. package/dist/node/entities/onboarding.js +301 -0
  112. package/dist/node/entities/quiz.js +304 -0
  113. package/dist/node/events.js +423 -0
  114. package/dist/node/index.js +3833 -0
  115. package/dist/node/learning-journey.capability.js +40 -0
  116. package/dist/node/learning-journey.feature.js +56 -0
  117. package/dist/node/track-spec.js +0 -0
  118. package/dist/track-spec.d.ts +115 -118
  119. package/dist/track-spec.d.ts.map +1 -1
  120. package/dist/track-spec.js +1 -0
  121. package/package.json +237 -60
  122. package/dist/contracts/models.js.map +0 -1
  123. package/dist/contracts/onboarding.js.map +0 -1
  124. package/dist/contracts/operations.js.map +0 -1
  125. package/dist/contracts/shared.js.map +0 -1
  126. package/dist/docs/learning-journey.docblock.js.map +0 -1
  127. package/dist/engines/srs.js.map +0 -1
  128. package/dist/engines/streak.js.map +0 -1
  129. package/dist/engines/xp.js.map +0 -1
  130. package/dist/entities/ai.js.map +0 -1
  131. package/dist/entities/course.js.map +0 -1
  132. package/dist/entities/flashcard.js.map +0 -1
  133. package/dist/entities/gamification.js.map +0 -1
  134. package/dist/entities/index.js.map +0 -1
  135. package/dist/entities/learner.js.map +0 -1
  136. package/dist/entities/onboarding.js.map +0 -1
  137. package/dist/entities/quiz.js.map +0 -1
  138. package/dist/events.js.map +0 -1
  139. package/dist/learning-journey.capability.js.map +0 -1
  140. package/dist/learning-journey.feature.js.map +0 -1
@@ -1,151 +1,327 @@
1
- import { LEARNING_JOURNEY_OWNERS } from "./shared.js";
2
- import { CompleteLessonInput, EnrollInCourseInput, EnrollmentModel, GetDueCardsInput, GetDueCardsOutput, GetLearnerDashboardInput, LearnerDashboardModel, SubmitCardReviewInput, SuccessOutput } from "./models.js";
3
- import { defineCommand, defineQuery } from "@contractspec/lib.contracts";
1
+ // @bun
2
+ // src/contracts/shared.ts
3
+ var LEARNING_JOURNEY_OWNERS = ["modules.learning-journey"];
4
4
 
5
- //#region src/contracts/operations.ts
6
- /**
7
- * Enroll in a course.
8
- */
9
- const EnrollInCourseContract = defineCommand({
10
- meta: {
11
- key: "learning.enroll",
12
- version: "1.0.0",
13
- stability: "stable",
14
- owners: [...LEARNING_JOURNEY_OWNERS],
15
- tags: ["learning", "enrollment"],
16
- description: "Enroll in a course.",
17
- goal: "Start learning a new course.",
18
- context: "Called when a learner wants to start a course."
19
- },
20
- io: {
21
- input: EnrollInCourseInput,
22
- output: EnrollmentModel,
23
- errors: {
24
- COURSE_NOT_FOUND: {
25
- description: "Course does not exist",
26
- http: 404,
27
- gqlCode: "COURSE_NOT_FOUND",
28
- when: "Course ID is invalid"
29
- },
30
- ALREADY_ENROLLED: {
31
- description: "Already enrolled in course",
32
- http: 409,
33
- gqlCode: "ALREADY_ENROLLED",
34
- when: "Learner is already enrolled"
35
- }
36
- }
37
- },
38
- policy: { auth: "user" }
39
- });
40
- /**
41
- * Complete a lesson.
42
- */
43
- const CompleteLessonContract = defineCommand({
44
- meta: {
45
- key: "learning.completeLesson",
46
- version: "1.0.0",
47
- stability: "stable",
48
- owners: [...LEARNING_JOURNEY_OWNERS],
49
- tags: ["learning", "progress"],
50
- description: "Mark a lesson as completed.",
51
- goal: "Record lesson completion and earn XP.",
52
- context: "Called when a learner finishes a lesson."
53
- },
54
- io: {
55
- input: CompleteLessonInput,
56
- output: SuccessOutput,
57
- errors: {
58
- LESSON_NOT_FOUND: {
59
- description: "Lesson does not exist",
60
- http: 404,
61
- gqlCode: "LESSON_NOT_FOUND",
62
- when: "Lesson ID is invalid"
63
- },
64
- NOT_ENROLLED: {
65
- description: "Not enrolled in course",
66
- http: 403,
67
- gqlCode: "NOT_ENROLLED",
68
- when: "Learner is not enrolled in the course"
69
- }
70
- }
71
- },
72
- policy: { auth: "user" }
73
- });
74
- /**
75
- * Submit a card review.
76
- */
77
- const SubmitCardReviewContract = defineCommand({
78
- meta: {
79
- key: "learning.submitCardReview",
80
- version: "1.0.0",
81
- stability: "stable",
82
- owners: [...LEARNING_JOURNEY_OWNERS],
83
- tags: ["learning", "flashcards"],
84
- description: "Submit a flashcard review.",
85
- goal: "Record review and update SRS schedule.",
86
- context: "Called when reviewing flashcards."
87
- },
88
- io: {
89
- input: SubmitCardReviewInput,
90
- output: SuccessOutput,
91
- errors: {
92
- CARD_NOT_FOUND: {
93
- description: "Card does not exist",
94
- http: 404,
95
- gqlCode: "CARD_NOT_FOUND",
96
- when: "Card ID is invalid"
97
- },
98
- INVALID_RATING: {
99
- description: "Invalid rating",
100
- http: 400,
101
- gqlCode: "INVALID_RATING",
102
- when: "Rating must be AGAIN, HARD, GOOD, or EASY"
103
- }
104
- }
105
- },
106
- policy: { auth: "user" }
107
- });
108
- /**
109
- * Get cards due for review.
110
- */
111
- const GetDueCardsContract = defineQuery({
112
- meta: {
113
- key: "learning.getDueCards",
114
- version: "1.0.0",
115
- stability: "stable",
116
- owners: [...LEARNING_JOURNEY_OWNERS],
117
- tags: ["learning", "flashcards"],
118
- description: "Get flashcards due for review.",
119
- goal: "Get the next batch of cards to review.",
120
- context: "Called when starting a review session."
121
- },
122
- io: {
123
- input: GetDueCardsInput,
124
- output: GetDueCardsOutput
125
- },
126
- policy: { auth: "user" }
127
- });
128
- /**
129
- * Get learner dashboard.
130
- */
131
- const GetLearnerDashboardContract = defineQuery({
132
- meta: {
133
- key: "learning.getDashboard",
134
- version: "1.0.0",
135
- stability: "stable",
136
- owners: [...LEARNING_JOURNEY_OWNERS],
137
- tags: ["learning", "dashboard"],
138
- description: "Get learner dashboard data.",
139
- goal: "Display learner progress and stats.",
140
- context: "Called when viewing the learning dashboard."
141
- },
142
- io: {
143
- input: GetLearnerDashboardInput,
144
- output: LearnerDashboardModel
145
- },
146
- policy: { auth: "user" }
5
+ // src/contracts/models.ts
6
+ import { ScalarTypeEnum, defineSchemaModel } from "@contractspec/lib.schema";
7
+ var CourseModel = defineSchemaModel({
8
+ name: "Course",
9
+ description: "A learning course",
10
+ fields: {
11
+ id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
12
+ title: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
13
+ slug: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
14
+ description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
15
+ difficulty: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
16
+ status: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
17
+ estimatedDuration: {
18
+ type: ScalarTypeEnum.Int_unsecure(),
19
+ isOptional: true
20
+ },
21
+ thumbnailUrl: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
22
+ createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false }
23
+ }
24
+ });
25
+ var LearnerModel = defineSchemaModel({
26
+ name: "Learner",
27
+ description: "A learner profile",
28
+ fields: {
29
+ id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
30
+ userId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
31
+ displayName: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
32
+ level: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
33
+ totalXp: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
34
+ currentStreak: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
35
+ longestStreak: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
36
+ createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false }
37
+ }
38
+ });
39
+ var EnrollmentModel = defineSchemaModel({
40
+ name: "Enrollment",
41
+ description: "A course enrollment",
42
+ fields: {
43
+ id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
44
+ learnerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
45
+ courseId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
46
+ status: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
47
+ progress: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
48
+ startedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },
49
+ completedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true }
50
+ }
51
+ });
52
+ var ProgressModel = defineSchemaModel({
53
+ name: "LessonProgress",
54
+ description: "Lesson progress",
55
+ fields: {
56
+ id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
57
+ learnerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
58
+ lessonId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
59
+ status: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
60
+ progress: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
61
+ score: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },
62
+ timeSpent: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
63
+ completedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true }
64
+ }
65
+ });
66
+ var DeckModel = defineSchemaModel({
67
+ name: "Deck",
68
+ description: "A flashcard deck",
69
+ fields: {
70
+ id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
71
+ title: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
72
+ description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
73
+ cardCount: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
74
+ isPublic: { type: ScalarTypeEnum.Boolean(), isOptional: false },
75
+ createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false }
76
+ }
77
+ });
78
+ var CardModel = defineSchemaModel({
79
+ name: "Card",
80
+ description: "A flashcard",
81
+ fields: {
82
+ id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
83
+ deckId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
84
+ front: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
85
+ back: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
86
+ hints: { type: ScalarTypeEnum.JSON(), isOptional: true },
87
+ isDue: { type: ScalarTypeEnum.Boolean(), isOptional: false },
88
+ nextReviewAt: { type: ScalarTypeEnum.DateTime(), isOptional: true }
89
+ }
90
+ });
91
+ var AchievementModel = defineSchemaModel({
92
+ name: "Achievement",
93
+ description: "An achievement",
94
+ fields: {
95
+ id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
96
+ key: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
97
+ name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
98
+ description: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
99
+ icon: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
100
+ xpReward: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
101
+ unlockedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true }
102
+ }
103
+ });
104
+ var EnrollInCourseInput = defineSchemaModel({
105
+ name: "EnrollInCourseInput",
106
+ description: "Input for enrolling in a course",
107
+ fields: {
108
+ courseId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false }
109
+ }
110
+ });
111
+ var CompleteLessonInput = defineSchemaModel({
112
+ name: "CompleteLessonInput",
113
+ description: "Input for completing a lesson",
114
+ fields: {
115
+ lessonId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
116
+ score: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },
117
+ timeSpent: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false }
118
+ }
119
+ });
120
+ var SubmitCardReviewInput = defineSchemaModel({
121
+ name: "SubmitCardReviewInput",
122
+ description: "Input for submitting a card review",
123
+ fields: {
124
+ cardId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
125
+ rating: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
126
+ responseTimeMs: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true }
127
+ }
128
+ });
129
+ var GetDueCardsInput = defineSchemaModel({
130
+ name: "GetDueCardsInput",
131
+ description: "Input for getting due cards",
132
+ fields: {
133
+ deckId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
134
+ limit: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true }
135
+ }
136
+ });
137
+ var GetDueCardsOutput = defineSchemaModel({
138
+ name: "GetDueCardsOutput",
139
+ description: "Output for getting due cards",
140
+ fields: {
141
+ cards: { type: CardModel, isArray: true, isOptional: false },
142
+ total: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false }
143
+ }
144
+ });
145
+ var GetLearnerDashboardInput = defineSchemaModel({
146
+ name: "GetLearnerDashboardInput",
147
+ description: "Input for getting learner dashboard",
148
+ fields: {
149
+ learnerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true }
150
+ }
151
+ });
152
+ var LearnerDashboardModel = defineSchemaModel({
153
+ name: "LearnerDashboard",
154
+ description: "Learner dashboard data",
155
+ fields: {
156
+ learner: { type: LearnerModel, isOptional: false },
157
+ currentStreak: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
158
+ dailyXpGoal: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
159
+ dailyXpProgress: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
160
+ activeEnrollments: {
161
+ type: EnrollmentModel,
162
+ isArray: true,
163
+ isOptional: false
164
+ },
165
+ recentAchievements: {
166
+ type: AchievementModel,
167
+ isArray: true,
168
+ isOptional: false
169
+ },
170
+ dueCardCount: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false }
171
+ }
172
+ });
173
+ var SuccessOutput = defineSchemaModel({
174
+ name: "SuccessOutput",
175
+ description: "Generic success output",
176
+ fields: {
177
+ success: { type: ScalarTypeEnum.Boolean(), isOptional: false },
178
+ xpEarned: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true }
179
+ }
147
180
  });
148
181
 
149
- //#endregion
150
- export { CompleteLessonContract, EnrollInCourseContract, GetDueCardsContract, GetLearnerDashboardContract, SubmitCardReviewContract };
151
- //# sourceMappingURL=operations.js.map
182
+ // src/contracts/operations.ts
183
+ import { defineCommand, defineQuery } from "@contractspec/lib.contracts";
184
+ var EnrollInCourseContract = defineCommand({
185
+ meta: {
186
+ key: "learning.enroll",
187
+ version: "1.0.0",
188
+ stability: "stable",
189
+ owners: [...LEARNING_JOURNEY_OWNERS],
190
+ tags: ["learning", "enrollment"],
191
+ description: "Enroll in a course.",
192
+ goal: "Start learning a new course.",
193
+ context: "Called when a learner wants to start a course."
194
+ },
195
+ io: {
196
+ input: EnrollInCourseInput,
197
+ output: EnrollmentModel,
198
+ errors: {
199
+ COURSE_NOT_FOUND: {
200
+ description: "Course does not exist",
201
+ http: 404,
202
+ gqlCode: "COURSE_NOT_FOUND",
203
+ when: "Course ID is invalid"
204
+ },
205
+ ALREADY_ENROLLED: {
206
+ description: "Already enrolled in course",
207
+ http: 409,
208
+ gqlCode: "ALREADY_ENROLLED",
209
+ when: "Learner is already enrolled"
210
+ }
211
+ }
212
+ },
213
+ policy: {
214
+ auth: "user"
215
+ }
216
+ });
217
+ var CompleteLessonContract = defineCommand({
218
+ meta: {
219
+ key: "learning.completeLesson",
220
+ version: "1.0.0",
221
+ stability: "stable",
222
+ owners: [...LEARNING_JOURNEY_OWNERS],
223
+ tags: ["learning", "progress"],
224
+ description: "Mark a lesson as completed.",
225
+ goal: "Record lesson completion and earn XP.",
226
+ context: "Called when a learner finishes a lesson."
227
+ },
228
+ io: {
229
+ input: CompleteLessonInput,
230
+ output: SuccessOutput,
231
+ errors: {
232
+ LESSON_NOT_FOUND: {
233
+ description: "Lesson does not exist",
234
+ http: 404,
235
+ gqlCode: "LESSON_NOT_FOUND",
236
+ when: "Lesson ID is invalid"
237
+ },
238
+ NOT_ENROLLED: {
239
+ description: "Not enrolled in course",
240
+ http: 403,
241
+ gqlCode: "NOT_ENROLLED",
242
+ when: "Learner is not enrolled in the course"
243
+ }
244
+ }
245
+ },
246
+ policy: {
247
+ auth: "user"
248
+ }
249
+ });
250
+ var SubmitCardReviewContract = defineCommand({
251
+ meta: {
252
+ key: "learning.submitCardReview",
253
+ version: "1.0.0",
254
+ stability: "stable",
255
+ owners: [...LEARNING_JOURNEY_OWNERS],
256
+ tags: ["learning", "flashcards"],
257
+ description: "Submit a flashcard review.",
258
+ goal: "Record review and update SRS schedule.",
259
+ context: "Called when reviewing flashcards."
260
+ },
261
+ io: {
262
+ input: SubmitCardReviewInput,
263
+ output: SuccessOutput,
264
+ errors: {
265
+ CARD_NOT_FOUND: {
266
+ description: "Card does not exist",
267
+ http: 404,
268
+ gqlCode: "CARD_NOT_FOUND",
269
+ when: "Card ID is invalid"
270
+ },
271
+ INVALID_RATING: {
272
+ description: "Invalid rating",
273
+ http: 400,
274
+ gqlCode: "INVALID_RATING",
275
+ when: "Rating must be AGAIN, HARD, GOOD, or EASY"
276
+ }
277
+ }
278
+ },
279
+ policy: {
280
+ auth: "user"
281
+ }
282
+ });
283
+ var GetDueCardsContract = defineQuery({
284
+ meta: {
285
+ key: "learning.getDueCards",
286
+ version: "1.0.0",
287
+ stability: "stable",
288
+ owners: [...LEARNING_JOURNEY_OWNERS],
289
+ tags: ["learning", "flashcards"],
290
+ description: "Get flashcards due for review.",
291
+ goal: "Get the next batch of cards to review.",
292
+ context: "Called when starting a review session."
293
+ },
294
+ io: {
295
+ input: GetDueCardsInput,
296
+ output: GetDueCardsOutput
297
+ },
298
+ policy: {
299
+ auth: "user"
300
+ }
301
+ });
302
+ var GetLearnerDashboardContract = defineQuery({
303
+ meta: {
304
+ key: "learning.getDashboard",
305
+ version: "1.0.0",
306
+ stability: "stable",
307
+ owners: [...LEARNING_JOURNEY_OWNERS],
308
+ tags: ["learning", "dashboard"],
309
+ description: "Get learner dashboard data.",
310
+ goal: "Display learner progress and stats.",
311
+ context: "Called when viewing the learning dashboard."
312
+ },
313
+ io: {
314
+ input: GetLearnerDashboardInput,
315
+ output: LearnerDashboardModel
316
+ },
317
+ policy: {
318
+ auth: "user"
319
+ }
320
+ });
321
+ export {
322
+ SubmitCardReviewContract,
323
+ GetLearnerDashboardContract,
324
+ GetDueCardsContract,
325
+ EnrollInCourseContract,
326
+ CompleteLessonContract
327
+ };
@@ -1,5 +1,2 @@
1
- //#region src/contracts/shared.d.ts
2
- declare const LEARNING_JOURNEY_OWNERS: readonly ["modules.learning-journey"];
3
- //#endregion
4
- export { LEARNING_JOURNEY_OWNERS };
1
+ export declare const LEARNING_JOURNEY_OWNERS: readonly ["modules.learning-journey"];
5
2
  //# sourceMappingURL=shared.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","names":[],"sources":["../../src/contracts/shared.ts"],"mappings":";cAAa,uBAAA"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/contracts/shared.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB,uCAAwC,CAAC"}
@@ -1,6 +1,6 @@
1
- //#region src/contracts/shared.ts
2
- const LEARNING_JOURNEY_OWNERS = ["modules.learning-journey"];
3
-
4
- //#endregion
5
- export { LEARNING_JOURNEY_OWNERS };
6
- //# sourceMappingURL=shared.js.map
1
+ // @bun
2
+ // src/contracts/shared.ts
3
+ var LEARNING_JOURNEY_OWNERS = ["modules.learning-journey"];
4
+ export {
5
+ LEARNING_JOURNEY_OWNERS
6
+ };
@@ -1 +1,2 @@
1
- export { };
1
+ import './learning-journey.docblock';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/docs/index.ts"],"names":[],"mappings":"AAAA,OAAO,6BAA6B,CAAC"}
@@ -1 +1,125 @@
1
- import "./learning-journey.docblock.js";
1
+ // @bun
2
+ // src/docs/learning-journey.docblock.ts
3
+ import { registerDocBlocks } from "@contractspec/lib.contracts/docs";
4
+ var learningJourneyDocBlocks = [
5
+ {
6
+ id: "docs.learning-journey.engine",
7
+ title: "Learning Journey Engine",
8
+ summary: "Tracks learners, tracks/modules/steps, progress, quizzes, streaks, XP, and AI coaching hooks for product-integrated onboarding.",
9
+ kind: "reference",
10
+ visibility: "public",
11
+ route: "/docs/learning-journey/engine",
12
+ tags: ["learning", "onboarding", "journey", "education"],
13
+ body: `## Capabilities
14
+
15
+ - **Entities**: Learner, Track, Module, Step, Progress, Quiz, Flashcard, AI Coach, Gamification (XP, streaks, badges).
16
+ - **Contracts**: enroll/resume/advance steps, complete quizzes, record streaks, assign XP, fetch progress dashboards, onboarding list/progress/recordEvent.
17
+ - **Engines**: spaced-repetition (SRS), streak calculator, XP progression.
18
+ - **Events**: learner.enrolled, step.completed, quiz.scored, streak.reset, xp.awarded, onboarding.started/completed/step_completed.
19
+
20
+ ## Completion conditions
21
+ - Event-based: name/version/source + payload filter
22
+ - Count-based: require N events (optional time window)
23
+ - Time-bounded: must complete within a window; steps can unlock by day/hour
24
+ - SRS mastery: complete when cards/skills hit mastery thresholds (with required counts)
25
+
26
+ ## Usage
27
+
28
+ 1) Compose schema
29
+ - Include \`learningJourneySchemaContribution\` (entities export) in composition.
30
+
31
+ 2) Register contracts/events
32
+ - Import from \`@contractspec/module.learning-journey\` into your spec registry.
33
+
34
+ 3) Bind to product actions
35
+ - Tie \`Step\` completion conditions to domain events (e.g., deal.created, agent.run.completed, drill.session.completed).
36
+ - Trigger notifications via Notification Center and audits on completion.
37
+
38
+ 4) Gamification
39
+ - Use \`XP\` and \`Streak\` engines to update learner stats; emit analytics for UI.
40
+
41
+ ## Example
42
+
43
+ ${"```"}ts
44
+ import { learningJourneyEntities } from '@contractspec/module.learning-journey';
45
+ import { StreakEngine } from '@contractspec/module.learning-journey/engines';
46
+
47
+ const streak = new StreakEngine({ graceDays: 1 });
48
+ const updated = streak.compute({ lastActiveAt: new Date(), today: new Date() });
49
+ ${"```"},
50
+
51
+ ## Guardrails
52
+
53
+ - Keep steps bound to real product events, not just button clicks.
54
+ - Avoid storing PII in content; keep org/user scoping for multi-tenant isolation.
55
+ - Emit analytics and audit logs for completions; respect \`prefers-reduced-motion\` in UIs consuming these specs.
56
+ - Track completion bonuses: \`completionXpBonus\`, \`completionBadgeKey\`, optional \`streakHoursWindow\` + \`streakBonusXp\`.
57
+ `
58
+ },
59
+ {
60
+ id: "docs.learning-journey.goal",
61
+ title: "Learning Journey \u2014 Goal",
62
+ summary: "Why the learning journey engine exists and the outcomes it targets.",
63
+ kind: "goal",
64
+ visibility: "public",
65
+ route: "/docs/learning-journey/goal",
66
+ tags: ["learning", "goal"],
67
+ body: `## Why it matters
68
+ - Provides a regenerable onboarding/education engine tied to product signals.
69
+ - Keeps tracks, steps, quizzes, and gamification consistent across surfaces.
70
+
71
+ ## Business/Product goal
72
+ - Drive activation and retention with measurable progress, SRS, and streaks.
73
+ - Allow product teams to adjust journeys safely via specs.
74
+
75
+ ## Success criteria
76
+ - Journey changes regenerate UI/API/events without drift.
77
+ - Analytics/audit hooks exist for completions and streaks.`
78
+ },
79
+ {
80
+ id: "docs.learning-journey.usage",
81
+ title: "Learning Journey \u2014 Usage",
82
+ summary: "How to compose, bind, and regenerate journeys safely.",
83
+ kind: "usage",
84
+ visibility: "public",
85
+ route: "/docs/learning-journey/usage",
86
+ tags: ["learning", "usage"],
87
+ body: `## Setup
88
+ 1) Include \`learningJourneyEntities\` in schema composition.
89
+ 2) Register contracts/events from \`@contractspec/module.learning-journey\`.
90
+ 3) Bind steps to real product events (e.g., deal.created, run.completed).
91
+
92
+ ## Extend & regenerate
93
+ 1) Update track/module/step definitions or quiz schemas in spec.
94
+ 2) Regenerate to sync UI/API/events; mark PII paths where needed.
95
+ 3) Use Feature Flags to trial new tracks or streak rules.
96
+
97
+ ## Guardrails
98
+ - Avoid hardcoded progression; keep engines declarative.
99
+ - Emit analytics/audit for completions; respect user locale/accessibility in presentations.
100
+ - Keep content free of PII; scope learners by org/tenant.`
101
+ },
102
+ {
103
+ id: "docs.learning-journey.constraints",
104
+ title: "Learning Journey \u2014 Constraints & Safety",
105
+ summary: "Internal guardrails for progression, telemetry, and regeneration semantics.",
106
+ kind: "reference",
107
+ visibility: "internal",
108
+ route: "/docs/learning-journey/constraints",
109
+ tags: ["learning", "constraints", "internal"],
110
+ body: `## Constraints
111
+ - Progression (tracks/modules/steps) and engines (SRS, streaks, XP) must stay declarative in spec.
112
+ - Events to emit: learner.enrolled, step.completed, quiz.scored, streak.reset, xp.awarded.
113
+ - Regeneration should not change scoring/streak rules without explicit spec change.
114
+
115
+ ## PII & Telemetry
116
+ - Mark PII (learner identifiers) and redact in presentations; keep telemetry aggregated when possible.
117
+ - Respect accessibility (prefers-reduced-motion) in UIs consuming these specs.
118
+
119
+ ## Verification
120
+ - Add fixtures for streak/XP rule changes and quiz scoring.
121
+ - Ensure Notifications/Audit wiring persists for completions; analytics emitted for progress.
122
+ - Use Feature Flags to trial new tracks or reward rules; default safe/off.`
123
+ }
124
+ ];
125
+ registerDocBlocks(learningJourneyDocBlocks);
@@ -1 +1,2 @@
1
- export { };
1
+ export {};
2
+ //# sourceMappingURL=learning-journey.docblock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"learning-journey.docblock.d.ts","sourceRoot":"","sources":["../../src/docs/learning-journey.docblock.ts"],"names":[],"mappings":""}