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

47 lines
1.9 KiB
Markdown

# 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
```bash
pnpm check # Must pass (knip + format + lint + typecheck + test)
```