Commit Graph

108 Commits

Author SHA1 Message Date
Cal Corum
50bd3f1591 Add config API endpoint for frontend game settings
Expose game configuration (energy types, card types, rule constants) via
/api/config endpoint so frontend can dynamically load game rules without
hardcoding values.
2026-01-31 15:43:41 -06:00
Cal Corum
aee7ad64b4 Add card images for sets a1 and a1a
Add ~90 card artwork webp files and a MISSING_IMAGES.json tracking file
for cards still needing artwork.
2026-01-31 15:43:29 -06:00
Cal Corum
d1862295e6 Update card JSON data with rarity_tier field
Add rarity_tier to all card definitions in sets a1 and a1a to support
the new pull rate calculation system for booster packs.
2026-01-31 15:43:19 -06:00
Cal Corum
1123d61067 Extend core card models with rarity tiers and card subtypes
Add CardRarityTier enum for pull rate calculations (common through
crown_rare). Add CardSubtype enum for Pokemon classifications (basic,
stage1, stage2, ex, etc.). Update CardDefinition model with new fields
for subtypes and rarity display.
2026-01-31 15:43:07 -06:00
Cal Corum
7b79f02124 Add project-specific skills reference to CLAUDE.md
Document local skill files in .claude/skills/ so they are discoverable
when invoking /backend-phase, /frontend-phase, /code-audit,
/frontend-code-audit, and /dev-server commands.
2026-01-31 15:40:37 -06:00
Cal Corum
6bfc928169 Refactor user store to use apiClient instead of direct fetch
- Replace manual fetch calls with apiClient.get() and apiClient.patch()
- Remove manual token handling (apiClient handles this automatically)
- Add typed UserProfileResponse interface for API response
- Improve error handling with ApiError type checking
- Gains automatic token refresh on 401 with retry logic

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 00:36:42 -06:00
Cal Corum
ca3aca2b38 Add has_starter_deck to user profile API response
The frontend routing guard checks has_starter_deck to decide whether to
redirect users to starter selection. The field was missing from the API
response, causing authenticated users with a starter deck to be
incorrectly redirected to /starter on page refresh.

- Add has_starter_deck computed property to User model
- Add has_starter_deck field to UserResponse schema
- Add unit tests for User model properties
- Add API tests for has_starter_deck in profile response

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 23:14:04 -06:00
Cal Corum
cd3efcb528 Implement ProfilePage and profanity filter for display names (F1-006)
ProfilePage implementation:
- Full profile page with avatar, editable display name, session count
- LinkedAccountCard and DisplayNameEditor components
- useProfile composable wrapping user store operations
- Support for linking/unlinking OAuth providers
- Logout and logout-all-devices functionality

Profanity service with bypass detection:
- Uses better-profanity library for base detection
- Enhanced to catch common bypass attempts:
  - Number suffixes/prefixes (shit123, 69fuck)
  - Leet-speak substitutions (sh1t, f@ck, $hit)
  - Separator characters (s.h.i.t, f-u-c-k)
- Integrated into PATCH /api/users/me endpoint
- 17 unit tests covering all normalization strategies

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 16:06:42 -06:00
Cal Corum
3cc8d6645e Implement auth composables and starter selection (F1-003, F1-004, F1-005)
Features:
- Add useAuth composable with OAuth flow and token management
- Add useStarter composable with API integration and dev mock fallback
- Implement app auth initialization blocking navigation until ready
- Complete StarterSelectionPage with 5 themed deck options

Bug fixes:
- Fix CORS by adding localhost:3001 to allowed origins
- Fix OAuth URL to include redirect_uri parameter
- Fix emoji rendering in nav components (use actual chars, not escapes)
- Fix requireStarter guard timing by allowing navigation from /starter
- Fix starter "already selected" detection for 400 status code

