Files
wyndham-ARR/database/009_source_read_grants.sql
2026-07-29 16:38:05 +08:00

62 lines
2.1 KiB
PL/PgSQL

-- ARR source XML single-read grants for the SuperAgent runtime fetch provider.
-- PostgreSQL 15+. Additive only; migration 008 remains immutable.
BEGIN;
DO $$
BEGIN
IF current_database() <> 'booking_test' THEN
RAISE EXCEPTION
'ARR source read grants are allowed only in booking_test';
END IF;
IF to_regclass('ingestion.artifacts') IS NULL
OR to_regclass('ingestion.processing_runs') IS NULL THEN
RAISE EXCEPTION
'ARR MVP v1 migration 008 must be applied first';
END IF;
END;
$$;
CREATE TABLE ingestion.source_read_grants (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
grant_key text NOT NULL UNIQUE CHECK (
grant_key ~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$'
),
job_key text NOT NULL CHECK (
job_key ~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$'
),
attempt_no integer NOT NULL CHECK (attempt_no BETWEEN 1 AND 9999),
object_key text NOT NULL CHECK (
btrim(object_key) <> ''
AND object_key !~ '^/'
AND object_key !~ '(^|/)\.\.(/|$)'
AND object_key !~ '[?#]'
),
original_filename text NOT NULL DEFAULT 'source.xml'
CHECK (original_filename = 'source.xml'),
created_at timestamptz NOT NULL,
expires_at timestamptz NOT NULL,
consumed_at timestamptz,
CONSTRAINT source_read_grants_lifetime CHECK (
expires_at > created_at
AND expires_at <= created_at + interval '5 minutes'
),
CONSTRAINT source_read_grants_consumption_shape CHECK (
consumed_at IS NULL OR consumed_at >= created_at
)
);
CREATE INDEX source_read_grants_expiry_idx
ON ingestion.source_read_grants (expires_at);
CREATE INDEX source_read_grants_job_attempt_idx
ON ingestion.source_read_grants (job_key, attempt_no);
COMMENT ON TABLE ingestion.source_read_grants IS
'Opaque job-bound source XML grants. One atomic redemption, maximum five-minute lifetime; never stores bytes, URLs, credentials, guest fields, or Agent-local paths.';
COMMENT ON COLUMN ingestion.source_read_grants.object_key IS
'Server-side committed ARR object identity resolved only by the trusted runtime fetch provider.';
COMMIT;