@contractspec/module.learning-journey 3.7.6 → 3.7.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +65 -188
  2. package/dist/browser/contracts/index.js +148 -148
  3. package/dist/browser/contracts/models.js +1 -1
  4. package/dist/browser/contracts/onboarding.js +5 -5
  5. package/dist/browser/contracts/operations.js +4 -4
  6. package/dist/browser/engines/index.js +173 -173
  7. package/dist/browser/engines/xp.js +18 -18
  8. package/dist/browser/events.js +1 -1
  9. package/dist/browser/i18n/catalogs/index.js +18 -18
  10. package/dist/browser/i18n/index.js +26 -26
  11. package/dist/browser/i18n/locale.js +2 -2
  12. package/dist/browser/i18n/messages.js +18 -18
  13. package/dist/browser/index.js +336 -335
  14. package/dist/contracts/index.d.ts +2 -2
  15. package/dist/contracts/index.js +148 -148
  16. package/dist/contracts/models.js +1 -1
  17. package/dist/contracts/onboarding.js +5 -5
  18. package/dist/contracts/operations.js +4 -4
  19. package/dist/engines/index.d.ts +1 -1
  20. package/dist/engines/index.js +173 -173
  21. package/dist/engines/xp.js +18 -18
  22. package/dist/events.js +1 -1
  23. package/dist/i18n/catalogs/index.d.ts +1 -1
  24. package/dist/i18n/catalogs/index.js +18 -18
  25. package/dist/i18n/index.d.ts +7 -7
  26. package/dist/i18n/index.js +26 -26
  27. package/dist/i18n/locale.d.ts +1 -1
  28. package/dist/i18n/locale.js +2 -2
  29. package/dist/i18n/messages.js +18 -18
  30. package/dist/index.d.ts +3 -3
  31. package/dist/index.js +336 -335
  32. package/dist/node/contracts/index.js +148 -148
  33. package/dist/node/contracts/models.js +1 -1
  34. package/dist/node/contracts/onboarding.js +5 -5
  35. package/dist/node/contracts/operations.js +4 -4
  36. package/dist/node/engines/index.js +173 -173
  37. package/dist/node/engines/xp.js +18 -18
  38. package/dist/node/events.js +1 -1
  39. package/dist/node/i18n/catalogs/index.js +18 -18
  40. package/dist/node/i18n/index.js +26 -26
  41. package/dist/node/i18n/locale.js +2 -2
  42. package/dist/node/i18n/messages.js +18 -18
  43. package/dist/node/index.js +336 -335
  44. package/package.json +7 -7
package/README.md CHANGED
@@ -1,200 +1,77 @@
1
1
  # @contractspec/module.learning-journey
2
2
 
3
- Website: https://contractspec.io/
3
+ Website: https://contractspec.io
4
4
 
5
+ **Comprehensive learning journey engine - onboarding, LMS, flashcards, gamification, and AI personalization.**
5
6
 
6
- Comprehensive learning journey engine for ContractSpec applications.
7
+ ## What It Provides
7
8
 
8
- ## Overview
9
+ - **Layer**: module.
10
+ - **Consumers**: bundles (library, contractspec-studio), apps (web-landing).
11
+ - `src/contracts/` contains contract specs, operations, entities, and registry exports.
12
+ - `src/docs/` contains docblocks and documentation-facing exports.
13
+ - `src/contracts/` contains contract specs, operations, entities, and registry exports.
14
+ - `src/docs/` contains docblocks and documentation-facing exports.
9
15
 
10
- This module provides a complete learning platform engine that supports multiple use cases:
16
+ ## Installation
11
17
 
12
- - **Product Onboarding**: Event-driven completion tied to product actions
13
- - **Learning Management System (LMS)**: Courses, modules, lessons, certifications
14
- - **Flashcards & Spaced Repetition (SRS)**: SM-2 algorithm for optimal retention
15
- - **Quizzes & Assessments**: Multiple question types, skill tracking
16
- - **Gamification**: XP, streaks, achievements, leaderboards (Duolingo-style)
17
- - **AI-Powered Personalization**: Adaptive paths, recommendations, gap detection
18
+ `npm install @contractspec/module.learning-journey`
18
19
 
