These subsystems are retired and replaced by better alternatives (FleetNow / FleetOps SPAs via dashboard_api; in-process pooling; reporting.v_ingest_health). Remove them so the repo reflects the live stack only. Nothing running depends on the deleted artifacts. Deleted (dead artifacts): - n8n-workflows/ (retired webhook exports), grafana/ (provisioning for the removed service), dwh/ (migrations for the decommissioned external warehouse) - runbooks: DWH_PIPELINE.md, DWH_Execution_Manual.md, grafanaDeployment.md, grafanaOperationalManual.md Code/config: - run_migrations.py: drop sync_role_passwords() (its only entries were the now -dead grafana_ro + pgbouncer syncs; the guard already made it inert) - .env: remove the two unused GRAFANA_* vars - ingest_movement_rev.py / db_audit / deploy_dashboard_api_staging.sh: reword stale Grafana/grafana_ro comments Docs: scrub n8n/Grafana/DWH from CLAUDE.md, CONNECTIONS, DATA_FLOW, OPERATIONS_MANUAL, docker_commands, KPI_FRAMEWORK, PLATFORM_OVERVIEW, STAGING_FLEETOPS, and deprecation-banner the two large SQL libraries (dwh_gold was already dropped 2026-06-05). Kept deliberately: the grafana_ro DB role (now an unused read-only login), applied migration history, dated docs/reports/*, and docs/superpowers/* specs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
102 lines
No EOL
101 KiB
HTML
102 lines
No EOL
101 KiB
HTML
<!doctype html><html lang=en><head><meta charset=utf-8>
|
||
<meta name=viewport content="width=device-width, initial-scale=1">
|
||
<title>Fireside · Tracksolid Fleet Intelligence — Platform Overview</title>
|
||
<style>
|
||
:root{--bg:#0d1117;--panel:#161b22;--bd:#30363d;--fg:#e6edf3;--mut:#9da7b3;--acc:#3b82f6;--grn:#3fb950;--amb:#d29922;--mono:'SF Mono',ui-monospace,Menlo,Consolas,monospace}
|
||
*{box-sizing:border-box}
|
||
body{margin:0;background:var(--bg);color:var(--fg);font:15px/1.6 -apple-system,Segoe UI,Roboto,sans-serif}
|
||
.wrap{max-width:1100px;margin:0 auto;padding:32px 22px 80px}
|
||
h1{font-size:30px;margin:0 0 4px} h2{font-size:22px;margin:42px 0 12px;padding-bottom:6px;border-bottom:1px solid var(--bd)}
|
||
h3{font-size:17px;margin:26px 0 8px;color:#c9d4e0}
|
||
.sub{color:var(--mut)} a{color:var(--acc);text-decoration:none}
|
||
code,.mono{font-family:var(--mono);font-size:13px}
|
||
.flow{display:flex;flex-wrap:wrap;gap:10px;align-items:stretch;margin:16px 0}
|
||
.node{background:var(--panel);border:1px solid var(--bd);border-radius:10px;padding:12px 14px;min-width:150px;flex:1}
|
||
.node b{display:block;color:#fff} .node small{color:var(--mut)}
|
||
.arrow{display:flex;align-items:center;color:var(--acc);font-weight:700;font-size:20px}
|
||
table{width:100%;border-collapse:collapse;margin:8px 0 18px;background:var(--panel);border:1px solid var(--bd);border-radius:8px;overflow:hidden}
|
||
th,td{text-align:left;padding:8px 11px;border-bottom:1px solid var(--bd);vertical-align:top;font-size:13.5px}
|
||
th{background:#1c232c;color:#c9d4e0;font-weight:600}
|
||
tr:last-child td{border-bottom:none}
|
||
table.cols{margin:6px 0 4px;background:#10151c}
|
||
details{background:var(--panel);border:1px solid var(--bd);border-radius:8px;margin:7px 0;padding:4px 12px}
|
||
summary{cursor:pointer;padding:7px 0;font-weight:600}
|
||
summary .pill{font-weight:400}
|
||
.pill{display:inline-block;font-size:11px;padding:1px 7px;border-radius:20px;border:1px solid var(--bd);color:var(--mut);margin-left:6px}
|
||
.pill.ht{color:var(--amb);border-color:#5a4a1f} .pill.mv{color:var(--acc);border-color:#244a7a} .pill.fn{color:var(--grn);border-color:#27512f}
|
||
.k{color:var(--mut)} .badge{color:var(--grn);font-weight:600}
|
||
.note{background:#13202b;border-left:3px solid var(--acc);padding:10px 14px;border-radius:6px;margin:12px 0}
|
||
.warn{background:#241d10;border-left:3px solid var(--amb)}
|
||
.toc{columns:2;gap:30px} .toc a{display:block;padding:2px 0}
|
||
.muted{color:var(--mut);font-size:13px}
|
||
</style></head><body><div class=wrap>
|
||
<h1>Fireside Communications — Tracksolid Fleet Intelligence</h1>
|
||
<p class=sub>Platform reference · generated 2026-06-05 09:46 UTC from the live database (<code>tracksolid_db</code> @ twala.rahamafresh.com:5433)</p>
|
||
<div class="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><h2 id=arch>1 · Architecture & data flow</h2><div class=flow>
|
||
<div class=node><b>Tracksolid Pro / Jimi IoT API</b><small>eu-open.tracksolidpro.com — GPS, trips, alarms, OBD</small></div>
|
||
<div class=arrow>→</div>
|
||
<div class=node><b>Ingestion (Python)</b><small>ingest_worker (movement + events) · webhook_receiver</small></div>
|
||
<div class=arrow>→</div>
|
||
<div class=node><b>TimescaleDB + PostGIS</b><small>schema <code>tracksolid</code> — single source of truth</small></div>
|
||
</div>
|
||
<div class=flow>
|
||
<div class=node><b>reporting.* read layer</b><small>v_live_positions · v_trips (matview) · fn_* functions</small></div>
|
||
<div class=arrow>→</div>
|
||
<div class=node><b>dashboard_api (FastAPI)</b><small>https://fleetapi.rahamafresh.com :8890</small></div>
|
||
<div class=arrow>→</div>
|
||
<div class=node><b>Map SPAs (rustfs/S3)</b><small>liveposition · fleetintelligence</small></div>
|
||
</div>
|
||
<p class=muted><b>Consolidation 2026-06-10:</b> the backend collapsed from 7 services to 4 app services + db. The two pollers merged into a single <code>ingest_worker</code>; <b>pgbouncer</b> (dormant) and <b>Grafana</b> (redundant with FleetOps) were removed. Pipeline freshness — the one thing only Grafana surfaced — is now <code>reporting.v_ingest_health</code> (migration 19) via <code>dashboard_api</code> <code>GET /health/ingest</code>.</p><h2 id=mig>2 · The n8n → fleetapi migration</h2><p>The two map dashboards previously fetched data from n8n webhooks at
|
||
<code class=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
|
||
<code class=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>
|
||
<table><thead><tr><th>Aspect</th><th>Before (n8n)</th><th>After (fleetapi)</th></tr></thead><tbody>
|
||
<tr><td>SPA base URL</td><td class=mono>automate.rahamafresh.com</td><td class=mono>fleetapi.rahamafresh.com</td></tr>
|
||
<tr><td>Live Positions</td><td>/webhook/live-positions</td><td>same path → reporting.fn_live_positions</td></tr>
|
||
<tr><td>Vehicle trail</td><td>/webhook/live-positions/track</td><td>same path (route alias added) → fn_vehicle_track</td></tr>
|
||
<tr><td>Fleet trips</td><td>/webhook/fleet-dashboard (GET+POST)</td><td>same paths → fn_trips_for_map</td></tr>
|
||
<tr><td>Transport</td><td>n8n workflow + credentials</td><td>FastAPI + psycopg2 pool (shared with ingestion)</td></tr>
|
||
<tr><td>v_trips refresh</td><td>n8n scheduled workflow</td><td>dashboard_api background loop (every 5 min)</td></tr>
|
||
</tbody></table>
|
||
<div class="note"><b>Cutover completed 2026-06-05.</b> Two follow-ups closed the last gaps left when n8n was switched off: (1) the POST
|
||
body parser was made Content-Type aware so the SPA's form-encoded filters actually apply (<code>f1387d1</code>); (2) the
|
||
<code>reporting.v_trips</code> refresh — previously a scheduled n8n workflow — was moved into <code>dashboard_api</code> so the
|
||
read layer keeps itself fresh (<code>30b3515</code>). See §4 and §7.</div><h2 id=deploy>3 · Deployment topology</h2><p>Host <code>twala.rahamafresh.com</code> (31.97.44.246, Hostinger VPS) running <b>Coolify 4.1</b>. The Tracksolid stack
|
||
is a docker-compose application (container suffix <code>bo3nov2ija7g8wn9b1g2paxs</code>); the reverse proxy is
|
||
<b>Traefik</b> on the <code>coolify</code> network with Let's Encrypt TLS.</p>
|
||
<table><thead><tr><th>Service</th><th>Role</th><th>Port / domain</th></tr></thead><tbody>
|
||
<tr><td class=mono>timescale_db</td><td>PostgreSQL 16 + TimescaleDB 2.15 + PostGIS 3</td><td>5432 internal · 5433 host</td></tr>
|
||
<tr><td class=mono>ingest_worker</td><td>GPS positions, trips, parking, track-list, device sync <b>+ alarm event polling</b> (merged movement + events, 2026-06-10)</td><td>—</td></tr>
|
||
<tr><td class=mono>webhook_receiver</td><td>Push receiver (/pushobd /pushevent /pushtripreport …)</td><td>8888 (Traefik)</td></tr>
|
||
<tr><td class=mono>dashboard_api</td><td><b>Map read-API</b> (replaces n8n)</td><td>8890 → <span class=badge>fleetapi.rahamafresh.com</span></td></tr>
|
||
<tr><td class=mono>db_backup</td><td>pg_dump → rustfs S3 (bucket fleet-db), scheduled</td><td>—</td></tr>
|
||
<tr><td class=mono><s>grafana</s></td><td><s>NOC + daily-ops dashboards</s> — <b>REMOVED 2026-06-10</b> (redundant with FleetOps)</td><td>—</td></tr>
|
||
<tr><td class=mono><s>pgbouncer</s></td><td><s>Connection pooler</s> — <b>REMOVED 2026-06-10</b> (dormant; in-process pooling suffices)</td><td>—</td></tr>
|
||
</tbody></table>
|
||
<p>The two map front-ends are single-file SPAs stored as <code>index.html</code> objects in <b>rustfs (S3)</b> at
|
||
<code>s3.rahamafresh.com</code> (buckets <code>liveposition</code>, <code>fleetintelligence</code>), each served by a small nginx
|
||
proxy container. The dashboard_api enforces CORS for both SPA origins.</p>
|
||
<div class="note warn"><b>Operational note.</b> dashboard_api currently runs as a standalone Traefik-labelled container reusing the
|
||
app image with <code>dashboard_api_rev.py</code> bind-mounted. The durable form is the compose <code>dashboard_api</code> service
|
||
(already in <code>docker-compose.yaml</code>) once the branch is merged and the <code>fleetapi</code> domain is set in Coolify.</div><h2 id=api>4 · Read-API reference (dashboard_api)</h2><p class=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><td class=mono>GET</td><td class=mono>/health</td><td class=mono>—</td><td>{status: ok}</td><td>Liveness probe.</td></tr><tr><td class=mono>GET</td><td class=mono>/webhook/live-positions</td><td class=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><td class=mono>GET</td><td class=mono>/webhook/live-positions/track</td><td class=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><td class=mono>GET</td><td class=mono>/webhook/vehicle-track</td><td class=mono>vehicle_number, hours</td><td>GeoJSON Feature</td><td>Alias of live-positions/track (kept for compatibility).</td></tr><tr><td class=mono>GET</td><td class=mono>/webhook/fleet-dashboard</td><td class=mono>—</td><td>{drivers, cost_centres, cities, vehicles}</td><td>Filter options for the Fleet Intelligence UI.</td></tr><tr><td class=mono>POST</td><td class=mono>/webhook/fleet-dashboard</td><td class=mono>form-urlencoded: 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. Body parsed by Content-Type — the SPA posts <code>application/x-www-form-urlencoded</code>; JSON also accepted.</td></tr></tbody></table>
|
||
<div class="note"><b>Fix (2026-06-05).</b> The POST handler originally read the body as JSON only, but the SPA sends <code>x-www-form-urlencoded</code>; the mismatch silently dropped every filter so the map always returned the whole fleet. Now parsed by Content-Type (<code>parse_qs</code> for form bodies). Commit <code>f1387d1</code>.</div><h2 id=db>5 · Database schema</h2><h3 id=s_tracksolid>tracksolid <span class=muted>· Live data — the single source of truth. Ingested from the Tracksolid API.</span></h3><p class=muted>17 table(s) · 15 view(s) · 1 function(s) documented.</p><details><summary><span class=mono>tracksolid.alarms</span><span class=pill>table</span><span class=pill>344,356 rows</span></summary><p>Alarm events (alarm_type, alarm_name, alarm_time).</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>id</td><td class=mono>bigint</td><td>NOT NULL</td><td class=mono>nextval('alarms_id_seq'::regclass)</td><td></td></tr><tr><td class=mono>imei</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>alarm_type</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>alarm_time</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>geom</td><td class=mono>geometry(Point,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lat</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lng</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>speed</td><td class=mono>numeric(7,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>acc_status</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>updated_at</td><td class=mono>timestamp with time zone</td><td></td><td class=mono>now()</td><td></td></tr><tr><td class=mono>alarm_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>source</td><td class=mono>text</td><td></td><td class=mono>'poll'::text</td><td></td></tr><tr><td class=mono>severity</td><td class=mono>text</td><td></td><td class=mono></td><td>Alarm severity level: critical | warning | info</td></tr><tr><td class=mono>geofence_id</td><td class=mono>text</td><td></td><td class=mono></td><td>Tracksolid geofence ID if this is a geofence alarm</td></tr><tr><td class=mono>geofence_name</td><td class=mono>text</td><td></td><td class=mono></td><td>Human-readable geofence name</td></tr><tr><td class=mono>acknowledged_at</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td>Timestamp when alarm was acknowledged by an operator</td></tr><tr><td class=mono>acknowledged_by</td><td class=mono>text</td><td></td><td class=mono></td><td>Username or ID of operator who acknowledged the alarm</td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.api_token_cache</span><span class=pill>table</span><span class=pill>1 rows</span></summary><p>OAuth2 token cache for the Jimi/Tracksolid API.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>id</td><td class=mono>bigint</td><td>NOT NULL</td><td class=mono>nextval('api_token_cache_id_seq'::regclass)</td><td></td></tr><tr><td class=mono>account</td><td class=mono>text</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>access_token</td><td class=mono>text</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>refresh_token</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>app_key</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>expires_at</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>obtained_at</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono>now()</td><td></td></tr><tr><td class=mono>updated_at</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono>now()</td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.device_events</span><span class=pill>table</span><span class=pill>0 rows</span></summary><p>Device network connection and disconnection events from /pushevent webhook.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>id</td><td class=mono>bigint</td><td>NOT NULL</td><td class=mono>nextval('device_events_id_seq'::regclass)</td><td></td></tr><tr><td class=mono>imei</td><td class=mono>text</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>event_type</td><td class=mono>text</td><td>NOT NULL</td><td class=mono></td><td>LOGIN = device connected to network; LOGOUT = device disconnected</td></tr><tr><td class=mono>event_time</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>timezone</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>created_at</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono>now()</td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.devices</span><span class=pill>table</span><span class=pill>181 rows</span></summary><p>Device / driver / vehicle registry. One row per tracker (IMEI). Source of plate, driver, SIM, model.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>imei</td><td class=mono>text</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>device_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>mc_type</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>mc_type_use_scope</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_number</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_models</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_icon</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vin</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>engine_number</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_brand</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>fuel_100km</td><td class=mono>numeric(6,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driver_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driver_phone</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>sim</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>iccid</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>imsi</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>account</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>customer_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>device_group_id</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>device_group</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>activation_time</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>expiration</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>enabled_flag</td><td class=mono>smallint</td><td>NOT NULL</td><td class=mono>1</td><td></td></tr><tr><td class=mono>status</td><td class=mono>text</td><td></td><td class=mono>'active'::text</td><td></td></tr><tr><td class=mono>city</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>current_mileage_km</td><td class=mono>numeric(12,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>created_at</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono>now()</td><td></td></tr><tr><td class=mono>updated_at</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono>now()</td><td></td></tr><tr><td class=mono>last_synced_at</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_category</td><td class=mono>text</td><td></td><td class=mono></td><td>Vehicle type: truck | van | motorcycle | car | other</td></tr><tr><td class=mono>cost_centre</td><td class=mono>text</td><td></td><td class=mono></td><td>Business unit or department this vehicle belongs to</td></tr><tr><td class=mono>assigned_route</td><td class=mono>text</td><td></td><td class=mono></td><td>Regular route name or ID for route-based reporting</td></tr><tr><td class=mono>depot_geom</td><td class=mono>geometry(Point,4326)</td><td></td><td class=mono></td><td>Home base/depot coordinates (WGS84)</td></tr><tr><td class=mono>depot_address</td><td class=mono>text</td><td></td><td class=mono></td><td>Human-readable depot address</td></tr><tr><td class=mono>assigned_city</td><td class=mono>text</td><td></td><td class=mono></td><td>Operating territory code: NBO (Nairobi) | MBA (Mombasa) | KLA (Kampala). Used for city-cohort analytics and geographic drift detection.</td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.fault_codes</span><span class=pill>table</span><span class=pill>0 rows</span></summary><p>—</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>id</td><td class=mono>bigint</td><td>NOT NULL</td><td class=mono>nextval('fault_codes_id_seq'::regclass)</td><td></td></tr><tr><td class=mono>imei</td><td class=mono>text</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>reported_at</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>fault_code</td><td class=mono>text</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>status_flags</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lat</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lng</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>geom</td><td class=mono>geometry(Point,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>event_time</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>created_at</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono>now()</td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.fuel_readings</span><span class="pill ht">hypertable</span><span class=pill>~0 rows</span></summary><p>Fuel/oil sensor readings from /pushoil webhook. Unit varies per sensor: cm | % | V | L.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>imei</td><td class=mono>text</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>reading_time</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>sensor_path</td><td class=mono>text</td><td></td><td class=mono></td><td>Sensor channel identifier from the device (path field in API payload)</td></tr><tr><td class=mono>value</td><td class=mono>numeric(10,3)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>unit</td><td class=mono>text</td><td></td><td class=mono></td><td>Measurement unit: cm (tank depth), % (percentage), V (voltage), L (litres)</td></tr><tr><td class=mono>lat</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lng</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>geom</td><td class=mono>geometry(Point,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>created_at</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono>now()</td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.geofences</span><span class=pill>table</span><span class=pill>0 rows</span></summary><p>Geofence boundary definitions synced from the Tracksolid platform.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>id</td><td class=mono>bigint</td><td>NOT NULL</td><td class=mono>nextval('geofences_id_seq'::regclass)</td><td></td></tr><tr><td class=mono>fence_id</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>fence_name</td><td class=mono>text</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>fence_type</td><td class=mono>text</td><td></td><td class=mono></td><td>circle | polygon</td></tr><tr><td class=mono>geom</td><td class=mono>geometry(Geometry,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>radius_m</td><td class=mono>numeric(10,2)</td><td></td><td class=mono></td><td>Radius in metres — only applicable for circle type geofences</td></tr><tr><td class=mono>description</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>created_at</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono>now()</td><td></td></tr><tr><td class=mono>updated_at</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono>now()</td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.heartbeats</span><span class="pill ht">hypertable</span><span class=pill>~0 rows</span></summary><p>Device heartbeat hypertable.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>imei</td><td class=mono>text</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>gate_time</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>power_level</td><td class=mono>smallint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>gsm_signal</td><td class=mono>smallint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>acc_status</td><td class=mono>smallint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>power_status</td><td class=mono>smallint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>fortify</td><td class=mono>smallint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>created_at</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono>now()</td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.ingestion_log</span><span class=pill>table</span><span class=pill>274,181 rows</span></summary><p>API call audit trail — one row per ingestion run.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>id</td><td class=mono>bigint</td><td>NOT NULL</td><td class=mono>nextval('ingestion_log_id_seq'::regclass)</td><td></td></tr><tr><td class=mono>run_at</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono>now()</td><td></td></tr><tr><td class=mono>endpoint</td><td class=mono>text</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>imei_count</td><td class=mono>integer</td><td>NOT NULL</td><td class=mono>0</td><td></td></tr><tr><td class=mono>rows_upserted</td><td class=mono>integer</td><td>NOT NULL</td><td class=mono>0</td><td></td></tr><tr><td class=mono>rows_inserted</td><td class=mono>integer</td><td>NOT NULL</td><td class=mono>0</td><td></td></tr><tr><td class=mono>duration_ms</td><td class=mono>integer</td><td>NOT NULL</td><td class=mono>0</td><td></td></tr><tr><td class=mono>success</td><td class=mono>boolean</td><td>NOT NULL</td><td class=mono>true</td><td></td></tr><tr><td class=mono>error_code</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>error_message</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.lbs_readings</span><span class=pill>table</span><span class=pill>0 rows</span></summary><p>Cell tower / WiFi positioning fallback data from /pushlbs webhook. Used when GPS signal is unavailable.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>id</td><td class=mono>bigint</td><td>NOT NULL</td><td class=mono>nextval('lbs_readings_id_seq'::regclass)</td><td></td></tr><tr><td class=mono>imei</td><td class=mono>text</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>gate_time</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>post_type</td><td class=mono>text</td><td></td><td class=mono></td><td>Positioning technology: WIFI | LBS (cell tower)</td></tr><tr><td class=mono>lbs_data</td><td class=mono>jsonb</td><td></td><td class=mono></td><td>Raw JSON payload containing MCC, MNC, and cell tower list for approximate geocoding.</td></tr><tr><td class=mono>created_at</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono>now()</td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.live_positions</span><span class=pill>table</span><span class=pill>179 rows</span></summary><p>Latest fix per IMEI, refreshed every 60s by ingest_movement. Feeds reporting.v_live_positions.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>imei</td><td class=mono>text</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>geom</td><td class=mono>geometry(Point,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lat</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lng</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>pos_type</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>confidence</td><td class=mono>smallint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>gps_time</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>hb_time</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>speed</td><td class=mono>numeric(7,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>direction</td><td class=mono>numeric(6,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>acc_status</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>gps_signal</td><td class=mono>smallint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>gps_num</td><td class=mono>smallint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>elec_quantity</td><td class=mono>numeric(5,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>power_value</td><td class=mono>numeric(5,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>battery_power_val</td><td class=mono>numeric(5,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>tracker_oil</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>temperature</td><td class=mono>numeric(8,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>current_mileage</td><td class=mono>numeric(12,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>device_status</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>expire_flag</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>activation_flag</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>loc_desc</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>recorded_at</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono>now()</td><td></td></tr><tr><td class=mono>updated_at</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono>now()</td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.obd_readings</span><span class=pill>table</span><span class=pill>0 rows</span></summary><p>OBD diagnostics — push only via /pushobd webhook.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>id</td><td class=mono>bigint</td><td>NOT NULL</td><td class=mono>nextval('obd_readings_id_seq'::regclass)</td><td></td></tr><tr><td class=mono>imei</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>reading_time</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>engine_rpm</td><td class=mono>integer</td><td></td><td class=mono></td><td>Engine RPM from OBD PID 0x0C</td></tr><tr><td class=mono>fuel_level_pct</td><td class=mono>numeric(5,2)</td><td></td><td class=mono></td><td>Fuel tank level % from OBD PID 0x2F</td></tr><tr><td class=mono>updated_at</td><td class=mono>timestamp with time zone</td><td></td><td class=mono>now()</td><td></td></tr><tr><td class=mono>car_type</td><td class=mono>smallint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>acc_state</td><td class=mono>smallint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>status_flags</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lat</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lng</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>geom</td><td class=mono>geometry(Point,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>obd_data</td><td class=mono>jsonb</td><td></td><td class=mono></td><td>Raw obdJson from Jimi push. Contains dataID1..N fields (engine RPM, coolant temp, fuel level, etc.)</td></tr><tr><td class=mono>coolant_temp_c</td><td class=mono>numeric(6,2)</td><td></td><td class=mono></td><td>Coolant temperature °C from OBD PID 0x05</td></tr><tr><td class=mono>battery_voltage</td><td class=mono>numeric(5,2)</td><td></td><td class=mono></td><td>Battery voltage (V) from OBD PID 0x42</td></tr><tr><td class=mono>intake_pressure</td><td class=mono>numeric(6,2)</td><td></td><td class=mono></td><td>Intake manifold pressure kPa from OBD PID 0x0B</td></tr><tr><td class=mono>throttle_pct</td><td class=mono>numeric(5,2)</td><td></td><td class=mono></td><td>Throttle position % from OBD PID 0x11</td></tr><tr><td class=mono>vehicle_speed</td><td class=mono>numeric(7,2)</td><td></td><td class=mono></td><td>Vehicle speed km/h from OBD PID 0x0D</td></tr><tr><td class=mono>engine_load_pct</td><td class=mono>numeric(5,2)</td><td></td><td class=mono></td><td>Calculated engine load % from OBD PID 0x04</td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.parking_events</span><span class=pill>table</span><span class=pill>0 rows</span></summary><p>Stop events with duration + address.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>id</td><td class=mono>bigint</td><td>NOT NULL</td><td class=mono>nextval('parking_events_id_seq'::regclass)</td><td></td></tr><tr><td class=mono>imei</td><td class=mono>text</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>event_type</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_time</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>end_time</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>duration_seconds</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>geom</td><td class=mono>geometry(Point,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>address</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>updated_at</td><td class=mono>timestamp with time zone</td><td></td><td class=mono>now()</td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.position_history</span><span class="pill ht">hypertable</span><span class=pill>~3,596,013 rows</span></summary><p>All GPS fixes (hypertable, partitioned by gps_time). source='poll' (60s) or 'track_list' (30m high-res).</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>imei</td><td class=mono>text</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>gps_time</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>geom</td><td class=mono>geometry(Point,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lat</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lng</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>speed</td><td class=mono>numeric(7,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>direction</td><td class=mono>numeric(6,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>acc_status</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>satellite</td><td class=mono>smallint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>current_mileage</td><td class=mono>numeric(12,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>recorded_at</td><td class=mono>timestamp with time zone</td><td></td><td class=mono>now()</td><td></td></tr><tr><td class=mono>altitude</td><td class=mono>numeric(8,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>post_type</td><td class=mono>smallint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>source</td><td class=mono>text</td><td></td><td class=mono>'poll'::text</td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.schema_migrations</span><span class=pill>table</span><span class=pill>9 rows</span></summary><p>—</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>filename</td><td class=mono>text</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>applied_at</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono>now()</td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.temperature_readings</span><span class="pill ht">hypertable</span><span class=pill>~0 rows</span></summary><p>Temperature and humidity sensor readings from /pushtem webhook. For cold-chain / refrigerated cargo monitoring.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>imei</td><td class=mono>text</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>reading_time</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>temperature</td><td class=mono>numeric(6,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>humidity_pct</td><td class=mono>numeric(5,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>created_at</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono>now()</td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.trips</span><span class=pill>table</span><span class=pill>43,765 rows</span></summary><p>Trip summaries: distance_km, driving time, avg/max speed, route geometry + addresses (FIX-M20).</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>id</td><td class=mono>bigint</td><td>NOT NULL</td><td class=mono>nextval('trips_id_seq'::regclass)</td><td></td></tr><tr><td class=mono>imei</td><td class=mono>text</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>start_time</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>end_time</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_geom</td><td class=mono>geometry(Point,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>end_geom</td><td class=mono>geometry(Point,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>distance_km</td><td class=mono>numeric(12,2)</td><td></td><td class=mono></td><td>Trip distance in kilometres. Corrected from mm storage on migration 04 (2026-04-10).</td></tr><tr><td class=mono>avg_speed_kmh</td><td class=mono>numeric(7,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>max_speed_kmh</td><td class=mono>numeric(7,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>updated_at</td><td class=mono>timestamp with time zone</td><td></td><td class=mono>now()</td><td></td></tr><tr><td class=mono>fuel_consumed_l</td><td class=mono>numeric(8,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>idle_time_s</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driving_time_s</td><td class=mono>integer</td><td></td><td class=mono></td><td>runTimeSecond from API: total driving time in seconds</td></tr><tr><td class=mono>trip_seq</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>source</td><td class=mono>text</td><td></td><td class=mono>'poll'::text</td><td>poll = from API polling, push = from webhook push</td></tr><tr><td class=mono>route_geom</td><td class=mono>geometry(LineString,4326)</td><td></td><td class=mono></td><td>Full GPS route polyline built at ingest from position_history points where gps_time BETWEEN start_time AND end_time. NULL when fewer than 2 fixes are available for the trip window.</td></tr><tr><td class=mono>start_address</td><td class=mono>text</td><td></td><td class=mono></td><td>Reverse-geocoded human-readable address near start_geom (Nominatim). NULL on lookup failure; address is best-effort, not authoritative.</td></tr><tr><td class=mono>end_address</td><td class=mono>text</td><td></td><td class=mono></td><td>Reverse-geocoded human-readable address near end_geom (Nominatim). NULL on lookup failure; address is best-effort, not authoritative.</td></tr><tr><td class=mono>vehicle_plate</td><td class=mono>text</td><td></td><td class=mono></td><td>Denormalised tracksolid.devices.vehicle_number cached at trip-insert time. Avoids a join for trip displays; refreshed only on next ingest.</td></tr><tr><td class=mono>waypoints_count</td><td class=mono>integer</td><td></td><td class=mono></td><td>Number of position_history fixes that contributed to route_geom. Audit aid: 0 or 1 means route_geom is NULL or degenerate.</td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.v_active_dispatch_map</span><span class=pill>view</span></summary><p>01_BusinessAnalytics.md §4.3 All Active Vehicles Map. Geomap source.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>imei</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_number</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driver_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driver_phone</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_city</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lat</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lng</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>speed</td><td class=mono>numeric(7,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>direction</td><td class=mono>numeric(6,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>acc_status</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>last_fix</td><td class=mono>timestamp without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>status</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.v_alarms_daily</span><span class=pill>view</span></summary><p>01_BusinessAnalytics.md §7 Panel 7 Alarm Frequency. Stacked-by-alarm_name time series.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>day</td><td class=mono>date</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>alarm_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>alarm_count</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.v_currently_idle</span><span class=pill>view</span></summary><p>01_BusinessAnalytics.md §2.2 idle lens. Engine on, speed <2 km/h, fix in last 15m.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>imei</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_number</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driver_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_city</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lat</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lng</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>since</td><td class=mono>timestamp without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>idle_seconds</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.v_driver_aggregates_daily</span><span class=pill>view</span></summary><p>01_BusinessAnalytics.md §3.1 (speeding) + §3.2 (harsh driving). Daily grain; panels window via $__timeFilter(day).</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>imei</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driver_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_number</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_city</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>day</td><td class=mono>date</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>km</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>trips</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>events_80</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>events_100</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>events_120</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>harsh_events</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>speeding_per_100km</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>harsh_per_100km</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.v_driver_attendance_daily</span><span class=pill>view</span></summary><p>—</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>report_date</td><td class=mono>date</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driver_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_number</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>cost_centre</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_city</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>reporting_time</td><td class=mono>time without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_address</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_lat</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_lng</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>status</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>mins_from_start</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.v_driver_clock_daily</span><span class=pill>view</span></summary><p>Driver clock-in / clock-out daily series. One row per IMEI per Africa/Nairobi date with at least one trip. Reporting/closing times are derived from trip start_time/end_time bounded by local-date start; closing_ts may cross midnight UTC. No policy embedded — n8n applies tardiness rules and cost-centre filtering. See plan i-would-like-to-wobbly-volcano (2026-05-04).</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>imei</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driver_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_number</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>cost_centre</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_city</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>report_date</td><td class=mono>date</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>reporting_time</td><td class=mono>time without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>closing_time</td><td class=mono>time without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>reporting_ts</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>closing_ts</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_lat</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_lng</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_address</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>end_lat</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>end_lng</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>end_address</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>trips_count</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>total_km</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>drive_hours</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.v_driver_clock_today</span><span class=pill>view</span></summary><p>Today snapshot of v_driver_clock_daily, filtered to (NOW() AT TIME ZONE 'Africa/Nairobi')::date. Refreshes as trips land throughout the day.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>imei</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driver_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_number</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>cost_centre</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_city</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>report_date</td><td class=mono>date</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>reporting_time</td><td class=mono>time without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>closing_time</td><td class=mono>time without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>reporting_ts</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>closing_ts</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_lat</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_lng</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_address</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>end_lat</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>end_lng</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>end_address</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>trips_count</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>total_km</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>drive_hours</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.v_fleet_km_daily</span><span class=pill>view</span></summary><p>01_BusinessAnalytics.md §7 Panel 5 Distance Trend. City-cohort cut built in.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>day</td><td class=mono>date</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_city</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>km</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>active_vehicles</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>trips</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.v_fleet_status</span><span class=pill>view</span></summary><p>—</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>imei</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_number</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driver_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lat</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lng</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>geom</td><td class=mono>geometry(Point,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>speed</td><td class=mono>numeric(7,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>acc_status</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>gps_time</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>connectivity_status</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>seconds_since_fix</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.v_fleet_today</span><span class=pill>view</span></summary><p>01_BusinessAnalytics.md §9 Fleet Readiness Scorecard. One row per device with today's roll-up.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>imei</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driver_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_number</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_city</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>enabled_flag</td><td class=mono>smallint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>km_today</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>trips_today</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>drive_hours</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>idle_hours</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>first_departure</td><td class=mono>time without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>last_return</td><td class=mono>time without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>alarms_today</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>last_fix</td><td class=mono>timestamp without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>last_speed</td><td class=mono>numeric(7,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>did_not_move</td><td class=mono>boolean</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.v_fleet_trace</span><span class=pill>view</span></summary><p>—</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>gid</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driver_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>device_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>imei</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>geom</td><td class=mono>geometry(Point,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lat</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lng</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_time</td><td class=mono>timestamp without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>end_time</td><td class=mono>timestamp without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>day_local</td><td class=mono>date</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>hour_local</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>dow_local</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>gps_time_utc</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>recorded_at</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>speed</td><td class=mono>numeric(7,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>direction</td><td class=mono>numeric(6,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>current_mileage</td><td class=mono>numeric(12,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>stationary</td><td class=mono>boolean</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>trip_id</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.v_ingestion_health</span><span class=pill>view</span></summary><p>—</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>endpoint</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>run_at</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>success</td><td class=mono>boolean</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>error_message</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>seconds_ago</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.v_mileage_daily_cagg</span><span class=pill>view</span></summary><p>—</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>bucket</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>imei</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>dist_km</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>avg_speed</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.v_trips_enriched</span><span class=pill>view</span></summary><p>tracksolid.trips with computed daily_seq (Nth trip per IMEI per local Africa/Nairobi day) and trip_date_eat. Replaces reliance on the device-supplied trip_seq column, which is NULL for poll-ingested trips.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>id</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>imei</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_time</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>end_time</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_geom</td><td class=mono>geometry(Point,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>end_geom</td><td class=mono>geometry(Point,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>distance_km</td><td class=mono>numeric(12,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>avg_speed_kmh</td><td class=mono>numeric(7,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>max_speed_kmh</td><td class=mono>numeric(7,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>updated_at</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>fuel_consumed_l</td><td class=mono>numeric(8,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>idle_time_s</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driving_time_s</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>trip_seq</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>source</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>route_geom</td><td class=mono>geometry(LineString,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_address</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>end_address</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_plate</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>waypoints_count</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>trip_date_eat</td><td class=mono>date</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>daily_seq</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.v_vehicles_not_moved_today</span><span class=pill>view</span></summary><p>01_BusinessAnalytics.md §2.3. Enabled vehicles with zero trips today.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>imei</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_number</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driver_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_city</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>last_seen</td><td class=mono>timestamp without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>speed</td><td class=mono>numeric(7,2)</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>tracksolid.set_updated_at(…)</span><span class='pill fn'>function · plpgsql</span></summary><p>—</p><table class=cols><tbody><tr><td class=k>arguments</td><td class=mono>()</td></tr><tr><td class=k>returns</td><td class=mono>trigger</td></tr></tbody></table></details><h3 id=s_reporting>reporting <span class=muted>· Read layer that backs the map dashboards (consumed by dashboard_api).</span></h3><p class=muted>2 table(s) · 12 view(s) · 4 function(s) documented.</p><details><summary><span class=mono>reporting.refresh_log</span><span class=pill>table</span><span class=pill>3,558 rows</span></summary><p>One row per REFRESH MATERIALIZED VIEW CONCURRENTLY reporting.v_trips. Written by dashboard_api's built-in refresher (<code>source='dashboard_api'</code>, every 5 min); the retired n8n job (<code>source='n8n'</code>) was the previous writer. Read MAX(refreshed_at) for staleness.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>refreshed_at</td><td class=mono>timestamp with time zone</td><td>NOT NULL</td><td class=mono>now()</td><td></td></tr><tr><td class=mono>source</td><td class=mono>text</td><td>NOT NULL</td><td class=mono>'n8n'::text</td><td></td></tr><tr><td class=mono>duration_ms</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>row_count</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>notes</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>reporting.v_trips</span><span class="pill mv">matview</span><span class=pill>31,670 rows</span></summary><p>Canonical trip view, MATERIALIZED for dashboard read latency (see header diagnostic note). All timestamps in Africa/Nairobi. LEFT JOINs devices so trips with no device row keep NULL cost_centre rather than disappearing. Refresh via n8n every 5 min; see reporting.refresh_log. See 260519_trips_kepler_deployment.md §Phase 1+6.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>trip_id</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>imei</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>device_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_number</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_models</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_category</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>cost_centre</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_city</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_driver</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_time</td><td class=mono>timestamp without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>end_time</td><td class=mono>timestamp without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>trip_date</td><td class=mono>date</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_hour</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_dow</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>daily_seq</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>distance_km</td><td class=mono>numeric(12,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>avg_speed_kmh</td><td class=mono>numeric(7,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>max_speed_kmh</td><td class=mono>numeric(7,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>idle_time_s</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driving_time_s</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>fuel_consumed_l</td><td class=mono>numeric(8,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>waypoints_count</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_address</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>end_address</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_geom</td><td class=mono>geometry(Point,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>end_geom</td><td class=mono>geometry(Point,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>route_geom</td><td class=mono>geometry(LineString,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>route_geojson</td><td class=mono>json</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>is_meaningful_route</td><td class=mono>boolean</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>updated_at</td><td class=mono>timestamp without time zone</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>reporting.v_daily_cost_centre</span><span class=pill>view</span></summary><p>Cost-centre × day rollup. Excludes trips with NULL cost_centre.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>trip_date</td><td class=mono>date</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>cost_centre</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>active_vehicles</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>active_drivers</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>trip_count</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>total_km</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driving_hours</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>idle_hours</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>idle_pct</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>km_per_vehicle</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>reporting.v_daily_summary</span><span class=pill>view</span></summary><p>Vehicle × day rollup. Filtered by is_meaningful_route. day_routes_geojson is the daily multi-line geometry for long-range Kepler.gl fallback.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>trip_date</td><td class=mono>date</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>cost_centre</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_city</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_number</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_driver</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>trip_count</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>total_km</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driving_hours</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>idle_hours</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>idle_pct</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>first_trip_start</td><td class=mono>timestamp without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>last_trip_end</td><td class=mono>timestamp without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>avg_speed_kmh</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>max_speed_kmh</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>day_routes_geojson</td><td class=mono>json</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>reporting.v_filter_cities</span><span class=pill>view</span></summary><p>Assigned-city dropdown source for the n8n dashboard. Distinct non-null cities.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>assigned_city</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>reporting.v_filter_cost_centres</span><span class=pill>view</span></summary><p>Cost-centre dropdown source for the n8n dashboard. Distinct non-null centres.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>cost_centre</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>reporting.v_filter_drivers</span><span class=pill>view</span></summary><p>Driver dropdown source for the n8n dashboard. Distinct non-null drivers.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>driver</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>reporting.v_filter_vehicles</span><span class=pill>view</span></summary><p>Vehicle dropdown source for the n8n dashboard. Plate is the value; drivers column lists every driver historically associated with the vehicle. cost_centre and assigned_city carry the vehicle's most-recent assignment so the frontend can auto-set those dependent dropdowns.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>vehicle_number</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>drivers</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>cost_centre</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_city</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>reporting.v_live_positions</span><span class=pill>view</span></summary><p>Latest known fix per vehicle, deduped to one primary IMEI per normalised plate. Provenance: 260521_liveposition_deployment.md §Phase 1.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>imei</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_number</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_driver</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>cost_centre</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_city</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_category</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_models</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>mc_type</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>device_kind</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lat</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>lng</td><td class=mono>double precision</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>speed</td><td class=mono>numeric(7,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>direction</td><td class=mono>numeric(6,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>acc_status</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>device_status</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>gps_signal</td><td class=mono>smallint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>gps_num</td><td class=mono>smallint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>current_mileage</td><td class=mono>numeric(12,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>loc_desc</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>gps_time</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>updated_at</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>gps_time_eat</td><td class=mono>timestamp without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>updated_at_eat</td><td class=mono>timestamp without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>source_age_hours</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>reporting.v_monthly_cost_centre</span><span class=pill>view</span></summary><p>Cost-centre × month rollup. Executive grain. Excludes trips with NULL cost_centre.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>month_start</td><td class=mono>date</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>month_label</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>cost_centre</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>active_vehicles</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>active_drivers</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>active_days</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>trip_count</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>total_km</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driving_hours</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>idle_hours</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>idle_pct</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>km_per_vehicle</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>reporting.v_monthly_summary</span><span class=pill>view</span></summary><p>Vehicle × month rollup with trend metrics (km_per_active_day, km_per_trip).</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>month_start</td><td class=mono>date</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>month_label</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>cost_centre</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_city</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_category</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_number</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_driver</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>trip_count</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>active_days</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>total_km</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driving_hours</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>idle_hours</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>idle_pct</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>km_per_active_day</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>km_per_trip</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>avg_speed_kmh</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>peak_speed_kmh</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>reporting.v_trips_today</span><span class=pill>view</span></summary><p>Today snapshot of reporting.v_trips, filtered to (NOW() AT TIME ZONE 'Africa/Nairobi')::date. Refreshes as trips land throughout the day.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>trip_id</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>imei</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>device_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_number</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_models</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_category</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>cost_centre</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_city</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_driver</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_time</td><td class=mono>timestamp without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>end_time</td><td class=mono>timestamp without time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>trip_date</td><td class=mono>date</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_hour</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_dow</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>daily_seq</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>distance_km</td><td class=mono>numeric(12,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>avg_speed_kmh</td><td class=mono>numeric(7,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>max_speed_kmh</td><td class=mono>numeric(7,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>idle_time_s</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driving_time_s</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>fuel_consumed_l</td><td class=mono>numeric(8,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>waypoints_count</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_address</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>end_address</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_geom</td><td class=mono>geometry(Point,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>end_geom</td><td class=mono>geometry(Point,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>route_geom</td><td class=mono>geometry(LineString,4326)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>route_geojson</td><td class=mono>json</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>is_meaningful_route</td><td class=mono>boolean</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>updated_at</td><td class=mono>timestamp without time zone</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>reporting.v_weekly_cost_centre</span><span class=pill>view</span></summary><p>Cost-centre × week rollup. Excludes trips with NULL cost_centre.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>week_start</td><td class=mono>date</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>cost_centre</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>active_vehicles</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>active_drivers</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>active_days</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>trip_count</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>total_km</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driving_hours</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>idle_hours</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>idle_pct</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>km_per_vehicle</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>reporting.v_weekly_summary</span><span class=pill>view</span></summary><p>Vehicle × week rollup. Numeric only, no geometry.</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>week_start</td><td class=mono>date</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>cost_centre</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_city</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_number</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>assigned_driver</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>trip_count</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>active_days</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>total_km</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driving_hours</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>idle_hours</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>avg_trip_km</td><td class=mono>numeric</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>reporting.fn_live_positions(…)</span><span class='pill fn'>function · plpgsql</span></summary><p>Dashboard contract for liveposition.rahamafresh.com. Returns {summary, geojson}. NULL params = wildcard. Reads reporting.v_live_positions (already deduped). Provenance: 260521_liveposition_deployment.md §Phase 2.</p><table class=cols><tbody><tr><td class=k>arguments</td><td class=mono>p_cost_centre text DEFAULT NULL::text, p_acc_status text DEFAULT NULL::text</td></tr><tr><td class=k>returns</td><td class=mono>jsonb</td></tr></tbody></table></details><details><summary><span class=mono>reporting.fn_trips_for_map(…)</span><span class='pill fn'>function · plpgsql</span></summary><p>Dashboard contract: see 260519_trips_kepler_deployment.md §Phase 2. Args (positional): vehicle_numbers[], driver, cost_centre, assigned_city, start_date, end_date. NULL = wildcard; empty array also = wildcard. Returns {summary, geojson} where each feature carries daily_seq for client-side sequence colouring. Refuses unfiltered ranges >31 days.</p><table class=cols><tbody><tr><td class=k>arguments</td><td class=mono>p_vehicle_numbers text[] DEFAULT NULL::text[], p_driver text DEFAULT NULL::text, p_cost_centre text DEFAULT NULL::text, p_assigned_city text DEFAULT NULL::text, p_start_date date DEFAULT NULL::date, p_end_date date DEFAULT NULL::date</td></tr><tr><td class=k>returns</td><td class=mono>jsonb</td></tr></tbody></table></details><details><summary><span class=mono>reporting.fn_vehicle_track(…)</span><span class='pill fn'>function · sql</span></summary><p>Returns a GeoJSON Feature(LineString) of the vehicle's last N hours of fixes from tracksolid.position_history. Provenance: 260521_liveposition_deployment.md §Phase 3.</p><table class=cols><tbody><tr><td class=k>arguments</td><td class=mono>p_vehicle_number text, p_hours integer DEFAULT 1</td></tr><tr><td class=k>returns</td><td class=mono>jsonb</td></tr></tbody></table></details><details><summary><span class=mono>reporting.normalize_plate(…)</span><span class='pill fn'>function · sql</span></summary><p>Canonicalise Kenyan vehicle plates: trim, collapse internal whitespace, and remove the space before a single trailing letter (e.g. "KDS 453 Y" → "KDS 453Y"). Used in v_trips so plate-level grouping/joining works consistently regardless of how the plate was typed into the registry.</p><table class=cols><tbody><tr><td class=k>arguments</td><td class=mono>p text</td></tr><tr><td class=k>returns</td><td class=mono>text</td></tr></tbody></table></details><h3 id=s_removed>ops · dwh_gold <span class=muted>· REMOVED 2026-06-05</span></h3><p class=muted>The <code>ops</code> schema (workshop / tickets / dispatch / SLA / odometer / cost_rates / kpi_targets) and the <code>dwh_gold</code> schema (dim_vehicles, fact_daily_fleet_metrics, refresh_daily_metrics) were <b>purged 2026-06-05</b> via migrations 12 / 13 — those features were never implemented. Also dropped: <code>tracksolid.dispatch_log</code>, <code>tracksolid.v_sla_inflight</code>, <code>tracksolid.v_utilisation_daily</code>, and their Grafana panels. The separate DWH pipeline (bronze/silver/gold on <code>tracksolid_dwh</code>) was decommissioned on 2026-06-10.</p><h3 id=s_public>public <span class=muted>· Extension objects + pgbouncer auth helper.</span></h3><p class=muted>1 table(s) · 3 view(s) · 1 function(s) documented.</p><details><summary><span class=mono>public.spatial_ref_sys</span><span class=pill>table</span><span class=pill>8,500 rows</span></summary><p>—</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>srid</td><td class=mono>integer</td><td>NOT NULL</td><td class=mono></td><td></td></tr><tr><td class=mono>auth_name</td><td class=mono>character varying(256)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>auth_srid</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>srtext</td><td class=mono>character varying(2048)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>proj4text</td><td class=mono>character varying(2048)</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>public.geography_columns</span><span class=pill>view</span></summary><p>—</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>f_table_catalog</td><td class=mono>name</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>f_table_schema</td><td class=mono>name</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>f_table_name</td><td class=mono>name</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>f_geography_column</td><td class=mono>name</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>coord_dimension</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>srid</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>type</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>public.geometry_columns</span><span class=pill>view</span></summary><p>—</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>f_table_catalog</td><td class=mono>character varying(256)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>f_table_schema</td><td class=mono>name</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>f_table_name</td><td class=mono>name</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>f_geometry_column</td><td class=mono>name</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>coord_dimension</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>srid</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>type</td><td class=mono>character varying(30)</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>public.trips_viz_v1</span><span class=pill>view</span></summary><p>—</p><table class="cols"><thead><tr><th>Column</th><th>Type</th><th>Null</th><th>Default</th><th>Comment</th></tr></thead><tbody><tr><td class=mono>trip_id</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>imei</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_name</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_number</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>cost_centre</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_time</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>end_time</td><td class=mono>timestamp with time zone</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>distance_km</td><td class=mono>numeric(12,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>avg_speed_kmh</td><td class=mono>numeric(7,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>max_speed_kmh</td><td class=mono>numeric(7,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>vehicle_plate</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>start_address</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>end_address</td><td class=mono>text</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>waypoints_count</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>driving_time_s</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>idle_time_s</td><td class=mono>integer</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>fuel_consumed_l</td><td class=mono>numeric(8,2)</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>trip_date_eat</td><td class=mono>date</td><td></td><td class=mono></td><td></td></tr><tr><td class=mono>daily_seq</td><td class=mono>bigint</td><td></td><td class=mono></td><td></td></tr></tbody></table></details><details><summary><span class=mono>public.user_lookup(…)</span><span class='pill fn'>function · plpgsql</span></summary><p>pgbouncer SCRAM auth_query — returns (username, password-hash) for connection pooling.</p><table class=cols><tbody><tr><td class=k>arguments</td><td class=mono>in_user text, OUT uname text, OUT phash text</td></tr><tr><td class=k>returns</td><td class=mono>record</td></tr></tbody></table></details><h2 id=readapi>6 · Read-API & pipeline health</h2><p class=muted>Grafana was <b>removed on 2026-06-10</b> (redundant with the FleetOps SPA). Fleet KPIs are now served by the FleetNow / FleetOps SPAs via <code>dashboard_api</code>; ingest-pipeline freshness is exposed at <code>GET /health/ingest</code> (<code>reporting.v_ingest_health</code>, migration 19). The <code>tracksolid.v_*</code> analytics views still exist but are currently unconsumed.</p><h2 id=ops>7 · Operational notes</h2><ul>
|
||
<li><b>Hypertables</b> (<code>position_history</code>, <code>heartbeats</code>, <code>fuel_readings</code>,
|
||
<code>temperature_readings</code>) report 0 in <code>pg_stat_user_tables</code> — counts above use TimescaleDB's
|
||
<code>approximate_row_count()</code>.</li>
|
||
<li><b>API distance fields are metres</b>, not km (divide by 1000) — see FIX-M16.</li>
|
||
<li><b>reporting.v_trips</b> is a materialized view (owned by <code>reporting_refresher</code>, DDL in
|
||
<code>migrations/11_reporting_schema.sql</code>). It is kept current by <b>dashboard_api</b>'s built-in background
|
||
refresher — <code>REFRESH MATERIALIZED VIEW CONCURRENTLY</code> every <code>VTRIPS_REFRESH_INTERVAL_S</code> (default 300s),
|
||
advisory-lock guarded so only one uvicorn worker refreshes per tick. This replaced the n8n scheduled workflow that
|
||
refreshed it until n8n was retired (2026-06-01); a stale matview was the cause of the "no trips" incident on 2026-06-05.
|
||
The container's <code>DATABASE_URL</code> connects as a superuser, which is why it may REFRESH a matview it does not own.</li>
|
||
<li><b>Migrations</b> apply at container startup via <code>run_migrations.py</code> (idempotent, tracked in
|
||
<code>tracksolid.schema_migrations</code>). Latest: <code>11_reporting_schema.sql</code>.</li>
|
||
<li><b>Backups</b>: <code>db_backup</code> sidecar → rustfs bucket <code>fleet-db</code>, scheduled (default 02:30/08:30/14:30/20:30 Africa/Nairobi).</li>
|
||
</ul>
|
||
<p class=muted>See also: <code>docs/CONNECTIONS.md</code>, <code>docs/reference/01_BusinessAnalytics.md</code>,
|
||
<code>docs/manuals/OPERATIONS_MANUAL.md</code>, and the project <code>CLAUDE.md</code>.</p></div></body></html> |