-- 08_inc_open_sla_view.sql — fleettickets · open-ticket SLA view -- ───────────────────────────────────────────────────────────────────────────── -- reporting view over the open (is_actionable) INC tickets with a DERIVED SLA -- state, since the source sla_status is only meaningful once a ticket is closed. -- -- SLA clock = created_at_service, falling back to first_seen_at (the export's -- first-sighting) when creation is missing (~70% of open rows lack -- created_at_service); sla_clock_source flags which was used. Contract rule: 48h. -- hours_open / sla_state use now(), so the view is always current. Includes the -- routing-grade geog so dispatch can join straight off it. -- ───────────────────────────────────────────────────────────────────────────── SET search_path = tickets, public; CREATE OR REPLACE VIEW tickets.inc_open_sla AS SELECT ticket_id, normalized_status, bucket, cluster, region, location_name, assigned_team, owner, sla_status AS source_sla_status, mttr, -- minutes (null until closed) COALESCE(created_at_service, first_seen_at) AS sla_clock, CASE WHEN created_at_service IS NOT NULL THEN 'service' ELSE 'first_seen' END AS sla_clock_source, round((EXTRACT(EPOCH FROM now() - COALESCE(created_at_service, first_seen_at)) / 3600)::numeric, 1) AS hours_open, CASE WHEN COALESCE(created_at_service, first_seen_at) IS NULL THEN 'unknown' WHEN now() - COALESCE(created_at_service, first_seen_at) >= interval '48h' THEN 'breached' WHEN now() - COALESCE(created_at_service, first_seen_at) >= interval '36h' THEN 'at_risk' ELSE 'ok' END AS sla_state, created_at_service, first_seen_at, scheduled_at, latitude, longitude, geo_source, geom, geog FROM tickets.inc WHERE is_actionable; COMMENT ON VIEW tickets.inc_open_sla IS 'Open (is_actionable) INC tickets with derived SLA (48h rule; clock = created_at_service ' 'or first_seen_at fallback). fleettickets 08.'; -- grants (guarded: roles may not exist on a fresh DB) DO $grants$ BEGIN IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'dashboard_ro') THEN GRANT SELECT ON tickets.inc_open_sla TO dashboard_ro; END IF; IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'grafana_ro') THEN GRANT SELECT ON tickets.inc_open_sla TO grafana_ro; END IF; END $grants$;