- 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>
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>
Add foundational data structures for X-Check play resolution system:
Models Added:
- PositionRating: Defensive ratings (range 1-5, error 0-88) for X-Check resolution
- XCheckResult: Dataclass tracking complete X-Check resolution flow with dice rolls,
conversions (SPD test, G2#/G3#→SI2), error results, and final outcomes
- BasePlayer.active_position_rating: Optional field for current defensive position
Enums Extended:
- PlayOutcome.X_CHECK: New outcome type requiring special resolution
- PlayOutcome.is_x_check(): Helper method for type checking
Documentation Enhanced:
- Play.check_pos: Documented as X-Check position identifier
- Play.hit_type: Documented with examples (single_2_plus_error_1, etc.)
Utilities Added:
- app/core/cache.py: Redis cache key helpers for player positions and game state
Implementation Planning:
- Complete 6-phase implementation plan (3A-3F) documented in .claude/implementation/
- Phase 3A complete with all acceptance criteria met
- Zero breaking changes, all existing tests passing
Next: Phase 3B will add defense tables, error charts, and advancement logic
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
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>
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>
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>
Initialize both Nuxt 3 frontends (SBA and PD) with full configuration:
Frontend Setup:
- Initialized Nuxt 3 projects for both leagues (SBA and PD)
- Installed dependencies: Tailwind CSS, Pinia, Socket.io-client, Axios
- Configured league-specific settings in nuxt.config.ts
- Created WebSocket plugins for real-time communication
- Set up TypeScript with strict mode and type checking
- Configured Tailwind CSS for styling
Backend Updates:
- Updated database models documentation in backend/CLAUDE.md
- Enhanced db_models.py with additional relationship patterns
Documentation:
- Updated Phase 1 completion checklist (12/12 items - 100% complete)
- Marked all infrastructure objectives as complete
Running Services:
- Backend (FastAPI + Socket.io): http://localhost:8000
- Frontend SBA: http://localhost:3000
- Frontend PD: http://localhost:3001
- Redis: port 6379
- PostgreSQL: Connected to remote server
Phase 1 is now complete. Ready to proceed to Phase 2 (Game Engine Core).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
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>