beb939b32a
27 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
beb939b32a |
CLAUDE: Fix all unit test failures and implement 100% test requirement
Test Fixes (609/609 passing): - Fixed DiceSystem API to accept team_id/player_id parameters for audit trails - Fixed dice roll history timing issue in test - Fixed terminal client mock to match resolve_play signature (X-Check params) - Fixed result chart test mocks with missing pitching fields - Fixed flaky test by using groundball_a (exists in both batting/pitching) Documentation Updates: - Added Testing Policy section to backend/CLAUDE.md - Added Testing Policy section to tests/CLAUDE.md - Documented 100% unit test requirement before commits - Added git hook setup instructions Git Hook System: - Created .git-hooks/pre-commit script (enforces 100% test pass) - Created .git-hooks/install-hooks.sh (easy installation) - Created .git-hooks/README.md (hook documentation) - Hook automatically runs all unit tests before each commit - Blocks commits if any test fails All 609 unit tests now passing (100%) Integration tests have known asyncpg connection issues (documented) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
cf7cc23f45 |
CLAUDE: Fix runner_advancement for new GameState structure
Updated runner_advancement.py and its tests to use the new GameState
structure where current_batter is a LineupPlayerState object instead of
an integer ID.
Changes:
- runner_advancement.py: Replaced all 17 references to
state.current_batter_lineup_id with state.current_batter.lineup_id
- tests/unit/core/test_runner_advancement.py: Updated test fixtures
- Mock fixture: Added mock_batter object with lineup_id attribute
- GameState constructor calls: Create LineupPlayerState objects instead
of using current_batter_lineup_id parameter (9 tests fixed)
All 34 runner advancement tests now passing. This fixes the AttributeError
that was preventing X-Check resolution from completing in the terminal
client ("'GameState' object has no attribute 'current_batter_lineup_id'").
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
||
|
|
e6bd66ee39 |
CLAUDE: Fix game recovery for new GameState structure
Fixed state_manager._rebuild_state_from_data to provide required current_batter field when recovering games from database. The GameState model now requires current_batter as a LineupPlayerState object, but recovery was not populating this field, causing validation errors. Changes: - state_manager.py: Create placeholder current_batter during recovery - Build LineupPlayerState from first active batter (batting_order=1) - Fallback to first available lineup if no #1 batter found - Raise error if no lineups exist (invalid game state) - _prepare_next_play() will correct the batter after recovery - Moved get_lineup_player helper to top of method (removed duplicate) - tests/unit/core/test_state_manager.py: Update test to use new structure - test_update_state_nonexistent_raises_error: Create LineupPlayerState instead of using old current_batter_lineup_id field All 26 state_manager unit tests passing. Game recovery now works correctly in terminal client - fixes "current_batter Field required" validation error when running status command on recovered games. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
440adf2c26 |
CLAUDE: Update REPL for new GameState and standardize UV commands
Updated terminal client REPL to work with refactored GameState structure where current_batter/pitcher/catcher are now LineupPlayerState objects instead of integer IDs. Also standardized all documentation to properly show 'uv run' prefixes for Python commands. REPL Updates: - terminal_client/display.py: Access lineup_id from LineupPlayerState objects - terminal_client/repl.py: Fix typos (self.current_game → self.current_game_id) - tests/unit/terminal_client/test_commands.py: Create proper LineupPlayerState objects in test fixtures (2 tests fixed, all 105 terminal client tests passing) Documentation Updates (100+ command examples): - CLAUDE.md: Updated pytest examples to use 'uv run' prefix - terminal_client/CLAUDE.md: Updated ~40 command examples - tests/CLAUDE.md: Updated all test commands (unit, integration, debugging) - app/*/CLAUDE.md: Updated test and server startup commands (5 files) All Python commands now consistently use 'uv run' prefix to align with project's UV migration, improving developer experience and preventing confusion about virtual environment activation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
d560844704 |
CLAUDE: Phase 3E-Prep - Refactor GameState to use full LineupPlayerState objects
**Architectural Improvement**: Unified player references in GameState **Changed**: Make all player references consistent - BEFORE: current_batter/pitcher/catcher were IDs (int) - AFTER: current_batter/pitcher/catcher are full LineupPlayerState objects - Matches pattern of on_first/on_second/on_third (already objects) **Benefits**: 1. Consistent API - all player references use same type 2. Self-contained GameState - everything needed for resolution 3. No lookups needed - direct access to player data 4. Sets foundation for Phase 3E-Main (adding position ratings) **Files Modified**: - app/models/game_models.py: Changed current_batter/pitcher/catcher to objects - app/core/game_engine.py: Updated _prepare_next_play() to populate full objects - app/core/state_manager.py: Create placeholder batter on game creation - tests/unit/models/test_game_models.py: Updated all 27 GameState tests **Database Operations**: - No schema changes needed - Play table still stores IDs (for referential integrity) - IDs extracted from objects when saving: state.current_batter.lineup_id **Testing**: - All 27 GameState tests passing - No regressions in existing functionality - Type checking passes **Next**: Phase 3E-Main - Add PositionRating dataclass and load ratings at game start 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
fc0e2f100c |
CLAUDE: Integrate X-Check advancement with full GameState support
Updated X-Check runner advancement functions to properly delegate to existing result handlers for non-error cases. Changes: - Updated x_check_g1/g2/g3 signatures to accept GameState, hit_location, and defensive_decision parameters - Updated x_check_f1/f2/f3 signatures to accept GameState and hit_location - Implemented delegation logic: error cases use simple tables, non-error cases delegate to existing tested result handlers (_execute_result, _fb_result_*) - Updated PlayResolver._get_x_check_advancement() to pass new parameters - Updated all tests to provide required GameState fixtures Benefits: - Reuses 13 existing groundball + 4 flyball result handlers (DRY) - No DP probability needed - X-Check d20 already tested defender - Full game context: real lineup IDs, outs count, conditional logic - Error cases remain simple and efficient Test Results: 264/265 core tests passing (1 pre-existing dice failure) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
5f42576694 |
CLAUDE: Remove double-dipping on double play probability
Fixed incorrect double play logic that was rolling for probability twice - once for the chart result and again for execution. Changes: - Removed _calculate_double_play_probability() method entirely - Updated _gb_result_2() to execute DP deterministically - Updated _gb_result_10() to execute DP deterministically - Updated _gb_result_13() to execute DP deterministically - Removed TestDoublePlayProbability test class (5 tests) - Updated DP tests to reflect deterministic behavior Logic: Chart already determines outcome via dice roll. When chart says "Result 2: Double Play", the DP happens (if <2 outs and runner on 1st exists). No additional probability roll needed. Tests: 55/55 runner advancement tests passing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
fb282a5e54 |
CLAUDE: Fix critical X-Check bugs and improve dice rolling
Fixed two critical bugs in Phase 3D X-Check implementation plus improved dice audit trail for better tracking. BUG #1: on_base_code Mapping Error (Sequential vs Bit Field) ============================================================ The implementation incorrectly treated on_base_code as a bit field when it is actually a sequential lookup mapping. WRONG (bit field): Code 3 (0b011) → R1 + R2 Code 4 (0b100) → R3 only CORRECT (sequential): Code 3 → R3 only Code 4 → R1 + R2 Fixed: - build_advancement_from_code() decoder (sequential mapping) - build_flyball_advancement_with_error() decoder (sequential mapping) - 13 test on_base_code values (3↔4 corrections) - Updated documentation to clarify NOT a bit field BUG #2: Table Data Not Matching Official Charts ================================================ 7 table entries in G1_ADVANCEMENT_TABLE and G2_ADVANCEMENT_TABLE did not match the official rulebook charts provided by user. Fixed table entries: - G1 Code 1, Infield In: Changed Result 3 → 2 - G1 Code 3, Normal: Changed Result 13 → 3 - G1 Code 3, Infield In: Changed Result 3 → 1 - G1 Code 4, Normal: Changed Result 3 → 13 - G1 Code 4, Infield In: Changed Result 4 → 2 - G2 Code 3, Infield In: Changed Result 3 → 1 - G2 Code 4, Normal: Changed Result 5 → 4 Also fixed 7 test expectations to match corrected tables. IMPROVEMENT: Better Dice Audit Trail ===================================== Updated _resolve_x_check() in PlayResolver to use proper dice_system.roll_fielding() instead of manual die rolling. Benefits: - All dice tracked in audit trail (roll_id, timestamp, position) - Automatic error_total calculation (no manual 3d6 addition) - Consistent with codebase patterns - Position recorded for historical analysis Testing: - All 59 X-Check advancement tests passing (100%) - All 9 PlayResolver tests passing (100%) - All table entries validated against official charts - Complete codebase scan: no bit field operations found Files modified: - backend/app/core/x_check_advancement_tables.py - backend/tests/unit/core/test_x_check_advancement_tables.py - backend/app/core/play_resolver.py - .claude/implementation/PHASE_3D_CRITICAL_FIX.md (documentation) - .claude/implementation/GROUNDBALL_CHART_REFERENCE.md (new) - .claude/implementation/XCHECK_TEST_VALIDATION.md (new) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
cc5bf43e84 |
CLAUDE: Complete Phase 3B - Add all 6 infield error charts
Added complete error chart data for all infield positions to finalize Phase 3B X-Check league config tables implementation. Changes: - Added CATCHER_ERROR_CHART (17 ratings: 0-16) - Added FIRST_BASE_ERROR_CHART (31 ratings: 0-30) - Added SECOND_BASE_ERROR_CHART (40 ratings: 0-71, sparse) - Added THIRD_BASE_ERROR_CHART (45 ratings: 0-65, sparse) - Added SHORTSTOP_ERROR_CHART (43 ratings: 0-88, sparse) - Added PITCHER_ERROR_CHART (40 ratings: 0-51, sparse) All charts follow same structure as outfield charts with E3 field (empty for infield positions). Total ~250 lines of error chart data. Testing: - Updated test_infield_error_charts_complete() to verify charts populated - All 36 X-Check table tests passing - Verified chart structure matches outfield charts Phase 3B Status: 100% COMPLETE ✅ All defense tables complete, all error charts complete, ready for Phase 3C 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
0b6076d5b8 |
CLAUDE: Implement Phase 3B - X-Check league config tables
Complete X-Check resolution table system for defensive play outcomes. Components: - Defense range tables (20×5) for infield, outfield, catcher - Error charts for LF/RF and CF (ratings 0-25) - Placeholder error charts for P, C, 1B, 2B, 3B, SS (awaiting data) - get_fielders_holding_runners() - Complete implementation - get_error_chart_for_position() - Maps all 9 positions - 6 X-Check placeholder advancement functions (g1-g3, f1-f3) League Config Integration: - Both SbaConfig and PdConfig include X-Check tables - Shared common tables via league_configs.py - Attributes: x_check_defense_tables, x_check_error_charts, x_check_holding_runners Testing: - 36 tests for X-Check tables (all passing) - 9 tests for X-Check placeholders (all passing) - Total: 45/45 tests passing Documentation: - Updated backend/CLAUDE.md with Phase 3B section - Updated app/config/CLAUDE.md with X-Check tables documentation - Updated app/core/CLAUDE.md with X-Check placeholder functions - Updated tests/CLAUDE.md with new test counts (519 unit tests) - Updated phase-3b-league-config-tables.md (marked complete) - Updated NEXT_SESSION.md with Phase 3B completion What's Pending: - 6 infield error charts need actual data (P, C, 1B, 2B, 3B, SS) - Phase 3C will implement full X-Check resolution logic 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
a696473d0a |
CLAUDE: Integrate flyball advancement with RunnerAdvancement system
Major Phase 2 refactoring to consolidate runner advancement logic: **Flyball System Enhancement**: - Add FLYOUT_BQ variant (medium-shallow depth) - 4 flyball types with clear semantics: A (deep), B (medium), BQ (medium-shallow), C (shallow) - Updated helper methods to include FLYOUT_BQ **RunnerAdvancement Integration**: - Extend runner_advancement.py to handle both groundballs AND flyballs - advance_runners() routes to _advance_runners_groundball() or _advance_runners_flyball() - Comprehensive flyball logic with proper DECIDE mechanics per flyball type - No-op movements recorded for state recovery consistency **PlayResolver Refactoring**: - Consolidate all 4 flyball outcomes to delegate to RunnerAdvancement (DRY) - Eliminate duplicate flyball resolution code - Rename helpers for clarity: _advance_on_single_1/_advance_on_single_2 (was _advance_on_single) - Fix single/double advancement logic for different hit types **State Recovery Fix**: - Fix state_manager.py game recovery to build LineupPlayerState objects properly - Use get_lineup_player() helper to construct from lineup data - Correctly track runners in on_first/on_second/on_third fields (matches Phase 2 model) **Database Support**: - Add runner tracking fields to play data for accurate recovery - Include batter_id, on_first_id, on_second_id, on_third_id, and *_final fields **Type Safety Improvements**: - Fix lineup_id access throughout runner_advancement.py (was accessing on_first directly, now on_first.lineup_id) - Make current_batter_lineup_id non-optional (always set by _prepare_next_play) - Add type: ignore for known SQLAlchemy false positives **Documentation**: - Update CLAUDE.md with comprehensive flyball documentation - Add flyball types table, usage examples, and test coverage notes - Document differences between groundball and flyball mechanics **Testing**: - Add test_flyball_advancement.py with 21 flyball tests - Coverage: all 4 types, DECIDE scenarios, no-op movements, edge cases 🚀 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
23a0a1db4e |
CLAUDE: Update tests to match Phase 2 model changes
- Update test fixtures to provide required current_batter_lineup_id field - Update validator tests for new infield depth values (infield_in, normal, corners_in) - Update runner advancement tests to match refactored runner management - Update game model tests to work with direct base references - Update play resolver tests for enhanced logic - Add missing imports in test files All changes ensure tests align with recent Phase 2 implementation updates including the transition from RunnerState list to direct base references (on_first, on_second, on_third) in GameState model. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
76e24ab22b |
CLAUDE: Refactor ManualOutcomeSubmission to use PlayOutcome enum + comprehensive documentation
## Refactoring - Changed `ManualOutcomeSubmission.outcome` from `str` to `PlayOutcome` enum type - Removed custom validator (Pydantic handles enum validation automatically) - Added direct import of PlayOutcome (no circular dependency due to TYPE_CHECKING guard) - Updated tests to use enum values while maintaining backward compatibility Benefits: - Better type safety with IDE autocomplete - Cleaner code (removed 15 lines of validator boilerplate) - Backward compatible (Pydantic auto-converts strings to enum) - Access to helper methods (is_hit(), is_out(), etc.) Files modified: - app/models/game_models.py: Enum type + import - tests/unit/config/test_result_charts.py: Updated 7 tests + added compatibility test ## Documentation Created comprehensive CLAUDE.md files for all backend/app/ subdirectories to help future AI agents quickly understand and work with the code. Added 8,799 lines of documentation covering: - api/ (906 lines): FastAPI routes, health checks, auth patterns - config/ (906 lines): League configs, PlayOutcome enum, result charts - core/ (1,288 lines): GameEngine, StateManager, PlayResolver, dice system - data/ (937 lines): API clients (planned), caching layer - database/ (945 lines): Async sessions, operations, recovery - models/ (1,270 lines): Pydantic/SQLAlchemy models, polymorphic patterns - utils/ (959 lines): Logging, JWT auth, security - websocket/ (1,588 lines): Socket.io handlers, real-time events - tests/ (475 lines): Testing patterns and structure Each CLAUDE.md includes: - Purpose & architecture overview - Key components with detailed explanations - Patterns & conventions - Integration points - Common tasks (step-by-step guides) - Troubleshooting with solutions - Working code examples - Testing guidance Total changes: +9,294 lines / -24 lines Tests: All passing (62/62 model tests, 7/7 ManualOutcomeSubmission tests) |
||
|
|
e2f1d6079f |
CLAUDE: Implement Week 7 Task 6 - PlayResolver Integration with RunnerAdvancement
Major Refactor: Outcome-First Architecture - PlayResolver now accepts league_id and auto_mode in constructor - Added core resolve_outcome() method - all resolution logic in one place - Added resolve_manual_play() wrapper for manual submissions (primary) - Added resolve_auto_play() wrapper for PD auto mode (rare) - Removed SimplifiedResultChart (obsolete with new architecture) - Removed play_resolver singleton RunnerAdvancement Integration: - All groundball outcomes (GROUNDBALL_A/B/C) now use RunnerAdvancement - Proper DP probability calculation with positioning modifiers - Hit location tracked for all relevant outcomes - 13 result types fully integrated from advancement charts Game State Updates: - Added auto_mode field to GameState (stored per-game) - Updated state_manager.create_game() to accept auto_mode parameter - GameEngine now uses state.auto_mode to create appropriate resolver League Configuration: - Added supports_auto_mode() to BaseGameConfig - SbaConfig: returns False (no digitized cards) - PdConfig: returns True (has digitized ratings) - PlayResolver validates auto mode support and raises error for SBA Play Results: - Added hit_location field to PlayResult - Groundballs include location from RunnerAdvancement - Flyouts track hit_location for tag-up logic (future) - Other outcomes have hit_location=None Testing: - Completely rewrote test_play_resolver.py for new architecture - 9 new tests covering initialization, strikeouts, walks, groundballs, home runs - All 9 tests passing - All 180 core tests still passing (1 pre-existing failure unrelated) Terminal Client: - No changes needed - defaults to manual mode (auto_mode=False) - Perfect for human testing of manual submissions This completes Week 7 Task 6 - the final task of Week 7! Week 7 is now 100% complete with all 8 tasks done. 🎯 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
102cbb6081 |
CLAUDE: Implement Week 7 Tasks 4 & 5 - Runner advancement logic and double play mechanics
- Created runner_advancement.py with complete groundball advancement system - Implemented GroundballResultType IntEnum with 13 rulebook-aligned results - Built RunnerAdvancement class with chart lookup logic (Infield Back/In) - Implemented all 13 result handlers (gb_result_1 through gb_result_13) - Added DECIDE mechanic support for interactive runner advancement decisions - Implemented double play probability calculation with positioning modifiers - Created 30 comprehensive unit tests covering all scenarios (100% passing) Key Features: - Supports Infield Back and Infield In defensive positioning - Handles Corners In hybrid positioning (applies In rules to corner fielders) - Conditional results based on hit location (middle IF, right side, corners) - Force play detection and advancement logic - Double play mechanics with probability-based success (45% base rate) - Result types match official rulebook exactly (1-13) Architecture: - IntEnum for result types (type-safe, self-documenting) - Comprehensive hit location tracking (1B, 2B, SS, 3B, P, C, LF, CF, RF) - Dataclasses for movements (RunnerMovement, AdvancementResult) - Probability modifiers: Infield In (-15%), hit location (±10%) Testing: - 30 unit tests covering chart lookup, all result types, and edge cases - Double play probability validation - All on-base codes (0-7) tested - All groundball types (A, B, C) verified Status: Week 7 Tasks 4 & 5 complete (~87% of Week 7 finished) Next: Task 6 (PlayResolver Integration) Related: #task4 #task5 #runner-advancement #double-play #week7 |
||
|
|
9cae63ac43 |
CLAUDE: Implement Week 7 Task 7 - WebSocket manual outcome handlers
Complete manual outcome workflow for SBA and PD manual mode gameplay: **WebSocket Event Handlers** (app/websocket/handlers.py): - roll_dice: Server rolls dice, stores in state, broadcasts to players - submit_manual_outcome: Validates and processes player submissions - Events: dice_rolled, outcome_accepted, outcome_rejected, play_resolved **Game Engine Integration** (app/core/game_engine.py): - resolve_manual_play(): Processes manual outcomes with server dice - Uses ab_roll for audit trail, player outcome for resolution - Same orchestration as resolve_play() (save, update, advance inning) **Data Model** (app/models/game_models.py): - pending_manual_roll: Stores server dice between roll and submission **Terminal Client** (terminal_client/): - roll_dice command: Roll dice and display results - manual_outcome command: Submit outcomes from physical cards - Both integrated into REPL for testing **Tests** (tests/unit/websocket/test_manual_outcome_handlers.py): - 12 comprehensive tests covering all validation paths - All tests passing (roll_dice: 4, submit_manual_outcome: 8) **Key Decisions**: - Server rolls dice for fairness (not players!) - One-time roll usage (cleared after submission) - Early validation (check pending roll before accepting) - Field-level error messages for clear feedback **Impact**: - Complete manual mode workflow ready - Frontend WebSocket integration supported - Terminal testing commands available - Audit trail with server-rolled dice maintained 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
9245b4e008 |
CLAUDE: Implement Week 7 Task 3 - Result chart abstraction and PD auto mode
Core Implementation: - Added ResultChart abstract base class with get_outcome() method - Implemented calculate_hit_location() helper for hit distribution - 45% pull, 35% center, 20% opposite field - RHB pulls left, LHB pulls right - Groundballs → infield positions, flyouts → outfield positions - Added PlayOutcome.requires_hit_location() helper method - Returns True for groundballs and flyouts only Manual Mode Support: - Added ManualResultChart (passthrough for interface completeness) - Manual mode doesn't use result charts - players submit directly - Added ManualOutcomeSubmission model for WebSocket submissions - Validates PlayOutcome enum values - Validates hit location positions (1B, 2B, SS, 3B, LF, CF, RF, P, C) PD Auto Mode Implementation: - Implemented PdAutoResultChart for automated outcome generation - Coin flip (50/50) to choose batting or pitching card - Gets rating for correct handedness matchup - Builds cumulative distribution from rating percentages - Rolls 1d100 to select outcome - Calculates hit location using handedness and pull rates - Maps rating fields to PlayOutcome enum: - Common: homerun, triple, doubles, singles, walks, strikeouts - Batting-specific: lineouts, popouts, flyout variants, groundout variants - Pitching-specific: uncapped singles/doubles, flyouts by location - Proper error handling when card data missing Testing: - Created 21 comprehensive unit tests (all passing) - Helper function tests (calculate_hit_location) - PlayOutcome helper tests (requires_hit_location) - ManualResultChart tests (NotImplementedError) - PdAutoResultChart tests: - Coin flip distribution (~50/50) - Handedness matchup selection - Cumulative distribution building - Outcome selection from probabilities - Hit location calculation - Error handling for missing cards - Statistical distribution verification (1000 trials) - ManualOutcomeSubmission validation tests - Valid/invalid outcomes - Valid/invalid hit locations - Optional location handling Deferred to Future Tasks: - PlayResolver integration (Phase 6 - Week 7 Task 3B) - Terminal client manual outcome command (Phase 8) - WebSocket handlers for manual submissions (Week 7 Task 6) - Runner advancement logic using hit locations (Week 7 Task 4) Files Modified: - app/config/result_charts.py: Added base class, auto mode, and helpers - app/models/game_models.py: Added ManualOutcomeSubmission model - tests/unit/config/test_result_charts.py: 21 comprehensive tests All tests passing, no regressions. |
||
|
|
c0051d2a65 |
CLAUDE: Fix defensive decision validation for corners_in/infield_in depths
- Updated validators.py to use is_runner_on_third() helper method instead of hardcoded on_base_code values - Fixed DefensiveDecision Pydantic model: infield depths now ['infield_in', 'normal', 'corners_in'] - Fixed DefensiveDecision Pydantic model: outfield depths now ['in', 'normal'] (removed 'back') - Removed invalid double_play depth tests (depth doesn't exist) - Added proper tests for corners_in and infield_in validation (requires runner on third) - All 54 validator tests now passing Changes maintain consistency between Pydantic validation and GameValidator logic. |
||
|
|
121a9082f1 |
CLAUDE: Implement Week 7 Task 2 - Decision Validators
- Enhanced validate_defensive_decision() with comprehensive validation: - Validate all alignments (normal, shifted_left, shifted_right, extreme_shift) - Validate all infield depths (in, normal, back, double_play) - Validate all outfield depths (in, normal, back) - Validate hold_runners require actual runners on specified bases - Validate hold_runners only on bases 1, 2, or 3 - Validate double_play depth requires runner on first - Validate double_play depth not allowed with 2 outs - Enhanced validate_offensive_decision() with comprehensive validation: - Validate all approaches (normal, contact, power, patient) - Validate steal_attempts only to bases 2, 3, or 4 - Validate steal_attempts require runner on base-1 - Validate bunt_attempt not allowed with 2 outs - Validate bunt_attempt and hit_and_run cannot be simultaneous - Validate hit_and_run requires at least one runner on base - Added 24+ comprehensive test cases covering all edge cases: - 13 new defensive decision validation tests - 16 new offensive decision validation tests - All tests pass (54/54 passing) Clear error messages for all validation failures. Follows 'Raise or Return' pattern with ValidationError exceptions. |
||
|
|
6880b6d5ad |
CLAUDE: Complete Week 6 - granular PlayOutcome integration and metadata support
- Renamed check_d20 → chaos_d20 throughout dice system - Expanded PlayOutcome enum with granular variants (SINGLE_1/2, DOUBLE_2/3, GROUNDBALL_A/B/C, etc.) - Integrated PlayOutcome from app.config into PlayResolver - Added play_metadata support for uncapped hit tracking - Updated all tests (139/140 passing) Week 6: 100% Complete - Ready for Phase 3 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
5d5c13f2b8 |
CLAUDE: Implement Week 6 league configuration and play outcome systems
Week 6 Progress: 75% Complete ## Components Implemented ### 1. League Configuration System ✅ - Created BaseGameConfig abstract class for league-agnostic rules - Implemented SbaConfig and PdConfig with league-specific settings - Immutable configs (frozen=True) with singleton registry - 28 unit tests, all passing Files: - backend/app/config/base_config.py - backend/app/config/league_configs.py - backend/tests/unit/config/test_league_configs.py ### 2. PlayOutcome Enum ✅ - Universal enum for all play outcomes (both SBA and PD) - Helper methods: is_hit(), is_out(), is_uncapped(), is_interrupt() - Supports standard hits, uncapped hits, interrupt plays, ballpark power - 30 unit tests, all passing Files: - backend/app/config/result_charts.py - backend/tests/unit/config/test_play_outcome.py ### 3. Player Model Refinements ✅ - Fixed PdPlayer.id field mapping (player_id → id) - Improved field docstrings for image types - Fixed position checking logic in SBA helper methods - Added safety checks for missing image data Files: - backend/app/models/player_models.py (updated) ### 4. Documentation ✅ - Updated backend/CLAUDE.md with Week 6 section - Documented card-based resolution mechanics - Detailed config system and PlayOutcome usage ## Architecture Decisions 1. **Card-Based Resolution**: Both SBA and PD use same mechanics - 1d6 (column) + 2d6 (row) + 1d20 (split resolution) - PD: Digitized cards with auto-resolution - SBA: Manual entry from physical cards 2. **Immutable Configs**: Prevent accidental modification using Pydantic frozen 3. **Universal PlayOutcome**: Single enum for both leagues reduces duplication ## Testing - Total: 58 tests, all passing - Config tests: 28 - PlayOutcome tests: 30 ## Remaining Work (25%) - Update dice system (check_d20 → chaos_d20) - Integrate PlayOutcome into PlayResolver - Add Play.metadata support for uncapped hits 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
1c32787195 |
CLAUDE: Refactor game models and modularize terminal client
This commit includes cleanup from model refactoring and terminal client
modularization for better code organization and maintainability.
## Game Models Refactor
**Removed RunnerState class:**
- Eliminated separate RunnerState model (was redundant)
- Replaced runners: List[RunnerState] with direct base references:
- on_first: Optional[LineupPlayerState]
- on_second: Optional[LineupPlayerState]
- on_third: Optional[LineupPlayerState]
- Updated helper methods:
- get_runner_at_base() now returns LineupPlayerState directly
- get_all_runners() returns List[Tuple[int, LineupPlayerState]]
- is_runner_on_X() simplified to direct None checks
**Benefits:**
- Matches database structure (plays table has on_first_id, etc.)
- Simpler state management (direct references vs list management)
- Better type safety (LineupPlayerState vs generic runner)
- Easier to work with in game engine logic
**Updated files:**
- app/models/game_models.py - Removed RunnerState, updated GameState
- app/core/play_resolver.py - Use get_all_runners() instead of state.runners
- app/core/validators.py - Updated runner access patterns
- tests/unit/models/test_game_models.py - Updated test assertions
- tests/unit/core/test_play_resolver.py - Updated test data
- tests/unit/core/test_validators.py - Updated test data
## Terminal Client Refactor
**Modularization (DRY principle):**
Created separate modules for better code organization:
1. **terminal_client/commands.py** (10,243 bytes)
- Shared command functions for game operations
- Used by both CLI (main.py) and REPL (repl.py)
- Functions: submit_defensive_decision, submit_offensive_decision,
resolve_play, quick_play_sequence
- Single source of truth for command logic
2. **terminal_client/arg_parser.py** (7,280 bytes)
- Centralized argument parsing and validation
- Handles defensive/offensive decision arguments
- Validates formats (alignment, depths, hold runners, steal attempts)
3. **terminal_client/completions.py** (10,357 bytes)
- TAB completion support for REPL mode
- Command completions, option completions, dynamic completions
- Game ID completions, defensive/offensive option suggestions
4. **terminal_client/help_text.py** (10,839 bytes)
- Centralized help text and command documentation
- Detailed command descriptions
- Usage examples for all commands
**Updated main modules:**
- terminal_client/main.py - Simplified by using shared commands module
- terminal_client/repl.py - Cleaner with shared functions and completions
**Benefits:**
- DRY: Behavior consistent between CLI and REPL modes
- Maintainability: Changes in one place affect both interfaces
- Testability: Can test commands module independently
- Organization: Clear separation of concerns
## Documentation
**New files:**
- app/models/visual_model_relationships.md
- Visual documentation of model relationships
- Helps understand data flow between models
- terminal_client/update_docs/ (6 phase documentation files)
- Phased documentation for terminal client evolution
- Historical context for implementation decisions
## Tests
**New test files:**
- tests/unit/terminal_client/__init__.py
- tests/unit/terminal_client/test_arg_parser.py
- tests/unit/terminal_client/test_commands.py
- tests/unit/terminal_client/test_completions.py
- tests/unit/terminal_client/test_help_text.py
**Updated tests:**
- Integration tests updated for new runner model
- Unit tests updated for model changes
- All tests passing with new structure
## Summary
- ✅ Simplified game state model (removed RunnerState)
- ✅ Better alignment with database structure
- ✅ Modularized terminal client (DRY principle)
- ✅ Shared command logic between CLI and REPL
- ✅ Comprehensive test coverage
- ✅ Improved documentation
Total changes: 26 files modified/created
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
||
|
|
aabb90feb5 |
CLAUDE: Implement player models and optimize database queries
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> |
||
|
|
f3238c4e6d |
CLAUDE: Complete Week 5 testing and update documentation
Add comprehensive unit and integration tests for Week 5 deliverables: - test_play_resolver.py: 18 tests covering outcome resolution and runner advancement - test_validators.py: 36 tests covering game state, decisions, lineups, and flow - test_game_engine.py: 7 test classes for complete game flow integration Update implementation documentation to reflect completed status: - 00-index.md: Mark Phase 2 Weeks 4-5 complete with test coverage - 02-week5-game-logic.md: Comprehensive test details and completion status - 02-game-engine.md: Forward-looking snapshot pattern documentation Week 5 now fully complete with 54 unit tests + 7 integration test classes passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
874e24dc75 |
CLAUDE: Implement comprehensive dice roll system with persistence
Core Implementation: - Created roll_types.py with AbRoll, JumpRoll, FieldingRoll, D20Roll dataclasses - Implemented DiceSystem singleton with cryptographically secure random generation - Added Roll model to db_models.py with JSONB storage for roll history - Implemented save_rolls_batch() and get_rolls_for_game() in database operations Testing: - 27 unit tests for roll type dataclasses (100% passing) - 35 unit tests for dice system (34/35 passing, 1 timing issue) - 16 integration tests for database persistence (uses production DiceSystem) Features: - Unique roll IDs using secrets.token_hex() - League-specific logic (SBA d100 rare plays, PD error-based rare plays) - Automatic derived value calculation (d6_two_total, jump_total, error_total) - Full audit trail with context metadata - Support for batch saving rolls per inning Technical Details: - Fixed dataclass inheritance with kw_only=True for Python 3.13 - Roll data stored as JSONB for flexible querying - Indexed on game_id, roll_type, league_id, team_id for efficient retrieval - Supports filtering by roll type, team, and timestamp ordering Note: Integration tests have async connection pool issue when run together (tests work individually, fixture cleanup needed in follow-up branch) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
3c5055dbf6 |
CLAUDE: Implement polymorphic RosterLink for both PD and SBA leagues
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> |
||
|
|
a287784328 |
CLAUDE: Complete Week 4 - State Management & Persistence
Implemented hybrid state management system with in-memory game states and async PostgreSQL persistence. This provides the foundation for fast gameplay (<500ms response) with complete state recovery capabilities. ## Components Implemented ### Production Code (3 files, 1,150 lines) - app/models/game_models.py (492 lines) - Pydantic GameState with 20+ helper methods - RunnerState, LineupPlayerState, TeamLineupState - DefensiveDecision and OffensiveDecision models - Full Pydantic v2 validation with field validators - app/core/state_manager.py (296 lines) - In-memory state management with O(1) lookups - State recovery from database - Idle game eviction mechanism - Statistics tracking - app/database/operations.py (362 lines) - Async PostgreSQL operations - Game, lineup, and play persistence - Complete state loading for recovery - GameSession WebSocket state tracking ### Tests (4 files, 1,963 lines, 115 tests) - tests/unit/models/test_game_models.py (60 tests, ALL PASSING) - tests/unit/core/test_state_manager.py (26 tests, ALL PASSING) - tests/integration/database/test_operations.py (21 tests) - tests/integration/test_state_persistence.py (8 tests) - pytest.ini (async test configuration) ### Documentation (6 files) - backend/CLAUDE.md (updated with Week 4 patterns) - .claude/implementation/02-week4-state-management.md (marked complete) - .claude/status-2025-10-22-0113.md (planning session summary) - .claude/status-2025-10-22-1147.md (implementation session summary) - .claude/implementation/player-data-catalog.md (player data reference) - Week 5 & 6 plans created ## Key Features - Hybrid state: in-memory (fast) + PostgreSQL (persistent) - O(1) state access via dictionary lookups - Async database writes (non-blocking) - Complete state recovery from database - Pydantic validation on all models - Helper methods for common game operations - Idle game eviction with configurable timeout - 86 unit tests passing (100%) ## Performance - State access: O(1) via UUID lookup - Memory per game: ~1KB (just state) - Target response time: <500ms ✅ - Database writes: <100ms (async) ✅ ## Testing - Unit tests: 86/86 passing (100%) - Integration tests: 29 written - Test configuration: pytest.ini created - Fixed Pydantic v2 config deprecation - Fixed pytest-asyncio configuration 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |