mirror of
https://github.com/block/buzz.git
synced 2026-10-27 20:41:57 +00:00
80 lines
4.5 KiB
SQL
80 lines
4.5 KiB
SQL
-- ── Relay admin actions (HTTP enforcement state machine) ──────────────────────
|
|
-- One row per HTTP report-resolution enforcement action. Tracks the durable
|
|
-- state machine from claim → enforcing → succeeded|failed|cancelled.
|
|
|
|
CREATE TABLE relay_admin_actions (
|
|
id UUID NOT NULL PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
-- NULL for a report-less direct action (migration 0055).
|
|
report_id UUID,
|
|
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).
|
|
-- Values: 'mutation_committed' (core DB mutation done), 'artifacts_done' (tombstone/notice done).
|
|
step_marker TEXT CHECK (step_marker IN ('mutation_committed', 'artifacts_done')),
|
|
-- Principal who cancelled a pre-mutation failed action; NULL until cancelled.
|
|
-- Attributes the cancel transition on the action row itself, mirroring
|
|
-- moderation_reports.resolved_by for report resolution.
|
|
cancelled_by BYTEA CHECK (cancelled_by IS NULL OR length(cancelled_by) = 32),
|
|
-- Error from the last failure, if any.
|
|
error_message TEXT,
|
|
-- Per-action exclusive lease (migration 0037): fences concurrent same-request
|
|
-- retries and lets the recovery worker claim/re-drive stranded actions.
|
|
action_lease_token UUID,
|
|
action_lease_expires_at TIMESTAMPTZ,
|
|
-- Authoritative enforcement target (migration 0047): persisted at claim time
|
|
-- so crash-recovery can fire live side effects without re-deriving from mutable
|
|
-- sources. enforcement_target_pubkey is the resolved target pubkey bytes for
|
|
-- kick/ban/timeout actions; NULL for event/blob targets. enforcement_channel_id
|
|
-- is the channel targeted by kick actions; NULL for community-wide actions.
|
|
enforcement_target_pubkey BYTEA
|
|
CHECK (enforcement_target_pubkey IS NULL OR length(enforcement_target_pubkey) = 32),
|
|
enforcement_channel_id UUID,
|
|
-- Direct actions (migration 0055): deleted event, and requested timeout
|
|
-- duration compared on idempotent retry.
|
|
enforcement_target_event_id BYTEA
|
|
CHECK (enforcement_target_event_id IS NULL OR length(enforcement_target_event_id) = 32),
|
|
timeout_secs BIGINT CHECK (timeout_secs IS NULL OR timeout_secs > 0),
|
|
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),
|
|
CONSTRAINT relay_admin_actions_direct_shape CHECK (
|
|
report_id IS NOT NULL
|
|
OR (action = 'ban' AND enforcement_target_pubkey IS NOT NULL
|
|
AND timeout_secs IS NULL AND timeout_until IS NULL)
|
|
OR (action = 'timeout' AND enforcement_target_pubkey IS NOT NULL
|
|
AND timeout_secs IS NOT NULL AND timeout_until IS NOT NULL)
|
|
OR (action = 'delete' AND enforcement_target_event_id IS NOT NULL
|
|
AND enforcement_target_pubkey IS NOT NULL
|
|
AND timeout_secs IS NULL AND timeout_until IS NULL)
|
|
),
|
|
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);
|
|
-- Direct-action idempotency (migration 0055): one per (community, request_id).
|
|
CREATE UNIQUE INDEX idx_relay_admin_actions_direct_request
|
|
ON relay_admin_actions (report_community_id, request_id)
|
|
WHERE report_id IS NULL;
|
|
CREATE INDEX idx_relay_admin_actions_state
|
|
ON relay_admin_actions (state)
|
|
WHERE state IN ('pending', 'enforcing');
|
|
-- Recovery worker (migration 0037): find stranded actions by lease expiry.
|
|
CREATE INDEX idx_relay_admin_actions_lease
|
|
ON relay_admin_actions (action_lease_expires_at)
|
|
WHERE state IN ('pending', 'enforcing');
|