docs: comprehensive API documentation from source code
Replace existing docs with fresh documentation built entirely from source code analysis. OpenAPI 3.1 spec as source of truth, plus human-readable Markdown with curl examples, response samples, and workflow guides. - OpenAPI 3.1 spec covering all 42 endpoints (validated against source) - 7 endpoint reference docs (auth, games, sessions, picker, stats, votes, webhooks) - WebSocket protocol documentation (auth, subscriptions, 4 event types) - 4 guide documents (getting started, session lifecycle, voting, webhooks) - API README with overview, auth docs, and quick reference table - Old docs archived to docs/archive/ Made-with: Cursor
This commit is contained in:
361
docs/archive/SESSION_START_WEBSOCKET.md
Normal file
361
docs/archive/SESSION_START_WEBSOCKET.md
Normal file
@@ -0,0 +1,361 @@
|
||||
# Session Start WebSocket Event
|
||||
|
||||
This document describes the `session.started` WebSocket event that is broadcast when a new game session is created.
|
||||
|
||||
## 📋 Event Overview
|
||||
|
||||
When a new session is created, the backend broadcasts a `session.started` event to all subscribed WebSocket clients. This allows bots and other integrations to react immediately to new game sessions.
|
||||
|
||||
## 🔌 WebSocket Connection
|
||||
|
||||
**Endpoint:** `ws://localhost:5000/api/sessions/live`
|
||||
|
||||
**Authentication:** Required (JWT token)
|
||||
|
||||
## 📨 Event Format
|
||||
|
||||
### Event Type
|
||||
```
|
||||
session.started
|
||||
```
|
||||
|
||||
### Full Message Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "session.started",
|
||||
"timestamp": "2025-11-01T20:00:00.123Z",
|
||||
"data": {
|
||||
"session": {
|
||||
"id": 17,
|
||||
"is_active": 1,
|
||||
"created_at": "2025-11-01T20:00:00.123Z",
|
||||
"notes": "Friday Game Night"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Field Descriptions
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `type` | string | Always `"session.started"` |
|
||||
| `timestamp` | string | ISO 8601 timestamp when the event was generated |
|
||||
| `data.session.id` | number | The ID of the newly created session |
|
||||
| `data.session.is_active` | number | Always `1` (active) for new sessions |
|
||||
| `data.session.created_at` | string | ISO 8601 timestamp when the session was created |
|
||||
| `data.session.notes` | string/null | Optional notes for the session |
|
||||
|
||||
## 🚀 Implementation
|
||||
|
||||
### Backend Implementation
|
||||
|
||||
The `session.started` event is automatically broadcast when:
|
||||
|
||||
1. **New Session Created**: Admin creates a session via `POST /api/sessions`
|
||||
|
||||
**Code Location:** `backend/routes/sessions.js` - `POST /` endpoint
|
||||
|
||||
```javascript
|
||||
// Broadcast session.started event via WebSocket
|
||||
const wsManager = getWebSocketManager();
|
||||
if (wsManager) {
|
||||
const eventData = {
|
||||
session: {
|
||||
id: newSession.id,
|
||||
is_active: 1,
|
||||
created_at: newSession.created_at,
|
||||
notes: newSession.notes
|
||||
}
|
||||
};
|
||||
|
||||
wsManager.broadcastEvent('session.started', eventData, parseInt(newSession.id));
|
||||
}
|
||||
```
|
||||
|
||||
### Client Implementation Example
|
||||
|
||||
#### Node.js with `ws` library
|
||||
|
||||
```javascript
|
||||
const WebSocket = require('ws');
|
||||
|
||||
const ws = new WebSocket('ws://localhost:5000/api/sessions/live');
|
||||
|
||||
ws.on('open', () => {
|
||||
// Authenticate
|
||||
ws.send(JSON.stringify({
|
||||
type: 'auth',
|
||||
token: 'your-jwt-token'
|
||||
}));
|
||||
});
|
||||
|
||||
ws.on('message', (data) => {
|
||||
const message = JSON.parse(data.toString());
|
||||
|
||||
switch (message.type) {
|
||||
case 'auth_success':
|
||||
// Subscribe to the new session (or subscribe when you receive session.started)
|
||||
ws.send(JSON.stringify({
|
||||
type: 'subscribe',
|
||||
sessionId: 17
|
||||
}));
|
||||
break;
|
||||
|
||||
case 'session.started':
|
||||
console.log('New session started!');
|
||||
console.log(`Session ID: ${message.data.session.id}`);
|
||||
console.log(`Created at: ${message.data.session.created_at}`);
|
||||
if (message.data.session.notes) {
|
||||
console.log(`Notes: ${message.data.session.notes}`);
|
||||
}
|
||||
|
||||
// Auto-subscribe to the new session
|
||||
ws.send(JSON.stringify({
|
||||
type: 'subscribe',
|
||||
sessionId: message.data.session.id
|
||||
}));
|
||||
break;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### Python with `websockets` library
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
import json
|
||||
import websockets
|
||||
|
||||
async def listen_for_session_start():
|
||||
uri = "ws://localhost:5000/api/sessions/live"
|
||||
|
||||
async with websockets.connect(uri) as websocket:
|
||||
# Authenticate
|
||||
await websocket.send(json.dumps({
|
||||
"type": "auth",
|
||||
"token": "your-jwt-token"
|
||||
}))
|
||||
|
||||
async for message in websocket:
|
||||
data = json.loads(message)
|
||||
|
||||
if data["type"] == "auth_success":
|
||||
print("Authenticated, waiting for sessions...")
|
||||
|
||||
elif data["type"] == "session.started":
|
||||
session = data["data"]["session"]
|
||||
print(f"🎮 New session started! ID: {session['id']}")
|
||||
print(f"📅 Created: {session['created_at']}")
|
||||
if session.get('notes'):
|
||||
print(f"📝 Notes: {session['notes']}")
|
||||
|
||||
# Auto-subscribe to the new session
|
||||
await websocket.send(json.dumps({
|
||||
"type": "subscribe",
|
||||
"sessionId": session["id"]
|
||||
}))
|
||||
|
||||
asyncio.run(listen_for_session_start())
|
||||
```
|
||||
|
||||
## 🧪 Testing
|
||||
|
||||
### Manual Testing Steps
|
||||
|
||||
1. **Start the backend server:**
|
||||
```bash
|
||||
cd backend
|
||||
npm start
|
||||
```
|
||||
|
||||
2. **Connect a WebSocket client** (use the test script or your own):
|
||||
```bash
|
||||
# You can modify ../tests/test-session-end-websocket.js to listen for session.started
|
||||
```
|
||||
|
||||
3. **Create a new session** in the Picker UI or via API:
|
||||
```bash
|
||||
curl -X POST http://localhost:5000/api/sessions \
|
||||
-H "Authorization: Bearer <your-jwt-token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"notes": "Friday Game Night"}'
|
||||
```
|
||||
|
||||
4. **Verify the event is received** by your WebSocket client
|
||||
|
||||
### Expected Event
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "session.started",
|
||||
"timestamp": "2025-11-01T20:00:00.123Z",
|
||||
"data": {
|
||||
"session": {
|
||||
"id": 18,
|
||||
"is_active": 1,
|
||||
"created_at": "2025-11-01T20:00:00.123Z",
|
||||
"notes": "Friday Game Night"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🤖 Bot Integration
|
||||
|
||||
### IRC/Kosmi Bot Example
|
||||
|
||||
When the bot receives a `session.started` event, it should:
|
||||
|
||||
1. **Announce the new game session** to users
|
||||
2. **Auto-subscribe to the session** to receive game.added and session.ended events
|
||||
3. **Optionally display session info** (notes, ID, etc.)
|
||||
|
||||
Example bot response:
|
||||
```
|
||||
🎮 Game Night has started! Session #18
|
||||
📝 Friday Game Night
|
||||
🗳️ Vote with thisgame++ or thisgame-- during games!
|
||||
```
|
||||
|
||||
### Implementation Example
|
||||
|
||||
```javascript
|
||||
ws.on('message', (data) => {
|
||||
const msg = JSON.parse(data.toString());
|
||||
|
||||
if (msg.type === 'session.started') {
|
||||
const { id, notes, created_at } = msg.data.session;
|
||||
|
||||
// Announce to IRC/Discord/etc
|
||||
bot.announce(`🎮 Game Night has started! Session #${id}`);
|
||||
if (notes) {
|
||||
bot.announce(`📝 ${notes}`);
|
||||
}
|
||||
bot.announce('🗳️ Vote with thisgame++ or thisgame-- during games!');
|
||||
|
||||
// Auto-subscribe to this session
|
||||
ws.send(JSON.stringify({
|
||||
type: 'subscribe',
|
||||
sessionId: id
|
||||
}));
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## 🔍 Debugging
|
||||
|
||||
### Check WebSocket Logs
|
||||
|
||||
The backend logs WebSocket events:
|
||||
|
||||
```
|
||||
[Sessions] Broadcasted session.started event for session 18
|
||||
[WebSocket] Broadcasted session.started to 1 client(s) for session 18
|
||||
```
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Event not received:**
|
||||
- Verify the client is authenticated (`auth_success` received)
|
||||
- Check backend logs for broadcast confirmation
|
||||
- **No subscription required** - All authenticated clients automatically receive `session.started` events
|
||||
- Make sure your WebSocket connection is open and authenticated
|
||||
|
||||
2. **Missing session data:**
|
||||
- Check if the session was created successfully
|
||||
- Verify the API response includes all fields
|
||||
|
||||
3. **Duplicate events:**
|
||||
- Normal if multiple clients are connected
|
||||
- Each client receives its own copy of the event
|
||||
|
||||
## 📚 Related Documentation
|
||||
|
||||
- [Session End WebSocket Event](SESSION_END_WEBSOCKET.md)
|
||||
- [WebSocket Testing Guide](WEBSOCKET_TESTING.md)
|
||||
- [Bot Integration Guide](BOT_INTEGRATION.md)
|
||||
- [API Quick Reference](API_QUICK_REFERENCE.md)
|
||||
|
||||
## 🔗 Session Lifecycle Events
|
||||
|
||||
```
|
||||
session.started
|
||||
↓
|
||||
game.added (multiple times)
|
||||
↓
|
||||
vote.received (during each game)
|
||||
↓
|
||||
session.ended
|
||||
```
|
||||
|
||||
## 📝 Notes
|
||||
|
||||
- The `session.started` event is broadcast to **all authenticated clients** (not just subscribed ones)
|
||||
- **No subscription required** - All authenticated clients automatically receive this event
|
||||
- Clients should auto-subscribe to the new session to receive subsequent `game.added` and `vote.received` events
|
||||
- The `is_active` field will always be `1` for new sessions
|
||||
- The `notes` field may be `null` if no notes were provided
|
||||
- The timestamp is in ISO 8601 format with timezone (UTC)
|
||||
|
||||
## 💡 Use Cases
|
||||
|
||||
1. **Bot Announcements** - Notify users when game night starts
|
||||
2. **Auto-Subscription** - Automatically subscribe to new sessions
|
||||
3. **Session Tracking** - Track all sessions in external systems
|
||||
4. **Analytics** - Log session creation times and frequency
|
||||
5. **Notifications** - Send push notifications to users
|
||||
|
||||
## 🎯 Best Practices
|
||||
|
||||
1. **Auto-subscribe** to new sessions when you receive `session.started`
|
||||
2. **Store the session ID** for later reference
|
||||
3. **Handle reconnections** gracefully (you might miss the event)
|
||||
4. **Use polling as fallback** to detect sessions created while disconnected
|
||||
5. **Validate session data** before processing
|
||||
|
||||
## 🔄 Complete Event Flow Example
|
||||
|
||||
```javascript
|
||||
const WebSocket = require('ws');
|
||||
const ws = new WebSocket('ws://localhost:5000/api/sessions/live');
|
||||
|
||||
let currentSessionId = null;
|
||||
|
||||
ws.on('message', (data) => {
|
||||
const msg = JSON.parse(data.toString());
|
||||
|
||||
switch (msg.type) {
|
||||
case 'session.started':
|
||||
currentSessionId = msg.data.session.id;
|
||||
console.log(`🎮 Session ${currentSessionId} started!`);
|
||||
|
||||
// Auto-subscribe
|
||||
ws.send(JSON.stringify({
|
||||
type: 'subscribe',
|
||||
sessionId: currentSessionId
|
||||
}));
|
||||
break;
|
||||
|
||||
case 'game.added':
|
||||
console.log(`🎲 New game: ${msg.data.game.title}`);
|
||||
break;
|
||||
|
||||
case 'vote.received':
|
||||
console.log(`🗳️ Vote: ${msg.data.vote.type}`);
|
||||
break;
|
||||
|
||||
case 'session.ended':
|
||||
console.log(`🌙 Session ${msg.data.session.id} ended!`);
|
||||
console.log(`📊 Games played: ${msg.data.session.games_played}`);
|
||||
currentSessionId = null;
|
||||
break;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## ✨ Conclusion
|
||||
|
||||
The `session.started` WebSocket event provides instant notification when new game sessions are created, allowing bots and integrations to react immediately and provide a seamless user experience.
|
||||
|
||||
Reference in New Issue
Block a user