strat-gameplay-webapp/CLAUDE.md
Cal Corum d60b7a2d60 CLAUDE: Store team display info in DB and fix lineup auto-start
Backend:
- Add game_metadata to create_game() and quick_create_game() endpoints
- Fetch team display info (lname, sname, abbrev, color, thumbnail) from
  SBA API at game creation time and store in DB
- Populate GameState with team display fields from game_metadata
- Fix submit_team_lineup to cache lineup in state_manager after DB write
  so auto-start correctly detects both teams ready

Frontend:
- Read team colors/names/thumbnails from gameState instead of useState
- Remove useState approach that failed across SSR navigation
- Fix create.vue redirect from legacy /games/lineup/[id] to /games/[id]
- Update game.vue header to show team names from gameState

Docs:
- Update CLAUDE.md to note dev mode has broken auth, always use prod

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 08:43:26 -06:00

9.5 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

  1. Player action → WebSocket → Backend
  2. Validate against in-memory state
  3. Process + resolve outcome
  4. Update in-memory state
  5. Async write to PostgreSQL
  6. 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.

⚠️ ALWAYS USE PROD MODE: Discord OAuth does not work in dev mode due to cookie/CORS configuration. Since this system isn't live yet, always build and run with prod mode for testing.

# Production (optimized build) - USE THIS
./start.sh prod

# Development - DO NOT USE (auth broken)
# ./start.sh dev

# 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
prod Production build SSR optimized build Always use this - auth works correctly
dev Hot-reload (uvicorn --reload) Hot-reload (nuxt dev) Auth broken - do not use

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 string
  • DISCORD_CLIENT_ID/SECRET - OAuth credentials
  • DISCORD_SERVER_REDIRECT_URI - Server-side OAuth callback
  • FRONTEND_URL - Frontend base URL for redirects
  • CORS_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 URL
  • NUXT_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:

  1. Authentication (Discord OAuth)
  2. Game creation & lobby
  3. Complete turn-based gameplay with all strategic decisions
  4. Real-time WebSocket updates
  5. Game persistence & recovery
  6. Spectator mode
  7. Mobile-optimized UI
  8. 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.