Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
# OpenSpec Change: websocket-gateway
- **Change ID**: websocket-gateway
- **Package**: `@suaveplan/websocket-gateway`
- **Category**: server (Node-only)
- **Target path**: `packages/network/websocket-gateway`
- **Status**: PROPOSED
- **Date**: 2026-05-11
- **Parent**: `network-transport-family` (2026-05-11) — Wave 5
- **Migration source**: `../suaveplan/packages/server/websocket-gateway` + `../suaveplan/enterprise/websocket-gateway.md`
---
## Summary
Migrate `@suaveplan/websocket-gateway` into genesis as a server-tier daemon providing **rooms + presence** semantics over WebSocket connections. Pairs with `@suaveplan/network-transport-websockets` ✅ (post-Wave-1 adapter refactor) on the client side. Rooms scope message delivery; presence tracks who is connected to which room; channel multiplexing lets multiple logical streams share one TCP connection.
---
## Why Wave 5 (not earlier)
- Depends on the `network-transport-websockets-adapter` Wave-1 refactor (server-side rooms need the `Transport` contract on the client side).
- Server-tier package — bundles with Wave-4 transports, not Wave-3 browser packages.
---
## Current-state audit
Upstream coverage: 97.85% statement.
Upstream source layout (`../suaveplan/packages/server/websocket-gateway/src/`):
- `gateway/` — main `WebSocketGateway` daemon
- `channel/` — channel multiplexing
- `room/` — room semantics (join / leave / broadcast / direct)
- `presence/` — presence subsystem (who's in which room)
- `types/` — public type surface
- `index.ts` — barrel
---
## Parity Checklist
| Capability | Upstream | Migrated | Notes |
|---|---|---|---|
| `WebSocketGateway` daemon | ✅ | ✅ | |
| Room semantics (join/leave/broadcast/direct) | ✅ | ✅ | |
| Presence tracking | ✅ | ✅ | |
| Channel multiplexing | ✅ | ✅ | |
| Plugin wiring via `@suaveplan/api` `definePlugin()` | upstream-required | ⬆️ | Once `@suaveplan/api` lands on genesis (not yet ✅), wire via `definePlugin()`. Until then a standalone `start()`/`stop()` lifecycle. |
| JWT auth via `@suaveplan/jwt-tenant` | upstream-required | ⬆️ | Once shipped on genesis. Until then inject `AuthVerifier` callback. |
| RBAC/ABAC via `@suaveplan/permissions` | upstream-required | ⬆️ | Same: inject `AuthorizationCheck` callback. |
| Rate-limiting via `@suaveplan/rate-limiter` | upstream-required | ⬆️ | Once available. |
| Idempotency via `@suaveplan/idempotency` ✅ | upstream-required | ✅ | Wired directly. |
| Audit logging via `@suaveplan/audit-logging` | upstream-required | ⬆️ | Once available. Until then `@suaveplan/logger` ✅ with structured fields. |
| OTel spans + Prometheus metrics | upstream-required | ⬆️ | Spans `ws_gateway.connect`/`message`/`broadcast`, counters `ws_gateway.rooms_active`, `ws_gateway.presence_updates_total`, histograms `ws_gateway.message_dispatch_ms`. |
| `AbortSignal` everywhere | partial | ⬆️ | Threaded through every lifecycle method. |
| Retry + circuit breakers via `@suaveplan/retry` ✅ | upstream-required | ✅ | Wired on every outbound integration. |
| Health / readiness / liveness | upstream-required | ⬆️ | Inline `/health`, `/ready`, `/live` endpoints until `@suaveplan/health-check` lands. |
| Webhooks via `@suaveplan/webhook-client` ✅ | upstream-required | ✅ | Wired for presence-event webhooks. |
| Structured errors | 🚫 | ⬆️ | `defineCodes("WS_GATEWAY", [...])`: `ROOM_NOT_FOUND`, `ROOM_FULL`, `CHANNEL_INVALID`, `AUTH_REJECTED`, `RATE_LIMITED`, `INVALID_OPTIONS`. |
| Zod boundary validation | partial | ⬆️ | Every public option + every wire frame. |
| `export *` barrels | check | ⬆️ | Convert to explicit named exports per §6a. |
| Test-runner imports | direct vitest | ⬆️ | Rewrite to `@suaveplan/testing/runner` per §7. |
| 100% test coverage | 🚫 (97.85%) | ⬆️ | Bring to 100/100/100/100. |
| Integration tests | partial | ⬆️ | Real-server boot via `@suaveplan/testing-integration`; no mocks. |
---
## Available workspace deps on genesis
- `@suaveplan/network-transport-websockets` ⬅ post-Wave-1 (after adapter refactor)
- `@suaveplan/idempotency` ✅
- `@suaveplan/retry` ✅
- `@suaveplan/webhook-client` ✅
- `@suaveplan/logger` ✅
- `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`, `@suaveplan/timing` ✅
- `@suaveplan/testing` + `@suaveplan/testing-integration` ✅
- External: `ws` or `bun:websocket` (universal façade) — add to root catalog under `network-server`.
**Blocking note.** Migration can start once `network-transport-websockets-adapter` ships and (optionally) `@suaveplan/api`, `@suaveplan/jwt-tenant`, `@suaveplan/permissions`, `@suaveplan/rate-limiter`, `@suaveplan/audit-logging`, `@suaveplan/health-check` are on genesis. Auth and rate-limit hooks accept callbacks until those packages land.
---
## Acceptance gate
1. `bunx turbo lint typecheck test --filter=@suaveplan/websocket-gateway` green.
2. `bunx turbo test:coverage --filter=@suaveplan/websocket-gateway` 100/100/100/100.
3. `bun run docs:check` green.
4. Integration test: 3 clients connect via `network-transport-websockets`, join rooms, exchange messages, observe presence events. No mocks.
5. `STATUS.md` row flipped.
---
## Out of scope
- Production TLS termination (deployment concern).
- Cross-instance gateway clustering (federate via `@suaveplan/network` mesh in a future change).
- Persistent room state (separate `websocket-gateway-store-*` package if needed).

View File

@@ -0,0 +1,63 @@
# Tasks — websocket-gateway
## Phase 1: Scaffold
- [ ] 1.1 Create `packages/network/websocket-gateway/`, server-tier marker comment.
- [ ] 1.2 `package.json` at `0.1.0`, `"engines": { "node": ">=20" }`, NO `browser` field.
- [ ] 1.3 Test config via `createTestConfig()`; `tests/dep-graph.test.ts`.
- [ ] 1.4 Add `ws` (or commit to `bun:websocket` façade) to root catalog under `network-server`.
## Phase 2: Types + errors
- [ ] 2.1 Port `types/` → `src/types/` + sibling `.md`.
- [ ] 2.2 `defineCodes("WS_GATEWAY", [...])`: `ROOM_NOT_FOUND`, `ROOM_FULL`, `CHANNEL_INVALID`, `AUTH_REJECTED`, `RATE_LIMITED`, `INVALID_OPTIONS`.
- [ ] 2.3 Zod schemas for every public option struct + every wire frame.
## Phase 3: Core subsystems
- [ ] 3.1 Port `room/` — join/leave/broadcast/direct.
- [ ] 3.2 Port `presence/` — who's in which room.
- [ ] 3.3 Port `channel/` — channel multiplexing over one WS connection.
- [ ] 3.4 Port `gateway/` — main `WebSocketGateway` daemon.
## Phase 4: Hooks for unmigrated deps
- [ ] 4.1 `AuthVerifier` callback (JWT integration deferred until `@suaveplan/jwt-tenant` lands).
- [ ] 4.2 `AuthorizationCheck` callback (RBAC integration deferred).
- [ ] 4.3 `RateLimitGate` callback (rate-limiter integration deferred).
- [ ] 4.4 Replace placeholders with real package wiring as each lands on genesis.
## Phase 5: Observability + reliability
- [ ] 5.1 OTel spans `ws_gateway.connect`/`message`/`broadcast`.
- [ ] 5.2 Counters `ws_gateway.rooms_active`, `presence_updates_total`.
- [ ] 5.3 Histograms `ws_gateway.message_dispatch_ms`.
- [ ] 5.4 Retry + circuit breakers via `@suaveplan/retry` on outbound integrations.
- [ ] 5.5 Idempotency guard via `@suaveplan/idempotency` on every mutating event.
- [ ] 5.6 Webhook delivery via `@suaveplan/webhook-client` on presence events.
- [ ] 5.7 Health / readiness / liveness endpoints (inline until `@suaveplan/health-check` lands).
## Phase 6: Tests + docs
- [ ] 6.1 Unit tests via `@suaveplan/testing/runner`.
- [ ] 6.2 fast-check property tests: room invariants, presence eventual consistency, channel mux fairness.
- [ ] 6.3 Integration test via `@suaveplan/testing-integration`: 3-client scenario (rooms + presence + messages), no mocks.
- [ ] 6.4 100/100/100/100 coverage gate.
- [ ] 6.5 Sibling `.md` per `.ts` impl file.
- [ ] 6.6 Root `README.md` with daemon-run + client-pairing examples.
## Phase 7: Verification
- [ ] 7.1 `bunx turbo lint typecheck test --filter=@suaveplan/websocket-gateway` green.
- [ ] 7.2 `bunx turbo test:coverage --filter=@suaveplan/websocket-gateway` 100/100/100/100.
- [ ] 7.3 `bun run docs:check` green.
- [ ] 7.4 `MANIFEST.md` regen.
- [ ] 7.5 `STATUS.md` row flipped.
## Pre-archive checklist
- [ ] Row 1 — Phase 7 green.
- [ ] Row 2 — 3-client integration test passes.
- [ ] Row 3 — Auth/rate-limit/audit callbacks documented with replacement paths.
- [ ] Row 4 — `openspec/specs/websocket-gateway/spec.md` written.
- [ ] Row 5 — Folder archived.