Add pending forced action and game_over fields to GameJoinResult:
- pending_forced_action: Included when player must complete a forced
action (e.g., select new active after KO). Essential for reconnection
so client knows what action is required.
- game_over: Boolean indicating if game has already ended.
- is_your_turn: Now True when player has pending forced action, even if
it's technically opponent's turn.
The join_game method now handles both initial joins and reconnections
(resume). The last_event_id parameter is accepted for future event
replay support.
Tests: 4 new tests for forced action handling and game_over flag.
Total 51 tests for GameService.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add forced action handling, turn boundary detection, and DB persistence:
- Check for pending forced actions before allowing regular actions
- Only specified player can act during forced action (except resign)
- Only specified action type allowed during forced action
- Detect turn boundaries (turn number OR current player change)
- Persist to Postgres at turn boundaries for durability
- Include pending_forced_action in GameActionResult for client
New exceptions: ForcedActionRequiredError
Tests: 11 new tests covering forced actions, turn boundaries, and
pending action reporting. Total 47 tests for GameService.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add create_game method that loads decks via DeckService, converts
CardDefinitions to CardInstances, and persists to Redis/Postgres
- Build card registry from only the cards in play (not all cards)
- Add GameCreationError exception and GameCreateResult dataclass
- Add creation_engine_factory for DI-based testing (no monkey patching)
- Add helper methods: _cards_to_instances, _build_card_registry
- Update tests with proper mocks for success, deck failure, engine failure
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
WebSocket Message Schemas (WS-002):
- Add Pydantic models for all client/server WebSocket messages
- Implement discriminated unions for message type parsing
- Include JoinGame, Action, Resign, Heartbeat client messages
- Include GameState, ActionResult, Error, TurnStart server messages
Connection Manager (WS-003):
- Add Redis-backed WebSocket connection tracking
- Implement user-to-sid mapping with TTL management
- Support game room association and opponent lookup
- Add heartbeat tracking for connection health
Socket.IO Authentication (WS-004):
- Add JWT-based authentication middleware
- Support token extraction from multiple formats
- Implement session setup with ConnectionManager integration
- Add require_auth helper for event handlers
Socket.IO Server Setup (WS-001):
- Configure AsyncServer with ASGI mode
- Register /game namespace with event handlers
- Integrate with FastAPI via ASGIApp wrapper
- Configure CORS from application settings
Game Service (GS-001):
- Add stateless GameService for game lifecycle orchestration
- Create engine per-operation using rules from GameState
- Implement action-based RNG seeding for deterministic replay
- Add rng_seed field to GameState for replay support
Architecture verified:
- Core module independence (no forbidden imports)
- Config from request pattern (rules in GameState)
- Dependency injection (constructor deps, method config)
- All 1090 tests passing
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Project plan updates:
- Mark all 14 Phase 3 tasks as completed
- Update acceptance criteria to met
- Update master plan status to Phase 4 next
- Add detailed deliverables list for Phase 3
Documentation updates:
- Add UNSET sentinel pattern to CLAUDE.md
- Document when to use UNSET vs None for nullable fields
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implemented with Repository Protocol pattern for offline fork support:
- CollectionService with PostgresCollectionRepository
- DeckService with PostgresDeckRepository
- DeckValidator with DeckConfig + CardService injection
- Starter deck definitions (5 types: grass, fire, water, psychic, lightning)
- Pydantic schemas for collection and deck APIs
- Unit tests for DeckValidator (32 tests passing)
Architecture follows pure dependency injection - no service locator patterns.
Added CLAUDE.md documenting DI requirements and patterns.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 1 Database Implementation (DB-001 through DB-012):
Models:
- User: OAuth support (Google/Discord), premium subscriptions
- Collection: Card ownership with CardSource enum
- Deck: JSONB cards/energy_cards, validation state
- CampaignProgress: One-to-one with User, medals/NPCs as JSONB
- ActiveGame: In-progress games with GameType enum
- GameHistory: Completed games with EndReason enum, replay data
Infrastructure:
- Alembic migrations with sync psycopg2 (avoids async issues)
- Docker Compose for Postgres (5433) and Redis (6380)
- App config with Pydantic settings
- Redis client helper
Test Infrastructure:
- 68 database tests (47 model + 21 relationship)
- Async factory pattern for test data creation
- Sync TRUNCATE cleanup (solves pytest-asyncio event loop mismatch)
- Uses dev containers instead of testcontainers for reliability
Key technical decisions:
- passive_deletes=True for ON DELETE SET NULL relationships
- NullPool for test sessions (no connection reuse)
- expire_on_commit=False with manual expire() for relationship tests