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

3.9 KiB

Implementation Plan: Turn Navigation

Branch: 012-turn-navigation | Date: 2026-03-05 | Spec: spec.md Input: Feature specification from /specs/012-turn-navigation/spec.md

Summary

Add a RetreatTurn domain operation (inverse of AdvanceTurn) and relocate both Previous/Next Turn buttons to a new turn navigation bar at the top of the encounter tracker. The domain function is a pure state transition that decrements the active index (wrapping to the last combatant and decrementing round number when crossing a round boundary), with a guard preventing retreat before the encounter start (round 1, index 0).

Technical Context

Language/Version: TypeScript 5.8 (strict mode, verbatimModuleSyntax) Primary Dependencies: React 19, Vite 6, Tailwind CSS v4, shadcn/ui-style components, Lucide React (icons) Storage: N/A (no storage changes -- existing localStorage persistence unchanged) Testing: Vitest (pure-function domain tests + component tests) Target Platform: Web browser (single-user, local-first) Project Type: Web application (monorepo: domain + application + web adapter) Performance Goals: Standard web app -- instant UI response (<100ms) Constraints: Domain layer must remain pure (no I/O, no framework imports) Scale/Scope: Single-user encounter tracker, ~5-20 combatants typical

Constitution Check

GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.

Principle Status Notes
I. Deterministic Domain Core PASS RetreatTurn is a pure function: same input = same output. No I/O, randomness, or clocks.
II. Layered Architecture PASS Domain (retreat-turn.ts) -> Application (retreat-turn-use-case.ts) -> Adapter (React hook + component). Dependency direction preserved.
III. Agent Boundary N/A No agent layer involved.
IV. Clarification-First PASS No ambiguities remain in spec. All edge cases resolved.
V. Escalation Gates PASS Implementation matches spec scope exactly.
VI. MVP Baseline Language PASS Assumptions use "MVP baseline does not include" phrasing.
VII. No Gameplay Rules PASS No gameplay mechanics in plan.

Project Structure

Documentation (this feature)

specs/012-turn-navigation/
├── plan.md              # This file
├── research.md          # Phase 0 output
├── data-model.md        # Phase 1 output
├── quickstart.md        # Phase 1 output
├── contracts/           # Phase 1 output
└── tasks.md             # Phase 2 output (via /speckit.tasks)

Source Code (repository root)

packages/domain/src/
├── retreat-turn.ts              # NEW: RetreatTurn pure function
├── events.ts                    # MODIFY: Add TurnRetreated + RoundRetreated events
├── types.ts                     # UNCHANGED
├── index.ts                     # MODIFY: Re-export retreatTurn
└── __tests__/
    └── retreat-turn.test.ts     # NEW: All acceptance scenarios

packages/application/src/
├── retreat-turn-use-case.ts     # NEW: Orchestrates retreatTurn via EncounterStore
├── ports.ts                     # UNCHANGED
├── index.ts                     # MODIFY: Re-export new use case
└── ...

apps/web/src/
├── components/
│   ├── turn-navigation.tsx      # NEW: Top-placed Previous/Next turn bar
│   └── action-bar.tsx           # MODIFY: Remove Next Turn button
├── hooks/
│   └── use-encounter.ts         # MODIFY: Add retreatTurn handler
└── App.tsx                      # MODIFY: Add TurnNavigation component above combatant list

Structure Decision: Follows existing monorepo layout (domain -> application -> web adapter). New files mirror the existing advance-turn pattern. The turn navigation component is a new UI component placed in the existing components directory.