@contractspec/example.learning-journey-quest-challenges 3.7.6 → 3.7.7

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.
@@ -3,7 +3,7 @@ $ bun run prebuild && bun run build:bundle && bun run build:types
3
3
  $ contractspec-bun-build prebuild
4
4
  $ contractspec-bun-build transpile
5
5
  [contractspec-bun-build] transpile target=bun root=src entries=6 noBundle=false
6
- Bundled 6 modules in 29ms
6
+ Bundled 6 modules in 36ms
7
7
 
8
8
  docs/index.js 1.53 KB (entry point)
9
9
  ./index.js 4.57 KB (entry point)
@@ -13,7 +13,7 @@ Bundled 6 modules in 29ms
13
13
  ./track.js 1.43 KB (entry point)
14
14
 
15
15
  [contractspec-bun-build] transpile target=node root=src entries=6 noBundle=false
16
- Bundled 6 modules in 13ms
16
+ Bundled 6 modules in 44ms
17
17
 
18
18
  docs/index.js 1.50 KB (entry point)
19
19
  ./index.js 4.53 KB (entry point)
@@ -23,7 +23,7 @@ Bundled 6 modules in 13ms
23
23
  ./track.js 1.42 KB (entry point)
24
24
 
25
25
  [contractspec-bun-build] transpile target=browser root=src entries=6 noBundle=false
26
- Bundled 6 modules in 26ms
26
+ Bundled 6 modules in 27ms
27
27
 
28
28
  docs/index.js 1.50 KB (entry point)
29
29
  ./index.js 4.53 KB (entry point)
package/AGENTS.md CHANGED
@@ -1,31 +1,53 @@
1
- # AI Agent Guide -- `@contractspec/example.learning-journey-quest-challenges`
1
+ # AI Agent Guide `@contractspec/example.learning-journey-quest-challenges`
2
2
 
3
3
  Scope: `packages/examples/learning-journey-quest-challenges/*`
4
4
 
5
- Demonstrates time-bound quest and challenge-based learning with deadlines and completion tracking.
5
+ Time-bound quest/challenge learning journey example.
6
6
 
7
7
  ## Quick Context
8
8
 
9
- - **Layer**: example
10
- - **Related Packages**: `module.learning-journey`, `lib.contracts-spec`
9
+ - Layer: `example`.
10
+ - Package visibility: published package.
11
+ - Primary consumers are example explorers, template authors, and documentation readers.
12
+ - Related packages: `@contractspec/lib.contracts-spec`, `@contractspec/module.learning-journey`, `@contractspec/tool.bun`, `@contractspec/tool.typescript`.
11
13
 
12
- ## What This Demonstrates
14
+ ## Architecture
13
15
 
14
- - Quest/challenge track with time-bound objectives
15
- - Completion tracking and deadline enforcement
16
- - Lightweight track + example pattern
17
- - Integration with the learning-journey module
16
+ - `src/docs/` contains docblocks and documentation-facing exports.
17
+ - `src/example.ts` is the runnable example entrypoint.
18
+ - `src/index.ts` is the root public barrel and package entrypoint.
19
+ - `src/learning-journey-quest-challenges.feature.ts` defines a feature entrypoint.
20
+ - `src/track.test.ts` is part of the package's public or composition surface.
21
+ - `src/track.ts` is part of the package's public or composition surface.
18
22
 
19
- ## Public Exports
23
+ ## Public Surface
20
24
 
21
- - `.` -- root barrel
22
- - `./docs` -- DocBlock documentation
23
- - `./example` -- runnable example entry point
24
- - `./track` -- quest challenges track definition
25
+ - Export `.` resolves through `./src/index.ts`.
26
+ - Export `./docs` resolves through `./src/docs/index.ts`.
27
+ - Export `./docs/quest-challenges.docblock` resolves through `./src/docs/quest-challenges.docblock.ts`.
28
+ - Export `./example` resolves through `./src/example.ts`.
29
+ - Export `./learning-journey-quest-challenges.feature` resolves through `./src/learning-journey-quest-challenges.feature.ts`.
30
+ - Export `./track` resolves through `./src/track.ts`.
31
+
32
+ ## Guardrails
33
+
34
+ - Keep the example package demonstrative, buildable, and aligned with the exported feature surface.
35
+ - Do not add hidden production assumptions that are not actually implemented in the example.
36
+ - Changes here can affect downstream packages such as `@contractspec/lib.contracts-spec`, `@contractspec/module.learning-journey`, `@contractspec/tool.bun`, `@contractspec/tool.typescript`.
37
+ - Changes here can affect downstream packages such as `@contractspec/lib.contracts-spec`, `@contractspec/module.learning-journey`, `@contractspec/tool.bun`, `@contractspec/tool.typescript`.
25
38
 
