owpengram-server/deploy/migrations/20260714003090_account_freeze_visibility.up.sql

37 lines
1.9 KiB
SQL

-- A freeze/unfreeze is a viewer-visible user projection change. Version the
-- durable fact so a claimed old nudge can never acknowledge a newer state.
ALTER TABLE public.account_restrictions
ADD COLUMN version bigint DEFAULT 1 NOT NULL,
ADD CONSTRAINT account_restrictions_version_check CHECK (version > 0);
-- updateUser has no pts. This coalesced queue is only a crash-safe online
-- nudge; offline clients reconstruct the current restriction from the
-- authoritative account_restrictions row during normal user hydration.
CREATE TABLE public.account_freeze_notifications (
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
target_user_id bigint NOT NULL REFERENCES public.users(id) ON DELETE CASCADE,
frozen_user_id bigint NOT NULL REFERENCES public.users(id) ON DELETE CASCADE,
version bigint NOT NULL,
frozen boolean NOT NULL,
status text DEFAULT 'pending' NOT NULL,
attempts integer DEFAULT 0 NOT NULL,
next_attempt_at timestamp with time zone DEFAULT now() NOT NULL,
lease_until timestamp with time zone,
last_error text DEFAULT '' NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL,
updated_at timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT account_freeze_notifications_status_check
CHECK (status IN ('pending', 'dispatching', 'delivered')),
CONSTRAINT account_freeze_notifications_attempts_check CHECK (attempts >= 0),
CONSTRAINT account_freeze_notifications_version_check CHECK (version > 0),
CONSTRAINT account_freeze_notifications_not_self_check CHECK (target_user_id <> frozen_user_id),
UNIQUE (target_user_id, frozen_user_id)
);
CREATE INDEX account_freeze_notifications_ready_idx
ON public.account_freeze_notifications(next_attempt_at, id)
WHERE status = 'pending';
CREATE INDEX account_freeze_notifications_lease_idx
ON public.account_freeze_notifications(lease_until, id)
WHERE status = 'dispatching';