Added league-agnostic roster tracking with single-table design: Database Changes: - Modified RosterLink model with surrogate primary key (id) - Added nullable card_id (PD) and player_id (SBA) columns - Added CHECK constraint ensuring exactly one ID populated (XOR logic) - Added unique constraints for (game_id, card_id) and (game_id, player_id) - Imported CheckConstraint and UniqueConstraint from SQLAlchemy New Files: - app/models/roster_models.py: Pydantic models for type safety - BaseRosterLinkData: Abstract base class - PdRosterLinkData: PD league card-based rosters - SbaRosterLinkData: SBA league player-based rosters - RosterLinkCreate: Request validation model - tests/unit/models/test_roster_models.py: 24 unit tests (all passing) - Tests for PD/SBA roster link creation and validation - Tests for RosterLinkCreate XOR validation - Tests for polymorphic behavior Database Operations: - add_pd_roster_card(): Add PD card to game roster - add_sba_roster_player(): Add SBA player to game roster - get_pd_roster(): Get PD cards with optional team filter - get_sba_roster(): Get SBA players with optional team filter - remove_roster_entry(): Remove roster entry by ID Tests: - Added 12 integration tests for roster operations - Fixed setup_database fixture scope (module → function) Documentation: - Updated backend/CLAUDE.md with RosterLink documentation - Added usage examples and design rationale - Updated Game model relationship description Design Pattern: Single table with application-layer type safety rather than SQLAlchemy polymorphic inheritance. Simpler queries, database-enforced integrity, and Pydantic type safety at application layer. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
47 lines
879 B
Python
47 lines
879 B
Python
"""Models package - exports for easy importing"""
|
|
|
|
from app.models.db_models import (
|
|
Game,
|
|
Play,
|
|
Lineup,
|
|
GameSession,
|
|
RosterLink,
|
|
GameCardsetLink,
|
|
)
|
|
from app.models.game_models import (
|
|
GameState,
|
|
RunnerState,
|
|
LineupPlayerState,
|
|
TeamLineupState,
|
|
DefensiveDecision,
|
|
OffensiveDecision,
|
|
)
|
|
from app.models.roster_models import (
|
|
BaseRosterLinkData,
|
|
PdRosterLinkData,
|
|
SbaRosterLinkData,
|
|
RosterLinkCreate,
|
|
)
|
|
|
|
__all__ = [
|
|
# Database models
|
|
"Game",
|
|
"Play",
|
|
"Lineup",
|
|
"GameSession",
|
|
"RosterLink",
|
|
"GameCardsetLink",
|
|
# Game state models
|
|
"GameState",
|
|
"RunnerState",
|
|
"LineupPlayerState",
|
|
"TeamLineupState",
|
|
"DefensiveDecision",
|
|
"OffensiveDecision",
|
|
# Roster models
|
|
"BaseRosterLinkData",
|
|
"PdRosterLinkData",
|
|
"SbaRosterLinkData",
|
|
"RosterLinkCreate",
|
|
]
|