server
The single process that hosts the rooms, the HTTP API, the WebSocket gateway and settlement.
@gavel/server (packages/server) is where everything meets. One Node process owns the rooms, the HTTP routes, the /ws room socket, the /audio voice socket, the stores and the settlement runner. A Render blueprint for it is in render.yaml.
Responsibilities
- Compose.
boot/compose.tsbuilds the stores, the engine runtime, the payments gateway (fake or sandbox), the room and the HTTP server, and mounts the sockets.main.tsstarts it;config.tsvalidates the environment before anything starts. - Rooms.
room/room.tsruns one live auction: join, bid, confirm, hammer, soft close, resync. It talks to the engine only through the ports in@gavel/sharedandroom/settle-port.ts. - The confirm gate. A voice-like bid is held in
room/confirm.tsuntil its bidder answers; it waitsCONFIRM_TTL_MS(15 seconds) and the engine does not see it meanwhile.isVoiceLikecatches a spoken bid labelled as another source. - HTTP. Routes under
http/: auctions, control and kill, invites, holds, webhook, read (snapshot and events), demo, ops, health and metrics. - Auth.
auth/token.tsdefines four token kinds (invite,session,auctioneer,screen) with lifetimes of 24 h, 4 h, 12 h and 12 h; the payload schema is strict and analgfield is rejected.ADMIN_KEYis the operator key, not a token role. See threat model. - Settlement host.
runtime/auction-service.tsand the files beside it call the payments package: hold service, settlement bridge, webhook intake, reconcile and void phase. - Stores.
store/has memory, file (file-ledger-store.ts,file-room-store.ts, with a data directory lock) and Postgres (postgres.tswith forward-only migrations frommigrations/). - Limits.
limits/rate-limiter.tskeeps token buckets per client key: bids, frames, joins, HTTP. - Voice host.
host/audio-ws.tsandvoice/connect the/audiosocket to the voice pipeline and its speech-to-text providers. - Operations.
ops/(shutdown, fatal errors, metrics),obs/(log ring, Prometheus text) andwarmup/.
Public interface
src/index.ts is small: it re-exports ErrorCode, the settle port (room/settle-port.ts) and runtime/index.ts. The real entry points are processes and routes, not library calls.
| Surface | Where |
|---|---|
| Process start | src/main.ts (npm run start, or start:prod on the built dist/main.js) |
| Room socket | /ws (host/node-ws.ts, WS_PATH) |
| Voice socket | /audio (host/audio-ws.ts, AUDIO_PATH) |
| Health and metrics | /healthz, /metrics, /metrics/prometheus (boot/compose.ts) |
| API | /api/auctions, /api/holds, /api/demo/* and the routes in src/http/ |
See WebSocket protocol for the messages.
Configuration
Names only, read from src/config.ts; the server stops at boot with one JSON line per problem. Production-like environments need TOKEN_SECRET of at least 32 bytes and ADMIN_KEY of at least 24 characters, and the two must differ.
Prop
Type
The full table is in configuration. The names TOKEN_SECRET, ADMIN_KEY and PAYPAL_CLIENT_SECRET are secrets: never commit a value.
Key files
| File | Note |
|---|---|
boot/compose.ts | the single wiring point; chooses the store and the payments mode |
room/fence.ts | FencedStore: a stale expected sequence fences this host, and later appends fail with host_fenced without touching the store |
room/resync.ts | a reconnecting client gets a replay of at most 200 missed events; one token holds at most 3 connections; the oldest is closed with code 4011 superseded |
room/snapshot-policy.ts | a snapshot on a state change, or after 100 events |
runtime/webhook-intake.ts | stores a verified event, then applies it at most once per event id; an event for an unknown hold is parked and retried by a sweep |
http/webhook-guard.ts | webhook body limit of 256 KiB; only an event id and an outcome are logged |
store/data-dir-lock.ts | one process owns the data directory |
ops/shutdown.ts | going-away close code 1001 and a 30 second default deadline (SHUTDOWN_DEADLINE_MS overrides) |
Invariants and the tests that guard them
Tests: test/room-confirm.test.ts, test/room-confirm-atomic.test.ts, test/room-confirm-recover.test.ts, test/room-confirm-resolve.test.ts, test/room-confirm-supersede.test.ts, test/room-manual-consent.test.ts, test/confirm-audit-scrub.test.ts.
Tests: test/room-fence.test.ts, test/data-dir-lock.test.ts, test/race.test.ts.
Tests: test/room-wal.test.ts, test/bench-recover.test.ts, test/durable-stores.test.ts, test/store-contract.memory.test.ts, test/store-postgres.test.ts, test/checkpoint-kill.test.ts.
Tests: test/token.test.ts, test/token-fuzz.test.ts, test/rotation.test.ts, test/authorize.test.ts, test/ws-token-recheck.test.ts, test/http-auctioneer-token.test.ts, test/http-invites.test.ts.
Tests: test/rate-limiter.test.ts, test/flood-rate-limited.test.ts, test/caps.test.ts, test/boot-join-limit.test.ts, test/client-key-parity.test.ts.
Tests: test/http-events-redaction.test.ts, test/admin-export.test.ts, test/replay-bundle.test.ts, test/store-export.test.ts, test/room-audit.test.ts.
Tests: test/http-webhook.test.ts, test/http-webhook-guard.test.ts, test/http-webhook-dispatch.test.ts, runtime/webhook-intake.test.ts.
Tests: test/config.test.ts, test/boot-validate.test.ts, test/env-example.test.ts (the example file names exactly the variables the server reads), test/render-blueprint.test.ts.
Tests: test/room-hammer.test.ts, test/room-soft-close.test.ts, test/room-auto-hammer.test.ts, test/http-ops-settlement.test.ts, runtime/settlement-own-hold.test.ts, runtime/void-phase-queue.test.ts, test/scenario-runner.test.ts with the golden scenarios in test/scenarios/.
Tests: test/ceiling-policy.test.ts, test/contract-shared-drift.test.ts, test/ledger-engine-contract.test.ts.
Where it sits
server may import shared, engine, payments and voice (ALLOWED.server in .dependency-cruiser.cjs) and is imported by nothing; the browser reaches it over HTTP and WebSocket. It declares pg and ws as its own runtime dependencies. npm run check:trace -w @gavel/server runs in CI beside the engine's check.
- packages/server/src/boot/compose.tswiring of all packages
- packages/server/src/config.tsevery environment variable the server reads
- packages/server/src/room/room.tsone live auction
- packages/server/src/room/confirm.tsthe confirm gate
- packages/server/src/runtime/auction-service.tssettlement host
- packages/server/src/store/postgres.tsPostgres store and migrations
- render.yamlthe Render blueprint
Last updated on