Implement the 014-inline-hp-delta feature that replaces the damage/heal mode toggle with explicit action buttons and Enter-to-damage keyboard shortcut
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
34
specs/014-inline-hp-delta/checklists/requirements.md
Normal file
34
specs/014-inline-hp-delta/checklists/requirements.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Specification Quality Checklist: Inline HP Delta Input
|
||||
|
||||
**Purpose**: Validate specification completeness and quality before proceeding to planning
|
||||
**Created**: 2026-03-05
|
||||
**Feature**: [spec.md](../spec.md)
|
||||
|
||||
## Content Quality
|
||||
|
||||
- [x] No implementation details (languages, frameworks, APIs)
|
||||
- [x] Focused on user value and business needs
|
||||
- [x] Written for non-technical stakeholders
|
||||
- [x] All mandatory sections completed
|
||||
|
||||
## Requirement Completeness
|
||||
|
||||
- [x] No [NEEDS CLARIFICATION] markers remain
|
||||
- [x] Requirements are testable and unambiguous
|
||||
- [x] Success criteria are measurable
|
||||
- [x] Success criteria are technology-agnostic (no implementation details)
|
||||
- [x] All acceptance scenarios are defined
|
||||
- [x] Edge cases are identified
|
||||
- [x] Scope is clearly bounded
|
||||
- [x] Dependencies and assumptions identified
|
||||
|
||||
## Feature Readiness
|
||||
|
||||
- [x] All functional requirements have clear acceptance criteria
|
||||
- [x] User scenarios cover primary flows
|
||||
- [x] Feature meets measurable outcomes defined in Success Criteria
|
||||
- [x] No implementation details leak into specification
|
||||
|
||||
## Notes
|
||||
|
||||
- All items pass. Spec is ready for `/speckit.clarify` or `/speckit.plan`.
|
||||
42
specs/014-inline-hp-delta/data-model.md
Normal file
42
specs/014-inline-hp-delta/data-model.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# Data Model: Inline HP Delta Input
|
||||
|
||||
## No data model changes
|
||||
|
||||
This feature does not modify any domain entities, events, or state transitions. The existing data model fully supports the new UI:
|
||||
|
||||
### Existing Entities (unchanged)
|
||||
|
||||
**Combatant**
|
||||
- `id`: CombatantId (branded string)
|
||||
- `name`: string
|
||||
- `initiative?`: number
|
||||
- `maxHp?`: number
|
||||
- `currentHp?`: number
|
||||
|
||||
**Encounter**
|
||||
- `combatants`: readonly Combatant[]
|
||||
- `activeIndex`: number
|
||||
- `roundNumber`: number
|
||||
|
||||
### Existing Domain Function (unchanged)
|
||||
|
||||
**adjustHp(encounter, combatantId, delta) -> AdjustHpSuccess | DomainError**
|
||||
- Negative delta = damage, positive delta = heal
|
||||
- Clamps result to [0, maxHp]
|
||||
- Emits `CurrentHpAdjusted` event
|
||||
|
||||
### Existing Domain Event (unchanged)
|
||||
|
||||
**CurrentHpAdjusted**
|
||||
- `combatantId`: CombatantId
|
||||
- `previousHp`: number
|
||||
- `newHp`: number
|
||||
- `delta`: number
|
||||
|
||||
### UI State Changes
|
||||
|
||||
The only state change is in the QuickHpInput component:
|
||||
- **Removed**: `mode: "damage" | "heal"` state variable
|
||||
- **Kept**: `value: string` state variable for the input field
|
||||
|
||||
The action (damage vs heal) is now determined at invocation time by which button/key triggered it, not by a stored mode.
|
||||
70
specs/014-inline-hp-delta/plan.md
Normal file
70
specs/014-inline-hp-delta/plan.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Implementation Plan: Inline HP Delta Input
|
||||
|
||||
**Branch**: `014-inline-hp-delta` | **Date**: 2026-03-05 | **Spec**: [spec.md](./spec.md)
|
||||
**Input**: Feature specification from `/specs/014-inline-hp-delta/spec.md`
|
||||
|
||||
## Summary
|
||||
|
||||
Replace the existing QuickHpInput component (which uses a damage/heal mode toggle) with a simpler inline HP delta input. Users type a number and press Enter to apply damage by default, or click explicit damage/heal buttons. No domain changes needed -- the existing `adjustHp` pure function already accepts positive and negative deltas. This is a UI-only refactor of the quick HP input component.
|
||||
|
||||
## Technical Context
|
||||
|
||||
**Language/Version**: TypeScript 5.8 (strict mode, verbatimModuleSyntax)
|
||||
**Primary Dependencies**: React 19, Vite 6, Tailwind CSS v4, shadcn/ui-style components, Lucide React (icons)
|
||||
**Storage**: N/A (no storage changes -- existing localStorage persistence unchanged)
|
||||
**Testing**: Vitest
|
||||
**Target Platform**: Web browser (local-first, single-user)
|
||||
**Project Type**: Web application (monorepo: domain + application + web adapter)
|
||||
**Performance Goals**: Instant feedback on HP adjustment (<100ms perceived)
|
||||
**Constraints**: Local-first, single-user MVP
|
||||
**Scale/Scope**: Single encounter screen, ~1-20 combatants
|
||||
|
||||
## Constitution Check
|
||||
|
||||
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
|
||||
|
||||
| Principle | Status | Notes |
|
||||
|-----------|--------|-------|
|
||||
| I. Deterministic Domain Core | PASS | No domain changes. Existing `adjustHp` is a pure function. |
|
||||
| II. Layered Architecture | PASS | Change is entirely in the adapter layer (web UI). Domain and application layers unchanged. |
|
||||
| III. Agent Boundary | N/A | No agent features involved. |
|
||||
| IV. Clarification-First | PASS | Spec is clear; no ambiguities remain. |
|
||||
| V. Escalation Gates | PASS | Feature is within spec scope -- replacing existing UI with simplified version. |
|
||||
| VI. MVP Baseline Language | PASS | Assumptions use "MVP baseline does not include" language. |
|
||||
| VII. No Gameplay Rules | PASS | No gameplay mechanics in this feature. |
|
||||
|
||||
**Gate result**: PASS -- all principles satisfied.
|
||||
|
||||
## Project Structure
|
||||
|
||||
### Documentation (this feature)
|
||||
|
||||
```text
|
||||
specs/014-inline-hp-delta/
|
||||
├── plan.md # This file
|
||||
├── research.md # Phase 0 output
|
||||
├── data-model.md # Phase 1 output
|
||||
├── quickstart.md # Phase 1 output
|
||||
└── tasks.md # Phase 2 output (/speckit.tasks command)
|
||||
```
|
||||
|
||||
### Source Code (repository root)
|
||||
|
||||
```text
|
||||
packages/domain/src/
|
||||
├── adjust-hp.ts # Existing — no changes needed
|
||||
├── types.ts # Existing — no changes needed
|
||||
└── __tests__/adjust-hp.test.ts # Existing — no changes needed
|
||||
|
||||
packages/application/src/
|
||||
└── adjust-hp-use-case.ts # Existing — no changes needed
|
||||
|
||||
apps/web/src/
|
||||
├── components/
|
||||
│ ├── quick-hp-input.tsx # MODIFY — replace mode toggle with damage/heal buttons
|
||||
│ └── combatant-row.tsx # Existing — integration point (no changes expected)
|
||||
└── hooks/
|
||||
└── use-encounter.ts # Existing — no changes needed
|
||||
```
|
||||
|
||||
**Structure Decision**: Existing monorepo structure (domain → application → web adapter) is used. This feature only modifies the web adapter layer, specifically the `quick-hp-input.tsx` component. No new files or packages needed.
|
||||
43
specs/014-inline-hp-delta/quickstart.md
Normal file
43
specs/014-inline-hp-delta/quickstart.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Quickstart: Inline HP Delta Input
|
||||
|
||||
## What changes
|
||||
|
||||
One file: `apps/web/src/components/quick-hp-input.tsx`
|
||||
|
||||
The QuickHpInput component is refactored from a mode-toggle design to an explicit-button design:
|
||||
|
||||
**Before** (011-quick-hp-input):
|
||||
- Mode toggle button (Sword/Heart icon) + numeric input
|
||||
- User switches mode, then types number, then presses Enter
|
||||
- Mode state determines whether delta is positive or negative
|
||||
|
||||
**After** (014-inline-hp-delta):
|
||||
- Numeric input + damage button (Sword) + heal button (Heart)
|
||||
- Enter key always applies damage (negative delta)
|
||||
- Damage button applies damage (negative delta)
|
||||
- Heal button applies healing (positive delta)
|
||||
- No mode state
|
||||
|
||||
## How to implement
|
||||
|
||||
1. Remove the `mode` state variable and the toggle button
|
||||
2. Replace with two action buttons (damage + heal) alongside the input
|
||||
3. Enter key handler calls `onAdjustHp(combatantId, -n)` (always damage)
|
||||
4. Damage button calls `onAdjustHp(combatantId, -n)`
|
||||
5. Heal button calls `onAdjustHp(combatantId, +n)`
|
||||
6. Remove Tab key override (restore default browser behavior)
|
||||
7. Clear input after any successful apply
|
||||
|
||||
## How to verify
|
||||
|
||||
```bash
|
||||
pnpm check # Must pass (knip + format + lint + typecheck + test)
|
||||
```
|
||||
|
||||
Manual verification:
|
||||
1. Set a combatant's max HP to 20 (currentHp initializes to 20)
|
||||
2. Type 7 in the delta input, press Enter → HP should show 13
|
||||
3. Type 5 in the delta input, click heal button → HP should show 18
|
||||
4. Type 3 in the delta input, click damage button → HP should show 15
|
||||
5. Verify input clears after each action
|
||||
6. Verify no mode toggle exists in the UI
|
||||
37
specs/014-inline-hp-delta/research.md
Normal file
37
specs/014-inline-hp-delta/research.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Research: Inline HP Delta Input
|
||||
|
||||
## R-001: Can the existing domain function support the new UI?
|
||||
|
||||
**Decision**: Yes -- the existing `adjustHp(encounter, combatantId, delta)` function already accepts any integer delta. Negative deltas deal damage, positive deltas heal. No domain changes required.
|
||||
|
||||
**Rationale**: The domain function is already delta-based and mode-agnostic. The current QuickHpInput component translates its damage/heal mode into a signed delta before calling `onAdjustHp`. The new UI simply changes how the sign is determined (Enter = negative, heal button = positive, damage button = negative).
|
||||
|
||||
**Alternatives considered**: None -- the domain API is already ideal for this use case.
|
||||
|
||||
## R-002: UI pattern for inline delta with explicit action buttons
|
||||
|
||||
**Decision**: Replace the mode toggle button + input with a single numeric input flanked by two small icon buttons (damage on left, heal on right). Enter key applies damage by default.
|
||||
|
||||
**Rationale**: This eliminates the mode toggle state entirely. Users always see both options. The most common action (damage) is the keyboard default. Less common action (heal) requires a button click -- still only 2-3 interactions.
|
||||
|
||||
**Alternatives considered**:
|
||||
- Separate damage and heal inputs per combatant: rejected as too much UI clutter for the compact row layout.
|
||||
- Negative number = damage, positive = heal (user types sign): rejected as slower (extra keystroke) and error-prone.
|
||||
|
||||
## R-003: What happens to the Tab key behavior?
|
||||
|
||||
**Decision**: Remove the Tab key override. Tab returns to its default browser behavior (move focus to next element).
|
||||
|
||||
**Rationale**: The Tab key was previously overridden to toggle between damage/heal modes. Since modes no longer exist, Tab should not be intercepted. This improves accessibility and standard keyboard navigation.
|
||||
|
||||
**Alternatives considered**: None -- restoring default Tab behavior is the obvious choice.
|
||||
|
||||
## R-004: Button icons and visual distinction
|
||||
|
||||
**Decision**: Use Sword icon (red) for damage button and Heart icon (green) for heal button, consistent with the existing color scheme from the mode toggle.
|
||||
|
||||
**Rationale**: These icons are already imported (Lucide React) and used in the current mode toggle. Users familiar with the current UI will recognize them. Red = damage, green = heal is a universal convention.
|
||||
|
||||
**Alternatives considered**:
|
||||
- Minus/Plus icons: too generic, less evocative of the D&D context.
|
||||
- Text labels ("Dmg"/"Heal"): take more space than icons in the compact row.
|
||||
104
specs/014-inline-hp-delta/spec.md
Normal file
104
specs/014-inline-hp-delta/spec.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# Feature Specification: Inline HP Delta Input
|
||||
|
||||
**Feature Branch**: `014-inline-hp-delta`
|
||||
**Created**: 2026-03-05
|
||||
**Status**: Draft
|
||||
**Input**: User description: "change the quick hp input to be an inline HP delta input per combatant. Users type a number and press Enter to apply damage by default, or click small damage/heal buttons to apply the value explicitly. Clear the input after applying. No toggle for damage and heal anymore."
|
||||
|
||||
## User Scenarios & Testing
|
||||
|
||||
### User Story 1 - Apply Damage via Enter Key (Priority: P1)
|
||||
|
||||
As a game master in the heat of combat, I want to type a damage number and press Enter to immediately subtract it from a combatant's HP, so that damage application is as fast as possible with minimal interaction.
|
||||
|
||||
**Why this priority**: Damage is the most frequent HP change during combat. Enter-to-damage is the fastest possible workflow for the most common action.
|
||||
|
||||
**Independent Test**: Can be fully tested by having a combatant with HP, typing a number, pressing Enter, and verifying HP decreases.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** a combatant has 20/20 HP, **When** the user types 7 into the delta input and presses Enter, **Then** current HP decreases to 13.
|
||||
2. **Given** a combatant has 10/20 HP, **When** the user types 15 and presses Enter, **Then** current HP is clamped to 0 (not negative).
|
||||
3. **Given** a combatant has 20/20 HP, **When** the user types a number and presses Enter, **Then** the input field clears and is ready for the next entry.
|
||||
4. **Given** a combatant has 5/20 HP, **When** the user types 0 and presses Enter, **Then** the input is rejected and HP remains unchanged.
|
||||
|
||||
---
|
||||
|
||||
### User Story 2 - Apply Damage or Heal via Explicit Buttons (Priority: P1)
|
||||
|
||||
As a game master, I want small damage and heal buttons next to the input so that I can explicitly choose whether to apply the entered value as damage or healing.
|
||||
|
||||
**Why this priority**: While Enter defaults to damage, users still need a way to heal. Explicit buttons remove ambiguity and eliminate the need for a mode toggle.
|
||||
|
||||
**Independent Test**: Can be fully tested by typing a number and clicking the heal button, verifying HP increases.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** a combatant has 10/20 HP and the user has typed 5, **When** the user clicks the heal button, **Then** current HP increases to 15 and the input clears.
|
||||
2. **Given** a combatant has 18/20 HP and the user has typed 10, **When** the user clicks the heal button, **Then** current HP is clamped to 20 (max HP) and the input clears.
|
||||
3. **Given** a combatant has 20/20 HP and the user has typed 7, **When** the user clicks the damage button, **Then** current HP decreases to 13 and the input clears.
|
||||
4. **Given** a combatant has 0/20 HP and the user has typed 8, **When** the user clicks the heal button, **Then** current HP increases to 8 and the input clears.
|
||||
|
||||
---
|
||||
|
||||
### User Story 3 - Keyboard-Driven Workflow (Priority: P2)
|
||||
|
||||
As a game master, I want to use only the keyboard to apply damage quickly so that I can keep up with fast-paced combat without reaching for the mouse.
|
||||
|
||||
**Why this priority**: Speed is critical during combat encounters. The keyboard workflow should cover the most common action (damage) end-to-end.
|
||||
|
||||
**Independent Test**: Can be fully tested by using only keyboard interactions to apply damage values.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** the delta input is focused, **When** the user types a number and presses Enter, **Then** damage is applied immediately and the input clears.
|
||||
2. **Given** the delta input is focused, **When** the user presses Escape, **Then** the input value is cleared without applying any change.
|
||||
|
||||
---
|
||||
|
||||
### Edge Cases
|
||||
|
||||
- What happens when the user enters a non-numeric value? The input only accepts digits; non-numeric characters are rejected.
|
||||
- What happens when the user enters a very large number (e.g., 99999)? The value is applied normally; clamping to 0 or max HP ensures no invalid state.
|
||||
- What happens when the combatant has no HP tracking (no max HP set)? The delta input is not shown for that combatant.
|
||||
- What happens when the user submits an empty input? No change is applied; the input remains ready for the next entry.
|
||||
- What happens when the user clicks a button with an empty input? No change is applied.
|
||||
- What happens when the user rapidly enters multiple values? Each entry is applied sequentially; no values are lost or merged.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Functional Requirements
|
||||
|
||||
- **FR-001**: The system MUST provide an inline numeric input per combatant for entering HP delta amounts.
|
||||
- **FR-002**: When the user types a number and presses Enter, the system MUST apply the value as damage (subtract from current HP), clamping to 0.
|
||||
- **FR-003**: The system MUST provide a small damage button that applies the entered value as damage (subtract from current HP), clamping to 0.
|
||||
- **FR-004**: The system MUST provide a small heal button that applies the entered value as healing (add to current HP), clamping to max HP.
|
||||
- **FR-005**: After any value is applied (via Enter or button click), the input MUST clear automatically.
|
||||
- **FR-006**: The input MUST only accept positive integers. Zero, negative numbers, and non-numeric input MUST be rejected.
|
||||
- **FR-007**: Pressing Escape while the input is focused MUST clear the input value without applying any change.
|
||||
- **FR-008**: The delta input MUST only be available for combatants that have HP tracking active (max HP is set).
|
||||
- **FR-009**: There MUST NOT be a toggle between damage and heal modes. The input is mode-free; the action is determined by which button is clicked or by pressing Enter (which defaults to damage).
|
||||
- **FR-010**: Direct editing of the current HP absolute value MUST remain available alongside the delta input.
|
||||
- **FR-011**: The damage and heal buttons MUST be visually distinct from each other (e.g., different colors or icons).
|
||||
|
||||
### Key Entities
|
||||
|
||||
- **HP Delta**: A numeric value entered by the user, applied as either damage or healing to a combatant's current HP.
|
||||
|
||||
## Success Criteria
|
||||
|
||||
### Measurable Outcomes
|
||||
|
||||
- **SC-001**: A user can apply damage to a combatant in 2 interactions or fewer (type number + press Enter).
|
||||
- **SC-002**: A user can apply healing to a combatant in 3 interactions or fewer (type number + click heal button).
|
||||
- **SC-003**: Current HP never exceeds max HP or drops below 0 after any delta input operation.
|
||||
- **SC-004**: No mode toggle exists in the interface -- damage and heal are always available as distinct actions.
|
||||
|
||||
## Assumptions
|
||||
|
||||
- This feature replaces the existing quick HP input (011-quick-hp-input) which used a damage/heal mode toggle. The toggle is removed in favor of explicit actions.
|
||||
- Enter key defaults to damage because damage is the most frequent HP change during combat.
|
||||
- Direct HP entry (absolute value) remains available for overrides and corrections.
|
||||
- There is no undo/redo for HP changes in the MVP baseline.
|
||||
- There is no damage type tracking (fire, slashing, etc.) in the MVP baseline.
|
||||
- There is no hit log or damage history in the MVP baseline.
|
||||
143
specs/014-inline-hp-delta/tasks.md
Normal file
143
specs/014-inline-hp-delta/tasks.md
Normal file
@@ -0,0 +1,143 @@
|
||||
# Tasks: Inline HP Delta Input
|
||||
|
||||
**Input**: Design documents from `/specs/014-inline-hp-delta/`
|
||||
**Prerequisites**: plan.md, spec.md, research.md, data-model.md, quickstart.md
|
||||
|
||||
**Tests**: Tests are included because domain tests already exist and the spec has testable acceptance scenarios.
|
||||
|
||||
**Organization**: Tasks are grouped by user story. US1 and US2 share the same component refactor but have distinct acceptance criteria.
|
||||
|
||||
## 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, US3)
|
||||
- Include exact file paths in descriptions
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Setup
|
||||
|
||||
**Purpose**: No new project setup needed. This feature modifies a single existing component.
|
||||
|
||||
- [x] T001 Verify existing `pnpm check` passes before starting work (run from repo root)
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Foundational
|
||||
|
||||
**Purpose**: No foundational changes needed. The existing `adjustHp` domain function, `adjustHpUseCase`, and `useEncounter` hook all support the new UI without modification.
|
||||
|
||||
**Checkpoint**: No blocking prerequisites -- proceed directly to user story implementation.
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: User Story 1 - Apply Damage via Enter Key (Priority: P1) MVP
|
||||
|
||||
**Goal**: Users type a number and press Enter to apply damage. Input clears after applying.
|
||||
|
||||
**Independent Test**: Set a combatant to 20/20 HP, type 7, press Enter, verify HP shows 13 and input is cleared.
|
||||
|
||||
### Tests for User Story 1
|
||||
|
||||
- [x] T002 [US1] Write acceptance tests for Enter-to-damage behavior in `packages/domain/src/__tests__/adjust-hp.test.ts` -- verify existing domain tests cover: damage subtraction, clamp to 0, zero rejection. Add any missing scenarios from spec (US1 scenarios 1-4).
|
||||
|
||||
### Implementation for User Story 1
|
||||
|
||||
- [x] T003 [US1] Refactor `apps/web/src/components/quick-hp-input.tsx`: remove `Mode` type, remove `mode` state variable, remove mode toggle button, remove Tab key override for mode switching. Keep the numeric input and the `value` state variable.
|
||||
- [x] T004 [US1] Update Enter key handler in `apps/web/src/components/quick-hp-input.tsx`: when user presses Enter with a valid positive integer, call `onAdjustHp(combatantId, -n)` (always damage), then clear input. Reject zero, empty, and non-numeric values.
|
||||
**Checkpoint**: At this point, Enter-to-damage works. No heal capability yet (added in US2). (Escape key verification merged into T009.)
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: User Story 2 - Apply Damage or Heal via Explicit Buttons (Priority: P1)
|
||||
|
||||
**Goal**: Small damage and heal buttons next to the input allow explicit action choice.
|
||||
|
||||
**Independent Test**: Set a combatant to 10/20 HP, type 5, click heal button, verify HP shows 15 and input clears.
|
||||
|
||||
### Implementation for User Story 2
|
||||
|
||||
- [x] T006 [US2] Add damage button (Sword icon, red styling) to `apps/web/src/components/quick-hp-input.tsx` that reads the current input value and calls `onAdjustHp(combatantId, -n)`, then clears input. Button is disabled when input is empty or invalid.
|
||||
- [x] T007 [US2] Add heal button (Heart icon, green styling) to `apps/web/src/components/quick-hp-input.tsx` that reads the current input value and calls `onAdjustHp(combatantId, +n)`, then clears input. Button is disabled when input is empty or invalid.
|
||||
- [x] T008 [US2] Ensure damage and heal buttons are visually distinct (red vs green, Sword vs Heart icons) and match existing Tailwind/shadcn styling conventions in `apps/web/src/components/quick-hp-input.tsx`.
|
||||
|
||||
**Checkpoint**: Both Enter-to-damage and explicit damage/heal buttons work. Full feature is functional.
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: User Story 3 - Keyboard-Driven Workflow (Priority: P2)
|
||||
|
||||
**Goal**: Keyboard-only workflow for damage is seamless (type + Enter). Escape clears without applying.
|
||||
|
||||
**Independent Test**: Focus input, type number, press Enter -- damage applied. Focus input, type number, press Escape -- input cleared, no HP change.
|
||||
|
||||
### Implementation for User Story 3
|
||||
|
||||
- [x] T009 [US3] Verify that the refactored component in `apps/web/src/components/quick-hp-input.tsx` supports full keyboard workflow: focus input, type digits, Enter applies damage, Escape clears. Confirm Tab key is NOT overridden (default browser focus behavior). Also verify FR-008: delta input is not rendered for combatants without HP tracking (no max HP set). Fix any issues found.
|
||||
|
||||
**Checkpoint**: All user stories functional and keyboard workflow verified.
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: Polish & Cross-Cutting Concerns
|
||||
|
||||
**Purpose**: Final validation across all stories.
|
||||
|
||||
- [x] T010 Run `pnpm check` (knip + format + lint + typecheck + test) and fix any issues
|
||||
- [ ] T011 Run quickstart.md manual verification steps against the dev server (`pnpm --filter web dev`). Also verify FR-010: direct editing of the current HP absolute value still works alongside the delta input.
|
||||
|
||||
---
|
||||
|
||||
## Dependencies & Execution Order
|
||||
|
||||
### Phase Dependencies
|
||||
|
||||
- **Setup (Phase 1)**: No dependencies
|
||||
- **Foundational (Phase 2)**: N/A (no foundational tasks)
|
||||
- **US1 (Phase 3)**: Depends on Phase 1 passing
|
||||
- **US2 (Phase 4)**: Depends on T003 (component refactor from US1)
|
||||
- **US3 (Phase 5)**: Depends on T004 (Enter key handler from US1)
|
||||
- **Polish (Phase 6)**: Depends on all user stories complete
|
||||
|
||||
### User Story Dependencies
|
||||
|
||||
- **User Story 1 (P1)**: No dependencies on other stories. Core refactor.
|
||||
- **User Story 2 (P1)**: Depends on US1 component refactor (T003) since buttons are added to the refactored component.
|
||||
- **User Story 3 (P2)**: Depends on US1 (T004) since it validates the keyboard workflow established there.
|
||||
|
||||
### Within Each User Story
|
||||
|
||||
- Tests/verification before or alongside implementation
|
||||
- Core logic before visual polish
|
||||
- Commit after each task or logical group
|
||||
|
||||
### Parallel Opportunities
|
||||
|
||||
- T006 and T007 (damage button and heal button) can be implemented in parallel since they are independent click handlers in the same file -- but given they're both small additions to one component, sequential is equally efficient.
|
||||
|
||||
---
|
||||
|
||||
## Implementation Strategy
|
||||
|
||||
### MVP First (User Story 1 Only)
|
||||
|
||||
1. T001: Verify clean state
|
||||
2. T002: Verify/add domain tests
|
||||
3. T003-T005: Refactor component, Enter-to-damage, verify Escape
|
||||
4. **STOP and VALIDATE**: Type number + Enter applies damage, input clears
|
||||
|
||||
### Incremental Delivery
|
||||
|
||||
1. US1: Enter-to-damage works (MVP)
|
||||
2. US2: Add damage/heal buttons (full feature)
|
||||
3. US3: Verify keyboard workflow (polish)
|
||||
4. T010-T011: Final quality gate
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- This is a single-component refactor. All implementation tasks modify `apps/web/src/components/quick-hp-input.tsx`.
|
||||
- No domain or application layer changes needed.
|
||||
- The existing `adjustHp` domain function already handles positive (heal) and negative (damage) deltas with clamping.
|
||||
- Total: 10 tasks across 6 phases (T005 merged into T009).
|
||||
Reference in New Issue
Block a user