Documentation:
- Update dev-server skill to use `docker compose` (newer CLI syntax)
- Update .env.example with port 3001 in CORS comment

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 15:36:14 -06:00
Cal Corum
f687909f91 Implement OAuth callback with token handling and profile fetch (F1-002)
Complete the AuthCallbackPage to handle OAuth redirects by parsing tokens
from URL fragment, fetching user profile, and redirecting based on starter
deck status. Includes open-redirect protection and comprehensive tests.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 12:39:18 -06:00
Cal Corum
09844cbf3f Add dev-server skill and update development ports
- Add /dev-server skill with preflight checks for environment, deps,
  ports, and services before starting frontend/backend
- Add /frontend-phase skill for tracking implementation phases
- Register skills in .claude/settings.json
- Update .env.development ports (8001 for API, 3001 for frontend)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:56:25 -06:00
Cal Corum
913b1e7eae Fix audit issues: OAuth login, remove dead code, add error boundary
Code audit fixes:
- Update LoginPage for OAuth (Google/Discord buttons, no password)
- Delete RegisterPage.vue (OAuth-only app)
- Delete AppHeader.vue (superseded by NavSidebar, had bugs)
- Add ErrorBoundary component for graceful error handling

Also adds Phase F1 (Authentication Flow) plan with 10 tasks.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:42:26 -06:00
Cal Corum
0dc52f74bc Add app shell with layouts and navigation (F0-007)
Create responsive layout system based on route meta:
- DefaultLayout: sidebar (desktop) / bottom tabs (mobile)
- MinimalLayout: centered content for auth pages
- GameLayout: full viewport for Phaser game

Navigation components:
- NavSidebar: desktop sidebar with main nav + user menu
- NavBottomTabs: mobile bottom tab bar

UI components (tied to UI store):
- LoadingOverlay: full-screen overlay with spinner
- ToastContainer: stacked notification toasts

Also adds Vue Router meta type declarations.

Phase F0 is now complete (8/8 tasks).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:26:15 -06:00
Cal Corum
3a566ffd5a Add Socket.IO client with typed game events (F0-006)
- Create typed event interfaces for game namespace
- Add full game state types (GameState, Card, CardInPlay, etc.)
- Implement connection manager singleton with auth
- Add auto-reconnection with exponential backoff
- Provide helper methods for game actions (joinGame, sendAction, etc.)
- Add typed event subscription helpers with unsubscribe

Phase F0 progress: 7/8 tasks complete

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:15:17 -06:00
Cal Corum
0720084cb1 Add typed API client with auth and error handling (F0-005)
- Create ApiError class with status helpers (isNotFound, etc.)
- Create typed fetch wrapper with get/post/put/patch/delete methods
- Auto-inject Authorization header from auth store
- Handle 401 with automatic token refresh and retry
- Add query parameter support and proper URL building
- Add comprehensive tests (11 tests)

Phase F0 progress: 6/8 tasks complete

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:11:11 -06:00
Cal Corum
f63e8be600 Add Pinia stores for auth, user, and UI (F0-004)
- Refactor auth store for OAuth flow (access/refresh tokens)
- Add token refresh logic and expiry tracking
- Create user store for profile data and linked accounts
- Create UI store for loading overlay, toasts, and modals
- Update router guard tests for new auth store structure
- Add comprehensive tests (45 total passing)

Phase F0 progress: 5/8 tasks complete

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:07:25 -06:00
Cal Corum
5424bf9086 Add environment config and Vue Router with guards (F0-003, F0-008)
- Add environment configuration with type-safe config.ts
- Implement navigation guards (requireAuth, requireGuest, requireStarter)
- Update router to match sitePlan routes and layouts
- Create placeholder pages for all sitePlan routes
- Update auth store User interface for OAuth flow
- Add phase plan tracking for F0