26
39
  ## Local Commands
27
40
 
28
- - Build: `bun run build`
29
- - Dev: `bun run dev`
30
- - Test: `bun test`
31
- - Typecheck: `bun run typecheck`
41
+ - `bun run dev` — contractspec-bun-build dev
42
+ - `bun run build`bun run prebuild && bun run build:bundle && bun run build:types
43
+ - `bun run test`bun test
44
+ - `bun run lint` — bun lint:fix
45
+ - `bun run lint:check` — biome check .
46
+ - `bun run lint:fix` — biome check --write --unsafe --only=nursery/useSortedClasses . && biome check --write .
47
+ - `bun run typecheck` — tsc --noEmit
48
+ - `bun run publish:pkg` — bun publish --tolerate-republish --ignore-scripts --verbose
49
+ - `bun run publish:pkg:canary` — bun publish:pkg --tag canary
50
+ - `bun run clean` — rimraf dist .turbo
51
+ - `bun run build:bundle` — contractspec-bun-build transpile
52
+ - `bun run build:types` — contractspec-bun-build types
53
+ - `bun run prebuild` — contractspec-bun-build prebuild
package/README.md CHANGED
@@ -1,30 +1,69 @@
1
1
  # @contractspec/example.learning-journey-quest-challenges
2
2
 
3
- Website: https://contractspec.io/
3
+ Website: https://contractspec.io
4
4
 
5
+ **Time-bound quest/challenge learning journey example.**
5
6
 
6
- Time-bound challenge/quest example (7-day money reset) showing day-based unlocks and event-driven completion.
7
+ ## What This Demonstrates
7
8
 
8
- ## What it shows
9
+ - Quest/challenge track with time-bound objectives.
10
+ - Completion tracking and deadline enforcement.
11
+ - Lightweight track + example pattern.
12
+ - Integration with the learning-journey module.
13
+ - `src/docs/` contains docblocks and documentation-facing exports.
14
+ - `src/docs/` contains docblocks and documentation-facing exports.
9
15
 
10
- - Track steps that unlock by day since quest start
11
- - Event-based completions for each day
12
- - XP per day with completion bonus when finished within duration
13
- - Optional recap via SRS mastery events
16
+ ## Running Locally
14
17
 
15
- ## How to run
18
+ From `packages/examples/learning-journey-quest-challenges`:
19
+ - `bun run dev`
20
+ - `bun run build`
21
+ - `bun run test`
22
+ - `bun run typecheck`
16
23
 
17
- 1. `bun test packages/examples/learning-journey-quest-challenges`
18
- 2. Emit events in order with `recordEvent` from the registry:
24
+ ## Usage
19
25
 
20
- ```ts
21
- recordEvent({ name: 'accounts.mapped', learnerId: 'u1' });
22
- recordEvent({ name: 'transactions.categorized', learnerId: 'u1' });
23
- // ...
24
- ```
26
+ Use `@contractspec/example.learning-journey-quest-challenges` as a reference implementation, or import its exported surfaces into a workspace that composes ContractSpec examples and bundles.
25
27
 
26
- ## Adapting
28
+ ## Architecture
27
29
 
