Files
initiative/specs/025-display-initiative/tasks.md

144 lines
6.2 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: Display Initiative
**Input**: Design documents from `/specs/025-display-initiative/`
**Prerequisites**: plan.md, spec.md, research.md, data-model.md, quickstart.md
**Tests**: Tests are included — the spec requires a pure domain function verified by layer boundary checks, and the project convention places tests in `packages/*/src/__tests__/`.
**Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story.
## 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)
- Include exact file paths in descriptions
---
## Phase 1: Setup (Shared Infrastructure)
**Purpose**: No new project setup needed — this feature extends existing packages. Skip to foundational.
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Domain types and pure functions that both user stories depend on.
**⚠️ CRITICAL**: No user story work can begin until this phase is complete.
- [x] T001 Add `initiativeProficiency: number` field to `Creature` interface in `packages/domain/src/creature-types.ts`
- [x] T002 Create `calculateInitiative` and `formatInitiativeModifier` pure functions in `packages/domain/src/initiative.ts`
- [x] T003 Export new function and types from `packages/domain/src/index.ts`
- [x] T004 Write unit tests for `calculateInitiative` and `formatInitiativeModifier` in `packages/domain/src/__tests__/initiative.test.ts` covering: positive modifier, negative modifier, zero modifier, no proficiency (multiplier 0), single proficiency (multiplier 1), expertise (multiplier 2), passive initiative calculation, sign formatting with U+2212 minus, and a guard test verifying the function is not called / returns no result for combatants without bestiary creature data (FR-006)
- [x] T005 Parse `initiative.proficiency` from raw 5etools JSON in `apps/web/src/adapters/bestiary-adapter.ts` — add `initiative?: { proficiency?: number }` to `RawMonster` interface and map `m.initiative?.proficiency ?? 0` to `Creature.initiativeProficiency`
**Checkpoint**: Domain function works and adapter provides initiative data. `pnpm check` passes.
---
## Phase 3: User Story 1 — View Initiative in Stat Block (Priority: P1) 🎯 MVP
**Goal**: Display calculated initiative modifier and passive initiative in the stat block header area.
**Independent Test**: Select any creature from the bestiary; verify the initiative line appears with correct calculated value (e.g., Aboleth shows "Initiative +7 (17)").
### Implementation for User Story 1
- [x] T006 [US1] Add initiative display to `apps/web/src/components/stat-block.tsx` — call `calculateInitiative` with creature data, render "Initiative +X (Y)" using `formatInitiativeModifier`, and conditionally hide the line when the combatant has no bestiary data
**Checkpoint**: Creatures display initiative in stat block. Aboleth shows "Initiative +7 (17)". `pnpm check` passes.
---
## Phase 4: User Story 2 — Initiative Position Matches MM 2024 Layout (Priority: P2)
**Goal**: Initiative appears adjacent to AC on the same line, matching the Monster Manual 2024 stat block layout.
**Independent Test**: Compare stat block layout to MM 2024 screenshot; initiative appears on the AC line before HP.
### Implementation for User Story 2
- [x] T007 [US2] Refine initiative positioning in `apps/web/src/components/stat-block.tsx` — adjust CSS/layout to place the initiative text on the same line as AC with appropriate spacing, matching the "AC 17 Initiative +7 (17)" format from MM 2024
**Checkpoint**: Layout matches MM 2024 format. `pnpm check` passes.
---
## Phase 5: Polish & Cross-Cutting Concerns
**Purpose**: Final validation across all stories.
- [x] T008 Run `pnpm check` to verify knip, format, lint, typecheck, and all tests pass
- [x] T009 Spot-check initiative values for several creatures against D&D Beyond: Aboleth (+7), and at least two creatures with no initiative proficiency and one with single proficiency
---
## Dependencies & Execution Order
### Phase Dependencies
- **Foundational (Phase 2)**: No dependencies — can start immediately
- **User Story 1 (Phase 3)**: Depends on Phase 2 completion (T001T005)
- **User Story 2 (Phase 4)**: Depends on Phase 3 completion (T006) — refines the layout from US1
- **Polish (Phase 5)**: Depends on all user stories being complete
### User Story Dependencies
- **User Story 1 (P1)**: Depends only on foundational phase. Core MVP.
- **User Story 2 (P2)**: Depends on US1 — refines the positioning of the initiative display added in US1.
### Within Each User Story
- Foundational types/functions before UI integration
- Tests written alongside domain functions (T004 with T002)
### Parallel Opportunities
- T002 and T005 can run in parallel (different packages, no dependencies between them)
- T001 must complete before T002 and T005 (type definition needed by both)
- T003 must follow T002 (exports the new function)
- T004 can run in parallel with T005 (different packages)
---
## Parallel Example: Foundational Phase
```bash
# After T001 (type change) completes, launch in parallel:
Task T002: "Create calculateInitiative in packages/domain/src/initiative.ts"
Task T005: "Parse initiative.proficiency in apps/web/src/adapters/bestiary-adapter.ts"
# After T002, launch in parallel:
Task T003: "Export from packages/domain/src/index.ts"
Task T004: "Write tests in packages/domain/src/__tests__/initiative.test.ts"
```
---
## Implementation Strategy
### MVP First (User Story 1 Only)
1. Complete Phase 2: Foundational (T001T005)
2. Complete Phase 3: User Story 1 (T006)
3. **STOP and VALIDATE**: Aboleth displays "Initiative +7 (17)" in stat block
4. Run `pnpm check`
### Incremental Delivery
1. Foundational → Domain function + adapter parsing ready
2. Add US1 → Initiative visible in stat block → Validate (MVP!)
3. Add US2 → Layout matches MM 2024 → Validate
4. Polish → Cross-creature spot-checks
---
## Notes
- [P] tasks = different files, no dependencies
- [Story] label maps task to specific user story for traceability
- US2 intentionally depends on US1 since it refines the same UI element
- Commit after each task or logical group
- The entire feature is 9 tasks — small enough for sequential execution