Files
initiative/specs/012-turn-navigation/spec.md

107 lines
8.7 KiB
Markdown

# Feature Specification: Turn Navigation
**Feature Branch**: `012-turn-navigation`
**Created**: 2026-03-05
**Status**: Draft
**Input**: User description: "Introduce a previous Turn button and put both, the previous and the next turn buttons at the top of the tracker. Make the UI/UX modern and sleek. Easy to use."
## User Scenarios & Testing
### User Story 1 - Go Back to the Previous Turn (Priority: P1)
As a game master running a combat encounter, I want to go back to the previous combatant's turn so that I can correct mistakes (e.g., a forgotten action, an incorrectly skipped combatant) without restarting the encounter.
**Why this priority**: The ability to undo a turn advancement is the core new capability. Without it, game masters must work around mistakes manually, disrupting the flow of combat.
**Independent Test**: Can be fully tested as a pure state transition. Given an Encounter and a RetreatTurn action, assert the resulting Encounter state and emitted domain events.
**Acceptance Scenarios**:
1. **Given** an encounter with combatants [A, B, C], activeIndex 1, roundNumber 1, **When** RetreatTurn, **Then** activeIndex is 0, roundNumber is 1, and a TurnRetreated event is emitted with previousCombatantId B, newCombatantId A, roundNumber 1.
2. **Given** an encounter with combatants [A, B, C], activeIndex 0, roundNumber 2, **When** RetreatTurn, **Then** activeIndex is 2, roundNumber is 1, and events are emitted: TurnRetreated (previousCombatantId A, newCombatantId C, roundNumber 1) then RoundRetreated (newRoundNumber 1).
3. **Given** an encounter with combatants [A, B, C], activeIndex 0, roundNumber 1, **When** RetreatTurn, **Then** the operation MUST fail with an error. The encounter is at the very beginning -- there is no previous turn to return to.
4. **Given** an encounter with a single combatant [A], activeIndex 0, roundNumber 3, **When** RetreatTurn, **Then** activeIndex is 0, roundNumber is 2, and events are emitted: TurnRetreated then RoundRetreated (newRoundNumber 2).
5. **Given** an encounter with an empty combatant list, **When** RetreatTurn, **Then** the operation MUST fail with an invalid-encounter error. No events are emitted. State is unchanged.
---
### User Story 2 - Turn Navigation Controls at the Top of the Tracker (Priority: P1)
As a game master, I want the Previous Turn and Next Turn buttons placed prominently at the top of the encounter tracker so that I can quickly navigate turns without scrolling to the bottom of a long combatant list.
**Why this priority**: Relocating the turn controls to the top directly improves usability -- the most-used combat controls should be immediately visible and accessible.
**Independent Test**: Can be fully tested by loading the tracker with combatants and verifying that the turn navigation controls appear above the combatant list and function correctly.
**Acceptance Scenarios**:
1. **Given** the encounter tracker is displayed, **When** the user looks at the screen, **Then** the Previous Turn and Next Turn buttons are visible at the top of the tracker, above the combatant list.
2. **Given** the tracker has many combatants requiring scrolling, **When** the user scrolls down, **Then** the turn navigation controls remain accessible at the top (no need to scroll to find them).
3. **Given** the encounter is at round 1 with the first combatant active, **When** the user views the turn controls, **Then** the Previous Turn button is disabled (visually indicating it cannot be used).
4. **Given** the encounter has no combatants, **When** the user views the tracker, **Then** the turn navigation controls are hidden or disabled.
---
### User Story 3 - Modern, Sleek Turn Navigation Design (Priority: P2)
As a game master, I want the turn navigation controls to have a clean, modern design with clear visual hierarchy so that I can navigate combat intuitively and confidently.
**Why this priority**: A polished design enhances usability and reduces errors during the fast pace of combat. However, functionality comes first.
**Independent Test**: Can be fully tested by visually inspecting the turn navigation area and verifying it meets design criteria.
**Acceptance Scenarios**:
1. **Given** the turn navigation is displayed, **When** the user looks at the controls, **Then** the Previous and Next buttons are visually distinct with clear labels or icons indicating direction.
2. **Given** the encounter is in progress, **When** the user views the turn navigation area, **Then** the current round number and active combatant name are displayed alongside the navigation controls.
3. **Given** the Previous Turn action is not available (round 1, first combatant), **When** the user views the Previous button, **Then** the button appears in a disabled state that is visually distinct from the active state.
---
### Edge Cases
- What happens when retreating at the very start of the encounter (round 1, activeIndex 0)? The operation fails with an error; the Previous Turn button is disabled in this state.
- What happens when retreating past the round boundary? The round number decrements by 1 and activeIndex wraps to the last combatant.
- What happens with a single combatant at round 1? RetreatTurn fails because there is no previous turn. The Previous Turn button is disabled.
- What happens when retreating would bring the round number below 1? This cannot happen -- round 1, activeIndex 0 is the earliest possible state and is blocked.
## Requirements
### Functional Requirements
- **FR-001**: The system MUST provide a RetreatTurn operation that moves the active turn to the previous combatant in initiative order.
- **FR-002**: RetreatTurn MUST decrement activeIndex by 1. When activeIndex would go below 0, it MUST wrap to the last combatant and decrement roundNumber by 1.
- **FR-003**: RetreatTurn at round 1 with activeIndex 0 MUST fail with an error. This is the earliest possible encounter state.
- **FR-004**: RetreatTurn on an empty encounter MUST fail with an error without modifying state or emitting events.
- **FR-005**: RetreatTurn MUST emit a TurnRetreated domain event on success. When the round boundary is crossed (going backward), a RoundRetreated event MUST also be emitted, in order: TurnRetreated first, then RoundRetreated.
- **FR-006**: RetreatTurn MUST be a pure function of the current encounter state. Given identical input, output MUST be identical.
- **FR-007**: The Previous Turn and Next Turn buttons MUST be positioned at the top of the encounter tracker, above the combatant list.
- **FR-008**: The Previous Turn button MUST be disabled when the encounter is at its earliest state (round 1, first combatant active).
- **FR-009**: Both turn navigation buttons MUST be disabled or hidden when the encounter has no combatants.
- **FR-010**: The turn navigation area MUST display the current round number and the active combatant's name.
- **FR-011**: The turn navigation buttons MUST have clear directional indicators (icons, labels, or both) so the user can distinguish Previous from Next at a glance.
### Key Entities
- **Encounter**: Existing aggregate. Contains combatants, activeIndex, and roundNumber. RetreatTurn operates on this entity.
- **TurnRetreated (new domain event)**: Emitted when the turn is moved backward. Carries: previousCombatantId, newCombatantId, roundNumber.
- **RoundRetreated (new domain event)**: Emitted when retreating crosses a round boundary. Carries: newRoundNumber.
## Success Criteria
### Measurable Outcomes
- **SC-001**: A user can reverse a turn advancement in under 1 second using a single click on the Previous Turn button.
- **SC-002**: Turn navigation controls are visible without scrolling, regardless of the number of combatants in the encounter.
- **SC-003**: The Previous Turn button is correctly disabled at the earliest encounter state (round 1, first combatant), preventing invalid operations 100% of the time.
- **SC-004**: All RetreatTurn acceptance scenarios pass as deterministic, pure-function tests with no I/O dependencies.
- **SC-005**: Users can identify which direction each button navigates (forward or backward) within 1 second of viewing the controls.
## Assumptions
- RetreatTurn is the inverse of AdvanceTurn. It does not restore any other state (e.g., HP changes made during a combatant's turn are not undone). It only changes the active combatant and round number.
- The Next Turn button is relocated from the bottom action bar to the new top navigation area. The bottom action bar retains the "Add Combatant" form.
- The existing AdvanceTurn domain operation and its events remain unchanged.
- The MVP baseline does not include a full undo/redo stack. RetreatTurn is a simple backward step through initiative order, not a state history undo.
- The MVP baseline does not include keyboard shortcuts for Previous/Next Turn navigation.