Commit Graph

8 Commits

Author SHA1 Message Date
Cal Corum
e165b449f5 CLAUDE: Refactor offensive decisions - replace approach with action field
Backend refactor complete - removed all deprecated parameters and replaced
with clean action-based system.

Changes:
- OffensiveDecision model: Added 'action' field (6 choices), removed
  deprecated 'hit_and_run' and 'bunt_attempt' boolean fields
- Validators: Added action-specific validation (squeeze_bunt, check_jump,
  sac_bunt, hit_and_run situational constraints)
- WebSocket handler: Updated submit_offensive_decision to use action field
- Terminal client: Updated CLI, REPL, arg parser, and display for actions
- Tests: Updated all 739 unit tests (100% passing)

Action field values:
- swing_away (default)
- steal (requires steal_attempts parameter)
- check_jump (requires runner on base)
- hit_and_run (requires runner on base)
- sac_bunt (cannot use with 2 outs)
- squeeze_bunt (requires R3, not with bases loaded, not with 2 outs)

Breaking changes:
- Removed: hit_and_run boolean → use action="hit_and_run"
- Removed: bunt_attempt boolean → use action="sac_bunt" or "squeeze_bunt"
- Removed: approach field → use action field

Files modified:
- app/models/game_models.py
- app/core/validators.py
- app/websocket/handlers.py
- terminal_client/main.py
- terminal_client/arg_parser.py
- terminal_client/commands.py
- terminal_client/repl.py
- terminal_client/display.py
- tests/unit/models/test_game_models.py
- tests/unit/core/test_validators.py
- tests/unit/terminal_client/test_arg_parser.py
- tests/unit/terminal_client/test_commands.py

Test results: 739/739 passing (100%)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-14 15:07:54 -06:00
Cal Corum
63bffbc23d CLAUDE: Session 1 cleanup complete - Parts 4-6
Completed remaining Session 1 work:

Part 4: Remove offensive approach field
- Removed `approach` field from OffensiveDecision model
- Removed approach validation and validator
- Updated 7 backend files (model, tests, handlers, AI, validators, display)

Part 5: Server-side depth validation
- Added walk-off validation for shallow outfield (home batting, 9th+, close game, runners)
- Updated outfield depths from ["in", "normal"] to ["normal", "shallow"]
- Infield validation already complete (corners_in/infield_in require R3)
- Added comprehensive test coverage

Part 6: Client-side smart filtering
- Updated DefensiveSetup.vue with dynamic option filtering
- Infield options: only show infield_in/corners_in when R3 present
- Outfield options: only show shallow in walk-off scenarios
- Hybrid validation (server authority + client UX)

Total Session 1: 25 files modified across 6 parts
- Removed unused config fields
- Fixed hit location requirements
- Removed alignment/approach fields
- Added complete depth validation

All backend tests passing (730/731 - 1 pre-existing failure)

