CREATE TABLE credential_reference ( id text PRIMARY KEY, provider text NOT NULL CHECK (provider IN ('os_keyring', 'secret_manager')), reference_key text NOT NULL UNIQUE, created_at timestamptz NOT NULL DEFAULT now() ); CREATE TABLE social_account ( id text PRIMARY KEY CHECK (id ~ '^[a-z0-9][a-z0-9-]{0,31}$'), credential_reference_id text NOT NULL UNIQUE REFERENCES credential_reference(id), profile_id text NOT NULL UNIQUE, version bigint NOT NULL DEFAULT 1 CHECK (version > 0), status text NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'paused')), paused_at timestamptz, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now() ); CREATE TABLE runtime_instance ( id text PRIMARY KEY, account_id text NOT NULL REFERENCES social_account(id), runtime_id text NOT NULL, acquired_at timestamptz NOT NULL DEFAULT now(), lease_until timestamptz NOT NULL, released_at timestamptz ); CREATE UNIQUE INDEX one_active_runtime_per_account ON runtime_instance (account_id) WHERE released_at IS NULL; CREATE UNIQUE INDEX one_account_per_active_runtime ON runtime_instance (runtime_id) WHERE released_at IS NULL; CREATE TABLE content_draft ( id text PRIMARY KEY, account_id text NOT NULL REFERENCES social_account(id), version bigint NOT NULL CHECK (version > 0), content text NOT NULL, created_at timestamptz NOT NULL DEFAULT now() ); CREATE TABLE confirmation ( id text PRIMARY KEY, account_id text NOT NULL REFERENCES social_account(id), account_version bigint NOT NULL CHECK (account_version > 0), draft_id text NOT NULL REFERENCES content_draft(id), draft_version bigint NOT NULL CHECK (draft_version > 0), version bigint NOT NULL CHECK (version > 0), confirmed_by text NOT NULL DEFAULT 'local-user' CHECK (confirmed_by = 'local-user'), confirmed_at timestamptz NOT NULL DEFAULT now() ); CREATE TABLE operation_task ( id text PRIMARY KEY, idempotency_key text NOT NULL UNIQUE, account_id text NOT NULL REFERENCES social_account(id), account_version bigint NOT NULL CHECK (account_version > 0), draft_id text NOT NULL REFERENCES content_draft(id), draft_version bigint NOT NULL CHECK (draft_version > 0), confirmation_id text REFERENCES confirmation(id), confirmation_version bigint CHECK (confirmation_version > 0), state text NOT NULL DEFAULT 'queued' CHECK (state IN ( 'queued', 'executing', 'succeeded', 'failed', 'needs_confirmation', 'policy_hold', 'cancelled' )), lease_owner text, lease_until timestamptz, current_attempt_id text, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(), CHECK ((confirmation_id IS NULL) = (confirmation_version IS NULL)) ); CREATE TABLE execution_attempt ( id text PRIMARY KEY, task_id text NOT NULL UNIQUE REFERENCES operation_task(id), started_at timestamptz NOT NULL DEFAULT now(), finished_at timestamptz, outcome text CHECK (outcome IN ('succeeded', 'failed', 'uncertain', 'policy_hold')), result jsonb NOT NULL DEFAULT '{}'::jsonb ); ALTER TABLE operation_task ADD CONSTRAINT operation_task_current_attempt_fk FOREIGN KEY (current_attempt_id) REFERENCES execution_attempt(id); CREATE TABLE audit_event ( id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY, event_type text NOT NULL, account_id text REFERENCES social_account(id), confirmation_id text REFERENCES confirmation(id), confirmation_version bigint, attempt_id text REFERENCES execution_attempt(id), task_id text REFERENCES operation_task(id), details jsonb NOT NULL DEFAULT '{}'::jsonb, created_at timestamptz NOT NULL DEFAULT now() ); CREATE FUNCTION reject_audit_event_mutation() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN RAISE EXCEPTION 'audit_event is append-only'; END; $$; CREATE TRIGGER audit_event_append_only BEFORE UPDATE OR DELETE ON audit_event FOR EACH ROW EXECUTE FUNCTION reject_audit_event_mutation();