paper-dynasty-gameplay-webapp/app/routers/README.md
Cal Corum c09f9d1302 CLAUDE: Initialize Paper Dynasty web app with Model/Service Architecture
Establishes foundation for migrating baseball simulation from Discord bot to web application using service-oriented architecture pattern.

Key components:
- FastAPI application structure with dependency injection
- Service layer foundation with base classes and container
- Comprehensive directory documentation with README files
- PostgreSQL containerization with Docker Compose
- Testing structure for unit/integration/e2e tests
- Migration planning documentation
- Rotating log configuration per user requirements

Architecture follows Model/Service/Controller pattern to improve testability, maintainability, and scalability over original monolithic Discord app.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-27 21:44:12 -05:00

138 lines
4.0 KiB
Markdown

# Routers Directory
This directory contains **FastAPI route handlers** following the Model/Service Architecture pattern. Routes are thin controllers that handle HTTP concerns and delegate business logic to services.
## Architecture Pattern
### Route Responsibilities
- **HTTP Handling**: Request/response processing, status codes
- **Input Validation**: Request data validation and parsing
- **Service Delegation**: Delegate business logic to services
- **Response Formatting**: Transform service results for HTTP responses
### Design Principles
- **Thin Controllers**: Minimal logic, delegate to services
- **Dependency Injection**: Use FastAPI `Depends()` for services
- **Error Handling**: Transform service exceptions to HTTP errors
- **Documentation**: FastAPI auto-generates OpenAPI documentation
## Current Files
### `auth.py`
Authentication routes:
- **Discord OAuth**: Login redirect and callback handling
- **Session Management**: Login/logout functionality
- **Uses**: `AuthService` for business logic
### `games.py`
Game-related endpoints:
- **Game Creation**: Start new games
- **Game Retrieval**: Get game details and listings
- **Uses**: `GameService` for business logic
### `api.py`
JSON API endpoints for HTMX:
- **Live Updates**: Scoreboard and game state
- **Player Actions**: Execute gameplay actions
- **Uses**: `GameplayService` for real-time updates
### `pages.py`
HTML page routes with Jinja2 templates:
- **Home Page**: Main application entry point
- **Game Interface**: Live game viewing
- **Template Rendering**: Server-side HTML generation
## Route Pattern Example
```python
from fastapi import APIRouter, HTTPException
from app.services.service_container import GameServiceDep
router = APIRouter()
@router.post("/games/start")
async def start_game(
request: StartGameRequest,
game_service: GameServiceDep
):
"""Start a new game - delegates to GameService."""
try:
game = await game_service.create_game(
away_team_id=request.away_team_id,
home_team_id=request.home_team_id
)
return {"game_id": game.id, "status": "created"}
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
```
## Service Integration
Routes use dependency injection to access services:
```python
# Service dependencies from service_container.py
GameServiceDep = Annotated[GameService, Depends(get_game_service)]
UserServiceDep = Annotated[UserService, Depends(get_user_service)]
AuthServiceDep = Annotated[AuthService, Depends(get_auth_service)]
```
## Route Organization
### `/auth` - Authentication
- `GET /auth/login` - Discord OAuth redirect
- `GET /auth/callback` - OAuth callback handler
- `POST /auth/logout` - Logout and session cleanup
### `/games` - Game Management
- `POST /games/start` - Create new game
- `GET /games/{game_id}` - Get game details
- `GET /games/` - List active games
### `/api` - HTMX JSON API
- `GET /api/scoreboard/{game_id}` - Live scoreboard data
- `POST /api/play` - Execute gameplay action
### `/` - HTML Pages
- `GET /` - Home page
- `GET /game/{game_id}` - Game interface page
## Error Handling
Routes should transform service exceptions to appropriate HTTP responses:
```python
try:
result = await service.do_something()
return result
except NotFoundException as e:
raise HTTPException(status_code=404, detail=str(e))
except ValidationError as e:
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
logger.error(f"Unexpected error: {e}")
raise HTTPException(status_code=500, detail="Internal server error")
```
## Testing Routes
Routes should be tested with service dependencies mocked:
```python
from fastapi.testclient import TestClient
from unittest.mock import Mock
def test_start_game(mock_game_service):
client = TestClient(app)
# Mock service response
mock_game_service.create_game.return_value = Game(id=1)
response = client.post("/games/start", json={
"away_team_id": 1,
"home_team_id": 2
})
assert response.status_code == 200
assert response.json()["game_id"] == 1
```