feat(reporting): exclude non-operational vehicles from the live map (migration 15)
Hide personal + management + mtn (Uganda/Kampala) vehicles from the live tracking map (FleetNow + liveposition SPA). Adds an ops-editable config table reporting.map_excluded_cost_centres and filters reporting.v_live_positions to drop any plate whose device(s) carry an excluded cost centre (robust to the tracker/cam cost_centre inconsistency). Scope is live-map only; reporting.v_trips (trip history) is intentionally untouched. The base view feeds reporting.fn_live_positions, so the change propagates to every live consumer with no dashboard_api redeploy or frontend change. Verified live: 80 -> 74 vehicles, all 6 targets gone (KDU 613A, KDW 781E, UMA 011EK/382EK/418EK/826AB). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
347c97ec4c
commit
0c32094347
2 changed files with 106 additions and 0 deletions
105
migrations/15_map_exclude_cost_centres.sql
Normal file
105
migrations/15_map_exclude_cost_centres.sql
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
-- 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$;
|
||||
|
|
@ -38,6 +38,7 @@ MIGRATIONS = [
|
|||
"12_drop_ops.sql", # purge dormant ops schema + dispatch_log + v_sla_inflight
|
||||
"13_drop_dwh_gold.sql", # purge dormant dwh_gold schema + v_utilisation_daily
|
||||
"14_fleet_segment_and_vehicles_view.sql", # reporting.fn_fleet_segment + reporting.v_vehicles roster
|
||||
"15_map_exclude_cost_centres.sql", # hide personal/management/mtn vehicles from the live map
|
||||
]
|
||||
|
||||
# ── Tables that must exist before the service is allowed to start ─────────────
|
||||
|
|
|
|||
Loading…
Reference in a new issue