Fireside Communications — Tracksolid Fleet Intelligence

Platform reference · generated 2026-06-05 09:46 UTC from the live database (tracksolid_db @ twala.rahamafresh.com:5433)

What this document is. A current-state reference for the fleet telematics platform after the map dashboards were moved off n8n onto the dedicated dashboard_api service (fleetapi.rahamafresh.com). Covers data flow, deployment, the read-API, and the full database schema (tables, views, functions).

1 · Architecture & data flow

Tracksolid Pro / Jimi IoT APIeu-open.tracksolidpro.com — GPS, trips, alarms, OBD
Ingestion (Python)ingest_movement · ingest_events · webhook_receiver
TimescaleDB + PostGISschema tracksolid — single source of truth
reporting.* read layerv_live_positions · v_trips (matview) · fn_* functions
dashboard_api (FastAPI)https://fleetapi.rahamafresh.com :8890
Map SPAs (rustfs/S3)liveposition · fleetintelligence

Grafana reads the same TimescaleDB directly via the tracksolid.v_* views (NOC + daily-ops dashboards).

2 · The n8n → fleetapi migration

The two map dashboards previously fetched data from n8n webhooks at https://automate.rahamafresh.com/webhook/…. n8n was only a thin HTTP→SQL proxy and a fragile link in the live-data path. It has been replaced by dashboard_api, a small FastAPI service that calls the proven reporting.* functions directly. The SPAs now point their N8N_BASE constant at https://fleetapi.rahamafresh.com; all webhook paths are unchanged, so the migration was a one-line front-end change per SPA plus the new service.

AspectBefore (n8n)After (fleetapi)
SPA base URLautomate.rahamafresh.comfleetapi.rahamafresh.com
Live Positions/webhook/live-positionssame path → reporting.fn_live_positions
Vehicle trail/webhook/live-positions/tracksame path (route alias added) → fn_vehicle_track
Fleet trips/webhook/fleet-dashboard (GET+POST)same paths → fn_trips_for_map
Transportn8n workflow + credentialsFastAPI + psycopg2 pool (shared with ingestion)
v_trips refreshn8n scheduled workflowdashboard_api background loop (every 5 min)
Cutover completed 2026-06-05. 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 (f1387d1); (2) the reporting.v_trips refresh — previously a scheduled n8n workflow — was moved into dashboard_api so the read layer keeps itself fresh (30b3515). See §4 and §7.

3 · Deployment topology

Host twala.rahamafresh.com (31.97.44.246, Hostinger VPS) running Coolify 4.1. The Tracksolid stack is a docker-compose application (container suffix bo3nov2ija7g8wn9b1g2paxs); the reverse proxy is Traefik on the coolify network with Let's Encrypt TLS.

ServiceRolePort / domain
timescale_dbPostgreSQL 16 + TimescaleDB 2.15 + PostGIS 35432 internal · 5433 host
ingest_movementGPS positions, trips, parking, track-list, device sync
ingest_eventsAlarm event polling
webhook_receiverPush receiver (/pushobd /pushevent /pushtripreport …)8888 (Traefik)
dashboard_apiMap read-API (replaces n8n)8890 → fleetapi.rahamafresh.com
grafanaNOC + daily-ops dashboards3000 → grafana.rahamafresh.com
pgbouncerConnection pooler (SCRAM via public.user_lookup)6432 internal
db_backuppg_dump → rustfs S3 (bucket fleet-db), scheduled

The two map front-ends are single-file SPAs stored as index.html objects in rustfs (S3) at s3.rahamafresh.com (buckets liveposition, fleetintelligence), each served by a small nginx proxy container. The dashboard_api enforces CORS for both SPA origins.

Operational note. dashboard_api currently runs as a standalone Traefik-labelled container reusing the app image with dashboard_api_rev.py bind-mounted. The durable form is the compose dashboard_api service (already in docker-compose.yaml) once the branch is merged and the fleetapi domain is set in Coolify.

4 · Read-API reference (dashboard_api)

Base: https://fleetapi.rahamafresh.com · all responses JSON · CORS limited to the two SPA origins.

MethodPathParamsReturnsNotes
GET/health{status: ok}Liveness probe.
GET/webhook/live-positionscost_centre?, acc_status?{summary, geojson}Live Positions map feed → reporting.fn_live_positions. ~80 vehicle point features.
GET/webhook/live-positions/trackvehicle_number, hours(1-24)GeoJSON Feature (LineString)One vehicle's recent trail. Alias: /webhook/vehicle-track.
GET/webhook/vehicle-trackvehicle_number, hoursGeoJSON FeatureAlias of live-positions/track (kept for compatibility).
GET/webhook/fleet-dashboard{drivers, cost_centres, cities, vehicles}Filter options for the Fleet Intelligence UI.
POST/webhook/fleet-dashboardform-urlencoded: period|start_date|end_date, vehicle_numbers, driver, cost_centre, assigned_citytrips GeoJSON payloadTrips for the map → reporting.fn_trips_for_map. period preset: today|7d|30d|custom. Body parsed by Content-Type — the SPA posts application/x-www-form-urlencoded; JSON also accepted.
Fix (2026-06-05). The POST handler originally read the body as JSON only, but the SPA sends x-www-form-urlencoded; the mismatch silently dropped every filter so the map always returned the whole fleet. Now parsed by Content-Type (parse_qs for form bodies). Commit f1387d1.

5 · Database schema

tracksolid · Live data — the single source of truth. Ingested from the Tracksolid API.

18 table(s) · 17 view(s) · 1 function(s) documented.

tracksolid.alarmstable344,356 rows

Alarm events (alarm_type, alarm_name, alarm_time).

ColumnTypeNullDefaultComment
idbigintNOT NULLnextval('alarms_id_seq'::regclass)
imeitext
alarm_typetext
alarm_timetimestamp with time zone
geomgeometry(Point,4326)
latdouble precision
lngdouble precision
speednumeric(7,2)
acc_statustext
updated_attimestamp with time zonenow()
alarm_nametext
sourcetext'poll'::text
severitytextAlarm severity level: critical | warning | info
geofence_idtextTracksolid geofence ID if this is a geofence alarm
geofence_nametextHuman-readable geofence name
acknowledged_attimestamp with time zoneTimestamp when alarm was acknowledged by an operator
acknowledged_bytextUsername or ID of operator who acknowledged the alarm
tracksolid.api_token_cachetable1 rows

OAuth2 token cache for the Jimi/Tracksolid API.

ColumnTypeNullDefaultComment
idbigintNOT NULLnextval('api_token_cache_id_seq'::regclass)
accounttextNOT NULL
access_tokentextNOT NULL
refresh_tokentext
app_keytext
expires_attimestamp with time zoneNOT NULL
obtained_attimestamp with time zoneNOT NULLnow()
updated_attimestamp with time zoneNOT NULLnow()
tracksolid.device_eventstable0 rows

Device network connection and disconnection events from /pushevent webhook.

ColumnTypeNullDefaultComment
idbigintNOT NULLnextval('device_events_id_seq'::regclass)
imeitextNOT NULL
event_typetextNOT NULLLOGIN = device connected to network; LOGOUT = device disconnected
event_timetimestamp with time zoneNOT NULL
timezonetext
created_attimestamp with time zoneNOT NULLnow()
tracksolid.devicestable181 rows

Device / driver / vehicle registry. One row per tracker (IMEI). Source of plate, driver, SIM, model.

ColumnTypeNullDefaultComment
imeitextNOT NULL
device_nametext
mc_typetext
mc_type_use_scopetext
vehicle_nametext
vehicle_numbertext
vehicle_modelstext
vehicle_icontext
vintext
engine_numbertext
vehicle_brandtext
fuel_100kmnumeric(6,2)
driver_nametext
driver_phonetext
simtext
iccidtext
imsitext
accounttext
customer_nametext
device_group_idtext
device_grouptext
activation_timetimestamp with time zone
expirationtimestamp with time zone
enabled_flagsmallintNOT NULL1
statustext'active'::text
citytext
current_mileage_kmnumeric(12,2)
created_attimestamp with time zoneNOT NULLnow()
updated_attimestamp with time zoneNOT NULLnow()
last_synced_attimestamp with time zone
vehicle_categorytextVehicle type: truck | van | motorcycle | car | other
cost_centretextBusiness unit or department this vehicle belongs to
assigned_routetextRegular route name or ID for route-based reporting
depot_geomgeometry(Point,4326)Home base/depot coordinates (WGS84)
depot_addresstextHuman-readable depot address
assigned_citytextOperating territory code: NBO (Nairobi) | MBA (Mombasa) | KLA (Kampala). Used for city-cohort analytics and geographic drift detection.
tracksolid.dispatch_logtable0 rows

Persistent record of every dispatch decision. Powers SLA metrics: dispatch latency, depart delay, time-to-site, wrench time.

ColumnTypeNullDefaultComment
dispatch_idbigintNOT NULLnextval('dispatch_log_dispatch_id_seq'::regclass)
ticket_idtextNOT NULL
imeitextNOT NULL
driver_nametext
job_latdouble precisionNOT NULL
job_lngdouble precisionNOT NULL
job_geomgeometry(Point,4326)
assigned_attimestamp with time zoneNOT NULLnow()
first_movement_attimestamp with time zoneFirst trip start after assigned_at. Back-filled nightly from trips.
on_site_attimestamp with time zoneTime vehicle entered 150 m radius of job_geom. Back-filled nightly.
resolved_attimestamp with time zoneTicket close time from the ops system (ops.tickets.closed_at).
cancelled_attimestamp with time zone
distance_kmnumeric(8,2)
created_attimestamp with time zoneNOT NULLnow()
tracksolid.fault_codestable0 rows

ColumnTypeNullDefaultComment
idbigintNOT NULLnextval('fault_codes_id_seq'::regclass)
imeitextNOT NULL
reported_attimestamp with time zoneNOT NULL
fault_codetextNOT NULL
status_flagsinteger
latdouble precision
lngdouble precision
geomgeometry(Point,4326)
event_timetimestamp with time zone
created_attimestamp with time zoneNOT NULLnow()
tracksolid.fuel_readingshypertable~0 rows

Fuel/oil sensor readings from /pushoil webhook. Unit varies per sensor: cm | % | V | L.

ColumnTypeNullDefaultComment
imeitextNOT NULL
reading_timetimestamp with time zoneNOT NULL
sensor_pathtextSensor channel identifier from the device (path field in API payload)
valuenumeric(10,3)
unittextMeasurement unit: cm (tank depth), % (percentage), V (voltage), L (litres)
latdouble precision
lngdouble precision
geomgeometry(Point,4326)
created_attimestamp with time zoneNOT NULLnow()
tracksolid.geofencestable0 rows

