70 lines
3.6 KiB
PL/PgSQL
70 lines
3.6 KiB
PL/PgSQL
BEGIN;
|
|
|
|
CREATE TABLE privacy_request (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
public_id uuid NOT NULL UNIQUE DEFAULT gen_random_uuid(),
|
|
tenant_id uuid NOT NULL REFERENCES tenant(id),
|
|
subject_id uuid NOT NULL,
|
|
request_type varchar(32) NOT NULL
|
|
CHECK (request_type IN ('ACCESS', 'CORRECTION', 'CONSENT_WITHDRAWAL', 'DELETE')),
|
|
scope jsonb NOT NULL DEFAULT '{}'::jsonb CHECK (jsonb_typeof(scope)='object'),
|
|
requested_by uuid NOT NULL,
|
|
status varchar(32) NOT NULL DEFAULT 'SUBMITTED'
|
|
CHECK (status IN ('SUBMITTED', 'VERIFYING', 'EXECUTING', 'COMPLETED', 'PARTIAL_FAILED')),
|
|
deadline_at timestamptz,
|
|
legal_hold boolean NOT NULL DEFAULT false,
|
|
result_summary jsonb NOT NULL DEFAULT '{}'::jsonb CHECK (jsonb_typeof(result_summary)='object'),
|
|
idempotency_key varchar(255) NOT NULL,
|
|
request_digest char(64) NOT NULL,
|
|
version bigint NOT NULL DEFAULT 1 CHECK (version > 0),
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
completed_at timestamptz,
|
|
CONSTRAINT privacy_request_subject_tenant_fk
|
|
FOREIGN KEY (subject_id, tenant_id) REFERENCES subject_profile (id, tenant_id),
|
|
CONSTRAINT privacy_request_requester_tenant_fk
|
|
FOREIGN KEY (requested_by, tenant_id) REFERENCES user_account (id, tenant_id),
|
|
CONSTRAINT privacy_request_actor_idempotency_key
|
|
UNIQUE (tenant_id, requested_by, idempotency_key)
|
|
);
|
|
CREATE INDEX privacy_request_subject_time_idx
|
|
ON privacy_request (tenant_id, subject_id, created_at DESC, id DESC);
|
|
CREATE INDEX privacy_request_work_idx
|
|
ON privacy_request (status, updated_at) WHERE status IN ('SUBMITTED', 'VERIFYING', 'EXECUTING', 'PARTIAL_FAILED');
|
|
|
|
CREATE TABLE privacy_subtask (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
public_id uuid NOT NULL UNIQUE DEFAULT gen_random_uuid(),
|
|
privacy_request_id uuid NOT NULL REFERENCES privacy_request(id) ON DELETE CASCADE,
|
|
subsystem varchar(32) NOT NULL
|
|
CHECK (subsystem IN ('postgresql', 'redis', 'object_storage', 'pgvector', 'provider_index', 'export_files')),
|
|
target_type varchar(64) NOT NULL,
|
|
target_ref varchar(300) NOT NULL,
|
|
status varchar(24) NOT NULL DEFAULT 'PENDING'
|
|
CHECK (status IN ('PENDING', 'RUNNING', 'COMPLETED', 'FAILED', 'SKIPPED')),
|
|
attempts integer NOT NULL DEFAULT 0 CHECK (attempts >= 0),
|
|
next_attempt_at timestamptz,
|
|
last_error varchar(500),
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
completed_at timestamptz,
|
|
CONSTRAINT privacy_subtask_target_key
|
|
UNIQUE (privacy_request_id, subsystem, target_type, target_ref)
|
|
);
|
|
CREATE INDEX privacy_subtask_work_idx
|
|
ON privacy_subtask (status, next_attempt_at, created_at)
|
|
WHERE status IN ('PENDING', 'RUNNING', 'FAILED');
|
|
|
|
CREATE TABLE tombstone (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id uuid NOT NULL REFERENCES tenant(id),
|
|
resource_type varchar(80) NOT NULL,
|
|
resource_digest char(64) NOT NULL,
|
|
deleted_at timestamptz NOT NULL DEFAULT now(),
|
|
deletion_request_id uuid NOT NULL REFERENCES privacy_request(id),
|
|
retention_reason varchar(500) NOT NULL,
|
|
CONSTRAINT tombstone_resource_key UNIQUE (tenant_id, resource_type, resource_digest)
|
|
);
|
|
|
|
COMMIT;
|