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
This commit is contained in:
cottongin
2026-03-15 19:16:23 -04:00
parent e9add95efa
commit 3ed3af06ba
5 changed files with 262 additions and 0 deletions

View File

@@ -6,10 +6,69 @@ Real-time popularity voting. Bots or integrations send votes during live gaming
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/api/votes` | None | Paginated vote history with filtering |
| POST | `/api/votes/live` | Bearer | Submit a live vote (up/down) |
---
## GET /api/votes
Paginated vote history with filtering. Use query parameters to filter by session, game, username, or vote type.
### Authentication
None.
### Query Parameters
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| session_id | int | No | — | Filter by session ID |
| game_id | int | No | — | Filter by game ID |
| username | string | No | — | Filter by voter username |
| vote_type | string | No | — | `"up"` or `"down"` |
| page | int | No | 1 | Page number |
| limit | int | No | 50 | Items per page (max 100) |
### Response
**200 OK**
Results are ordered by `timestamp DESC`. The `vote_type` field is returned as `"up"` or `"down"` (not raw integers).
```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": "2026-03-15T20:29:55.000Z",
"created_at": "2026-03-15T20:29:56.000Z"
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 237,
"total_pages": 5
}
}
```
### Error Responses
| Status | Body | When |
|--------|------|------|
| 400 | `{ "error": "..." }` | Invalid `session_id`, `game_id`, or `vote_type` |
| 200 | `{ "votes": [], "pagination": { "page": 1, "limit": 50, "total": 0, "total_pages": 0 } }` | No results match the filters |
---
## POST /api/votes/live
Submit a real-time up/down vote for the game currently being played. Automatically finds the active session and matches the vote to the correct game using the provided timestamp and session game intervals.
@@ -40,6 +99,7 @@ Bearer token required. Include in header: `Authorization: Bearer <token>`.
- Matches the vote timestamp to the game being played at that time (uses interval between consecutive `played_at` timestamps).
- Updates game `upvotes`, `downvotes`, and `popularity_score` atomically in a transaction.
- **Deduplication:** Rejects votes from the same username within a 1-second window (409 Conflict).
- Broadcasts a `vote.received` WebSocket event to all clients subscribed to the active session. See [WebSocket Protocol](../websocket.md#votereceived) for event payload.
### Response