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