System Architecture
:::info Status
Implemented — reflects docker-compose.yml, Caddyfile, and fastapi-backend/main.py.
:::
Azan360 is one Python/FastAPI backend serving three built React frontends as static files, backed by PostgreSQL, an MQTT broker (EMQX) for device control, and Icecast for audio streaming.
Components
| Component | Responsibility | Communication | Trust boundary |
|---|---|---|---|
| Website | Public marketing/info site | Served static by Nginx (prod) or Vite dev server | Public, unauthenticated |
| Admin Panel | Mosque admin dashboard: broadcasts, prayer times, events, devices, memberships, audio | REST (/api/v1), WebSocket (/ws) | JWT-authenticated mosque admin |
| Super Admin Panel | Platform operator: approve devices, manage all mosques | REST (/api/v1) | JWT-authenticated superadmin, hardened with 2FA |
| fastapi-backend | All business logic, WebSocket handlers, FFmpeg process management, MQTT publish/subscribe, push delivery | Owns all outbound integrations | Single trust boundary — everything else talks through it |
| PostgreSQL | System of record for mosques, users, memberships, devices, triggers, audit logs | asyncpg, plain TCP, no pooler, pod-network only | Not exposed publicly |
| EMQX (MQTT broker) | Self-hosted; per-device credentials, command/event delivery to hardware | MQTT over TLS | Per-device auth — see MQTT Protocol |
| Icecast | Audio streaming server — one mount per mosque+room | HTTP source-client push (backend), HTTPS pull (listeners) | Source push requires ICECAST_PASSWORD; listener pull is public |
Data ownership
Every table lives in PostgreSQL, owned exclusively by fastapi-backend — no
other service touches the database directly. See Database
for the split between Alembic-owned and ensure_*-owned schema.
Authentication boundary
- Browser/admin traffic — JWT bearer tokens issued by
/api/v1/auth/*; see Authentication. - Device traffic (MQTT) — per-device EMQX credentials, provisioned at claim time; see MQTT Protocol and Device Authorization.
- Live broadcast WebSocket — a shared static
BROADCAST_TOKEN, not per-user; see Azaan Broadcast. - Stream pull (
/stream/*) — public, unauthenticated at the Icecast layer; per-request gating exists at/api/v1/stream-auth/*for scoped tokens (see API Reference).
Local development
No Docker, no Caddy — Vite dev servers proxy /api and /ws to
localhost:8082 directly. See Local Development.
Next
- Backend Architecture — inside
fastapi-backend - Device Architecture — how hardware fits in
- Data Flow — the live/offline azan path end to end
- Deployment Architecture — how this ships to production