@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
@@ -0,0 +1,340 @@
1
+ // src/entities/gamification.ts
2
+ import {
3
+ defineEntity,
4
+ defineEntityEnum,
5
+ field,
6
+ index
7
+ } from "@contractspec/lib.schema";
8
+ var AchievementTypeEnum = defineEntityEnum({
9
+ name: "AchievementType",
10
+ values: [
11
+ "MILESTONE",
12
+ "STREAK",
13
+ "SKILL",
14
+ "SOCIAL",
15
+ "SPECIAL",
16
+ "SEASONAL"
17
+ ],
18
+ schema: "lssm_learning",
19
+ description: "Type of achievement."
20
+ });
21
+ var LeaderboardPeriodEnum = defineEntityEnum({
22
+ name: "LeaderboardPeriod",
23
+ values: ["DAILY", "WEEKLY", "MONTHLY", "ALL_TIME"],
24
+ schema: "lssm_learning",
25
+ description: "Leaderboard time period."
26
+ });
27
+ var AchievementEntity = defineEntity({
28
+ name: "Achievement",
29
+ description: "An achievement that can be unlocked.",
30
+ schema: "lssm_learning",
31
+ map: "achievement",
32
+ fields: {
33
+ id: field.id({ description: "Unique achievement identifier" }),
34
+ key: field.string({ isUnique: true, description: "Achievement key" }),
35
+ name: field.string({ description: "Achievement name" }),
36
+ description: field.string({ description: "Achievement description" }),
37
+ icon: field.string({ isOptional: true, description: "Icon name or URL" }),
38
+ color: field.string({ isOptional: true, description: "Display color" }),
39
+ badgeUrl: field.string({
40
+ isOptional: true,
41
+ description: "Badge image URL"
42
+ }),
43
+ type: field.enum("AchievementType", {
44
+ default: "MILESTONE",
45
+ description: "Achievement type"
46
+ }),
47
+ category: field.string({
48
+ isOptional: true,
49
+ description: "Achievement category"
50
+ }),
51
+ rarity: field.string({
52
+ default: '"common"',
53
+ description: "Rarity: common, rare, epic, legendary"
54
+ }),
55
+ xpReward: field.int({ default: 50, description: "XP awarded" }),
56
+ condition: field.json({ description: "Unlock condition" }),
57
+ order: field.int({ default: 0, description: "Display order" }),
58
+ isHidden: field.boolean({
59
+ default: false,
60
+ description: "Hide until unlocked"
61
+ }),
62
+ isActive: field.boolean({
63
+ default: true,
64
+ description: "Whether achievement is active"
65
+ }),
66
+ orgId: field.string({
67
+ isOptional: true,
68
+ description: "Organization scope"
69
+ }),
70
+ metadata: field.json({
71
+ isOptional: true,
72
+ description: "Additional metadata"
73
+ }),
74
+ createdAt: field.createdAt(),
75
+ updatedAt: field.updatedAt(),
76
+ learnerAchievements: field.hasMany("LearnerAchievement")
77
+ },
78
+ indexes: [
79
+ index.on(["type"]),
80
+ index.on(["category"]),
81
+ index.on(["isActive"]),
82
+ index.on(["orgId"])
83
+ ],
84
+ enums: [AchievementTypeEnum]
85
+ });
86
+ var LearnerAchievementEntity = defineEntity({
87
+ name: "LearnerAchievement",
88
+ description: "An achievement unlocked by a learner.",
89
+ schema: "lssm_learning",
90
+ map: "learner_achievement",
91
+ fields: {
92
+ id: field.id({ description: "Unique record identifier" }),
93
+ learnerId: field.foreignKey({ description: "Learner" }),
94
+ achievementId: field.foreignKey({ description: "Achievement" }),
95
+ xpEarned: field.int({ default: 0, description: "XP earned" }),
96
+ progress: field.int({ default: 100, description: "Progress percentage" }),
97
+ currentValue: field.int({
98
+ isOptional: true,
99
+ description: "Current value towards goal"
100
+ }),
101
+ targetValue: field.int({
102
+ isOptional: true,
103
+ description: "Target value for completion"
104
+ }),
105
+ unlockedAt: field.dateTime({ description: "When unlocked" }),
106
+ createdAt: field.createdAt(),
107
+ learner: field.belongsTo("Learner", ["learnerId"], ["id"], {
108
+ onDelete: "Cascade"
109
+ }),
110
+ achievement: field.belongsTo("Achievement", ["achievementId"], ["id"], {
111
+ onDelete: "Cascade"
112
+ })
113
+ },
114
+ indexes: [
115
+ index.unique(["learnerId", "achievementId"], {
116
+ name: "learner_achievement_unique"
117
+ }),
118
+ index.on(["learnerId", "unlockedAt"]),
119
+ index.on(["achievementId"])
120
+ ]
121
+ });
122
+ var StreakEntity = defineEntity({
123
+ name: "Streak",
124
+ description: "Tracks daily learning streaks.",
125
+ schema: "lssm_learning",
126
+ map: "streak",
127
+ fields: {
128
+ id: field.id({ description: "Unique streak identifier" }),
129
+ learnerId: field.foreignKey({ description: "Learner" }),
130
+ currentStreak: field.int({
131
+ default: 0,
132
+ description: "Current streak days"
133
+ }),
134
+ longestStreak: field.int({
135
+ default: 0,
136
+ description: "Longest streak ever"
137
+ }),
138
+ lastActivityAt: field.dateTime({
139
+ isOptional: true,
140
+ description: "Last learning activity"
141
+ }),
142
+ lastActivityDate: field.string({
143
+ isOptional: true,
144
+ description: "Last activity date (YYYY-MM-DD)"
145
+ }),
146
+ freezesRemaining: field.int({
147
+ default: 0,
148
+ description: "Streak freezes available"
149
+ }),
150
+ freezeUsedAt: field.dateTime({
151
+ isOptional: true,
152
+ description: "When last freeze was used"
153
+ }),
154
+ streakHistory: field.json({
155
+ isOptional: true,
156
+ description: "Historical streak data"
157
+ }),
158
+ createdAt: field.createdAt(),
159
+ updatedAt: field.updatedAt(),
160
+ learner: field.belongsTo("Learner", ["learnerId"], ["id"], {
161
+ onDelete: "Cascade"
162
+ })
163
+ },
164
+ indexes: [
165
+ index.unique(["learnerId"], { name: "streak_learner_unique" }),
166
+ index.on(["currentStreak"]),
167
+ index.on(["longestStreak"])
168
+ ]
169
+ });
170
+ var DailyGoalEntity = defineEntity({
171
+ name: "DailyGoal",
172
+ description: "Daily XP goal tracking.",
173
+ schema: "lssm_learning",
174
+ map: "daily_goal",
175
+ fields: {
176
+ id: field.id({ description: "Unique goal identifier" }),
177
+ learnerId: field.foreignKey({ description: "Learner" }),
178
+ date: field.string({ description: "Date (YYYY-MM-DD)" }),
179
+ targetXp: field.int({ description: "Target XP for the day" }),
180
+ currentXp: field.int({ default: 0, description: "XP earned today" }),
181
+ isCompleted: field.boolean({
182
+ default: false,
183
+ description: "Whether goal was met"
184
+ }),
185
+ completedAt: field.dateTime({
186
+ isOptional: true,
187
+ description: "When goal was completed"
188
+ }),
189
+ xpBreakdown: field.json({
190
+ isOptional: true,
191
+ description: "XP sources breakdown"
192
+ }),
193
+ createdAt: field.createdAt(),
194
+ updatedAt: field.updatedAt(),
195
+ learner: field.belongsTo("Learner", ["learnerId"], ["id"], {
196
+ onDelete: "Cascade"
197
+ })
198
+ },
199
+ indexes: [
200
+ index.unique(["learnerId", "date"], { name: "daily_goal_unique" }),
201
+ index.on(["date", "isCompleted"])
202
+ ]
203
+ });
204
+ var LeaderboardEntryEntity = defineEntity({
205
+ name: "LeaderboardEntry",
206
+ description: "Leaderboard entry for a learner.",
207
+ schema: "lssm_learning",
208
+ map: "leaderboard_entry",
209
+ fields: {
210
+ id: field.id({ description: "Unique entry identifier" }),
211
+ learnerId: field.foreignKey({ description: "Learner" }),
212
+ periodType: field.enum("LeaderboardPeriod", { description: "Period type" }),
213
+ periodKey: field.string({ description: "Period key (e.g., 2024-W01)" }),
214
+ xp: field.int({ default: 0, description: "XP earned in period" }),
215
+ rank: field.int({ isOptional: true, description: "Rank in leaderboard" }),
216
+ lessonsCompleted: field.int({
217
+ default: 0,
218
+ description: "Lessons completed"
219
+ }),
220
+ quizzesPassed: field.int({ default: 0, description: "Quizzes passed" }),
221
+ cardsReviewed: field.int({ default: 0, description: "Cards reviewed" }),
222
+ streakDays: field.int({ default: 0, description: "Streak days in period" }),
223
+ league: field.string({ isOptional: true, description: "League tier" }),
224
+ orgId: field.string({
225
+ isOptional: true,
226
+ description: "Organization scope"
227
+ }),
228
+ createdAt: field.createdAt(),
229
+ updatedAt: field.updatedAt(),
230
+ learner: field.belongsTo("Learner", ["learnerId"], ["id"], {
231
+ onDelete: "Cascade"
232
+ })
233
+ },
234
+ indexes: [
235
+ index.unique(["learnerId", "periodType", "periodKey"], {
236
+ name: "leaderboard_entry_unique"
237
+ }),
238
+ index.on(["periodType", "periodKey", "xp"]),
239
+ index.on(["orgId", "periodType", "periodKey", "xp"])
240
+ ],
241
+ enums: [LeaderboardPeriodEnum]
242
+ });
243
+ var HeartEntity = defineEntity({
244
+ name: "Heart",
245
+ description: "Lives/hearts system for quiz attempts.",
246
+ schema: "lssm_learning",
247
+ map: "heart",
248
+ fields: {
249
+ id: field.id({ description: "Unique heart record identifier" }),
250
+ learnerId: field.foreignKey({ description: "Learner" }),
251
+ current: field.int({ default: 5, description: "Current hearts" }),
252
+ max: field.int({ default: 5, description: "Maximum hearts" }),
253
+ lastRefillAt: field.dateTime({
254
+ isOptional: true,
255
+ description: "Last refill time"
256
+ }),
257
+ nextRefillAt: field.dateTime({
258
+ isOptional: true,
259
+ description: "Next refill time"
260
+ }),
261
+ refillIntervalMinutes: field.int({
262
+ default: 240,
263
+ description: "Minutes between refills"
264
+ }),
265
+ infiniteUntil: field.dateTime({
266
+ isOptional: true,
267
+ description: "Infinite hearts until"
268
+ }),
269
+ createdAt: field.createdAt(),
270
+ updatedAt: field.updatedAt(),
271
+ learner: field.belongsTo("Learner", ["learnerId"], ["id"], {
272
+ onDelete: "Cascade"
273
+ })
274
+ },
275
+ indexes: [
276
+ index.unique(["learnerId"], { name: "heart_learner_unique" }),
277
+ index.on(["nextRefillAt"])
278
+ ]
279
+ });
280
+ var XPTransactionEntity = defineEntity({
281
+ name: "XPTransaction",
282
+ description: "Record of XP earned or spent.",
283
+ schema: "lssm_learning",
284
+ map: "xp_transaction",
285
+ fields: {
286
+ id: field.id({ description: "Unique transaction identifier" }),
287
+ learnerId: field.foreignKey({ description: "Learner" }),
288
+ amount: field.int({
289
+ description: "XP amount (positive = earned, negative = spent)"
290
+ }),
291
+ type: field.string({
292
+ description: "Transaction type (lesson, quiz, streak, achievement, etc.)"
293
+ }),
294
+ sourceType: field.string({
295
+ isOptional: true,
296
+ description: "Source entity type"
297
+ }),
298
+ sourceId: field.string({
299
+ isOptional: true,
300
+ description: "Source entity ID"
301
+ }),
302
+ description: field.string({
303
+ isOptional: true,
304
+ description: "Human-readable description"
305
+ }),
306
+ balanceAfter: field.int({ description: "Total XP after transaction" }),
307
+ createdAt: field.createdAt(),
308
+ learner: field.belongsTo("Learner", ["learnerId"], ["id"], {
309
+ onDelete: "Cascade"
310
+ })
311
+ },
312
+ indexes: [
313
+ index.on(["learnerId", "createdAt"]),
314
+ index.on(["type"]),
315
+ index.on(["sourceType", "sourceId"])
316
+ ]
317
+ });
318
+ var gamificationEntities = [
319
+ AchievementEntity,
320
+ LearnerAchievementEntity,
321
+ StreakEntity,
322
+ DailyGoalEntity,
323
+ LeaderboardEntryEntity,
324
+ HeartEntity,
325
+ XPTransactionEntity
326
+ ];
327
+ var gamificationEnums = [AchievementTypeEnum, LeaderboardPeriodEnum];
328
+ export {
329
+ gamificationEnums,
330
+ gamificationEntities,
331
+ XPTransactionEntity,
332
+ StreakEntity,
333
+ LearnerAchievementEntity,
334
+ LeaderboardPeriodEnum,
335
+ LeaderboardEntryEntity,
336
+ HeartEntity,
337
+ DailyGoalEntity,
338
+ AchievementTypeEnum,
339
+ AchievementEntity
340
+ };