Phase F0 progress: 4/8 tasks complete

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 10:59:04 -06:00
Cal Corum
25cb22eb84 Rename AGENTS.md to CLAUDE.md, add root .gitignore
- Rename project instructions file to Claude Code standard name
- Add .gitignore to exclude IDE files and frontend-poc/

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 10:24:48 -06:00
Cal Corum
b9b803da66 Scaffold Vue 3 + TypeScript frontend (Phase F0)
Vue 3 with Composition API, Pinia, Vue Router, Tailwind v4:
- Vite build with @/ path aliases and backend proxy
- TypeScript strict mode with proper type imports
- Pinia stores (auth, game) with setup syntax and persistence
- Vue Router with auth guards and lazy-loaded routes
- Tailwind v4 with custom theme (Pokemon types, dark UI)
- Vitest configured for component testing
- ESLint v9 flat config with Vue/TypeScript support

Pages: Home, Login, Register, Campaign, Collection, DeckBuilder, Match
Components: AppHeader with auth-aware navigation
Types: Card, GameState, Player, Deck, Campaign types

Also adds frontend-code-audit skill with patterns for:
- Error handling (unhandled promises, empty catches)
- Security (XSS, token storage, input validation)
- Architecture (Composition API, Pinia patterns, Phaser rules)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 09:23:53 -06:00
Cal Corum
5b12df0cb1 Add backend API reference to frontend CLAUDE.md
- REST endpoints for auth, users, collections, decks, games
- WebSocket events (client→server and server→client)
- Key backend files to reference
- Type definitions to mirror from backend schemas

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 08:24:34 -06:00
Cal Corum
f27830d19e Add frontend CLAUDE.md with coding standards
- Vue 3 Composition API patterns (<script setup>)
- Pinia setup store syntax
- Composable patterns for API calls
- Vue-Phaser integration guidelines
- Tailwind mobile-first approach
- TypeScript strict mode requirements
- Testing patterns with docstrings
- Path aliases and environment config
- Common patterns (loading states, guards, error handling)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 08:22:14 -06:00
Cal Corum
29b5d36621 Add site plan to frontend project plan
- Mobile-first, desktop first-class citizen
- Navigation: left sidebar (desktop), bottom tabs (mobile)
- 11 routes defined with auth requirements and layouts
- 3 layout types: minimal (login), game (full viewport), default (nav)
- Auth flow: login → starter (if needed) → dashboard
- Dashboard widgets and profile page v1 scope defined

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 08:19:52 -06:00
Cal Corum
f452e69999 Complete Phase 4 implementation files
- TurnTimeoutService with percentage-based warnings (35 tests)
- ConnectionManager enhancements for spectators and reconnection
- GameService with timer integration, spectator support, handle_timeout
- GameNamespace with spectate/leave_spectate handlers, reconnection
- WebSocket message schemas for spectator events
- WinConditionsConfig additions for turn timer thresholds
- 83 GameService tests, 37 ConnectionManager tests, 37 GameNamespace tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 08:03:43 -06:00
Cal Corum
6f871d7187 Add frontend project plan (F0-F8)
Comprehensive Vue 3 + Phaser 3 frontend plan with 8 phases:
- F0: Project Foundation (Vite, Vue, Tailwind, Pinia, Socket.IO)
- F1: Authentication (OAuth flow, token management)
- F2: Deck Management (collection, deck builder, starter selection)
- F3: Phaser Integration (Vue-Phaser bridge, board layout, cards)
- F4: Live Gameplay (WebSocket sync, actions, turn flow)
- F5: Polish & UX (reconnection, animations, timer)
- F6: Campaign Mode (blocked on backend Phase 5)
- F7: Multiplayer (blocked on backend Phase 6)
- F8: Pack Opening (blocked on backend Phase 5)

F0-F5 are unblocked - all backend dependencies (Phases 2-4) complete.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 08:02:07 -06:00
Cal Corum
2ae6429798 Mark Phase 4 (Game Service + WebSocket) as complete
- Update status to COMPLETE with completedDate 2026-01-30
- Increment completedPhases from 4 to 5
- Update deliverables list with actual implementations
- 306 new tests added, 1505 total tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 07:35:40 -06:00
Cal Corum
7fcb86ff51 Implement UserRepository pattern with dependency injection
- Add UserRepository and LinkedAccountRepository protocols to protocols.py
- Add UserEntry and LinkedAccountEntry DTOs for service layer decoupling
- Implement PostgresUserRepository and PostgresLinkedAccountRepository
- Refactor UserService to use constructor-injected repositories
- Add get_user_service factory and UserServiceDep to API deps
- Update auth.py and users.py endpoints to use UserServiceDep
- Rewrite tests to use FastAPI dependency overrides (no monkey patching)

This follows the established repository pattern used by DeckService and
CollectionService, enabling future offline fork support.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 07:30:16 -06:00
Cal Corum
f6e8ab5f67 Add integration tests for WebSocket game flow (TEST-002)
Create 16 integration tests across 7 test classes covering:
- JWT authentication (valid/invalid/expired tokens)
- Game join flow with Redis connection tracking
- Action execution and state broadcasting
- Turn timeout Redis operations (start/get/cancel/extend)
- Disconnection cleanup
- Spectator filtered state
- Reconnection tracking

Uses testcontainers for real Redis/Postgres integration. Completes
Phase 4 (Game Service + WebSocket) with all 18 tasks finished.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 00:02:40 -06:00
Cal Corum
cc0254d5ab Implement REST endpoints for game management (API-001)
Add REST API endpoints for game lifecycle operations:
- POST /games - Create new game between two players
- GET /games/{game_id} - Get game info for reconnection
- GET /games/me/active - List user's active games
- POST /games/{game_id}/resign - Resign from game via HTTP

Includes proper reverse proxy support for WebSocket URL generation
(X-Forwarded-* headers -> settings.base_url -> Host header fallback).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 23:09:12 -06:00
Cal Corum
154d466ff1 Implement /game namespace event handlers (WS-005, WS-006)
Add GameNamespaceHandler with full event handling for real-time gameplay:
- handle_join: Join/rejoin games with visibility-filtered state
- handle_action: Execute actions and broadcast state to participants
- handle_resign: Process resignation and end game
- handle_disconnect: Notify opponent of disconnection
- Broadcast helpers for state, game over, and opponent status

Includes 28 unit tests covering all handler methods.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 20:40:06 -06:00
Cal Corum
531d3e1e79 Implement GameService.end_game with history archival (GS-005)
- Add GameEndResult dataclass with winner, loser, final views, duration
- Add _map_end_reason() to map core GameEndReason to DB EndReason
  (raises ValueError for unknown reasons to catch missing enum sync)
- Enhance end_game() to build replay data and return comprehensive result
- Add archive_to_history() to GameStateManager for complete game archival:
  - Creates GameHistory record with replay data
  - Deletes ActiveGame record
  - Clears Redis cache
  - All in single transaction
- Add ArchiveResult dataclass for archive operation metadata
- Add TODO for session_factory DI refactor in GameStateManager
- Update tests: 5 new end_game tests, 6 new archive_to_history tests

Phase 4 progress: 10/18 tasks complete

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 20:10:27 -06:00
Cal Corum
d5460ff418 Enhance GameService.join_game for reconnection support (GS-004)
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>
2026-01-29 19:30:44 -06:00
Cal Corum
ce8a36b14c Add backend-phase skill for consistent development workflow
Standardizes the phased development workflow:
- /backend-phase status - Show current phase and progress
- /backend-phase next - Show details of next task
- /backend-phase start <id> - Begin working on task
- /backend-phase done <id> - Mark task complete with tests
- /backend-phase plan - Create plan for next NOT_STARTED phase

Reads from PROJECT_PLAN_MASTER.json and project_plans/PHASE_*.json.
Ensures dependencies are met before starting tasks and tests exist
before marking complete.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 19:11:27 -06:00
Cal Corum
0a9cd73daf Validate connection data integrity in ConnectionManager
Fix audit warnings about empty string defaults hiding data corruption:

