# Tasks: Set Initiative **Input**: Design documents from `/specs/005-set-initiative/` **Prerequisites**: plan.md (required), spec.md (required), research.md, data-model.md, contracts/domain-api.md, quickstart.md **Tests**: Tests are included as this project follows TDD conventions (test files exist for all domain functions). **Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story. ## Format: `[ID] [P?] [Story] Description` - **[P]**: Can run in parallel (different files, no dependencies) - **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3) - Include exact file paths in descriptions --- ## Phase 1: Setup (Shared Infrastructure) **Purpose**: No new project setup needed — existing monorepo. This phase covers foundational type and event changes shared across all user stories. - [x] T001 Add optional `initiative` property to `Combatant` interface in `packages/domain/src/types.ts` - [x] T002 Add `InitiativeSet` event type (with `combatantId`, `previousValue`, `newValue` fields) to `DomainEvent` union in `packages/domain/src/events.ts` **Checkpoint**: Types compile, existing tests still pass (`pnpm check`) --- ## Phase 2: User Story 1 + User Story 2 — Set Initiative & Automatic Ordering (Priority: P1) MVP **Goal**: Users can set/change/clear initiative values on combatants, and the encounter automatically reorders combatants from highest to lowest initiative. **Independent Test**: Set initiative on multiple combatants and verify the combatant list is sorted descending by initiative value. ### Tests for User Stories 1 & 2 > **NOTE: Write these tests FIRST, ensure they FAIL before implementation** - [x] T003 [US1] Write acceptance tests for setting initiative (set, change, reject non-integer) in `packages/domain/src/__tests__/set-initiative.test.ts` - [x] T004 [US2] Write acceptance tests for automatic ordering (descending sort, stable sort for ties, reorder on change) in `packages/domain/src/__tests__/set-initiative.test.ts` - [x] T005 Write invariant tests (determinism, immutability, event shape, roundNumber unchanged) in `packages/domain/src/__tests__/set-initiative.test.ts` ### Implementation for User Stories 1 & 2 - [x] T006 [US1] [US2] Implement `setInitiative(encounter, combatantId, value)` domain function in `packages/domain/src/set-initiative.ts` — validate combatant exists, validate integer, update initiative, stable-sort descending, emit `InitiativeSet` event - [x] T007 Export `setInitiative` and related types from `packages/domain/src/index.ts` - [x] T008 Implement `setInitiativeUseCase(store, combatantId, value)` in `packages/application/src/set-initiative-use-case.ts` following existing use case pattern (get → call → check error → save → return events) - [x] T009 Export `setInitiativeUseCase` from `packages/application/src/index.ts` **Checkpoint**: Domain tests pass, `pnpm check` passes. Core initiative logic is complete. --- ## Phase 3: User Story 3 — Combatants Without Initiative (Priority: P2) **Goal**: Combatants without initiative appear after all combatants with initiative, preserving their relative order. **Independent Test**: Create a mix of combatants with and without initiative and verify ordering (initiative-set first descending, then unset in insertion order). ### Tests for User Story 3 - [x] T010 [US3] Write acceptance tests for unset-initiative ordering (unset after set, multiple unset preserve order, setting initiative moves combatant up) in `packages/domain/src/__tests__/set-initiative.test.ts` ### Implementation for User Story 3 - [x] T011 [US3] Verify that sort logic in `packages/domain/src/set-initiative.ts` already handles `undefined` initiative correctly (combatants without initiative sort after those with initiative, stable sort within each group) — add handling if not already present in T006 **Checkpoint**: All ordering scenarios pass including mixed set/unset combatants. --- ## Phase 4: User Story 4 — Active Turn Preservation During Reorder (Priority: P2) **Goal**: The active combatant's turn is preserved when initiative changes cause the combatant list to be reordered. **Independent Test**: Set active combatant, change another combatant's initiative causing reorder, verify active turn still points to the same combatant. ### Tests for User Story 4 - [x] T012 [US4] Write acceptance tests for active turn preservation (reorder doesn't shift active turn, active combatant's own initiative change preserves turn) in `packages/domain/src/__tests__/set-initiative.test.ts` ### Implementation for User Story 4 - [x] T013 [US4] Verify that `activeIndex` identity-tracking in `packages/domain/src/set-initiative.ts` works correctly when reordering occurs — the logic (record active id before sort, find new index after sort) should already exist from T006; add or fix if needed **Checkpoint**: Active turn is preserved through all reorder scenarios. `pnpm check` passes. --- ## Phase 5: Web Adapter Integration **Purpose**: Wire initiative into the React UI so users can actually set initiative values. - [x] T014 Add `setInitiative` callback to `useEncounter` hook in `apps/web/src/hooks/use-encounter.ts` — call `setInitiativeUseCase`, handle errors, append events - [x] T015 Add initiative input field next to each combatant in `apps/web/src/App.tsx` — numeric input, display current value, clear button, call `setInitiative` on change **Checkpoint**: Full feature works end-to-end in the browser. `pnpm check` passes. --- ## Phase 6: Polish & Cross-Cutting Concerns **Purpose**: Edge case coverage and final validation. - [x] T016 Write edge case tests (zero initiative, negative initiative, clearing initiative, all same value) in `packages/domain/src/__tests__/set-initiative.test.ts` - [x] T017 Run `pnpm check` (format + lint + typecheck + test) and fix any issues - [x] T018 Verify layer boundary compliance (domain imports no framework/adapter code) --- ## Dependencies & Execution Order ### Phase Dependencies - **Phase 1 (Setup)**: No dependencies — types and events first - **Phase 2 (US1+US2 MVP)**: Depends on Phase 1 - **Phase 3 (US3)**: Depends on Phase 2 (extends sort logic) - **Phase 4 (US4)**: Depends on Phase 2 (extends activeIndex logic) - **Phase 5 (Web Adapter)**: Depends on Phases 2–4 (needs complete domain + application layer) - **Phase 6 (Polish)**: Depends on all previous phases ### User Story Dependencies - **US1 + US2 (P1)**: Combined because sorting is inherent to setting initiative — they share the same domain function - **US3 (P2)**: Extends the sort logic from US1+US2 to handle `undefined`. Can be developed immediately after Phase 2. - **US4 (P2)**: Extends the `activeIndex` logic from US1+US2. Can be developed in parallel with US3. ### Parallel Opportunities - **T001 and T002** can run in parallel (different files) - **T003, T004, T005** can run in parallel (same file but different test groups — practically written together) - **US3 (Phase 3) and US4 (Phase 4)** can run in parallel after Phase 2 - **T014 and T015** can run in parallel (different files) --- ## Parallel Example: Phase 2 (MVP) ```bash # Tests first (all in same file, written together): T003: Acceptance tests for setting initiative T004: Acceptance tests for automatic ordering T005: Invariant tests # Then implementation: T006: Domain function (core logic) T007: Domain exports T008: Application use case (after T006-T007) T009: Application exports ``` --- ## Implementation Strategy ### MVP First (User Stories 1 + 2) 1. Complete Phase 1: Type + event changes 2. Complete Phase 2: Domain function + use case with tests 3. **STOP and VALIDATE**: `pnpm check` passes, initiative setting and ordering works 4. Optionally wire up UI (Phase 5) for a minimal demo ### Incremental Delivery 1. Phase 1 → Types ready 2. Phase 2 → MVP: set initiative + auto-ordering works 3. Phase 3 → Unset combatants handled correctly 4. Phase 4 → Active turn preserved through reorders 5. Phase 5 → UI wired up, feature usable in browser 6. Phase 6 → Edge cases covered, quality verified --- ## Notes - US1 and US2 are combined in Phase 2 because the domain function `setInitiative` inherently performs both setting and sorting — they cannot be meaningfully separated - US3 and US4 are separable extensions of the sort and activeIndex logic respectively - All domain tests follow existing patterns: helper functions for test data, acceptance scenarios mapped from spec, invariant tests for determinism/immutability - Commit after each phase checkpoint