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)
383 lines
7.1 KiB
Markdown
383 lines
7.1 KiB
Markdown
# 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](./websocket-protocol.md) document.
|
|
|
|
## Base URLs
|
|
|
|
- **Production**: `https://api.paperdynasty.com`
|
|
- **Development**: `http://localhost:8000`
|
|
|
|
## Authentication
|
|
|
|
All endpoints except health checks require authentication via JWT token:
|
|
|
|
```http
|
|
Authorization: Bearer <jwt_token>
|
|
```
|
|
|
|
## REST Endpoints
|
|
|
|
### Health & Status
|
|
|
|
#### GET /
|
|
Get API information
|
|
```json
|
|
Response 200:
|
|
{
|
|
"message": "Paper Dynasty Game Backend",
|
|
"version": "1.0.0"
|
|
}
|
|
```
|
|
|
|
#### GET /api/health
|
|
Health check endpoint
|
|
```json
|
|
Response 200:
|
|
{
|
|
"status": "healthy",
|
|
"database": "connected",
|
|
"timestamp": "2025-10-21T19:45:23Z"
|
|
}
|
|
```
|
|
|
|
### Authentication
|
|
|
|
#### POST /api/auth/discord/login
|
|
Initiate Discord OAuth flow
|
|
```json
|
|
Response 200:
|
|
{
|
|
"redirect_url": "https://discord.com/api/oauth2/authorize?..."
|
|
}
|
|
```
|
|
|
|
#### GET /api/auth/discord/callback
|
|
OAuth callback endpoint (query params: code)
|
|
```json
|
|
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
|
|
```json
|
|
Request:
|
|
{
|
|
"refresh_token": "refresh-token-here"
|
|
}
|
|
|
|
Response 200:
|
|
{
|
|
"access_token": "new-jwt-token",
|
|
"expires_in": 86400
|
|
}
|
|
```
|
|
|
|
#### POST /api/auth/logout
|
|
Logout user (invalidate token)
|
|
```json
|
|
Response 200:
|
|
{
|
|
"message": "Logged out successfully"
|
|
}
|
|
```
|
|
|
|
### Games
|
|
|
|
#### POST /api/games
|
|
Create new game
|
|
```json
|
|
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
|
|
```json
|
|
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
|
|
|
|
```json
|
|
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
|
|
```json
|
|
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)
|
|
```json
|
|
Response 200:
|
|
{
|
|
"message": "Game deleted successfully"
|
|
}
|
|
```
|
|
|
|
### Lineups
|
|
|
|
#### GET /api/games/:id/lineups
|
|
Get lineups for game
|
|
```json
|
|
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
|
|
```json
|
|
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
|
|
```json
|
|
{
|
|
"error": "Bad Request",
|
|
"message": "Invalid game_mode: must be 'live', 'async', or 'vs_ai'",
|
|
"details": {
|
|
"field": "game_mode",
|
|
"provided": "invalid_mode"
|
|
}
|
|
}
|
|
```
|
|
|
|
### 401 Unauthorized
|
|
```json
|
|
{
|
|
"error": "Unauthorized",
|
|
"message": "Invalid or expired token"
|
|
}
|
|
```
|
|
|
|
### 403 Forbidden
|
|
```json
|
|
{
|
|
"error": "Forbidden",
|
|
"message": "You do not have permission to perform this action"
|
|
}
|
|
```
|
|
|
|
### 404 Not Found
|
|
```json
|
|
{
|
|
"error": "Not Found",
|
|
"message": "Game not found"
|
|
}
|
|
```
|
|
|
|
### 429 Too Many Requests
|
|
```json
|
|
{
|
|
"error": "Rate Limit Exceeded",
|
|
"message": "Too many requests. Please try again in 60 seconds.",
|
|
"retry_after": 60
|
|
}
|
|
```
|
|
|
|
### 500 Internal Server Error
|
|
```json
|
|
{
|
|
"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:
|
|
```http
|
|
X-RateLimit-Limit: 100
|
|
X-RateLimit-Remaining: 95
|
|
X-RateLimit-Reset: 1735689600
|
|
```
|
|
|
|
## Pagination
|
|
|
|
List endpoints support pagination via `limit` and `offset`:
|
|
|
|
```http
|
|
GET /api/games?limit=25&offset=50
|
|
```
|
|
|
|
Response includes pagination metadata:
|
|
```json
|
|
{
|
|
"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](./websocket-protocol.md).
|
|
|
|
## 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
|
|
|
|
- [WebSocket Protocol](./websocket-protocol.md) - Real-time event API
|
|
- [Backend Architecture](./backend-architecture.md) - Implementation details
|
|
- [PRD Lines 1106-1127](../prd-web-scorecard-1.1.md) - 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. |