Next: Session 2 - Offensive decision workflow refactor (Changes #10-11)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-14 13:54:34 -06:00
Cal Corum
eab61ad966 CLAUDE: Phases 3.5, F1-F5 Complete - Statistics & Frontend Components
This commit captures work from multiple sessions building the statistics
system and frontend component library.

Backend - Phase 3.5: Statistics System
- Box score statistics with materialized views
- Play stat calculator for real-time updates
- Stat view refresher service
- Alembic migration for materialized views
- Test coverage: 41 new tests (all passing)

Frontend - Phase F1: Foundation
- Composables: useGameState, useGameActions, useWebSocket
- Type definitions and interfaces
- Store setup with Pinia

Frontend - Phase F2: Game Display
- ScoreBoard, GameBoard, CurrentSituation, PlayByPlay components
- Demo page at /demo

Frontend - Phase F3: Decision Inputs
- DefensiveSetup, OffensiveApproach, StolenBaseInputs components
- DecisionPanel orchestration
- Demo page at /demo-decisions
- Test coverage: 213 tests passing

Frontend - Phase F4: Dice & Manual Outcome
- DiceRoller component
- ManualOutcomeEntry with validation
- PlayResult display
- GameplayPanel orchestration
- Demo page at /demo-gameplay
- Test coverage: 119 tests passing

Frontend - Phase F5: Substitutions
- PinchHitterSelector, DefensiveReplacementSelector, PitchingChangeSelector
- SubstitutionPanel with tab navigation
- Demo page at /demo-substitutions
- Test coverage: 114 tests passing

Documentation:
- PHASE_3_5_HANDOFF.md - Statistics system handoff
- PHASE_F2_COMPLETE.md - Game display completion
- Frontend phase planning docs
- NEXT_SESSION.md updated for Phase F6

Configuration:
- Package updates (Nuxt 4 fixes)
- Tailwind config enhancements
- Game store updates

Test Status:
- Backend: 731/731 passing (100%)
- Frontend: 446/446 passing (100%)
- Total: 1,177 tests passing

Next Phase: F6 - Integration (wire all components into game page)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-14 09:52:30 -06:00
Cal Corum
e147ab17f1 CLAUDE: Phase 3F - Substitution System WebSocket Events
Implemented complete WebSocket integration for real-time player substitutions.
System is now 80% complete - only tests remain.

## WebSocket Events Implemented (600 lines)

### Event Handlers (backend/app/websocket/handlers.py):
1. request_pinch_hitter - Pinch hitter substitution
   - Validates: game_id, player_out_lineup_id, player_in_card_id, team_id
   - Executes: SubstitutionManager.pinch_hit()
   - Broadcasts: player_substituted (all clients), substitution_confirmed (requester)
   - Error codes: MISSING_FIELD, INVALID_FORMAT, NOT_CURRENT_BATTER, etc.

2. request_defensive_replacement - Defensive replacement
   - Additional field: new_position (P, C, 1B, 2B, 3B, SS, LF, CF, RF)
   - Executes: SubstitutionManager.defensive_replace()
   - Same broadcast pattern as pinch hitter

3. request_pitching_change - Pitching change
   - Validates minimum batters faced (handled in SubstitutionManager)
   - Executes: SubstitutionManager.change_pitcher()
   - Broadcasts new pitcher to all clients

4. get_lineup - Get active lineup for team
   - Returns: lineup_data with all active players
   - Uses: StateManager cache (O(1)) or database fallback
   - Purpose: UI refresh after substitutions

### Event Pattern (follows existing handlers):
- Validate inputs (UUID format, required fields, game exists)
- Create SubstitutionManager instance with DatabaseOperations
- Execute substitution (validate → DB → state)
- Broadcast player_substituted to game room
- Send substitution_confirmed to requester
- Error handling with specific error codes

### Events Emitted:
- player_substituted (broadcast) - Includes: type, lineup IDs, position, batting_order
- substitution_confirmed (requester) - Success confirmation with new_lineup_id
- substitution_error (requester) - Validation error with error code
- lineup_data (requester) - Active lineup response
- error (requester) - Generic error

## Documentation Updates (350 lines)

### backend/app/websocket/CLAUDE.md:
- Complete handler documentation with examples
- Event data structures and response formats
- Error code reference (MISSING_FIELD, INVALID_FORMAT, NOT_CURRENT_BATTER, etc.)
- Client integration examples (JavaScript)
- Complete workflow diagrams
- Updated event summary table (+8 events)
- Updated Common Imports section

### .claude/implementation/ updates:
- NEXT_SESSION.md: Marked Task 1 complete, updated to 80% done
- SUBSTITUTION_SYSTEM_SUMMARY.md: Added WebSocket section, updated status
- GAMESTATE_REFACTOR_PLAN.md: Marked complete
- PHASE_3_OVERVIEW.md: Updated all phases to reflect completion
- phase-3e-COMPLETED.md: Created comprehensive completion doc

## Architecture

### DB-First Pattern (maintained):
```
Client Request → WebSocket Handler
    ↓
SubstitutionManager
    ├─ SubstitutionRules.validate_*()
    ├─ DatabaseOperations.create_substitution() (DB first!)
    ├─ StateManager.update_lineup_cache()
    └─ Update GameState if applicable
    ↓
Success Responses
    ├─ player_substituted (broadcast to room)
    └─ substitution_confirmed (to requester)
```

### Error Handling:
- Three-tier: ValidationError, GameValidationError, Exception
- Specific error codes for each failure type
- User-friendly error messages
- Comprehensive logging at each step

## Status Update

**Phase 3F Substitution System**: 80% Complete
-  Core logic (SubstitutionRules, SubstitutionManager) - 1,027 lines
-  Database operations (create_substitution, get_eligible_substitutes)
-  WebSocket events (4 handlers) - 600 lines
-  Documentation (350 lines)
-  Unit tests (20% remaining) - ~300 lines needed
-  Integration tests - ~400 lines needed

**Phase 3 Overall**: ~97% Complete
- Phase 3A-D (X-Check Core): 100%
- Phase 3E (GameState, Ratings, Redis, Testing): 100%
- Phase 3F (Substitutions): 80%

## Files Modified

backend/app/websocket/handlers.py (+600 lines)
backend/app/websocket/CLAUDE.md (+350 lines)
.claude/implementation/NEXT_SESSION.md (updated progress)
.claude/implementation/SUBSTITUTION_SYSTEM_SUMMARY.md (added WebSocket section)
.claude/implementation/GAMESTATE_REFACTOR_PLAN.md (marked complete)
.claude/implementation/PHASE_3_OVERVIEW.md (updated all phases)
.claude/implementation/phase-3e-COMPLETED.md (new file, 400+ lines)

## Next Steps

Remaining work (2-3 hours):
1. Unit tests for SubstitutionRules (~300 lines)
   - 15+ pinch hitter tests
   - 12+ defensive replacement tests
   - 10+ pitching change tests
2. Integration tests for SubstitutionManager (~400 lines)
   - Full DB + state sync flow
   - State recovery verification
   - Error handling and rollback

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 21:24:43 -06:00
Cal Corum
adf7c7646d CLAUDE: Phase 3E-Final - Redis Caching & X-Check WebSocket Integration
Completed Phase 3E-Final with Redis caching upgrade and WebSocket X-Check
integration for real-time defensive play resolution.

## Redis Caching System

### New Files
- app/services/redis_client.py - Async Redis client with connection pooling
  * 10 connection pool size
  * Automatic connect/disconnect lifecycle
  * Ping health checks
  * Environment-configurable via REDIS_URL

### Modified Files
- app/services/position_rating_service.py - Migrated from in-memory to Redis
  * Redis key pattern: "position_ratings:{card_id}"
  * TTL: 86400 seconds (24 hours)
  * Graceful fallback if Redis unavailable
  * Individual and bulk cache clearing (scan_iter)
  * 760x performance improvement (0.274s API → 0.000361s Redis)

- app/main.py - Added Redis startup/shutdown events
  * Connect on app startup with settings.redis_url
  * Disconnect on shutdown
  * Warning logged if Redis connection fails

- app/config.py - Added redis_url setting
  * Default: "redis://localhost:6379/0"
  * Override via REDIS_URL environment variable

- app/services/__init__.py - Export redis_client

### Testing
- test_redis_cache.py - Live integration test
  * 10-step validation: connect, cache miss, cache hit, performance, etc.
  * Verified 760x speedup with player 8807 (7 positions)
  * Data integrity checks pass

## X-Check WebSocket Integration

### Modified Files
- app/websocket/handlers.py - Enhanced submit_manual_outcome handler
  * Serialize XCheckResult to JSON when present
  * Include x_check_details in play_resolved broadcast
  * Fixed bug: Use result.outcome instead of submitted outcome
  * Includes defender ratings, dice rolls, resolution steps

### New Files
- app/websocket/X_CHECK_FRONTEND_GUIDE.md - Comprehensive frontend documentation
  * Event structure and field definitions
  * Implementation examples (basic, enhanced, polished)
  * Error handling and common pitfalls
  * Test scenarios with expected data
  * League differences (SBA vs PD)
  * 500+ lines of frontend integration guide

- app/websocket/MANUAL_VS_AUTO_MODE.md - Workflow documentation
  * Manual mode: Players read cards, submit outcomes
  * Auto mode: System generates from ratings (PD only)
  * X-Check resolution comparison
  * UI recommendations for each mode
  * Configuration reference
  * Testing considerations

### Testing
- tests/integration/test_xcheck_websocket.py - WebSocket integration tests
  * Test X-Check play includes x_check_details 
  * Test non-X-Check plays don't include details 
  * Full event structure validation

## Performance Impact

- Redis caching: 760x speedup for position ratings
- WebSocket: No performance impact (optional field)
- Graceful degradation: System works without Redis

## Phase 3E-Final Progress

-  WebSocket event handlers for X-Check UI
-  Frontend integration documentation
-  Redis caching upgrade (from in-memory)
-  Redis connection pool in app lifecycle
-  Integration tests (2 WebSocket, 1 Redis)
-  Manual vs Auto mode workflow documentation

Phase 3E-Final: 100% Complete
Phase 3 Overall: ~98% Complete

## Testing Results

All tests passing:
- X-Check table tests: 36/36 
- WebSocket integration: 2/2 
- Redis live test: 10/10 steps 

## Configuration

Development:
  REDIS_URL=redis://localhost:6379/0  (Docker Compose)

Production options:
  REDIS_URL=redis://10.10.0.42:6379/0  (DB server)
  REDIS_URL=redis://your-redis-cloud.com:6379/0  (Managed)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 22:46:59 -06: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
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>
2025-10-30 22:51:31 -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