28
- - Swap events for your vertical (coliving integration week, artisan onboarding).
29
- - Adjust unlock windows via `availability.unlockOnDay`.
30
- - Tweak XP/bonus and add recap SRS mastery after completion.
30
+ - `src/docs/` contains docblocks and documentation-facing exports.
31
+ - `src/example.ts` is the runnable example entrypoint.
32
+ - `src/index.ts` is the root public barrel and package entrypoint.
33
+ - `src/learning-journey-quest-challenges.feature.ts` defines a feature entrypoint.
34
+ - `src/track.test.ts` is part of the package's public or composition surface.
35
+ - `src/track.ts` is part of the package's public or composition surface.
36
+
37
+ ## Public Entry Points
38
+
39
+ - Export `.` resolves through `./src/index.ts`.
40
+ - Export `./docs` resolves through `./src/docs/index.ts`.
41
+ - Export `./docs/quest-challenges.docblock` resolves through `./src/docs/quest-challenges.docblock.ts`.
42
+ - Export `./example` resolves through `./src/example.ts`.
43
+ - Export `./learning-journey-quest-challenges.feature` resolves through `./src/learning-journey-quest-challenges.feature.ts`.
44
+ - Export `./track` resolves through `./src/track.ts`.
45
+
46
+ ## Local Commands
47
+
48
+ - `bun run dev` — contractspec-bun-build dev
49
+ - `bun run build` — bun run prebuild && bun run build:bundle && bun run build:types
50
+ - `bun run test` — bun test
51
+ - `bun run lint` — bun lint:fix
52
+ - `bun run lint:check` — biome check .
53
+ - `bun run lint:fix` — biome check --write --unsafe --only=nursery/useSortedClasses . && biome check --write .
54
+ - `bun run typecheck` — tsc --noEmit
55
+ - `bun run publish:pkg` — bun publish --tolerate-republish --ignore-scripts --verbose
56
+ - `bun run publish:pkg:canary` — bun publish:pkg --tag canary
57
+ - `bun run clean` — rimraf dist .turbo
58
+ - `bun run build:bundle` — contractspec-bun-build transpile
59
+ - `bun run build:types` — contractspec-bun-build types
60
+ - `bun run prebuild` — contractspec-bun-build prebuild
61
+
62
+ ## Recent Updates
63
+
64
+ - Replace eslint+prettier by biomejs to optimize speed.
65
+ - Missing contract layers.
66
+
67
+ ## Notes
68
+
69
+ - Works alongside `@contractspec/lib.contracts-spec`, `@contractspec/module.learning-journey`, `@contractspec/tool.bun`, `@contractspec/tool.typescript`.
@@ -61,6 +61,22 @@ var example = defineExample({
61
61
  });
62
62
  var example_default = example;
63
63
 
64
+ // src/learning-journey-quest-challenges.feature.ts
65
+ import { defineFeature } from "@contractspec/lib.contracts-spec";
66
+ var LearningJourneyQuestChallengesFeature = defineFeature({
67
+ meta: {
68
+ key: "learning-journey-quest-challenges",
69
+ version: "1.0.0",
70
+ title: "Learning Journey: Quest Challenges",
71
+ description: "Quest and challenge-based learning with deadlines and completion tracking",
72
+ domain: "learning-journey",
73
+ owners: ["@examples"],
74
+ tags: ["learning", "quests", "challenges", "gamification"],
75
+ stability: "experimental"
76
+ },
77
+ docs: ["docs.learning-journey.quest-challenges"]
78
+ });
79
+
64
80
  // src/track.ts
