Mark games as 'played' when shard detects game.ended or room_closed.
Stop old shard monitors before demoting previous playing games on new
game add or status change. Sync frontend playingGame state with the
games list on every refresh to prevent stale UI. Use terminate() for
probe connections to prevent shard connection leaks.
Made-with: Cursor
Add 20-second game.status WebSocket heartbeat from active shard monitors
containing full game state, and GET /status-live REST endpoint for on-demand
polling. Fix missing token destructuring in SessionInfo causing crash.
Relax frontend polling from 3s to 60s since WebSocket events now cover
real-time updates. Bump version to 0.6.0.
Made-with: Cursor
- Bump Dockerfile base image from node:18-alpine to node:22-alpine to
fix build failure (better-sqlite3@12.8.0 requires Node 20+)
- Add post-transaction verification logging in POST /api/votes/live to
detect live_votes insertion failures in production
- Add direct DB assertion to regression test for live_votes population
- Add end-to-end integration tests covering the full vote flow: POST
vote -> GET /api/sessions/:id/votes -> GET /api/votes -> direct DB
Made-with: Cursor
Extracts checkRoomStatus into shared jackbox-api.js with proper
User-Agent header (bare fetch was silently rejected by Jackbox API)
and always-on error logging (previously gated behind DEBUG flag).
Splits room-start detection (room-monitor.js) from audience-based
player counting (player-count-checker.js) to eliminate circular
dependency and allow immediate game.started detection. Room monitor
now polls immediately instead of waiting 10 seconds for first check.
Made-with: Cursor
JWT_SECRET and ADMIN_KEY no longer fall back to insecure defaults.
The app will throw at startup if these env vars are not set.
docker-compose.yml now uses :? syntax to require them.
Co-authored-by: Cursor <cursoragent@cursor.com>