# 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 - [X] T001 Initialize pnpm workspace and root config — create `pnpm-workspace.yaml`, `.nvmrc` (Node 22), root `package.json` (with `packageManager` pinning pnpm 10.6 and scripts: check, test, lint, format, typecheck), `biome.json`, and `tsconfig.base.json` (strict, composite, path aliases) - [X] T002 [P] Create `packages/domain` package skeleton — `packages/domain/package.json` (`@initiative/domain`, no deps), `packages/domain/tsconfig.json` (extends base, composite), empty `packages/domain/src/index.ts` - [X] T003 [P] Create `packages/application` package skeleton — `packages/application/package.json` (`@initiative/application`, depends on `@initiative/domain`), `packages/application/tsconfig.json` (extends base, references domain), empty `packages/application/src/index.ts` - [X] T004 [P] Create `apps/web` package 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) - [X] T005 Configure Vitest — add `vitest` as root dev dependency, create `vitest.config.ts` at root (workspace mode or per-package), verify `pnpm test` exits 0 - [X] T006 Create layer boundary check — `scripts/check-layer-boundaries.mjs` (scans domain/application for forbidden imports) and `packages/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. - [X] T007 [US1] Define domain types in `packages/domain/src/types.ts` — `CombatantId` (branded/opaque), `Combatant`, `Encounter` (combatants, activeIndex, roundNumber), factory `createEncounter` enforcing INV-1, INV-2, INV-3 - [X] T008 [P] [US1] Define domain events in `packages/domain/src/events.ts` — `TurnAdvanced`, `RoundAdvanced`, `DomainEvent` union (plain data, no classes) - [X] T009 [US1] Implement `advanceTurn` in `packages/domain/src/advance-turn.ts` — pure function `(Encounter) => { encounter, events } | DomainError`, implements FR-001 through FR-005 - [X] 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 - [X] 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` — `EncounterStore` port: `get(): Encounter`, `save(e: Encounter)` - [ ] T013 Implement `AdvanceTurnUseCase` in `packages/application/src/advance-turn-use-case.ts` — accepts `EncounterStore`, calls `advanceTurn`, saves result, returns events - [ ] T014 Export public API from `packages/application/src/index.ts` — re-export use case and port types - [ ] T015 Implement `useEncounter` hook in `apps/web/src/hooks/use-encounter.ts` — in-memory `EncounterStore` via React state, exposes encounter state + `advanceTurn` action, 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 ```text # 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) 1. Complete Phase 1: Setup (T001–T006) 2. Complete Phase 2: Domain (T007–T011) 3. **STOP and VALIDATE**: `pnpm check` passes, all 8 scenarios green ### Full Feature (Milestone 2) 4. Complete Phase 3: App + Web Shell (T012–T016) 5. **VALIDATE**: `pnpm check` passes, 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)