Architecture

How SAFER’s components fit together at a high level.

System overview

┌─────────────────────────────────────────────┐
│                  Web Client                 │
│           (map view, dispatch UI)           │
└────────────────────┬────────────────────────┘
                     │ REST / WebSocket
┌────────────────────▼────────────────────────┐
│                  API Server                 │
│         (authentication, routing)           │
└───────────┬─────────────────────────────────┘
            │
┌───────────▼──────────┐   ┌──────────────────┐
│       Database       │   │  Message Broker  │
│   (persistent data)  │   │  (live updates)  │
└──────────────────────┘   └──────────────────┘

Components

Web Client

A single-page application served as static files. Communicates with the API server over REST for CRUD operations and over WebSocket for live updates.

API Server

Handles authentication (JWT), input validation, business logic, and database access. Publishes state changes to the message broker for fan-out to connected WebSocket clients.

Database

Stores all persistent state: users, units, incidents, and audit logs.

Message Broker

Decouples the API server from WebSocket fan-out. When an incident is updated, the API server publishes one message; the broker delivers it to every connected client subscribed to that incident’s channel.

Key design decisions

  • Stateless API server — any request can be handled by any server instance, enabling horizontal scaling.
  • JWT authentication — tokens are verified locally without a round-trip to a session store.
  • WebSocket fan-out via broker — keeps the API server lean and makes it easy to add new consumers (e.g. a mobile push notification service) without changing the core API.