Files
jackboxpartypack-gamepicker/docs/WEBSOCKET_FLOW_DIAGRAM.md
cottongin 84398ebdd0 Reorganize project: move docs to docs/ and test scripts to tests/
Moved 9 documentation .md files from root into docs/.
Moved 4 test scripts from root into tests/.
Updated cross-references in README.md and docs to reflect new paths.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:07:39 -05:00

18 KiB

WebSocket Event Flow Diagram

🔄 Complete Session Lifecycle

┌─────────────────────────────────────────────────────────────────┐
│                         BOT CONNECTS                             │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│  Bot → Server: { type: "auth", token: "..." }                   │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│  Server → Bot: { type: "auth_success" }                         │
│  ✅ Bot is now AUTHENTICATED                                     │
│  ⏳ Bot waits... (no subscription yet)                           │
└─────────────────────────────────────────────────────────────────┘
                              ↓
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│                    ADMIN CREATES SESSION                         │
│  POST /api/sessions { notes: "Friday Game Night" }              │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│  Server → ALL AUTHENTICATED CLIENTS:                            │
│  {                                                               │
│    type: "session.started",                                     │
│    data: {                                                       │
│      session: { id: 22, is_active: 1, ... }                    │
│    }                                                             │
│  }                                                               │
│  📢 Broadcast to ALL (no subscription needed)                   │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│  Bot receives session.started                                   │
│  🎮 Bot announces: "Game Night #22 has started!"                │
│                                                                  │
│  Bot → Server: { type: "subscribe", sessionId: 22 }            │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│  Server → Bot: { type: "subscribed", sessionId: 22 }           │
│  ✅ Bot is now SUBSCRIBED to session 22                         │
└─────────────────────────────────────────────────────────────────┘
                              ↓
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│                    ADMIN ADDS GAME                               │
│  POST /api/sessions/22/games { game_id: 45 }                   │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│  Server → SUBSCRIBED CLIENTS (session 22):                      │
│  {                                                               │
│    type: "game.added",                                          │
│    data: {                                                       │
│      game: { title: "Quiplash 3", ... }                        │
│    }                                                             │
│  }                                                               │
│  📢 Only to subscribers of session 22                           │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│  Bot receives game.added                                        │
│  🎲 Bot announces: "Now playing: Quiplash 3"                    │
│  🗳️ Bot announces: "Vote with thisgame++ or thisgame--"        │
└─────────────────────────────────────────────────────────────────┘
                              ↓
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│                    USER VOTES                                    │
│  POST /api/votes/live { username: "Alice", vote: "up" }        │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│  Server → SUBSCRIBED CLIENTS (session 22):                      │
│  {                                                               │
│    type: "vote.received",                                       │
│    data: {                                                       │
│      vote: { username: "Alice", type: "up" }                   │
│    }                                                             │
│  }                                                               │
│  📢 Only to subscribers of session 22                           │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│  Bot receives vote.received                                     │
│  🗳️ Bot tracks vote (may announce later)                        │
└─────────────────────────────────────────────────────────────────┘
                              ↓
                    (more games and votes...)
                              ↓
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│                    ADMIN CLOSES SESSION                          │
│  POST /api/sessions/22/close                                    │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│  Server → SUBSCRIBED CLIENTS (session 22):                      │
│  {                                                               │
│    type: "session.ended",                                       │
│    data: {                                                       │
│      session: { id: 22, is_active: 0, games_played: 5 }       │
│    }                                                             │
│  }                                                               │
│  📢 Only to subscribers of session 22                           │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│  Bot receives session.ended                                     │
│  🗳️ Bot announces: "Final votes for Quiplash 3: 5👍 1👎"       │
│  🌙 Bot announces: "Game Night ended! 5 games played"           │
│  ⏳ Bot waits for next session.started...                       │
└─────────────────────────────────────────────────────────────────┘

📊 Broadcast Scope Comparison

session.started (Global Broadcast)

