# FleetOps Fleet **operations** analytics for the Tracksolid fleet — fuel, utilisation, distance and driver behaviour. Sibling to **FleetNow** (live tracking); reuses the same warm-dark ops palette so the two feel like one product. This is a self-contained single-page app (`src/index.html`, inline CSS/JS + Chart.js from CDN) served by **Caddy**. It reads the FleetOps analytics API (the `dashboard_api` `/analytics/*` endpoints). ## Architecture ``` fleetops.fivetitude.com (staging) ─┐ fleetops.rahamafresh.com (prod) ─┼─► this SPA (Caddy :80, behind Traefik/Coolify) └─► API_BASE → dashboard_api /analytics/* ``` - **Web server:** Caddy. Traefik (via Coolify) terminates TLS, so Caddy is a plain `:80` file server. See `Caddyfile`. - **Per-environment API base:** Caddy's `templates` directive renders `{{env "API_BASE"}}` into `/env.js` at request time, so the **same image** serves staging and prod — just set the `API_BASE` env var on each Coolify app: - staging → `https://fleetapi.fivetitude.com` - prod → `https://fleetapi.rahamafresh.com` - if unset, `index.html` falls back to the staging API. ## Endpoints consumed | Endpoint | Panel | |---|---| | `GET /analytics/filters` | cost-centre / city dropdowns | | `GET /analytics/fleet-summary` | KPI strip + per-vehicle table | | `GET /analytics/utilisation` | distance & idle daily-trend chart | | `GET /analytics/driver-behaviour` | driver leaderboard | | `GET /analytics/fuel` | fuel panel (data-gated) | The SPA's origin must be in the API's `DASHBOARD_CORS_ORIGINS` (staging API already allows `fleetops.fivetitude.com`). ## Deploy Coolify app (Dockerfile → Caddy), one per environment, bound to a branch: | Env | Domain | Branch | `API_BASE` | |---|---|---|---| | staging | `fleetops.fivetitude.com` | `staging` | `https://fleetapi.fivetitude.com` | | prod | `fleetops.rahamafresh.com` | `main` | `https://fleetapi.rahamafresh.com` | Promotion: feature → `staging` (auto-deploys staging via Forgejo webhook) → `main` (auto-deploys prod). ## Local ```bash docker build -t fleetops . && docker run --rm -p 8080:80 -e API_BASE=https://fleetapi.fivetitude.com fleetops # open http://localhost:8080 (live data needs the localhost origin in the API CORS allowlist) ```