# Store Directory

Pinia stores for centralized state management. All stores use Composition API syntax.

## Available Stores

### game.ts - Active Game State
**Purpose**: Central state for real-time gameplay, synchronized via WebSocket.

**Key State**:
```typescript
gameState: GameState | null       // Full game state from backend
homeLineup: Lineup[]              // Cached home team roster
awayLineup: Lineup[]              // Cached away team roster
playHistory: PlayResult[]         // Play-by-play history
currentDecisionPrompt: DecisionPrompt | null
pendingRoll: RollData | null      // Manual mode dice roll
```

**Critical Getters**:
```typescript
// Team determination (mirrors backend logic)
battingTeamId    // away if top, home if bottom
fieldingTeamId   // home if top, away if bottom

// Current players (LineupPlayerState)
currentBatter
currentPitcher
currentCatcher

// Decision state
needsDefensiveDecision
needsOffensiveDecision
canRollDice
canSubmitOutcome
```

**Player Lookup Method**:
```typescript
// Critical: Joins LineupPlayerState with full Lineup data
findPlayerInLineup(lineupId: number): Lineup | undefined
```

### auth.ts - Authentication
**Purpose**: Discord OAuth state with HttpOnly cookie-based authentication.

**Key State**: `currentUser`, `isAuthenticated`

**Critical Pattern - SSR Cookie Forwarding**:
```typescript
// checkAuth() must forward cookies during SSR
async function checkAuth(): Promise<boolean> {
  const headers: Record<string, string> = {}
  if (import.meta.server) {
    const event = useRequestEvent()
    const cookieHeader = event?.node.req.headers.cookie
    if (cookieHeader) {
      headers['Cookie'] = cookieHeader  // Forward to backend
    }
  }
  const response = await $fetch('/api/auth/me', {
    credentials: 'include',
    headers,
  })
}
```

**API Calls Pattern**:
```typescript
// ALL API calls must use credentials: 'include'
const response = await $fetch('/api/games/', {
  credentials: 'include',  // Sends HttpOnly cookies
})

// NEVER use Authorization header - tokens are in cookies
```

**Reference**: See `COOKIE_AUTH_IMPLEMENTATION.md` for complete auth flow documentation.

### ui.ts - UI State
**Purpose**: Toasts, modals, loading states.

**Key Methods**: `showSuccess()`, `showError()`, `showWarning()`, `showInfo()`

## Data Resolution Pattern

Game state contains minimal `LineupPlayerState`:
```typescript
interface LineupPlayerState {
  lineup_id: number  // Key for lookup
  card_id: number
  position: string
  // NO player name, headshot, etc.
}
```

Store caches full `Lineup` with nested player:
```typescript
interface Lineup {
  lineup_id: number
  player: {
    id: number
    name: string
    headshot: string
  }
}
```

**Resolution**:
```typescript
const batterState = gameStore.currentBatter           // LineupPlayerState
const batterLineup = gameStore.findPlayerInLineup(    // Full Lineup
  batterState.lineup_id
)
const name = batterLineup?.player.name                // "Mike Trout"
```

## Store Patterns

### Nuxt 4 Import Requirement
```typescript
// ALWAYS explicitly import stores
import { useGameStore } from '~/store/game'
const gameStore = useGameStore()

// NEVER rely on auto-imports (breaks in Nuxt 4)
```

### Readonly State
All state refs are exposed as `readonly()` to prevent direct mutation:
```typescript
return {
  gameState: readonly(gameState),  // Can't do gameStore.gameState.value = x
  setGameState,                    // Use action instead
}
```

### Team Determination Logic
```typescript
// Same logic as backend state_manager.py
const battingTeamId = computed(() => {
  return gameState.value.half === 'top'
    ? gameState.value.away_team_id   // Top: away bats
    : gameState.value.home_team_id   // Bottom: home bats
})
```
