cf4fef22d8
13 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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> |
||
|
|
d1619b4a1f |
CLAUDE: Phase 3 - Substitution System Core Logic
Implemented comprehensive substitution system with DB-first pattern: ## Core Components (1,027 lines) 1. SubstitutionRules (345 lines) - Validates pinch hitter, defensive replacement, pitching change - Enforces no re-entry, roster eligibility, active status - Comprehensive error messages with error codes 2. SubstitutionManager (552 lines) - Orchestrates DB-first pattern: validate → DB → state - Handles pinch_hit, defensive_replace, change_pitcher - Automatic state sync and lineup cache updates 3. Database Operations (+115 lines) - create_substitution(): Creates sub with full metadata - get_eligible_substitutes(): Lists inactive players 4. Model Enhancements (+15 lines) - Added get_player_by_card_id() to TeamLineupState ## Key Features - ✅ DB-first pattern (database is source of truth) - ✅ Immutable lineup history (audit trail) - ✅ Comprehensive validation (8+ rule checks) - ✅ State + DB sync guaranteed - ✅ Error handling at every step - ✅ Detailed logging for debugging ## Architecture Decisions - Position flexibility (MVP - no eligibility check) - Batting order inheritance (pinch hitter takes spot) - No re-entry (matches real baseball rules) - Validation uses in-memory state (fast) ## Remaining Work - WebSocket event handlers (2-3 hours) - Comprehensive testing (2-3 hours) - API documentation (1 hour) 🤖 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> |
||
|
|
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) |
||
|
|
9b03fb555b |
CLAUDE: Implement play rollback functionality for error recovery
Add ability to roll back the last N plays, useful for correcting mistakes or recovering from corrupted plays. Deletes plays from database and reconstructs game state by replaying remaining plays. Database Operations (app/database/operations.py): - delete_plays_after(): Delete plays with play_number > target - delete_substitutions_after(): Delete lineup entries with after_play >= target - delete_rolls_after(): Delete dice rolls (kept for reference, not used) Game Engine (app/core/game_engine.py): - rollback_plays(): Main rollback orchestration - Validates: num_plays > 0, enough plays exist, game not completed - Deletes plays and substitutions from database - Clears in-memory roll tracking - Calls state_manager.recover_game() to rebuild state - Returns updated GameState Terminal Client (terminal_client/commands.py, terminal_client/repl.py): - rollback_plays(): Command wrapper with user-friendly output - do_rollback(): REPL command with argument parsing Usage: ⚾ > rollback 3 Validations: - Cannot roll back more plays than exist - Cannot roll back completed games - Rolling back across innings is allowed - Substitutions after rolled-back plays are undone Testing: - ✅ Successfully rolls back 2 plays from 5-play game - ✅ Correctly validates rollback of 10 plays when only 2 exist - ✅ Game state properly reconstructed via replay Note: Dice rolls kept in database for auditing (don't affect state). 🤖 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> |
||
|
|
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> |
||
|
|
9284162682 | Clean up false positive Pylance errors | ||
|
|
8f67883be1 |
CLAUDE: Implement polymorphic Lineup model for PD and SBA leagues
Updated Lineup model to support both leagues using the same pattern as RosterLink: - Made card_id nullable (PD league) - Added player_id nullable (SBA league) - Added XOR CHECK constraint to ensure exactly one ID is populated - Created league-specific methods: add_pd_lineup_card() and add_sba_lineup_player() - Replaced generic create_lineup_entry() with league-specific methods Database migration applied to convert existing schema. Bonus fix: Resolved Pendulum DateTime + asyncpg timezone compatibility issue by using .naive() on all DateTime defaults in Game, Play, and GameSession models. Updated tests to use league-specific lineup methods. Archived migration docs and script to .claude/archive/ for reference. 🤖 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> |
||
|
|
fc7f53adf3 |
CLAUDE: Complete Phase 1 backend infrastructure setup
Implemented full FastAPI backend with WebSocket support, database models, and comprehensive documentation for the Paper Dynasty game engine. Backend Implementation: - FastAPI application with Socket.io WebSocket server - SQLAlchemy async database models (Game, Play, Lineup, GameSession) - PostgreSQL connection to dev server (10.10.0.42:5432) - Connection manager for WebSocket lifecycle - JWT authentication utilities - Health check and stub API endpoints - Rotating file logger with Pendulum datetime handling - Redis via Docker Compose for caching Technical Details: - Python 3.13 with updated package versions - Pendulum 3.0 for all datetime operations - Greenlet for SQLAlchemy async support - Fixed SQLAlchemy reserved column names (metadata -> *_metadata) - Pydantic Settings with JSON array format for lists - Docker Compose V2 commands Documentation: - Updated backend/CLAUDE.md with environment-specific details - Created .claude/ENVIRONMENT.md for gotchas and quirks - Created QUICKSTART.md for developer onboarding - Documented all critical learnings and troubleshooting steps Database: - Tables created: games, plays, lineups, game_sessions - All indexes and foreign keys configured - Successfully tested connection and health checks Verified: - Server starts at http://localhost:8000 - Health endpoints responding - Database connection working - WebSocket infrastructure functional - Hot-reload working 🎯 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |