Backend:
- Fix session never being attached to ws.data at upgrade time
- Add GameServer class: connection registry, per-connection room tracking,
automatic room cleanup on disconnect via ws.data.rooms
- Replace ws-handler.ts with typed event-driven architecture using mitt
- Remove redundant subscription tracking from RoomManager
- Add JOIN_RESULT with player/spectator lists replacing error-as-control-flow
- Add SESSION_REPLACED for multi-tab same-account detection
- Add FILL_ROOM command for admin solo testing (fills empty slots with host)
- Fix dual-schema routing; remove game types from WsMessageSchema
- Per-player personalized views sent directly after each action
Chess plugin:
- Allow same-player (solo) mode: skip color/turn ownership checks
- Fix forfeit and disconnect handling in solo mode (winner: null)
Frontend:
- Click-to-move with legal move dots and last-move highlight
- Auto-scroll move history, forfeit confirmation, turn-reactive board border
- JOIN_RESULT initialises player/spectator lists immediately on join
- Contextual connecting state, player slot cards in waiting room
- Copy-invite button with Copied! flash, Back to Lobby CTA on finish
- Session-replaced warning banner with Rejoin here action
- Lobby passes preferAs intent through route state
- Admin waiting room shows Start Solo Test button
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Prevent same player from joining as both white and black
- Add validation to reject duplicate players in RoomManager
- Fix spectator status not resetting when joining as player
- Use ref to track latest chess state in ChessBoard for accurate move validation
- Add role field to JOIN_ROOM message schema
- Allow admin users to join rooms and be added as players
- Update panel to pass user role when joining game rooms
- Fix chess move coordinates in tests (algebraic notation)
- Ensure admin users can make moves for both sides
Skip the duplicate-player check when the joining user has the admin
role, so admins can test games solo by joining their own room as both
players.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The room creator was added as a player during createRoom, but when
GameRoom mounted it sent JOIN_ROOM which failed with "Already in room",
leaving the UI stuck on the loading spinner. Now treats duplicate joins
as successful rejoins, which also fixes reconnection after page refresh.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>