Geofence boundary definitions synced from the Tracksolid platform.

ColumnTypeNullDefaultComment
idbigintNOT NULLnextval('geofences_id_seq'::regclass)
fence_idtext
fence_nametextNOT NULL
fence_typetextcircle | polygon
geomgeometry(Geometry,4326)
radius_mnumeric(10,2)Radius in metres — only applicable for circle type geofences
descriptiontext
created_attimestamp with time zoneNOT NULLnow()
updated_attimestamp with time zoneNOT NULLnow()
tracksolid.heartbeatshypertable~0 rows

Device heartbeat hypertable.

ColumnTypeNullDefaultComment
imeitextNOT NULL
gate_timetimestamp with time zoneNOT NULL
power_levelsmallint
gsm_signalsmallint
acc_statussmallint
power_statussmallint
fortifysmallint
created_attimestamp with time zoneNOT NULLnow()
tracksolid.ingestion_logtable274,181 rows

API call audit trail — one row per ingestion run.

ColumnTypeNullDefaultComment
idbigintNOT NULLnextval('ingestion_log_id_seq'::regclass)
run_attimestamp with time zoneNOT NULLnow()
endpointtextNOT NULL
imei_countintegerNOT NULL0
rows_upsertedintegerNOT NULL0
rows_insertedintegerNOT NULL0
duration_msintegerNOT NULL0
successbooleanNOT NULLtrue
error_codetext
error_messagetext
tracksolid.lbs_readingstable0 rows

Cell tower / WiFi positioning fallback data from /pushlbs webhook. Used when GPS signal is unavailable.

ColumnTypeNullDefaultComment
idbigintNOT NULLnextval('lbs_readings_id_seq'::regclass)
imeitextNOT NULL
gate_timetimestamp with time zoneNOT NULL
post_typetextPositioning technology: WIFI | LBS (cell tower)
lbs_datajsonbRaw JSON payload containing MCC, MNC, and cell tower list for approximate geocoding.
created_attimestamp with time zoneNOT NULLnow()
tracksolid.live_positionstable179 rows

Latest fix per IMEI, refreshed every 60s by ingest_movement. Feeds reporting.v_live_positions.

ColumnTypeNullDefaultComment
imeitextNOT NULL
geomgeometry(Point,4326)
latdouble precision
lngdouble precision
pos_typetext
confidencesmallint
gps_timetimestamp with time zone
hb_timetimestamp with time zone
speednumeric(7,2)
directionnumeric(6,2)
acc_statustext
gps_signalsmallint
gps_numsmallint
elec_quantitynumeric(5,2)
power_valuenumeric(5,2)
battery_power_valnumeric(5,2)
tracker_oiltext
temperaturenumeric(8,2)
current_mileagenumeric(12,2)
device_statustext
expire_flagtext
activation_flagtext
loc_desctext
recorded_attimestamp with time zoneNOT NULLnow()
updated_attimestamp with time zoneNOT NULLnow()
tracksolid.obd_readingstable0 rows

OBD diagnostics — push only via /pushobd webhook.

ColumnTypeNullDefaultComment
idbigintNOT NULLnextval('obd_readings_id_seq'::regclass)
imeitext
reading_timetimestamp with time zone
engine_rpmintegerEngine RPM from OBD PID 0x0C
fuel_level_pctnumeric(5,2)Fuel tank level % from OBD PID 0x2F
updated_attimestamp with time zonenow()
car_typesmallint
acc_statesmallint
status_flagsinteger
latdouble precision
lngdouble precision
geomgeometry(Point,4326)
obd_datajsonbRaw obdJson from Jimi push. Contains dataID1..N fields (engine RPM, coolant temp, fuel level, etc.)
coolant_temp_cnumeric(6,2)Coolant temperature °C from OBD PID 0x05
battery_voltagenumeric(5,2)Battery voltage (V) from OBD PID 0x42
intake_pressurenumeric(6,2)Intake manifold pressure kPa from OBD PID 0x0B
throttle_pctnumeric(5,2)Throttle position % from OBD PID 0x11
vehicle_speednumeric(7,2)Vehicle speed km/h from OBD PID 0x0D
engine_load_pctnumeric(5,2)Calculated engine load % from OBD PID 0x04
tracksolid.parking_eventstable0 rows

Stop events with duration + address.

ColumnTypeNullDefaultComment
idbigintNOT NULLnextval('parking_events_id_seq'::regclass)
imeitextNOT NULL
event_typetext
start_timetimestamp with time zoneNOT NULL
end_timetimestamp with time zone
duration_secondsinteger
geomgeometry(Point,4326)
addresstext
updated_attimestamp with time zonenow()
tracksolid.position_historyhypertable~3,596,013 rows

All GPS fixes (hypertable, partitioned by gps_time). source='poll' (60s) or 'track_list' (30m high-res).

ColumnTypeNullDefaultComment
imeitextNOT NULL
gps_timetimestamp with time zoneNOT NULL
geomgeometry(Point,4326)
latdouble precision
lngdouble precision
speednumeric(7,2)
directionnumeric(6,2)
acc_statustext
satellitesmallint
current_mileagenumeric(12,2)
recorded_attimestamp with time zonenow()
altitudenumeric(8,2)
post_typesmallint
sourcetext'poll'::text
tracksolid.schema_migrationstable9 rows

