Commit Graph

126 Commits

Author SHA1 Message Date
Cal Corum
8ad7552ecc Add HandManager for card interaction handling
- Implement drag-and-drop for cards in hand
- Add click handlers for card actions
- Validate drop zones based on game state
- Enable/disable interactions based on turn

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 20:51:43 -06:00
Cal Corum
a963eb70d3 Add Phaser game asset placeholders
- Add board background placeholder
- Add type icons (fire, water, grass, lightning, psychic, etc.)
- Add UI elements (damage counter, zone highlight)
- Prevent missing asset errors in Phaser

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 20:51:35 -06:00
Cal Corum
76e15187d0 Add energy type placeholder images
- Add fire, water, grass, lightning, psychic energy icons
- Add card_back directory with placeholder
- Support UI display of energy types

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 20:51:29 -06:00
Cal Corum
9f2ac7146b Update frontend project plan progress
- Mark completed tasks in Phase F4
- Track live gameplay implementation progress

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 20:51:19 -06:00
Cal Corum
c274ff6d3a Update Vite config for test environment
- Add environment-specific configuration
- Support test mode setup

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 20:51:12 -06:00
Cal Corum
594aa2d8ad Add card back placeholder image
- Add card_back.webp for Phaser to load
- Prevents missing asset errors in game rendering

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 20:51:05 -06:00
Cal Corum
0af5d32cfe Update GamePage tests for new WebSocket composable
- Replace direct socket client usage with useGameSocket
- Update test expectations for composable-based architecture
- Fix mocking for new component structure

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 20:50:57 -06:00
Cal Corum
40a2cd34d9 Hardcode Bob's user and deck IDs for game creation testing
- Replace placeholder UUIDs with Bob's actual IDs
- Enables testing game creation flow
- Temporary fix until matchmaking endpoint is implemented

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 20:50:50 -06:00
Cal Corum
c0194b77eb Add WebSocket client and game store infrastructure
- Extend socket client with heartbeat handling
- Add game store computed properties and state management
- Add ConnectionStatus and game-related types
- Support turn phase, game over, and connection tracking

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 20:50:43 -06:00
Cal Corum
a20e97a0a0 Add card click event handling in GamePage
- Listen for card:clicked events from Phaser
- Log card clicks to console for debugging
- Add TODO for implementing game action logic based on phase

Cards now respond to clicks and emit events to Vue layer.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 20:50:35 -06:00
Cal Corum
fdb5225356 Improve API error handling for validation errors
- Parse FastAPI 422 validation error arrays into readable messages
- Update ErrorResponse type to handle both string and array detail
- Use inline type for validation error objects (no any)
- Display field-level validation errors instead of [object Object]

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 20:50:03 -06:00
Cal Corum
52c8edcf93 Fix WebSocket game:join to emit game:state event
Backend was returning the state but not emitting the game:state
event that the frontend listens for. Added explicit emit call
to send game:state to the client after successful join.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 12:27:01 -06:00
Cal Corum
c594f0c8f8 Add lessons learned README for frontend POC 2026-01-31 22:06:10 -06:00
Cal Corum
dc06a93e2e Move older frontend-poc to .claude/f0-frontend-poc/
This is an earlier POC version (pre-F3 demo) preserved for reference.
2026-01-31 22:02:22 -06:00
Cal Corum
8685e3e16e Archive frontend POC to .claude/frontend-poc/
Preserves the working F3 Phaser demo implementation before resetting
the main frontend/ directory for a fresh start. The POC demonstrates:
- Vue 3 + Phaser 3 integration
- Real card rendering with images
- Vue-Phaser state sync via gameBridge
- Card interactions and damage counters

To restore: copy .claude/frontend-poc/ back to frontend/ and run npm install
2026-01-31 22:00:51 -06:00
Cal Corum
2986eed142 Add F3 demo page with real card data and fix Phaser initialization
- Add /demo route with full game board demo using real card images
- Fix PhaserGame.vue to pass scenes array to createGame()
- Fix timing issue: listen for gameBridge ready event instead of Phaser core ready
- Add card images for Lightning and Fire starter decks (24 Pokemon + 5 energy)
- Add mockGameState.ts with realistic Lightning vs Fire matchup
- Add demoCards.json/ts with card definitions from backend
- Update Card.ts to use image_path from card definitions
- Add loadCardImageFromPath() to asset loader for new image format
- Update CardDefinition type with image_path and rarity fields

Demo verifies: Vue-Phaser state sync, card rendering, damage counters,
card click events, and debug controls. Layout issues noted for Phase F4.
2026-01-31 21:58:26 -06:00
Cal Corum
f759d56d4d Add .opencode/ to gitignore 2026-01-31 15:56:27 -06:00
Cal Corum
059536a42b Implement frontend phases F1-F3: auth, deck management, Phaser integration
Phase F1 - Authentication:
- OAuth callback handling with token management
- Auth guards for protected routes
- Account linking composable
- Profile page updates

Phase F2 - Deck Management:
- Collection page with card filtering and display
- Decks page with CRUD operations
- Deck builder with drag-drop support
- Collection and deck Pinia stores

Phase F3 - Phaser Integration:
- Game bridge composable for Vue-Phaser communication
- Game page with Phaser canvas mounting
- Socket.io event types for real-time gameplay
- Game store with match state management
- Phaser scene scaffolding and type definitions

Also includes:
- New UI components (ConfirmDialog, EmptyState, FilterBar, etc.)
- Toast notification system
- Game config composable for dynamic rule loading
- Comprehensive test coverage for new features
2026-01-31 15:43:56 -06:00
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