# 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 { const headers: Record = {} 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 }) ```