6.2 KiB
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.
- T001 Add
initiativeProficiency: numberfield toCreatureinterface inpackages/domain/src/creature-types.ts - T002 Create
calculateInitiativeandformatInitiativeModifierpure functions inpackages/domain/src/initiative.ts - T003 Export new function and types from
packages/domain/src/index.ts - T004 Write unit tests for
calculateInitiativeandformatInitiativeModifierinpackages/domain/src/__tests__/initiative.test.tscovering: 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) - T005 Parse
initiative.proficiencyfrom raw 5etools JSON inapps/web/src/adapters/bestiary-adapter.ts— addinitiative?: { proficiency?: number }toRawMonsterinterface and mapm.initiative?.proficiency ?? 0toCreature.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
- T006 [US1] Add initiative display to
apps/web/src/components/stat-block.tsx— callcalculateInitiativewith creature data, render "Initiative +X (Y)" usingformatInitiativeModifier, 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
- 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.
- T008 Run
pnpm checkto verify knip, format, lint, typecheck, and all tests pass - 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 (T001–T005)
- 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
# 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)
- Complete Phase 2: Foundational (T001–T005)
- Complete Phase 3: User Story 1 (T006)
- STOP and VALIDATE: Aboleth displays "Initiative +7 (17)" in stat block
- Run
pnpm check
Incremental Delivery
- Foundational → Domain function + adapter parsing ready
- Add US1 → Initiative visible in stat block → Validate (MVP!)
- Add US2 → Layout matches MM 2024 → Validate
- 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