CREATE TABLE ops_sensitive_access_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), conversation_id uuid NOT NULL, requester_user_id uuid NOT NULL, capabilities text[] NOT NULL, reason varchar(500) NOT NULL, requested_expires_at timestamptz NOT NULL, status varchar(24) NOT NULL DEFAULT 'PENDING' CHECK (status IN ('PENDING','APPROVED','REJECTED','REVOKED','EXPIRED')), reviewed_by uuid, review_reason varchar(500), reviewed_at timestamptz, revoked_by uuid, revoked_at timestamptz, version bigint NOT NULL DEFAULT 1 CHECK (version > 0), created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(), CONSTRAINT ops_sensitive_access_conversation_tenant_fk FOREIGN KEY (conversation_id,tenant_id) REFERENCES conversation(id,tenant_id), CONSTRAINT ops_sensitive_access_requester_tenant_fk FOREIGN KEY (requester_user_id,tenant_id) REFERENCES user_account(id,tenant_id), CONSTRAINT ops_sensitive_access_reviewer_tenant_fk FOREIGN KEY (reviewed_by,tenant_id) REFERENCES user_account(id,tenant_id), CONSTRAINT ops_sensitive_access_revoker_tenant_fk FOREIGN KEY (revoked_by,tenant_id) REFERENCES user_account(id,tenant_id), CONSTRAINT ops_sensitive_access_capabilities_check CHECK ( capabilities=ARRAY['RECORDING_PLAY']::text[] OR capabilities=ARRAY['TRANSCRIPT_READ']::text[] OR capabilities=ARRAY['RECORDING_PLAY','TRANSCRIPT_READ']::text[] ), CONSTRAINT ops_sensitive_access_expiry_check CHECK (requested_expires_at > created_at AND requested_expires_at <= created_at + interval '4 hours'), CONSTRAINT ops_sensitive_access_review_check CHECK ( (status='PENDING' AND reviewed_by IS NULL AND reviewed_at IS NULL) OR (status<>'PENDING') ) ); CREATE UNIQUE INDEX ops_sensitive_access_one_open_key ON ops_sensitive_access_request(tenant_id,conversation_id,requester_user_id) WHERE status IN ('PENDING','APPROVED'); CREATE INDEX ops_sensitive_access_review_queue_idx ON ops_sensitive_access_request(tenant_id,status,created_at DESC); CREATE TABLE ops_sensitive_access_log ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id uuid NOT NULL REFERENCES tenant(id), access_request_id uuid NOT NULL REFERENCES ops_sensitive_access_request(id), actor_user_id uuid NOT NULL, conversation_id uuid NOT NULL, media_segment_id uuid, capability varchar(32) NOT NULL CHECK (capability IN ('TRANSCRIPT_READ','RECORDING_PLAY')), result varchar(16) NOT NULL CHECK (result IN ('SUCCESS','DENIED')), reason_code varchar(64), request_id varchar(128), accessed_at timestamptz NOT NULL DEFAULT now(), CONSTRAINT ops_sensitive_access_log_actor_tenant_fk FOREIGN KEY (actor_user_id,tenant_id) REFERENCES user_account(id,tenant_id), CONSTRAINT ops_sensitive_access_log_conversation_tenant_fk FOREIGN KEY (conversation_id,tenant_id) REFERENCES conversation(id,tenant_id), CONSTRAINT ops_sensitive_access_log_segment_tenant_fk FOREIGN KEY (media_segment_id,tenant_id) REFERENCES media_segment(id,tenant_id) ); CREATE INDEX ops_sensitive_access_log_request_time_idx ON ops_sensitive_access_log(access_request_id,accessed_at DESC); CREATE INDEX ops_sensitive_access_log_tenant_time_idx ON ops_sensitive_access_log(tenant_id,accessed_at DESC);