ColumnTypeNullDefaultComment
filenametextNOT NULL
applied_attimestamp with time zoneNOT NULLnow()
tracksolid.temperature_readingshypertable~0 rows

Temperature and humidity sensor readings from /pushtem webhook. For cold-chain / refrigerated cargo monitoring.

ColumnTypeNullDefaultComment
imeitextNOT NULL
reading_timetimestamp with time zoneNOT NULL
temperaturenumeric(6,2)
humidity_pctnumeric(5,2)
created_attimestamp with time zoneNOT NULLnow()
tracksolid.tripstable43,765 rows

Trip summaries: distance_km, driving time, avg/max speed, route geometry + addresses (FIX-M20).

ColumnTypeNullDefaultComment
idbigintNOT NULLnextval('trips_id_seq'::regclass)
imeitextNOT NULL
start_timetimestamp with time zoneNOT NULL
end_timetimestamp with time zone
start_geomgeometry(Point,4326)
end_geomgeometry(Point,4326)
distance_kmnumeric(12,2)Trip distance in kilometres. Corrected from mm storage on migration 04 (2026-04-10).
avg_speed_kmhnumeric(7,2)
max_speed_kmhnumeric(7,2)
updated_attimestamp with time zonenow()
fuel_consumed_lnumeric(8,2)
idle_time_sinteger
driving_time_sintegerrunTimeSecond from API: total driving time in seconds
trip_seqinteger
sourcetext'poll'::textpoll = from API polling, push = from webhook push
route_geomgeometry(LineString,4326)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.
start_addresstextReverse-geocoded human-readable address near start_geom (Nominatim). NULL on lookup failure; address is best-effort, not authoritative.
end_addresstextReverse-geocoded human-readable address near end_geom (Nominatim). NULL on lookup failure; address is best-effort, not authoritative.
vehicle_platetextDenormalised tracksolid.devices.vehicle_number cached at trip-insert time. Avoids a join for trip displays; refreshed only on next ingest.
waypoints_countintegerNumber of position_history fixes that contributed to route_geom. Audit aid: 0 or 1 means route_geom is NULL or degenerate.
tracksolid.v_active_dispatch_mapview

01_BusinessAnalytics.md §4.3 All Active Vehicles Map. Geomap source.

ColumnTypeNullDefaultComment
imeitext
vehicle_numbertext
vehicle_nametext
driver_nametext
driver_phonetext
assigned_citytext
latdouble precision
lngdouble precision
speednumeric(7,2)
directionnumeric(6,2)
acc_statustext
last_fixtimestamp without time zone
statustext
tracksolid.v_alarms_dailyview

01_BusinessAnalytics.md §7 Panel 7 Alarm Frequency. Stacked-by-alarm_name time series.

ColumnTypeNullDefaultComment
daydate
alarm_nametext
alarm_countbigint
tracksolid.v_currently_idleview

01_BusinessAnalytics.md §2.2 idle lens. Engine on, speed <2 km/h, fix in last 15m.

ColumnTypeNullDefaultComment
imeitext
vehicle_numbertext
driver_nametext
assigned_citytext
latdouble precision
lngdouble precision
sincetimestamp without time zone
idle_secondsinteger
tracksolid.v_driver_aggregates_dailyview

01_BusinessAnalytics.md §3.1 (speeding) + §3.2 (harsh driving). Daily grain; panels window via $__timeFilter(day).

ColumnTypeNullDefaultComment
imeitext
driver_nametext
vehicle_numbertext
assigned_citytext
daydate
kmnumeric
tripsbigint
events_80bigint
events_100bigint
events_120bigint
harsh_eventsbigint
speeding_per_100kmnumeric
harsh_per_100kmnumeric
tracksolid.v_driver_attendance_dailyview

ColumnTypeNullDefaultComment
report_datedate
driver_nametext
vehicle_numbertext
cost_centretext
assigned_citytext
reporting_timetime without time zone
start_addresstext
start_latdouble precision
start_lngdouble precision
statustext
mins_from_startinteger
tracksolid.v_driver_clock_dailyview

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).

ColumnTypeNullDefaultComment
imeitext
driver_nametext
vehicle_numbertext
cost_centretext
assigned_citytext
report_datedate
reporting_timetime without time zone
closing_timetime without time zone
reporting_tstimestamp with time zone
closing_tstimestamp with time zone
start_latdouble precision
start_lngdouble precision
start_addresstext
end_latdouble precision
end_lngdouble precision
end_addresstext
trips_countbigint
total_kmnumeric
drive_hoursnumeric
tracksolid.v_driver_clock_todayview

Today snapshot of v_driver_clock_daily, filtered to (NOW() AT TIME ZONE 'Africa/Nairobi')::date. Refreshes as trips land throughout the day.

ColumnTypeNullDefaultComment
imeitext
driver_nametext
vehicle_numbertext
cost_centretext
assigned_citytext
report_datedate
reporting_timetime without time zone
closing_timetime without time zone
reporting_tstimestamp with time zone
closing_tstimestamp with time zone
start_latdouble precision
start_lngdouble precision
start_addresstext
end_latdouble precision
end_lngdouble precision
end_addresstext
trips_countbigint
total_kmnumeric
drive_hoursnumeric
tracksolid.v_fleet_km_dailyview

01_BusinessAnalytics.md §7 Panel 5 Distance Trend. City-cohort cut built in.

ColumnTypeNullDefaultComment
daydate
assigned_citytext
kmnumeric
active_vehiclesbigint
tripsbigint
tracksolid.v_fleet_statusview

