Files
initiative/specs/012-turn-navigation/tasks.md

7.9 KiB

Tasks: Turn Navigation

Input: Design documents from /specs/012-turn-navigation/ Prerequisites: plan.md (required), spec.md (required for user stories), research.md, data-model.md, contracts/

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 structure is in place. This phase is empty.

Checkpoint: Existing infrastructure is sufficient. Proceed directly to foundational work.


Phase 2: Foundational (Blocking Prerequisites)

Purpose: Add new domain event types. These are shared by US1 (domain logic) and US2/US3 (UI).

CRITICAL: No user story work can begin until this phase is complete.

  • T001 Add TurnRetreated and RoundRetreated event interfaces to the DomainEvent union in packages/domain/src/events.ts

Checkpoint: Foundation ready -- event types defined, user story implementation can begin.


Phase 3: User Story 1 - Go Back to the Previous Turn (Priority: P1) MVP

Goal: Implement the RetreatTurn pure domain function and its application use case so that turns can be reversed programmatically.

Independent Test: Call retreatTurn with various encounter states and verify correct activeIndex, roundNumber, and emitted events. All tests are pure-function assertions with no I/O.

Implementation for User Story 1

  • T003 [US1] Create retreatTurn pure function in packages/domain/src/retreat-turn.ts implementing: decrement activeIndex, wrap to last combatant on round boundary, decrement roundNumber on wrap, error on empty encounter, error on round 1 index 0
  • T004 [US1] Write acceptance scenario tests for retreatTurn in packages/domain/src/__tests__/retreat-turn.test.ts covering all 5 spec scenarios: mid-round retreat, round-boundary retreat, start-of-encounter error, single-combatant retreat, empty-encounter error
  • T005 [US1] Re-export retreatTurn from domain index in packages/domain/src/index.ts
  • T006 [US1] Create retreatTurnUseCase in packages/application/src/retreat-turn-use-case.ts following the advanceTurnUseCase pattern (get encounter from store, call retreatTurn, save result or return error)
  • T007 [US1] Export retreatTurnUseCase from application index in packages/application/src/index.ts
  • T008 [US1] Run pnpm check to verify all tests pass, types check, and no lint/format issues

Checkpoint: RetreatTurn domain logic is fully functional and tested. UI work can proceed.


Phase 4: User Story 2 - Turn Navigation Controls at the Top (Priority: P1)

Goal: Create a turn navigation bar at the top of the tracker with Previous and Next Turn buttons, relocating Next Turn from the bottom action bar.

Independent Test: Load the tracker with combatants, verify Previous/Next buttons appear above the combatant list, click Next to advance, click Previous to retreat, verify disabled states.

Implementation for User Story 2

  • T009 [US2] Add retreatTurn handler to the encounter hook in apps/web/src/hooks/use-encounter.ts (mirror the existing advanceTurn handler pattern)
  • T010 [US2] Create TurnNavigation component in apps/web/src/components/turn-navigation.tsx with Previous/Next buttons, round number display, active combatant name, and disabled states (Previous disabled at round 1 index 0 or no combatants; Next disabled when no combatants)
  • T011 [US2] Wire TurnNavigation into App between header and combatant list in apps/web/src/App.tsx, passing encounter state, onAdvanceTurn, and onRetreatTurn
  • T012 [US2] Remove Next Turn button from ActionBar in apps/web/src/components/action-bar.tsx (keep only the Add Combatant form)

Checkpoint: Turn navigation is fully functional at the top of the tracker. Previous and Next Turn work correctly with proper disabled states.


Phase 5: User Story 3 - Modern, Sleek Turn Navigation Design (Priority: P2)

Goal: Polish the turn navigation bar with clear visual hierarchy, directional icons, and a clean modern design consistent with the existing shadcn/ui-style components.

Independent Test: Visually inspect the turn navigation area -- buttons have directional icons, round/combatant info is clearly displayed, disabled state is visually distinct, layout is balanced and clean.

Implementation for User Story 3

  • T014 [US3] Add directional icons (e.g., ChevronLeft, ChevronRight from Lucide React) to the Previous/Next buttons in apps/web/src/components/turn-navigation.tsx
  • T015 [US3] Style the turn navigation bar with proper spacing, border, background, and visual hierarchy consistent with existing card/action-bar styling in apps/web/src/components/turn-navigation.tsx
  • T016 [US3] Ensure disabled button state has reduced opacity and no hover effects, visually distinct from active state in apps/web/src/components/turn-navigation.tsx

Checkpoint: Turn navigation is visually polished with clear directional indicators and modern design.


Phase 6: Polish & Cross-Cutting Concerns

Purpose: Final validation across all stories.

  • T018 Verify layer boundary compliance -- retreatTurn in domain has no application/adapter imports (covered by existing layer-boundaries.test.ts)
  • T019 Run full quality gate with pnpm check and verify clean pass
  • T020 Verify localStorage persistence handles retreat correctly (existing persistence should work transparently since it saves the Encounter state)

Dependencies & Execution Order

Phase Dependencies

  • Foundational (Phase 2): No dependencies -- can start immediately
  • User Story 1 (Phase 3): Depends on Phase 2 (event types must exist)
  • User Story 2 (Phase 4): Depends on Phase 3 (retreatTurn domain + use case must exist)
  • User Story 3 (Phase 5): Depends on Phase 4 (TurnNavigation component must exist to polish)
  • Polish (Phase 6): Depends on all user stories being complete

User Story Dependencies

  • User Story 1 (P1): Can start after Foundational (Phase 2) -- pure domain work, no UI dependency
  • User Story 2 (P1): Depends on US1 completion -- needs retreatTurn use case to wire into the UI
  • User Story 3 (P2): Depends on US2 completion -- polishes the component created in US2

Within Each User Story

  • Domain function before tests (or TDD: tests first, then function)
  • Domain before application use case
  • Application use case before adapter/UI wiring
  • UI component creation before styling polish

Parallel Opportunities

  • T014, T015, T016 can run in parallel (same file but independent style concerns -- may be done in one pass)

Implementation Strategy

MVP First (User Story 1 Only)

  1. Complete Phase 2: Foundational (event types)
  2. Complete Phase 3: User Story 1 (retreatTurn domain + tests + use case)
  3. STOP and VALIDATE: All acceptance scenarios pass as pure-function tests
  4. Domain logic is fully verified before any UI work

Incremental Delivery

  1. Phase 2: Foundation -> Event types defined
  2. Phase 3: US1 -> RetreatTurn domain logic tested and working (MVP domain!)
  3. Phase 4: US2 -> Turn navigation bar at top, Previous/Next buttons functional (MVP UI!)
  4. Phase 5: US3 -> Visual polish with icons and consistent styling
  5. Phase 6: Polish -> Final cross-cutting validation

Notes

  • [P] tasks = different files, no dependencies
  • [Story] label maps task to specific user story for traceability
  • US2 depends on US1 (needs the domain function); US3 depends on US2 (polishes the component)
  • This feature has a linear dependency chain, limiting parallel opportunities
  • Commit after each phase checkpoint
  • The existing advance-turn pattern (domain -> use case -> hook -> component) serves as the reference implementation for all new code