Frontend UX improvements: - Single-click Discord OAuth from home page (no intermediate /auth page) - Auto-redirect authenticated users from home to /games - Fixed Nuxt layout system - app.vue now wraps NuxtPage with NuxtLayout - Games page now has proper card container with shadow/border styling - Layout header includes working logout with API cookie clearing Games list enhancements: - Display team names (lname) instead of just team IDs - Show current score for each team - Show inning indicator (Top/Bot X) for active games - Responsive header with wrapped buttons on mobile Backend improvements: - Added team caching to SbaApiClient (1-hour TTL) - Enhanced GameListItem with team names, scores, inning data - Games endpoint now enriches response with SBA API team data Docker optimizations: - Optimized Dockerfile using --chown flag on COPY (faster than chown -R) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
9.2 KiB
🚨 CRITICAL: @ MENTION HANDLING 🚨
When ANY file is mentioned with @ syntax, you MUST IMMEDIATELY call Read tool on that file BEFORE responding. You will see automatic loads of any @ mentioned filed, this is NOT ENOUGH, it only loads the file contents. You MUST perform Read tool calls on the files directly, even if they were @ included. This is NOT optional - it loads required CLAUDE.md context. along the file path. See @./.claude/force-claude-reads.md for details.
Paper Dynasty Real-Time Game Engine - Development Guide
Project Overview
Web-based real-time multiplayer baseball simulation platform replacing legacy Google Sheets system. Consists of:
- Shared Backend: FastAPI (Python 3.11+) with WebSocket support, PostgreSQL persistence
- Dual Frontends: Separate Vue 3/Nuxt 3 apps per league (SBA and PD) with shared component library
Critical Business Driver: Legacy Google Sheets being deprecated - this is mission-critical replacement.
Architecture Principles
Backend Philosophy
- Hybrid State Model: In-memory game state for performance + PostgreSQL for persistence/recovery
- League-Agnostic Core: Polymorphic player models, config-driven league variations
- Async-First: All I/O operations use async/await patterns
- Type Safety: Pydantic models for validation, SQLAlchemy for ORM
Frontend Philosophy
- Mobile-First: Primary design target is mobile portrait mode
- Real-Time Updates: WebSocket (Socket.io) for all game state changes
- Shared Components: Maximize reuse between league frontends
- Type Safety: TypeScript with strict mode
Technology Stack
Backend
- FastAPI + Socket.io (WebSocket)
- PostgreSQL 14+ with SQLAlchemy 2.0
- Pydantic for data validation
- pytest for testing
Frontend (Per League)
- Vue 3 Composition API + Nuxt 3
- TypeScript (strict mode)
- Tailwind CSS
- Pinia for state management
- Socket.io-client
- Discord OAuth via HttpOnly cookies (see
COOKIE_AUTH_IMPLEMENTATION.md)
Key Technical Patterns
Polymorphic Player Architecture
Use factory pattern for league-specific player types:
BasePlayer(abstract base)SbaPlayer(simple model)PdPlayer(detailed scouting data)Lineup.from_api_data(config, data)factory method
WebSocket Event Flow
- Player action → WebSocket → Backend
- Validate against in-memory state
- Process + resolve outcome
- Update in-memory state
- Async write to PostgreSQL
- Broadcast state update to all clients
Game State Recovery
On reconnect: Load plays from DB → Replay to rebuild state → Send current state
Project Structure
strat-gameplay-webapp/
├── backend/ # FastAPI game engine
│ ├── app/
│ │ ├── core/ # Game engine, dice, state management
│ │ ├── config/ # League configs and result charts
│ │ ├── websocket/ # Socket.io handlers
│ │ ├── models/ # Pydantic + SQLAlchemy models
│ │ └── api/ # REST endpoints
│ └── tests/
├── frontend-sba/ # SBA League Nuxt app
├── frontend-pd/ # PD League Nuxt app (disabled)
├── docker-compose.yml # Base service configuration
├── docker-compose.dev.yml # Development overrides (hot-reload)
├── docker-compose.prod.yml # Production overrides (optimized)
├── start.sh # Single-command startup script
└── scripts/env-switch.sh # Environment profile switcher
Quick Start (All-Docker Workflow)
The entire stack runs in Docker with a single command. No local Python or Node.js required.
# Development (hot-reload enabled)
./start.sh dev
# Production (optimized build)
./start.sh prod
# Stop all services
./start.sh stop
# View logs
./start.sh logs
# Check status
./start.sh status
# Force rebuild
./start.sh rebuild [dev|prod]
What Each Mode Does
| Mode | Backend | Frontend | Use Case |
|---|---|---|---|
dev |
Hot-reload (uvicorn --reload) | Hot-reload (nuxt dev) | Active development |
prod |
Production build | SSR optimized build | Demo/deployment |
Service URLs
| Service | Dev Mode | Prod Mode |
|---|---|---|
| Frontend | http://localhost:3000 | https://gameplay-demo.manticorum.com |
| Backend API | http://localhost:8000 | https://gameplay-demo.manticorum.com/api |
| API Docs | http://localhost:8000/docs | https://gameplay-demo.manticorum.com/api/docs |
Docker Compose Architecture
The stack uses layered compose files:
docker-compose.yml- Base services (Redis, Backend, Frontend-SBA)docker-compose.dev.yml- Development overrides (volume mounts, hot-reload)docker-compose.prod.yml- Production overrides (optimized builds, restart policies)
The start.sh script handles composing these correctly.
Environment Configuration
Environment Profiles
| Profile | Backend URL | Frontend URL |
|---|---|---|
dev |
http://localhost:8000 |
http://localhost:3000 |
prod |
https://gameplay-demo.manticorum.com |
https://gameplay-demo.manticorum.com |
Environment Files
| File | Purpose |
|---|---|
backend/.env |
Active backend config (gitignored) |
backend/.env.dev |
Local development settings |
backend/.env.prod |
Production settings |
frontend-sba/.env |
Active frontend config (gitignored) |
frontend-sba/.env.dev |
Local development settings |
frontend-sba/.env.prod |
Production settings |
Key Environment Variables
Backend (in backend/.env):
DATABASE_URL- PostgreSQL connection stringDISCORD_CLIENT_ID/SECRET- OAuth credentialsDISCORD_SERVER_REDIRECT_URI- Server-side OAuth callbackFRONTEND_URL- Frontend base URL for redirectsCORS_ORIGINS- Allowed origins (JSON array)ALLOWED_DISCORD_IDS- User whitelist (comma-separated, empty = all)
Frontend (in frontend-*/.env):
NUXT_PUBLIC_API_URL- Backend API URL (public, client-side)NUXT_API_URL_INTERNAL- Backend URL for SSR (Docker internal:http://backend:8000)NUXT_PUBLIC_WS_URL- WebSocket URLNUXT_PUBLIC_DISCORD_CLIENT_ID- OAuth client ID (public)NUXT_PUBLIC_DISCORD_REDIRECT_URI- OAuth callback URL
Discord OAuth Setup
Both environments require redirect URIs in Discord Developer Portal:
| Environment | Redirect URI |
|---|---|
| dev | http://localhost:8000/api/auth/discord/callback/server |
| prod | https://gameplay-demo.manticorum.com/api/auth/discord/callback/server |
Manual Environment Switching
If you need to switch between dev/prod configs without Docker:
./scripts/env-switch.sh dev # Copy .env.dev → .env
./scripts/env-switch.sh prod # Copy .env.prod → .env
The start.sh script handles this automatically based on mode.
Development Guidelines
Code Quality
- Python: Dataclasses preferred, rotating loggers with
f'{__name__}.<className>' - Error Handling: "Raise or Return" pattern - no Optional unless required
- Testing: Run tests freely without asking permission
- Imports: Always verify imports during code review to prevent NameErrors
- Git Commits: Prefix with "CLAUDE: "
Performance Targets
- Action response: < 500ms
- WebSocket delivery: < 200ms
- DB writes: < 100ms (async)
- State recovery: < 2 seconds
Security Requirements
- Discord OAuth for authentication
- Server-side game logic only (zero client trust)
- Cryptographically secure dice rolls
- All rules enforced server-side
Phase 1 MVP Scope (Weeks 1-13)
Core Deliverables:
- Authentication (Discord OAuth)
- Game creation & lobby
- Complete turn-based gameplay with all strategic decisions
- Real-time WebSocket updates
- Game persistence & recovery
- Spectator mode
- Mobile-optimized UI
- AI opponent support
Explicitly Out of Scope for MVP:
- Roster management
- Marketplace
- Tournaments
- Advanced analytics
Critical References
- Full PRD:
/mnt/NV2/Development/strat-gameplay-webapp/prd-web-scorecard-1.1.md - Player Model Architecture: PRD lines 378-551
- Database Schema: PRD lines 553-628
- WebSocket Events: PRD lines 630-669
- League Config System: PRD lines 780-846
League Differences
SBA League
- Minimal player data (id, name, image)
- Simpler rules configuration
PD League
- Detailed scouting data on players
- Complex probability calculations
- Additional analytics requirements
Success Metrics
- 90% player migration within 1 month
- 99.5% uptime
- < 500ms average action latency
- 60%+ mobile usage
- Zero data corruption
Current Implementation Status
Phase 3E-Final: ✅ COMPLETE (2025-01-10)
Backend is production-ready for frontend integration:
- ✅ All 15 WebSocket event handlers implemented
- ✅ Strategic decisions (defensive/offensive)
- ✅ Manual outcome workflow (dice rolling + card reading)
- ✅ Player substitutions (3 types)
- ✅ Box score statistics (materialized views)
- ✅ Position ratings integration (PD league)
- ✅ 730/731 tests passing (99.9%)
Next Phase: Vue 3 + Nuxt 3 frontend implementation with Socket.io client
Note: Subdirectories have their own CLAUDE.md files with implementation-specific details to minimize context usage.