ColumnTypeNullDefaultComment
imeitext
vehicle_numbertext
driver_nametext
latdouble precision
lngdouble precision
geomgeometry(Point,4326)
speednumeric(7,2)
acc_statustext
gps_timetimestamp with time zone
connectivity_statustext
seconds_since_fixinteger
tracksolid.v_fleet_todayview

01_BusinessAnalytics.md §9 Fleet Readiness Scorecard. One row per device with today's roll-up.

ColumnTypeNullDefaultComment
imeitext
driver_nametext
vehicle_numbertext
vehicle_nametext
assigned_citytext
enabled_flagsmallint
km_todaynumeric
trips_todaybigint
drive_hoursnumeric
idle_hoursnumeric
first_departuretime without time zone
last_returntime without time zone
alarms_todaybigint
last_fixtimestamp without time zone
last_speednumeric(7,2)
did_not_moveboolean
tracksolid.v_fleet_traceview

ColumnTypeNullDefaultComment
gidbigint
driver_nametext
vehicle_nametext
device_nametext
imeitext
geomgeometry(Point,4326)
latnumeric
lngnumeric
start_timetimestamp without time zone
end_timetimestamp without time zone
day_localdate
hour_localinteger
dow_localinteger
gps_time_utctimestamp with time zone
recorded_attimestamp with time zone
speednumeric(7,2)
directionnumeric(6,2)
current_mileagenumeric(12,2)
stationaryboolean
trip_idbigint
tracksolid.v_ingestion_healthview

ColumnTypeNullDefaultComment
endpointtext
run_attimestamp with time zone
successboolean
error_messagetext
seconds_agointeger
tracksolid.v_mileage_daily_caggview

ColumnTypeNullDefaultComment
buckettimestamp with time zone
imeitext
dist_kmnumeric
avg_speednumeric
tracksolid.v_sla_inflightview

01_BusinessAnalytics.md §4.5 Field-Service SLA Metrics. Open tickets + last 24h resolved.

ColumnTypeNullDefaultComment
ticket_idtext
customertext
prioritytext
job_typetext
statustext
created_attimestamp with time zone
assigned_attimestamp with time zone
closed_attimestamp with time zone
assigned_imeitext
driver_nametext
first_movement_attimestamp with time zone
on_site_attimestamp with time zone
resolved_attimestamp with time zone
dispatch_minsnumeric
enroute_minsnumeric
onsite_minsnumeric
resolution_minsnumeric
ticket_stagetext
tracksolid.v_trips_enrichedview

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.

ColumnTypeNullDefaultComment
idbigint
imeitext
start_timetimestamp with time zone
end_timetimestamp with time zone
start_geomgeometry(Point,4326)
end_geomgeometry(Point,4326)
distance_kmnumeric(12,2)
avg_speed_kmhnumeric(7,2)
max_speed_kmhnumeric(7,2)
updated_attimestamp with time zone
fuel_consumed_lnumeric(8,2)
idle_time_sinteger
driving_time_sinteger
trip_seqinteger
sourcetext
route_geomgeometry(LineString,4326)
start_addresstext
end_addresstext
vehicle_platetext
waypoints_countinteger
trip_date_eatdate
daily_seqbigint
tracksolid.v_utilisation_dailyview

01_BusinessAnalytics.md §7 Panel 8 Utilisation Heatmap. Empty until nightly ETL runs.

ColumnTypeNullDefaultComment
daydate
imeitext
vehicle_numbertext
driver_nametext
assigned_citytext
total_distance_kmnumeric(12,2)
total_drive_hoursnumeric(8,2)
total_idle_hoursnumeric(8,2)
alarm_countinteger
overspeed_countinteger
utilisation_pctnumeric
tracksolid.v_vehicles_not_moved_todayview

01_BusinessAnalytics.md §2.3. Enabled vehicles with zero trips today.

ColumnTypeNullDefaultComment
imeitext
vehicle_nametext
vehicle_numbertext
driver_nametext
assigned_citytext
last_seentimestamp without time zone
speednumeric(7,2)
tracksolid.set_updated_at(…)function · plpgsql

arguments()
returnstrigger

reporting · Read layer that backs the map dashboards (consumed by dashboard_api).

2 table(s) · 12 view(s) · 4 function(s) documented.

reporting.refresh_logtable3,558 rows

One row per REFRESH MATERIALIZED VIEW CONCURRENTLY reporting.v_trips. Written by dashboard_api's built-in refresher (source='dashboard_api', every 5 min); the retired n8n job (source='n8n') was the previous writer. Read MAX(refreshed_at) for staleness.

ColumnTypeNullDefaultComment
refreshed_attimestamp with time zoneNOT NULLnow()
sourcetextNOT NULL'n8n'::text
duration_msinteger
row_countinteger
notestext
reporting.v_tripsmatview31,670 rows

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.

ColumnTypeNullDefaultComment
trip_idbigint
imeitext
device_nametext
vehicle_numbertext
vehicle_modelstext
vehicle_categorytext
cost_centretext
assigned_citytext
assigned_drivertext
start_timetimestamp without time zone
end_timetimestamp without time zone
trip_datedate
start_hourinteger
start_dowinteger
daily_seqbigint
distance_kmnumeric(12,2)
avg_speed_kmhnumeric(7,2)
max_speed_kmhnumeric(7,2)
idle_time_sinteger
driving_time_sinteger
fuel_consumed_lnumeric(8,2)
waypoints_countinteger
start_addresstext
end_addresstext
start_geomgeometry(Point,4326)
end_geomgeometry(Point,4326)
route_geomgeometry(LineString,4326)
route_geojsonjson
is_meaningful_routeboolean
updated_attimestamp without time zone
reporting.v_daily_cost_centreview