┌─────────────────────────────────────────────────────────────────┐
│                         SERVER                                   │
│                                                                  │
│  broadcastToAll('session.started', data)                        │
└─────────────────────────────────────────────────────────────────┘
                    ↓           ↓           ↓
         ┌──────────┴───────────┴───────────┴──────────┐
         ↓                      ↓                       ↓
    ┌────────┐            ┌────────┐             ┌────────┐
    │ Bot A  │            │ Bot B  │             │ Bot C  │
    │   ✅   │            │   ✅   │             │   ✅   │
    └────────┘            └────────┘             └────────┘
    
    ALL authenticated clients receive it
    (no subscription required)

game.added, vote.received, session.ended (Session-Specific)

┌─────────────────────────────────────────────────────────────────┐
│                         SERVER                                   │
│                                                                  │
│  broadcastEvent('game.added', data, sessionId: 22)              │
└─────────────────────────────────────────────────────────────────┘
                              ↓
                    ┌─────────┴─────────┐
                    ↓                   ↓
               ┌────────┐          ┌────────┐          ┌────────┐
               │ Bot A  │          │ Bot B  │          │ Bot C  │
               │   ✅   │          │   ❌   │          │   ✅   │
               │subscr. │          │  not   │          │subscr. │
               │sess 22 │          │subscr. │          │sess 22 │
               └────────┘          └────────┘          └────────┘
    
    ONLY subscribers to session 22 receive it

🎯 Bot State Machine

┌─────────────┐
│ DISCONNECTED│
└──────┬──────┘
       │ connect()
       ↓
┌─────────────┐
│  CONNECTED  │
└──────┬──────┘
       │ send auth
       ↓
┌─────────────┐
│AUTHENTICATED│ ← Wait here for session.started
└──────┬──────┘   (no subscription yet)
       │
       │ receive session.started
       ↓
┌─────────────┐
│   WAITING   │
│     TO      │
│  SUBSCRIBE  │
└──────┬──────┘
       │ send subscribe
       ↓
┌─────────────┐
│ SUBSCRIBED  │ ← Now receive game.added, vote.received, session.ended
└──────┬──────┘
       │
       │ receive session.ended
       ↓
┌─────────────┐
│AUTHENTICATED│ ← Back to waiting for next session.started
└─────────────┘   (still authenticated, but not subscribed)

🔍 Event Flow by Subscription Status

Before Subscription (Just Authenticated)

Server Events:              Bot Receives:
─────────────               ─────────────
session.started      ✅      YES (broadcast to all)
game.added           ❌      NO  (not subscribed yet)
vote.received        ❌      NO  (not subscribed yet)
session.ended        ❌      NO  (not subscribed yet)

After Subscription (Subscribed to Session 22)

Server Events:              Bot Receives:
─────────────               ─────────────
session.started      ✅      YES (still broadcast to all)
game.added           ✅      YES (subscribed to session 22)
vote.received        ✅      YES (subscribed to session 22)
session.ended        ✅      YES (subscribed to session 22)

🎮 Multiple Sessions Example

Time    Event                           Bot A (sess 22)    Bot B (sess 23)
────    ─────                           ───────────────    ───────────────
10:00   session.started (sess 22)       ✅ Receives        ✅ Receives
10:01   Bot A subscribes to sess 22     ✅ Subscribed      ❌ Not subscribed
10:02   game.added (sess 22)            ✅ Receives        ❌ Doesn't receive
10:05   session.started (sess 23)       ✅ Receives        ✅ Receives
10:06   Bot B subscribes to sess 23     ✅ Still sess 22   ✅ Subscribed
10:07   game.added (sess 22)            ✅ Receives        ❌ Doesn't receive
10:08   game.added (sess 23)            ❌ Doesn't receive ✅ Receives
10:10   session.ended (sess 22)         ✅ Receives        ❌ Doesn't receive
10:15   session.ended (sess 23)         ❌ Doesn't receive ✅ Receives

📝 Quick Reference

Event Broadcast Method Scope Subscription Required?
session.started broadcastToAll() All authenticated clients NO
game.added broadcastEvent() Session subscribers only YES
vote.received broadcastEvent() Session subscribers only YES
session.ended broadcastEvent() Session subscribers only YES