-- migrate:up CREATE TABLE slo.targets ( metric text PRIMARY KEY, threshold numeric NOT NULL, window_seconds int NOT NULL, description text, updated_at timestamptz NOT NULL DEFAULT now() ); INSERT INTO slo.targets (metric, threshold, window_seconds, description) VALUES ('fix_freshness_pct_60s', 95, 300, 'Pct of active devices with a fix within 90s, window 5 min'), ('parser_lag_p95_sec', 30, 300, 'P95 of received_at -> events.parsed insertion lag, window 5 min'), ('contract_drift_days', 1, 86400, 'Days since last successful sandbox contract validation'); CREATE TABLE slo.measurements ( measurement_id bigserial, metric text NOT NULL REFERENCES slo.targets(metric), value numeric NOT NULL, measured_at timestamptz NOT NULL DEFAULT now(), PRIMARY KEY (measurement_id, measured_at) ); SELECT create_hypertable('slo.measurements', 'measured_at', chunk_time_interval => INTERVAL '7 days'); CREATE INDEX slo_measurements_metric_time_idx ON slo.measurements (metric, measured_at DESC); CREATE OR REPLACE VIEW slo.v_current_status AS SELECT t.metric, t.threshold, t.window_seconds, latest.value AS current_value, latest.measured_at AS measured_at, CASE WHEN latest.value IS NULL THEN 'unknown' WHEN t.metric LIKE '%pct%' AND latest.value >= t.threshold THEN 'green' WHEN t.metric LIKE '%pct%' AND latest.value < t.threshold THEN 'red' WHEN latest.value <= t.threshold THEN 'green' ELSE 'red' END AS status FROM slo.targets t LEFT JOIN LATERAL ( SELECT value, measured_at FROM slo.measurements m WHERE m.metric = t.metric ORDER BY measured_at DESC LIMIT 1 ) latest ON true; -- migrate:down DROP VIEW IF EXISTS slo.v_current_status; DROP TABLE IF EXISTS slo.measurements; DROP TABLE IF EXISTS slo.targets;