<pclass=sub>Platform reference · generated 2026-06-05 09:46 UTC from the live database (<code>tracksolid_db</code> @ twala.rahamafresh.com:5433)</p>
<divclass="note"><b>What this document is.</b> A current-state reference for the fleet telematics platform after the
map dashboards were moved off n8n onto the dedicated <code>dashboard_api</code> service (<code>fleetapi.rahamafresh.com</code>).
Covers data flow, deployment, the read-API, and the full database schema (tables, views, functions).</div><h2id=arch>1 · Architecture & data flow</h2><divclass=flow>
<pclass=muted>Grafana reads the same TimescaleDB directly via the <code>tracksolid.v_*</code> views (NOC + daily-ops dashboards).</p><h2id=mig>2 · The n8n → fleetapi migration</h2><p>The two map dashboards previously fetched data from n8n webhooks at
<codeclass=k>https://automate.rahamafresh.com/webhook/…</code>. n8n was only a thin HTTP→SQL proxy and a fragile link in the
live-data path. It has been replaced by <b>dashboard_api</b>, a small FastAPI service that calls the proven
<code>reporting.*</code> functions directly. The SPAs now point their <code>N8N_BASE</code> constant at
<codeclass=badge>https://fleetapi.rahamafresh.com</code>; all webhook <i>paths</i> are unchanged, so the migration was a one-line
front-end change per SPA plus the new service.</p>
(already in <code>docker-compose.yaml</code>) once the branch is merged and the <code>fleetapi</code> domain is set in Coolify.</div><h2id=api>4 · Read-API reference (dashboard_api)</h2><pclass=muted>Base: <code>https://fleetapi.rahamafresh.com</code> · all responses JSON · CORS limited to the two SPA origins.</p><table><thead><tr><th>Method</th><th>Path</th><th>Params</th><th>Returns</th><th>Notes</th></tr></thead><tbody><tr><tdclass=mono>GET</td><tdclass=mono>/health</td><tdclass=mono>—</td><td>{status: ok}</td><td>Liveness probe.</td></tr><tr><tdclass=mono>GET</td><tdclass=mono>/webhook/live-positions</td><tdclass=mono>cost_centre?, acc_status?</td><td>{summary, geojson}</td><td>Live Positions map feed → reporting.fn_live_positions. ~80 vehicle point features.</td></tr><tr><tdclass=mono>GET</td><tdclass=mono>/webhook/live-positions/track</td><tdclass=mono>vehicle_number, hours(1-24)</td><td>GeoJSON Feature (LineString)</td><td>One vehicle's recent trail. Alias: /webhook/vehicle-track.</td></tr><tr><tdclass=mono>GET</td><tdclass=mono>/webhook/vehicle-track</td><tdclass=mono>vehicle_number, hours</td><td>GeoJSON Feature</td><td>Alias of live-positions/track (kept for compatibility).</td></tr><tr><tdclass=mono>GET</td><tdclass=mono>/webhook/fleet-dashboard</td><tdclass=mono>—</td><td>{drivers, cost_centres, cities, vehicles}</td><td>Filter options for the Fleet Intelligence UI.</td></tr><tr><tdclass=mono>POST</td><tdclass=mono>/webhook/fleet-dashboard</td><tdclass=mono>JSON: period|start_date|end_date, vehicle_numbers, driver, cost_centre, assigned_city</td><td>trips GeoJSON payload</td><td>Trips for the map → reporting.fn_trips_for_map. period preset: today|7d|30d|custom.</td></tr></tbody></table><h2id=db>5 · Database schema</h2><h3id=s_tracksolid>tracksolid <spanclass=muted>· Live data — the single source of truth. Ingested from the Tracksolid API.</span></h3><pclass=muted>18 table(s) · 17 view(s) · 1 function(s) documented.</p><details><summary><spanclass=mono>tracksolid.alarms</span><spanclass=pill>table</span><spanclass=pill>344,356 rows</span></summary><p>Alarm events (alarm_type, alarm_name, alarm_time).</p><tableclass="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><tdclass=mono>id</td><tdclass=mono>bigint</td><td>NOT NULL</td><tdclass=mono>nextval('alarms_id_seq'::regclass)</td><td></td></tr><tr><tdclass=mono>imei</td><tdclass=mono>text</td><td></td><tdclass=mono></td><td></td></tr><tr><tdclass=mono>alarm_type</td><tdclass=mono>text</td><td></td><tdclass=mono></td><td></td></tr><tr><tdclass=mono>alarm_time</td><tdclass=mono>timestamp with time zone</td><td></td><tdclass=mono></td><td></td></tr><tr><tdclass=mono>geom</td><tdclass=mono>geometry(Point,4326)</td><td></td><tdclass=mono></td><td></td></tr><tr><tdclass=mono>lat</td><tdclass=mono>double precision</td><td></td><tdclass=mono></td><td></td></tr><tr><tdclass=mono>lng</td><tdclass=mono>double precision</td><td></td><tdclass=mono></td><td></td></tr><tr><tdclass=mono>speed</td><tdclass=mono>numeric(7,2)</td><td></td><tdclass=mono></td><td></td></tr><tr><tdclass=mono>acc_status</td><tdclass=mono>text</td><td></td><tdclass=mono></td><td></td></tr><tr><tdclass=mono>updated_at</td><tdclass=mono>timestamp with time zone</td><td></td><tdclass=mono>now()</td><td></td></tr><tr><tdclass=mono>alarm_name</td><tdclass=mono>text</td><td></td><tdclass=mono></td><td></td></tr><tr><tdclass=mono>source</td><tdclass=mono>text</td><td></td><tdclass=mono>'poll'::text</td><td></td></tr><tr><tdclass=mono>severity</td><tdclass=mono>text</td><td></td><tdclass=mono></td><td>Alarm severity level: critical | warning | info</td></tr><tr><tdclass=mono>geofence_id</td><tdclass=mono>text</td><td></td><tdclass=mono></td><td>Tracksolid geofence ID if this is a geofence alarm</td></tr><tr><tdclass=mono>geofence_name</td><tdclass=mono>text</td><td></td><tdclass=mono></td><td>Human-readable geofence name</td></tr><t