# Signaling Server (server) Owns the shared, internet-reachable runtime: HTTP routes for server directory / invites / join requests / link metadata, WebSocket signaling between clients (P2P session setup, presence, status), CQRS command and query handlers, and the shared TypeORM + sql.js persistence layer that holds signaling state. > **Format reference:** > - **Vocabulary** — bold term, one-sentence definition, aliases to avoid. > - **Relationships** — bullets with bold terms and cardinality. > - **Boundaries / IO** — what this subdomain exposes and consumes. > - **Invariants** — rules that always hold. > - **Flagged ambiguities** — terms in dispute with proposed resolutions. > > See `agents-docs/AGENTS_CONTEXT.md` for the contract. Update in the same turn a trigger fires (see `agents-docs/AGENT_WORKFLOW.md` § CONTEXT.md upkeep). ## Vocabulary | Term | Definition | Aliases to avoid | |------|------------|------------------| | **Envelope** | The on-the-wire shape of a WebSocket message — `type`, `payload`, and routing metadata, typed in `src/websocket/types.ts` and mirrored in `toju-app/src/app/shared-kernel/signaling-contracts.ts`. | "packet", "frame" | | **Handler** | A WebSocket message handler registered in `src/websocket/handler.ts`; one per envelope type. | "listener" | | **CQRS command/query** | A typed request dispatched through `src/cqrs/` — commands mutate state, queries read it; both return a typed result. | "action" (NgRx term) | | **Server directory** | The catalog of joinable chat servers, exposed by `src/routes/servers.ts` plus invite and join-request routes. | "guild list" | | **SSRF guard** | The outbound-fetch policy enforced by `src/routes/ssrf-guard.ts` — gates link-metadata and proxy routes that fetch user-supplied URLs. | "proxy filter" | | **Variables file** | `data/variables.json` — runtime config (klipy key, server host/protocol, release manifest URL, link-preview toggle) normalized on startup. | "config", ".env" (those are separate) | ## Relationships - A **WebSocket connection** carries many **Envelopes**; each envelope is routed to exactly one **Handler**. - A **Route** (HTTP) may dispatch zero or more **CQRS commands/queries** to mutate or read persistent state. - The **Server directory** depends on **Invites** and **Join requests** — listing, accepting, and revoking flows are split across `routes/servers.ts`, `routes/invites.ts`, `routes/join-requests.ts`. - **Persistence** entities in `src/entities/` are owned by this subdomain and never shipped to the renderer; the wire envelope is the contract instead. - **SSRF guard** is consumed by `link-metadata`, `proxy`, and `klipy` routes that fetch user-supplied URLs. ## Boundaries / IO - **Exposes:** - HTTP routes under `src/routes/`: `health`, `users`, `servers`, `invites`, `join-requests`, `games`, `klipy`, `link-metadata`, `proxy`, `plugin-support`, `openapi-docs`. - WebSocket envelopes typed in `src/websocket/types.ts` — the realtime contract shared with `toju-app/src/app/shared-kernel/signaling-contracts.ts`. - OpenAPI document served by `openapi-docs` route. - **Consumes:** - The shared TypeORM SQLite database via `src/db/` (entities in `src/entities/`, migrations in `src/migrations/`). - `data/variables.json` for runtime configuration; `.env` for `PORT` / SSL toggles. - Optional outbound HTTP for link previews and klipy (all gated by **SSRF guard**). ## Invariants - Every database schema change ships as a TypeORM **migration**; the live database is never mutated outside the migration system. - WebSocket **Envelope** types are defined once in `src/websocket/types.ts` and **must** stay structurally compatible with `toju-app/src/app/shared-kernel/signaling-contracts.ts` — drift between the two is a wire-protocol break. - User-supplied URLs are **never** fetched without going through `ssrf-guard.ts`. - Secrets (klipy API key, OAuth tokens, signing keys) live in `data/variables.json` or environment variables — never in code, never in logs. ## Flagged ambiguities - _None recorded yet — add entries when an envelope type or route name resists clean definition._ --- *Agent-procedural rules (TDD, lint, build) live in `/AGENTS.md`. WebSocket envelope schemas and HTTP request/response shapes belong in `agents-docs/features/` when they cross subdomain boundaries. This file is the bounded-context domain artefact for the signaling server.*