tracksolid_timescale_grafan.../10_driver_clock_views.sql

112 lines
5.6 KiB
MySQL
Raw Normal View History

-- 10_driver_clock_views.sql
-- Driver clock-in / clock-out views for n8n tardiness + working-hours monitoring.
--
-- Two views, both keyed by IMEI per local Africa/Nairobi date:
-- • v_driver_clock_daily — historical, one row per IMEI per day with activity
-- • v_driver_clock_today — thin pass-through filtered to today (EAT)
--
-- The view exposes raw times, locations, and addresses; n8n owns tardiness
-- thresholds and cost-centre filtering. Closing time is the latest end_time
-- of any trip whose start_time falls on the local Nairobi date — kept lossless
-- so n8n can detect midnight crossings via reporting_ts/closing_ts.
--
-- Reuses:
-- • tracksolid.trips.distance_km (renamed in migration 04)
-- • tracksolid.trips.driving_time_s (referenced in migration 05)
-- • tracksolid.trips.start_geom/end_geom (migration 02 §3.06)
-- • tracksolid.trips.start_address/end_address (migration 09 — Nominatim)
--
-- Pattern follows 07_analytics_views.sql: regular views (not materialised),
-- COMMENT ON VIEW with provenance, GRANT SELECT TO grafana_ro.
BEGIN;
-- ─────────────────────────────────────────────────────────────────────────────
-- v_driver_clock_daily
-- One row per IMEI per local Africa/Nairobi date with at least one trip.
-- ─────────────────────────────────────────────────────────────────────────────
CREATE OR REPLACE VIEW tracksolid.v_driver_clock_daily AS
WITH daily_agg AS (
SELECT
t.imei,
(t.start_time AT TIME ZONE 'Africa/Nairobi')::date AS report_date,
MIN(t.start_time) AS reporting_ts,
MAX(t.end_time) AS closing_ts,
COUNT(*) AS trips_count,
SUM(t.distance_km) AS total_km,
SUM(t.driving_time_s)::numeric / 3600 AS drive_hours
FROM tracksolid.trips t
GROUP BY t.imei, (t.start_time AT TIME ZONE 'Africa/Nairobi')::date
),
start_row AS (
SELECT DISTINCT ON (t.imei, (t.start_time AT TIME ZONE 'Africa/Nairobi')::date)
t.imei,
(t.start_time AT TIME ZONE 'Africa/Nairobi')::date AS report_date,
ST_Y(t.start_geom::geometry) AS start_lat,
ST_X(t.start_geom::geometry) AS start_lng,
t.start_address AS start_address
FROM tracksolid.trips t
ORDER BY t.imei, (t.start_time AT TIME ZONE 'Africa/Nairobi')::date, t.start_time ASC
),
end_row AS (
SELECT DISTINCT ON (t.imei, (t.start_time AT TIME ZONE 'Africa/Nairobi')::date)
t.imei,
(t.start_time AT TIME ZONE 'Africa/Nairobi')::date AS report_date,
ST_Y(t.end_geom::geometry) AS end_lat,
ST_X(t.end_geom::geometry) AS end_lng,
t.end_address AS end_address
FROM tracksolid.trips t
ORDER BY t.imei, (t.start_time AT TIME ZONE 'Africa/Nairobi')::date, t.end_time DESC NULLS LAST
)
SELECT
a.imei,
d.driver_name,
d.vehicle_number,
d.cost_centre,
COALESCE(d.assigned_city, d.city, 'unassigned') AS assigned_city,
a.report_date,
(a.reporting_ts AT TIME ZONE 'Africa/Nairobi')::time AS reporting_time,
(a.closing_ts AT TIME ZONE 'Africa/Nairobi')::time AS closing_time,
a.reporting_ts,
a.closing_ts,
s.start_lat,
s.start_lng,
s.start_address,
e.end_lat,
e.end_lng,
e.end_address,
a.trips_count,
a.total_km,
a.drive_hours
FROM daily_agg a
LEFT JOIN start_row s ON s.imei = a.imei AND s.report_date = a.report_date
LEFT JOIN end_row e ON e.imei = a.imei AND e.report_date = a.report_date
LEFT JOIN tracksolid.devices d ON d.imei = a.imei;
COMMENT ON VIEW tracksolid.v_driver_clock_daily IS
'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).';
GRANT SELECT ON tracksolid.v_driver_clock_daily TO grafana_ro;
-- ─────────────────────────────────────────────────────────────────────────────
-- v_driver_clock_today
-- Pass-through filter: today's row from v_driver_clock_daily.
-- ─────────────────────────────────────────────────────────────────────────────
CREATE OR REPLACE VIEW tracksolid.v_driver_clock_today AS
SELECT *
FROM tracksolid.v_driver_clock_daily
WHERE report_date = (NOW() AT TIME ZONE 'Africa/Nairobi')::date;
COMMENT ON VIEW tracksolid.v_driver_clock_today IS
'Today snapshot of v_driver_clock_daily, filtered to (NOW() AT TIME ZONE '
'''Africa/Nairobi'')::date. Refreshes as trips land throughout the day.';
GRANT SELECT ON tracksolid.v_driver_clock_today TO grafana_ro;
COMMIT;