Files
initiative/specs/002-add-combatant/tasks.md

130 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Tasks: Add Combatant
**Input**: Design documents from `/specs/002-add-combatant/`
**Prerequisites**: plan.md, spec.md, research.md, data-model.md, quickstart.md
**Tests**: Included — spec success criteria SC-001 and SC-002 require all acceptance scenarios and invariants to be verified by tests.
**Organization**: Single user story (P1). Tasks follow the established `advanceTurn` pattern across all three layers.
## 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)
- Include exact file paths in descriptions
---
## Phase 1: Foundational (Domain Event)
**Purpose**: Add the CombatantAdded event type that all layers depend on
- [x] T001 Add CombatantAdded event interface and extend DomainEvent union in packages/domain/src/events.ts
**Checkpoint**: CombatantAdded event type available for import
---
## Phase 2: User Story 1 - Add Combatant to Encounter (Priority: P1) 🎯 MVP
**Goal**: A game master can add a new combatant to an existing encounter. The combatant is appended to the end of the initiative list without changing the active turn or round.
**Independent Test**: Call `addCombatant` with an Encounter, a CombatantId, and a name. Assert the returned Encounter has the new combatant at the end, activeIndex and roundNumber unchanged, and a CombatantAdded event emitted.
### Domain Layer
- [x] T002 [US1] Create addCombatant pure function in packages/domain/src/add-combatant.ts
- [x] T003 [US1] Export addCombatant and AddCombatantSuccess from packages/domain/src/index.ts
### Domain Tests
- [x] T004 [US1] Create acceptance tests (6 scenarios) and invariant tests (INV-1 through INV-7) in packages/domain/src/__tests__/add-combatant.test.ts
### Application Layer
- [x] T005 [P] [US1] Create addCombatantUseCase in packages/application/src/add-combatant-use-case.ts
- [x] T006 [US1] Export addCombatantUseCase from packages/application/src/index.ts
### Web Adapter
- [x] T007 [US1] Add addCombatant callback to useEncounter hook in apps/web/src/hooks/use-encounter.ts
- [x] T008 [US1] Add combatant name input and add button to apps/web/src/App.tsx
**Checkpoint**: All 6 acceptance scenarios pass. User can type a name and add a combatant via the UI. `pnpm check` passes.
---
## Phase 3: Polish & Cross-Cutting Concerns
- [x] T009 Run pnpm check (format + lint + typecheck + test) and fix any issues
- [x] T010 Verify layer boundary compliance (domain has no outer-layer imports)
---
## Dependencies & Execution Order
### Phase Dependencies
- **Foundational (Phase 1)**: No dependencies — start immediately
- **User Story 1 (Phase 2)**: Depends on T001 (CombatantAdded event type)
- **Polish (Phase 3)**: Depends on all Phase 2 tasks
### Within User Story 1
```
T001 (event type)
├── T002 (domain function) → T003 (domain exports) → T004 (domain tests)
└── T005 (use case) ──────→ T006 (app exports) → T007 (hook) → T008 (UI)
```
- T002 depends on T001 (needs CombatantAdded type)
- T003 depends on T002 (exports the new function)
- T004 depends on T003 (tests import from index)
- T005 depends on T003 (use case imports domain function) — can run in parallel with T004
- T006 depends on T005
- T007 depends on T006
- T008 depends on T007
### Parallel Opportunities
- T004 (domain tests) and T005 (use case) can run in parallel after T003
- T009 and T010 can run in parallel
---
## Parallel Example: After T003
```
# These two tasks touch different packages and can run in parallel:
T004: "Acceptance + invariant tests in packages/domain/src/__tests__/add-combatant.test.ts"
T005: "Use case in packages/application/src/add-combatant-use-case.ts"
```
---
## Implementation Strategy
### MVP (This Feature)
1. T001: Add event type (foundation)
2. T002T003: Domain function + exports
3. T004 + T005 in parallel: Tests + use case
4. T006T008: Application exports → hook → UI
5. T009T010: Verify everything passes
### Validation
After T004: All 6 acceptance scenarios pass as pure-function tests
After T008: UI allows adding combatants by name
After T009: `pnpm check` passes clean (merge gate)
---
## Notes
- Follow the `advanceTurn` pattern for function signature, result type, and error handling
- CombatantId is passed in as input (generated by caller), not created inside domain
- Name is trimmed then validated; empty after trim returns DomainError with code "invalid-name"
- Commit after each task or logical group
- Total: 10 tasks (1 foundational + 7 US1 + 2 polish)