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>
3.3 KiB
Frontend SBA - Strat-O-Matic Baseball Association Web App
Overview
Vue 3 + Nuxt 3 frontend for the SBA league. Real-time game interface with WebSocket communication to backend.
Tech Stack: Nuxt 4.1.3, TypeScript (strict), Tailwind CSS, Pinia, Socket.io-client, Discord OAuth
CRITICAL: Nuxt 4 Breaking Changes
MUST READ: .claude/NUXT4_BREAKING_CHANGES.md
All Pinia stores MUST be explicitly imported:
// WRONG - will cause "useAuthStore is not defined":
const authStore = useAuthStore()
// CORRECT:
import { useAuthStore } from '~/store/auth'
const authStore = useAuthStore()
Project Structure
frontend-sba/
├── components/ # See components/CLAUDE.md for inventory
│ ├── Game/ # ScoreBoard, GameBoard, CurrentSituation, PlayByPlay
│ ├── Decisions/ # DecisionPanel, DefensiveSetup, OffensiveApproach
│ ├── Substitutions/
│ └── UI/ # ActionButton, ButtonGroup, ToggleSwitch
├── composables/ # See composables/CLAUDE.md for data flow
│ ├── useWebSocket.ts # Connection, event handlers
│ └── useGameActions.ts # Game action wrappers
├── store/ # See store/CLAUDE.md for patterns
│ ├── auth.ts # Discord OAuth, JWT
│ ├── game.ts # Game state, lineups, decisions
│ └── ui.ts # Toasts, modals
├── types/ # See types/CLAUDE.md for mappings
│ ├── game.ts # GameState, PlayResult
│ ├── player.ts # SbaPlayer, Lineup
│ └── websocket.ts
├── pages/
├── layouts/
├── middleware/
└── plugins/
Development
npm install # First time
npm run dev # Dev server at http://localhost:3000
npm run type-check # Check types
npm run lint # Lint code
Configuration
Environment Variables (.env)
NUXT_PUBLIC_LEAGUE_ID=sba
NUXT_PUBLIC_API_URL=http://localhost:8000
NUXT_PUBLIC_WS_URL=http://localhost:8000
NUXT_PUBLIC_DISCORD_CLIENT_ID=your-client-id
League Theme
- Primary: #1e40af (SBA Blue)
- Secondary: #dc2626 (SBA Red)
Mobile-First Design
- Breakpoints: xs(375px), sm(640px), md(768px), lg(1024px)
- Touch-friendly: 44x44px minimum buttons
- Sticky scoreboard, bottom sheets for inputs
Key Architecture Concepts
Data Resolution Pattern
Game state contains minimal LineupPlayerState (lineup_id, position). Use gameStore.findPlayerInLineup(lineupId) to get full player data (name, headshot).
Team Determination
- Top of inning: away bats, home fields
- Bottom of inning: home bats, away fields
- Use
gameStore.battingTeamId/gameStore.fieldingTeamId
Full details: See subdirectory CLAUDE.md files for component inventory, data flow, store patterns, and type mappings.
References
- Implementation Guide:
../.claude/implementation/01-infrastructure.md - WebSocket Protocol:
../.claude/implementation/websocket-protocol.md - Full PRD:
../prd-web-scorecard-1.1.md
League: SBA | Port: 3000 | Last Updated: 2025-01-19
Current Phase
Phase F2: Game State Display - COMPLETE (2025-01-10)
Components: ScoreBoard, GameBoard, CurrentSituation, PlayByPlay
Phase F3: Decision Input Workflow - NEXT
Components to integrate with live backend
See: .claude/implementation/NEXT_SESSION.md for detailed plan