Files
initiative/specs/004-edit-combatant/plan.md

3.0 KiB

Implementation Plan: Edit Combatant

Branch: 004-edit-combatant | Date: 2026-03-03 | Spec: spec.md Input: Feature specification from /specs/004-edit-combatant/spec.md

Summary

Add the ability to rename a combatant by id within an encounter. A pure domain function editCombatant validates the id and new name, returns the updated encounter with a CombatantUpdated event, or a DomainError. Wired through an application use case and exposed via the existing useEncounter hook to a minimal UI control.

Technical Context

Language/Version: TypeScript 5.x (strict mode, verbatimModuleSyntax) Primary Dependencies: React 19, Vite Storage: In-memory React state (local-first, single-user MVP) Testing: Vitest Target Platform: Browser (localhost:5173) Project Type: Web application (monorepo: domain → application → web) Performance Goals: N/A — single-user local state, instant updates Constraints: Pure domain logic, no I/O in domain layer Scale/Scope: Single-user encounter tracker

Constitution Check

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

Principle Status Notes
I. Deterministic Domain Core PASS editCombatant is a pure function: same encounter + id + name → same result
II. Layered Architecture PASS Domain function → use case → hook/UI. No layer violations.
III. Agent Boundary N/A No agent layer involvement
IV. Clarification-First PASS Spec is complete, no ambiguities remain
V. Escalation Gates PASS All work is within spec scope
VI. MVP Baseline Language PASS Spec uses "MVP baseline does not include" for out-of-scope items
VII. No Gameplay Rules PASS Constitution contains no gameplay logic

Project Structure

Documentation (this feature)

specs/004-edit-combatant/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
└── tasks.md

Source Code (repository root)

packages/domain/src/
├── edit-combatant.ts          # New: pure editCombatant function
├── events.ts                  # Modified: add CombatantUpdated event
├── types.ts                   # Unchanged (Combatant, Encounter, DomainError)
├── index.ts                   # Modified: re-export editCombatant
└── __tests__/
    └── edit-combatant.test.ts # New: acceptance + invariant tests

packages/application/src/
├── edit-combatant-use-case.ts # New: use case wiring
└── index.ts                   # Modified: re-export use case

apps/web/src/
├── hooks/use-encounter.ts     # Modified: add editCombatant action
└── App.tsx                    # Modified: add rename UI control

Structure Decision: Follows the existing monorepo layout (packages/domainpackages/applicationapps/web). Each new file mirrors the pattern established by add-combatant and remove-combatant.