# t0mer/cic architecture

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

- Interactive diagram: https://gitdiagram.com/t0mer/cic
- Repository: https://github.com/t0mer/cic

## Overview

CIC is a DRADIS phone-telemetry control plane: phones publish over MQTT, CIC maintains device state and history, and administrators inspect and manage devices through a browser UI or REST API. The principal flow runs from MQTT ingestion through the device registry and persistence to live UI updates; command requests travel from the UI through API validation, audit and command services back to MQTT. The README documents geocoding, safe places, authentication, history and settings capabilities. Some subsystem links rely on that documentation because their implementation files were not excerpted.

Main entry points: [`internal/api/api.go`](https://github.com/t0mer/cic/blob/main/internal/api/api.go) (REST and SSE API), [`web/src/App.tsx`](https://github.com/t0mer/cic/blob/main/web/src/App.tsx) (Routed web app), [`internal/devices/registry.go`](https://github.com/t0mer/cic/blob/main/internal/devices/registry.go) (Device registry), [`internal/store/store.go`](https://github.com/t0mer/cic/blob/main/internal/store/store.go) (SQLite store)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_runtime["Server runtime"]
  node_serve["HTTP server<br/>[serve.go]"]
  node_api["REST and SSE API<br/>[api.go]"]
  node_store[("SQLite store<br/>[store.go]")]
end

subgraph group_ingest["Telemetry and state"]
  node_mqtt["MQTT client<br/>[client.go]"]
  node_registry["Device registry<br/>[registry.go]"]
  node_events["Live event hub<br/>[hub.go]"]
end

subgraph group_domain["Device capabilities"]
  node_history["Location history<br/>[history.go]"]
  node_geocode["Reverse geocoding<br/>[worker.go]"]
  node_places["Safe places<br/>[places.go]"]
  node_commands["Device commands<br/>[service.go]"]
end

subgraph group_security["Identity and audit"]
  node_audit["Command audit<br/>[audit.go]"]
  node_auth["Users and MFA<br/>[store_totp.go]"]
end

subgraph group_client["Browser application"]
  node_app["Routed web app<br/>[App.tsx]"]
  node_authui["Browser authentication<br/>[auth-context.ts]"]
  node_deviceui["Device cards and map<br/>[DevicesPage.tsx]"]
  node_historyui["History routes<br/>[HistoryPage.tsx]"]
  node_settingsui["Settings screens<br/>[SettingsPage.tsx]"]
  node_commandui["Command actions<br/>[useCommand.ts]"]
  node_results["Command results<br/>[results.ts]"]
end

node_admin(("Administrator"))
node_phone(("DRADIS phone"))
node_broker["MQTT broker"]
node_browser(("Browser"))
node_latlng["LatLng API"]

node_admin -->|"uses"| node_browser
node_browser -->|"opens"| node_app
node_app -->|"provides auth"| node_authui
node_app -->|"routes devices"| node_deviceui
node_app -->|"routes history"| node_historyui
node_app -->|"routes settings"| node_settingsui
node_app -->|"hosts actions"| node_commandui
node_commandui -->|"registers IDs"| node_results
node_browser -->|"REST and SSE"| node_api
node_phone -->|"publishes telemetry"| node_broker
node_broker -->|"delivers telemetry"| node_mqtt
node_mqtt -->|"updates state"| node_registry
node_registry -->|"persists devices"| node_store
node_registry -.->|"notifies changes"| node_events
node_events -.->|"streams events"| node_api
node_api -.->|"serves history"| node_history
node_history -->|"stores routes"| node_store
node_registry -->|"queues locations"| node_geocode
node_geocode -.->|"resolves names"| node_latlng
node_geocode -->|"caches results"| node_store
node_api -.->|"manages places"| node_places
node_places -.->|"persists places"| node_store
node_api -->|"dispatches actions"| node_commands
node_commands -->|"checks device"| node_registry
node_commands -->|"publishes commands"| node_mqtt
node_api -->|"audits attempts"| node_audit
node_api -->|"authenticates users"| node_auth
node_auth -.->|"stores credentials"| node_store
node_serve -->|"mounts routes"| node_api
node_serve -->|"starts client"| node_mqtt

click node_serve "https://github.com/t0mer/cic/blob/main/cmd/cic/serve.go"
click node_api "https://github.com/t0mer/cic/blob/main/internal/api/api.go"
click node_store "https://github.com/t0mer/cic/blob/main/internal/store/store.go"
click node_mqtt "https://github.com/t0mer/cic/blob/main/internal/mqtt/client.go"
click node_registry "https://github.com/t0mer/cic/blob/main/internal/devices/registry.go"
click node_events "https://github.com/t0mer/cic/blob/main/internal/events/hub.go"
click node_history "https://github.com/t0mer/cic/blob/main/internal/history/history.go"
click node_geocode "https://github.com/t0mer/cic/blob/main/internal/geocode/worker.go"
click node_places "https://github.com/t0mer/cic/blob/main/internal/places/places.go"
click node_commands "https://github.com/t0mer/cic/blob/main/internal/commands/service.go"
click node_audit "https://github.com/t0mer/cic/blob/main/internal/audit/audit.go"
click node_auth "https://github.com/t0mer/cic/blob/main/internal/auth/store_totp.go"
click node_app "https://github.com/t0mer/cic/blob/main/web/src/App.tsx"
click node_authui "https://github.com/t0mer/cic/blob/main/web/src/features/auth/auth-context.ts"
click node_deviceui "https://github.com/t0mer/cic/blob/main/web/src/features/devices/DevicesPage.tsx"
click node_historyui "https://github.com/t0mer/cic/blob/main/web/src/features/history/HistoryPage.tsx"
click node_settingsui "https://github.com/t0mer/cic/blob/main/web/src/features/settings/SettingsPage.tsx"
click node_commandui "https://github.com/t0mer/cic/blob/main/web/src/features/commands/useCommand.ts"
click node_results "https://github.com/t0mer/cic/blob/main/web/src/features/commands/results.ts"

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_serve,node_api,node_store,node_browser toneBlue
class node_mqtt,node_registry,node_events toneAmber
class node_history,node_geocode,node_places,node_commands,node_latlng toneMint
class node_audit,node_auth toneRose
class node_app,node_authui,node_deviceui,node_historyui,node_settingsui,node_commandui,node_results,node_admin,node_phone,node_broker toneIndigo
```

## Components

### Server runtime

- [HTTP server](https://github.com/t0mer/cic/blob/main/cmd/cic/serve.go): `cmd/cic/serve.go`
- [REST and SSE API](https://github.com/t0mer/cic/blob/main/internal/api/api.go): `internal/api/api.go`
- [SQLite store](https://github.com/t0mer/cic/blob/main/internal/store/store.go): `internal/store/store.go`

### Telemetry and state

- [MQTT client](https://github.com/t0mer/cic/blob/main/internal/mqtt/client.go): `internal/mqtt/client.go`
- [Device registry](https://github.com/t0mer/cic/blob/main/internal/devices/registry.go): `internal/devices/registry.go`
- [Live event hub](https://github.com/t0mer/cic/blob/main/internal/events/hub.go): `internal/events/hub.go`

### Device capabilities

- [Location history](https://github.com/t0mer/cic/blob/main/internal/history/history.go): `internal/history/history.go`
- [Reverse geocoding](https://github.com/t0mer/cic/blob/main/internal/geocode/worker.go): `internal/geocode/worker.go`
- [Safe places](https://github.com/t0mer/cic/blob/main/internal/places/places.go): `internal/places/places.go`
- [Device commands](https://github.com/t0mer/cic/blob/main/internal/commands/service.go): `internal/commands/service.go`

### Identity and audit

- [Command audit](https://github.com/t0mer/cic/blob/main/internal/audit/audit.go): `internal/audit/audit.go`
- [Users and MFA](https://github.com/t0mer/cic/blob/main/internal/auth/store_totp.go): `internal/auth/store_totp.go`

### Browser application

- [Routed web app](https://github.com/t0mer/cic/blob/main/web/src/App.tsx): `web/src/App.tsx`
- [Browser authentication](https://github.com/t0mer/cic/blob/main/web/src/features/auth/auth-context.ts): `web/src/features/auth/auth-context.ts`
- [Device cards and map](https://github.com/t0mer/cic/blob/main/web/src/features/devices/DevicesPage.tsx): `web/src/features/devices/DevicesPage.tsx`
- [History routes](https://github.com/t0mer/cic/blob/main/web/src/features/history/HistoryPage.tsx): `web/src/features/history/HistoryPage.tsx`
- [Settings screens](https://github.com/t0mer/cic/blob/main/web/src/features/settings/SettingsPage.tsx): `web/src/features/settings/SettingsPage.tsx`
- [Command actions](https://github.com/t0mer/cic/blob/main/web/src/features/commands/useCommand.ts): `web/src/features/commands/useCommand.ts`
- [Command results](https://github.com/t0mer/cic/blob/main/web/src/features/commands/results.ts): `web/src/features/commands/results.ts`

### Other components

- **Administrator**
- **DRADIS phone**
- **MQTT broker**
- **Browser**
- **LatLng API**

## Connections

- Administrator → Browser: uses (evidence: `README.md`)
- Browser → Routed web app: opens (evidence: `web/src/App.tsx`)
- Routed web app → Browser authentication: provides auth (evidence: `web/src/App.tsx`)
- Routed web app → Device cards and map: routes devices (evidence: `web/src/App.tsx`)
- Routed web app → History routes: routes history (evidence: `web/src/App.tsx`)
- Routed web app → Settings screens: routes settings (evidence: `web/src/App.tsx`)
- Routed web app → Command actions: hosts actions (evidence: `web/src/App.tsx`)
- Command actions → Command results: registers IDs (evidence: `web/src/features/commands/useCommand.ts`)
- Browser → REST and SSE API: REST and SSE (evidence: `README.md`)
- DRADIS phone → MQTT broker: publishes telemetry (evidence: `README.md`)
- MQTT broker → MQTT client: delivers telemetry (evidence: `README.md`)
- MQTT client → Device registry: updates state (evidence: `README.md`)
- Device registry → SQLite store: persists devices (evidence: `internal/devices/registry.go`)
- Device registry → Live event hub: notifies changes
- Live event hub → REST and SSE API: streams events
- REST and SSE API → Location history: serves history (evidence: `README.md`)
- Location history → SQLite store: stores routes (evidence: `internal/history/history.go`)
- Device registry → Reverse geocoding: queues locations (evidence: `internal/geocode/worker.go`)
- Reverse geocoding → LatLng API: resolves names (evidence: `README.md`)
- Reverse geocoding → SQLite store: caches results (evidence: `internal/geocode/worker.go`)
- REST and SSE API → Safe places: manages places (evidence: `README.md`)
- Safe places → SQLite store: persists places (evidence: `README.md`)
- REST and SSE API → Device commands: dispatches actions
- Device commands → Device registry: checks device (evidence: `internal/commands/service.go`)
- Device commands → MQTT client: publishes commands (evidence: `README.md`)
- REST and SSE API → Command audit: audits attempts
- REST and SSE API → Users and MFA: authenticates users (evidence: `internal/api/api.go`)
- Users and MFA → SQLite store: stores credentials
- HTTP server → REST and SSE API: mounts routes (evidence: `cmd/cic/serve.go`)
- HTTP server → MQTT client: starts client (evidence: `cmd/cic/serve.go`)
