From 0d0d20161bcf42d1827fce1d42a2665767034c0f Mon Sep 17 00:00:00 2001 From: cottongin Date: Sun, 15 Mar 2026 19:21:35 -0400 Subject: [PATCH] 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 --- README.md | 6 +++- docs/api/README.md | 6 +++- docs/api/guides/session-lifecycle.md | 2 +- docs/api/guides/webhooks-and-events.md | 3 +- docs/archive/API_QUICK_REFERENCE.md | 42 +++++++++++++++++++++++++- docs/archive/BOT_INTEGRATION.md | 5 +-- 6 files changed, 57 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 2dce02d..5e83466 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,8 @@ A full-stack web application that helps groups pick games to play from various J - **Live Voting API**: Real-time vote processing from external bots - Accept live votes via REST API + - Real-time `vote.received` WebSocket event for stream overlays + - Per-session vote breakdown and paginated global vote history - Automatic deduplication (1-second window) - Timestamp-based game matching - JWT authentication for security @@ -249,6 +251,7 @@ The manifest is automatically generated during the build process, so you don't n - `POST /api/sessions` - Create new session (admin) - `POST /api/sessions/:id/close` - Close session (admin) - `GET /api/sessions/:id/games` - Get games in session +- `GET /api/sessions/:id/votes` - Get per-game vote breakdown for a session - `POST /api/sessions/:id/games` - Add game to session (admin) - `POST /api/sessions/:id/chat-import` - Import chat log (admin) @@ -258,7 +261,8 @@ The manifest is automatically generated during the build process, so you don't n ### Statistics - `GET /api/stats` - Get overall statistics -### Live Votes +### Votes +- `GET /api/votes` - Paginated vote history with filtering - `POST /api/votes/live` - Submit real-time vote (admin) ### Webhooks diff --git a/docs/api/README.md b/docs/api/README.md index 48d7b82..ff6ecd3 100644 --- a/docs/api/README.md +++ b/docs/api/README.md @@ -40,6 +40,8 @@ All REST endpoints are prefixed with `/api/` except `/health`. - `GET /api/sessions/active` - `GET /api/sessions/{id}` - `GET /api/sessions/{id}/games` +- `GET /api/sessions/{id}/votes` +- `GET /api/votes` - `GET /api/stats` - `POST /api/pick` - `GET /health` @@ -82,7 +84,7 @@ SQLite stores booleans as integers (0/1). In request bodies, pass JavaScript boo ## Pagination -No pagination. All list endpoints return full result sets. +Most list endpoints return full result sets. The exception is `GET /api/votes`, which supports pagination via `page` and `limit` query parameters (default: page 1, limit 50, max 100). ## Quick Reference @@ -128,6 +130,7 @@ No pagination. All list endpoints return full result sets. | DELETE | `/api/sessions/{id}` | Yes | Delete a session | | POST | `/api/sessions/{id}/close` | Yes | Close a session | | GET | `/api/sessions/{id}/games` | No | List games in a session | +| GET | `/api/sessions/{id}/votes` | No | Get per-game vote breakdown for a session | | POST | `/api/sessions/{id}/games` | Yes | Add a game to a session | | POST | `/api/sessions/{id}/chat-import` | Yes | Import chat log for vote processing | | GET | `/api/sessions/{id}/export` | Yes | Export session | @@ -154,6 +157,7 @@ No pagination. All list endpoints return full result sets. | Method | Path | Auth | Description | |--------|------|------|-------------| +| GET | `/api/votes` | No | Paginated vote history with filtering | | POST | `/api/votes/live` | Yes | Record a live vote (up/down) | ### Webhooks diff --git a/docs/api/guides/session-lifecycle.md b/docs/api/guides/session-lifecycle.md index 6abedba..5699abd 100644 --- a/docs/api/guides/session-lifecycle.md +++ b/docs/api/guides/session-lifecycle.md @@ -270,7 +270,7 @@ curl -X DELETE "http://localhost:5000/api/sessions/5" \ ## 9. Real-time Updates via WebSocket -The API provides real-time updates over WebSocket for session events: `session.started`, `game.added`, `session.ended`, and `player-count.updated`. Connect to `/api/sessions/live`, authenticate with your JWT, and subscribe to session IDs to receive these events without polling. +The API provides real-time updates over WebSocket for session events: `session.started`, `game.added`, `session.ended`, `player-count.updated`, and `vote.received`. Connect to `/api/sessions/live`, authenticate with your JWT, and subscribe to session IDs to receive these events without polling. For connection setup, message types, and event payloads, see [WebSocket Protocol](../websocket.md). diff --git a/docs/api/guides/webhooks-and-events.md b/docs/api/guides/webhooks-and-events.md index ab9cc4a..705b17c 100644 --- a/docs/api/guides/webhooks-and-events.md +++ b/docs/api/guides/webhooks-and-events.md @@ -132,6 +132,7 @@ The WebSocket server runs at `/api/sessions/live` on the same host and port as t | `game.added` | Session subscribers | `POST /api/sessions/{id}/games` | | `session.ended` | Session subscribers | `POST /api/sessions/{id}/close` | | `player-count.updated` | Session subscribers | `PATCH /api/sessions/{sessionId}/games/{sessionGameId}/player-count` | +| `vote.received` | Session subscribers | `POST /api/votes/live` (live votes only, not chat-import) | `session.started` goes to every authenticated client. The others go only to clients that have subscribed to the relevant session via `{ "type": "subscribe", "sessionId": 3 }`. @@ -157,7 +158,7 @@ All events use this envelope: |---------|----------|-----------| | **Connection** | Stateless HTTP | Persistent | | **Auth** | Secret in config | JWT per connection | -| **Events** | `game.added` | `session.started`, `game.added`, `session.ended`, `player-count.updated` | +| **Events** | `game.added` | `session.started`, `game.added`, `session.ended`, `player-count.updated`, `vote.received` | | **Latency** | Higher (HTTP round trip) | Lower (push) | | **Reliability** | Logged, auditable | Best-effort | diff --git a/docs/archive/API_QUICK_REFERENCE.md b/docs/archive/API_QUICK_REFERENCE.md index a15b317..b1651fd 100644 --- a/docs/archive/API_QUICK_REFERENCE.md +++ b/docs/archive/API_QUICK_REFERENCE.md @@ -85,13 +85,53 @@ ws://localhost:5000/api/sessions/live } } +// Vote received (live votes only, not chat-import) +{ + "type": "vote.received", + "timestamp": "2025-11-01T...", + "data": { + "sessionId": 123, + "game": { "id": 42, "title": "Quiplash 3", "pack_name": "Party Pack 7" }, + "vote": { "username": "viewer123", "type": "up", "timestamp": "2025-11-01T20:30:00Z" }, + "totals": { "upvotes": 14, "downvotes": 3, "popularity_score": 11 } + } +} + // Pong { "type": "pong" } ``` --- -## Live Voting +## Votes + +### Get Vote History + +```http +GET /api/votes?session_id=5&game_id=42&username=viewer123&vote_type=up&page=1&limit=50 +``` + +**Response (200)**: +```json +{ + "votes": [ + { + "id": 891, + "session_id": 5, + "game_id": 42, + "game_title": "Quiplash 3", + "pack_name": "Party Pack 7", + "username": "viewer123", + "vote_type": "up", + "timestamp": "2025-11-01T20:30:00.000Z", + "created_at": "2025-11-01T20:30:01.000Z" + } + ], + "pagination": { "page": 1, "limit": 50, "total": 237, "total_pages": 5 } +} +``` + +All query parameters are optional. No authentication required. ### Submit Live Vote diff --git a/docs/archive/BOT_INTEGRATION.md b/docs/archive/BOT_INTEGRATION.md index 0a860f3..accce1c 100644 --- a/docs/archive/BOT_INTEGRATION.md +++ b/docs/archive/BOT_INTEGRATION.md @@ -696,8 +696,9 @@ curl -X GET "http://localhost:5000/api/webhooks/1/logs" \ - `game.started` - Triggered when the Jackbox room becomes locked (gameplay has begun). Detected by polling the Jackbox REST API every 10 seconds via the room monitor. Sent to clients subscribed to that session. Includes `roomCode` and `maxPlayers`. - `audience.joined` - Triggered when the app successfully joins a Jackbox room as an audience member for player count tracking. Sent to clients subscribed to that session. - `player-count.updated` - Triggered when the player count for a game is updated. Sent to clients subscribed to that session. +- `vote.received` - Triggered when a live vote is recorded via `POST /api/votes/live`. Sent to clients subscribed to that session. Includes voter username, vote direction, game info, and updated global vote totals. Does **not** fire for chat-import votes. -> **Tip:** To receive `session.started` events, your bot only needs to authenticate — no subscription is needed. Once you receive a `session.started` event, subscribe to the new session ID to receive `game.added` and `session.ended` events for it. +> **Tip:** To receive `session.started` events, your bot only needs to authenticate — no subscription is needed. Once you receive a `session.started` event, subscribe to the new session ID to receive `game.added`, `vote.received`, and `session.ended` events for it. ### Event Lifecycle (for a game with room code) @@ -711,7 +712,7 @@ When a game is added with a room code, events fire in this order: Room monitoring and player counting are separate systems. The room monitor (`room-monitor.js`) handles steps 1-2 and then hands off to the player count checker (`player-count-checker.js`) for steps 3-5. -More events may be added in the future (e.g., `vote.recorded`). +More events may be added in the future. ---