Add comprehensive test coverage for the main game scene:
Test Coverage:
- Constructor and scene key registration
- init() method - state reset
- create() method - board setup, StateRenderer creation, event subscription
- update() loop - intentionally minimal design
- shutdown() method - cleanup and event unsubscription
- Event handling - state updates and resize events
- Event subscription lifecycle - proper bind/unbind
- Integration tests - full lifecycle execution
- Edge cases - rapid cycles, large states
Key Testing Challenges Solved:
- Phaser canvas dependency - mocked Phaser.Scene with minimal API
- gameBridge integration - mocked event system with spy functions
- StateRenderer mocking - included all necessary methods (clear, getPlayerZones, etc.)
- Container API - added removeAll() for proper cleanup testing
All 1,282 tests passing (26 new MatchScene tests).
Foundation for TEST-004 (Card rendering) and TEST-005 (StateRenderer).
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Build foundation for game engine testing with comprehensive mocks and utilities:
Infrastructure Created:
- src/test/mocks/phaser.ts (33 tests)
* MockEventEmitter - Event system with on/once/off/emit
* MockScene - Scene lifecycle and factories
* MockGame - Game instance with scale and scene manager
* MockContainer - Game object container with child management
* MockSprite - Image sprites with texture support
* MockText - Styled text objects
* MockGraphics - Shape drawing API
* MockLoader - Asset loading simulation
- src/test/helpers/gameTestUtils.ts (22 tests)
* createMockGameState() - Complete game state with players
* createMockCardDefinition() - Card definitions with type helpers
* createMockCardInstance() - Card instances with damage/status
* createGameScenario() - Full game setups with cards in zones
* setupMockScene() - Scene setup with game instance
* Type-specific helpers: createMockPokemonCard(), createMockEnergyCard(), etc.
- src/test/README.md
* Complete documentation with usage examples
* Testing patterns and best practices
* Troubleshooting guide
This infrastructure enables testing of all Phaser game objects (Board, Card, Zone,
MatchScene, etc.) without requiring WebGL/Canvas. All 1,256 tests passing.
Foundation for TEST-002 through TEST-009 (scene and state testing).
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Quick win #3: Test coverage for user store edge cases
Tests cover:
- fetchProfile success and error paths
- fetchProfile with/without authentication
- fetchProfile with missing/null fields
- fetchProfile API errors (404, network, generic)
- fetchProfile concurrent calls
- updateDisplayName success and error paths
- updateDisplayName validation errors (too short, profanity)
- updateDisplayName with/without authentication
- Loading state management during operations
- Error clearing on successful operations
- Auth store synchronization
Results:
- 20 new tests, all passing
- User store coverage: 52% → ~90%+ (estimated)
- Complete edge case coverage for profile operations
- All authentication state transitions tested
All quick wins complete! Total: 65 new tests across 3 files
Test count: 1000 → 1065 (+6.5%)
Quick win #1: Test coverage for CardBack game object
Tests cover:
- Constructor with sprite (texture exists)
- Constructor with fallback graphics (texture missing)
- Initial positioning and sizing
- setCardSize() for all sizes (small, medium, large)
- setSize() alias for method chaining
- getDimensions() returns correct values
- Fallback graphics rendering (background, border, pattern, emblem)
- destroy() cleanup for both sprite and graphics paths
- Integration tests for full lifecycle
Results:
- 25 new tests, all passing
- CardBack coverage: 0% → ~95%
- Game engine coverage starting point established
- Phaser mocking pattern validated
All tests pass (1025/1025)
* Fix hand card rotation direction
Cards now fan outward correctly instead of curling inward
* Update StateRenderer to require MatchScene type for type safety
- Change constructor parameter from Phaser.Scene to MatchScene
- Update scene property type to MatchScene
- Add import for MatchScene type
- Update JSDoc example to reflect type-safe constructor
* Defer Board creation to StateRenderer for correct rules config
- Make board property nullable (Board | null instead of Board?)
- Remove Board and createBoard imports (now handled by StateRenderer)
- Update setupBoard() to skip Board creation
- Add setBoard() method for StateRenderer to call
- Update clearBoard() to use null instead of undefined
- Add JSDoc explaining why Board creation is deferred
* Create Board in StateRenderer with correct layout options
- Add Board and createBoard imports
- Add board property to StateRenderer
- Create Board in render() on first call with correct rules_config
- Add debug logging for Board creation and zone creation
- Update clear() to destroy Board when clearing
- Board now created after we have rules_config from first state
* Add fatal error handling with toast notification and auto-redirect
- Add 'fatal-error' event to GameBridgeEvents type
- Import and initialize useToast in GamePage
- Listen for 'fatal-error' event from Phaser
- Show error toast that persists until redirect
- Show full-screen fatal error overlay with countdown
- Auto-redirect to /play after 3 seconds
- Update StateRenderer to emit 'fatal-error' when Board creation fails
* Gate debug logging with DEV flag
- Add DEBUG_RENDERER constant gated by import.meta.env.DEV
- Update all console.log statements in StateRenderer to only log in development
- Keep console.error and console.warn as they are (always show errors)
- Debug logs now only appear during development, not in production
* Fix code audit issues - add missing imports and improve error UX
Critical fixes:
- Add missing gameBridge import to StateRenderer (fixes runtime error in fatal error handler)
- Add missing Board type import to MatchScene (fixes TypeScript compilation error)
UX improvements:
- Replace fatal error auto-redirect with manual 'Return to Menu' button
- Add toast notification when resignation fails
- Give users unlimited time to read fatal errors before returning
Addresses issues found in frontend code audit:
- errors.missing-import (StateRenderer.ts:166)
- errors.missing-type-import (MatchScene.ts:84)
- errors.catch-only-console (GamePage.vue:145)
- architecture.missing-fatal-error-handling (GamePage.vue:261)
* Add CONTRIBUTING policy and fix pre-existing lint/test errors
- Add CONTRIBUTING.md with strict policy: never use --no-verify without approval
- Add comprehensive testing documentation (TESTING.md, VISUAL-TEST-GUIDE.md)
- Add test-prize-fix.md quick test checklist and verify-fix.sh script
Lint fixes (enables pre-commit hooks):
- Remove unused imports in 9 files
- Fix unused variables (underscore convention)
- Replace 'as any' type assertions with proper VisibleGameState types
- Add missing CARD_WIDTH_MEDIUM import in layout.spec.ts
- All ESLint errors now resolved (only acceptable warnings remain)
Test fixes (all 1000 tests now passing):
- Fix layout.spec.ts: Add missing CARD_WIDTH_MEDIUM import
- Fix PlayPage.spec.ts: Update test to use actual hardcoded UUIDs
- Fix useAuth.spec.ts: Mock API profile fetch in initialization tests
- Fix PhaserGame.spec.ts: Add scenes export to mock and update createGame call expectations
This ensures pre-commit hooks work properly going forward and prevents
bypassing TypeScript/lint checks that catch errors early.
* Add comprehensive test coverage improvement plan
- Create PROJECT_PLAN_TEST_COVERAGE.json with 25 structured tasks
- Create TEST_COVERAGE_PLAN.md with executive summary and roadmap
- Plan addresses critical gaps: game engine (0%), WebSocket (27%)
- 6-week roadmap to reach 85% coverage from current 63%
- Target: Phase 1 (weeks 1-3) - critical game engine and network tests
- Includes quick wins, production blockers, and success metrics
Based on coverage analysis showing:
- Strong: Composables (84%), Components (90%), Stores (88%)
- Critical gaps: Phaser game engine (~5,500 untested lines)
- High priority: WebSocket/multiplayer reliability
See TEST_COVERAGE_PLAN.md for overview and week-by-week breakdown.
* Add coverage tooling and ignore coverage directory
- Add @vitest/coverage-v8 package for coverage analysis
- Add coverage/ directory to .gitignore
- Used during test coverage analysis for PROJECT_PLAN_TEST_COVERAGE.json
- Always fetch user profile during app init to get fresh hasStarterDeck status
- Verify with API when local state shows no starter (handles stale localStorage data)
- Clear starter status cache when user data is set
Extends RulesConfig support in the frontend game board to conditionally
render energy deck zones based on deck.energy_deck_enabled setting.
When disabled (classic mode), energy zones are null and omitted from
the layout, saving screen space.
Changes:
- Add energyDeckEnabled option to LayoutOptions interface
- Update landscape/portrait layouts to conditionally generate energy zones
- Make myEnergyZone/oppEnergyZone nullable in BoardLayout type
- Update StateRenderer to conditionally create and update energy zones
- Add energyDeckEnabled computed property to game store
- Add 7 tests for conditional energy deck rendering
https://claude.ai/code/session_01AAxKmpq2AGde327eX1nzUC
Extends the RulesConfig support in the frontend game board to also
honor the bench.max_size setting:
- Add benchSize option to LayoutOptions interface
- Update calculateLandscapeLayout to use configurable bench count
- Update calculatePortraitLayout to use configurable bench count
- Update StateRenderer to pass benchSize from rules_config.bench.max_size
- Add benchSize computed property to game store
- Add 7 tests for configurable bench size behavior
The layout now generates the correct number of bench slots based on
the rules config (defaults to 5 for backwards compatibility). Bench
slots remain horizontally centered regardless of count.
https://claude.ai/code/session_01AAxKmpq2AGde327eX1nzUC
The game board now conditionally renders prize card zones based on
the RulesConfig sent from the backend:
- Add rules_config field to VisibleGameState in backend (visibility.py)
- Add rules_config to frontend game types and game store
- Update layout.ts to accept LayoutOptions with usePrizeCards and prizeCount
- Update StateRenderer to conditionally create PrizeZone objects
- Update Board to handle empty prize position arrays gracefully
- Add game store computed properties: rulesConfig, usePrizeCards, prizeCount
- Add tests for conditional prize zone rendering
When use_prize_cards is false (Mantimon TCG points system), the prize
zones are not rendered, saving screen space. When true (classic Pokemon
TCG mode), the correct number of prize slots is rendered based on
the rules config's prize count.
https://claude.ai/code/session_01AAxKmpq2AGde327eX1nzUC
- Document Phase F4 implementation tasks
- Track progress on live gameplay features
- Define component structure and requirements
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add useGameSocket for WebSocket connection management
- Add useGameActions for dispatching game actions
- Add useGames for fetching active games list
- Include comprehensive tests
- Type-safe action dispatch with precondition checks
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add TurnIndicator to show current turn and phase
- Add AttackMenu for selecting Pokemon attacks
- Add GameOverlay container for positioning UI over Phaser
- Add GameOverModal for end-game display
- Add ForcedActionModal for required player actions
- Add PhaseActions for phase-specific buttons
- Include component tests
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- 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>
- 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>
- 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>
- 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>
- 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>
- 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>
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>
- 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.
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
- 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>
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>
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>
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>
- 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>
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>
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>
- 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>
- 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>
- 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>
- 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>
- 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>