65
81
  var dayStep = (id, day, eventName, description) => ({
66
82
  id,
@@ -93,22 +109,6 @@ var moneyResetQuestTrack = {
93
109
  ]
94
110
  };
95
111
  var questTracks = [moneyResetQuestTrack];
96
-
97
- // src/learning-journey-quest-challenges.feature.ts
98
- import { defineFeature } from "@contractspec/lib.contracts-spec";
99
- var LearningJourneyQuestChallengesFeature = defineFeature({
100
- meta: {
101
- key: "learning-journey-quest-challenges",
102
- version: "1.0.0",
103
- title: "Learning Journey: Quest Challenges",
104
- description: "Quest and challenge-based learning with deadlines and completion tracking",
105
- domain: "learning-journey",
106
- owners: ["@examples"],
107
- tags: ["learning", "quests", "challenges", "gamification"],
108
- stability: "experimental"
109
- },
110
- docs: ["docs.learning-journey.quest-challenges"]
111
- });
112
112
  export {
113
113
  questTracks,
114
114
  moneyResetQuestTrack,
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export * from './track';
2
- export * from './learning-journey-quest-challenges.feature';
3
1
  export { default as example } from './example';
2
+ export * from './learning-journey-quest-challenges.feature';
3
+ export * from './track';
4
4
  import './docs';
package/dist/index.js CHANGED
@@ -62,6 +62,22 @@ var example = defineExample({
62
62
  });
63
63
  var example_default = example;
64
64
 
65
+ // src/learning-journey-quest-challenges.feature.ts
66
+ import { defineFeature } from "@contractspec/lib.contracts-spec";
67
+ var LearningJourneyQuestChallengesFeature = defineFeature({
68
+ meta: {
69
+ key: "learning-journey-quest-challenges",
70
+ version: "1.0.0",
71
+ title: "Learning Journey: Quest Challenges",
72
+ description: "Quest and challenge-based learning with deadlines and completion tracking",
73
+ domain: "learning-journey",
74
+ owners: ["@examples"],
75
+ tags: ["learning", "quests", "challenges", "gamification"],
76
+ stability: "experimental"
77
+ },
78
+ docs: ["docs.learning-journey.quest-challenges"]
79
+ });
80
+
65
81
  // src/track.ts
66
82
  var dayStep = (id, day, eventName, description) => ({
67
83
  id,
@@ -94,22 +110,6 @@ var moneyResetQuestTrack = {
94
110
  ]
95
111
  };
96
112
  var questTracks = [moneyResetQuestTrack];
97
-
98
- // src/learning-journey-quest-challenges.feature.ts
99
- import { defineFeature } from "@contractspec/lib.contracts-spec";
100
- var LearningJourneyQuestChallengesFeature = defineFeature({
101
- meta: {
102
- key: "learning-journey-quest-challenges",
103
- version: "1.0.0",
104
- title: "Learning Journey: Quest Challenges",
105
- description: "Quest and challenge-based learning with deadlines and completion tracking",
106
- domain: "learning-journey",
107
- owners: ["@examples"],
108
- tags: ["learning", "quests", "challenges", "gamification"],
109
- stability: "experimental"
110
- },
111
- docs: ["docs.learning-journey.quest-challenges"]
112
- });
113
113
  export {
114
114
  questTracks,
115
115
  moneyResetQuestTrack,
@@ -61,6 +61,22 @@ var example = defineExample({
61
61
  });
62
62
  var example_default = example;
63
63
 
64
+ // src/learning-journey-quest-challenges.feature.ts
65
+ import { defineFeature } from "@contractspec/lib.contracts-spec";
66
+ var LearningJourneyQuestChallengesFeature = defineFeature({
67
+ meta: {
68
+ key: "learning-journey-quest-challenges",
69
+ version: "1.0.0",
70
+ title: "Learning Journey: Quest Challenges",
71
+ description: "Quest and challenge-based learning with deadlines and completion tracking",
72
+ domain: "learning-journey",
73
+ owners: ["@examples"],
74
+ tags: ["learning", "quests", "challenges", "gamification"],
75
+ stability: "experimental"
76
+ },
77
+ docs: ["docs.learning-journey.quest-challenges"]
78
+ });
79
+
64
80
  // src/track.ts
65
81
  var dayStep = (id, day, eventName, description) => ({
66
82
  id,
@@ -93,22 +109,6 @@ var moneyResetQuestTrack = {
93
109
  ]
94
110
  };
95
111
  var questTracks = [moneyResetQuestTrack];
96
-
97
- // src/learning-journey-quest-challenges.feature.ts
98
- import { defineFeature } from "@contractspec/lib.contracts-spec";
99
- var LearningJourneyQuestChallengesFeature = defineFeature({
100
- meta: {
101
- key: "learning-journey-quest-challenges",
102
- version: "1.0.0",
103
- title: "Learning Journey: Quest Challenges",
104
- description: "Quest and challenge-based learning with deadlines and completion tracking",
105
- domain: "learning-journey",
106
- owners: ["@examples"],
107
- tags: ["learning", "quests", "challenges", "gamification"],
108
- stability: "experimental"
109
- },
110
- docs: ["docs.learning-journey.quest-challenges"]
111
- });
112
112
  export {
113
113
  questTracks,
114
114
  moneyResetQuestTrack,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contractspec/example.learning-journey-quest-challenges",
3
- "version": "3.7.6",
3
+ "version": "3.7.7",
4
4
  "description": "Time-bound quest/challenge learning journey example.",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -57,15 +57,15 @@
57
57
  "dev": "contractspec-bun-build dev",
58
58
  "clean": "rimraf dist .turbo",
59
59
  "lint": "bun lint:fix",
60
- "lint:fix": "eslint src --fix",
61
- "lint:check": "eslint src",
60
+ "lint:fix": "biome check --write --unsafe --only=nursery/useSortedClasses . && biome check --write .",
61
+ "lint:check": "biome check .",
62
62
  "test": "bun test",
63
63
  "prebuild": "contractspec-bun-build prebuild",
64
64
  "typecheck": "tsc --noEmit"
65
65
  },
66
66
  "dependencies": {
67
- "@contractspec/module.learning-journey": "3.7.6",
68
- "@contractspec/lib.contracts-spec": "3.7.6"
67
+ "@contractspec/module.learning-journey": "3.7.7",
68
+ "@contractspec/lib.contracts-spec": "4.0.0"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@contractspec/tool.typescript": "3.7.6",
@@ -2,16 +2,16 @@ import type { DocBlock } from '@contractspec/lib.contracts-spec/docs';
2
2
  import { registerDocBlocks } from '@contractspec/lib.contracts-spec/docs';
3
3
 
4
4
  const questDocBlocks: DocBlock[] = [
5
- {
6
- id: 'docs.learning-journey.quest-challenges',
7
- title: 'Learning Journey — Quest Challenges',
8
- summary:
9
- 'Time-bound challenge pattern (7-day money reset) with day unlocks and event-driven completion.',
10
- kind: 'reference',
11
- visibility: 'public',
12
- route: '/docs/learning-journey/quest-challenges',
13
- tags: ['learning', 'quest', 'challenge'],
14
- body: `## Track
5
+ {
6
+ id: 'docs.learning-journey.quest-challenges',
7
+ title: 'Learning Journey — Quest Challenges',
8
+ summary:
9
+ 'Time-bound challenge pattern (7-day money reset) with day unlocks and event-driven completion.',
10
+ kind: 'reference',
11
+ visibility: 'public',
12
+ route: '/docs/learning-journey/quest-challenges',
13
+ tags: ['learning', 'quest', 'challenge'],
14
+ body: `## Track
15
15
  - **Key**: \`money_reset_7day\`
16
16
  - **Duration**: 7 days, steps unlock day by day
17
17
 
@@ -30,7 +30,7 @@ XP: 15 per day, completion bonus 30 if finished within duration. Optional recap
30
30
  - Exported via \`@contractspec/example.learning-journey-quest-challenges/track\`.
31
31
  - Step availability uses \`availability.unlockOnDay\` to gate days.
32
32
  - Registry progression handles event matching and XP application.`,
33
- },
33
+ },
34
34
  ];
35
35
 
36
36
  registerDocBlocks(questDocBlocks);
package/src/example.ts CHANGED
@@ -1,31 +1,31 @@
1
1
  import { defineExample } from '@contractspec/lib.contracts-spec';
2
2
 
3
3
  const example = defineExample({
4
- meta: {
5
- key: 'learning-journey-quest-challenges',
6
- version: '1.0.0',
7
- title: 'Learning Journey — Quest Challenges',
8
- description:
9
- 'Quest/challenge pattern: multi-step goals with progress events, rewards, and streak hooks.',
10
- kind: 'template',
11
- visibility: 'public',
12
- stability: 'experimental',
13
- owners: ['@platform.core'],
14
- tags: ['learning', 'quests', 'challenges'],
15
- },
16
- docs: {
17
- rootDocId: 'docs.learning-journey.quest-challenges',
18
- },
19
- entrypoints: {
20
- packageName: '@contractspec/example.learning-journey-quest-challenges',
21
- docs: './docs',
22
- },
23
- surfaces: {
24
- templates: true,
25
- sandbox: { enabled: true, modes: ['playground', 'markdown'] },
26
- studio: { enabled: true, installable: true },
27
- mcp: { enabled: true },
28
- },
4
+ meta: {
5
+ key: 'learning-journey-quest-challenges',
6
+ version: '1.0.0',
7
+ title: 'Learning Journey — Quest Challenges',
8
+ description:
9
+ 'Quest/challenge pattern: multi-step goals with progress events, rewards, and streak hooks.',
10
+ kind: 'template',
11
+ visibility: 'public',
12
+ stability: 'experimental',
13
+ owners: ['@platform.core'],
14
+ tags: ['learning', 'quests', 'challenges'],
15
+ },
16
+ docs: {
17
+ rootDocId: 'docs.learning-journey.quest-challenges',
18
+ },
19
+ entrypoints: {
20
+ packageName: '@contractspec/example.learning-journey-quest-challenges',
21
+ docs: './docs',
22
+ },
23
+ surfaces: {
24
+ templates: true,
25
+ sandbox: { enabled: true, modes: ['playground', 'markdown'] },
26
+ studio: { enabled: true, installable: true },
27
+ mcp: { enabled: true },
28
+ },
29
29
  });
30
30
 
31
31
  export default example;
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- export * from './track';
2
- export * from './learning-journey-quest-challenges.feature';
3
1
  export { default as example } from './example';
2
+ export * from './learning-journey-quest-challenges.feature';
3
+ export * from './track';
4
4
  import './docs';
@@ -1,17 +1,17 @@
1
1
  import { defineFeature } from '@contractspec/lib.contracts-spec';
2
2
 
3
3
  export const LearningJourneyQuestChallengesFeature = defineFeature({
4
- meta: {
5
- key: 'learning-journey-quest-challenges',
6
- version: '1.0.0',
7
- title: 'Learning Journey: Quest Challenges',
8
- description:
9
- 'Quest and challenge-based learning with deadlines and completion tracking',
10
- domain: 'learning-journey',
11
- owners: ['@examples'],
12
- tags: ['learning', 'quests', 'challenges', 'gamification'],
13
- stability: 'experimental',
14
- },
4
+ meta: {
5
+ key: 'learning-journey-quest-challenges',
6
+ version: '1.0.0',
7
+ title: 'Learning Journey: Quest Challenges',
8
+ description:
9
+ 'Quest and challenge-based learning with deadlines and completion tracking',
10
+ domain: 'learning-journey',
11
+ owners: ['@examples'],
12
+ tags: ['learning', 'quests', 'challenges', 'gamification'],
13
+ stability: 'experimental',
14
+ },
15
15
 
16
- docs: ['docs.learning-journey.quest-challenges'],
16
+ docs: ['docs.learning-journey.quest-challenges'],
17
17
  });
package/src/track.test.ts CHANGED
@@ -3,50 +3,50 @@ import { describe, expect, it } from 'bun:test';
3
3
  import { moneyResetQuestTrack } from './track';
4
4
 
5
5
  const addDays = (date: Date, days: number) =>
6
- new Date(date.getTime() + days * 24 * 60 * 60 * 1000);
6
+ new Date(date.getTime() + days * 24 * 60 * 60 * 1000);
7
7
 
8
8
  type StepStatus = 'PENDING' | 'COMPLETED';
9
9
 
10
10
  describe('quest challenges track', () => {
11
- it('unlocks by day and completes within window', () => {
12
- const start = new Date('2024-01-01T09:00:00Z');
13
- const events = [
14
- { name: 'accounts.mapped', dayOffset: 0 },
15
- { name: 'transactions.categorized', dayOffset: 1 },
16
- { name: 'goals.created', dayOffset: 2 },
17
- { name: 'recurring_rule.created', dayOffset: 3 },
18
- { name: 'subscription.flagged_or_cancelled', dayOffset: 4 },
19
- { name: 'emergency_plan.completed', dayOffset: 5 },
20
- { name: 'quest.review.completed', dayOffset: 6 },
21
- ];
11
+ it('unlocks by day and completes within window', () => {
12
+ const start = new Date('2024-01-01T09:00:00Z');
13
+ const events = [
14
+ { name: 'accounts.mapped', dayOffset: 0 },
15
+ { name: 'transactions.categorized', dayOffset: 1 },
16
+ { name: 'goals.created', dayOffset: 2 },
17
+ { name: 'recurring_rule.created', dayOffset: 3 },
18
+ { name: 'subscription.flagged_or_cancelled', dayOffset: 4 },
19
+ { name: 'emergency_plan.completed', dayOffset: 5 },
20
+ { name: 'quest.review.completed', dayOffset: 6 },
21
+ ];
22
22
 
23
- const progress = moneyResetQuestTrack.steps.map((step) => ({
24
- id: step.id,
25
- status: 'PENDING' as StepStatus,
26
- }));
23
+ const progress = moneyResetQuestTrack.steps.map((step) => ({
24
+ id: step.id,
25
+ status: 'PENDING' as StepStatus,
26
+ }));
27
27
 
28
- events.forEach((evt) => {
29
- const now = addDays(start, evt.dayOffset);
30
- moneyResetQuestTrack.steps.forEach((spec, idx) => {
31
- const step = progress[idx];
32
- if (!step || step.status === 'COMPLETED') return;
33
- const availableAt =
34
- spec.availability?.unlockOnDay !== undefined
35
- ? addDays(start, spec.availability.unlockOnDay - 1)
36
- : start;
37
- if (now < availableAt) return;
38
- const within =
39
- spec.completion.kind === 'time_window' &&
40
- spec.completion.withinHoursOfStart !== undefined
41
- ? (now.getTime() - start.getTime()) / (1000 * 60 * 60) <=
42
- spec.completion.withinHoursOfStart
43
- : true;
44
- if (!within) return;
45
- if (spec.completion.eventName !== evt.name) return;
46
- step.status = 'COMPLETED';
47
- });
48
- });
28
+ events.forEach((evt) => {
29
+ const now = addDays(start, evt.dayOffset);
30
+ moneyResetQuestTrack.steps.forEach((spec, idx) => {
31
+ const step = progress[idx];
32
+ if (!step || step.status === 'COMPLETED') return;
33
+ const availableAt =
34
+ spec.availability?.unlockOnDay !== undefined
35
+ ? addDays(start, spec.availability.unlockOnDay - 1)
36
+ : start;
37
+ if (now < availableAt) return;
38
+ const within =
39
+ spec.completion.kind === 'time_window' &&
40
+ spec.completion.withinHoursOfStart !== undefined
41
+ ? (now.getTime() - start.getTime()) / (1000 * 60 * 60) <=
42
+ spec.completion.withinHoursOfStart
43
+ : true;
44
+ if (!within) return;
45
+ if (spec.completion.eventName !== evt.name) return;
46
+ step.status = 'COMPLETED';
47
+ });
48
+ });
49
49
 
50
- expect(progress.every((s) => s.status === 'COMPLETED')).toBeTrue();
51
- });
50
+ expect(progress.every((s) => s.status === 'COMPLETED')).toBeTrue();
51
+ });
52
52
  });
package/src/track.ts CHANGED
@@ -1,76 +1,76 @@
1
1
  import type { LearningJourneyTrackSpec } from '@contractspec/module.learning-journey/track-spec';
2
2
 
3
3
  const dayStep = (
4
- id: string,
5
- day: number,
6
- eventName: string,
7
- description: string
4
+ id: string,
5
+ day: number,
6
+ eventName: string,
7
+ description: string
8
8
  ): LearningJourneyTrackSpec['steps'][number] => ({
9
- id,
10
- title: `Day ${day}`,
11
- description,
12
- availability: { unlockOnDay: day },
13
- completion: {
14
- kind: 'time_window',
15
- eventName,
16
- withinHoursOfStart: (day + 1) * 24, // allow grace through next day
17
- },
18
- xpReward: 15,
19
- metadata: { day },
9
+ id,
10
+ title: `Day ${day}`,
11
+ description,
12
+ availability: { unlockOnDay: day },
13
+ completion: {
14
+ kind: 'time_window',
15
+ eventName,
16
+ withinHoursOfStart: (day + 1) * 24, // allow grace through next day
17
+ },
18
+ xpReward: 15,
19
+ metadata: { day },
20
20
  });
21
21
 
22
22
  export const moneyResetQuestTrack: LearningJourneyTrackSpec = {
23
- id: 'money_reset_7day',
24
- name: '7-day Money Reset',
25
- description:
26
- 'Time-bound quest to reset personal finances over a focused week.',
27
- targetUserSegment: 'money_user',
28
- totalXp: 105,
29
- completionRewards: { xpBonus: 30 },
30
- steps: [
31
- dayStep(
32
- 'day1_map_accounts',
33
- 1,
34
- 'accounts.mapped',
35
- 'Map bank and card accounts.'
36
- ),
37
- dayStep(
38
- 'day2_categorize_transactions',
39
- 2,
40
- 'transactions.categorized',
41
- 'Categorize recent transactions.'
42
- ),
43
- dayStep(
44
- 'day3_define_goals',
45
- 3,
46
- 'goals.created',
47
- 'Define at least one savings goal.'
48
- ),
49
- dayStep(
50
- 'day4_setup_recurring_savings',
51
- 4,
52
- 'recurring_rule.created',
53
- 'Set a recurring savings rule.'
54
- ),
55
- dayStep(
56
- 'day5_review_subscriptions',
57
- 5,
58
- 'subscription.flagged_or_cancelled',
59
- 'Review subscriptions and flag or cancel wasteful ones.'
60
- ),
61
- dayStep(
62
- 'day6_plan_emergency',
63
- 6,
64
- 'emergency_plan.completed',
65
- 'Draft an emergency plan and target buffer.'
66
- ),
67
- dayStep(
68
- 'day7_review_commit',
69
- 7,
70
- 'quest.review.completed',
71
- 'Review week outcomes and commit to the next month.'
72
- ),
73
- ],
23
+ id: 'money_reset_7day',
24
+ name: '7-day Money Reset',
25
+ description:
26
+ 'Time-bound quest to reset personal finances over a focused week.',
27
+ targetUserSegment: 'money_user',
28
+ totalXp: 105,
29
+ completionRewards: { xpBonus: 30 },
30
+ steps: [
31
+ dayStep(
32
+ 'day1_map_accounts',
33
+ 1,
34
+ 'accounts.mapped',
35
+ 'Map bank and card accounts.'
36
+ ),
37
+ dayStep(
38
+ 'day2_categorize_transactions',
39
+ 2,
40
+ 'transactions.categorized',
41
+ 'Categorize recent transactions.'
42
+ ),
43
+ dayStep(
44
+ 'day3_define_goals',
45
+ 3,
46
+ 'goals.created',
47
+ 'Define at least one savings goal.'
48
+ ),
49
+ dayStep(
50
+ 'day4_setup_recurring_savings',
51
+ 4,
52
+ 'recurring_rule.created',
53
+ 'Set a recurring savings rule.'
54
+ ),
55
+ dayStep(
56
+ 'day5_review_subscriptions',
57
+ 5,
58
+ 'subscription.flagged_or_cancelled',
59
+ 'Review subscriptions and flag or cancel wasteful ones.'
60
+ ),
61
+ dayStep(
62
+ 'day6_plan_emergency',
63
+ 6,
64
+ 'emergency_plan.completed',
65
+ 'Draft an emergency plan and target buffer.'
66
+ ),
67
+ dayStep(
68
+ 'day7_review_commit',
69
+ 7,
70
+ 'quest.review.completed',
71
+ 'Review week outcomes and commit to the next month.'
72
+ ),
73
+ ],
74
74
  };
75
75
 
76
76
  export const questTracks: LearningJourneyTrackSpec[] = [moneyResetQuestTrack];
package/tsconfig.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
- "extends": "@contractspec/tool.typescript/react-library.json",
3
- "include": ["src"],
4
- "exclude": ["node_modules"],
5
- "compilerOptions": {
6
- "rootDir": "src",
7
- "outDir": "dist"
8
- }
2
+ "extends": "@contractspec/tool.typescript/react-library.json",
3
+ "include": ["src"],
4
+ "exclude": ["node_modules"],
5
+ "compilerOptions": {
6
+ "rootDir": "src",
7
+ "outDir": "dist"
8
+ }
9
9
  }
package/tsdown.config.js CHANGED
@@ -1,16 +1,10 @@
1
- import { defineConfig, moduleLibrary, withDevExports } from '@contractspec/tool.bun';
1
+ import {
2
+ defineConfig,
3
+ moduleLibrary,
4
+ withDevExports,
5
+ } from '@contractspec/tool.bun';
2
6
 
3
7
  export default defineConfig(() => ({
4
- ...moduleLibrary,
5
- ...withDevExports,
8
+ ...moduleLibrary,
9
+ ...withDevExports,
6
10
  }));
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-