Files
IRC-kosmi-relay/docs/plans/2026-03-16-votes-command-design.md
cottongin 88cc140087 Add !votes command, fix vote tally timing, and improve Kosmi stability
- Add !votes command (IRC + Kosmi) showing per-session and all-time vote
  breakdowns for the current game via new Jackbox API endpoints
  (GET sessions/{id}/games, sessions/{id}/votes, games/{id})
- Fix vote tally broadcasting: remove debounce timer, announce tallies
  only at game transitions or session end instead of after every vote
- Add !kreconnect IRC command to manually trigger Kosmi reconnection
- Add WebSocket ping/pong keepalive and write mutex to Kosmi client
  for connection stability
- Add watchConnection() auto-reconnect on unexpected Kosmi disconnects
- Remove old 2025-10-31 chat summaries; add votes command design doc

Made-with: Cursor
2026-03-16 20:56:18 -04:00

58 lines
2.1 KiB
Markdown

# !votes Command Design
## Summary
Add a `!votes` IRC/Kosmi command that displays session and all-time vote data for the currently playing game. The response is broadcast to all connected chats via the gateway. If there is no active session, no playing game, or any API call fails, the command logs the reason and silently does nothing.
## Output Format
Matches the existing vote tally style:
```
🗳️ Split the Room • 14👍 3👎 (Score: +11) | All-time: 127
```
- Left side: session votes for the current game (upvotes, downvotes, net score)
- Right side: all-time `popularity_score` from the game catalog
## Architecture
Uses the gateway-level event routing pattern (same as `!kreconnect`).
### Flow
1. User types `!votes` in IRC or Kosmi
2. Bridge detects the command, sends `EventVotesQuery` on `b.Remote`, returns without relaying
3. Gateway router catches the event in `handleReceive`
4. `handleEventVotesQuery` fetches data from the Jackbox API:
- `GetActiveSession()` to get session ID
- `GetSessionGames(sessionID)` to find the game with status "playing"
- `GetSessionVotes(sessionID)` to get per-game vote breakdown
- `GetGame(gameID)` to get all-time `popularity_score`
5. Formats the message and broadcasts via `broadcastJackboxMessage`
### Failure handling
All failures are logged at warn level and produce no chat output:
- No Jackbox client configured
- No active session
- No game currently playing
- API errors on any of the fetch calls
- No vote data found for the current game
## Files Changed
- `bridge/config/config.go` -- add `EventVotesQuery` constant
- `bridge/jackbox/client.go` -- add `GetSessionGames`, `GetSessionVotes`, `GetGame` methods and response structs
- `bridge/irc/handlers.go` -- detect `!votes` command, emit event
- `bridge/kosmi/kosmi.go` -- detect `!votes` command, emit event
- `gateway/router.go` -- call `handleEventVotesQuery` in `handleReceive`
- `gateway/handlers.go` -- implement `handleEventVotesQuery`
## API Endpoints Used
- `GET /api/sessions/active` (existing)
- `GET /api/sessions/{id}/games` (new client method)
- `GET /api/sessions/{id}/votes` (new client method)
- `GET /api/games/{id}` (new client method)