# voidjack233/void-chats architecture

> Architecture diagram of the GitHub repository voidjack233/void-chats, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-14). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/voidjack233/void-chats
- Repository: https://github.com/voidjack233/void-chats

## Overview

1. The repo is a split chat system, not a single app. The main runtime pieces are:
   - `VOID0000-www`: React + TypeScript + Vite frontend
   - `VOID0000-api`: Node/Express backend split into multiple service entrypoints
   - `VOID0000-api/void_gateway`: Phoenix/Elixir realtime gateway
   - `VOIDADMIN`: a small separate admin panel
   Root `server.js` and root `package.json` are legacy remnants and not part of the normal path.

2. The frontend is the user-facing shell. It owns routing, UI state, and most client-side orchestration for auth, chat, friends, profile, settings, notifications, and encrypted media flows. The main architectural boundary is that the frontend talks to the API over HTTP and to the gateway for realtime presence/chat fanout.

3. The frontend is also where the crypto-heavy client logic lives. `VOID0000-www/src/Services/Crypto` and `.../Chat` handle message encryption/decryption, MLS group state, key management, attachment encryption, queued sends, conversation caches, and sync. A vendored `ts-mls` copy is included under `VOID0000-www/vendor/ts-mls`, so MLS behavior is intentionally pinned.

4. The backend is split by responsibility rather than a single monolith. The entrypoints in `VOID0000-api/server/entrypoints` separate account, conversation, message, social, and worker processes. That means the architecture has distinct process boundaries for HTTP APIs, background work, and any shared infrastructure they all depend on.

5. Authentication and account management are centralized in the Node API. The `server/routes/auth` and `server/routes/user` areas cover registration, login, refresh, logout, password changes, email verification, 2FA, session management, profile reads/updates, and account preferences. Supporting middleware handles JWTs, encrypted CSRF, session storage, captcha checks, email delivery, and rate limiting.

6. Chat data is split across storage systems. PostgreSQL migrations define the core application schema: users, conversations, membership, reactions, invites, MLS metadata, push subscriptions, and recovery/backups. ScyllaDB migrations under `db/scylla-migrations` store message-oriented data and message metadata, which is a clear separation between relational control data and high-volume message storage.

7. Realtime behavior is handled by the Phoenix gateway, not by Express. The gateway’s job is presence, socket auth, connection tracking, session buffering, event dispatch, and fanout. The Node side includes `server/gateway` and `valkey-pubsub` integration, which suggests Node publishes events into shared infrastructure and Phoenix distributes them to connected clients.

8. Valkey/Redis is the coordination layer between services. It appears in rate limiting, pub/sub, session-related state, and gateway coordination. This is a key architecture boundary: stateless HTTP services rely on shared in-memory infrastructure for throttling, presence/event propagation, and short-lived coordination.

9. Media and file handling are separated from message transport. MinIO is used for object storage, and the backend includes private attachment routes plus MinIO integration. The frontend also has encrypted attachment flows, while server-side image processing via `sharp` is used for non-encrypted assets like avatars. The repo notes that profile/group pictures are public-read, while chat attachment blobs are private and fetched through authenticated API paths.

10. Background processing exists for non-interactive work. `server/queues/imageQueue.js` and the `worker-server` entrypoint indicate asynchronous jobs, likely for image processing, cleanup, or other deferred tasks. This keeps heavier work off the request path.

11. Notifications are a separate subsystem. The backend has `server/notifications/webPush.js` and push-subscription migrations, while the frontend includes a service worker (`public/push-sw.js`) and notification prompting UI. So push notifications are end-to-end: subscription storage in the API, delivery from backend, and browser handling in the client.

12. Messaging features are layered on top of a larger conversation model. The conversation routes cover groups, DMs, member roles, invites, permissions, reactions, read state, typing, attachments, and MLS-specific endpoints like key packages, commits, welcomes, group states, sync, and recovery artifacts. This is the core product domain and is split into normal chat operations plus MLS lifecycle management.