1. get_connection_info(): Validate required fields (user_id, connected_at,
   last_seen) exist before creating ConnectionInfo. Return None and log
   warning for corrupted records instead of returning invalid data.

2. unregister_connection(): Log warning if user_id is missing during
   cleanup. Existing code safely handles this (skips cleanup), but now
   we have visibility into data corruption.

Test added for corrupted data case.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 19:03:17 -06:00
Cal Corum
1346853869 Add code-audit skill for systematic anti-pattern detection
Project-specific skill to audit codebase for:
- Error handling: silent failures, swallowed exceptions, hidden errors
- Security: missing auth, data exposure, injection risks
- Architecture: DI violations, import boundaries, coupling

Pattern definitions in YAML with verdict hints (ISSUE_IF/OK_IF) for
context-aware analysis. Tailored to Mantimon TCG architecture patterns
(core independence, stateless backend, repository pattern).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 18:59:17 -06:00
Cal Corum
55e02ceb21 Replace silent error hiding with explicit failures
Three changes to fail fast instead of silently degrading:

1. GameService.create_game: Raise GameCreationError when energy card
   definition not found instead of logging warning and continuing.
   A deck with missing energy cards is fundamentally broken.

2. CardService.load_all: Collect all card file load failures and raise
   CardServiceLoadError at end with comprehensive error report. Prevents
   startup with partial card data that causes cryptic runtime errors.
   New exceptions: CardLoadError, CardServiceLoadError

3. GameStateManager.recover_active_games: Return RecoveryResult dataclass
   with recovered count, failed game IDs with error messages, and total.
   Enables proper monitoring and alerting for corrupted game state.

Tests added for energy card error case. Existing tests updated for
new RecoveryResult return type.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 18:48:06 -06:00
Cal Corum
cd3cc892f4 Implement GameService.execute_action enhancements (GS-003)
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>
2026-01-29 15:15:34 -06:00
Cal Corum
3c75ee0e00 Implement GameService.create_game (GS-002)
- 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>
2026-01-29 14:09:11 -06:00
Cal Corum
f93f5b617a Remove legacy modifier field from WeaknessResistance
Migrate all usages to the proper mode/value fields:
- Weakness: mode=MULTIPLICATIVE, value=2
- Resistance: mode=ADDITIVE, value=-30

Remove backwards compatibility code and legacy test.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 13:16:51 -06:00
Cal Corum
f512c7b2b3 Refactor to dependency injection pattern - no monkey patching
- ConnectionManager: Add redis_factory constructor parameter
- GameService: Add engine_factory constructor parameter
- AuthHandler: New class replacing standalone functions with
  token_verifier and conn_manager injection
- Update all tests to use constructor DI instead of patch()
- Update CLAUDE.md with factory injection patterns
- Update services README with new patterns
- Add socketio README documenting AuthHandler and events

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 22:54:57 -06:00
Cal Corum
0c810e5b30 Add Phase 4 WebSocket infrastructure (WS-001 through GS-001)
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>
2026-01-28 22:21:20 -06:00
Cal Corum
c00ee87f25 Switch to testcontainers for automatic test container management
- Create tests/conftest.py with testcontainers for Postgres and Redis
- Auto-detect Docker Desktop socket and disable Ryuk for compatibility
- Update tests/db/conftest.py and tests/services/conftest.py to use shared fixtures
- Fix test_resolve_effect_logs_exceptions: logger was disabled by pytest
- Fix test_save_and_load_with_real_redis: use redis_url fixture
- Minor lint fix in engine_validation.py

Tests now auto-start containers on run - no need for `docker compose up`
All 1199 tests passing.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 16:49:11 -06:00
Cal Corum
0a7c35c262 Add detailed Phase 4 (Game Service + WebSocket) project plan
18 tasks covering:
- WebSocket setup with python-socketio
- GameService lifecycle (create, join, execute, resume, end)
- Message protocol specification
- Connection management with Redis
- Turn timeout system
- Reconnection handling
- REST endpoints for game management
- Unit and integration tests
- Spectator mode (stretch goal)

