-- HTTP report-resolution enforcement state machine (Phase 2 admin auth). -- -- relay_admin_actions: one row per HTTP-initiated enforcement action. -- relay_admin_outbox: durable delivery queue for tombstones, system messages, -- and reporter notice DMs. -- -- Both tables are deployment-global (no community_id direct column; the report -- FK carries community provenance). Registered in _operator_global_tables and -- in the hardcoded parser list in crates/buzz-db/src/migration.rs. CREATE TABLE relay_admin_actions ( id UUID NOT NULL PRIMARY KEY DEFAULT gen_random_uuid(), report_id UUID NOT NULL, report_community_id UUID NOT NULL, -- Client-generated idempotency key (signed in NIP-98 request body). request_id UUID NOT NULL, -- Principal who claimed the report. actor_pubkey BYTEA NOT NULL CHECK (length(actor_pubkey) = 32), actor_role TEXT NOT NULL CHECK (actor_role IN ('operator', 'moderator')), -- The enforcement action requested. action TEXT NOT NULL, reason TEXT, -- Timeout expiration for timeout actions; NULL otherwise. timeout_until TIMESTAMPTZ, -- Durable state machine: pending → enforcing → succeeded|failed|cancelled. state TEXT NOT NULL DEFAULT 'pending' CHECK (state IN ('pending', 'enforcing', 'succeeded', 'failed', 'cancelled')), -- Step marker: the last durably committed mutation step (NULL = none yet). step_marker TEXT CHECK (step_marker IN ('mutation_committed', 'artifacts_done')), -- Error from the last failure, if any. error_message TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), -- Report-scoped idempotency: one action per (report, request_id). UNIQUE (report_community_id, report_id, request_id), FOREIGN KEY (report_community_id, report_id) REFERENCES moderation_reports (community_id, id) ); CREATE INDEX idx_relay_admin_actions_report ON relay_admin_actions (report_community_id, report_id); CREATE INDEX idx_relay_admin_actions_state ON relay_admin_actions (state) WHERE state IN ('pending', 'enforcing'); INSERT INTO _operator_global_tables (table_name, reason) VALUES ('relay_admin_actions', 'deployment-global enforcement state machine; community provenance via report FK'); -- ── Relay admin outbox ──────────────────────────────────────────────────────── CREATE TABLE relay_admin_outbox ( id UUID NOT NULL PRIMARY KEY DEFAULT gen_random_uuid(), action_id UUID NOT NULL REFERENCES relay_admin_actions(id), -- Delivery task type: 'tombstone' | 'system_message' | 'reporter_notice'. task_type TEXT NOT NULL, -- Task payload (JSON). payload JSONB NOT NULL DEFAULT '{}'::jsonb, -- Lease-based delivery: held_by identifies the worker pod. held_by TEXT, lease_expires_at TIMESTAMPTZ, -- Delivery state: pending → delivered | failed. state TEXT NOT NULL DEFAULT 'pending' CHECK (state IN ('pending', 'delivered', 'failed')), -- Deduplication key: prevents re-creating an artifact after delivery. dedup_key TEXT UNIQUE, error_message TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX idx_relay_admin_outbox_action ON relay_admin_outbox (action_id); CREATE INDEX idx_relay_admin_outbox_pending ON relay_admin_outbox (lease_expires_at) WHERE state = 'pending'; INSERT INTO _operator_global_tables (table_name, reason) VALUES ('relay_admin_outbox', 'deployment-global enforcement artifact delivery queue');