Cost-centre × day rollup. Excludes trips with NULL cost_centre.

ColumnTypeNullDefaultComment
trip_datedate
cost_centretext
active_vehiclesbigint
active_driversbigint
trip_countbigint
total_kmnumeric
driving_hoursnumeric
idle_hoursnumeric
idle_pctnumeric
km_per_vehiclenumeric
reporting.v_daily_summaryview

Vehicle × day rollup. Filtered by is_meaningful_route. day_routes_geojson is the daily multi-line geometry for long-range Kepler.gl fallback.

ColumnTypeNullDefaultComment
trip_datedate
cost_centretext
assigned_citytext
vehicle_numbertext
assigned_drivertext
trip_countbigint
total_kmnumeric
driving_hoursnumeric
idle_hoursnumeric
idle_pctnumeric
first_trip_starttimestamp without time zone
last_trip_endtimestamp without time zone
avg_speed_kmhnumeric
max_speed_kmhnumeric
day_routes_geojsonjson
reporting.v_filter_citiesview

Assigned-city dropdown source for the n8n dashboard. Distinct non-null cities.

ColumnTypeNullDefaultComment
assigned_citytext
reporting.v_filter_cost_centresview

Cost-centre dropdown source for the n8n dashboard. Distinct non-null centres.

ColumnTypeNullDefaultComment
cost_centretext
reporting.v_filter_driversview

Driver dropdown source for the n8n dashboard. Distinct non-null drivers.

ColumnTypeNullDefaultComment
drivertext
reporting.v_filter_vehiclesview

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.

ColumnTypeNullDefaultComment
vehicle_numbertext
driverstext
cost_centretext
assigned_citytext
reporting.v_live_positionsview

Latest known fix per vehicle, deduped to one primary IMEI per normalised plate. Provenance: 260521_liveposition_deployment.md §Phase 1.

ColumnTypeNullDefaultComment
imeitext
vehicle_numbertext
assigned_drivertext
cost_centretext
assigned_citytext
vehicle_categorytext
vehicle_modelstext
mc_typetext
device_kindtext
latdouble precision
lngdouble precision
speednumeric(7,2)
directionnumeric(6,2)
acc_statustext
device_statustext
gps_signalsmallint
gps_numsmallint
current_mileagenumeric(12,2)
loc_desctext
gps_timetimestamp with time zone
updated_attimestamp with time zone
gps_time_eattimestamp without time zone
updated_at_eattimestamp without time zone
source_age_hoursnumeric
reporting.v_monthly_cost_centreview

Cost-centre × month rollup. Executive grain. Excludes trips with NULL cost_centre.

ColumnTypeNullDefaultComment
month_startdate
month_labeltext
cost_centretext
active_vehiclesbigint
active_driversbigint
active_daysbigint
trip_countbigint
total_kmnumeric
driving_hoursnumeric
idle_hoursnumeric
idle_pctnumeric
km_per_vehiclenumeric
reporting.v_monthly_summaryview

Vehicle × month rollup with trend metrics (km_per_active_day, km_per_trip).

ColumnTypeNullDefaultComment
month_startdate
month_labeltext
cost_centretext
assigned_citytext
vehicle_categorytext
vehicle_numbertext
assigned_drivertext
trip_countbigint
active_daysbigint
total_kmnumeric
driving_hoursnumeric
idle_hoursnumeric
idle_pctnumeric
km_per_active_daynumeric
km_per_tripnumeric
avg_speed_kmhnumeric
peak_speed_kmhnumeric
reporting.v_trips_todayview

Today snapshot of reporting.v_trips, filtered to (NOW() AT TIME ZONE 'Africa/Nairobi')::date. Refreshes as trips land throughout the day.

ColumnTypeNullDefaultComment
trip_idbigint
imeitext
device_nametext
vehicle_numbertext
vehicle_modelstext
vehicle_categorytext
cost_centretext
assigned_citytext
assigned_drivertext
start_timetimestamp without time zone
end_timetimestamp without time zone
trip_datedate
start_hourinteger
start_dowinteger
daily_seqbigint
distance_kmnumeric(12,2)
avg_speed_kmhnumeric(7,2)
max_speed_kmhnumeric(7,2)
idle_time_sinteger
driving_time_sinteger
fuel_consumed_lnumeric(8,2)
waypoints_countinteger
start_addresstext
end_addresstext
start_geomgeometry(Point,4326)
end_geomgeometry(Point,4326)
route_geomgeometry(LineString,4326)
route_geojsonjson
is_meaningful_routeboolean
updated_attimestamp without time zone
reporting.v_weekly_cost_centreview

Cost-centre × week rollup. Excludes trips with NULL cost_centre.

ColumnTypeNullDefaultComment
week_startdate
cost_centretext
active_vehiclesbigint
active_driversbigint
active_daysbigint
trip_countbigint
total_kmnumeric
driving_hoursnumeric
idle_hoursnumeric
idle_pctnumeric
km_per_vehiclenumeric
reporting.v_weekly_summaryview

Vehicle × week rollup. Numeric only, no geometry.

