-- Durable event-to-push matching follower. The trigger runs in the event insert -- transaction, so every accepted persistent event has a crash-safe match job and -- rejected/rolled-back events never do. Processing is idempotent through the -- push_wake_outbox endpoint/event unique key. CREATE TABLE push_match_queue ( community_id UUID NOT NULL REFERENCES communities(id), event_id BYTEA NOT NULL CHECK (length(event_id) = 32), state TEXT NOT NULL DEFAULT 'pending' CHECK (state IN ('pending','matching')), attempts INTEGER NOT NULL DEFAULT 0 CHECK (attempts >= 0), next_attempt_at TIMESTAMPTZ NOT NULL DEFAULT now(), lease_until TIMESTAMPTZ, claim_id UUID, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), PRIMARY KEY (community_id, event_id) ); CREATE INDEX push_match_queue_due ON push_match_queue (next_attempt_at, created_at) WHERE state = 'pending'; CREATE INDEX push_match_queue_recovery ON push_match_queue (lease_until) WHERE state = 'matching';