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)
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 leagueteam_id- Filter by team participationlimit- 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.comhttps://pd.paperdynasty.comhttp://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_URLenv var - Authentication: API key via
SBA_API_KEYenv var
PD League API
- Base URL: Configured via
PD_API_URLenv var - Authentication: API key via
PD_API_KEYenv var
Endpoints used:
GET /api/teams/:id- Team detailsGET /api/teams/:id/roster- Team rosterGET /api/players/:id- Player detailsGET /api/cards/:id- Card details
Reference Documents
- WebSocket Protocol - Real-time event API
- Backend Architecture - Implementation details
- PRD Lines 1106-1127 - API endpoint reference
Note: This is a placeholder to be expanded with complete request/response examples during implementation. Full OpenAPI spec will be auto-generated by FastAPI.