
# Realtime Hub Design Specification - `gameHub`

This document provides a detailed architectural overview of the `gameHub` realtime hub within the `gameplay` service. It covers the hub's room management, message handling, role-based authorization, event system, and server-side logic.

## Hub Overview

**Description:** Real-time chess game hub. Each chessGame is a room where two players exchange moves, see board state, and receive game lifecycle events (draw offer, resign, timeout, save requests). Supports both guest and registered players.

- **Socket.IO Namespace:** `/hub/gameHub`
- **Room DataObject:** `chessGame`

## Room Settings


Rooms are backed by the `chessGame` DataObject. Each record in this object represents a room that users can join.



### Room Eligibility
Before authorization checks, the following condition is evaluated. If it returns false, nobody can join the room:

```js
chessGame.status == 'active' || chessGame.status == 'pending' || chessGame.status == 'paused'
```


### Authorization Flow

The hub uses a layered authorization flow to determine each user's role when joining a room:


1. **Absolute Roles:** Users with roles `administrator` bypass all checks and receive the `system` hub role with full permissions.







4. **Auth Sources:** The following DataObject-based authorization sources are checked in order. The first match determines the user's hub role:

   1. **whitePlayer**
   2. **blackPlayer**






## Hub Roles

| Role | Read | Send | Moderate | Delete Any | Manage Room | Moderated |
|------|------|------|----------|------------|-------------|-----------|
| `player` | Yes | Yes | No | No | No | No |





## Message Settings




### Built-in Message Types
The following message types are supported:

- `text`
- `system`



### Cross-Cutting Features
- **Reply Threading:** Disabled
- **Reactions:** Disabled
- **Forwarded Flag:** Disabled


### Custom Message Types
- **chessMove**: App-specific message type
  Fields: `[]`
- **drawOffer**: App-specific message type
  Fields: `[]`
- **drawAccepted**: App-specific message type
  Fields: `[]`
- **drawDeclined**: App-specific message type
  Fields: `[]`
- **resignation**: App-specific message type
  Fields: `[]`
- **saveRequest**: App-specific message type
  Fields: `[]`
- **saveAccepted**: App-specific message type
  Fields: `[]`
- **saveDeclined**: App-specific message type
  Fields: `[]`
- **resumeRequest**: App-specific message type
  Fields: `[]`
- **resumeAccepted**: App-specific message type
  Fields: `[]`
- **resumeDeclined**: App-specific message type
  Fields: `[]`




## Event Settings


### Standard Events
| Event | Enabled | Type |
|-------|---------|------|
| Typing Indicator | No | Ephemeral |
| Recording Indicator | No | Ephemeral |
| Read Receipts | No | Persisted |
| Delivery Receipts | No | Persisted |
| Presence | Yes | Ephemeral |

### Auto-Bridged DataObject Events
CRUD events from the room, membership, and message DataObjects are automatically bridged via Kafka and broadcast to connected clients. This includes events like `memberJoined`, `messageEdited`, `roomUpdated`, etc.


### Custom Events
- **gameStateUpdate**
  - Direction: `serverToRoom`
  - Ephemeral: Yes
  - Broadcast updated game state (status, result, timers) to both players when the game state changes server-side.
- **clockTick**
  - Direction: `serverToRoom`
  - Ephemeral: Yes
  - Server broadcasts remaining time for each player (for timed/blitz/rapid games).







## History Settings




## Guardrails

| Setting | Value |
|---------|-------|
| Max Users Per Room | 3 |
| Max Rooms Per User | 5 |
| Message Rate Limit | 120 msg/min |
| Max Message Size | 16384 bytes |
| Connection Timeout | 600000 ms |
| Auth Cache TTL | 300 seconds |
| Global Moderation | No |
| Default Silenced | No |



## Server-Side Logic








---

*This document was generated from the realtime hub configuration and should be kept in sync with design changes.*
