feat: add poll start/end endpoints, poll.leading WS handler, and poll state persistence

Adds POST /:id/voting/start and POST /:id/voting/end endpoints that
broadcast poll lifecycle events and persist poll state to the sessions
table. The poll.leading WebSocket message is now handled server-side
(rebroadcast + DB persist) with self-healing for polls started before
the persistence columns existed.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
cottongin
2026-05-07 20:43:39 -04:00
parent 1c9f0ef280
commit 9cd601bab2
4 changed files with 158 additions and 0 deletions

View File

@@ -90,6 +90,7 @@ Obtain a JWT by calling `POST /api/auth/login` with your admin key.
| `subscribe` | `sessionId` | Subscribe to a session's events |
| `unsubscribe`| `sessionId` | Unsubscribe from a session |
| `ping` | — | Heartbeat; server responds with `pong` |
| `poll.leading` | `sessionId`, `gameId`, `label`, `votes` | Report current poll leader (rebroadcast to subscribers) |
### auth
```json
@@ -139,6 +140,9 @@ Must be authenticated.
| `game.status` | Periodic game state heartbeat every 20s (broadcast to subscribers) |
| `player-count.updated` | Manual player count override (broadcast to subscribers) |
| `vote.received` | Live vote recorded (broadcast to subscribers) |
| `voting.ended` | Host ended the voting/polling period (broadcast to subscribers) |
| `poll.start` | Host started a new poll (broadcast to subscribers) |
| `poll.leading` | Current poll leader updated (broadcast to subscribers) |
---
@@ -384,6 +388,45 @@ Possible `reason` values: `room_closed`, `room_not_found`, `connection_failed`,
}
```
### voting.ended
- **Broadcast to:** Clients subscribed to the session
- **Triggered by:** `POST /api/sessions/:id/voting/end` (host ends the voting/polling period)
**Data:**
```json
{
"sessionId": 3
}
```
### poll.start
- **Broadcast to:** Clients subscribed to the session
- **Triggered by:** `POST /api/sessions/:id/voting/start` (host starts a new poll)
**Data:**
```json
{
"sessionId": 3
}
```
### poll.leading
- **Broadcast to:** Clients subscribed to the session
- **Triggered by:** Downstream voting client sends `poll.leading` message (rebroadcast to all session subscribers)
**Data:**
```json
{
"sessionId": 3,
"gameId": 42,
"label": "Quiplash 3",
"votes": 7
}
```
---
## 7. Error Handling