13. Presence and friend discovery are separate from chat rooms. The `friends` routes and corresponding frontend hooks/components handle requests, lists, pending states, and presence. This is useful for diagramming because “social graph/presence” is not embedded inside conversation handling; it is its own API slice.

14. The deployment model assumes internal services behind a public front door. The README and docs indicate Nginx and Cloudflared are used as the public edge, while backend, gateway, and storage services are meant to stay loopback-only. So the architecture is “edge proxy/tunnel in front, private internal services behind.”

15. The admin app is a standalone internal tool. `VOIDADMIN` is a separate Express app with its own public assets and server, likely used for user/security oversight rather than normal end-user chat flow. It should be diagrammed as an auxiliary operational surface, not part of the main client path.

16. In diagram terms, the most important flows are:
   - Browser UI → Express API for auth, profiles, conversations, media, and history
   - Browser UI → Phoenix gateway for realtime presence/chat updates
   - Express services ↔ PostgreSQL for control data
   - Express services ↔ ScyllaDB for message storage
   - Express services ↔ MinIO for attachments/media
   - Express services ↔ Valkey for coordination, rate limits, and pub/sub
   - Frontend crypto layer handles encryption/decryption before payloads cross those boundaries

Main entry points: [`VOID0000-api/server/routes`](https://github.com/voidjack233/void-chats/tree/main/VOID0000-api/server/routes) (HTTP routes), [`VOID0000-www/src`](https://github.com/voidjack233/void-chats/tree/main/VOID0000-www/src) (Frontend shell), [`VOID0000-api/void_gateway/lib/void_gateway`](https://github.com/voidjack233/void-chats/tree/main/VOID0000-api/void_gateway/lib/void_gateway) (Realtime gateway), [`docs/nginx-frontend-only.example.conf`](https://github.com/voidjack233/void-chats/blob/main/docs/nginx-frontend-only.example.conf) (Public edge)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Client surfaces"]
  node_www_shell["Frontend shell<br/>React/Vite app"]
  node_www_crypto{{"Crypto layer<br/>Client crypto"}}
  node_www_chat["Chat services<br/>Client chat"]
  node_www_auth["Auth services<br/>Client auth"]
  node_www_gateway["Gateway client<br/>Realtime client<br/>[gateway.ts]"]
  node_www_push["Push client<br/>Notifications"]
  node_www_chat_ui["Chat UI<br/>React views"]
  node_www_friends_ui["Friends UI<br/>React views"]
  node_www_settings_ui["Settings UI<br/>React views"]
end

subgraph group_api["Node services"]
  node_api_account["Account API<br/>Express entrypoint<br/>[account-server.js]"]
  node_api_conversation["Conversation API<br/>Express entrypoint"]
  node_api_message["Message API<br/>Express entrypoint<br/>[message-server.js]"]
  node_api_social["Social API<br/>Express entrypoint<br/>[social-server.js]"]
  node_api_worker["Worker process<br/>Background jobs<br/>[worker-server.js]"]
  node_api_gateway["Gateway bridge<br/>Pubsub bridge"]
  node_api_middleware["Shared middleware<br/>HTTP controls"]
  node_api_notifications["Notification service<br/>Web push<br/>[webPush.js]"]
  node_api_minio[("Object storage<br/>MinIO integration<br/>[minio.js]")]
  node_api_routes["HTTP routes<br/>Express routes"]
end

subgraph group_gateway["Realtime gateway"]
  node_gateway_phoenix["Realtime gateway<br/>Phoenix app"]
  node_gateway_web["Socket endpoint<br/>Phoenix web"]
end

subgraph group_data["Data stores"]
  node_postgres[("PostgreSQL<br/>Relational store")]
  node_scylla[("ScyllaDB<br/>Message store")]
  node_valkey[("Valkey<br/>Coordination cache<br/>[valkey.js]")]
end

subgraph group_ops["Ops edge"]
  node_admin_app["Admin panel<br/>Express app<br/>[server.js]"]
  node_edge["Public edge<br/>Nginx/Cloudflared"]
end

node_www_shell -->|"auth flows"| node_www_auth
node_www_shell -->|"chat state"| node_www_chat
node_www_shell -->|"realtime"| node_www_gateway
node_www_shell -->|"push UI"| node_www_push
node_www_chat -->|"encrypts"| node_www_crypto
node_www_chat_ui -->|"renders"| node_www_chat
node_www_friends_ui -->|"social data"| node_api_social
node_www_settings_ui -->|"account data"| node_api_account
node_www_auth -->|"HTTP"| node_api_account
node_www_chat -->|"HTTP"| node_api_routes
node_www_gateway -->|"socket"| node_gateway_phoenix
node_api_routes -->|"protects"| node_api_middleware
node_api_routes -->|"control data"| node_postgres
node_api_routes -->|"messages"| node_scylla
node_api_routes -->|"attachments"| node_api_minio
node_api_routes -->|"coordination"| node_valkey
node_api_routes -->|"push"| node_api_notifications
node_api_gateway -->|"pubsub"| node_valkey
node_api_gateway -->|"bridge"| node_gateway_phoenix
node_gateway_phoenix -->|"serves"| node_gateway_web
node_gateway_phoenix -->|"state"| node_valkey
node_gateway_phoenix -->|"auth state"| node_postgres
node_api_worker -->|"jobs"| node_postgres
node_api_worker -->|"jobs"| node_scylla
node_api_notifications -->|"delivery coord"| node_valkey
node_admin_app -->|"admin data"| node_postgres
node_edge -->|"public web"| node_www_shell
node_edge -->|"api ingress"| node_api_routes
node_edge -->|"socket ingress"| node_gateway_web
node_edge -->|"admin ingress"| node_admin_app

click node_www_shell "https://github.com/voidjack233/void-chats/tree/main/VOID0000-www/src"
click node_www_crypto "https://github.com/voidjack233/void-chats/tree/main/VOID0000-www/src/Services/Crypto"
click node_www_chat "https://github.com/voidjack233/void-chats/tree/main/VOID0000-www/src/Services/Chat"
click node_www_auth "https://github.com/voidjack233/void-chats/tree/main/VOID0000-www/src/Services/Auth"
click node_www_gateway "https://github.com/voidjack233/void-chats/blob/main/VOID0000-www/src/Services/Gateway/gateway.ts"
click node_www_push "https://github.com/voidjack233/void-chats/blob/main/VOID0000-www/src/Services/Notifications/pushNotificationService.ts"
click node_www_chat_ui "https://github.com/voidjack233/void-chats/tree/main/VOID0000-www/src/components/Chat"
click node_www_friends_ui "https://github.com/voidjack233/void-chats/tree/main/VOID0000-www/src/components/common/Friends"
click node_www_settings_ui "https://github.com/voidjack233/void-chats/tree/main/VOID0000-www/src/components/common/Settings"
click node_api_account "https://github.com/voidjack233/void-chats/blob/main/VOID0000-api/server/entrypoints/account-server.js"
click node_api_conversation "https://github.com/voidjack233/void-chats/blob/main/VOID0000-api/server/entrypoints/conversation-server.js"
click node_api_message "https://github.com/voidjack233/void-chats/blob/main/VOID0000-api/server/entrypoints/message-server.js"
click node_api_social "https://github.com/voidjack233/void-chats/blob/main/VOID0000-api/server/entrypoints/social-server.js"
click node_api_worker "https://github.com/voidjack233/void-chats/blob/main/VOID0000-api/server/entrypoints/worker-server.js"
click node_api_gateway "https://github.com/voidjack233/void-chats/tree/main/VOID0000-api/server/gateway"
click node_api_middleware "https://github.com/voidjack233/void-chats/tree/main/VOID0000-api/server/middleware"
click node_api_notifications "https://github.com/voidjack233/void-chats/blob/main/VOID0000-api/server/notifications/webPush.js"
click node_api_minio "https://github.com/voidjack233/void-chats/blob/main/VOID0000-api/server/minio.js"
click node_api_routes "https://github.com/voidjack233/void-chats/tree/main/VOID0000-api/server/routes"
click node_gateway_phoenix "https://github.com/voidjack233/void-chats/tree/main/VOID0000-api/void_gateway/lib/void_gateway"
click node_gateway_web "https://github.com/voidjack233/void-chats/tree/main/VOID0000-api/void_gateway/lib/void_gateway_web"
click node_postgres "https://github.com/voidjack233/void-chats/tree/main/VOID0000-api/db/migrations"
click node_scylla "https://github.com/voidjack233/void-chats/tree/main/VOID0000-api/db/scylla-migrations"
click node_valkey "https://github.com/voidjack233/void-chats/blob/main/VOID0000-api/server/valkey.js"
click node_admin_app "https://github.com/voidjack233/void-chats/blob/main/VOIDADMIN/server.js"
click node_edge "https://github.com/voidjack233/void-chats/blob/main/docs/nginx-frontend-only.example.conf"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_www_shell,node_www_crypto,node_www_chat,node_www_auth,node_www_gateway,node_www_push,node_www_chat_ui,node_www_friends_ui,node_www_settings_ui toneBlue
class node_api_account,node_api_conversation,node_api_message,node_api_social,node_api_worker,node_api_gateway,node_api_middleware,node_api_notifications,node_api_minio,node_api_routes toneAmber
class node_gateway_phoenix,node_gateway_web toneMint
class node_postgres,node_scylla,node_valkey toneRose
class node_admin_app,node_edge toneIndigo
```

## Components

### Client surfaces

Browser apps and the user-facing shell.

- [Frontend shell](https://github.com/voidjack233/void-chats/tree/main/VOID0000-www/src): React/Vite app · Main user-facing client that owns routing, UI state, and orchestration across auth, chat, friends, profile, settings, and notifications. · `VOID0000-www/src`
- [Crypto layer](https://github.com/voidjack233/void-chats/tree/main/VOID0000-www/src/Services/Crypto): Client crypto · Message, attachment, and MLS cryptography; includes encryption workers, key management, queued sends, and state sync. · `VOID0000-www/src/Services/Crypto`
- [Chat services](https://github.com/voidjack233/void-chats/tree/main/VOID0000-www/src/Services/Chat): Client chat · Conversation, message, cache, sync, reaction, typing, and attachment flow logic on the client side. · `VOID0000-www/src/Services/Chat`
- [Auth services](https://github.com/voidjack233/void-chats/tree/main/VOID0000-www/src/Services/Auth): Client auth · Login, registration, password reset, email verification, 2FA, session, and profile bootstrap flows. · `VOID0000-www/src/Services/Auth`
- [Gateway client](https://github.com/voidjack233/void-chats/blob/main/VOID0000-www/src/Services/Gateway/gateway.ts): Realtime client · Browser-side bridge for presence and socket-driven chat updates. · `VOID0000-www/src/Services/Gateway/gateway.ts`
- [Push client](https://github.com/voidjack233/void-chats/blob/main/VOID0000-www/src/Services/Notifications/pushNotificationService.ts): Notifications · Browser push subscription and service-worker handling for notifications. · `VOID0000-www/src/Services/Notifications/pushNotificationService.ts`
- [Chat UI](https://github.com/voidjack233/void-chats/tree/main/VOID0000-www/src/components/Chat): React views · Conversation list, message timeline, composer, attachments, reactions, and conversation settings UI. · `VOID0000-www/src/components/Chat`
- [Friends UI](https://github.com/voidjack233/void-chats/tree/main/VOID0000-www/src/components/common/Friends): React views · Friend requests, presence, and social-discovery screens. · `VOID0000-www/src/components/common/Friends`
- [Settings UI](https://github.com/voidjack233/void-chats/tree/main/VOID0000-www/src/components/common/Settings): React views · Account, appearance, notifications, 2FA, sessions, and profile settings surfaces. · `VOID0000-www/src/components/common/Settings`

### Node services

Express-based HTTP services, background work, and shared backend infrastructure.

- [Account API](https://github.com/voidjack233/void-chats/blob/main/VOID0000-api/server/entrypoints/account-server.js): Express entrypoint · HTTP process for registration, login, refresh, logout, password changes, verification, 2FA, session management, and user profile operations. · `VOID0000-api/server/entrypoints/account-server.js`
- [Conversation API](https://github.com/voidjack233/void-chats/blob/main/VOID0000-api/server/entrypoints/conversation-server.js): Express entrypoint · HTTP process for conversations, members, invites, permissions, reactions, read state, typing, attachments, and MLS lifecycle endpoints. · `VOID0000-api/server/entrypoints/conversation-server.js`
- [Message API](https://github.com/voidjack233/void-chats/blob/main/VOID0000-api/server/entrypoints/message-server.js): Express entrypoint · HTTP process for message creation, history, retrieval, read tracking, and send orchestration. · `VOID0000-api/server/entrypoints/message-server.js`
- [Social API](https://github.com/voidjack233/void-chats/blob/main/VOID0000-api/server/entrypoints/social-server.js): Express entrypoint · HTTP process for friends, presence discovery, and related social graph operations. · `VOID0000-api/server/entrypoints/social-server.js`
- [Worker process](https://github.com/voidjack233/void-chats/blob/main/VOID0000-api/server/entrypoints/worker-server.js): Background jobs · Async entrypoint for deferred work such as image processing and cleanup tasks. · `VOID0000-api/server/entrypoints/worker-server.js`
- [Gateway bridge](https://github.com/voidjack233/void-chats/tree/main/VOID0000-api/server/gateway): Pubsub bridge · Node-side integration that publishes events and coordinates with the realtime gateway. · `VOID0000-api/server/gateway`
- [Shared middleware](https://github.com/voidjack233/void-chats/tree/main/VOID0000-api/server/middleware): HTTP controls · JWT, encrypted CSRF, session storage, captcha, email delivery, cache, XSS protection, and rate limiting. · `VOID0000-api/server/middleware`
- [Notification service](https://github.com/voidjack233/void-chats/blob/main/VOID0000-api/server/notifications/webPush.js): Web push · Backend push notification delivery and subscription management. · `VOID0000-api/server/notifications/webPush.js`
- [Object storage](https://github.com/voidjack233/void-chats/blob/main/VOID0000-api/server/minio.js): MinIO integration · Private attachment and media storage integration on the backend. · `VOID0000-api/server/minio.js`
- [HTTP routes](https://github.com/voidjack233/void-chats/tree/main/VOID0000-api/server/routes): Express routes · Main API surface for auth, user, conversations, friends, notifications, CSRF, captcha, and link previews. · `VOID0000-api/server/routes`

### Realtime gateway

Phoenix/Elixir websocket and presence layer.

- [Realtime gateway](https://github.com/voidjack233/void-chats/tree/main/VOID0000-api/void_gateway/lib/void_gateway): Phoenix app · Elixir websocket gateway handling socket auth, presence, connection tracking, session buffering, event dispatch, and fanout. · `VOID0000-api/void_gateway/lib/void_gateway`
- [Socket endpoint](https://github.com/voidjack233/void-chats/tree/main/VOID0000-api/void_gateway/lib/void_gateway_web): Phoenix web · Websocket endpoint, router, plugs, and socket handler for client connections. · `VOID0000-api/void_gateway/lib/void_gateway_web`

### Data stores

Primary persistence and coordination systems.

- [PostgreSQL](https://github.com/voidjack233/void-chats/tree/main/VOID0000-api/db/migrations): Relational store · Core application schema for users, conversations, memberships, reactions, invites, MLS metadata, push subscriptions, and recovery data. · `VOID0000-api/db/migrations`
- [ScyllaDB](https://github.com/voidjack233/void-chats/tree/main/VOID0000-api/db/scylla-migrations): Message store · High-volume message storage and message metadata tables. · `VOID0000-api/db/scylla-migrations`
- [Valkey](https://github.com/voidjack233/void-chats/blob/main/VOID0000-api/server/valkey.js): Coordination cache · Shared coordination layer for rate limits, pub/sub, session state, and gateway signaling. · `VOID0000-api/server/valkey.js`

### Ops edge

Deployment, proxying, and auxiliary operational tooling.

- [Admin panel](https://github.com/voidjack233/void-chats/blob/main/VOIDADMIN/server.js): Express app · Standalone internal admin surface with its own server and public assets. · `VOIDADMIN/server.js`
- [Public edge](https://github.com/voidjack233/void-chats/blob/main/docs/nginx-frontend-only.example.conf): Nginx/Cloudflared · External front door in front of private loopback-only services. · `docs/nginx-frontend-only.example.conf`

## Connections

- Frontend shell → Auth services: auth flows · The shell delegates login, registration, reset, and verification flows to auth services.
- Frontend shell → Chat services: chat state · The shell uses chat services for conversation orchestration and local state.
- Frontend shell → Gateway client: realtime · The shell connects to the gateway client for presence and live updates.
- Frontend shell → Push client: push UI · The shell drives notification prompting and browser push setup.
- Chat services → Crypto layer: encrypts · Chat services rely on client crypto for message and attachment protection.
- Chat UI → Chat services: renders · Chat UI components consume the chat service layer.
- Friends UI → Social API: social data · Friends screens consume social and presence data from the API.
- Settings UI → Account API: account data · Settings screens consume account, session, and profile endpoints.
- Auth services → Account API: HTTP · Authentication and account management are handled by the Node API.
- Chat services → HTTP routes: HTTP · Chat services fetch and mutate conversations, messages, and related records over HTTP.
- Gateway client → Realtime gateway: socket · The browser client connects to the Phoenix gateway for realtime traffic.
- HTTP routes → Shared middleware: protects · Routes are wrapped by shared security, session, captcha, and rate-limit middleware.
- HTTP routes → PostgreSQL: control data · Express routes persist control-plane application data in PostgreSQL.
- HTTP routes → ScyllaDB: messages · Message-oriented endpoints read and write high-volume message data in ScyllaDB.
- HTTP routes → Object storage: attachments · Authenticated media and attachment flows use MinIO-backed object storage.
- HTTP routes → Valkey: coordination · HTTP services use Valkey for throttling, short-lived state, and coordination.
- HTTP routes → Notification service: push · Notification routes and services manage push delivery.
- Gateway bridge → Valkey: pubsub · Node backend publishes coordination events through Valkey into the realtime layer.
- Gateway bridge → Realtime gateway: bridge · The Node side bridges backend events into Phoenix fanout.
- Realtime gateway → Socket endpoint: serves · Phoenix exposes the websocket endpoint and upgrade path.
- Realtime gateway → Valkey: state · Presence and session coordination rely on shared in-memory infrastructure.
- Realtime gateway → PostgreSQL: auth state · Gateway auth and presence flows depend on persisted user/session data.
- Worker process → PostgreSQL: jobs · Background jobs operate on relational state such as cleanup and derived records.
- Worker process → ScyllaDB: jobs · Background jobs may process message storage tasks.
- Notification service → Valkey: delivery coord · Push delivery coordination uses the shared cache and pub/sub layer.
- Admin panel → PostgreSQL: admin data · The admin surface likely reads and acts on core application data.
- Public edge → Frontend shell: public web · The public edge fronts the main browser application.
- Public edge → HTTP routes: api ingress · The edge routes browser API traffic to private Node services.
- Public edge → Socket endpoint: socket ingress · The edge also fronts realtime websocket traffic to the Phoenix gateway.
- Public edge → Admin panel: admin ingress · The edge can expose the separate admin surface as an internal tool.
