This commit includes Week 6 player models implementation and critical performance optimizations discovered during testing. ## Player Models (Week 6 - 50% Complete) **New Files:** - app/models/player_models.py (516 lines) - BasePlayer abstract class with polymorphic interface - SbaPlayer with API parsing factory method - PdPlayer with batting/pitching scouting data support - Supporting models: PdCardset, PdRarity, PdBattingCard, PdPitchingCard - tests/unit/models/test_player_models.py (692 lines) - 32 comprehensive unit tests, all passing - Tests for BasePlayer, SbaPlayer, PdPlayer, polymorphism **Architecture:** - Simplified single-layer approach vs planned two-layer - Factory methods handle API → Game transformation directly - SbaPlayer.from_api_response(data) - parses SBA API inline - PdPlayer.from_api_response(player_data, batting_data, pitching_data) - Full Pydantic validation, type safety, and polymorphism ## Performance Optimizations **Database Query Reduction (60% fewer queries per play):** - Before: 5 queries per play (INSERT play, SELECT play with JOINs, SELECT games, 2x SELECT lineups) - After: 2 queries per play (INSERT play, UPDATE games conditionally) Changes: 1. Lineup caching (game_engine.py:384-425) - Check state_manager.get_lineup() cache before DB fetch - Eliminates 2 SELECT queries per play 2. Remove unnecessary refresh (operations.py:281-302) - Removed session.refresh(play) after INSERT - Eliminates 1 SELECT with 3 expensive LEFT JOINs 3. Direct UPDATE statement (operations.py:109-165) - Changed update_game_state() to use direct UPDATE - No longer does SELECT + modify + commit 4. Conditional game state updates (game_engine.py:200-217) - Only UPDATE games table when score/inning/status changes - Captures state before/after and compares - ~40-60% fewer updates (many plays don't score) ## Bug Fixes 1. Fixed outs_before tracking (game_engine.py:551) - Was incorrectly calculating: state.outs - result.outs_recorded - Now correctly captures: state.outs (before applying result) - All play records now have accurate out counts 2. Fixed game recovery (state_manager.py:312-314) - AttributeError when recovering: 'GameState' has no attribute 'runners' - Changed to use state.get_all_runners() method - Games can now be properly recovered from database ## Enhanced Terminal Client **Status Display Improvements (terminal_client/display.py:75-97):** - Added "⚠️ WAITING FOR ACTION" section when play is pending - Shows specific guidance: - "The defense needs to submit their decision" → Run defensive [OPTIONS] - "The offense needs to submit their decision" → Run offensive [OPTIONS] - "Ready to resolve play" → Run resolve - Color-coded command hints for better UX ## Documentation Updates **backend/CLAUDE.md:** - Added comprehensive Player Models section (204 lines) - Updated Current Phase status to Week 6 (~50% complete) - Documented all optimizations and bug fixes - Added integration examples and usage patterns **New Files:** - .claude/implementation/week6-status-assessment.md - Comprehensive Week 6 progress review - Architecture decision rationale (single-layer vs two-layer) - Completion status and next priorities - Updated roadmap for remaining Week 6 work ## Test Results - Player models: 32/32 tests passing - All existing tests continue to pass - Performance improvements verified with terminal client ## Next Steps (Week 6 Remaining) 1. Configuration system (BaseConfig, SbaConfig, PdConfig) 2. Result charts & PD play resolution with ratings 3. API client for live roster data (deferred) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
66 lines
1.2 KiB
Python
66 lines
1.2 KiB
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,
|
|
LineupPlayerState,
|
|
TeamLineupState,
|
|
DefensiveDecision,
|
|
OffensiveDecision,
|
|
)
|
|
from app.models.roster_models import (
|
|
BaseRosterLinkData,
|
|
PdRosterLinkData,
|
|
SbaRosterLinkData,
|
|
RosterLinkCreate,
|
|
)
|
|
from app.models.player_models import (
|
|
BasePlayer,
|
|
SbaPlayer,
|
|
PdPlayer,
|
|
PdCardset,
|
|
PdRarity,
|
|
PdBattingRating,
|
|
PdPitchingRating,
|
|
PdBattingCard,
|
|
PdPitchingCard,
|
|
)
|
|
|
|
__all__ = [
|
|
# Database models
|
|
"Game",
|
|
"Play",
|
|
"Lineup",
|
|
"GameSession",
|
|
"RosterLink",
|
|
"GameCardsetLink",
|
|
# Game state models
|
|
"GameState",
|
|
"LineupPlayerState",
|
|
"TeamLineupState",
|
|
"DefensiveDecision",
|
|
"OffensiveDecision",
|
|
# Roster models
|
|
"BaseRosterLinkData",
|
|
"PdRosterLinkData",
|
|
"SbaRosterLinkData",
|
|
"RosterLinkCreate",
|
|
# Player models
|
|
"BasePlayer",
|
|
"SbaPlayer",
|
|
"PdPlayer",
|
|
"PdCardset",
|
|
"PdRarity",
|
|
"PdBattingRating",
|
|
"PdPitchingRating",
|
|
"PdBattingCard",
|
|
"PdPitchingCard",
|
|
]
|