Architecture overview¶
This page describes the current production-oriented architecture in the repository.
When to use this page¶
Use this page to understand how services depend on one another, how data flows end to end, and where to triage failures.
System shape¶
The platform runs as a Docker-based service mesh:
frontend(React): user-facing UI.api-gateway(FastAPI): external API facade under/v1.tactic-middleware(FastAPI): data adapter and RADAR orchestration.db-sync: schema initialization and readiness API.mqtt-proxy: source MQTT ingestion and optional bridge publishing.mqtt-radar: anomaly workload, either profile-based or TACTIC-managed.timescaledb(PostgreSQL + TimescaleDB): operational persistence.emqx-main, plus optionalemqx-worker: internal broker.source-broker: deterministic local source telemetry broker.mailpit: local mail capture for authentication flows.socket-proxy: restricted Docker API access for TACTIC.
Service responsibilities and interplay¶
| Service | Owns | Reads from | Writes to | Critical dependencies |
|---|---|---|---|---|
| Frontend | User workflows and UI state | API Gateway /v1 |
Browser state | API Gateway and a valid VITE_API_URL |
| API Gateway | External route contract and request composition | TACTIC data/orchestration endpoints | HTTP responses | TACTIC readiness |
| TACTIC | Domain data adapter and RADAR lifecycle | Database services, Docker API proxy, model registry | Database and container lifecycle | Docker API, model registry, database |
| DB Sync | Schema bootstrap and readiness | Database | Database schema | Database availability |
| MQTT Proxy | Source ingest, parsing, batching, optional forwarding | Source broker or ingress | telemetry, optional bridge broker |
MQTT source and database |
| EMQX | Internal monitoring message bus | Bridge publishers | MQTT streams | Broker health and authentication settings |
| MQTT RADAR | Online anomaly detection | EMQX topics and model configuration | Monitoring evidence and anomalies | Topic stream, model initialization, database |
| TimescaleDB | Relational and time-series persistence | Write-capable services | Query results | Storage and schema readiness |
End-to-end flows¶
1. Authentication and session flow¶
- The frontend calls Gateway authentication routes under
/v1/auth. - The Gateway delegates data operations to TACTIC.
- Password hashes and verification state are resolved through database-backed services.
- Verification and reset emails use the configured SMTP service; local mode uses Mailpit.
- The frontend stores the bearer token and attaches it to later API calls.
2. Telemetry ingestion flow¶
- A producer publishes
device/evCharger/<charger_id>/<telemetry_type>to the source broker. mqtt-proxysubscribes throughMQTT_SOURCE_TOPICS, parses charger/type fields, and batches messages.- Valid observations are persisted in the
telemetryhypertable. - When bridge publishing is configured, the same stream is made available to the RADAR broker.
- Gateway telemetry endpoints expose stored data through TACTIC to frontend charts.
3. Monitoring lifecycle flow¶
- An operator selects sensors and a strategy in the frontend.
- The frontend calls Gateway monitor routes under
/v1/monitors. - TACTIC validates the request and claims the selected sensors.
- TACTIC creates, starts, inspects, or removes the RADAR workload through the Docker API proxy.
- The workload runs either the static-baseline or adaptive-stream lane.
- Runtime state and processing stages are surfaced through the Gateway.
4. Evidence and anomaly flow¶
- RADAR consumes selected telemetry topics from EMQX.
- The configured strategy calculates scores, p-values where applicable, and tracker evidence.
- Evidence is written to
monitoring_evidence; threshold crossings produceanomaliesrecords. - The frontend retrieves service state, evidence, counts, and events through the Gateway.
Startup order and readiness¶
The normal local startup remains one command, but dependencies become ready in this order:
timescaledbdb-syncat/ready/schematactic-middlewareat/readyapi-gatewayat/healthmqtt-proxyat/ready/bridgewhen bridge readiness is applicablefrontend
Gateway liveness can succeed while TACTIC-backed data or monitoring operations remain unavailable.
Service-to-service HTTP contracts¶
| Caller | Callee | Critical paths | Purpose |
|---|---|---|---|
| Frontend | API Gateway | /v1/auth/*, /v1/chargers/*, /v1/telemetry/*, /v1/monitors/*, /v1/anomalies* |
Primary user contract |
| API Gateway | TACTIC | /api/v1/data/*, /api/v1/orchestration/radar/*, /api/v1/models/* |
Data access and orchestration |
| Health tooling | API Gateway | /health |
Gateway liveness |
| Health tooling | TACTIC | /health, /ready |
Orchestration and registry readiness |
| Internal checks | DB Sync | /health, /ready/schema |
Schema readiness |
| Internal checks | MQTT Proxy | /health, /ready/bridge |
Ingest and bridge readiness |
Failure modes and recovery checkpoints¶
| Symptom | Likely breakpoint | First checks |
|---|---|---|
| Frontend loads but has no data | Gateway-to-TACTIC data path | Gateway health, TACTIC readiness, both logs |
| Monitoring start fails | Model validation, sensor ownership, or Docker API | TACTIC readiness, /v1/monitors/models, active services |
| Telemetry is missing | Source, proxy parsing, or database write | Source publish, proxy logs/readiness, database health |
| Evidence is absent | RADAR workload or broker topic path | Service list, RADAR logs, EMQX stream |
| Authentication email is missing | SMTP configuration | Mail service logs and EMAIL_* transport settings |
Deployment context¶
- Local default:
docker compose up -d --build - Cluster override:
docker-compose.cluster.yml - Swarm:
docker-compose.swarm.yml - Swarm ingress overlay: add
docker-compose.ingress.yml
See Deployment modes for operational commands.