Includes architecture decisions, sequence diagrams, and acceptance criteria.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 15:50:57 -06:00
Cal Corum
9e14ab906f Add services layer README documentation
Documents:
- Architecture principles (stateless, DI, repository protocol)
- Services overview table
- Key patterns (config from request, UNSET sentinel, repository injection)
- Service details with usage examples
- Testing approach with examples

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 15:40:56 -06:00
Cal Corum
ebe776d54d Update project plans and documentation for Phase 3 completion
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>
2026-01-28 15:26:01 -06:00
Cal Corum
7d397a2e22 Fix medium priority issues from code review
UNSET sentinel pattern:
- Add UNSET sentinel in protocols.py for nullable field updates
- Fix inability to clear deck description (UNSET=keep, None=clear)
- Fix repository inability to clear validation_errors

Starter deck improvements:
- Remove unused has_starter_deck from CollectionService
- Add deprecation notes to old starter deck methods

Validation improvements:
- Add energy type validation in deck_validator.py
- Add energy type validation in deck schemas
- Add VALID_ENERGY_TYPES constant

Game loading fix:
- Fix get_deck_for_game silently skipping invalid cards
- Now raises ValueError with clear error message

Tests:
- Add TestEnergyTypeValidation test class
- Add TestGetDeckForGame test class
- Add tests for validate_energy_types utility function

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 14:32:08 -06:00
Cal Corum
3ec670753b Fix security and validation issues from code review
Critical fixes:
- Add admin API key authentication for admin endpoints
- Add race condition protection via unique partial index for starter decks
- Make starter deck selection atomic with combined method

Moderate fixes:
- Fix DI pattern violation in validate_deck_endpoint
- Add card ID format validation (regex pattern)
- Add card quantity validation (1-99 range)
- Fix exception chaining with from None (B904)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 14:16:07 -06:00
Cal Corum
58349c126a Phase 3: Collections + Decks - Services and DI architecture
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>
2026-01-28 11:27:14 -06:00
Cal Corum
4859b2a9cb Add detailed Phase 3 (Collections + Decks) project plan
14 tasks covering card ownership, deck building, validation, and
starter deck selection. 29 estimated hours total.

Key components:
- CollectionService for card ownership CRUD
- DeckService with slot limits and validation
- DeckValidator for rule enforcement
- 5 starter deck definitions
- REST API endpoints for collections and decks
- ~80-90 tests planned

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 00:40:25 -06:00
Cal Corum
f82bc8aa1f Fix OAuth callback redirect and deps import
- Discord OAuth callback now redirects to frontend with tokens in URL fragment
  (more secure than query params - fragment not sent to server)
- Error responses also redirect with error in query params
- Fix deps.py import: get_session_dependency -> get_session

Part of Phase 2 Authentication completion.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 00:17:27 -06:00
Cal Corum
5cf2198542 Add engine validation script with attack_coin_status effect handler
- Add attack_coin_status effect handler for coin-flip status conditions
  (e.g., Thunder Shock paralysis on heads)
- Create comprehensive engine_validation.py script (~1250 lines) that
  validates game engine behavior with 29 test cases:
  - Illegal moves (attack without energy, wrong turn, evolution rules)
  - Energy mechanics (attachment limits, cost validation)
  - Weakness calculation (+20 additive mode)
  - Status conditions (paralysis blocks actions, poison damage)
  - Knockout flow (points, forced actions, state cleanup)
  - Win conditions (4 points triggers game over)
- Update game_walkthrough.py Thunder Shock to use new effect handler
- Interactive prompts between sections (Enter to continue, q to quit)
- Uses seed=42 for deterministic, reproducible coin flips

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 00:15:12 -06:00