4.9 KiB
Tasks: Remove Combatant
Input: Design documents from /specs/003-remove-combatant/
Prerequisites: plan.md, spec.md, research.md, data-model.md
Tests: Included — spec requires all six acceptance scenarios as automated tests (SC-002).
Organization: Tasks grouped by user story for independent implementation and testing.
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)
- Exact file paths included in descriptions
Phase 1: Foundational (Event Type)
Purpose: Add the CombatantRemoved event type that all subsequent tasks depend on.
- T001 Add
CombatantRemovedinterface and extendDomainEventunion inpackages/domain/src/events.ts - T002 Export
CombatantRemovedtype frompackages/domain/src/index.ts
Checkpoint: CombatantRemoved event type available for domain function and UI event display.
Phase 2: User Story 1 - Remove Combatant Domain Logic (Priority: P1) MVP
Goal: Pure removeCombatant domain function that removes a combatant by ID, adjusts activeIndex correctly, preserves roundNumber, and emits CombatantRemoved.
Independent Test: Call removeCombatant with various encounter states and verify combatant list, activeIndex, roundNumber, events, and error cases.
Tests for User Story 1
NOTE: Write these tests FIRST, ensure they FAIL before implementation
- T003 [US1] Write acceptance tests for
removeCombatantinpackages/domain/src/__tests__/remove-combatant.test.tscovering all 6 spec scenarios: remove after active (AS-1), remove before active (AS-2), remove active combatant mid-list (AS-3), remove active combatant at end/wrap (AS-4), remove only combatant (AS-5), ID not found error (AS-6). Also test: event shape (CombatantRemoved with id+name), roundNumber invariance, and determinism.
Implementation for User Story 1
- T004 [US1] Implement
removeCombatantpure function andRemoveCombatantSuccesstype inpackages/domain/src/remove-combatant.ts— find combatant by ID, compute new activeIndex per data-model rules, filter combatant list, emit CombatantRemoved event, return DomainError for not-found - T005 [US1] Export
removeCombatantandRemoveCombatantSuccessfrompackages/domain/src/index.ts
Checkpoint: All 6 acceptance tests pass. Domain function is complete and independently testable.
Phase 3: User Story 2 - Application + UI Wiring (Priority: P2)
Goal: Wire removeCombatant through application use case and expose via minimal UI with a remove button per combatant.
Independent Test: Render encounter UI, click remove on a combatant, verify it disappears from the list and event log updates.
Implementation for User Story 2
- T006 [P] [US2] Create
removeCombatantUseCaseinpackages/application/src/remove-combatant-use-case.ts— follows existing pattern:store.get()→removeCombatant()→store.save()→ return events or DomainError - T007 [US2] Export
removeCombatantUseCasefrompackages/application/src/index.ts - T008 [US2] Add
removeCombatant(id: CombatantId)callback touseEncounterhook inapps/web/src/hooks/use-encounter.ts— call use case, append events to log on success - T009 [US2] Add remove button per combatant and
CombatantRemovedevent display case inapps/web/src/App.tsx
Checkpoint: Full vertical slice works — GM can remove combatants from UI, initiative order updates correctly, event log shows removal.
Phase 4: Polish & Cross-Cutting Concerns
- T010 Run
pnpm check(format + lint + typecheck + test) and fix any issues
Dependencies & Execution Order
Phase Dependencies
- Phase 1 (Foundational): No dependencies — start immediately
- Phase 2 (US1 Domain): Depends on Phase 1 (needs CombatantRemoved type)
- Phase 3 (US2 App+UI): Depends on Phase 2 (needs domain function)
- Phase 4 (Polish): Depends on Phase 3
Within Each Phase
- T001 → T002 (export after defining)
- T003 (tests first) → T004 (implement) → T005 (export)
- T006 → T007 (export after creating use case file)
- T008 depends on T006+T007 (needs use case)
- T009 depends on T008 (needs hook callback)
Parallel Opportunities
- Within T003, individual test cases are independent
Implementation Strategy
MVP First (User Story 1 Only)
- Complete Phase 1: Event type (T001–T002)
- Complete Phase 2: Domain tests + function (T003–T005)
- STOP and VALIDATE: All 6 acceptance tests pass
- Domain is complete and usable without UI
Full Feature
- Phase 1 → Phase 2 → Phase 3 → Phase 4
- Each phase adds a testable increment
- Commit after each phase checkpoint
Notes
- [P] tasks = different files, no dependencies
- [Story] label maps task to specific user story
- Tests written first (TDD) per spec requirement SC-002
- Commit after each phase checkpoint
- Total: 10 tasks across 4 phases