Files
initiative/specs/003-remove-combatant/tasks.md

4.9 KiB
Raw Blame History

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 CombatantRemoved interface and extend DomainEvent union in packages/domain/src/events.ts
  • T002 Export CombatantRemoved type from packages/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 removeCombatant in packages/domain/src/__tests__/remove-combatant.test.ts covering 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 removeCombatant pure function and RemoveCombatantSuccess type in packages/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 removeCombatant and RemoveCombatantSuccess from packages/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 removeCombatantUseCase in packages/application/src/remove-combatant-use-case.ts — follows existing pattern: store.get()removeCombatant()store.save() → return events or DomainError
  • T007 [US2] Export removeCombatantUseCase from packages/application/src/index.ts
  • T008 [US2] Add removeCombatant(id: CombatantId) callback to useEncounter hook in apps/web/src/hooks/use-encounter.ts — call use case, append events to log on success
  • T009 [US2] Add remove button per combatant and CombatantRemoved event display case in apps/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)

  1. Complete Phase 1: Event type (T001T002)
  2. Complete Phase 2: Domain tests + function (T003T005)
  3. STOP and VALIDATE: All 6 acceptance tests pass
  4. Domain is complete and usable without UI

Full Feature

  1. Phase 1 → Phase 2 → Phase 3 → Phase 4
  2. Each phase adds a testable increment
  3. 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