ColumnTypeNullDefaultComment
week_startdate
cost_centretext
assigned_citytext
vehicle_numbertext
assigned_drivertext
trip_countbigint
active_daysbigint
total_kmnumeric
driving_hoursnumeric
idle_hoursnumeric
avg_trip_kmnumeric
reporting.fn_live_positions(…)function · plpgsql

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.

argumentsp_cost_centre text DEFAULT NULL::text, p_acc_status text DEFAULT NULL::text
returnsjsonb
reporting.fn_trips_for_map(…)function · plpgsql

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.

argumentsp_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
returnsjsonb
reporting.fn_vehicle_track(…)function · sql

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.

argumentsp_vehicle_number text, p_hours integer DEFAULT 1
returnsjsonb
reporting.normalize_plate(…)function · sql

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.

argumentsp text
returnstext

ops · Workshop / tickets / odometer integrations.

5 table(s) · 1 view(s) · 0 function(s) documented.

ops.cost_ratestable3 rows

Reference rates for analytics monetisation: fuel price per litre by city, labour cost per hour by role. Resolution order in views: scope_type=city > scope_type=role > scope_type=global.

ColumnTypeNullDefaultComment
rate_keytextNOT NULL
scope_typetextNOT NULLcity | role | global
scope_valuetext
metrictextNOT NULLfuel_per_litre | labour_per_hour
amountnumeric(12,2)NOT NULL
currencytextNOT NULL
effective_fromdateNOT NULLCURRENT_DATE
notestext
created_attimestamp with time zoneNOT NULLnow()
updated_attimestamp with time zoneNOT NULLnow()
ops.kpi_targetstable12 rows

Traffic-light targets per KPI per scope. Resolution order in views: cost_centre > vehicle_category > city > global.

ColumnTypeNullDefaultComment
target_idbigintNOT NULLnextval('ops.kpi_targets_target_id_seq'::regclass)
kpi_keytextNOT NULL
scope_typetextNOT NULL
scope_valuetext
target_valuenumeric(12,2)NOT NULL
amber_thresholdnumeric(12,2)
red_thresholdnumeric(12,2)
directiontextNOT NULL'higher_is_better'::texthigher_is_better -> green when value >= target. lower_is_better -> green when value <= target.
effective_fromdateNOT NULLCURRENT_DATE
notestext
created_attimestamp with time zoneNOT NULLnow()
updated_attimestamp with time zoneNOT NULLnow()
ops.odometer_readingstable0 rows

Physical odometer captures from service, fuel card, or manual entry. Powers §3.8 Odometer Divergence audit.

ColumnTypeNullDefaultComment
reading_idbigintNOT NULLnextval('ops.odometer_readings_reading_id_seq'::regclass)
imeitextNOT NULL
reading_datedateNOT NULL
reading_kmintegerNOT NULL
sourcetextservice | fuel_card | driver_manual | workshop_form
recorded_bytext
created_attimestamp with time zoneNOT NULLnow()
ops.service_logtable0 rows

Workshop service history. Powers §10 Service-Interval Forecaster.

ColumnTypeNullDefaultComment
service_idbigintNOT NULLnextval('ops.service_log_service_id_seq'::regclass)
imeitextNOT NULL
service_datedateNOT NULL
odometer_kmintegerNOT NULLPhysical odometer reading at service time (integer km).
service_typetextscheduled | repair | tyre | bodywork | inspection | other
cost_kesinteger
notestext
created_attimestamp with time zoneNOT NULLnow()
ops.ticketstable0 rows

Skeleton for ticket data sourced from the Fireside ops system. Replace or extend to match the actual feed (Zoho Desk, Freshdesk, etc).

ColumnTypeNullDefaultComment
ticket_idtextNOT NULL
assigned_imeitext
driver_nametext
customertext
job_typetext
prioritytext
statustextNOT NULL'open'::textopen | assigned | in_progress | resolved | cancelled
created_attimestamp with time zoneNOT NULL
assigned_attimestamp with time zone
closed_attimestamp with time zone
job_latdouble precision
job_lngdouble precision
job_geomgeometry(Point,4326)
ingested_attimestamp with time zoneNOT NULLnow()
ops.vw_service_forecastview

Projected next-service date per vehicle based on 30-day km rate. Service interval default 10,000 km — override at query time if needed.

ColumnTypeNullDefaultComment
imeitext
driver_nametext
vehicle_numbertext
last_service_datedate
last_service_odointeger
current_odonumeric(12,2)
km_since_servicenumeric
km_to_next_servicenumeric
km_per_day_30dnumeric
projected_service_datedate

dwh_gold · Nightly ETL aggregates.

2 table(s) · 0 view(s) · 1 function(s) documented.

dwh_gold.dim_vehiclestable0 rows

ColumnTypeNullDefaultComment
vehicle_keyintegerNOT NULLnextval('dim_vehicles_vehicle_key_seq'::regclass)
imeitext
vehicle_numbertext
is_activebooleantrue
dwh_gold.fact_daily_fleet_metricstable0 rows

