strat-gameplay-webapp/frontend-sba/composables/CLAUDE.md
Cal Corum cbdd8cf903 CLAUDE: Fix critical game engine issues and refactor CLAUDE.md docs
Critical fixes in game_engine.py:
- Fix silent error swallowing in _batch_save_inning_rolls (re-raise)
- Add per-game asyncio.Lock for race condition prevention
- Add _cleanup_game_resources() for memory leak prevention
- All 739 tests passing

Documentation refactoring:
- Created CODE_REVIEW_GAME_ENGINE.md documenting 24 identified issues
- Trimmed backend/app/core/CLAUDE.md from 1371 to 143 lines
- Trimmed frontend-sba/CLAUDE.md from 696 to 110 lines
- Created focused subdirectory CLAUDE.md files:
  - frontend-sba/components/CLAUDE.md (105 lines)
  - frontend-sba/composables/CLAUDE.md (79 lines)
  - frontend-sba/store/CLAUDE.md (116 lines)
  - frontend-sba/types/CLAUDE.md (95 lines)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 16:05:26 -06:00

2.5 KiB

Composables Directory

Vue 3 composables for shared logic. These handle WebSocket communication and game actions.

Available Composables

useWebSocket.ts

Purpose: Manages Socket.io connection with authentication and auto-reconnection.

Key Exports:

const {
  socket,           // Computed<TypedSocket | null>
  isConnected,      // Readonly<Ref<boolean>>
  isConnecting,     // Readonly<Ref<boolean>>
  connectionError,  // Readonly<Ref<string | null>>
  connect,          // () => void
  disconnect,       // () => void
} = useWebSocket()

Event Flow (Backend → Store):

socketInstance.on('game_state_update') → gameStore.setGameState()
socketInstance.on('lineup_data')       → gameStore.updateLineup()
socketInstance.on('decision_required') → gameStore.setDecisionPrompt()
socketInstance.on('play_completed')    → gameStore.addPlayToHistory()
socketInstance.on('dice_rolled')       → gameStore.setPendingRoll()

Singleton Pattern: Socket instance is module-level, shared across all useWebSocket() calls.

useGameActions.ts

Purpose: Wraps WebSocket emits with type safety and validation.

Key Exports:

const {
  joinGame,           // (gameId: string) => void
  requestGameState,   // (gameId: string) => void
  setDefense,         // (gameId: string, decision: DefensiveDecision) => void
  setOffense,         // (gameId: string, decision: OffensiveDecision) => void
  rollDice,           // (gameId: string) => void
  submitOutcome,      // (gameId: string, outcome: PlayOutcome) => void
  // ... substitution methods
} = useGameActions()

Usage Pattern:

// In component
const { setDefense } = useGameActions()

const handleSubmit = (decision: DefensiveDecision) => {
  setDefense(gameId, decision)
}

Data Flow Architecture

User Action → useGameActions → socket.emit() → Backend
                                                  ↓
Component ← gameStore ← useWebSocket.on() ← socket event

Why this separation?

  • useWebSocket: Low-level connection management, event routing
  • useGameActions: High-level game operations, business logic validation
  • gameStore: Centralized state, computed getters

Common Issues

Issue Cause Solution
"Not connected" error Socket disconnected Check isConnected before actions
Events not firing Listeners not set up Ensure useWebSocket() called in component
Stale data Missed reconnection Call requestGameState() after reconnect