strat-gameplay-webapp/.claude/implementation/api-reference.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

7.1 KiB

API Reference

Status: Placeholder Cross-Cutting Concern: All Phases


Overview

REST API endpoints for game management, authentication, and data retrieval. WebSocket API covered in separate WebSocket Protocol document.

Base URLs

  • Production: https://api.paperdynasty.com
  • Development: http://localhost:8000

Authentication

All endpoints except health checks require authentication via JWT token:

Authorization: Bearer <jwt_token>

REST Endpoints

Health & Status

GET /

Get API information

Response 200:
{
  "message": "Paper Dynasty Game Backend",
  "version": "1.0.0"
}

GET /api/health

Health check endpoint

Response 200:
{
  "status": "healthy",
  "database": "connected",
  "timestamp": "2025-10-21T19:45:23Z"
}

Authentication

POST /api/auth/discord/login

Initiate Discord OAuth flow

Response 200:
{
  "redirect_url": "https://discord.com/api/oauth2/authorize?..."
}

GET /api/auth/discord/callback

OAuth callback endpoint (query params: code)

Response 200:
{
  "access_token": "jwt-token-here",
  "token_type": "Bearer",
  "expires_in": 86400,
  "user": {
    "id": "discord_snowflake_id",
    "username": "DiscordUser#1234",
    "avatar": "avatar_hash",
    "teams": [42, 99]
  }
}

POST /api/auth/refresh

Refresh JWT token

Request:
{
  "refresh_token": "refresh-token-here"
}

Response 200:
{
  "access_token": "new-jwt-token",
  "expires_in": 86400
}

POST /api/auth/logout

Logout user (invalidate token)

Response 200:
{
  "message": "Logged out successfully"
}

Games

POST /api/games

Create new game

Request:
{
  "league_id": "sba",
  "home_team_id": 42,
  "away_team_id": 99,
  "game_mode": "live",  // "live", "async", "vs_ai"
  "visibility": "public"  // "public", "private"
}

Response 201:
{
  "game_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "pending",
  "created_at": "2025-10-21T19:45:23Z"
}

GET /api/games/:id

Get game details

Response 200:
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "league_id": "sba",
  "home_team_id": 42,
  "away_team_id": 99,
  "status": "active",
  "game_mode": "live",
  "visibility": "public",
  "current_inning": 3,
  "current_half": "top",
  "home_score": 2,
  "away_score": 1,
  "created_at": "2025-10-21T19:30:00Z",
  "started_at": "2025-10-21T19:35:00Z",
  "completed_at": null,
  "winner_team_id": null
}

GET /api/games

List games (with filters)

Query Parameters:

  • status - Filter by status (pending, active, completed)
  • league_id - Filter by league
  • team_id - Filter by team participation
  • limit - Number of results (default: 50)
  • offset - Pagination offset
Response 200:
{
  "games": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "league_id": "sba",
      "home_team_id": 42,
      "away_team_id": 99,
      "status": "active",
      "current_inning": 3,
      "home_score": 2,
      "away_score": 1,
      "created_at": "2025-10-21T19:30:00Z"
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0
}

GET /api/games/:id/history

Get play-by-play history

Response 200:
{
  "game_id": "550e8400-e29b-41d4-a716-446655440000",
  "plays": [
    {
      "play_number": 1,
      "inning": 1,
      "half": "top",
      "batter_id": 12345,
      "pitcher_id": 67890,
      "dice_roll": 5,
      "hit_type": "groundout",
      "result_description": "Groundout to shortstop",
      "runs_scored": 0,
      "outs_recorded": 1
    }
  ],
  "total_plays": 1
}

DELETE /api/games/:id

Delete/abandon game (admin only)

Response 200:
{
  "message": "Game deleted successfully"
}

Lineups

GET /api/games/:id/lineups

Get lineups for game

Response 200:
{
  "home": [
    {
      "card_id": 12345,
      "position": "CF",
      "batting_order": 1,
      "is_active": true,
      "player": {
        "id": 999,
        "name": "Mike Trout",
        "image": "https://..."
      }
    }
  ],
  "away": [...]
}

Spectate

GET /api/spectate/:id/join

Get spectator link for game

Response 200:
{
  "game_id": "550e8400-e29b-41d4-a716-446655440000",
  "spectator_link": "https://sba.paperdynasty.com/spectate/550e8400-e29b-41d4-a716-446655440000",
  "can_spectate": true
}

Error Responses

400 Bad Request

{
  "error": "Bad Request",
  "message": "Invalid game_mode: must be 'live', 'async', or 'vs_ai'",
  "details": {
    "field": "game_mode",
    "provided": "invalid_mode"
  }
}

401 Unauthorized

{
  "error": "Unauthorized",
  "message": "Invalid or expired token"
}

403 Forbidden

{
  "error": "Forbidden",
  "message": "You do not have permission to perform this action"
}

404 Not Found

{
  "error": "Not Found",
  "message": "Game not found"
}

429 Too Many Requests

{
  "error": "Rate Limit Exceeded",
  "message": "Too many requests. Please try again in 60 seconds.",
  "retry_after": 60
}

500 Internal Server Error

{
  "error": "Internal Server Error",
  "message": "An unexpected error occurred",
  "request_id": "abc123xyz"
}

Rate Limits

  • Authenticated requests: 100 requests/minute per user
  • Unauthenticated requests: 20 requests/minute per IP
  • Game creation: 5 games/hour per user

Headers included in response:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1735689600

Pagination

List endpoints support pagination via limit and offset:

GET /api/games?limit=25&offset=50

Response includes pagination metadata:

{
  "data": [...],
  "pagination": {
    "total": 200,
    "limit": 25,
    "offset": 50,
    "has_more": true
  }
}

CORS

CORS headers are configured for allowed origins:

  • https://sba.paperdynasty.com
  • https://pd.paperdynasty.com
  • http://localhost:3000 (development)
  • http://localhost:3001 (development)

OpenAPI Specification

Full OpenAPI/Swagger documentation available at:

  • Development: http://localhost:8000/docs
  • Production: https://api.paperdynasty.com/docs

WebSocket API

WebSocket events documented separately in WebSocket Protocol.

League-Specific APIs

The game backend integrates with league-specific REST APIs for team/player data:

SBA League API

  • Base URL: Configured via SBA_API_URL env var
  • Authentication: API key via SBA_API_KEY env var

PD League API

  • Base URL: Configured via PD_API_URL env var
  • Authentication: API key via PD_API_KEY env var

Endpoints used:

  • GET /api/teams/:id - Team details
  • GET /api/teams/:id/roster - Team roster
  • GET /api/players/:id - Player details
  • GET /api/cards/:id - Card details

Reference Documents


Note: This is a placeholder to be expanded with complete request/response examples during implementation. Full OpenAPI spec will be auto-generated by FastAPI.