Commit Graph

70 Commits

Author SHA1 Message Date
cottongin
512b36da51 fix: long-press select deselection bug, swap sun emoji for dice, bump version to 0.6.2
Made-with: Cursor
2026-03-23 02:48:56 -04:00
cottongin
d613d4e507 feat: rewrite History page with controls bar, multi-select, Sunday badge, and update SessionDetail with archive support
Made-with: Cursor
2026-03-23 02:21:37 -04:00
cottongin
bbd2e51567 feat: add POST /sessions/bulk endpoint for bulk archive, unarchive, and delete
Made-with: Cursor
2026-03-23 02:19:41 -04:00
cottongin
b40176033f feat: add POST archive and unarchive endpoints for sessions
Made-with: Cursor
2026-03-23 01:45:36 -04:00
cottongin
68045afbbc feat: add filter, limit, and X-Total-Count to session list endpoint
Made-with: Cursor
2026-03-23 01:42:51 -04:00
cottongin
35474e5df4 feat: add archived column to sessions table and isSunday helper
Made-with: Cursor
2026-03-23 01:40:07 -04:00
cottongin
4da2c15d56 docs: add session archive, multi-select, Sunday badge, and pagination implementation plan
Made-with: Cursor
2026-03-23 01:36:45 -04:00
cottongin
bff103e26e docs: add session archive, multi-select, Sunday badge, and pagination design spec
Made-with: Cursor
2026-03-23 01:30:01 -04:00
cottongin
a68a617508 feat: simplify History page to session list with notes preview and navigation
Made-with: Cursor
2026-03-23 00:17:32 -04:00
cottongin
0ee97b35c5 feat: add SessionDetail page with notes view/edit and route
Made-with: Cursor
2026-03-23 00:16:45 -04:00
cottongin
7ce5251543 chore: add react-markdown and @tailwindcss/typography dependencies
Made-with: Cursor
2026-03-23 00:14:31 -04:00
cottongin
b9206b6cfe feat: add PUT and DELETE /api/sessions/:id/notes endpoints
Made-with: Cursor
2026-03-23 00:13:09 -04:00
cottongin
ce3347d0b1 feat: gate full notes behind auth on single session endpoint
Made-with: Cursor
2026-03-23 00:09:39 -04:00
cottongin
e9f1b89d44 feat: add has_notes and notes_preview to session list, omit full notes
Made-with: Cursor
2026-03-23 00:06:09 -04:00
cottongin
656d9c3bf6 feat: add notes preview helper with tests
Made-with: Cursor
2026-03-23 00:01:09 -04:00
cottongin
974d7315b9 feat: add optional auth middleware
Made-with: Cursor
2026-03-22 23:58:27 -04:00
cottongin
341257a04d docs: add session notes implementation plan
Made-with: Cursor
2026-03-22 23:49:13 -04:00
cottongin
8c36b399d0 docs: add session notes read/edit/delete design spec
Made-with: Cursor
2026-03-22 23:33:36 -04:00
cottongin
c756d45e24 fix: guard shard event emissions on both manuallyStopped and gameFinished
Prevent stale events from shards that ended naturally (not via
stopMonitor). handleMessage now gates on gameFinished in addition to
manuallyStopped. handleEntityUpdate properly cleans up on gameFinished
by emitting room.disconnected, removing from activeShards, and calling
disconnect. handleError also removes from activeShards. Probe message
handler and status broadcast bail out when the shard is stopped or the
game has finished.

Made-with: Cursor
2026-03-21 00:07:10 -04:00
cottongin
171303a6f9 fix: enforce single playing game and clean up stale shard monitors
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
2026-03-20 23:34:22 -04:00
cottongin
4999060970 fix: periodic player count refresh via probe shard connection
Some Jackbox games (e.g. Trivia Murder Party 2) do not send
client/connected events to shard connections and lack textDescriptions,
leaving the player count stuck at 0 if the shard connects before
players join. Fix by opening a lightweight probe shard every 20s to
read the fresh here map. Also fix bc:room entity lookup in
handleWelcome and a WebSocket close handler race condition.

Made-with: Cursor
2026-03-20 21:29:58 -04:00
cottongin
34637d6d2c feat: add periodic game.status broadcast and live status REST endpoint
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
2026-03-20 21:05:19 -04:00
cottongin
a7bd0650eb docs: update ecast API reference with connection roles and shard details
Add Connection Roles table documenting host, player, shard, audience,
observer, and moderator roles with their capabilities and slot impact.
Add shard client/welcome capture and passive room monitoring section.

Made-with: Cursor
2026-03-20 11:47:47 -04:00
cottongin
65036a4e1b fix: Picker WebSocket auth, event handling, and status display
- Authenticate with JWT before subscribing to session events
- Use message.type instead of message.event (matches server format)
- Handle all new shard monitor events (room.connected, lobby.*,
  game.started, game.ended, room.disconnected)
- Replace never-set 'waiting' status with 'monitoring'
- Show monitoring indicator with live player count

Made-with: Cursor
2026-03-20 11:47:19 -04:00
cottongin
336ba0e608 docs: update websocket event reference with new shard monitor events
Add room.connected, lobby.player-joined, lobby.updated, game.started,
game.ended, room.disconnected events. Clarify player-count.updated as
manual-override only. Update complete example with new event handlers.

Made-with: Cursor
2026-03-20 11:35:29 -04:00
cottongin
03f79422af fix: clean up activeShards on reconnection failure
Remove stale entries from the activeShards map when
reconnectWithBackoff exhausts all attempts or detects room closure.

