strat-gameplay-webapp/backend/CLAUDE.md
Cal Corum 5c75b935f0 CLAUDE: Initial project setup - documentation and infrastructure
Add comprehensive project documentation and Docker infrastructure for
Paper Dynasty Real-Time Game Engine - a web-based multiplayer baseball
simulation platform replacing the legacy Google Sheets system.

Documentation Added:
- Complete PRD (Product Requirements Document)
- Project README with dual development workflows
- Implementation guide with 5-phase roadmap
- Architecture docs (backend, frontend, database, WebSocket)
- CLAUDE.md context files for each major directory

Infrastructure Added:
- Root docker-compose.yml for full stack orchestration
- Dockerfiles for backend and both frontends (multi-stage builds)
- .dockerignore files for optimal build context
- .env.example with all required configuration
- Updated .gitignore for Python, Node, Nuxt, and Docker

Project Structure:
- backend/ - FastAPI + Socket.io game engine (Python 3.11+)
- frontend-sba/ - SBA League Nuxt 3 frontend
- frontend-pd/ - PD League Nuxt 3 frontend
- .claude/implementation/ - Detailed implementation guides

Supports two development workflows:
1. Local dev (recommended): Services run natively with hot-reload
2. Full Docker: One-command stack orchestration for testing/demos

Next: Phase 1 implementation (backend/frontend foundations)
2025-10-21 16:21:13 -05:00

9.8 KiB

Backend - Paper Dynasty Game Engine

Overview

FastAPI-based real-time game backend handling WebSocket communication, game state management, and database persistence for both SBA and PD leagues.

Technology Stack

  • Framework: FastAPI (Python 3.11+)
  • WebSocket: Socket.io (python-socketio)
  • Database: PostgreSQL 14+ with SQLAlchemy 2.0 (async)
  • ORM: SQLAlchemy with asyncpg driver
  • Validation: Pydantic v2
  • Testing: pytest with pytest-asyncio
  • Code Quality: black, flake8, mypy

Project Structure

backend/
├── app/
│   ├── main.py                 # FastAPI app + Socket.io initialization
│   ├── config.py               # Settings with pydantic-settings
│   │
│   ├── core/                   # Game logic (Phase 2+)
│   │   ├── game_engine.py      # Main game simulation
│   │   ├── state_manager.py    # In-memory state
│   │   ├── play_resolver.py    # Play outcome resolution
│   │   ├── dice.py             # Secure random rolls
│   │   └── validators.py       # Rule validation
│   │
│   ├── config/                 # League configurations (Phase 2+)
│   │   ├── base_config.py      # Shared configuration
│   │   ├── league_configs.py   # SBA/PD specific
│   │   └── result_charts.py    # d20 outcome tables
│   │
│   ├── models/                 # Data models
│   │   ├── db_models.py        # SQLAlchemy ORM models
│   │   ├── game_models.py      # Pydantic game state models (Phase 2+)
│   │   └── player_models.py    # Polymorphic player models (Phase 2+)
│   │
│   ├── websocket/              # WebSocket handling
│   │   ├── connection_manager.py  # Connection lifecycle
│   │   ├── handlers.py            # Event handlers
│   │   └── events.py              # Event definitions (Phase 2+)
│   │
│   ├── api/                    # REST API
│   │   ├── routes/
│   │   │   ├── health.py       # Health check endpoints
│   │   │   ├── auth.py         # Discord OAuth (Phase 1)
│   │   │   └── games.py        # Game CRUD (Phase 2+)
│   │   └── dependencies.py     # FastAPI dependencies
│   │
│   ├── database/               # Database layer
│   │   ├── session.py          # Async session management
│   │   └── operations.py       # DB operations (Phase 2+)
│   │
│   ├── data/                   # External data (Phase 2+)
│   │   ├── api_client.py       # League REST API client
│   │   └── cache.py            # Caching layer
│   │
│   └── utils/                  # Utilities
│       ├── logging.py          # Logging setup
│       └── auth.py             # JWT utilities (Phase 1)
│
├── tests/
│   ├── unit/                   # Unit tests
│   ├── integration/            # Integration tests
│   └── e2e/                    # End-to-end tests
│
├── logs/                       # Application logs (gitignored)
├── venv/                       # Virtual environment (gitignored)
├── .env                        # Environment variables (gitignored)
├── .env.example                # Environment template
├── requirements.txt            # Production dependencies
├── requirements-dev.txt        # Dev dependencies
├── Dockerfile                  # Container definition
├── docker-compose.yml          # Redis for local dev
└── pytest.ini                  # Pytest configuration

Key Architectural Patterns

1. Hybrid State Management

  • In-Memory: Active game states for fast access (<500ms response)
  • PostgreSQL: Persistent storage for recovery and history
  • Pattern: Write-through cache (update memory + async DB write)

2. Polymorphic Player Models

# Base class with abstract methods
class BasePlayer(BaseModel, ABC):
    @abstractmethod
    def get_image_url(self) -> str: ...

# League-specific implementations
class SbaPlayer(BasePlayer): ...
class PdPlayer(BasePlayer): ...

# Factory pattern for instantiation
Lineup.from_api_data(config, data)

3. League-Agnostic Core

  • Game engine works for any league
  • League-specific logic in config classes
  • Result charts loaded per league

