@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.
- package/dist/browser/contracts/index.js +578 -0
- package/dist/browser/contracts/models.js +193 -0
- package/dist/browser/contracts/onboarding.js +417 -0
- package/dist/browser/contracts/operations.js +326 -0
- package/dist/browser/contracts/shared.js +5 -0
- package/dist/browser/docs/index.js +124 -0
- package/dist/browser/docs/learning-journey.docblock.js +124 -0
- package/dist/browser/engines/index.js +526 -0
- package/dist/browser/engines/srs.js +198 -0
- package/dist/browser/engines/streak.js +159 -0
- package/dist/browser/engines/xp.js +171 -0
- package/dist/browser/entities/ai.js +343 -0
- package/dist/browser/entities/course.js +276 -0
- package/dist/browser/entities/flashcard.js +222 -0
- package/dist/browser/entities/gamification.js +340 -0
- package/dist/browser/entities/index.js +2136 -0
- package/dist/browser/entities/learner.js +329 -0
- package/dist/browser/entities/onboarding.js +301 -0
- package/dist/browser/entities/quiz.js +304 -0
- package/dist/browser/events.js +423 -0
- package/dist/browser/index.js +3833 -0
- package/dist/browser/learning-journey.capability.js +40 -0
- package/dist/browser/learning-journey.feature.js +56 -0
- package/dist/browser/track-spec.js +0 -0
- package/dist/contracts/index.d.ts +5 -5
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +578 -5
- package/dist/contracts/models.d.ts +426 -431
- package/dist/contracts/models.d.ts.map +1 -1
- package/dist/contracts/models.js +178 -372
- package/dist/contracts/onboarding.d.ts +621 -627
- package/dist/contracts/onboarding.d.ts.map +1 -1
- package/dist/contracts/onboarding.js +404 -388
- package/dist/contracts/operations.d.ts +243 -249
- package/dist/contracts/operations.d.ts.map +1 -1
- package/dist/contracts/operations.js +324 -148
- package/dist/contracts/shared.d.ts +1 -4
- package/dist/contracts/shared.d.ts.map +1 -1
- package/dist/contracts/shared.js +6 -6
- package/dist/docs/index.d.ts +2 -1
- package/dist/docs/index.d.ts.map +1 -0
- package/dist/docs/index.js +125 -1
- package/dist/docs/learning-journey.docblock.d.ts +2 -1
- package/dist/docs/learning-journey.docblock.d.ts.map +1 -0
- package/dist/docs/learning-journey.docblock.js +47 -58
- package/dist/engines/index.d.ts +4 -4
- package/dist/engines/index.d.ts.map +1 -0
- package/dist/engines/index.js +526 -4
- package/dist/engines/srs.d.ts +89 -92
- package/dist/engines/srs.d.ts.map +1 -1
- package/dist/engines/srs.js +197 -217
- package/dist/engines/streak.d.ts +84 -87
- package/dist/engines/streak.d.ts.map +1 -1
- package/dist/engines/streak.js +158 -192
- package/dist/engines/xp.d.ts +80 -83
- package/dist/engines/xp.d.ts.map +1 -1
- package/dist/engines/xp.js +170 -211
- package/dist/entities/ai.d.ts +199 -204
- package/dist/entities/ai.d.ts.map +1 -1
- package/dist/entities/ai.js +336 -368
- package/dist/entities/course.d.ts +149 -154
- package/dist/entities/course.d.ts.map +1 -1
- package/dist/entities/course.js +267 -306
- package/dist/entities/flashcard.d.ts +144 -149
- package/dist/entities/flashcard.d.ts.map +1 -1
- package/dist/entities/flashcard.js +217 -243
- package/dist/entities/gamification.d.ts +197 -202
- package/dist/entities/gamification.d.ts.map +1 -1
- package/dist/entities/gamification.js +331 -382
- package/dist/entities/index.d.ts +613 -618
- package/dist/entities/index.d.ts.map +1 -1
- package/dist/entities/index.js +2135 -43
- package/dist/entities/learner.d.ts +191 -196
- package/dist/entities/learner.d.ts.map +1 -1
- package/dist/entities/learner.js +322 -357
- package/dist/entities/onboarding.d.ts +164 -169
- package/dist/entities/onboarding.d.ts.map +1 -1
- package/dist/entities/onboarding.js +296 -301
- package/dist/entities/quiz.d.ts +184 -189
- package/dist/entities/quiz.d.ts.map +1 -1
- package/dist/entities/quiz.js +296 -361
- package/dist/events.d.ts +608 -614
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +421 -687
- package/dist/index.d.ts +8 -20
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3834 -22
- package/dist/learning-journey.capability.d.ts +3 -8
- package/dist/learning-journey.capability.d.ts.map +1 -1
- package/dist/learning-journey.capability.js +41 -46
- package/dist/learning-journey.feature.d.ts +1 -6
- package/dist/learning-journey.feature.d.ts.map +1 -1
- package/dist/learning-journey.feature.js +55 -155
- package/dist/node/contracts/index.js +578 -0
- package/dist/node/contracts/models.js +193 -0
- package/dist/node/contracts/onboarding.js +417 -0
- package/dist/node/contracts/operations.js +326 -0
- package/dist/node/contracts/shared.js +5 -0
- package/dist/node/docs/index.js +124 -0
- package/dist/node/docs/learning-journey.docblock.js +124 -0
- package/dist/node/engines/index.js +526 -0
- package/dist/node/engines/srs.js +198 -0
- package/dist/node/engines/streak.js +159 -0
- package/dist/node/engines/xp.js +171 -0
- package/dist/node/entities/ai.js +343 -0
- package/dist/node/entities/course.js +276 -0
- package/dist/node/entities/flashcard.js +222 -0
- package/dist/node/entities/gamification.js +340 -0
- package/dist/node/entities/index.js +2136 -0
- package/dist/node/entities/learner.js +329 -0
- package/dist/node/entities/onboarding.js +301 -0
- package/dist/node/entities/quiz.js +304 -0
- package/dist/node/events.js +423 -0
- package/dist/node/index.js +3833 -0
- package/dist/node/learning-journey.capability.js +40 -0
- package/dist/node/learning-journey.feature.js +56 -0
- package/dist/node/track-spec.js +0 -0
- package/dist/track-spec.d.ts +115 -118
- package/dist/track-spec.d.ts.map +1 -1
- package/dist/track-spec.js +1 -0
- package/package.json +237 -60
- package/dist/contracts/models.js.map +0 -1
- package/dist/contracts/onboarding.js.map +0 -1
- package/dist/contracts/operations.js.map +0 -1
- package/dist/contracts/shared.js.map +0 -1
- package/dist/docs/learning-journey.docblock.js.map +0 -1
- package/dist/engines/srs.js.map +0 -1
- package/dist/engines/streak.js.map +0 -1
- package/dist/engines/xp.js.map +0 -1
- package/dist/entities/ai.js.map +0 -1
- package/dist/entities/course.js.map +0 -1
- package/dist/entities/flashcard.js.map +0 -1
- package/dist/entities/gamification.js.map +0 -1
- package/dist/entities/index.js.map +0 -1
- package/dist/entities/learner.js.map +0 -1
- package/dist/entities/onboarding.js.map +0 -1
- package/dist/entities/quiz.js.map +0 -1
- package/dist/events.js.map +0 -1
- package/dist/learning-journey.capability.js.map +0 -1
- package/dist/learning-journey.feature.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contractspec/module.learning-journey",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.58.0",
|
|
4
4
|
"description": "Comprehensive learning journey engine - onboarding, LMS, flashcards, gamification, and AI personalization",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"contractspec",
|
|
@@ -15,51 +15,56 @@
|
|
|
15
15
|
"scripts": {
|
|
16
16
|
"publish:pkg": "bun publish --tolerate-republish --ignore-scripts --verbose",
|
|
17
17
|
"publish:pkg:canary": "bun publish:pkg --tag canary",
|
|
18
|
-
"build": "bun build:
|
|
19
|
-
"build:bundle": "
|
|
20
|
-
"build:types": "
|
|
21
|
-
"dev": "bun
|
|
18
|
+
"build": "bun run prebuild && bun run build:bundle && bun run build:types",
|
|
19
|
+
"build:bundle": "contractspec-bun-build transpile",
|
|
20
|
+
"build:types": "contractspec-bun-build types",
|
|
21
|
+
"dev": "contractspec-bun-build dev",
|
|
22
22
|
"clean": "rimraf dist .turbo",
|
|
23
23
|
"lint": "bun lint:fix",
|
|
24
24
|
"lint:fix": "eslint src --fix",
|
|
25
|
-
"lint:check": "eslint src"
|
|
25
|
+
"lint:check": "eslint src",
|
|
26
|
+
"prebuild": "contractspec-bun-build prebuild",
|
|
27
|
+
"typecheck": "tsc --noEmit"
|
|
26
28
|
},
|
|
27
29
|
"dependencies": {
|
|
28
|
-
"@contractspec/lib.schema": "1.
|
|
29
|
-
"@contractspec/lib.contracts": "1.
|
|
30
|
+
"@contractspec/lib.schema": "1.58.0",
|
|
31
|
+
"@contractspec/lib.contracts": "1.58.0",
|
|
30
32
|
"zod": "^4.3.5"
|
|
31
33
|
},
|
|
32
34
|
"devDependencies": {
|
|
33
|
-
"@contractspec/tool.typescript": "1.
|
|
34
|
-
"
|
|
35
|
-
"
|
|
35
|
+
"@contractspec/tool.typescript": "1.58.0",
|
|
36
|
+
"typescript": "^5.9.3",
|
|
37
|
+
"@contractspec/tool.bun": "1.57.0"
|
|
36
38
|
},
|
|
37
39
|
"exports": {
|
|
38
|
-
".": "./
|
|
39
|
-
"./contracts": "./
|
|
40
|
-
"./contracts/
|
|
41
|
-
"./contracts/
|
|
42
|
-
"./contracts/
|
|
43
|
-
"./contracts/
|
|
44
|
-
"./
|
|
45
|
-
"./docs
|
|
46
|
-
"./
|
|
47
|
-
"./
|
|
48
|
-
"./engines
|
|
49
|
-
"./engines/
|
|
50
|
-
"./
|
|
51
|
-
"./
|
|
52
|
-
"./
|
|
53
|
-
"./entities
|
|
54
|
-
"./entities/
|
|
55
|
-
"./entities/
|
|
56
|
-
"./entities/
|
|
57
|
-
"./entities/
|
|
58
|
-
"./
|
|
59
|
-
"./
|
|
60
|
-
"./
|
|
61
|
-
"./
|
|
62
|
-
"
|
|
40
|
+
".": "./src/index.ts",
|
|
41
|
+
"./contracts": "./src/contracts/index.ts",
|
|
42
|
+
"./contracts/index": "./src/contracts/index.ts",
|
|
43
|
+
"./contracts/models": "./src/contracts/models.ts",
|
|
44
|
+
"./contracts/onboarding": "./src/contracts/onboarding.ts",
|
|
45
|
+
"./contracts/operations": "./src/contracts/operations.ts",
|
|
46
|
+
"./contracts/shared": "./src/contracts/shared.ts",
|
|
47
|
+
"./docs": "./src/docs/index.ts",
|
|
48
|
+
"./docs/index": "./src/docs/index.ts",
|
|
49
|
+
"./docs/learning-journey.docblock": "./src/docs/learning-journey.docblock.ts",
|
|
50
|
+
"./engines": "./src/engines/index.ts",
|
|
51
|
+
"./engines/index": "./src/engines/index.ts",
|
|
52
|
+
"./engines/srs": "./src/engines/srs.ts",
|
|
53
|
+
"./engines/streak": "./src/engines/streak.ts",
|
|
54
|
+
"./engines/xp": "./src/engines/xp.ts",
|
|
55
|
+
"./entities": "./src/entities/index.ts",
|
|
56
|
+
"./entities/ai": "./src/entities/ai.ts",
|
|
57
|
+
"./entities/course": "./src/entities/course.ts",
|
|
58
|
+
"./entities/flashcard": "./src/entities/flashcard.ts",
|
|
59
|
+
"./entities/gamification": "./src/entities/gamification.ts",
|
|
60
|
+
"./entities/index": "./src/entities/index.ts",
|
|
61
|
+
"./entities/learner": "./src/entities/learner.ts",
|
|
62
|
+
"./entities/onboarding": "./src/entities/onboarding.ts",
|
|
63
|
+
"./entities/quiz": "./src/entities/quiz.ts",
|
|
64
|
+
"./events": "./src/events.ts",
|
|
65
|
+
"./learning-journey.capability": "./src/learning-journey.capability.ts",
|
|
66
|
+
"./learning-journey.feature": "./src/learning-journey.feature.ts",
|
|
67
|
+
"./track-spec": "./src/track-spec.ts"
|
|
63
68
|
},
|
|
64
69
|
"files": [
|
|
65
70
|
"dist",
|
|
@@ -68,30 +73,202 @@
|
|
|
68
73
|
"publishConfig": {
|
|
69
74
|
"access": "public",
|
|
70
75
|
"exports": {
|
|
71
|
-
".":
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
"./
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
"./
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
"./
|
|
93
|
-
|
|
94
|
-
|
|
76
|
+
".": {
|
|
77
|
+
"types": "./dist/index.d.ts",
|
|
78
|
+
"bun": "./dist/index.js",
|
|
79
|
+
"node": "./dist/node/index.mjs",
|
|
80
|
+
"browser": "./dist/browser/index.js",
|
|
81
|
+
"default": "./dist/index.js"
|
|
82
|
+
},
|
|
83
|
+
"./contracts": {
|
|
84
|
+
"types": "./dist/contracts/index.d.ts",
|
|
85
|
+
"bun": "./dist/contracts/index.js",
|
|
86
|
+
"node": "./dist/node/contracts/index.mjs",
|
|
87
|
+
"browser": "./dist/browser/contracts/index.js",
|
|
88
|
+
"default": "./dist/contracts/index.js"
|
|
89
|
+
},
|
|
90
|
+
"./contracts/index": {
|
|
91
|
+
"types": "./dist/contracts/index.d.ts",
|
|
92
|
+
"bun": "./dist/contracts/index.js",
|
|
93
|
+
"node": "./dist/node/contracts/index.mjs",
|
|
94
|
+
"browser": "./dist/browser/contracts/index.js",
|
|
95
|
+
"default": "./dist/contracts/index.js"
|
|
96
|
+
},
|
|
97
|
+
"./contracts/models": {
|
|
98
|
+
"types": "./dist/contracts/models.d.ts",
|
|
99
|
+
"bun": "./dist/contracts/models.js",
|
|
100
|
+
"node": "./dist/node/contracts/models.mjs",
|
|
101
|
+
"browser": "./dist/browser/contracts/models.js",
|
|
102
|
+
"default": "./dist/contracts/models.js"
|
|
103
|
+
},
|
|
104
|
+
"./contracts/onboarding": {
|
|
105
|
+
"types": "./dist/contracts/onboarding.d.ts",
|
|
106
|
+
"bun": "./dist/contracts/onboarding.js",
|
|
107
|
+
"node": "./dist/node/contracts/onboarding.mjs",
|
|
108
|
+
"browser": "./dist/browser/contracts/onboarding.js",
|
|
109
|
+
"default": "./dist/contracts/onboarding.js"
|
|
110
|
+
},
|
|
111
|
+
"./contracts/operations": {
|
|
112
|
+
"types": "./dist/contracts/operations.d.ts",
|
|
113
|
+
"bun": "./dist/contracts/operations.js",
|
|
114
|
+
"node": "./dist/node/contracts/operations.mjs",
|
|
115
|
+
"browser": "./dist/browser/contracts/operations.js",
|
|
116
|
+
"default": "./dist/contracts/operations.js"
|
|
117
|
+
},
|
|
118
|
+
"./contracts/shared": {
|
|
119
|
+
"types": "./dist/contracts/shared.d.ts",
|
|
120
|
+
"bun": "./dist/contracts/shared.js",
|
|
121
|
+
"node": "./dist/node/contracts/shared.mjs",
|
|
122
|
+
"browser": "./dist/browser/contracts/shared.js",
|
|
123
|
+
"default": "./dist/contracts/shared.js"
|
|
124
|
+
},
|
|
125
|
+
"./docs": {
|
|
126
|
+
"types": "./dist/docs/index.d.ts",
|
|
127
|
+
"bun": "./dist/docs/index.js",
|
|
128
|
+
"node": "./dist/node/docs/index.mjs",
|
|
129
|
+
"browser": "./dist/browser/docs/index.js",
|
|
130
|
+
"default": "./dist/docs/index.js"
|
|
131
|
+
},
|
|
132
|
+
"./docs/index": {
|
|
133
|
+
"types": "./dist/docs/index.d.ts",
|
|
134
|
+
"bun": "./dist/docs/index.js",
|
|
135
|
+
"node": "./dist/node/docs/index.mjs",
|
|
136
|
+
"browser": "./dist/browser/docs/index.js",
|
|
137
|
+
"default": "./dist/docs/index.js"
|
|
138
|
+
},
|
|
139
|
+
"./docs/learning-journey.docblock": {
|
|
140
|
+
"types": "./dist/docs/learning-journey.docblock.d.ts",
|
|
141
|
+
"bun": "./dist/docs/learning-journey.docblock.js",
|
|
142
|
+
"node": "./dist/node/docs/learning-journey.docblock.mjs",
|
|
143
|
+
"browser": "./dist/browser/docs/learning-journey.docblock.js",
|
|
144
|
+
"default": "./dist/docs/learning-journey.docblock.js"
|
|
145
|
+
},
|
|
146
|
+
"./engines": {
|
|
147
|
+
"types": "./dist/engines/index.d.ts",
|
|
148
|
+
"bun": "./dist/engines/index.js",
|
|
149
|
+
"node": "./dist/node/engines/index.mjs",
|
|
150
|
+
"browser": "./dist/browser/engines/index.js",
|
|
151
|
+
"default": "./dist/engines/index.js"
|
|
152
|
+
},
|
|
153
|
+
"./engines/index": {
|
|
154
|
+
"types": "./dist/engines/index.d.ts",
|
|
155
|
+
"bun": "./dist/engines/index.js",
|
|
156
|
+
"node": "./dist/node/engines/index.mjs",
|
|
157
|
+
"browser": "./dist/browser/engines/index.js",
|
|
158
|
+
"default": "./dist/engines/index.js"
|
|
159
|
+
},
|
|
160
|
+
"./engines/srs": {
|
|
161
|
+
"types": "./dist/engines/srs.d.ts",
|
|
162
|
+
"bun": "./dist/engines/srs.js",
|
|
163
|
+
"node": "./dist/node/engines/srs.mjs",
|
|
164
|
+
"browser": "./dist/browser/engines/srs.js",
|
|
165
|
+
"default": "./dist/engines/srs.js"
|
|
166
|
+
},
|
|
167
|
+
"./engines/streak": {
|
|
168
|
+
"types": "./dist/engines/streak.d.ts",
|
|
169
|
+
"bun": "./dist/engines/streak.js",
|
|
170
|
+
"node": "./dist/node/engines/streak.mjs",
|
|
171
|
+
"browser": "./dist/browser/engines/streak.js",
|
|
172
|
+
"default": "./dist/engines/streak.js"
|
|
173
|
+
},
|
|
174
|
+
"./engines/xp": {
|
|
175
|
+
"types": "./dist/engines/xp.d.ts",
|
|
176
|
+
"bun": "./dist/engines/xp.js",
|
|
177
|
+
"node": "./dist/node/engines/xp.mjs",
|
|
178
|
+
"browser": "./dist/browser/engines/xp.js",
|
|
179
|
+
"default": "./dist/engines/xp.js"
|
|
180
|
+
},
|
|
181
|
+
"./entities": {
|
|
182
|
+
"types": "./dist/entities/index.d.ts",
|
|
183
|
+
"bun": "./dist/entities/index.js",
|
|
184
|
+
"node": "./dist/node/entities/index.mjs",
|
|
185
|
+
"browser": "./dist/browser/entities/index.js",
|
|
186
|
+
"default": "./dist/entities/index.js"
|
|
187
|
+
},
|
|
188
|
+
"./entities/ai": {
|
|
189
|
+
"types": "./dist/entities/ai.d.ts",
|
|
190
|
+
"bun": "./dist/entities/ai.js",
|
|
191
|
+
"node": "./dist/node/entities/ai.mjs",
|
|
192
|
+
"browser": "./dist/browser/entities/ai.js",
|
|
193
|
+
"default": "./dist/entities/ai.js"
|
|
194
|
+
},
|
|
195
|
+
"./entities/course": {
|
|
196
|
+
"types": "./dist/entities/course.d.ts",
|
|
197
|
+
"bun": "./dist/entities/course.js",
|
|
198
|
+
"node": "./dist/node/entities/course.mjs",
|
|
199
|
+
"browser": "./dist/browser/entities/course.js",
|
|
200
|
+
"default": "./dist/entities/course.js"
|
|
201
|
+
},
|
|
202
|
+
"./entities/flashcard": {
|
|
203
|
+
"types": "./dist/entities/flashcard.d.ts",
|
|
204
|
+
"bun": "./dist/entities/flashcard.js",
|
|
205
|
+
"node": "./dist/node/entities/flashcard.mjs",
|
|
206
|
+
"browser": "./dist/browser/entities/flashcard.js",
|
|
207
|
+
"default": "./dist/entities/flashcard.js"
|
|
208
|
+
},
|
|
209
|
+
"./entities/gamification": {
|
|
210
|
+
"types": "./dist/entities/gamification.d.ts",
|
|
211
|
+
"bun": "./dist/entities/gamification.js",
|
|
212
|
+
"node": "./dist/node/entities/gamification.mjs",
|
|
213
|
+
"browser": "./dist/browser/entities/gamification.js",
|
|
214
|
+
"default": "./dist/entities/gamification.js"
|
|
215
|
+
},
|
|
216
|
+
"./entities/index": {
|
|
217
|
+
"types": "./dist/entities/index.d.ts",
|
|
218
|
+
"bun": "./dist/entities/index.js",
|
|
219
|
+
"node": "./dist/node/entities/index.mjs",
|
|
220
|
+
"browser": "./dist/browser/entities/index.js",
|
|
221
|
+
"default": "./dist/entities/index.js"
|
|
222
|
+
},
|
|
223
|
+
"./entities/learner": {
|
|
224
|
+
"types": "./dist/entities/learner.d.ts",
|
|
225
|
+
"bun": "./dist/entities/learner.js",
|
|
226
|
+
"node": "./dist/node/entities/learner.mjs",
|
|
227
|
+
"browser": "./dist/browser/entities/learner.js",
|
|
228
|
+
"default": "./dist/entities/learner.js"
|
|
229
|
+
},
|
|
230
|
+
"./entities/onboarding": {
|
|
231
|
+
"types": "./dist/entities/onboarding.d.ts",
|
|
232
|
+
"bun": "./dist/entities/onboarding.js",
|
|
233
|
+
"node": "./dist/node/entities/onboarding.mjs",
|
|
234
|
+
"browser": "./dist/browser/entities/onboarding.js",
|
|
235
|
+
"default": "./dist/entities/onboarding.js"
|
|
236
|
+
},
|
|
237
|
+
"./entities/quiz": {
|
|
238
|
+
"types": "./dist/entities/quiz.d.ts",
|
|
239
|
+
"bun": "./dist/entities/quiz.js",
|
|
240
|
+
"node": "./dist/node/entities/quiz.mjs",
|
|
241
|
+
"browser": "./dist/browser/entities/quiz.js",
|
|
242
|
+
"default": "./dist/entities/quiz.js"
|
|
243
|
+
},
|
|
244
|
+
"./events": {
|
|
245
|
+
"types": "./dist/events.d.ts",
|
|
246
|
+
"bun": "./dist/events.js",
|
|
247
|
+
"node": "./dist/node/events.mjs",
|
|
248
|
+
"browser": "./dist/browser/events.js",
|
|
249
|
+
"default": "./dist/events.js"
|
|
250
|
+
},
|
|
251
|
+
"./learning-journey.capability": {
|
|
252
|
+
"types": "./dist/learning-journey.capability.d.ts",
|
|
253
|
+
"bun": "./dist/learning-journey.capability.js",
|
|
254
|
+
"node": "./dist/node/learning-journey.capability.mjs",
|
|
255
|
+
"browser": "./dist/browser/learning-journey.capability.js",
|
|
256
|
+
"default": "./dist/learning-journey.capability.js"
|
|
257
|
+
},
|
|
258
|
+
"./learning-journey.feature": {
|
|
259
|
+
"types": "./dist/learning-journey.feature.d.ts",
|
|
260
|
+
"bun": "./dist/learning-journey.feature.js",
|
|
261
|
+
"node": "./dist/node/learning-journey.feature.mjs",
|
|
262
|
+
"browser": "./dist/browser/learning-journey.feature.js",
|
|
263
|
+
"default": "./dist/learning-journey.feature.js"
|
|
264
|
+
},
|
|
265
|
+
"./track-spec": {
|
|
266
|
+
"types": "./dist/track-spec.d.ts",
|
|
267
|
+
"bun": "./dist/track-spec.js",
|
|
268
|
+
"node": "./dist/node/track-spec.mjs",
|
|
269
|
+
"browser": "./dist/browser/track-spec.js",
|
|
270
|
+
"default": "./dist/track-spec.js"
|
|
271
|
+
}
|
|
95
272
|
},
|
|
96
273
|
"registry": "https://registry.npmjs.org/"
|
|
97
274
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"models.js","names":[],"sources":["../../src/contracts/models.ts"],"sourcesContent":["import { ScalarTypeEnum, defineSchemaModel } from '@contractspec/lib.schema';\n\nexport const CourseModel = defineSchemaModel({\n name: 'Course',\n description: 'A learning course',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n title: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n slug: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n difficulty: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n status: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n estimatedDuration: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: true,\n },\n thumbnailUrl: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\nexport const LearnerModel = defineSchemaModel({\n name: 'Learner',\n description: 'A learner profile',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n userId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n displayName: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n level: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n totalXp: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n currentStreak: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n longestStreak: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\nexport const EnrollmentModel = defineSchemaModel({\n name: 'Enrollment',\n description: 'A course enrollment',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n learnerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n courseId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n status: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n progress: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n startedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n completedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n },\n});\n\nexport const ProgressModel = defineSchemaModel({\n name: 'LessonProgress',\n description: 'Lesson progress',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n learnerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n lessonId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n status: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n progress: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n score: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n timeSpent: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n completedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n },\n});\n\nexport const DeckModel = defineSchemaModel({\n name: 'Deck',\n description: 'A flashcard deck',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n title: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n cardCount: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n isPublic: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\nexport const CardModel = defineSchemaModel({\n name: 'Card',\n description: 'A flashcard',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n deckId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n front: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n back: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n hints: { type: ScalarTypeEnum.JSON(), isOptional: true },\n isDue: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n nextReviewAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n },\n});\n\nexport const AchievementModel = defineSchemaModel({\n name: 'Achievement',\n description: 'An achievement',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n key: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n description: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n icon: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n xpReward: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n unlockedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n },\n});\n\nexport const EnrollInCourseInput = defineSchemaModel({\n name: 'EnrollInCourseInput',\n description: 'Input for enrolling in a course',\n fields: {\n courseId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n },\n});\n\nexport const CompleteLessonInput = defineSchemaModel({\n name: 'CompleteLessonInput',\n description: 'Input for completing a lesson',\n fields: {\n lessonId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n score: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n timeSpent: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n },\n});\n\nexport const SubmitCardReviewInput = defineSchemaModel({\n name: 'SubmitCardReviewInput',\n description: 'Input for submitting a card review',\n fields: {\n cardId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n rating: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n responseTimeMs: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n },\n});\n\nexport const GetDueCardsInput = defineSchemaModel({\n name: 'GetDueCardsInput',\n description: 'Input for getting due cards',\n fields: {\n deckId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n limit: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n },\n});\n\nexport const GetDueCardsOutput = defineSchemaModel({\n name: 'GetDueCardsOutput',\n description: 'Output for getting due cards',\n fields: {\n cards: { type: CardModel, isArray: true, isOptional: false },\n total: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n },\n});\n\nexport const GetLearnerDashboardInput = defineSchemaModel({\n name: 'GetLearnerDashboardInput',\n description: 'Input for getting learner dashboard',\n fields: {\n learnerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n },\n});\n\nexport const LearnerDashboardModel = defineSchemaModel({\n name: 'LearnerDashboard',\n description: 'Learner dashboard data',\n fields: {\n learner: { type: LearnerModel, isOptional: false },\n currentStreak: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n dailyXpGoal: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n dailyXpProgress: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n activeEnrollments: {\n type: EnrollmentModel,\n isArray: true,\n isOptional: false,\n },\n recentAchievements: {\n type: AchievementModel,\n isArray: true,\n isOptional: false,\n },\n dueCardCount: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n },\n});\n\nexport const SuccessOutput = defineSchemaModel({\n name: 'SuccessOutput',\n description: 'Generic success output',\n fields: {\n success: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n xpEarned: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n },\n});\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"onboarding.js","names":[],"sources":["../../src/contracts/onboarding.ts"],"sourcesContent":["import { ScalarTypeEnum, defineSchemaModel } from '@contractspec/lib.schema';\nimport { defineCommand, defineQuery } from '@contractspec/lib.contracts';\n\nimport { SuccessOutput } from './models';\nimport { LEARNING_JOURNEY_OWNERS } from './shared';\n\nconst OnboardingStepConditionModel = defineSchemaModel({\n name: 'OnboardingStepCondition',\n description: 'Structured completion condition for onboarding steps.',\n fields: {\n eventName: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n eventVersion: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n sourceModule: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n payloadFilter: { type: ScalarTypeEnum.JSON(), isOptional: true },\n },\n});\n\nexport const OnboardingStepModel = defineSchemaModel({\n name: 'OnboardingStep',\n description: 'Declarative onboarding step definition.',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n trackId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n title: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n instructions: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n helpUrl: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n order: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n completionEvent: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n completionCondition: {\n type: OnboardingStepConditionModel,\n isOptional: true,\n },\n xpReward: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n isRequired: { type: ScalarTypeEnum.Boolean(), isOptional: true },\n canSkip: { type: ScalarTypeEnum.Boolean(), isOptional: true },\n actionUrl: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n actionLabel: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n metadata: { type: ScalarTypeEnum.JSON(), isOptional: true },\n },\n});\n\nexport const OnboardingTrackModel = defineSchemaModel({\n name: 'OnboardingTrack',\n description: 'Onboarding track metadata and steps.',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n productId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n targetUserSegment: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n targetRole: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n isActive: { type: ScalarTypeEnum.Boolean(), isOptional: true },\n isRequired: { type: ScalarTypeEnum.Boolean(), isOptional: true },\n canSkip: { type: ScalarTypeEnum.Boolean(), isOptional: true },\n totalXp: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n completionXpBonus: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: true,\n },\n completionBadgeKey: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n streakHoursWindow: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: true,\n },\n streakBonusXp: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n metadata: { type: ScalarTypeEnum.JSON(), isOptional: true },\n steps: { type: OnboardingStepModel, isArray: true, isOptional: false },\n },\n});\n\nexport const OnboardingStepProgressModel = defineSchemaModel({\n name: 'OnboardingStepProgress',\n description: 'Progress for a specific onboarding step.',\n fields: {\n stepId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n status: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n xpEarned: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n triggeringEvent: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n eventPayload: { type: ScalarTypeEnum.JSON(), isOptional: true },\n completedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n },\n});\n\nexport const OnboardingProgressModel = defineSchemaModel({\n name: 'OnboardingProgress',\n description: 'Aggregated progress for an onboarding track.',\n fields: {\n learnerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n trackId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n progress: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n isCompleted: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n xpEarned: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n startedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n completedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n lastActivityAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n steps: {\n type: OnboardingStepProgressModel,\n isArray: true,\n isOptional: true,\n },\n },\n});\n\nconst ListOnboardingTracksInput = defineSchemaModel({\n name: 'ListOnboardingTracksInput',\n description: 'Filters for listing onboarding tracks.',\n fields: {\n learnerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n productId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n trackIds: {\n type: ScalarTypeEnum.String_unsecure(),\n isArray: true,\n isOptional: true,\n },\n includeProgress: {\n type: ScalarTypeEnum.Boolean(),\n isOptional: true,\n },\n },\n});\n\nconst ListOnboardingTracksOutput = defineSchemaModel({\n name: 'ListOnboardingTracksOutput',\n description: 'Available onboarding tracks with optional progress.',\n fields: {\n tracks: { type: OnboardingTrackModel, isArray: true, isOptional: false },\n progress: {\n type: OnboardingProgressModel,\n isArray: true,\n isOptional: true,\n },\n },\n});\n\nconst GetOnboardingProgressInput = defineSchemaModel({\n name: 'GetOnboardingProgressInput',\n description: 'Input for fetching onboarding progress for a track.',\n fields: {\n trackId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n learnerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n },\n});\n\nconst RecordOnboardingEventInput = defineSchemaModel({\n name: 'RecordOnboardingEventInput',\n description:\n 'Record a domain event to advance onboarding progress via completion conditions.',\n fields: {\n learnerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n trackId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n eventName: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n eventVersion: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n eventPayload: { type: ScalarTypeEnum.JSON(), isOptional: true },\n occurredAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n },\n});\n\nexport const ListOnboardingTracksContract = defineQuery({\n meta: {\n key: 'learning.onboarding.listTracks',\n version: '1.0.0',\n stability: 'stable',\n owners: [...LEARNING_JOURNEY_OWNERS],\n tags: ['learning', 'onboarding', 'journey'],\n description: 'List onboarding tracks available to a learner or product.',\n goal: 'Expose track catalog for UI/API surfaces.',\n context: 'Called when showing onboarding/learning journey catalog.',\n },\n io: {\n input: ListOnboardingTracksInput,\n output: ListOnboardingTracksOutput,\n },\n policy: {\n auth: 'user',\n },\n});\n\nexport const GetOnboardingProgressContract = defineQuery({\n meta: {\n key: 'learning.onboarding.getProgress',\n version: '1.0.0',\n stability: 'stable',\n owners: [...LEARNING_JOURNEY_OWNERS],\n tags: ['learning', 'onboarding', 'journey'],\n description: 'Fetch onboarding progress for a specific track.',\n goal: 'Display learner progress and remaining steps.',\n context: 'Called when rendering a track detail or widget.',\n },\n io: {\n input: GetOnboardingProgressInput,\n output: OnboardingProgressModel,\n },\n policy: {\n auth: 'user',\n },\n});\n\nexport const RecordOnboardingEventContract = defineCommand({\n meta: {\n key: 'learning.onboarding.recordEvent',\n version: '1.0.0',\n stability: 'stable',\n owners: [...LEARNING_JOURNEY_OWNERS],\n tags: ['learning', 'onboarding', 'events'],\n description:\n 'Record a domain event to evaluate onboarding step completion conditions.',\n goal: 'Advance onboarding automatically from product events.',\n context:\n 'Called by event bus handlers when relevant product events fire (e.g., deal.created).',\n },\n io: {\n input: RecordOnboardingEventInput,\n output: SuccessOutput,\n errors: {\n TRACK_NOT_FOUND: {\n description: 'Track not found for event routing',\n http: 404,\n gqlCode: 'TRACK_NOT_FOUND',\n when: 'Track ID or routing context is invalid',\n },\n STEP_NOT_FOUND: {\n description: 'Step not found for completion condition',\n http: 404,\n gqlCode: 'STEP_NOT_FOUND',\n when: 'No step matches the incoming event',\n },\n },\n },\n policy: {\n auth: 'user',\n },\n});\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"operations.js","names":[],"sources":["../../src/contracts/operations.ts"],"sourcesContent":["import { defineCommand, defineQuery } from '@contractspec/lib.contracts';\n\nimport {\n CompleteLessonInput,\n EnrollInCourseInput,\n EnrollmentModel,\n GetDueCardsInput,\n GetDueCardsOutput,\n GetLearnerDashboardInput,\n LearnerDashboardModel,\n SubmitCardReviewInput,\n SuccessOutput,\n} from './models';\nimport { LEARNING_JOURNEY_OWNERS } from './shared';\n\n/**\n * Enroll in a course.\n */\nexport const EnrollInCourseContract = defineCommand({\n meta: {\n key: 'learning.enroll',\n version: '1.0.0',\n stability: 'stable',\n owners: [...LEARNING_JOURNEY_OWNERS],\n tags: ['learning', 'enrollment'],\n description: 'Enroll in a course.',\n goal: 'Start learning a new course.',\n context: 'Called when a learner wants to start a course.',\n },\n io: {\n input: EnrollInCourseInput,\n output: EnrollmentModel,\n errors: {\n COURSE_NOT_FOUND: {\n description: 'Course does not exist',\n http: 404,\n gqlCode: 'COURSE_NOT_FOUND',\n when: 'Course ID is invalid',\n },\n ALREADY_ENROLLED: {\n description: 'Already enrolled in course',\n http: 409,\n gqlCode: 'ALREADY_ENROLLED',\n when: 'Learner is already enrolled',\n },\n },\n },\n policy: {\n auth: 'user',\n },\n});\n\n/**\n * Complete a lesson.\n */\nexport const CompleteLessonContract = defineCommand({\n meta: {\n key: 'learning.completeLesson',\n version: '1.0.0',\n stability: 'stable',\n owners: [...LEARNING_JOURNEY_OWNERS],\n tags: ['learning', 'progress'],\n description: 'Mark a lesson as completed.',\n goal: 'Record lesson completion and earn XP.',\n context: 'Called when a learner finishes a lesson.',\n },\n io: {\n input: CompleteLessonInput,\n output: SuccessOutput,\n errors: {\n LESSON_NOT_FOUND: {\n description: 'Lesson does not exist',\n http: 404,\n gqlCode: 'LESSON_NOT_FOUND',\n when: 'Lesson ID is invalid',\n },\n NOT_ENROLLED: {\n description: 'Not enrolled in course',\n http: 403,\n gqlCode: 'NOT_ENROLLED',\n when: 'Learner is not enrolled in the course',\n },\n },\n },\n policy: {\n auth: 'user',\n },\n});\n\n/**\n * Submit a card review.\n */\nexport const SubmitCardReviewContract = defineCommand({\n meta: {\n key: 'learning.submitCardReview',\n version: '1.0.0',\n stability: 'stable',\n owners: [...LEARNING_JOURNEY_OWNERS],\n tags: ['learning', 'flashcards'],\n description: 'Submit a flashcard review.',\n goal: 'Record review and update SRS schedule.',\n context: 'Called when reviewing flashcards.',\n },\n io: {\n input: SubmitCardReviewInput,\n output: SuccessOutput,\n errors: {\n CARD_NOT_FOUND: {\n description: 'Card does not exist',\n http: 404,\n gqlCode: 'CARD_NOT_FOUND',\n when: 'Card ID is invalid',\n },\n INVALID_RATING: {\n description: 'Invalid rating',\n http: 400,\n gqlCode: 'INVALID_RATING',\n when: 'Rating must be AGAIN, HARD, GOOD, or EASY',\n },\n },\n },\n policy: {\n auth: 'user',\n },\n});\n\n/**\n * Get cards due for review.\n */\nexport const GetDueCardsContract = defineQuery({\n meta: {\n key: 'learning.getDueCards',\n version: '1.0.0',\n stability: 'stable',\n owners: [...LEARNING_JOURNEY_OWNERS],\n tags: ['learning', 'flashcards'],\n description: 'Get flashcards due for review.',\n goal: 'Get the next batch of cards to review.',\n context: 'Called when starting a review session.',\n },\n io: {\n input: GetDueCardsInput,\n output: GetDueCardsOutput,\n },\n policy: {\n auth: 'user',\n },\n});\n\n/**\n * Get learner dashboard.\n */\nexport const GetLearnerDashboardContract = defineQuery({\n meta: {\n key: 'learning.getDashboard',\n version: '1.0.0',\n stability: 'stable',\n owners: [...LEARNING_JOURNEY_OWNERS],\n tags: ['learning', 'dashboard'],\n description: 'Get learner dashboard data.',\n goal: 'Display learner progress and stats.',\n context: 'Called when viewing the learning dashboard.',\n },\n io: {\n input: GetLearnerDashboardInput,\n output: LearnerDashboardModel,\n },\n policy: {\n auth: 'user',\n },\n});\n"],"mappings":";;;;;;;;AAkBA,MAAa,yBAAyB,cAAc;CAClD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,wBAAwB;EACpC,MAAM,CAAC,YAAY,aAAa;EAChC,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACR,QAAQ;GACN,kBAAkB;IAChB,aAAa;IACb,MAAM;IACN,SAAS;IACT,MAAM;IACP;GACD,kBAAkB;IAChB,aAAa;IACb,MAAM;IACN,SAAS;IACT,MAAM;IACP;GACF;EACF;CACD,QAAQ,EACN,MAAM,QACP;CACF,CAAC;;;;AAKF,MAAa,yBAAyB,cAAc;CAClD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,wBAAwB;EACpC,MAAM,CAAC,YAAY,WAAW;EAC9B,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACR,QAAQ;GACN,kBAAkB;IAChB,aAAa;IACb,MAAM;IACN,SAAS;IACT,MAAM;IACP;GACD,cAAc;IACZ,aAAa;IACb,MAAM;IACN,SAAS;IACT,MAAM;IACP;GACF;EACF;CACD,QAAQ,EACN,MAAM,QACP;CACF,CAAC;;;;AAKF,MAAa,2BAA2B,cAAc;CACpD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,wBAAwB;EACpC,MAAM,CAAC,YAAY,aAAa;EAChC,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACR,QAAQ;GACN,gBAAgB;IACd,aAAa;IACb,MAAM;IACN,SAAS;IACT,MAAM;IACP;GACD,gBAAgB;IACd,aAAa;IACb,MAAM;IACN,SAAS;IACT,MAAM;IACP;GACF;EACF;CACD,QAAQ,EACN,MAAM,QACP;CACF,CAAC;;;;AAKF,MAAa,sBAAsB,YAAY;CAC7C,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,wBAAwB;EACpC,MAAM,CAAC,YAAY,aAAa;EAChC,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACT;CACD,QAAQ,EACN,MAAM,QACP;CACF,CAAC;;;;AAKF,MAAa,8BAA8B,YAAY;CACrD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,wBAAwB;EACpC,MAAM,CAAC,YAAY,YAAY;EAC/B,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACT;CACD,QAAQ,EACN,MAAM,QACP;CACF,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","names":[],"sources":["../../src/contracts/shared.ts"],"sourcesContent":["export const LEARNING_JOURNEY_OWNERS = ['modules.learning-journey'] as const;\n"],"mappings":";AAAA,MAAa,0BAA0B,CAAC,2BAA2B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"learning-journey.docblock.js","names":[],"sources":["../../src/docs/learning-journey.docblock.ts"],"sourcesContent":["import type { DocBlock } from '@contractspec/lib.contracts/docs';\nimport { registerDocBlocks } from '@contractspec/lib.contracts/docs';\n\nconst learningJourneyDocBlocks: DocBlock[] = [\n {\n id: 'docs.learning-journey.engine',\n title: 'Learning Journey Engine',\n summary:\n 'Tracks learners, tracks/modules/steps, progress, quizzes, streaks, XP, and AI coaching hooks for product-integrated onboarding.',\n kind: 'reference',\n visibility: 'public',\n route: '/docs/learning-journey/engine',\n tags: ['learning', 'onboarding', 'journey', 'education'],\n body: `## Capabilities\n\n- **Entities**: Learner, Track, Module, Step, Progress, Quiz, Flashcard, AI Coach, Gamification (XP, streaks, badges).\n- **Contracts**: enroll/resume/advance steps, complete quizzes, record streaks, assign XP, fetch progress dashboards, onboarding list/progress/recordEvent.\n- **Engines**: spaced-repetition (SRS), streak calculator, XP progression.\n- **Events**: learner.enrolled, step.completed, quiz.scored, streak.reset, xp.awarded, onboarding.started/completed/step_completed.\n\n## Completion conditions\n- Event-based: name/version/source + payload filter\n- Count-based: require N events (optional time window)\n- Time-bounded: must complete within a window; steps can unlock by day/hour\n- SRS mastery: complete when cards/skills hit mastery thresholds (with required counts)\n\n## Usage\n\n1) Compose schema\n- Include \\`learningJourneySchemaContribution\\` (entities export) in composition.\n\n2) Register contracts/events\n- Import from \\`@contractspec/module.learning-journey\\` into your spec registry.\n\n3) Bind to product actions\n- Tie \\`Step\\` completion conditions to domain events (e.g., deal.created, agent.run.completed, drill.session.completed).\n- Trigger notifications via Notification Center and audits on completion.\n\n4) Gamification\n- Use \\`XP\\` and \\`Streak\\` engines to update learner stats; emit analytics for UI.\n\n## Example\n\n${'```'}ts\nimport { learningJourneyEntities } from '@contractspec/module.learning-journey';\nimport { StreakEngine } from '@contractspec/module.learning-journey/engines';\n\nconst streak = new StreakEngine({ graceDays: 1 });\nconst updated = streak.compute({ lastActiveAt: new Date(), today: new Date() });\n${'```'},\n\n## Guardrails\n\n- Keep steps bound to real product events, not just button clicks.\n- Avoid storing PII in content; keep org/user scoping for multi-tenant isolation.\n- Emit analytics and audit logs for completions; respect \\`prefers-reduced-motion\\` in UIs consuming these specs.\n- Track completion bonuses: \\`completionXpBonus\\`, \\`completionBadgeKey\\`, optional \\`streakHoursWindow\\` + \\`streakBonusXp\\`.\n`,\n },\n {\n id: 'docs.learning-journey.goal',\n title: 'Learning Journey — Goal',\n summary:\n 'Why the learning journey engine exists and the outcomes it targets.',\n kind: 'goal',\n visibility: 'public',\n route: '/docs/learning-journey/goal',\n tags: ['learning', 'goal'],\n body: `## Why it matters\n- Provides a regenerable onboarding/education engine tied to product signals.\n- Keeps tracks, steps, quizzes, and gamification consistent across surfaces.\n\n## Business/Product goal\n- Drive activation and retention with measurable progress, SRS, and streaks.\n- Allow product teams to adjust journeys safely via specs.\n\n## Success criteria\n- Journey changes regenerate UI/API/events without drift.\n- Analytics/audit hooks exist for completions and streaks.`,\n },\n {\n id: 'docs.learning-journey.usage',\n title: 'Learning Journey — Usage',\n summary: 'How to compose, bind, and regenerate journeys safely.',\n kind: 'usage',\n visibility: 'public',\n route: '/docs/learning-journey/usage',\n tags: ['learning', 'usage'],\n body: `## Setup\n1) Include \\`learningJourneyEntities\\` in schema composition.\n2) Register contracts/events from \\`@contractspec/module.learning-journey\\`.\n3) Bind steps to real product events (e.g., deal.created, run.completed).\n\n## Extend & regenerate\n1) Update track/module/step definitions or quiz schemas in spec.\n2) Regenerate to sync UI/API/events; mark PII paths where needed.\n3) Use Feature Flags to trial new tracks or streak rules.\n\n## Guardrails\n- Avoid hardcoded progression; keep engines declarative.\n- Emit analytics/audit for completions; respect user locale/accessibility in presentations.\n- Keep content free of PII; scope learners by org/tenant.`,\n },\n {\n id: 'docs.learning-journey.constraints',\n title: 'Learning Journey — Constraints & Safety',\n summary:\n 'Internal guardrails for progression, telemetry, and regeneration semantics.',\n kind: 'reference',\n visibility: 'internal',\n route: '/docs/learning-journey/constraints',\n tags: ['learning', 'constraints', 'internal'],\n body: `## Constraints\n- Progression (tracks/modules/steps) and engines (SRS, streaks, XP) must stay declarative in spec.\n- Events to emit: learner.enrolled, step.completed, quiz.scored, streak.reset, xp.awarded.\n- Regeneration should not change scoring/streak rules without explicit spec change.\n\n## PII & Telemetry\n- Mark PII (learner identifiers) and redact in presentations; keep telemetry aggregated when possible.\n- Respect accessibility (prefers-reduced-motion) in UIs consuming these specs.\n\n## Verification\n- Add fixtures for streak/XP rule changes and quiz scoring.\n- Ensure Notifications/Audit wiring persists for completions; analytics emitted for progress.\n- Use Feature Flags to trial new tracks or reward rules; default safe/off.`,\n },\n];\n\nregisterDocBlocks(learningJourneyDocBlocks);\n"],"mappings":";;;AAgIA,kBA7H6C;CAC3C;EACE,IAAI;EACJ,OAAO;EACP,SACE;EACF,MAAM;EACN,YAAY;EACZ,OAAO;EACP,MAAM;GAAC;GAAY;GAAc;GAAW;GAAY;EACxD,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6CP;CACD;EACE,IAAI;EACJ,OAAO;EACP,SACE;EACF,MAAM;EACN,YAAY;EACZ,OAAO;EACP,MAAM,CAAC,YAAY,OAAO;EAC1B,MAAM;;;;;;;;;;;EAWP;CACD;EACE,IAAI;EACJ,OAAO;EACP,SAAS;EACT,MAAM;EACN,YAAY;EACZ,OAAO;EACP,MAAM,CAAC,YAAY,QAAQ;EAC3B,MAAM;;;;;;;;;;;;;;EAcP;CACD;EACE,IAAI;EACJ,OAAO;EACP,SACE;EACF,MAAM;EACN,YAAY;EACZ,OAAO;EACP,MAAM;GAAC;GAAY;GAAe;GAAW;EAC7C,MAAM;;;;;;;;;;;;;EAaP;CACF,CAE0C"}
|
package/dist/engines/srs.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"srs.js","names":[],"sources":["../../src/engines/srs.ts"],"sourcesContent":["/**\n * Spaced Repetition System (SRS) Engine\n *\n * Implements the SM-2 algorithm variant for optimal flashcard scheduling.\n *\n * The algorithm calculates the optimal time to review a card based on:\n * - User's rating of recall difficulty (again, hard, good, easy)\n * - Current interval between reviews\n * - Ease factor (how easy the card is for this user)\n * - Number of successful repetitions\n */\n\n// ============ Types ============\n\nexport type CardRating = 'AGAIN' | 'HARD' | 'GOOD' | 'EASY';\n\nexport interface SRSState {\n /** Current interval in days */\n interval: number;\n /** Ease factor (typically 1.3 to 2.5+) */\n easeFactor: number;\n /** Number of successful repetitions */\n repetitions: number;\n /** Current learning step (for new cards) */\n learningStep: number;\n /** Whether card has graduated to review phase */\n isGraduated: boolean;\n /** Whether card is being relearned after a lapse */\n isRelearning: boolean;\n /** Number of times card was forgotten */\n lapses: number;\n}\n\nexport interface ReviewResult {\n /** New interval in days */\n interval: number;\n /** New ease factor */\n easeFactor: number;\n /** New repetition count */\n repetitions: number;\n /** Next review date */\n nextReviewAt: Date;\n /** New learning step */\n learningStep: number;\n /** Whether card has graduated */\n isGraduated: boolean;\n /** Whether card is being relearned */\n isRelearning: boolean;\n /** Updated lapse count */\n lapses: number;\n}\n\nexport interface SRSConfig {\n /** Learning steps in minutes [1, 10] = 1 min, 10 min */\n learningSteps: number[];\n /** Graduating interval in days */\n graduatingInterval: number;\n /** Easy interval (for easy button on new cards) */\n easyInterval: number;\n /** Relearning steps in minutes */\n relearningSteps: number[];\n /** Minimum ease factor */\n minEaseFactor: number;\n /** Maximum interval in days */\n maxInterval: number;\n /** Interval modifier (1.0 = 100%) */\n intervalModifier: number;\n /** New cards interval modifier */\n newIntervalModifier: number;\n /** Hard interval modifier */\n hardIntervalModifier: number;\n /** Easy bonus modifier */\n easyBonus: number;\n}\n\n// ============ Default Configuration ============\n\nexport const DEFAULT_SRS_CONFIG: SRSConfig = {\n learningSteps: [1, 10], // 1 minute, 10 minutes\n graduatingInterval: 1, // 1 day\n easyInterval: 4, // 4 days\n relearningSteps: [10], // 10 minutes\n minEaseFactor: 1.3,\n maxInterval: 365, // 1 year\n intervalModifier: 1.0,\n newIntervalModifier: 0.5,\n hardIntervalModifier: 1.2,\n easyBonus: 1.3,\n};\n\n// ============ SRS Engine ============\n\nexport class SRSEngine {\n private config: SRSConfig;\n\n constructor(config: Partial<SRSConfig> = {}) {\n this.config = { ...DEFAULT_SRS_CONFIG, ...config };\n }\n\n /**\n * Calculate the next review state based on rating.\n */\n calculateNextReview(\n state: SRSState,\n rating: CardRating,\n now: Date = new Date()\n ): ReviewResult {\n // Handle new/learning cards\n if (!state.isGraduated && !state.isRelearning) {\n return this.handleLearningCard(state, rating, now);\n }\n\n // Handle relearning cards\n if (state.isRelearning) {\n return this.handleRelearningCard(state, rating, now);\n }\n\n // Handle graduated cards in review\n return this.handleReviewCard(state, rating, now);\n }\n\n /**\n * Get initial SRS state for a new card.\n */\n getInitialState(): SRSState {\n return {\n interval: 0,\n easeFactor: 2.5,\n repetitions: 0,\n learningStep: 0,\n isGraduated: false,\n isRelearning: false,\n lapses: 0,\n };\n }\n\n /**\n * Check if a card is due for review.\n */\n isDue(nextReviewAt: Date, now: Date = new Date()): boolean {\n return nextReviewAt <= now;\n }\n\n /**\n * Calculate overdue days (negative if not yet due).\n */\n getOverdueDays(nextReviewAt: Date, now: Date = new Date()): number {\n const diff = now.getTime() - nextReviewAt.getTime();\n return Math.floor(diff / (1000 * 60 * 60 * 24));\n }\n\n /**\n * Handle learning phase (new cards).\n */\n private handleLearningCard(\n state: SRSState,\n rating: CardRating,\n now: Date\n ): ReviewResult {\n const steps = this.config.learningSteps;\n let newStep = state.learningStep;\n let isGraduated = false;\n let interval = 0;\n let nextReviewAt: Date;\n\n switch (rating) {\n case 'AGAIN':\n // Reset to first step\n newStep = 0;\n interval = steps[0] ?? 1;\n nextReviewAt = this.addMinutes(now, interval);\n break;\n\n case 'HARD':\n // Stay at current step (or repeat first step)\n interval = steps[newStep] ?? steps[0] ?? 1;\n nextReviewAt = this.addMinutes(now, interval);\n break;\n\n case 'GOOD':\n // Move to next step\n newStep++;\n if (newStep >= steps.length) {\n // Graduate the card\n isGraduated = true;\n interval = this.config.graduatingInterval;\n nextReviewAt = this.addDays(now, interval);\n } else {\n interval = steps[newStep] ?? 10;\n nextReviewAt = this.addMinutes(now, interval);\n }\n break;\n\n case 'EASY':\n // Graduate immediately with easy interval\n isGraduated = true;\n interval = this.config.easyInterval;\n nextReviewAt = this.addDays(now, interval);\n break;\n }\n\n return {\n interval: isGraduated ? interval : 0,\n easeFactor: state.easeFactor,\n repetitions: isGraduated ? 1 : 0,\n nextReviewAt,\n learningStep: newStep,\n isGraduated,\n isRelearning: false,\n lapses: state.lapses,\n };\n }\n\n /**\n * Handle relearning phase (lapsed cards).\n */\n private handleRelearningCard(\n state: SRSState,\n rating: CardRating,\n now: Date\n ): ReviewResult {\n const steps = this.config.relearningSteps;\n let newStep = state.learningStep;\n let isRelearning = true;\n let interval = 0;\n let nextReviewAt: Date;\n\n switch (rating) {\n case 'AGAIN':\n // Reset to first relearning step\n newStep = 0;\n interval = steps[0] ?? 10;\n nextReviewAt = this.addMinutes(now, interval);\n break;\n\n case 'HARD':\n // Stay at current step\n interval = steps[newStep] ?? steps[0] ?? 10;\n nextReviewAt = this.addMinutes(now, interval);\n break;\n\n case 'GOOD':\n // Move to next step or graduate back to review\n newStep++;\n if (newStep >= steps.length) {\n isRelearning = false;\n // Use reduced interval after lapse\n interval = Math.max(\n 1,\n Math.floor(state.interval * this.config.newIntervalModifier)\n );\n nextReviewAt = this.addDays(now, interval);\n } else {\n interval = steps[newStep] ?? 10;\n nextReviewAt = this.addMinutes(now, interval);\n }\n break;\n\n case 'EASY':\n // Graduate immediately with slightly longer interval\n isRelearning = false;\n interval = Math.max(\n 1,\n Math.floor(state.interval * this.config.newIntervalModifier * 1.5)\n );\n nextReviewAt = this.addDays(now, interval);\n break;\n }\n\n return {\n interval: isRelearning ? state.interval : interval,\n easeFactor: state.easeFactor,\n repetitions: isRelearning ? state.repetitions : state.repetitions + 1,\n nextReviewAt,\n learningStep: newStep,\n isGraduated: true,\n isRelearning,\n lapses: state.lapses,\n };\n }\n\n /**\n * Handle review phase (graduated cards).\n */\n private handleReviewCard(\n state: SRSState,\n rating: CardRating,\n now: Date\n ): ReviewResult {\n let newInterval: number;\n let newEaseFactor = state.easeFactor;\n let repetitions = state.repetitions;\n let isRelearning = false;\n let learningStep = 0;\n let lapses = state.lapses;\n\n switch (rating) {\n case 'AGAIN':\n // Card lapsed - move to relearning\n lapses++;\n isRelearning = true;\n learningStep = 0;\n newEaseFactor = Math.max(\n this.config.minEaseFactor,\n newEaseFactor - 0.2\n );\n newInterval = state.interval; // Keep old interval for reference\n return {\n interval: newInterval,\n easeFactor: newEaseFactor,\n repetitions,\n nextReviewAt: this.addMinutes(\n now,\n this.config.relearningSteps[0] ?? 10\n ),\n learningStep,\n isGraduated: true,\n isRelearning: true,\n lapses,\n };\n\n case 'HARD':\n // Reduce interval slightly, reduce ease\n newEaseFactor = Math.max(\n this.config.minEaseFactor,\n newEaseFactor - 0.15\n );\n newInterval = Math.max(\n state.interval + 1,\n state.interval * this.config.hardIntervalModifier\n );\n break;\n\n case 'GOOD':\n // Standard interval increase\n newInterval =\n state.interval * newEaseFactor * this.config.intervalModifier;\n repetitions++;\n break;\n\n case 'EASY':\n // Larger interval increase, increase ease\n newEaseFactor = newEaseFactor + 0.15;\n newInterval =\n state.interval *\n newEaseFactor *\n this.config.easyBonus *\n this.config.intervalModifier;\n repetitions++;\n break;\n }\n\n // Apply bounds\n newInterval = Math.min(Math.round(newInterval), this.config.maxInterval);\n newInterval = Math.max(1, newInterval);\n\n return {\n interval: newInterval,\n easeFactor: newEaseFactor,\n repetitions,\n nextReviewAt: this.addDays(now, newInterval),\n learningStep,\n isGraduated: true,\n isRelearning,\n lapses,\n };\n }\n\n // ============ Helpers ============\n\n private addMinutes(date: Date, minutes: number): Date {\n return new Date(date.getTime() + minutes * 60 * 1000);\n }\n\n private addDays(date: Date, days: number): Date {\n return new Date(date.getTime() + days * 24 * 60 * 60 * 1000);\n }\n}\n\n/**\n * Default SRS engine instance.\n */\nexport const srsEngine = new SRSEngine();\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"streak.js","names":[],"sources":["../../src/engines/streak.ts"],"sourcesContent":["/**\n * Streak Tracking Engine\n *\n * Manages daily learning streaks with timezone support and freeze protection.\n */\n\n// ============ Types ============\n\nexport interface StreakState {\n /** Current streak days */\n currentStreak: number;\n /** Longest streak ever */\n longestStreak: number;\n /** Last activity timestamp */\n lastActivityAt: Date | null;\n /** Last activity date (YYYY-MM-DD) */\n lastActivityDate: string | null;\n /** Available streak freezes */\n freezesRemaining: number;\n /** When a freeze was last used */\n freezeUsedAt: Date | null;\n}\n\nexport interface StreakUpdateResult {\n /** Updated streak state */\n state: StreakState;\n /** Whether streak was maintained */\n streakMaintained: boolean;\n /** Whether streak was lost */\n streakLost: boolean;\n /** Whether a freeze was used */\n freezeUsed: boolean;\n /** Whether this activity started a new streak */\n newStreak: boolean;\n /** Days missed (if streak was lost) */\n daysMissed: number;\n}\n\nexport interface StreakConfig {\n /** Timezone for the user */\n timezone: string;\n /** How many streak freezes to give per month */\n freezesPerMonth: number;\n /** Maximum freezes that can be accumulated */\n maxFreezes: number;\n /** Grace period in hours after midnight */\n gracePeriodHours: number;\n}\n\n// ============ Default Configuration ============\n\nexport const DEFAULT_STREAK_CONFIG: StreakConfig = {\n timezone: 'UTC',\n freezesPerMonth: 2,\n maxFreezes: 5,\n gracePeriodHours: 4, // 4 hours grace period\n};\n\n// ============ Streak Engine ============\n\nexport class StreakEngine {\n private config: StreakConfig;\n\n constructor(config: Partial<StreakConfig> = {}) {\n this.config = { ...DEFAULT_STREAK_CONFIG, ...config };\n }\n\n /**\n * Update streak based on new activity.\n */\n update(state: StreakState, now: Date = new Date()): StreakUpdateResult {\n const todayDate = this.getDateString(now);\n const result: StreakUpdateResult = {\n state: { ...state },\n streakMaintained: false,\n streakLost: false,\n freezeUsed: false,\n newStreak: false,\n daysMissed: 0,\n };\n\n // If no previous activity, start new streak\n if (!state.lastActivityDate) {\n result.state.currentStreak = 1;\n result.state.longestStreak = Math.max(1, state.longestStreak);\n result.state.lastActivityAt = now;\n result.state.lastActivityDate = todayDate;\n result.newStreak = true;\n result.streakMaintained = true;\n return result;\n }\n\n // Check if activity is on the same day\n if (state.lastActivityDate === todayDate) {\n // Same day - just update timestamp, streak unchanged\n result.state.lastActivityAt = now;\n result.streakMaintained = true;\n return result;\n }\n\n // Calculate days since last activity\n const daysSinceActivity = this.getDaysBetween(\n state.lastActivityDate,\n todayDate\n );\n\n if (daysSinceActivity === 1) {\n // Perfect - activity on consecutive day\n result.state.currentStreak = state.currentStreak + 1;\n result.state.longestStreak = Math.max(\n result.state.currentStreak,\n state.longestStreak\n );\n result.state.lastActivityAt = now;\n result.state.lastActivityDate = todayDate;\n result.streakMaintained = true;\n return result;\n }\n\n // Streak was potentially broken\n result.daysMissed = daysSinceActivity - 1;\n\n // Check if we can use freezes\n const freezesNeeded = result.daysMissed;\n if (freezesNeeded <= state.freezesRemaining) {\n // Use freezes to maintain streak\n result.state.freezesRemaining = state.freezesRemaining - freezesNeeded;\n result.state.freezeUsedAt = now;\n result.state.currentStreak = state.currentStreak + 1; // Add today\n result.state.longestStreak = Math.max(\n result.state.currentStreak,\n state.longestStreak\n );\n result.state.lastActivityAt = now;\n result.state.lastActivityDate = todayDate;\n result.freezeUsed = true;\n result.streakMaintained = true;\n return result;\n }\n\n // Streak is lost\n result.streakLost = true;\n result.state.currentStreak = 1; // Start new streak\n result.state.lastActivityAt = now;\n result.state.lastActivityDate = todayDate;\n result.newStreak = true;\n return result;\n }\n\n /**\n * Check streak status without recording activity.\n */\n checkStatus(\n state: StreakState,\n now: Date = new Date()\n ): {\n isActive: boolean;\n willExpireAt: Date | null;\n canUseFreeze: boolean;\n daysUntilExpiry: number;\n } {\n if (!state.lastActivityDate) {\n return {\n isActive: false,\n willExpireAt: null,\n canUseFreeze: false,\n daysUntilExpiry: 0,\n };\n }\n\n const todayDate = this.getDateString(now);\n const daysSinceActivity = this.getDaysBetween(\n state.lastActivityDate,\n todayDate\n );\n\n if (daysSinceActivity === 0) {\n // Activity today - streak is active\n const tomorrow = this.addDays(now, 1);\n tomorrow.setHours(23, 59, 59, 999);\n return {\n isActive: true,\n willExpireAt: tomorrow,\n canUseFreeze: state.freezesRemaining > 0,\n daysUntilExpiry: 1,\n };\n }\n\n if (daysSinceActivity === 1) {\n // No activity today yet, but still within window\n const endOfDay = new Date(now);\n endOfDay.setHours(23 + this.config.gracePeriodHours, 59, 59, 999);\n return {\n isActive: true,\n willExpireAt: endOfDay,\n canUseFreeze: state.freezesRemaining > 0,\n daysUntilExpiry: 0,\n };\n }\n\n // Streak would be broken\n const missedDays = daysSinceActivity - 1;\n return {\n isActive: missedDays <= state.freezesRemaining,\n willExpireAt: null,\n canUseFreeze: missedDays <= state.freezesRemaining,\n daysUntilExpiry: -missedDays,\n };\n }\n\n /**\n * Manually use a freeze to protect streak.\n */\n useFreeze(state: StreakState, now: Date = new Date()): StreakState | null {\n if (state.freezesRemaining <= 0) {\n return null;\n }\n\n return {\n ...state,\n freezesRemaining: state.freezesRemaining - 1,\n freezeUsedAt: now,\n };\n }\n\n /**\n * Award monthly freezes.\n */\n awardMonthlyFreezes(state: StreakState): StreakState {\n return {\n ...state,\n freezesRemaining: Math.min(\n state.freezesRemaining + this.config.freezesPerMonth,\n this.config.maxFreezes\n ),\n };\n }\n\n /**\n * Get initial streak state.\n */\n getInitialState(): StreakState {\n return {\n currentStreak: 0,\n longestStreak: 0,\n lastActivityAt: null,\n lastActivityDate: null,\n freezesRemaining: this.config.freezesPerMonth,\n freezeUsedAt: null,\n };\n }\n\n /**\n * Calculate streak milestones.\n */\n getMilestones(currentStreak: number): {\n achieved: number[];\n next: number | null;\n } {\n const milestones = [3, 7, 14, 30, 60, 90, 180, 365, 500, 1000];\n const achieved = milestones.filter((m) => currentStreak >= m);\n const next = milestones.find((m) => currentStreak < m) ?? null;\n return { achieved, next };\n }\n\n // ============ Helpers ============\n\n /**\n * Get date string in YYYY-MM-DD format.\n */\n private getDateString(date: Date): string {\n // Simple implementation - for production, use a proper timezone library\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n }\n\n /**\n * Get number of days between two date strings.\n */\n private getDaysBetween(dateStr1: string, dateStr2: string): number {\n const date1 = new Date(dateStr1);\n const date2 = new Date(dateStr2);\n const diffTime = date2.getTime() - date1.getTime();\n return Math.floor(diffTime / (1000 * 60 * 60 * 24));\n }\n\n /**\n * Add days to a date.\n */\n private addDays(date: Date, days: number): Date {\n return new Date(date.getTime() + days * 24 * 60 * 60 * 1000);\n }\n}\n\n/**\n * Default streak engine instance.\n */\nexport const streakEngine = new StreakEngine();\n"],"mappings":"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"}
|
package/dist/engines/xp.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"xp.js","names":[],"sources":["../../src/engines/xp.ts"],"sourcesContent":["/**\n * XP (Experience Points) Engine\n *\n * Calculates XP rewards for various learning activities.\n */\n\n// ============ Types ============\n\nexport type XPActivityType =\n | 'lesson_complete'\n | 'quiz_pass'\n | 'quiz_perfect'\n | 'flashcard_review'\n | 'course_complete'\n | 'module_complete'\n | 'streak_bonus'\n | 'achievement_unlock'\n | 'daily_goal_complete'\n | 'first_lesson'\n | 'onboarding_step'\n | 'onboarding_complete';\n\nexport interface XPCalculationInput {\n /** Type of activity */\n activity: XPActivityType;\n /** Base XP for the activity (from content config) */\n baseXp?: number;\n /** Score achieved (0-100) for scored activities */\n score?: number;\n /** Current streak (for streak bonuses) */\n currentStreak?: number;\n /** Time spent in seconds */\n timeSpent?: number;\n /** Attempt number (for quizzes) */\n attemptNumber?: number;\n /** Whether this is a retry */\n isRetry?: boolean;\n}\n\nexport interface XPResult {\n /** Total XP earned */\n totalXp: number;\n /** Base XP before bonuses */\n baseXp: number;\n /** Breakdown of XP sources */\n breakdown: XPBreakdown[];\n}\n\nexport interface XPBreakdown {\n /** Source of XP */\n source: string;\n /** XP amount */\n amount: number;\n /** Multiplier applied */\n multiplier?: number;\n}\n\nexport interface XPConfig {\n /** Base XP values for each activity */\n baseValues: Record<XPActivityType, number>;\n /** Score thresholds for bonus XP */\n scoreThresholds: { min: number; multiplier: number }[];\n /** Streak bonus tiers */\n streakTiers: { days: number; bonus: number }[];\n /** Perfect score bonus multiplier */\n perfectScoreMultiplier: number;\n /** First attempt bonus */\n firstAttemptBonus: number;\n /** Retry penalty multiplier */\n retryPenalty: number;\n /** Speed bonus (complete under expected time) */\n speedBonusMultiplier: number;\n /** Speed bonus threshold (percentage of expected time) */\n speedBonusThreshold: number;\n}\n\n// ============ Default Configuration ============\n\nexport const DEFAULT_XP_CONFIG: XPConfig = {\n baseValues: {\n lesson_complete: 10,\n quiz_pass: 20,\n quiz_perfect: 50,\n flashcard_review: 1,\n course_complete: 200,\n module_complete: 50,\n streak_bonus: 5,\n achievement_unlock: 0, // XP comes from achievement\n daily_goal_complete: 15,\n first_lesson: 25,\n onboarding_step: 5,\n onboarding_complete: 50,\n },\n scoreThresholds: [\n { min: 90, multiplier: 1.5 },\n { min: 80, multiplier: 1.25 },\n { min: 70, multiplier: 1.0 },\n { min: 60, multiplier: 0.75 },\n { min: 0, multiplier: 0.5 },\n ],\n streakTiers: [\n { days: 365, bonus: 50 },\n { days: 180, bonus: 30 },\n { days: 90, bonus: 20 },\n { days: 30, bonus: 15 },\n { days: 14, bonus: 10 },\n { days: 7, bonus: 5 },\n { days: 3, bonus: 2 },\n { days: 1, bonus: 0 },\n ],\n perfectScoreMultiplier: 1.5,\n firstAttemptBonus: 10,\n retryPenalty: 0.5,\n speedBonusMultiplier: 1.2,\n speedBonusThreshold: 0.8,\n};\n\n// ============ XP Engine ============\n\nexport class XPEngine {\n private config: XPConfig;\n\n constructor(config: Partial<XPConfig> = {}) {\n this.config = {\n ...DEFAULT_XP_CONFIG,\n ...config,\n baseValues: { ...DEFAULT_XP_CONFIG.baseValues, ...config.baseValues },\n scoreThresholds:\n config.scoreThresholds || DEFAULT_XP_CONFIG.scoreThresholds,\n streakTiers: config.streakTiers || DEFAULT_XP_CONFIG.streakTiers,\n };\n }\n\n /**\n * Calculate XP for an activity.\n */\n calculate(input: XPCalculationInput): XPResult {\n const breakdown: XPBreakdown[] = [];\n\n // Get base XP\n const baseXp = input.baseXp ?? this.config.baseValues[input.activity];\n let totalXp = baseXp;\n\n breakdown.push({\n source: 'base',\n amount: baseXp,\n });\n\n // Apply score-based multiplier\n if (input.score !== undefined) {\n const scoreMultiplier = this.getScoreMultiplier(input.score);\n if (scoreMultiplier !== 1.0) {\n const scoreBonus = Math.round(baseXp * (scoreMultiplier - 1));\n totalXp += scoreBonus;\n breakdown.push({\n source: 'score_bonus',\n amount: scoreBonus,\n multiplier: scoreMultiplier,\n });\n }\n\n // Perfect score bonus\n if (input.score === 100) {\n const perfectBonus = Math.round(\n baseXp * (this.config.perfectScoreMultiplier - 1)\n );\n totalXp += perfectBonus;\n breakdown.push({\n source: 'perfect_score',\n amount: perfectBonus,\n multiplier: this.config.perfectScoreMultiplier,\n });\n }\n }\n\n // First attempt bonus\n if (input.attemptNumber === 1 && !input.isRetry) {\n totalXp += this.config.firstAttemptBonus;\n breakdown.push({\n source: 'first_attempt',\n amount: this.config.firstAttemptBonus,\n });\n }\n\n // Retry penalty\n if (input.isRetry) {\n const penalty = Math.round(totalXp * (1 - this.config.retryPenalty));\n totalXp -= penalty;\n breakdown.push({\n source: 'retry_penalty',\n amount: -penalty,\n multiplier: this.config.retryPenalty,\n });\n }\n\n // Streak bonus\n if (input.currentStreak && input.currentStreak > 0) {\n const streakBonus = this.getStreakBonus(input.currentStreak);\n if (streakBonus > 0) {\n totalXp += streakBonus;\n breakdown.push({\n source: 'streak_bonus',\n amount: streakBonus,\n });\n }\n }\n\n // Ensure XP is at least 1 (if base was > 0)\n if (baseXp > 0) {\n totalXp = Math.max(1, totalXp);\n }\n\n return {\n totalXp: Math.round(totalXp),\n baseXp,\n breakdown,\n };\n }\n\n /**\n * Calculate streak bonus XP.\n */\n calculateStreakBonus(currentStreak: number): XPResult {\n const bonus = this.getStreakBonus(currentStreak);\n return {\n totalXp: bonus,\n baseXp: bonus,\n breakdown: [\n {\n source: 'streak_bonus',\n amount: bonus,\n },\n ],\n };\n }\n\n /**\n * Calculate XP needed for a level.\n */\n getXpForLevel(level: number): number {\n // Exponential growth formula\n // Level 1: 0 XP\n // Level 2: 100 XP\n // Level 3: 300 XP\n // etc.\n if (level <= 1) return 0;\n return Math.round(100 * Math.pow(level - 1, 1.5));\n }\n\n /**\n * Get level from total XP.\n */\n getLevelFromXp(totalXp: number): {\n level: number;\n xpInLevel: number;\n xpForNextLevel: number;\n } {\n let level = 1;\n let xpRequired = this.getXpForLevel(level + 1);\n\n while (totalXp >= xpRequired && level < 1000) {\n level++;\n xpRequired = this.getXpForLevel(level + 1);\n }\n\n const xpForCurrentLevel = this.getXpForLevel(level);\n const xpForNextLevel = this.getXpForLevel(level + 1);\n\n return {\n level,\n xpInLevel: totalXp - xpForCurrentLevel,\n xpForNextLevel: xpForNextLevel - xpForCurrentLevel,\n };\n }\n\n // ============ Helpers ============\n\n private getScoreMultiplier(score: number): number {\n for (const threshold of this.config.scoreThresholds) {\n if (score >= threshold.min) {\n return threshold.multiplier;\n }\n }\n return 1.0;\n }\n\n private getStreakBonus(streak: number): number {\n for (const tier of this.config.streakTiers) {\n if (streak >= tier.days) {\n return tier.bonus;\n }\n }\n return 0;\n }\n}\n\n/**\n * Default XP engine instance.\n */\nexport const xpEngine = new XPEngine();\n"],"mappings":"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"}
|
package/dist/entities/ai.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ai.js","names":[],"sources":["../../src/entities/ai.ts"],"sourcesContent":["import {\n defineEntity,\n defineEntityEnum,\n field,\n index,\n} from '@contractspec/lib.schema';\n\n/**\n * Learning style enum.\n */\nexport const LearningStyleEnum = defineEntityEnum({\n name: 'LearningStyle',\n values: ['VISUAL', 'AUDITORY', 'READING', 'KINESTHETIC', 'MIXED'] as const,\n schema: 'lssm_learning',\n description: 'Preferred learning style.',\n});\n\n/**\n * Recommendation type enum.\n */\nexport const RecommendationTypeEnum = defineEntityEnum({\n name: 'RecommendationType',\n values: [\n 'COURSE',\n 'LESSON',\n 'REVIEW',\n 'PRACTICE',\n 'ASSESSMENT',\n 'DECK',\n ] as const,\n schema: 'lssm_learning',\n description: 'Type of learning recommendation.',\n});\n\n/**\n * LearnerProfile entity - AI personalization profile.\n */\nexport const LearnerProfileEntity = defineEntity({\n name: 'LearnerProfile',\n description: 'AI personalization profile for a learner.',\n schema: 'lssm_learning',\n map: 'learner_profile',\n fields: {\n id: field.id({ description: 'Unique profile identifier' }),\n learnerId: field.foreignKey({ description: 'Learner' }),\n\n // Learning preferences\n learningStyle: field.enum('LearningStyle', {\n default: 'MIXED',\n description: 'Preferred learning style',\n }),\n preferredDifficulty: field.string({\n default: '\"adaptive\"',\n description: 'Difficulty preference',\n }),\n preferredSessionLength: field.int({\n default: 30,\n description: 'Preferred session length in minutes',\n }),\n\n // Interests and goals\n interests: field.json({ isOptional: true, description: 'Topic interests' }),\n goals: field.json({ isOptional: true, description: 'Learning goals' }),\n\n // Pace\n pacePreference: field.string({\n default: '\"normal\"',\n description: 'Learning pace: slow, normal, fast',\n }),\n\n // Engagement patterns\n bestTimeOfDay: field.string({\n isOptional: true,\n description: 'Best time for learning',\n }),\n averageSessionLength: field.int({\n isOptional: true,\n description: 'Average session length',\n }),\n daysActivePerWeek: field.int({\n isOptional: true,\n description: 'Days active per week',\n }),\n\n // Performance\n avgQuizScore: field.int({\n isOptional: true,\n description: 'Average quiz score',\n }),\n avgLessonCompletionTime: field.int({\n isOptional: true,\n description: 'Avg lesson completion time',\n }),\n\n // AI analysis\n strengths: field.json({\n isOptional: true,\n description: 'Identified strengths',\n }),\n weaknesses: field.json({\n isOptional: true,\n description: 'Areas for improvement',\n }),\n\n // Metadata\n lastAnalyzedAt: field.dateTime({\n isOptional: true,\n description: 'Last AI analysis',\n }),\n metadata: field.json({\n isOptional: true,\n description: 'Additional metadata',\n }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n learner: field.belongsTo('Learner', ['learnerId'], ['id'], {\n onDelete: 'Cascade',\n }),\n },\n indexes: [\n index.unique(['learnerId'], { name: 'learner_profile_unique' }),\n index.on(['learningStyle']),\n ],\n enums: [LearningStyleEnum],\n});\n\n/**\n * SkillMap entity - tracks skill proficiency.\n */\nexport const SkillMapEntity = defineEntity({\n name: 'SkillMap',\n description: 'Maps learner proficiency across skills.',\n schema: 'lssm_learning',\n map: 'skill_map',\n fields: {\n id: field.id({ description: 'Unique skill map identifier' }),\n learnerId: field.foreignKey({ description: 'Learner' }),\n\n // Skill\n skillId: field.string({ description: 'Skill identifier' }),\n skillName: field.string({ description: 'Skill name' }),\n skillCategory: field.string({\n isOptional: true,\n description: 'Skill category',\n }),\n\n // Proficiency\n level: field.int({ default: 0, description: 'Proficiency level (0-100)' }),\n confidence: field.decimal({\n default: 0.5,\n description: 'Confidence in assessment',\n }),\n\n // Progress\n lessonsCompleted: field.int({\n default: 0,\n description: 'Related lessons completed',\n }),\n quizzesCompleted: field.int({\n default: 0,\n description: 'Related quizzes completed',\n }),\n practiceTime: field.int({\n default: 0,\n description: 'Practice time in minutes',\n }),\n\n // Last activity\n lastPracticedAt: field.dateTime({\n isOptional: true,\n description: 'Last practice time',\n }),\n\n // AI analysis\n learningVelocity: field.decimal({\n isOptional: true,\n description: 'Learning speed for this skill',\n }),\n predictedTimeToMastery: field.int({\n isOptional: true,\n description: 'Predicted time to mastery (minutes)',\n }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n learner: field.belongsTo('Learner', ['learnerId'], ['id'], {\n onDelete: 'Cascade',\n }),\n },\n indexes: [\n index.unique(['learnerId', 'skillId'], { name: 'skill_map_unique' }),\n index.on(['skillId', 'level']),\n index.on(['learnerId', 'level']),\n ],\n});\n\n/**\n * LearningPath entity - AI-generated learning paths.\n */\nexport const LearningPathEntity = defineEntity({\n name: 'LearningPath',\n description: 'AI-generated personalized learning path.',\n schema: 'lssm_learning',\n map: 'learning_path',\n fields: {\n id: field.id({ description: 'Unique path identifier' }),\n learnerId: field.foreignKey({ description: 'Learner' }),\n\n // Path info\n name: field.string({ description: 'Path name' }),\n description: field.string({\n isOptional: true,\n description: 'Path description',\n }),\n goal: field.string({ isOptional: true, description: 'Path goal' }),\n\n // Steps\n steps: field.json({ description: 'Ordered list of learning steps' }),\n currentStepIndex: field.int({\n default: 0,\n description: 'Current step index',\n }),\n\n // Progress\n progress: field.int({ default: 0, description: 'Completion percentage' }),\n completedSteps: field.int({ default: 0, description: 'Steps completed' }),\n totalSteps: field.int({ default: 0, description: 'Total steps' }),\n\n // Generation\n generatedAt: field.dateTime({ description: 'When path was generated' }),\n adaptedFrom: field.string({\n isOptional: true,\n description: 'Original path ID if adapted',\n }),\n\n // AI metadata\n generationParams: field.json({\n isOptional: true,\n description: 'AI generation parameters',\n }),\n adaptationHistory: field.json({\n isOptional: true,\n description: 'Path adaptation history',\n }),\n\n // Status\n isActive: field.boolean({\n default: true,\n description: 'Whether path is active',\n }),\n isCompleted: field.boolean({\n default: false,\n description: 'Whether path is completed',\n }),\n\n // Timeline\n startedAt: field.dateTime({\n isOptional: true,\n description: 'When started',\n }),\n completedAt: field.dateTime({\n isOptional: true,\n description: 'When completed',\n }),\n estimatedCompletionDate: field.dateTime({\n isOptional: true,\n description: 'Estimated completion',\n }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n learner: field.belongsTo('Learner', ['learnerId'], ['id'], {\n onDelete: 'Cascade',\n }),\n },\n indexes: [index.on(['learnerId', 'isActive']), index.on(['generatedAt'])],\n});\n\n/**\n * Recommendation entity - AI-powered learning recommendations.\n */\nexport const RecommendationEntity = defineEntity({\n name: 'Recommendation',\n description: 'AI-powered learning recommendation.',\n schema: 'lssm_learning',\n map: 'recommendation',\n fields: {\n id: field.id({ description: 'Unique recommendation identifier' }),\n learnerId: field.foreignKey({ description: 'Learner' }),\n\n // Recommendation\n type: field.enum('RecommendationType', {\n description: 'Recommendation type',\n }),\n itemId: field.string({ description: 'Recommended item ID' }),\n itemType: field.string({\n description: 'Item type (course, lesson, deck, etc.)',\n }),\n\n // Scoring\n score: field.decimal({ description: 'Recommendation score (0-1)' }),\n confidence: field.decimal({ description: 'Confidence in recommendation' }),\n\n // Reasoning\n reason: field.string({ description: 'Human-readable reason' }),\n factors: field.json({\n isOptional: true,\n description: 'Factors that contributed to recommendation',\n }),\n\n // Status\n status: field.string({\n default: '\"pending\"',\n description: 'Status: pending, viewed, accepted, dismissed',\n }),\n viewedAt: field.dateTime({ isOptional: true, description: 'When viewed' }),\n acceptedAt: field.dateTime({\n isOptional: true,\n description: 'When accepted',\n }),\n dismissedAt: field.dateTime({\n isOptional: true,\n description: 'When dismissed',\n }),\n\n // Feedback\n feedback: field.string({ isOptional: true, description: 'User feedback' }),\n feedbackRating: field.int({\n isOptional: true,\n description: 'Feedback rating (1-5)',\n }),\n\n // Expiry\n expiresAt: field.dateTime({\n isOptional: true,\n description: 'When recommendation expires',\n }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n learner: field.belongsTo('Learner', ['learnerId'], ['id'], {\n onDelete: 'Cascade',\n }),\n },\n indexes: [\n index.on(['learnerId', 'status', 'score']),\n index.on(['type', 'status']),\n index.on(['expiresAt']),\n ],\n enums: [RecommendationTypeEnum],\n});\n\n/**\n * LearningGap entity - identified knowledge gaps.\n */\nexport const LearningGapEntity = defineEntity({\n name: 'LearningGap',\n description: 'Identified learning gap.',\n schema: 'lssm_learning',\n map: 'learning_gap',\n fields: {\n id: field.id({ description: 'Unique gap identifier' }),\n learnerId: field.foreignKey({ description: 'Learner' }),\n\n // Gap info\n skillId: field.string({ description: 'Skill with gap' }),\n skillName: field.string({ description: 'Skill name' }),\n\n // Severity\n severity: field.string({\n default: '\"moderate\"',\n description: 'Gap severity: minor, moderate, major',\n }),\n confidence: field.decimal({ description: 'Confidence in gap detection' }),\n\n // Evidence\n evidence: field.json({ isOptional: true, description: 'Evidence for gap' }),\n relatedQuestions: field.json({\n isOptional: true,\n description: 'Questions that revealed gap',\n }),\n\n // Remediation\n suggestedRemediation: field.json({\n isOptional: true,\n description: 'Suggested remediation',\n }),\n remediationProgress: field.int({\n default: 0,\n description: 'Remediation progress',\n }),\n\n // Status\n status: field.string({\n default: '\"open\"',\n description: 'Status: open, in_progress, resolved',\n }),\n resolvedAt: field.dateTime({\n isOptional: true,\n description: 'When resolved',\n }),\n\n // Timestamps\n detectedAt: field.dateTime({ description: 'When gap was detected' }),\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n learner: field.belongsTo('Learner', ['learnerId'], ['id'], {\n onDelete: 'Cascade',\n }),\n },\n indexes: [\n index.on(['learnerId', 'status']),\n index.on(['skillId', 'status']),\n index.on(['severity', 'status']),\n ],\n});\n\nexport const aiEntities = [\n LearnerProfileEntity,\n SkillMapEntity,\n LearningPathEntity,\n RecommendationEntity,\n LearningGapEntity,\n];\n\nexport const aiEnums = [LearningStyleEnum, RecommendationTypeEnum];\n"],"mappings":"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"}
|