19
- ## Features
20
+ or
20
21
 
21
- ### Core Learning Structure
22
-
23
- - **Courses**: Structured learning content with prerequisites and difficulty levels
24
- - **Modules**: Groups of related lessons within a course
25
- - **Lessons**: Individual learning units (content, video, interactive, quiz)
26
- - **Progress Tracking**: Track completion, time spent, scores
27
-
28
- ### Product Onboarding
29
-
30
- - **Onboarding Tracks**: Product-specific onboarding journeys
31
- - **Event-Driven Completion**: Steps auto-complete when product events fire
32
- - **Example**: "Create your first project" completes on `ProjectCreated` event
33
-
34
- ### Flashcards & Spaced Repetition
35
-
36
- - **Decks & Cards**: Organize flashcards by topic
37
- - **SM-2 Algorithm**: Optimized review scheduling
38
- - **Review Sessions**: Get cards due for review
39
- - **Retention Metrics**: Track long-term retention
40
-
41
- ### Quizzes & Assessments
42
-
43
- - **Question Types**: Multiple choice, true/false, fill-in-blank, matching
44
- - **Timed Quizzes**: Optional time limits
45
- - **Skill Assessment**: Map quiz performance to skills
46
-
47
- ### Gamification
48
-
49
- - **Experience Points (XP)**: Earn XP for completing activities
50
- - **Streaks**: Maintain daily learning streaks
51
- - **Achievements**: Unlock achievements for milestones
52
- - **Leaderboards**: Compete with others (daily/weekly/monthly)
53
- - **Lives System**: Optional hearts/lives for quiz attempts
54
-
55
- ### AI Personalization
56
-
57
- - **Learner Profiles**: Track learning style, preferences, goals
58
- - **Skill Maps**: Map proficiency across skills
59
- - **Adaptive Paths**: Generate personalized learning sequences
60
- - **Recommendations**: AI-powered content suggestions
61
- - **Gap Detection**: Identify and address learning gaps
62
-
63
- ## Entities
64
-
65
- ### Course Structure
66
- - `Course`, `Module`, `Lesson`, `LessonContent`
67
-
68
- ### Learner & Progress
69
- - `Learner`, `Enrollment`, `LessonProgress`, `ModuleCompletion`, `Certificate`
70
-
71
- ### Onboarding
72
- - `OnboardingTrack`, `OnboardingStep`, `OnboardingProgress`
73
-
74
- ### Flashcards
75
- - `Deck`, `Card`, `CardReview`, `CardSchedule`
76
-
77
- ### Quizzes
78
- - `Quiz`, `Question`, `QuestionOption`, `QuizAttempt`, `SkillAssessment`
79
-
80
- ### Gamification
81
- - `Achievement`, `LearnerAchievement`, `Streak`, `DailyGoal`, `LeaderboardEntry`, `Heart`
82
-
83
- ### AI
84
- - `LearnerProfile`, `SkillMap`, `LearningPath`, `Recommendation`
85
-
86
- ## Engines
87
-
88
- ### Spaced Repetition Engine (SRS)
89
-
90
- ```typescript
91
- import { SRSEngine } from '@contractspec/module.learning-journey/engines/srs';
92
-
93
- const engine = new SRSEngine();
94
- const nextReview = engine.calculateNextReview({
95
- rating: 'good', // again, hard, good, easy
96
- currentInterval: 1,
97
- easeFactor: 2.5,
98
- repetitions: 3,
99
- });
100
- ```
101
-
102
- ### XP Engine
103
-
104
- ```typescript
105
- import { XPEngine } from '@contractspec/module.learning-journey/engines/xp';
106
-
107
- const engine = new XPEngine();
108
- const xp = engine.calculate({
109
- activity: 'lesson_complete',
110
- score: 95,
111
- streakBonus: true,
112
- });
113
- ```
114
-
115
- ### Streak Engine
116
-
117
- ```typescript
118
- import { StreakEngine } from '@contractspec/module.learning-journey/engines/streak';
119
-
120
- const engine = new StreakEngine();
121
- const streak = engine.update({
122
- lastActivityAt: new Date('2024-01-14'),
123
- currentStreak: 5,
124
- });
125
- ```
22
+ `bun add @contractspec/module.learning-journey`
126
23
 