ColumnTypeNullDefaultComment
daydateNOT NULL
vehicle_keyintegerNOT NULL
total_distance_kmnumeric(12,2)Total km driven that day across all trips
max_speed_kmhnumeric(7,2)
idle_hoursnumeric(5,2)
total_tripsintegerNumber of completed trips
total_drive_hoursnumeric(8,2)Total hours of active driving (engine on + moving)
total_idle_hoursnumeric(8,2)Total hours engine on but stationary
fuel_consumed_lnumeric(10,3)Total fuel consumed in litres (from webhook trip reports)
alarm_countintegerTotal alarm events triggered that day
overspeed_countintegerNumber of overspeed alarm events
day_start_timetime without time zoneTime of first trip start (Africa/Nairobi)
day_end_timetime without time zoneTime of last trip end (Africa/Nairobi)
avg_speed_kmhnumeric(7,2)Fleet average speed across all trips that day
peak_speed_kmhnumeric(7,2)Highest max_speed_kmh recorded across all trips
dwh_gold.refresh_daily_metrics(…)function · plpgsql

Populates or refreshes fact_daily_fleet_metrics for the given date. Call nightly: SELECT dwh_gold.refresh_daily_metrics(CURRENT_DATE - 1);

argumentstarget_date date
returnsvoid

public · Extension objects + pgbouncer auth helper.

1 table(s) · 3 view(s) · 1 function(s) documented.

public.spatial_ref_systable8,500 rows

ColumnTypeNullDefaultComment
sridintegerNOT NULL
auth_namecharacter varying(256)
auth_sridinteger
srtextcharacter varying(2048)
proj4textcharacter varying(2048)
public.geography_columnsview

ColumnTypeNullDefaultComment
f_table_catalogname
f_table_schemaname
f_table_namename
f_geography_columnname
coord_dimensioninteger
sridinteger
typetext
public.geometry_columnsview

ColumnTypeNullDefaultComment
f_table_catalogcharacter varying(256)
f_table_schemaname
f_table_namename
f_geometry_columnname
coord_dimensioninteger
sridinteger
typecharacter varying(30)
public.trips_viz_v1view

ColumnTypeNullDefaultComment
trip_idbigint
imeitext
vehicle_nametext
vehicle_numbertext
cost_centretext
start_timetimestamp with time zone
end_timetimestamp with time zone
distance_kmnumeric(12,2)
avg_speed_kmhnumeric(7,2)
max_speed_kmhnumeric(7,2)
vehicle_platetext
start_addresstext
end_addresstext
waypoints_countinteger
driving_time_sinteger
idle_time_sinteger
fuel_consumed_lnumeric(8,2)
trip_date_eatdate
daily_seqbigint
public.user_lookup(…)function · plpgsql

pgbouncer SCRAM auth_query — returns (username, password-hash) for connection pooling.

argumentsin_user text, OUT uname text, OUT phash text
returnsrecord

6 · Grafana dashboards

Grafana is provisioned via a baked image and reads TimescaleDB directly (read-only role grafana_ro), mostly through the tracksolid.v_* analytics views documented in §5. Two dashboards ship with the stack.

NOC Fleet Operations — Live · uid noc-fleet-live · 9 panels

SectionPanelTypeSource view / table
Total Vehiclesstattracksolid.devices
Online Nowstattracksolid.v_fleet_status
Recent (5-30 min)stattracksolid.v_fleet_status
Offlinestattracksolid.v_fleet_status
Moving Nowstattracksolid.v_fleet_status
Avg Speed (km/h)stattracksolid.v_fleet_status
Live Vehicle Locationsgeomaptracksolid.devices, tracksolid.live_positions
Vehicle Statustabletracksolid.devices, tracksolid.live_positions
Ingestion Healthtabletracksolid.v_ingestion_health

Daily Operations — Fleet & Dispatch · uid daily-ops · 21 panels

SectionPanelTypeSource view / table
Last GPS Fix (fleet)stattracksolid.live_positions
Vehicles reporting todaystattracksolid.v_fleet_today
Fleet km todaystattracksolid.v_fleet_today
Drive hours todaystattracksolid.v_fleet_today
Idle hours todaystattracksolid.v_fleet_today
Open alarms (24h)stattracksolid.alarms
In-flight SLA jobsstattracksolid.v_sla_inflight
Active Vehicles Mapgeomaptracksolid.v_active_dispatch_map
Currently Idle (engine on, speed < 2)tabletracksolid.v_currently_idle
Vehicles Not Moved Todaytabletracksolid.v_vehicles_not_moved_today
Per-Vehicle Daily Roll-uptabletracksolid.v_fleet_today
Driver Leaderboardtabletracksolid.v_driver_aggregates_daily
Fleet Distance — 7-day (by city)timeseriestracksolid.v_fleet_km_daily
Alarm Frequency — 30-day (by type)timeseriestracksolid.v_alarms_daily
Idle Cost (month-to-date)stattracksolid.v_utilisation_daily
Utilisation Heatmap (30-day)heatmaptracksolid.v_utilisation_daily
Row 7 — Field-Service SLAs (data-gated)Dispatch SLA (median mins, 24h)stattracksolid.v_sla_inflight
En-route SLA (median mins, 24h)stattracksolid.v_sla_inflight
On-site SLA (median mins, 24h)stattracksolid.v_sla_inflight
Resolution SLA (median mins, 24h)stattracksolid.v_sla_inflight
At-risk ticketstabletracksolid.v_sla_inflight

SLA panels (v_sla_inflight) and the utilisation heatmap (v_utilisation_daily) are data-gated on the ops ticket integration and nightly dwh_gold ETL respectively.

7 · Operational notes

See also: docs/CONNECTIONS.md, docs/reference/01_BusinessAnalytics.md, docs/manuals/OPERATIONS_MANUAL.md, and the project CLAUDE.md.