> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kair.is/llms.txt
> Use this file to discover all available pages before exploring further.

# Architecture

> How the pieces connect — services, data flows, and deployment topology.

## Services

```
┌─────────────────────────────────────────────────────────┐
│                        Traefik                          │
│              (reverse proxy / TLS termination)          │
└──────────────┬──────────────────────────┬───────────────┘
               │                          │
       ┌───────▼────────┐        ┌────────▼────────┐
       │   Web App      │        │      API         │
       │  (SvelteKit)   │        │   (Rust/Poem)    │
       │  kair.is       │        │  kair.is/api/... │
       └────────────────┘        └──────┬───────────┘
                                        │
                   ┌────────────────────┼────────────────────┐
                   │                    │                     │
          ┌────────▼──────┐   ┌─────────▼──────┐   ┌────────▼──────┐
          │  PostgreSQL   │   │     Redis       │   │      S3       │
          │  (main DB)    │   │  (jobs + pubsub)│   │  (audio files)│
          └───────────────┘   └────────┬────────┘   └───────────────┘
                                       │
              ┌────────────────────────┼────────────────┐
              │                        │                │
     ┌────────▼──────┐      ┌──────────▼──────┐  ┌────▼──────────────┐
     │ Transcription │      │  Summarisation   │  │   HiRAG Worker    │
     │    Worker     │      │    Worker        │  │  (knowledge graph)│
     └───────────────┘      └─────────────────┘  └────────┬──────────┘
                                                           │
                                                  ┌────────▼──────┐
                                                  │    Neo4j      │
                                                  │ (graph store) │
                                                  └───────────────┘
```

## Codebase layout

The backend is a Rust Cargo workspace under `api/`:

| Crate             | Purpose                                                                                  |
| ----------------- | ---------------------------------------------------------------------------------------- |
| `api`             | HTTP routes, auth, WebSocket, OpenAPI spec                                               |
| `core`            | Database entities (SeaORM), migrations, shared types                                     |
| `transcription`   | Whisper.cpp (local) and Foresight (remote) transcription clients                         |
| `summarisation`   | LLM-based session summary generation                                                     |
| `hirag`           | Knowledge graph — indexing, retrieval, agent orchestration                               |
| `hirag-worker`    | Knowledge-graph indexing worker binary (drains `hirag_indexing_queue`)                   |
| `document-worker` | Document extraction, chunking, summarisation and hand-off to HiRAG indexing              |
| `moderator-agent` | Live discourse analysis (divergence, convergence, intensity) for the moderator dashboard |
| `telemetry`       | OpenTelemetry tracing setup (OTLP export)                                                |
| `cli`             | Deployment CLI (`kair-cli deploy`, `kair-cli deploy-frontend`)                           |

The frontend is a SvelteKit app under `ui/web/`.

## Authentication model

Two token types are in use:

| Token              | Used by                  | How it's passed                        |
| ------------------ | ------------------------ | -------------------------------------- |
| JWT (user session) | Web app users            | `Authorization: Bearer <token>` header |
| Device API key     | Hardware devices (ESP32) | `X-API-Key: <key>` header              |

Guest users get short-lived JWT tokens scoped to a single session.

## WebSocket

Real-time updates (transcription progress, recording status, live transcript lines) flow via a single WebSocket connection established when the moderator opens a session. The API subscribes to Redis pub/sub channels and forwards events to connected clients. This replaces the polling approach that was previously used for recording status.

## Observability

The API and workers export OpenTelemetry traces over OTLP (HTTP/protobuf) to whatever collector is configured in `config.yml` (`app.otel_exporter_otlp_endpoint`). In production this points to Grafana Alloy. Traces cover HTTP requests, database queries, and worker job processing.