127
24
  ## Usage
128
25
 
129
- ```typescript
130
- import {
131
- CourseEntity,
132
- LearnerEntity,
133
- SRSEngine,
134
- } from '@contractspec/module.learning-journey';
135
-
136
- // Enroll learner in course
137
- await enrollmentService.enroll({
138
- learnerId: 'learner-123',
139
- courseId: 'course-456',
140
- });
141
-
142
- // Complete a lesson
143
- await progressService.completeLesson({
144
- learnerId: 'learner-123',
145
- lessonId: 'lesson-789',
146
- score: 95,
147
- });
148
-
149
- // Get flashcards due for review
150
- const cards = await flashcardService.getDueCards({
151
- learnerId: 'learner-123',
152
- limit: 20,
153
- });
154
-
155
- // Submit flashcard review
156
- await flashcardService.submitReview({
157
- learnerId: 'learner-123',
158
- cardId: 'card-abc',
159
- rating: 'good',
160
- });
161
- ```
162
-
163
- ## Integration
164
-
165
- This module integrates with:
166
-
167
- - `@contractspec/lib.identity-rbac` - Learner identity
168
- - `@contractspec/lib.files` - Media attachments
169
- - `@contractspec/lib.jobs` - Scheduled reminders, streak checks
170
- - `@contractspec/lib.ai-agent` - AI-powered features
171
- - `@contractspec/module.notifications` - Learning reminders
172
-
173
- ## Schema Contribution
174
-
175
- ```typescript
176
- import { learningJourneySchemaContribution } from '@contractspec/module.learning-journey';
177
-
178
- export const schemaComposition = {
179
- modules: [
180
- learningJourneySchemaContribution,
181
- // ... other modules
182
- ],
183
- };
184
- ```
185
-
186
-
187
-
188
-
189
-
190
-
191
-
192
-
193
-
194
-
195
-
196
-
197
-
198
-
199
-
200
-
26
+ Import the root entrypoint from `@contractspec/module.learning-journey`, or choose a documented subpath when you only need one part of the package surface.
27
+
28
+ ## Architecture
29
+
30
+ - `src/contracts/` contains contract specs, operations, entities, and registry exports.
31
+ - `src/docs/` contains docblocks and documentation-facing exports.
32
+ - `src/engines` is part of the package's public or composition surface.
33
+ - `src/entities/` contains domain entities and value objects.
34
+ - `src/events.ts` is package-level event definitions.
35
+ - `src/i18n` is part of the package's public or composition surface.
36
+ - `src/index.ts` is the root public barrel and package entrypoint.
37
+
38
+ ## Public Entry Points
39
+
40
+ - Export `.` resolves through `./src/index.ts`.
41
+ - Export `./contracts` resolves through `./src/contracts/index.ts`.
42
+ - Export `./contracts/models` resolves through `./src/contracts/models.ts`.
43
+ - Export `./contracts/onboarding` resolves through `./src/contracts/onboarding.ts`.
44
+ - Export `./contracts/operations` resolves through `./src/contracts/operations.ts`.
45
+ - Export `./contracts/shared` resolves through `./src/contracts/shared.ts`.
46
+ - Export `./docs` resolves through `./src/docs/index.ts`.
47
+ - Export `./docs/learning-journey.docblock` resolves through `./src/docs/learning-journey.docblock.ts`.
48
+ - Export `./engines` resolves through `./src/engines/index.ts`.
49
+ - Export `./engines/srs` resolves through `./src/engines/srs.ts`.
50
+ - The package publishes 32 total export subpaths; keep docs aligned with `package.json`.
51
+
52
+ ## Local Commands
53
+
54
+ - `bun run dev` — contractspec-bun-build dev
55
+ - `bun run build` — bun run prebuild && bun run build:bundle && bun run build:types
56
+ - `bun run test` — bun test
57
+ - `bun run lint` — bun lint:fix
58
+ - `bun run lint:check` — biome check .
59
+ - `bun run lint:fix` — biome check --write --unsafe --only=nursery/useSortedClasses . && biome check --write .
60
+ - `bun run typecheck` — tsc --noEmit
61
+ - `bun run publish:pkg` — bun publish --tolerate-republish --ignore-scripts --verbose
62
+ - `bun run publish:pkg:canary` — bun publish:pkg --tag canary
63
+ - `bun run clean` — rimraf dist .turbo
64
+ - `bun run build:bundle` — contractspec-bun-build transpile
65
+ - `bun run build:types` — contractspec-bun-build types
66
+ - `bun run prebuild` contractspec-bun-build prebuild
67
+
68
+ ## Recent Updates
69
+
70
+ - Replace eslint+prettier by biomejs to optimize speed.
71
+ - Add full i18n support across all 10 packages (en/fr/es, 460 keys).
72
+
73
+ ## Notes
74
+
75
+ - SRS/streak/XP engines are pure functions -- keep them side-effect-free.
76
+ - i18n catalogs must stay in sync across all supported locales (en, es, fr).
77
+ - Entity schemas are shared with the UI; breaking changes propagate to all learning surfaces.
@@ -1,8 +1,5 @@
1
- // src/contracts/shared.ts
2
- var LEARNING_JOURNEY_OWNERS = ["modules.learning-journey"];
3
-
4
1
  // src/contracts/models.ts
