57 lines
3.4 KiB
PL/PgSQL
57 lines
3.4 KiB
PL/PgSQL
BEGIN;
|
|||
|
|
|
||
|
|
CREATE TABLE sharing_grant (
|
||
|
|
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),
|
||
|
|
household_id uuid NOT NULL,
|
||
|
|
subject_id uuid NOT NULL,
|
||
|
|
resource_type varchar(32) NOT NULL CHECK (resource_type IN ('STORY','TRANSCRIPT','RECORDING')),
|
||
|
|
resource_public_id uuid NOT NULL,
|
||
|
|
grantee_user_id uuid NOT NULL,
|
||
|
|
permission varchar(24) NOT NULL CHECK (permission IN ('VIEW_TEXT','LISTEN','DOWNLOAD','EDIT')),
|
||
|
|
purpose varchar(500) NOT NULL CHECK (length(trim(purpose))>0),
|
||
|
|
login_required boolean NOT NULL DEFAULT true,
|
||
|
|
granted_by uuid NOT NULL,
|
||
|
|
granted_at timestamptz NOT NULL DEFAULT now(),
|
||
|
|
expires_at timestamptz NOT NULL,
|
||
|
|
revoked_at timestamptz,
|
||
|
|
revoked_by uuid,
|
||
|
|
version bigint NOT NULL DEFAULT 1 CHECK (version>0),
|
||
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
||
|
|
CONSTRAINT sharing_grant_household_tenant_fk FOREIGN KEY (household_id,tenant_id) REFERENCES household(id,tenant_id),
|
||
|
|
CONSTRAINT sharing_grant_subject_tenant_fk FOREIGN KEY (subject_id,tenant_id) REFERENCES subject_profile(id,tenant_id) ON DELETE CASCADE,
|
||
|
|
CONSTRAINT sharing_grant_grantee_tenant_fk FOREIGN KEY (grantee_user_id,tenant_id) REFERENCES user_account(id,tenant_id),
|
||
|
|
CONSTRAINT sharing_grant_grantor_tenant_fk FOREIGN KEY (granted_by,tenant_id) REFERENCES user_account(id,tenant_id),
|
||
|
|
CONSTRAINT sharing_grant_revoker_tenant_fk FOREIGN KEY (revoked_by,tenant_id) REFERENCES user_account(id,tenant_id),
|
||
|
|
CONSTRAINT sharing_grant_permission_resource_check CHECK (
|
||
|
|
(resource_type='STORY' AND permission IN ('VIEW_TEXT','EDIT')) OR
|
||
|
|
(resource_type='TRANSCRIPT' AND permission='VIEW_TEXT') OR
|
||
|
|
(resource_type='RECORDING' AND permission IN ('LISTEN','DOWNLOAD'))
|
||
|
|
),
|
||
|
|
CONSTRAINT sharing_grant_expiry_check CHECK (expires_at>granted_at)
|
||
|
|
);
|
||
|
|
CREATE INDEX sharing_grant_subject_idx ON sharing_grant(tenant_id,subject_id,granted_at DESC);
|
||
|
|
CREATE INDEX sharing_grant_recipient_idx ON sharing_grant(tenant_id,grantee_user_id,expires_at DESC) WHERE revoked_at IS NULL;
|
||
|
|
CREATE INDEX sharing_grant_resource_idx ON sharing_grant(tenant_id,resource_type,resource_public_id);
|
||
|
|
|
||
|
|
CREATE TABLE sharing_access_log (
|
||
|
|
id bigserial PRIMARY KEY,
|
||
|
|
tenant_id uuid NOT NULL REFERENCES tenant(id),
|
||
|
|
sharing_grant_id uuid NOT NULL REFERENCES sharing_grant(id) ON DELETE CASCADE,
|
||
|
|
actor_user_id uuid,
|
||
|
|
actor_identifier_digest char(64) NOT NULL,
|
||
|
|
resource_type varchar(32) NOT NULL,
|
||
|
|
resource_public_id uuid NOT NULL,
|
||
|
|
permission varchar(24) NOT NULL,
|
||
|
|
result varchar(16) NOT NULL CHECK (result IN ('SUCCESS','DENIED')),
|
||
|
|
reason_code varchar(80),
|
||
|
|
request_id varchar(128),
|
||
|
|
accessed_at timestamptz NOT NULL DEFAULT now(),
|
||
|
|
CONSTRAINT sharing_access_actor_tenant_fk FOREIGN KEY (actor_user_id,tenant_id) REFERENCES user_account(id,tenant_id)
|
||
|
|
);
|
||
|
|
CREATE INDEX sharing_access_grant_time_idx ON sharing_access_log(sharing_grant_id,accessed_at DESC);
|
||
|
|
CREATE INDEX sharing_access_tenant_time_idx ON sharing_access_log(tenant_id,accessed_at DESC);
|
||
|
|
|
||
|
|
COMMIT;
|