Files
initiative/specs/005-set-initiative/tasks.md

8.4 KiB
Raw Blame History

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.

  • T001 Add optional initiative property to Combatant interface in packages/domain/src/types.ts
  • 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

  • T003 [US1] Write acceptance tests for setting initiative (set, change, reject non-integer) in packages/domain/src/__tests__/set-initiative.test.ts
  • 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
  • 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

  • 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
  • T007 Export setInitiative and related types from packages/domain/src/index.ts
  • 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)
  • 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

  • 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

  • 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

  • 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

  • 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.

  • T014 Add setInitiative callback to useEncounter hook in apps/web/src/hooks/use-encounter.ts — call setInitiativeUseCase, handle errors, append events
  • 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.

  • T016 Write edge case tests (zero initiative, negative initiative, clearing initiative, all same value) in packages/domain/src/__tests__/set-initiative.test.ts
  • T017 Run pnpm check (format + lint + typecheck + test) and fix any issues
  • 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 24 (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)

# 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