5
- import { ScalarTypeEnum, defineSchemaModel } from "@contractspec/lib.schema";
2
+ import { defineSchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
6
3
  var CourseModel = defineSchemaModel({
7
4
  name: "Course",
8
5
  description: "A learning course",
@@ -178,149 +175,12 @@ var SuccessOutput = defineSchemaModel({
178
175
  }
179
176
  });
180
177
 
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
- });
178
+ // src/contracts/shared.ts
179
+ var LEARNING_JOURNEY_OWNERS = ["modules.learning-journey"];
320
180
 
321
181
  // src/contracts/onboarding.ts
322
- import { ScalarTypeEnum as ScalarTypeEnum2, defineSchemaModel as defineSchemaModel2 } from "@contractspec/lib.schema";
323
- import { defineCommand as defineCommand2, defineQuery as defineQuery2 } from "@contractspec/lib.contracts-spec";
182
+ import { defineCommand, defineQuery } from "@contractspec/lib.contracts-spec";
183
+ import { defineSchemaModel as defineSchemaModel2, ScalarTypeEnum as ScalarTypeEnum2 } from "@contractspec/lib.schema";
324
184
  var OnboardingStepConditionModel = defineSchemaModel2({
325
185
  name: "OnboardingStepCondition",
326
186
  description: "Structured completion condition for onboarding steps.",
@@ -475,7 +335,7 @@ var RecordOnboardingEventInput = defineSchemaModel2({
475
335
  occurredAt: { type: ScalarTypeEnum2.DateTime(), isOptional: true }
476
336
  }
477
337
  });
478
- var ListOnboardingTracksContract = defineQuery2({
338
+ var ListOnboardingTracksContract = defineQuery({
479
339
  meta: {
480
340
  key: "learning.onboarding.listTracks",
481
341
  version: "1.0.0",
@@ -494,7 +354,7 @@ var ListOnboardingTracksContract = defineQuery2({
494
354
  auth: "user"
495
355
  }
496
356
  });
497
- var GetOnboardingProgressContract = defineQuery2({
357
+ var GetOnboardingProgressContract = defineQuery({
498
358
  meta: {
499
359
  key: "learning.onboarding.getProgress",
500
360
  version: "1.0.0",
@@ -513,7 +373,7 @@ var GetOnboardingProgressContract = defineQuery2({
513
373
  auth: "user"
514
374
  }
515
375
  });
516
- var RecordOnboardingEventContract = defineCommand2({
376
+ var RecordOnboardingEventContract = defineCommand({
517
377
  meta: {
518
378
  key: "learning.onboarding.recordEvent",
519
379
  version: "1.0.0",
@@ -546,6 +406,146 @@ var RecordOnboardingEventContract = defineCommand2({
546
406
  auth: "user"
547
407
  }
548
408
  });
409
+
410
+ // src/contracts/operations.ts
411
+ import { defineCommand as defineCommand2, defineQuery as defineQuery2 } from "@contractspec/lib.contracts-spec";
412
+ var EnrollInCourseContract = defineCommand2({
413
+ meta: {
414
+ key: "learning.enroll",
415
+ version: "1.0.0",
416
+ stability: "stable",
417
+ owners: [...LEARNING_JOURNEY_OWNERS],
418
+ tags: ["learning", "enrollment"],
419
+ description: "Enroll in a course.",
420
+ goal: "Start learning a new course.",
421
+ context: "Called when a learner wants to start a course."
422
+ },
423
+ io: {
424
+ input: EnrollInCourseInput,
425
+ output: EnrollmentModel,
426
+ errors: {
427
+ COURSE_NOT_FOUND: {
428
+ description: "Course does not exist",
429
+ http: 404,
430
+ gqlCode: "COURSE_NOT_FOUND",
431
+ when: "Course ID is invalid"
432
+ },
433
+ ALREADY_ENROLLED: {
434
+ description: "Already enrolled in course",
435
+ http: 409,
436
+ gqlCode: "ALREADY_ENROLLED",
437
+ when: "Learner is already enrolled"
438
+ }
439
+ }
440
+ },
441
+ policy: {
442
+ auth: "user"
443
+ }
444
+ });
445
+ var CompleteLessonContract = defineCommand2({
446
+ meta: {
447
+ key: "learning.completeLesson",
448
+ version: "1.0.0",
449
+ stability: "stable",
450
+ owners: [...LEARNING_JOURNEY_OWNERS],
451
+ tags: ["learning", "progress"],
452
+ description: "Mark a lesson as completed.",
453
+ goal: "Record lesson completion and earn XP.",
454
+ context: "Called when a learner finishes a lesson."
455
+ },
456
+ io: {
457
+ input: CompleteLessonInput,
458
+ output: SuccessOutput,
459
+ errors: {
460
+ LESSON_NOT_FOUND: {
461
+ description: "Lesson does not exist",
462
+ http: 404,
463
+ gqlCode: "LESSON_NOT_FOUND",
464
+ when: "Lesson ID is invalid"
465
+ },
466
+ NOT_ENROLLED: {
467
+ description: "Not enrolled in course",
468
+ http: 403,
469
+ gqlCode: "NOT_ENROLLED",
470
+ when: "Learner is not enrolled in the course"
471
+ }
472
+ }
473
+ },
474
+ policy: {
475
+ auth: "user"
476
+ }
477
+ });
478
+ var SubmitCardReviewContract = defineCommand2({
479
+ meta: {
480
+ key: "learning.submitCardReview",
481
+ version: "1.0.0",
482
+ stability: "stable",
483
+ owners: [...LEARNING_JOURNEY_OWNERS],
484
+ tags: ["learning", "flashcards"],
485
+ description: "Submit a flashcard review.",
486
+ goal: "Record review and update SRS schedule.",
487
+ context: "Called when reviewing flashcards."
488
+ },
489
+ io: {
490
+ input: SubmitCardReviewInput,
491
+ output: SuccessOutput,
492
+ errors: {
493
+ CARD_NOT_FOUND: {
494
+ description: "Card does not exist",
495
+ http: 404,
496
+ gqlCode: "CARD_NOT_FOUND",
497
+ when: "Card ID is invalid"
498
+ },
499
+ INVALID_RATING: {
500
+ description: "Invalid rating",
501
+ http: 400,
502
+ gqlCode: "INVALID_RATING",
503
+ when: "Rating must be AGAIN, HARD, GOOD, or EASY"
504
+ }
505
+ }
506
+ },
507
+ policy: {
508
+ auth: "user"
509
+ }
510
+ });
511
+ var GetDueCardsContract = defineQuery2({
512
+ meta: {
513
+ key: "learning.getDueCards",
514
+ version: "1.0.0",
515
+ stability: "stable",
516
+ owners: [...LEARNING_JOURNEY_OWNERS],
517
+ tags: ["learning", "flashcards"],
518
+ description: "Get flashcards due for review.",
519
+ goal: "Get the next batch of cards to review.",
520
+ context: "Called when starting a review session."
521
+ },
522
+ io: {
523
+ input: GetDueCardsInput,
524
+ output: GetDueCardsOutput
525
+ },
526
+ policy: {
527
+ auth: "user"
528
+ }
529
+ });
530
+ var GetLearnerDashboardContract = defineQuery2({
531
+ meta: {
532
+ key: "learning.getDashboard",
533
+ version: "1.0.0",
534
+ stability: "stable",
535
+ owners: [...LEARNING_JOURNEY_OWNERS],
536
+ tags: ["learning", "dashboard"],
537
+ description: "Get learner dashboard data.",
538
+ goal: "Display learner progress and stats.",
539
+ context: "Called when viewing the learning dashboard."
540
+ },
541
+ io: {
542
+ input: GetLearnerDashboardInput,
543
+ output: LearnerDashboardModel
544
+ },
545
+ policy: {
546
+ auth: "user"
547
+ }
548
+ });
549
549
  export {
550
550
  SuccessOutput,
551
551
  SubmitCardReviewInput,
@@ -1,5 +1,5 @@
1
1
  // src/contracts/models.ts
2
- import { ScalarTypeEnum, defineSchemaModel } from "@contractspec/lib.schema";
2
+ import { defineSchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
3
3
  var CourseModel = defineSchemaModel({
4
4
  name: "Course",
5
5
  description: "A learning course",
@@ -1,8 +1,5 @@
1
- // src/contracts/shared.ts
2
- var LEARNING_JOURNEY_OWNERS = ["modules.learning-journey"];
3
-
4
1
  // src/contracts/models.ts
5
- import { ScalarTypeEnum, defineSchemaModel } from "@contractspec/lib.schema";
2
+ import { defineSchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
6
3
  var CourseModel = defineSchemaModel({
7
4
  name: "Course",
8
5
  description: "A learning course",
@@ -178,9 +175,12 @@ var SuccessOutput = defineSchemaModel({
178
175
  }
179
176
  });
180
177
 
178
+ // src/contracts/shared.ts
179
+ var LEARNING_JOURNEY_OWNERS = ["modules.learning-journey"];
180
+
181
181
  // src/contracts/onboarding.ts
182
- import { ScalarTypeEnum as ScalarTypeEnum2, defineSchemaModel as defineSchemaModel2 } from "@contractspec/lib.schema";
183
182
  import { defineCommand, defineQuery } from "@contractspec/lib.contracts-spec";
183
+ import { defineSchemaModel as defineSchemaModel2, ScalarTypeEnum as ScalarTypeEnum2 } from "@contractspec/lib.schema";
184
184
  var OnboardingStepConditionModel = defineSchemaModel2({
185
185
  name: "OnboardingStepCondition",
186
186
  description: "Structured completion condition for onboarding steps.",
@@ -1,8 +1,5 @@
1
- // src/contracts/shared.ts
2
- var LEARNING_JOURNEY_OWNERS = ["modules.learning-journey"];
3
-
4
1
  // src/contracts/models.ts
5
- import { ScalarTypeEnum, defineSchemaModel } from "@contractspec/lib.schema";
2
+ import { defineSchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
6
3
  var CourseModel = defineSchemaModel({
7
4
  name: "Course",
8
5
  description: "A learning course",
@@ -178,6 +175,9 @@ var SuccessOutput = defineSchemaModel({
178
175
  }
179
176
  });
180
177
 
178
+ // src/contracts/shared.ts
179
+ var LEARNING_JOURNEY_OWNERS = ["modules.learning-journey"];
180
+
181
181
  // src/contracts/operations.ts
182
182
  import { defineCommand, defineQuery } from "@contractspec/lib.contracts-spec";
183
183
  var EnrollInCourseContract = defineCommand({