Made-with: Cursor
2026-03-20 11:34:15 -04:00
cottongin
2503c3fc09 chore: remove Puppeteer and old room-monitor/player-count-checker modules
Made-with: Cursor
2026-03-20 11:29:01 -04:00
cottongin
9c9927218a feat: wire graceful shutdown for shard connections on SIGTERM/SIGINT
Made-with: Cursor
2026-03-20 11:27:58 -04:00
cottongin
3c1d5b2224 refactor: rewire sessions routes to use ecast shard client
Made-with: Cursor
2026-03-20 11:27:54 -04:00
cottongin
1c4c8bc19c feat: add startMonitor, stopMonitor, cleanupAllShards module exports 2026-03-20 11:25:01 -04:00
cottongin
de395d3a28 feat: add reconnection logic with exponential backoff to shard client 2026-03-20 11:24:48 -04:00
cottongin
3f21299720 feat: add event broadcasting and entity update handlers to shard client
Made-with: Cursor
2026-03-20 11:19:57 -04:00
cottongin
516db57248 feat: add EcastShardClient with connection, welcome parsing, and player counting
Made-with: Cursor
2026-03-20 11:09:05 -04:00
cottongin
0fc2ddbf23 feat: add getRoomInfo to jackbox-api for full room data including host
Made-with: Cursor
2026-03-20 11:04:54 -04:00
cottongin
7712ebeb04 Add implementation plan for ecast shard monitor
10-task TDD plan covering: jackbox-api extension, EcastShardClient
class, event broadcasting, reconnection, route rewiring, graceful
shutdown, old module removal, doc updates, and manual smoke test.

Made-with: Cursor
2026-03-20 10:53:19 -04:00
cottongin
002e1d70a6 Add design doc for ecast shard monitor replacing Puppeteer audience approach
Replaces room-monitor.js (REST polling) and player-count-checker.js
(Puppeteer/CDP audience join) with a single EcastShardClient that
connects as a shard via direct WebSocket. Defines new event contract,
integration points, error handling, and reconnection strategy.

Made-with: Cursor
2026-03-20 10:42:33 -04:00
cottongin
e6198181f8 docs: reframe player counting as slot-based (not a limitation)
Occupied slots = effective player count since held reconnection slots
are unavailable to new players. connections - 1 = player count,
maxPlayers - (connections - 1) = available slots. Clean and simple.

Made-with: Cursor
2026-03-20 09:56:58 -04:00
cottongin
7b0dc5c015 docs: major corrections to ecast API docs from second round of testing
Key corrections based on testing with fresh room SCWX:
- connections count includes ALL ever-joined players, not just active ones
  (slots persist for reconnection, count never decreases)
- here field also includes disconnected players (slot reservation model)
- client/connected and client/disconnected confirmed as NOT delivered to
  player connections after extensive testing
- Jackbox has no concept of "leaving" — player disconnect is invisible
  to the API
- Added reconnection URL format (secret + id query params)
- Added error code 2027 (REST/WebSocket state divergence)
- Added ws-lifecycle-test.js for systematic protocol testing

Made-with: Cursor
2026-03-20 09:51:24 -04:00
cottongin
af5e8cbd94 docs: comprehensive Jackbox ecast API reverse engineering
Adds complete documentation of the ecast platform covering:
- REST API (8 endpoints including newly discovered /connections, /info, /status)
- WebSocket protocol (connection, message format, 40+ opcodes)
- Entity model (room, player, audience, textDescriptions)
- Game lifecycle (lobby → start → gameplay → end)
- Player/room management answers (counting, join/leave detection, etc.)

Also adds scripts/ws-probe.js utility for direct WebSocket probing.

Made-with: Cursor
2026-03-20 09:39:17 -04:00
cottongin
e5ba43bcbb Add design doc for Jackbox ecast API reverse engineering
Defines scope, methodology (REST probing + WebSocket interception),
and documentation structure for comprehensive API documentation effort.

Made-with: Cursor
2026-03-20 09:18:55 -04:00
cottongin
35617268e9 fix: upgrade Docker to Node 22, add vote persistence diagnostics and e2e tests
- 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
2026-03-16 20:53:32 -04:00
cottongin
0d0d20161b docs: update remaining docs with vote tracking API changes
Update README.md, docs/api/README.md, session-lifecycle guide,
webhooks-and-events guide, and archive docs (BOT_INTEGRATION,
API_QUICK_REFERENCE) with new endpoints and vote.received event.

Made-with: Cursor
2026-03-15 19:21:35 -04:00
cottongin
3ed3af06ba docs: add vote tracking endpoints to API documentation
Update REST endpoint docs (votes.md, sessions.md), WebSocket protocol
(websocket.md), OpenAPI spec, and voting guide with the new
GET /api/votes, GET /api/sessions/:id/votes, and vote.received event.

Made-with: Cursor
2026-03-15 19:16:23 -04:00
cottongin
e9add95efa feat: add vote.received WebSocket event on live votes
Made-with: Cursor
2026-03-15 19:08:00 -04:00
cottongin
83b274de79 feat: add GET /api/votes endpoint with filtering and pagination
Made-with: Cursor
2026-03-15 19:00:00 -04:00
cottongin
264953453c test: regression tests for WebSocket events
Made-with: Cursor
2026-03-15 18:55:55 -04:00
cottongin
56adbe7aa2 test: regression tests for GET /api/sessions endpoints
Made-with: Cursor
2026-03-15 18:53:32 -04:00
cottongin
8ddbd1440f test: regression tests for POST /api/votes/live
Made-with: Cursor
2026-03-15 18:53:25 -04:00
cottongin
19c4b7dc37 test: regression tests for GET /api/games vote fields
Made-with: Cursor
2026-03-15 18:53:07 -04:00
cottongin
8e8e6bdf05 fix: upgrade better-sqlite3 for Node 24 compat, add --forceExit to jest
Made-with: Cursor
2026-03-15 18:51:50 -04:00