4. Async-First

  • All database operations use async/await
  • Database writes don't block game logic
  • Connection pooling for efficiency

Development Workflow

Daily Development

# Activate virtual environment
source venv/bin/activate

# Start Redis (in separate terminal)
docker-compose up

# Run backend with hot-reload
python -m app.main

# Backend available at http://localhost:8000
# API docs at http://localhost:8000/docs

Testing

# Run all tests
pytest tests/ -v

# Run with coverage
pytest tests/ --cov=app --cov-report=html

# Run specific test file
pytest tests/unit/test_game_engine.py -v

# Type checking
mypy app/

# Code formatting
black app/ tests/

# Linting
flake8 app/ tests/

Coding Standards

Python Style

  • Formatting: Black with default settings
  • Line Length: 88 characters (black default)
  • Imports: Group stdlib, third-party, local (isort compatible)
  • Type Hints: Required for all public functions
  • Docstrings: Google style for classes and public methods

Logging Pattern

import logging

logger = logging.getLogger(f'{__name__}.ClassName')

# Usage
logger.info(f"User {user_id} connected")
logger.error(f"Failed to process action: {error}", exc_info=True)

Error Handling

  • Raise or Return: Never return Optional unless specifically required
  • Custom Exceptions: Use for domain-specific errors
  • Logging: Always log exceptions with context

Dataclasses

from dataclasses import dataclass

@dataclass
class GameState:
    game_id: str
    inning: int
    outs: int
    # ... fields

Database Patterns

Async Session Usage

from app.database.session import get_session

async def some_function():
    async with get_session() as session:
        result = await session.execute(query)
        # session.commit() happens automatically

Model Definitions

from app.database.session import Base
from sqlalchemy import Column, String, Integer

class Game(Base):
    __tablename__ = "games"

    id = Column(UUID(as_uuid=True), primary_key=True)
    # ... columns

WebSocket Patterns

Event Handler Registration

@sio.event
async def some_event(sid, data):
    """Handle some_event from client"""
    try:
        # Validate data
        # Process action
        # Emit response
        await sio.emit('response_event', result, room=sid)
    except Exception as e:
        logger.error(f"Error handling event: {e}")
        await sio.emit('error', {'message': str(e)}, room=sid)

Broadcasting

# To specific game room
await connection_manager.broadcast_to_game(
    game_id,
    'game_state_update',
    state_data
)

# To specific user
await connection_manager.emit_to_user(
    sid,
    'decision_required',
    decision_data
)

Environment Variables

Required in .env:

# Database
DATABASE_URL=postgresql+asyncpg://user:pass@host:5432/dbname

# Application
SECRET_KEY=your-secret-key-at-least-32-chars

# Discord OAuth
DISCORD_CLIENT_ID=your-client-id
DISCORD_CLIENT_SECRET=your-client-secret

# League APIs
SBA_API_URL=https://sba-api.example.com
SBA_API_KEY=your-api-key
PD_API_URL=https://pd-api.example.com
PD_API_KEY=your-api-key

Performance Targets

  • Action Response: < 500ms from user action to state update
  • WebSocket Delivery: < 200ms
  • Database Write: < 100ms (async, non-blocking)
  • State Recovery: < 2 seconds
  • Concurrent Games: Support 10+ simultaneous games
  • Memory: < 1GB with 10 active games

Security Considerations

  • Authentication: All WebSocket connections require valid JWT
  • Authorization: Verify team ownership before allowing actions
  • Input Validation: Pydantic models validate all inputs
  • SQL Injection: Prevented by SQLAlchemy ORM
  • Dice Rolls: Cryptographically secure random generation
  • Server-Side Logic: All game rules enforced server-side

Common Tasks

Adding a New API Endpoint

  1. Create route in app/api/routes/
  2. Define Pydantic request/response models
  3. Add dependency injection if needed
  4. Register router in app/main.py

Adding a New WebSocket Event

  1. Define event handler in app/websocket/handlers.py
  2. Register with @sio.event decorator
  3. Validate data with Pydantic
  4. Add corresponding client handling in frontend

Adding a New Database Model

  1. Define SQLAlchemy model in app/models/db_models.py
  2. Create Alembic migration: alembic revision --autogenerate -m "description"
  3. Apply migration: alembic upgrade head

Troubleshooting

Import Errors

  • Ensure virtual environment is activated
  • Check PYTHONPATH if using custom structure
  • Verify all __init__.py files exist

Database Connection Issues

  • Verify DATABASE_URL in .env is correct
  • Test connection: psql $DATABASE_URL
  • Check firewall/network access
  • Verify database exists

WebSocket Not Connecting

  • Check CORS settings in config.py
  • Verify token is being sent from client
  • Check logs for connection errors
  • Ensure Socket.io versions match (client/server)

References

  • Implementation Guide: ../.claude/implementation/01-infrastructure.md
  • Backend Architecture: ../.claude/implementation/backend-architecture.md
  • WebSocket Protocol: ../.claude/implementation/websocket-protocol.md
  • Database Design: ../.claude/implementation/database-design.md
  • Full PRD: ../prd-web-scorecard-1.1.md

Current Phase: Phase 1 - Core Infrastructure Next Phase: Phase 2 - Game Engine Core