strat-gameplay-webapp/backend/app/models/CLAUDE.md
Cal Corum 88a5207c2c CLAUDE: Refactor backend CLAUDE.md files for conciseness
Major reduction in CLAUDE.md file sizes to follow concise documentation standard:

| File | Before | After | Reduction |
|------|--------|-------|-----------|
| backend/CLAUDE.md | 2,467 | 123 | 95% |
| models/CLAUDE.md | 1,586 | 102 | 94% |
| websocket/CLAUDE.md | 2,094 | 119 | 94% |
| config/CLAUDE.md | 1,017 | 126 | 88% |
| database/CLAUDE.md | 946 | 130 | 86% |
| api/CLAUDE.md | 906 | 140 | 85% |

Total: 9,016 -> 740 lines (92% reduction)

All files now under 150 lines with:
- Essential patterns and usage
- Cross-references to related docs
- Quick-start examples
- Updated timestamps

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 16:10:08 -06:00

103 lines
3.1 KiB
Markdown

# Models - Data Models for Game Engine
## Purpose
Data models split into two systems:
- **Pydantic**: In-memory game state, API contracts, WebSocket serialization
- **SQLAlchemy**: Database persistence, relationships, audit trail
## Directory Structure
```
models/
├── __init__.py # Central exports - import from here
├── game_models.py # Pydantic in-memory state (GameState, decisions)
├── player_models.py # Polymorphic players (BasePlayer → SbaPlayer, PdPlayer)
├── db_models.py # SQLAlchemy ORM (Game, Play, Lineup)
└── roster_models.py # Roster link models
```
## Key Models
### GameState (game_models.py)
Core in-memory state for active games.
**Critical Fields**:
- Identity: `game_id`, `league_id`
- Teams: `home_team_id`, `away_team_id`, `*_is_ai`
- Game state: `inning`, `half`, `outs`, `*_score`
- Runners: `on_first`, `on_second`, `on_third` (LineupPlayerState)
- Current: `current_batter`, `current_pitcher`, `current_catcher`
- Decisions: `pending_defensive_decision`, `pending_offensive_decision`
**Helper Methods**: 20+ including `get_batting_team_id()`, `add_runner()`, `is_game_over()`
### LineupPlayerState
Lightweight player reference in lineup.
- `lineup_id`, `card_id`, `position`, `batting_order`, `is_active`
- `position_rating` (Optional - PD league only)
### TeamLineupState
Team's active lineup with helpers: `get_batting_order()`, `get_pitcher()`, `get_batter()`
### Decision Models
- **DefensiveDecision**: `alignment`, `infield_depth`, `outfield_depth`, `hold_runners`
- **OffensiveDecision**: `action`, `steal_attempts`, `hit_and_run`, `bunt_attempt`
### Player Models (player_models.py)
Polymorphic architecture for league-agnostic game engine.
```
BasePlayer (ABC)
├── SbaPlayer - Simple (id, name, image, positions)
└── PdPlayer - Complex (scouting data, ratings)
```
Factory: `Player.from_api_data(config, data)`
### Database Models (db_models.py)
| Model | Purpose |
|-------|---------|
| Game | Game container with status, scores, AI flags |
| Play | At-bat record with 25+ stat fields |
| Lineup | Player assignments and substitutions |
| GameSession | WebSocket state tracking |
| RosterLink | Eligible cards/players (polymorphic) |
## Common Patterns
### Import from Package
```python
from app.models import GameState, Game, SbaPlayer # ✅
from app.models.game_models import GameState # ❌
```
### Data Resolution
GameState uses minimal LineupPlayerState refs. Get full player data from StateManager:
```python
lineup_state = state_manager.get_lineup(game_id, team_id)
player = lineup_state.get_player_by_lineup_id(lineup_id)
```
### Pydantic Validation
All models use field validators for data integrity:
```python
@field_validator('position')
@classmethod
def validate_position(cls, v):
if v not in VALID_POSITIONS:
raise ValueError(...)
return v
```
## References
- **Game Recovery**: See `app/core/state_manager.py` for state rebuild
- **Database Schema**: See `app/database/CLAUDE.md` for table details
- **Type Checking**: See `backend/.claude/type-checking-guide.md`
---
**Tests**: `tests/unit/models/` | **Updated**: 2025-01-19