-- 15_map_exclude_cost_centres.sql -- Hide non-operational vehicles from the LIVE tracking map (FleetNow + liveposition SPA). -- -- A small, ops-editable config table lists the cost centres to exclude. reporting.v_live_positions -- (the base view behind reporting.fn_live_positions, which dashboard_api serves) filters out any -- plate whose device(s) carry an excluded cost centre. Editing the table changes the map on the -- next query — no code change, no redeploy. -- -- Scope: LIVE map only. Trip history (reporting.v_trips materialised view) is deliberately NOT -- touched. Initial exclusions: personal + management (staff/personal cars) and mtn (the MTN -- contract / Uganda-Kampala fleet, outside Kenyan ops). -- -- The v_live_positions body below is reproduced verbatim from the live prod definition -- (== migrations/11_reporting_schema.sql) with a single added filter in the primary_device CTE. -- Safe to re-apply (CREATE TABLE IF NOT EXISTS / INSERT ON CONFLICT / CREATE OR REPLACE VIEW). SET search_path = tracksolid, reporting, public; -- ── exclusion config (data-driven, editable without a migration) ────────────── CREATE TABLE IF NOT EXISTS reporting.map_excluded_cost_centres ( cost_centre text PRIMARY KEY, -- compared case-insensitively (store lowercase) note text, added_at timestamptz NOT NULL DEFAULT now() ); INSERT INTO reporting.map_excluded_cost_centres (cost_centre, note) VALUES ('personal', 'staff/personal vehicles — not operational fleet'), ('management', 'management vehicles — not operational fleet'), ('mtn', 'MTN contract / Uganda (Kampala) — outside Kenyan ops') ON CONFLICT (cost_centre) DO NOTHING; -- ── v_live_positions: same definition + exclusion filter ────────────────────── CREATE OR REPLACE VIEW reporting.v_live_positions AS WITH primary_device AS ( SELECT DISTINCT ON ((reporting.normalize_plate(d_1.vehicle_number))) reporting.normalize_plate(d_1.vehicle_number) AS vehicle_number, d_1.imei AS primary_imei FROM devices d_1 LEFT JOIN live_positions lp_1 ON lp_1.imei = d_1.imei WHERE d_1.vehicle_number IS NOT NULL AND d_1.enabled_flag = 1 -- exclude plates whose device(s) carry a non-operational cost centre AND reporting.normalize_plate(d_1.vehicle_number) NOT IN ( SELECT reporting.normalize_plate(x.vehicle_number) FROM devices x WHERE x.vehicle_number IS NOT NULL AND lower(trim(x.cost_centre)) IN ( SELECT cost_centre FROM reporting.map_excluded_cost_centres) ) ORDER BY (reporting.normalize_plate(d_1.vehicle_number)), ( CASE WHEN (d_1.mc_type = ANY (ARRAY['GT06E'::text, 'X3'::text, 'AT4'::text])) AND lp_1.gps_time >= (now() - '24:00:00'::interval) THEN 0 ELSE 1 END), lp_1.gps_time DESC NULLS LAST, ( CASE d_1.mc_type WHEN 'GT06E'::text THEN 1 WHEN 'X3'::text THEN 2 WHEN 'AT4'::text THEN 3 WHEN 'JC400P'::text THEN 4 ELSE 5 END), d_1.activation_time, d_1.imei ) SELECT lp.imei, pd.vehicle_number, d.driver_name AS assigned_driver, d.cost_centre, d.assigned_city, d.vehicle_category, d.vehicle_models, d.mc_type, CASE d.mc_type WHEN 'GT06E'::text THEN 'tracker'::text WHEN 'X3'::text THEN 'tracker'::text WHEN 'AT4'::text THEN 'tracker'::text WHEN 'JC400P'::text THEN 'camera'::text ELSE 'other'::text END AS device_kind, lp.lat, lp.lng, lp.speed, lp.direction, lp.acc_status, lp.device_status, lp.gps_signal, lp.gps_num, lp.current_mileage, lp.loc_desc, lp.gps_time, lp.updated_at, (lp.gps_time AT TIME ZONE 'Africa/Nairobi'::text) AS gps_time_eat, (lp.updated_at AT TIME ZONE 'Africa/Nairobi'::text) AS updated_at_eat, round(EXTRACT(epoch FROM now() - lp.gps_time) / 3600::numeric, 2) AS source_age_hours FROM live_positions lp JOIN primary_device pd ON pd.primary_imei = lp.imei JOIN devices d ON d.imei = lp.imei; COMMENT ON TABLE reporting.map_excluded_cost_centres IS 'Cost centres hidden from the live map (reporting.v_live_positions). Edit to hide/restore; ' 'effective on next query. Seeded: personal, management, mtn. See migration 15.'; -- ── grants (guarded: roles may not exist on a fresh DB) ─────────────────────── DO $grants$ BEGIN IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'grafana_ro') THEN GRANT SELECT ON reporting.map_excluded_cost_centres TO grafana_ro; END IF; END $grants$;