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