-- Append-only task alert events plus a monotonic current-state projection. BEGIN; CREATE SCHEMA IF NOT EXISTS workbench; CREATE TABLE IF NOT EXISTS workbench.alert_events ( project_id uuid NOT NULL, producer_id text NOT NULL CHECK (length(producer_id) > 0), event_id uuid NOT NULL, alert_id text NOT NULL CHECK (length(alert_id) > 0), event_type text NOT NULL CHECK (event_type IN ('raised','acknowledged','resolved')), occurred_at timestamptz NOT NULL, ingested_at timestamptz NOT NULL DEFAULT now(), document jsonb NOT NULL, PRIMARY KEY (project_id,producer_id,event_id), CHECK ((jsonb_typeof(document)='object' AND document->>'producer_id'=producer_id AND document->>'event_id'=event_id::text AND document->>'alert_id'=alert_id AND document->>'event_type'=event_type AND (document->>'occurred_at')::timestamptz=occurred_at) IS TRUE) ); CREATE INDEX IF NOT EXISTS alert_events_alert_idx ON workbench.alert_events(project_id,alert_id,occurred_at,event_id); CREATE TABLE IF NOT EXISTS workbench.alerts ( project_id uuid NOT NULL, alert_id text NOT NULL CHECK (length(alert_id) > 0), revision bigint NOT NULL CHECK (revision >= 1), status text NOT NULL CHECK (status IN ('active','acknowledged','resolved')), occurred_at timestamptz NOT NULL, updated_at timestamptz NOT NULL, document jsonb NOT NULL, PRIMARY KEY (project_id,alert_id), CHECK ((jsonb_typeof(document)='object' AND document->>'alert_id'=alert_id AND document->>'status'=status AND (document->>'occurred_at')::timestamptz=occurred_at) IS TRUE) ); CREATE INDEX IF NOT EXISTS alerts_active_recent_idx ON workbench.alerts(project_id,occurred_at DESC,alert_id) WHERE status='active'; REVOKE ALL ON ALL TABLES IN SCHEMA workbench FROM PUBLIC; COMMIT;