6.7 KiB
Tasks: Advance Turn
Input: Design documents from /specs/001-advance-turn/
Prerequisites: plan.md (required), spec.md (required)
Organization: Tasks follow the phased structure from plan.md. There is only one user story (US1 — Advance Turn, P1), so phases map directly to the plan's milestones.
Format: [ID] [P?] [Story?] Description
- [P]: Can run in parallel (different files, no dependencies)
- [US1]: User Story 1 — Advance Turn
- Exact file paths included in every task
Phase 1: Setup (Milestone 1 — Tooling)
Purpose: Initialize pnpm monorepo, Biome, TypeScript, Vitest, and layer boundary enforcement
- T001 Initialize pnpm workspace and root config — create
pnpm-workspace.yaml,.nvmrc(Node 22), rootpackage.json(withpackageManagerpinning pnpm 10.6 and scripts: check, test, lint, format, typecheck),biome.json, andtsconfig.base.json(strict, composite, path aliases) - T002 [P] Create
packages/domainpackage skeleton —packages/domain/package.json(@initiative/domain, no deps),packages/domain/tsconfig.json(extends base, composite), emptypackages/domain/src/index.ts - T003 [P] Create
packages/applicationpackage skeleton —packages/application/package.json(@initiative/application, depends on@initiative/domain),packages/application/tsconfig.json(extends base, references domain), emptypackages/application/src/index.ts - T004 [P] Create
apps/webpackage skeleton —apps/web/package.json(React 19, Vite 6.2, depends on both packages),apps/web/tsconfig.json,apps/web/vite.config.ts,apps/web/index.html,apps/web/src/main.tsx,apps/web/src/App.tsx(placeholder) - T005 Configure Vitest — add
vitestas root dev dependency, createvitest.config.tsat root (workspace mode or per-package), verifypnpm testexits 0 - T006 Create layer boundary check —
scripts/check-layer-boundaries.mjs(scans domain/application for forbidden imports) andpackages/domain/src/__tests__/layer-boundaries.test.ts(wraps script as Vitest test)
Checkpoint: pnpm install succeeds, biome check . runs, tsc --build compiles, pnpm test exits 0 with layer boundary test green.
Phase 2: Domain Implementation — User Story 1: Advance Turn (Priority: P1) (Milestone 1)
Goal: Implement the complete AdvanceTurn domain logic as a pure function with all 8 acceptance scenarios and invariant tests.
Independent Test: Pure state transition — given an Encounter value and AdvanceTurn action, assert resulting Encounter and emitted domain events. No I/O, persistence, or UI needed.
- T007 [US1] Define domain types in
packages/domain/src/types.ts—CombatantId(branded/opaque),Combatant,Encounter(combatants, activeIndex, roundNumber), factorycreateEncounterenforcing INV-1, INV-2, INV-3 - T008 [P] [US1] Define domain events in
packages/domain/src/events.ts—TurnAdvanced,RoundAdvanced,DomainEventunion (plain data, no classes) - T009 [US1] Implement
advanceTurninpackages/domain/src/advance-turn.ts— pure function(Encounter) => { encounter, events } | DomainError, implements FR-001 through FR-005 - T010 [US1] Write tests for all 8 acceptance scenarios + invariants in
packages/domain/src/__tests__/advance-turn.test.ts— scenarios 1–8, INV-1 through INV-5, event ordering on round wrap - T011 [US1] Export public API from
packages/domain/src/index.ts— re-export types, events,advanceTurn,createEncounter
Checkpoint (Milestone 1): pnpm check passes (format + lint + typecheck + test + layer boundaries). All 8 scenarios + invariants green. No React/Vite imports in domain or application.
Phase 3: Application + Web Shell (Milestone 2)
Goal: Wire up the application use case and minimal React UI with a "Next Turn" button.
- T012 Define port interface in
packages/application/src/ports.ts—EncounterStoreport:get(): Encounter,save(e: Encounter) - T013 Implement
AdvanceTurnUseCaseinpackages/application/src/advance-turn-use-case.ts— acceptsEncounterStore, callsadvanceTurn, saves result, returns events - T014 Export public API from
packages/application/src/index.ts— re-export use case and port types - T015 Implement
useEncounterhook inapps/web/src/hooks/use-encounter.ts— in-memoryEncounterStorevia React state, exposes encounter state +advanceTurnaction, hardcoded 3-combatant demo - T016 Wire up
apps/web/src/App.tsx— display current combatant, round number, combatant list with active indicator, "Next Turn" button, emitted events
Checkpoint (Milestone 2): pnpm check passes. vite build succeeds. Clicking "Next Turn" cycles combatants and increments rounds correctly.
Dependencies & Execution Order
Phase Dependencies
- Phase 1 (Setup): No dependencies — start immediately
- Phase 2 (Domain): Depends on Phase 1 completion
- Phase 3 (App + Web): Depends on Phase 2 completion (needs domain types and
advanceTurn)
Within Phase 1
- T001 must complete first (workspace and root config)
- T002, T003, T004 can run in parallel [P] after T001
- T005 depends on T001 (needs root package.json)
- T006 depends on T002 and T005 (needs domain package + Vitest)
Within Phase 2
- T007 must complete first (types needed by everything)
- T008 can run in parallel [P] with T007 (events are independent types)
- T009 depends on T007 and T008 (uses types and events)
- T010 depends on T009 (tests the implementation)
- T011 depends on T007, T008, T009 (exports all public API)
Within Phase 3
- T012 first (port interface)
- T013 depends on T012 (uses port)
- T014 depends on T013 (exports use case)
- T015 depends on T014 (uses application layer)
- T016 depends on T015 (uses hook)
Parallel Opportunities
# After T001 completes:
T002, T003, T004 — all package skeletons in parallel
# After T007 starts:
T008 — domain events can be written in parallel with types
# Independent stories: only one user story (US1), so parallelism is within-phase only
Implementation Strategy
MVP First (Milestone 1)
- Complete Phase 1: Setup (T001–T006)
- Complete Phase 2: Domain (T007–T011)
- STOP and VALIDATE:
pnpm checkpasses, all 8 scenarios green
Full Feature (Milestone 2)
- Complete Phase 3: App + Web Shell (T012–T016)
- VALIDATE:
pnpm checkpasses, app runs in browser
Notes
- All task IDs (T001–T016) match plan.md — no scope expansion
- Single user story (US1: Advance Turn) — no cross-story dependencies
- Tests (T010) are included as specified in plan.md and spec.md
- Domain package must have zero React/Vite imports (enforced by T006)