# Service communication

This page describes how Crown services and frontends talk to one another, with a deliberate focus on **HTTP vs WebSocket** traffic.

## Full communication map

![HTTP vs WebSocket communication map](../diagrams/generated/service-communication.svg)

Source: [`service-communication.mmd`](../diagrams/generated/service-communication.mmd)

## Frontend-to-backend map

![Frontend to backend map](../diagrams/generated/frontend-backend-map.svg)

Source: [`frontend-backend-map.mmd`](../diagrams/generated/frontend-backend-map.mmd)

## Authentication flow

![Authentication flow](../diagrams/generated/auth-flow.svg)

Source: [`auth-flow.mmd`](../diagrams/generated/auth-flow.mmd)

The auth flow artifacts are generated from the live auth app so they track Better Auth changes automatically:

- `apps/auth/package.json`
- `apps/auth/src/lib/auth.ts`
- `apps/auth/src/index.ts`

Generated runtime summary: [`generated/auth-runtime.md`](./generated/auth-runtime.md)

## Protocol summary

| Area      | HTTP                                                               | WebSocket                                     |
| --------- | ------------------------------------------------------------------ | --------------------------------------------- |
| Auth      | Login, session, token, JWKS, account actions                       | Not a primary runtime path                    |
| Forms     | CRUD, exports, stats endpoints                                     | Live entry updates, locks, live stats         |
| Person    | CRUD, search, stats                                                | Live person updates and stats streams         |
| Analytics | Reports, queries, dashboard data                                   | Live dashboard / live query updates           |
| CMS       | Content CRUD and merged views                                      | Live nav link and announcement updates        |
| Support   | Ticket CRUD, unread counts, notifications                          | Live ticket and notification streams          |
| Frontends | Typed Hono clients, better-auth client, plain `fetch` where needed | Browser `WebSocket` subscriptions for live UX |

## Common communication patterns

### Frontend → backend HTTP

Most UI apps use one or more of these patterns:

- `hc<...>()` typed Hono clients
- `createAuthClient(...)` for auth flows
- `fetch(...)` for direct calls where a typed client is not used

This is the standard path for:

- auth and session operations
- list/detail views
- form submission
- exports
- analytics queries
- content management
- support ticket actions

### Frontend → backend WebSocket

WebSockets are used where the UI needs to stay in sync without refreshes:

- live form entry changes and locks
- live audit / stats dashboards
- CMS announcement and navigation streams
- support notifications and ticket activity
- analytics live updates

A common pattern in the codebase is:

- start with a service HTTP URL
- transform it with `.replace(/^http/, 'ws')`
- append a token query parameter where required
- maintain a ping/pong timer for long-lived connections

### Service → service HTTP

Server-to-server communication is narrower and mostly configuration-driven:

- multiple services depend on `auth-service` for auth metadata and validation context
- services read shared data from SurrealDB using internal network addresses

## Current notable frontend connections

### `audits`

Uses both HTTP and WebSocket flows with several services:

- `records-service`
- `entity-service`
- `analytics-service`
- `cms-service`
- `support-service`
- `user-activity-service`
- `auth-service`

### `admin-ui`

Uses HTTP for admin and operational actions, plus WebSockets for live content and support updates:

- `auth-service`
- `audit-service`
- `records-service`
- `cms-service`
- `support-service`

### `application-list`

Mixes typed HTTP clients with live support connections:

- `auth-service`
- `records-service`
- `audit-service`
- `entity-service`
- `support-service`

### `analytics-ui`

Uses:

- HTTP for analytics queries and dashboards
- WebSocket for live updates from `analytics-service`
- HTTP auth flows through `auth-service`

## How the auth model fits in

A typical request path is:

1. the UI logs in against `auth-service`
2. the UI receives a session / token via better-auth
3. the UI sends that token to another backend service via HTTP or WebSocket query params
4. the backend validates issuer/JWKS details from the auth domain configuration
5. the backend executes the request against SurrealDB or its own service logic

## Maintenance note

The generated communication diagrams are derived from:

- source code usage of `hc<>`, `createAuthClient`, and `new WebSocket(...)`
- Docker Compose environment and service wiring

If you add a new service URL or a new live subscription path, regenerate the docs so the map stays current:

- from `apps/docs-site/`, run `bun run generate`
