Engine
Architecture
GozWire is a messaging engine. PostgreSQL is the durable source of truth. Realtime, storage, moderation, and push are adapters.
GozWire is a messaging engine: primitives for conversations, messages, receipts, attachments, expiration, retention, realtime fanout, configurable moderation, and optional durable push. Developers can build WhatsApp-like, Discord-like, or Stream Chat-like products on top of it. The engine is not those products.
PostgreSQL is the only durable source of truth. Redis, Centrifugo, object storage, the moderation sidecar, and push providers (Web Push, FCM, APNs) are infrastructure. A persisted message must survive realtime, Redis, sidecar, and provider failure.
The package boundary
@gozwire/core is the messaging engine. The Express demo host, the Svelte playground, and the Python moderation sidecar are repository applications. The engine does not import Express, Svelte, or Python.
Domain model
Durable PostgreSQL entities include:
- identities : referenced users, not a full account system
- conversations :
direct,group,channel, orforum - conversation_participants : membership plus role (
owner/admin/moderator/member) - messages : public UUIDv7 id,
clientMessageId, type, body, reply,threadRootId, timestamps, expiration, moderation status, per-conversation sequence - message_attachments : object keys and sanitized filenames, not bytes
- message_reactions : idempotent
(message, user, reaction)rows - message_receipts : delivered and read timestamps
- message_outbox : at-least-once realtime publication work
- push_installations / push_intents / push_jobs : device registry and per-installation push work, independent of the outbox
- moderation_jobs / results / events : lifecycle, raw signals, audit
- upload_sessions : authorized object-storage uploads
Adapters
| Port | Default |
|---|---|
| Realtime | Centrifugo HTTP API |
| Object storage | S3-compatible SDK (MinIO locally, R2 or S3 in production) |
| Image processor | Sharp (profile pictures) |
| Moderation | HTTP sidecar |
| Metrics | In-memory sink |
| Push | Web Push, FCM HTTP v1, APNs HTTP/2 behind a composite adapter, or a no-op when push.enabled is false |
The engine owns authorization against participant records, idempotency, persistence, outbox, push intents (when enabled), and workers.
Command path
- Validate payload (type, size, MIME, membership).
- Authorize the sender as an active participant.
- Enforce rate limits.
- Resolve idempotency (
clientMessageId). - In one PostgreSQL transaction: insert the message, insert outbox row(s), and when
push.enabledinsert one push intent per recipient for a visiblemessage.created. - Commit, then return the persisted message.
- Outbox and push workers publish and call providers independently. Duplicate delivery is harmless because events carry stable IDs.
Audio and video skip the moderation pipeline. Text and images enter it when enabled. BLOCK prevents fanout and keeps audit rows.