Files
initiative/specs/005-set-initiative/contracts/domain-api.md

58 lines
1.9 KiB
Markdown

# Domain API Contract: Set Initiative
## Function Signature
```
setInitiative(encounter, combatantId, value) → Success | DomainError
```
### Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| encounter | Encounter | Current encounter state |
| combatantId | CombatantId | Target combatant to update |
| value | integer or undefined | New initiative value, or undefined to clear |
### Success Result
| Field | Type | Description |
|-------|------|-------------|
| encounter | Encounter | New encounter with updated combatant and reordered list |
| events | DomainEvent[] | Array containing one `InitiativeSet` event |
### Error Codes
| Code | Condition |
|------|-----------|
| `combatant-not-found` | No combatant with the given id exists |
| `invalid-initiative` | Value is defined but not an integer |
### Ordering Contract
After a successful call, `encounter.combatants` is sorted such that:
1. All combatants with `initiative !== undefined` come before those with `initiative === undefined`
2. Within the "has initiative" group: sorted descending by initiative value
3. Within the "no initiative" group: original relative order preserved
4. Equal initiative values: original relative order preserved (stable sort)
### Active Turn Contract
The combatant who was active before the call remains active after:
- `encounter.activeIndex` points to the same combatant (by identity) in the new order
- This holds even if the active combatant's own initiative changes
### Invariants Preserved
- INV-1: Empty encounters remain valid (0 combatants allowed)
- INV-2: `activeIndex` remains in bounds after reorder
- INV-3: `roundNumber` is never changed by `setInitiative`
## Use Case Signature
```
setInitiativeUseCase(store, combatantId, value) → DomainEvent[] | DomainError
```
Follows the standard use case pattern: get encounter from store, call domain function, save on success, return events or error.