# Research: Turn Navigation ## R1: RetreatTurn Domain Pattern **Decision**: Implement RetreatTurn as a mirror of the existing AdvanceTurn pattern -- a pure function that accepts an Encounter and returns the updated Encounter plus domain events, or a DomainError. **Rationale**: The existing AdvanceTurn function (`packages/domain/src/advance-turn.ts`) establishes a clear pattern: pure function, value-based error handling via DomainError, domain events returned as data. RetreatTurn is its exact inverse, so following the same pattern maintains consistency and testability. **Alternatives considered**: - Generic "move turn" function with direction parameter: Rejected because AdvanceTurn already exists and changing its signature would break the existing API for no benefit. Two focused functions are simpler than one parameterized function. - Undo/redo stack: Out of scope per spec assumptions. RetreatTurn is a positional operation, not a state-history undo. ## R2: Boundary Guard (Cannot Retreat Before Start) **Decision**: RetreatTurn returns a DomainError when `roundNumber === 1 && activeIndex === 0`. This is the earliest possible encounter state. **Rationale**: There is no meaningful "previous turn" before the encounter starts. Allowing retreat past this point would require round 0 or negative rounds, which violates INV-3 (roundNumber >= 1). The spec explicitly requires this guard (FR-003, acceptance scenario 3). **Alternatives considered**: - Silently no-op: Rejected because domain operations should be explicit about failures (constitution principle I). - Allow round 0 as "setup" round: Out of scope, would require spec amendment. ## R3: New Domain Events (TurnRetreated, RoundRetreated) **Decision**: Introduce two new domain event types: `TurnRetreated` and `RoundRetreated`, mirroring the existing `TurnAdvanced` and `RoundAdvanced` event shapes. **Rationale**: The existing event system uses discriminated unions with a `type` field. Retreat events should be distinct from advance events so consumers can differentiate the direction of navigation. The shapes mirror their forward counterparts for consistency. **Alternatives considered**: - Reuse TurnAdvanced/RoundAdvanced with a `direction` field: Rejected because it changes the existing event shape (breaking change) and complicates event consumers that only care about forward progression. ## R4: UI Placement -- Turn Navigation at Top **Decision**: Create a new `TurnNavigation` component positioned between the header and the combatant list. Move the Next Turn button out of ActionBar into this new component. ActionBar retains only the Add Combatant form. **Rationale**: The spec requires turn controls at the top of the tracker (FR-007). The current Next Turn button lives in ActionBar at the bottom. Splitting concerns (turn navigation vs. combatant management) improves the component structure and matches the spec's UX intent. **Alternatives considered**: - Keep Next Turn in ActionBar and duplicate at top: Rejected -- redundant controls create confusion. - Move entire ActionBar to top: Rejected -- the Add Combatant form is secondary to turn navigation and should not compete for top-of-page prominence. ## R5: Disabled State for Previous Turn Button **Decision**: The Previous Turn button renders in a disabled state (using the existing Button component's `disabled` prop) when the encounter is at round 1, activeIndex 0, or when there are no combatants. **Rationale**: The spec requires visual indication that Previous Turn is unavailable (FR-008, FR-009). Using the existing Button disabled styling from shadcn/ui-style components ensures visual consistency. **Alternatives considered**: - Hide the button entirely when unavailable: Rejected -- hiding causes layout shifts and makes the control harder to discover.