50 lines
1.8 KiB
PL/PgSQL
50 lines
1.8 KiB
PL/PgSQL
-- 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;
|