Commit Graph

25 Commits

Author SHA1 Message Date
Cal Corum
be31e2ccb4 CLAUDE: Complete in-game UI overhaul with player cards and outcome wizard
Features:
- PlayerCardModal: Tap any player to view full playing card image
- OutcomeWizard: Progressive 3-step outcome selection (On Base/Out/X-Check)
- GameBoard: Expandable view showing all 9 fielder positions
- Post-roll card display: Shows batter/pitcher card based on d6 roll
- CurrentSituation: Tappable player cards with modal integration

Bug fixes:
- Fix batter not advancing after play (state_manager recovery logic)
- Add dark mode support for buttons and panels (partial - iOS issue noted)

New files:
- PlayerCardModal.vue, OutcomeWizard.vue, BottomSheet.vue
- outcomeFlow.ts constants for outcome category mapping
- TEST_PLAN_UI_OVERHAUL.md with 23/24 tests passing

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 15:23:38 -06:00
Cal Corum
e058bc4a6c CLAUDE: RosterLink refactor for bench players with cached player data
- Add player_positions JSONB column to roster_links (migration 006)
- Add player_data JSONB column to cache name/image/headshot (migration 007)
- Add is_pitcher/is_batter computed properties for two-way player support
- Update lineup submission to populate RosterLink with all players + positions
- Update get_bench handler to use cached data (no runtime API calls)
- Add BenchPlayer type to frontend with proper filtering
- Add new Lineup components: InlineSubstitutionPanel, LineupSlotRow,
  PositionSelector, UnifiedLineupTab
- Add integration tests for get_bench_players

Bench players now load instantly without API dependency, and properly
filter batters vs pitchers (including CP closer position).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 22:15:12 -06:00
Cal Corum
64325d7163 CLAUDE: Fix game recovery to load team display info and add score text outline
Backend:
- Add game_metadata to load_game_state() return dict in DatabaseOperations
- Populate team display fields (name, color, thumbnail) in _rebuild_state_from_data()
  so recovered games show team colors/names

Frontend:
- Add text-outline CSS for score visibility on any background (light logos, gradients)
- Handle thumbnail 404 with @error event, show enhanced shadow when no thumbnail
- Apply consistent outline across mobile and desktop layouts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 09:03:59 -06:00
Cal Corum
d60b7a2d60 CLAUDE: Store team display info in DB and fix lineup auto-start
Backend:
- Add game_metadata to create_game() and quick_create_game() endpoints
- Fetch team display info (lname, sname, abbrev, color, thumbnail) from
  SBA API at game creation time and store in DB
- Populate GameState with team display fields from game_metadata
- Fix submit_team_lineup to cache lineup in state_manager after DB write
  so auto-start correctly detects both teams ready

Frontend:
- Read team colors/names/thumbnails from gameState instead of useState
- Remove useState approach that failed across SSR navigation
- Fix create.vue redirect from legacy /games/lineup/[id] to /games/[id]
- Update game.vue header to show team names from gameState

Docs:
- Update CLAUDE.md to note dev mode has broken auth, always use prod

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 08:43:26 -06:00
Cal Corum
a22513b053 CLAUDE: Add schedule_game_id linking for webapp games to external schedules
Enables precise tracking of which webapp games correspond to specific
scheduled matchups from SBA/PD league systems.

Backend:
- Add schedule_game_id column to games table with index
- Create Alembic migration for the new column
- Update QuickCreateRequest to accept schedule_game_id
- Update GameListItem response to include schedule_game_id
- Update DatabaseOperations.create_game() to store the link

Frontend:
- Pass schedule_game_id when creating game from "Play" button
- Add activeScheduleGameMap to track webapp games by schedule ID
- Show "In Progress" (green) link for active games
- Show "Resume" (green) link for pending games
- Show "Play" (blue) button for unstarted games

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 23:55:53 -06:00
Cal Corum
9c90893b5d CLAUDE: Update documentation across codebase
Updated CLAUDE.md files with:
- Current test counts and status
- Session injection pattern documentation
- New module references and architecture notes
- Updated Phase status (3E-Final complete)
- Enhanced troubleshooting guides

Files updated:
- Root CLAUDE.md: Project overview and phase status
- backend/CLAUDE.md: Backend overview with test counts
- backend/README.md: Quick start and development guide
- backend/app/api/CLAUDE.md: API routes documentation
- backend/app/database/CLAUDE.md: Session injection docs
- backend/app/utils/CLAUDE.md: Utilities documentation
- backend/tests/CLAUDE.md: Testing patterns and policy
- frontend-sba/CLAUDE.md: Frontend overview
- frontend-sba/store/CLAUDE.md: Store patterns

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 12:10:10 -06:00
Cal Corum
9d0d29ef18 CLAUDE: Add Alembic migrations and database session injection
Database Infrastructure:
- Added Alembic migration system (alembic.ini, env.py)
- Migration 001: Initial schema
- Migration 004: Stat materialized views (enhanced)
- Migration 005: Composite indexes for performance
- operations.py: Session injection support for test isolation
- session.py: Enhanced session management

Application Updates:
- main.py: Integration with new database infrastructure
- health.py: Enhanced health checks with pool monitoring

Integration Tests:
- conftest.py: Session injection pattern for reliable tests
- test_operations.py: Database operations tests
- test_migrations.py: Migration verification tests

