Files
initiative/specs/013-hp-status-indicators/quickstart.md

1.9 KiB

Quickstart: HP Status Indicators

Feature: 013-hp-status-indicators

Overview

Add a pure domain function deriveHpStatus and apply visual status indicators (color treatments) to combatant rows in the encounter tracker.

Key Files

File Action Purpose
packages/domain/src/hp-status.ts CREATE Pure function deriveHpStatus + HpStatus type
packages/domain/src/__tests__/hp-status.test.ts CREATE Unit tests for all status thresholds and edge cases
packages/domain/src/index.ts MODIFY Export deriveHpStatus and HpStatus
apps/web/src/components/combatant-row.tsx MODIFY Call deriveHpStatus and apply conditional CSS classes

Implementation Steps

  1. Domain function (packages/domain/src/hp-status.ts):

    • Define type HpStatus = "healthy" | "bloodied" | "unconscious"
    • Implement deriveHpStatus(currentHp: number | undefined, maxHp: number | undefined): HpStatus | undefined
    • Return undefined if either input is undefined
    • Check currentHp <= 0 first (unconscious), then currentHp < maxHp / 2 (bloodied), else healthy
  2. Tests (packages/domain/src/__tests__/hp-status.test.ts):

    • Healthy: currentHp >= maxHp/2
    • Bloodied: 0 < currentHp < maxHp/2
    • Unconscious: currentHp <= 0 (including negative)
    • Undefined inputs: returns undefined
    • Edge cases: maxHp=1, maxHp=2, odd maxHp, currentHp > maxHp
  3. Export (packages/domain/src/index.ts):

    • Add export { type HpStatus, deriveHpStatus } from "./hp-status.js"
  4. UI styling (apps/web/src/components/combatant-row.tsx):

    • Import deriveHpStatus from @initiative/domain
    • Call it with combatant's currentHp and maxHp
    • Apply to HP text: text-amber-400 for bloodied, text-red-400 for unconscious
    • Apply to row: opacity-50 for unconscious combatants

Validation

pnpm check  # Must pass (knip + format + lint + typecheck + test)