63 lines
3.7 KiB
SQL
63 lines
3.7 KiB
SQL
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);
|