Session injection pattern enables:
- Production: Auto-commit per operation
- Testing: Shared session with automatic rollback
- Transactions: Multiple ops, single commit

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 12:09:09 -06:00
Cal Corum
bcbf6036c7 CLAUDE: Fix state recovery batter advancement and flyball descriptions
This commit fixes two critical bugs in the game engine and updates tests
to match current webhook behavior:

1. State Recovery - Batter Advancement (operations.py:545-546)
   - Added missing batting_order and outs_recorded fields to plays dictionary
   - These fields exist in database but weren't loaded by load_game_state()
   - Root cause: Batter index was correctly recovered but current_batter remained
     at placeholder (batting_order=1) because recovery logic couldn't find the
     actual batting_order from last play
   - Fix enables proper batter advancement after backend restarts

2. Flyball Descriptions - 2 Outs Logic (runner_advancement.py)
   - Made flyball descriptions dynamic based on outs and actual base runners
   - FLYOUT_A (Deep): Lines 1352-1363
   - FLYOUT_B (Medium): Lines 1438-1449
   - FLYOUT_BQ (Medium-shallow): Lines 1521-1530
   - With 2 outs: "3rd out, inning over" (no advancement possible)
   - With 0-1 outs: Dynamic based on runners ("R3 scores" only if R3 exists)
   - Game logic was already correct (runs_scored=0), only descriptions were wrong
   - Fixed method signatures to include hit_location parameter for all flyball methods
   - Updated X-check function calls to pass hit_location parameter

3. Test Updates
   - Fixed test expectation in test_flyball_advancement.py to match corrected behavior
   - Descriptions now only show runners that actually exist (no phantom "R2 DECIDE")
   - Auto-fixed import ordering with Ruff
   - Updated websocket tests to match current webhook behavior:
     * test_submit_manual_outcome_success now expects 2 broadcasts (play_resolved + game_state_update)
     * test_submit_manual_outcome_missing_required_location updated to reflect hit_location now optional

Testing:
- All 739 unit tests passing (100%)
- Verified batter advances correctly after state recovery
- Verified flyball with 2 outs shows correct description
- Verified dynamic descriptions only mention actual runners on base
- Verified websocket handler broadcasts work correctly

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 15:38:29 -06:00
Cal Corum
a4b99ee53e CLAUDE: Replace black and flake8 with ruff for formatting and linting
Migrated to ruff for faster, modern code formatting and linting:

Configuration changes:
- pyproject.toml: Added ruff 0.8.6, removed black/flake8
- Configured ruff with black-compatible formatting (88 chars)
- Enabled comprehensive linting rules (pycodestyle, pyflakes, isort,
  pyupgrade, bugbear, comprehensions, simplify, return)
- Updated CLAUDE.md: Changed code quality commands to use ruff

Code improvements (490 auto-fixes):
- Modernized type hints: List[T] → list[T], Dict[K,V] → dict[K,V],
  Optional[T] → T | None
- Sorted all imports (isort integration)
- Removed unused imports
- Fixed whitespace issues
- Reformatted 38 files for consistency

Bug fixes:
- app/core/play_resolver.py: Fixed type hint bug (any → Any)
- tests/unit/core/test_runner_advancement.py: Removed obsolete random mock

Testing:
- All 739 unit tests passing (100%)
- No regressions introduced

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 15:33:21 -06:00
Cal Corum
72a3b94ce7 CLAUDE: Add transaction handling for multi-step DB operations
Issue #4 from code review - multi-step database operations were not
wrapped in transactions, risking partial state on failure.

Changes:
- Modified save_play() and update_game_state() in DatabaseOperations
  to accept optional session parameter for transaction grouping
- Wrapped resolve_play() DB operations in single atomic transaction
- Wrapped resolve_manual_play() DB operations in single atomic transaction
- Transaction commits atomically or rolls back entirely on failure

Pattern: When session provided, use flush() for IDs without committing;
caller controls transaction. When no session, create internal transaction.

All 739 unit tests passing.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 16:39:01 -06:00
Cal Corum
9546d2a370 CLAUDE: Extract database schema to reference document
- Created backend/.claude/DATABASE_SCHEMA.md with full table details
- Updated database/CLAUDE.md to reference the new schema doc
- Preserves valuable reference material while keeping CLAUDE.md concise

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 16:27:27 -06:00
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
Cal Corum
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>
2025-11-04 09:59:13 -06:00
Cal Corum
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>
2025-11-03 23:50:33 -06:00
Cal Corum
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>
2025-11-01 19:50:55 -05:00
Cal Corum
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>
2025-10-31 17:04:23 -05:00
Cal Corum
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)
2025-10-31 16:03:54 -05:00
Cal Corum
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>
2025-10-30 16:02:51 -05:00
Cal Corum
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>
2025-10-28 14:08:56 -05:00
Cal Corum
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>
2025-10-24 08:29:02 -05:00
Cal Corum
9284162682 Clean up false positive Pylance errors 2025-10-23 09:10:41 -05:00
Cal Corum
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>
2025-10-23 08:35:24 -05:00
Cal Corum
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>
2025-10-22 22:45:44 -05:00
Cal Corum
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>
2025-10-22 12:01:03 -05:00
Cal Corum
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>
2025-10-21 19:46:16 -05:00