fleetops/README.md
david kiania ff5945a85d feat: FleetOps analytics SPA (Caddy) — initial scaffold
Fleet operations analytics (fuel · utilisation · distance · driver behaviour),
sibling to FleetNow. Self-contained src/index.html (inline CSS/JS + Chart.js CDN)
reusing FleetNow's warm-dark ops palette + header shell for a familiar look.

Reads dashboard_api /analytics/* (fleet-summary, utilisation, driver-behaviour,
fuel, filters). Panels: KPI strip, distance/idle daily-trend chart, per-vehicle
table, driver leaderboard, fuel (data-gated).

Served by Caddy on :80 (Traefik terminates TLS). Per-env API base injected at
runtime via Caddy `templates` -> /env.js ({{env "API_BASE"}}); falls back to the
staging API. Dockerfile runs `caddy validate` at build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 13:00:31 +03:00

58 lines
2.3 KiB
Markdown

# 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)
```