@lssm/module.learning-journey 0.0.0-canary-20251217063201 → 0.0.0-canary-20251217072406

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