# Domain API Contract: Turn Navigation ## retreatTurn(encounter: Encounter): RetreatTurnSuccess | DomainError ### Input - `encounter`: Encounter (combatants, activeIndex, roundNumber) ### Success Output ``` { encounter: Encounter // Updated state events: DomainEvent[] // TurnRetreated, optionally RoundRetreated } ``` ### Error Cases | Condition | Error Code | Message | |-----------|------------|---------| | combatants.length === 0 | `invalid-encounter` | Cannot retreat turn on an encounter with no combatants | | roundNumber === 1 && activeIndex === 0 | `no-previous-turn` | Cannot retreat before the start of the encounter | ### Event Contracts **TurnRetreated** (always emitted on success): ``` { type: "TurnRetreated" previousCombatantId: CombatantId // Was active before retreat newCombatantId: CombatantId // Now active after retreat roundNumber: number // Round number after retreat } ``` **RoundRetreated** (emitted when crossing round boundary): ``` { type: "RoundRetreated" newRoundNumber: number // Decremented round number } ``` **Emission order**: TurnRetreated first, then RoundRetreated (when applicable). ## UI Contract: TurnNavigation Component ### Props - `encounter`: Encounter (current state) - `onAdvanceTurn`: () => void - `onRetreatTurn`: () => void ### Behavior - Previous Turn button: calls onRetreatTurn; disabled when roundNumber === 1 && activeIndex === 0, or combatants.length === 0 - Next Turn button: calls onAdvanceTurn; disabled when combatants.length === 0 - Displays: round number and active combatant name