Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

08 — Form Specifications (WS / Realtime Module)

The realtime module has no forms — but it has wire inputs. This file specifies the only data the client ever sends, the handshake parameters, and their validation, because they are the module's equivalent of a form contract. General form/validation conventions: 00-shared/07 (API conventions) and 00-shared/03 (form primitives).


1. Handshake inputs (not a form, but a contract)

InputWhereRulesSource
Access tokenhandshake.auth.token or handshake.query.tokenrequired; JWT verified against JWT_ACCESS_SECRET; missing → UnauthorizedException('Missing token'); any verify failure → socket closedws.gateway.ts:37-44,54-56
NamespaceURL path /wsfixedws.gateway.ts:20-23

Client rules:

  • Prefer auth.token (not in URL/logs); query.token exists for non-engine.io clients.
  • Token must be the same family as REST (JWT_ACCESS_SECRET), so refresh flow is shared.
  • No other handshake fields (no tenantId — server takes it from the token, ws.gateway.ts:47).

2. Client→server messages

EventPayloadValidation (source)Effect
subscriberoom: stringtypeof room !== 'string' → silently ignored (ws.gateway.ts:65)join room → future broadcastToRoom delivery (ws.gateway.ts:80-82)
unsubscriberoom: stringtypeof room !== 'string' → silently ignored (ws.gateway.ts:71)leave room

Semantics:

  • Idempotent: subscribing twice is safe (socket.io joins are idempotent).
  • No acknowledgment message is sent (server does not reply — no ack/error channel in source; verified: gateway handlers return void).
  • No validation of room name content: any string accepted → gap (allow-list + RBAC recommended, 12 §5).

3. What the client must validate (proposed)

  • room length ≤ 128; only [a-z0-9:_-] charset enforced client-side to avoid injecting reserved namespaces; server-side enforcement is the real fix (gap).
  • Never subscribe to tenant:{...} explicitly (automatic — duplicate is harmless).

4. Server→client "responses" (informational, not form errors)

SituationServer behaviorClient handling
Bad/missing tokenclose connection (no error event)state error-auth → refresh token → reconnect (06 §1.2)
Successful connectjoins tenant:{tenantId} (ws.gateway.ts:50)state connected
Event deliveryenvelope {eventType, occurredAt, payload} (ws-bridge.service.ts:17-21)validate envelope, route to blocs (13)
Unknown client event nameignored (no handler registered)n/a (client only sends subscribe/unsubscribe)

5. Future wire inputs (planned)

  • Communication module will define its own client→server messages (send/typing/read receipts) (planned)docs/IMPLEMENTATION_PLAN.md:119. Until then the client MUST NOT send free-form messages.
  • Event-subscription filters (per-eventType) (planned); today a client receives the whole tenant stream and filters locally (06 §6).