# zaneham/callout architecture

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

- Interactive diagram: https://gitdiagram.com/zaneham/callout
- Repository: https://github.com/zaneham/callout

## Overview

Callout is a self-hosted, offline-capable computer-aided dispatch system. Dispatchers and field personnel use role-specific client views to manage incidents and units; server requests cross a C/OCaml bridge into the dispatch logic, while event history is persisted for replay and clients synchronize over WebSockets. The graph preserves incident, authority/sync, mapping, and administration capabilities documented by the README and tree. Several client and domain implementations were not sampled, so their detailed call wiring is intentionally limited.

Main entry points: [`src/client/app.ml`](https://github.com/zaneham/callout/blob/master/src/client/app.ml) (Client app), [`src/engine/engine.ml`](https://github.com/zaneham/callout/blob/master/src/engine/engine.ml) (Dispatch engine), [`src/server/main.c`](https://github.com/zaneham/callout/blob/master/src/server/main.c) (Server event loop), [`src/server/http.c`](https://github.com/zaneham/callout/blob/master/src/server/http.c) (HTTP API)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Dispatch client"]
  node_app["Client app<br/>[app.ml]"]
  node_login["Login view<br/>[login_view.ml]"]
  node_incident_view["Incident view<br/>[incident_view.ml]"]
  node_dispatch_view["Dispatch view<br/>[dispatch_view.ml]"]
  node_map_view["Map view<br/>[map_view.ml]"]
  node_admin_view["Admin view<br/>[admin_view.ml]"]
  node_sop_view["SOP view<br/>[sop_view.ml]"]
  node_offline["Offline queue<br/>[offline.ml]"]
end

subgraph group_server["Server and persistence"]
  node_server_main["Server event loop<br/>[main.c]"]
  node_http["HTTP API<br/>[http.c]"]
  node_websocket["WebSocket transport<br/>[ws.c]"]
  node_bridge_c["C–OCaml bridge<br/>[bridge.c]"]
  node_database[("SQLite event store<br/>[db.c]")]
  node_schema["Database schema<br/>[schema.sql]"]
end

subgraph group_domain["Dispatch domain"]
  node_bridge_ffi["OCaml callbacks<br/>[bridge_ffi.ml]"]
  node_engine["Dispatch engine<br/>[engine.ml]"]
  node_incident["Incident lifecycle<br/>[incident.ml]"]
  node_dispatch["Dispatch and assignment<br/>[dispatch.ml]"]
  node_unit["Unit state<br/>[unit.ml]"]
  node_authority["Authentication and rank<br/>[auth.ml]"]
  node_sync["Authority-ranked sync<br/>[sync.ml]"]
  node_geo["Geospatial logic<br/>[geo.ml]"]
end

subgraph group_shared["Shared formats"]
  node_codec["JSON codec<br/>[codec.ml]"]
  node_protocol["Client/server protocol<br/>[protocol.ml]"]
  node_types["Shared types<br/>[types.ml]"]
end

node_personnel(("Dispatch personnel"))

node_personnel -->|"uses"| node_app
node_app -->|"shows"| node_login
node_app -->|"shows"| node_incident_view
node_app -->|"shows"| node_dispatch_view
node_app -->|"shows"| node_map_view
node_app -->|"shows"| node_admin_view
node_app -->|"shows"| node_sop_view
node_app -->|"uses offline queue"| node_offline
node_app -->|"sends HTTP requests"| node_http
node_app -->|"syncs events"| node_websocket
node_server_main -->|"opens and replays"| node_database
node_server_main -->|"initializes and loads events"| node_bridge_c
node_server_main -->|"initializes"| node_http
node_server_main -->|"initializes"| node_websocket
node_http -->|"reads and writes"| node_database
node_http -.->|"dispatch callbacks"| node_bridge_c
node_websocket -->|"forwards messages"| node_bridge_c
node_bridge_c -->|"invokes callbacks"| node_bridge_ffi
node_bridge_ffi -->|"handles dispatch commands"| node_engine
node_engine -->|"evaluates transitions"| node_incident
node_engine -->|"evaluates assignments"| node_dispatch
node_engine -->|"uses unit state"| node_unit
node_engine -->|"checks authority"| node_authority
node_engine -->|"applies event priority"| node_sync
node_engine -->|"uses location logic"| node_geo
node_bridge_ffi -->|"encodes and decodes"| node_codec
node_schema -->|"defines tables"| node_database
node_app -->|"uses message format"| node_protocol
node_websocket -->|"exchanges messages"| node_protocol
node_engine -->|"uses domain types"| node_types

click node_app "https://github.com/zaneham/callout/blob/master/src/client/app.ml"
click node_login "https://github.com/zaneham/callout/blob/master/src/client/login_view.ml"
click node_incident_view "https://github.com/zaneham/callout/blob/master/src/client/incident_view.ml"
click node_dispatch_view "https://github.com/zaneham/callout/blob/master/src/client/dispatch_view.ml"
click node_map_view "https://github.com/zaneham/callout/blob/master/src/client/map_view.ml"
click node_admin_view "https://github.com/zaneham/callout/blob/master/src/client/admin_view.ml"
click node_sop_view "https://github.com/zaneham/callout/blob/master/src/client/sop_view.ml"
click node_offline "https://github.com/zaneham/callout/blob/master/src/client/offline.ml"
click node_server_main "https://github.com/zaneham/callout/blob/master/src/server/main.c"
click node_http "https://github.com/zaneham/callout/blob/master/src/server/http.c"
click node_websocket "https://github.com/zaneham/callout/blob/master/src/server/ws.c"
click node_bridge_c "https://github.com/zaneham/callout/blob/master/src/server/bridge.c"
click node_bridge_ffi "https://github.com/zaneham/callout/blob/master/src/bridge_ffi/bridge_ffi.ml"
click node_database "https://github.com/zaneham/callout/blob/master/src/server/db.c"
click node_schema "https://github.com/zaneham/callout/blob/master/db/schema.sql"
click node_engine "https://github.com/zaneham/callout/blob/master/src/engine/engine.ml"
click node_incident "https://github.com/zaneham/callout/blob/master/src/core/incident.ml"
click node_dispatch "https://github.com/zaneham/callout/blob/master/src/core/dispatch.ml"
click node_unit "https://github.com/zaneham/callout/blob/master/src/core/unit.ml"
click node_authority "https://github.com/zaneham/callout/blob/master/src/core/auth.ml"
click node_sync "https://github.com/zaneham/callout/blob/master/src/core/sync.ml"
click node_geo "https://github.com/zaneham/callout/blob/master/src/core/geo.ml"
click node_codec "https://github.com/zaneham/callout/blob/master/src/codec/codec.ml"
click node_protocol "https://github.com/zaneham/callout/blob/master/src/shared/protocol.ml"
click node_types "https://github.com/zaneham/callout/blob/master/src/shared/types.ml"

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_app,node_login,node_incident_view,node_dispatch_view,node_map_view,node_admin_view,node_sop_view,node_offline toneBlue
class node_server_main,node_http,node_websocket,node_bridge_c,node_database,node_schema toneAmber
class node_bridge_ffi,node_engine,node_incident,node_dispatch,node_unit,node_authority,node_sync,node_geo toneMint
class node_codec,node_protocol,node_types toneRose
class node_personnel toneIndigo
```

## Components

### Dispatch client

- [Client app](https://github.com/zaneham/callout/blob/master/src/client/app.ml): `src/client/app.ml`
- [Login view](https://github.com/zaneham/callout/blob/master/src/client/login_view.ml): `src/client/login_view.ml`
- [Incident view](https://github.com/zaneham/callout/blob/master/src/client/incident_view.ml): `src/client/incident_view.ml`
- [Dispatch view](https://github.com/zaneham/callout/blob/master/src/client/dispatch_view.ml): `src/client/dispatch_view.ml`
- [Map view](https://github.com/zaneham/callout/blob/master/src/client/map_view.ml): `src/client/map_view.ml`
- [Admin view](https://github.com/zaneham/callout/blob/master/src/client/admin_view.ml): `src/client/admin_view.ml`
- [SOP view](https://github.com/zaneham/callout/blob/master/src/client/sop_view.ml): `src/client/sop_view.ml`
- [Offline queue](https://github.com/zaneham/callout/blob/master/src/client/offline.ml): `src/client/offline.ml`

### Server and persistence

- [Server event loop](https://github.com/zaneham/callout/blob/master/src/server/main.c): `src/server/main.c`
- [HTTP API](https://github.com/zaneham/callout/blob/master/src/server/http.c): `src/server/http.c`
- [WebSocket transport](https://github.com/zaneham/callout/blob/master/src/server/ws.c): `src/server/ws.c`
- [C–OCaml bridge](https://github.com/zaneham/callout/blob/master/src/server/bridge.c): `src/server/bridge.c`
- [SQLite event store](https://github.com/zaneham/callout/blob/master/src/server/db.c): `src/server/db.c`
- [Database schema](https://github.com/zaneham/callout/blob/master/db/schema.sql): `db/schema.sql`

### Dispatch domain

- [OCaml callbacks](https://github.com/zaneham/callout/blob/master/src/bridge_ffi/bridge_ffi.ml): `src/bridge_ffi/bridge_ffi.ml`
- [Dispatch engine](https://github.com/zaneham/callout/blob/master/src/engine/engine.ml): `src/engine/engine.ml`
- [Incident lifecycle](https://github.com/zaneham/callout/blob/master/src/core/incident.ml): `src/core/incident.ml`
- [Dispatch and assignment](https://github.com/zaneham/callout/blob/master/src/core/dispatch.ml): `src/core/dispatch.ml`
- [Unit state](https://github.com/zaneham/callout/blob/master/src/core/unit.ml): `src/core/unit.ml`
- [Authentication and rank](https://github.com/zaneham/callout/blob/master/src/core/auth.ml): `src/core/auth.ml`
- [Authority-ranked sync](https://github.com/zaneham/callout/blob/master/src/core/sync.ml): `src/core/sync.ml`
- [Geospatial logic](https://github.com/zaneham/callout/blob/master/src/core/geo.ml): `src/core/geo.ml`

### Shared formats

- [JSON codec](https://github.com/zaneham/callout/blob/master/src/codec/codec.ml): `src/codec/codec.ml`
- [Client/server protocol](https://github.com/zaneham/callout/blob/master/src/shared/protocol.ml): `src/shared/protocol.ml`
- [Shared types](https://github.com/zaneham/callout/blob/master/src/shared/types.ml): `src/shared/types.ml`

### Other components

- **Dispatch personnel**

## Connections

- Dispatch personnel → Client app: uses
- Client app → Login view: shows
- Client app → Incident view: shows
- Client app → Dispatch view: shows
- Client app → Map view: shows
- Client app → Admin view: shows
- Client app → SOP view: shows
- Client app → Offline queue: uses offline queue
- Client app → HTTP API: sends HTTP requests
- Client app → WebSocket transport: syncs events
- Server event loop → SQLite event store: opens and replays
- Server event loop → C–OCaml bridge: initializes and loads events
- Server event loop → HTTP API: initializes
- Server event loop → WebSocket transport: initializes
- HTTP API → SQLite event store: reads and writes
- HTTP API → C–OCaml bridge: dispatch callbacks
- WebSocket transport → C–OCaml bridge: forwards messages
- C–OCaml bridge → OCaml callbacks: invokes callbacks
- OCaml callbacks → Dispatch engine: handles dispatch commands
- Dispatch engine → Incident lifecycle: evaluates transitions
- Dispatch engine → Dispatch and assignment: evaluates assignments
- Dispatch engine → Unit state: uses unit state
- Dispatch engine → Authentication and rank: checks authority
- Dispatch engine → Authority-ranked sync: applies event priority
- Dispatch engine → Geospatial logic: uses location logic
- OCaml callbacks → JSON codec: encodes and decodes
- Database schema → SQLite event store: defines tables
- Client app → Client/server protocol: uses message format
- WebSocket transport → Client/server protocol: exchanges messages
- Dispatch engine → Shared types: uses domain types
