@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,370 +1,305 @@
1
- import { defineEntity, defineEntityEnum, field, index } from "@contractspec/lib.schema";
2
-
3
- //#region src/entities/quiz.ts
4
- /**
5
- * Question type enum.
6
- */
7
- const QuestionTypeEnum = defineEntityEnum({
8
- name: "QuestionType",
9
- values: [
10
- "MULTIPLE_CHOICE",
11
- "TRUE_FALSE",
12
- "FILL_BLANK",
13
- "MATCHING",
14
- "SHORT_ANSWER",
15
- "CODE"
16
- ],
17
- schema: "lssm_learning",
18
- description: "Type of quiz question."
1
+ // @bun
2
+ // src/entities/quiz.ts
3
+ import {
4
+ defineEntity,
5
+ defineEntityEnum,
6
+ field,
7
+ index
8
+ } from "@contractspec/lib.schema";
9
+ var QuestionTypeEnum = defineEntityEnum({
10
+ name: "QuestionType",
11
+ values: [
12
+ "MULTIPLE_CHOICE",
13
+ "TRUE_FALSE",
14
+ "FILL_BLANK",
15
+ "MATCHING",
16
+ "SHORT_ANSWER",
17
+ "CODE"
18
+ ],
19
+ schema: "lssm_learning",
20
+ description: "Type of quiz question."
19
21
  });
20
- /**
21
- * Quiz status enum.
22
- */
23
- const QuizStatusEnum = defineEntityEnum({
24
- name: "QuizStatus",
25
- values: [
26
- "DRAFT",
27
- "PUBLISHED",
28
- "ARCHIVED"
29
- ],
30
- schema: "lssm_learning",
31
- description: "Publication status of a quiz."
22
+ var QuizStatusEnum = defineEntityEnum({
23
+ name: "QuizStatus",
24
+ values: ["DRAFT", "PUBLISHED", "ARCHIVED"],
25
+ schema: "lssm_learning",
26
+ description: "Publication status of a quiz."
32
27
  });
33
- /**
34
- * Attempt status enum.
35
- */
36
- const AttemptStatusEnum = defineEntityEnum({
37
- name: "AttemptStatus",
38
- values: [
39
- "IN_PROGRESS",
40
- "COMPLETED",
41
- "TIMED_OUT",
42
- "ABANDONED"
43
- ],
44
- schema: "lssm_learning",
45
- description: "Status of a quiz attempt."
28
+ var AttemptStatusEnum = defineEntityEnum({
29
+ name: "AttemptStatus",
30
+ values: ["IN_PROGRESS", "COMPLETED", "TIMED_OUT", "ABANDONED"],
31
+ schema: "lssm_learning",
32
+ description: "Status of a quiz attempt."
46
33
  });
47
- /**
48
- * Quiz entity - assessment for a lesson.
49
- */
50
- const QuizEntity = defineEntity({
51
- name: "Quiz",
52
- description: "A quiz assessment.",
53
- schema: "lssm_learning",
54
- map: "quiz",
55
- fields: {
56
- id: field.id({ description: "Unique quiz identifier" }),
57
- lessonId: field.foreignKey({
58
- isOptional: true,
59
- description: "Associated lesson"
60
- }),
61
- title: field.string({ description: "Quiz title" }),
62
- description: field.string({
63
- isOptional: true,
64
- description: "Quiz description"
65
- }),
66
- instructions: field.string({
67
- isOptional: true,
68
- description: "Quiz instructions"
69
- }),
70
- passingScore: field.int({
71
- default: 70,
72
- description: "Passing score percentage"
73
- }),
74
- timeLimit: field.int({
75
- isOptional: true,
76
- description: "Time limit in seconds"
77
- }),
78
- maxAttempts: field.int({
79
- isOptional: true,
80
- description: "Maximum attempts allowed"
81
- }),
82
- shuffleQuestions: field.boolean({
83
- default: false,
84
- description: "Shuffle question order"
85
- }),
86
- shuffleOptions: field.boolean({
87
- default: false,
88
- description: "Shuffle answer options"
89
- }),
90
- showCorrectAnswers: field.boolean({
91
- default: true,
92
- description: "Show correct answers after"
93
- }),
94
- showExplanations: field.boolean({
95
- default: true,
96
- description: "Show explanations after"
97
- }),
98
- status: field.enum("QuizStatus", {
99
- default: "DRAFT",
100
- description: "Publication status"
101
- }),
102
- totalPoints: field.int({
103
- default: 0,
104
- description: "Total points available"
105
- }),
106
- xpReward: field.int({
107
- default: 20,
108
- description: "XP for passing"
109
- }),
110
- orgId: field.string({
111
- isOptional: true,
112
- description: "Organization scope"
113
- }),
114
- metadata: field.json({
115
- isOptional: true,
116
- description: "Additional metadata"
117
- }),
118
- createdAt: field.createdAt(),
119
- updatedAt: field.updatedAt(),
120
- lesson: field.belongsTo("Lesson", ["lessonId"], ["id"], { onDelete: "Cascade" }),
121
- questions: field.hasMany("Question"),
122
- attempts: field.hasMany("QuizAttempt")
123
- },
124
- indexes: [
125
- index.on(["lessonId"]),
126
- index.on(["status"]),
127
- index.on(["orgId"])
128
- ],
129
- enums: [QuizStatusEnum]
34
+ var QuizEntity = defineEntity({
35
+ name: "Quiz",
36
+ description: "A quiz assessment.",
37
+ schema: "lssm_learning",
38
+ map: "quiz",
39
+ fields: {
40
+ id: field.id({ description: "Unique quiz identifier" }),
41
+ lessonId: field.foreignKey({
42
+ isOptional: true,
43
+ description: "Associated lesson"
44
+ }),
45
+ title: field.string({ description: "Quiz title" }),
46
+ description: field.string({
47
+ isOptional: true,
48
+ description: "Quiz description"
49
+ }),
50
+ instructions: field.string({
51
+ isOptional: true,
52
+ description: "Quiz instructions"
53
+ }),
54
+ passingScore: field.int({
55
+ default: 70,
56
+ description: "Passing score percentage"
57
+ }),
58
+ timeLimit: field.int({
59
+ isOptional: true,
60
+ description: "Time limit in seconds"
61
+ }),
62
+ maxAttempts: field.int({
63
+ isOptional: true,
64
+ description: "Maximum attempts allowed"
65
+ }),
66
+ shuffleQuestions: field.boolean({
67
+ default: false,
68
+ description: "Shuffle question order"
69
+ }),
70
+ shuffleOptions: field.boolean({
71
+ default: false,
72
+ description: "Shuffle answer options"
73
+ }),
74
+ showCorrectAnswers: field.boolean({
75
+ default: true,
76
+ description: "Show correct answers after"
77
+ }),
78
+ showExplanations: field.boolean({
79
+ default: true,
80
+ description: "Show explanations after"
81
+ }),
82
+ status: field.enum("QuizStatus", {
83
+ default: "DRAFT",
84
+ description: "Publication status"
85
+ }),
86
+ totalPoints: field.int({
87
+ default: 0,
88
+ description: "Total points available"
89
+ }),
90
+ xpReward: field.int({ default: 20, description: "XP for passing" }),
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
+ lesson: field.belongsTo("Lesson", ["lessonId"], ["id"], {
102
+ onDelete: "Cascade"
103
+ }),
104
+ questions: field.hasMany("Question"),
105
+ attempts: field.hasMany("QuizAttempt")
106
+ },
107
+ indexes: [index.on(["lessonId"]), index.on(["status"]), index.on(["orgId"])],
108
+ enums: [QuizStatusEnum]
130
109
  });
131
- /**
132
- * Question entity - individual quiz question.
133
- */
134
- const QuestionEntity = defineEntity({
135
- name: "Question",
136
- description: "A quiz question.",
137
- schema: "lssm_learning",
138
- map: "question",
139
- fields: {
140
- id: field.id({ description: "Unique question identifier" }),
141
- quizId: field.foreignKey({ description: "Parent quiz" }),
142
- type: field.enum("QuestionType", { description: "Question type" }),
143
- content: field.string({ description: "Question text" }),
144
- mediaUrl: field.string({
145
- isOptional: true,
146
- description: "Question media"
147
- }),
148
- points: field.int({
149
- default: 1,
150
- description: "Points for correct answer"
151
- }),
152
- codeLanguage: field.string({
153
- isOptional: true,
154
- description: "Programming language"
155
- }),
156
- codeTemplate: field.string({
157
- isOptional: true,
158
- description: "Starter code template"
159
- }),
160
- testCases: field.json({
161
- isOptional: true,
162
- description: "Test cases for code validation"
163
- }),
164
- explanation: field.string({
165
- isOptional: true,
166
- description: "Explanation of correct answer"
167
- }),
168
- hint: field.string({
169
- isOptional: true,
170
- description: "Hint for the question"
171
- }),
172
- order: field.int({
173
- default: 0,
174
- description: "Display order"
175
- }),
176
- skillId: field.string({
177
- isOptional: true,
178
- description: "Associated skill"
179
- }),
180
- metadata: field.json({
181
- isOptional: true,
182
- description: "Additional metadata"
183
- }),
184
- createdAt: field.createdAt(),
185
- updatedAt: field.updatedAt(),
186
- quiz: field.belongsTo("Quiz", ["quizId"], ["id"], { onDelete: "Cascade" }),
187
- options: field.hasMany("QuestionOption")
188
- },
189
- indexes: [
190
- index.on(["quizId", "order"]),
191
- index.on(["type"]),
192
- index.on(["skillId"])
193
- ],
194
- enums: [QuestionTypeEnum]
110
+ var QuestionEntity = defineEntity({
111
+ name: "Question",
112
+ description: "A quiz question.",
113
+ schema: "lssm_learning",
114
+ map: "question",
115
+ fields: {
116
+ id: field.id({ description: "Unique question identifier" }),
117
+ quizId: field.foreignKey({ description: "Parent quiz" }),
118
+ type: field.enum("QuestionType", { description: "Question type" }),
119
+ content: field.string({ description: "Question text" }),
120
+ mediaUrl: field.string({ isOptional: true, description: "Question media" }),
121
+ points: field.int({ default: 1, description: "Points for correct answer" }),
122
+ codeLanguage: field.string({
123
+ isOptional: true,
124
+ description: "Programming language"
125
+ }),
126
+ codeTemplate: field.string({
127
+ isOptional: true,
128
+ description: "Starter code template"
129
+ }),
130
+ testCases: field.json({
131
+ isOptional: true,
132
+ description: "Test cases for code validation"
133
+ }),
134
+ explanation: field.string({
135
+ isOptional: true,
136
+ description: "Explanation of correct answer"
137
+ }),
138
+ hint: field.string({
139
+ isOptional: true,
140
+ description: "Hint for the question"
141
+ }),
142
+ order: field.int({ default: 0, description: "Display order" }),
143
+ skillId: field.string({
144
+ isOptional: true,
145
+ description: "Associated skill"
146
+ }),
147
+ metadata: field.json({
148
+ isOptional: true,
149
+ description: "Additional metadata"
150
+ }),
151
+ createdAt: field.createdAt(),
152
+ updatedAt: field.updatedAt(),
153
+ quiz: field.belongsTo("Quiz", ["quizId"], ["id"], { onDelete: "Cascade" }),
154
+ options: field.hasMany("QuestionOption")
155
+ },
156
+ indexes: [
157
+ index.on(["quizId", "order"]),
158
+ index.on(["type"]),
159
+ index.on(["skillId"])
160
+ ],
161
+ enums: [QuestionTypeEnum]
195
162
  });
196
- /**
197
- * QuestionOption entity - answer option for a question.
198
- */
199
- const QuestionOptionEntity = defineEntity({
200
- name: "QuestionOption",
201
- description: "An answer option for a question.",
202
- schema: "lssm_learning",
203
- map: "question_option",
204
- fields: {
205
- id: field.id({ description: "Unique option identifier" }),
206
- questionId: field.foreignKey({ description: "Parent question" }),
207
- content: field.string({ description: "Option text" }),
208
- matchContent: field.string({
209
- isOptional: true,
210
- description: "Match pair content"
211
- }),
212
- isCorrect: field.boolean({
213
- default: false,
214
- description: "Whether option is correct"
215
- }),
216
- feedback: field.string({
217
- isOptional: true,
218
- description: "Feedback when selected"
219
- }),
220
- order: field.int({
221
- default: 0,
222
- description: "Display order"
223
- }),
224
- metadata: field.json({
225
- isOptional: true,
226
- description: "Additional metadata"
227
- }),
228
- createdAt: field.createdAt(),
229
- updatedAt: field.updatedAt(),
230
- question: field.belongsTo("Question", ["questionId"], ["id"], { onDelete: "Cascade" })
231
- },
232
- indexes: [index.on(["questionId", "order"])]
163
+ var QuestionOptionEntity = defineEntity({
164
+ name: "QuestionOption",
165
+ description: "An answer option for a question.",
166
+ schema: "lssm_learning",
167
+ map: "question_option",
168
+ fields: {
169
+ id: field.id({ description: "Unique option identifier" }),
170
+ questionId: field.foreignKey({ description: "Parent question" }),
171
+ content: field.string({ description: "Option text" }),
172
+ matchContent: field.string({
173
+ isOptional: true,
174
+ description: "Match pair content"
175
+ }),
176
+ isCorrect: field.boolean({
177
+ default: false,
178
+ description: "Whether option is correct"
179
+ }),
180
+ feedback: field.string({
181
+ isOptional: true,
182
+ description: "Feedback when selected"
183
+ }),
184
+ order: field.int({ default: 0, description: "Display order" }),
185
+ metadata: field.json({
186
+ isOptional: true,
187
+ description: "Additional metadata"
188
+ }),
189
+ createdAt: field.createdAt(),
190
+ updatedAt: field.updatedAt(),
191
+ question: field.belongsTo("Question", ["questionId"], ["id"], {
192
+ onDelete: "Cascade"
193
+ })
194
+ },
195
+ indexes: [index.on(["questionId", "order"])]
233
196
  });
234
- /**
235
- * QuizAttempt entity - a learner's quiz attempt.
236
- */
237
- const QuizAttemptEntity = defineEntity({
238
- name: "QuizAttempt",
239
- description: "A learner quiz attempt.",
240
- schema: "lssm_learning",
241
- map: "quiz_attempt",
242
- fields: {
243
- id: field.id({ description: "Unique attempt identifier" }),
244
- learnerId: field.foreignKey({ description: "Learner" }),
245
- quizId: field.foreignKey({ description: "Quiz" }),
246
- status: field.enum("AttemptStatus", {
247
- default: "IN_PROGRESS",
248
- description: "Attempt status"
249
- }),
250
- score: field.int({
251
- isOptional: true,
252
- description: "Score achieved"
253
- }),
254
- percentageScore: field.int({
255
- isOptional: true,
256
- description: "Percentage score"
257
- }),
258
- passed: field.boolean({
259
- isOptional: true,
260
- description: "Whether passed"
261
- }),
262
- totalQuestions: field.int({
263
- default: 0,
264
- description: "Total questions"
265
- }),
266
- answeredQuestions: field.int({
267
- default: 0,
268
- description: "Questions answered"
269
- }),
270
- correctAnswers: field.int({
271
- default: 0,
272
- description: "Correct answers"
273
- }),
274
- answers: field.json({
275
- isOptional: true,
276
- description: "Submitted answers"
277
- }),
278
- xpEarned: field.int({
279
- default: 0,
280
- description: "XP earned"
281
- }),
282
- timeSpent: field.int({
283
- default: 0,
284
- description: "Time spent in seconds"
285
- }),
286
- startedAt: field.dateTime({ description: "When started" }),
287
- completedAt: field.dateTime({
288
- isOptional: true,
289
- description: "When completed"
290
- }),
291
- attemptNumber: field.int({
292
- default: 1,
293
- description: "Which attempt this is"
294
- }),
295
- metadata: field.json({
296
- isOptional: true,
297
- description: "Additional metadata"
298
- }),
299
- createdAt: field.createdAt(),
300
- updatedAt: field.updatedAt(),
301
- learner: field.belongsTo("Learner", ["learnerId"], ["id"], { onDelete: "Cascade" }),
302
- quiz: field.belongsTo("Quiz", ["quizId"], ["id"], { onDelete: "Cascade" })
303
- },
304
- indexes: [
305
- index.on(["learnerId", "quizId"]),
306
- index.on(["learnerId", "status"]),
307
- index.on(["quizId", "status"])
308
- ],
309
- enums: [AttemptStatusEnum]
197
+ var QuizAttemptEntity = defineEntity({
198
+ name: "QuizAttempt",
199
+ description: "A learner quiz attempt.",
200
+ schema: "lssm_learning",
201
+ map: "quiz_attempt",
202
+ fields: {
203
+ id: field.id({ description: "Unique attempt identifier" }),
204
+ learnerId: field.foreignKey({ description: "Learner" }),
205
+ quizId: field.foreignKey({ description: "Quiz" }),
206
+ status: field.enum("AttemptStatus", {
207
+ default: "IN_PROGRESS",
208
+ description: "Attempt status"
209
+ }),
210
+ score: field.int({ isOptional: true, description: "Score achieved" }),
211
+ percentageScore: field.int({
212
+ isOptional: true,
213
+ description: "Percentage score"
214
+ }),
215
+ passed: field.boolean({ isOptional: true, description: "Whether passed" }),
216
+ totalQuestions: field.int({ default: 0, description: "Total questions" }),
217
+ answeredQuestions: field.int({
218
+ default: 0,
219
+ description: "Questions answered"
220
+ }),
221
+ correctAnswers: field.int({ default: 0, description: "Correct answers" }),
222
+ answers: field.json({ isOptional: true, description: "Submitted answers" }),
223
+ xpEarned: field.int({ default: 0, description: "XP earned" }),
224
+ timeSpent: field.int({ default: 0, description: "Time spent in seconds" }),
225
+ startedAt: field.dateTime({ description: "When started" }),
226
+ completedAt: field.dateTime({
227
+ isOptional: true,
228
+ description: "When completed"
229
+ }),
230
+ attemptNumber: field.int({
231
+ default: 1,
232
+ description: "Which attempt this is"
233
+ }),
234
+ metadata: field.json({
235
+ isOptional: true,
236
+ description: "Additional metadata"
237
+ }),
238
+ createdAt: field.createdAt(),
239
+ updatedAt: field.updatedAt(),
240
+ learner: field.belongsTo("Learner", ["learnerId"], ["id"], {
241
+ onDelete: "Cascade"
242
+ }),
243
+ quiz: field.belongsTo("Quiz", ["quizId"], ["id"], { onDelete: "Cascade" })
244
+ },
245
+ indexes: [
246
+ index.on(["learnerId", "quizId"]),
247
+ index.on(["learnerId", "status"]),
248
+ index.on(["quizId", "status"])
249
+ ],
250
+ enums: [AttemptStatusEnum]
310
251
  });
311
- /**
312
- * SkillAssessment entity - maps quiz performance to skills.
313
- */
314
- const SkillAssessmentEntity = defineEntity({
315
- name: "SkillAssessment",
316
- description: "Assessment of a skill based on quiz performance.",
317
- schema: "lssm_learning",
318
- map: "skill_assessment",
319
- fields: {
320
- id: field.id({ description: "Unique assessment identifier" }),
321
- learnerId: field.foreignKey({ description: "Learner" }),
322
- skillId: field.string({ description: "Skill identifier" }),
323
- skillName: field.string({ description: "Skill name" }),
324
- level: field.int({
325
- default: 1,
326
- description: "Proficiency level (1-5)"
327
- }),
328
- score: field.int({
329
- default: 0,
330
- description: "Assessment score (0-100)"
331
- }),
332
- confidence: field.decimal({
333
- default: .5,
334
- description: "Confidence in assessment"
335
- }),
336
- questionsAnswered: field.int({
337
- default: 0,
338
- description: "Total questions answered"
339
- }),
340
- questionsCorrect: field.int({
341
- default: 0,
342
- description: "Total correct"
343
- }),
344
- assessedAt: field.dateTime({ description: "Last assessment time" }),
345
- createdAt: field.createdAt(),
346
- updatedAt: field.updatedAt(),
347
- learner: field.belongsTo("Learner", ["learnerId"], ["id"], { onDelete: "Cascade" })
348
- },
349
- indexes: [
350
- index.unique(["learnerId", "skillId"], { name: "skill_assessment_unique" }),
351
- index.on(["learnerId", "level"]),
352
- index.on(["skillId"])
353
- ]
252
+ var SkillAssessmentEntity = defineEntity({
253
+ name: "SkillAssessment",
254
+ description: "Assessment of a skill based on quiz performance.",
255
+ schema: "lssm_learning",
256
+ map: "skill_assessment",
257
+ fields: {
258
+ id: field.id({ description: "Unique assessment identifier" }),
259
+ learnerId: field.foreignKey({ description: "Learner" }),
260
+ skillId: field.string({ description: "Skill identifier" }),
261
+ skillName: field.string({ description: "Skill name" }),
262
+ level: field.int({ default: 1, description: "Proficiency level (1-5)" }),
263
+ score: field.int({ default: 0, description: "Assessment score (0-100)" }),
264
+ confidence: field.decimal({
265
+ default: 0.5,
266
+ description: "Confidence in assessment"
267
+ }),
268
+ questionsAnswered: field.int({
269
+ default: 0,
270
+ description: "Total questions answered"
271
+ }),
272
+ questionsCorrect: field.int({ default: 0, description: "Total correct" }),
273
+ assessedAt: field.dateTime({ description: "Last assessment time" }),
274
+ createdAt: field.createdAt(),
275
+ updatedAt: field.updatedAt(),
276
+ learner: field.belongsTo("Learner", ["learnerId"], ["id"], {
277
+ onDelete: "Cascade"
278
+ })
279
+ },
280
+ indexes: [
281
+ index.unique(["learnerId", "skillId"], { name: "skill_assessment_unique" }),
282
+ index.on(["learnerId", "level"]),
283
+ index.on(["skillId"])
284
+ ]
354
285
  });
355
- const quizEntities = [
356
- QuizEntity,
357
- QuestionEntity,
358
- QuestionOptionEntity,
359
- QuizAttemptEntity,
360
- SkillAssessmentEntity
286
+ var quizEntities = [
287
+ QuizEntity,
288
+ QuestionEntity,
289
+ QuestionOptionEntity,
290
+ QuizAttemptEntity,
291
+ SkillAssessmentEntity
361
292
  ];
362
- const quizEnums = [
363
- QuestionTypeEnum,
364
- QuizStatusEnum,
365
- AttemptStatusEnum
366
- ];
367
-
368
- //#endregion
369
- export { AttemptStatusEnum, QuestionEntity, QuestionOptionEntity, QuestionTypeEnum, QuizAttemptEntity, QuizEntity, QuizStatusEnum, SkillAssessmentEntity, quizEntities, quizEnums };
370
- //# sourceMappingURL=quiz.js.map
293
+ var quizEnums = [QuestionTypeEnum, QuizStatusEnum, AttemptStatusEnum];
294
+ export {
295
+ quizEnums,
296
+ quizEntities,
297
+ SkillAssessmentEntity,
298
+ QuizStatusEnum,
299
+ QuizEntity,
300
+ QuizAttemptEntity,
301
+ QuestionTypeEnum,
302
+ QuestionOptionEntity,
303
+ QuestionEntity,
304
+ AttemptStatusEnum
305
+ };