chore: establish local platform baseline
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE upload_batch (
|
||||
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,
|
||||
device_id uuid NOT NULL,
|
||||
idempotency_key varchar(128) NOT NULL,
|
||||
manifest_digest char(64) NOT NULL,
|
||||
status varchar(24) NOT NULL DEFAULT 'PENDING'
|
||||
CHECK (status IN ('PENDING', 'UPLOADING', 'VERIFYING', 'COMPLETED', 'FAILED', 'EXPIRED')),
|
||||
segment_count integer NOT NULL CHECK (segment_count > 0),
|
||||
expected_total_size bigint NOT NULL CHECK (expected_total_size > 0),
|
||||
verified_count integer NOT NULL DEFAULT 0 CHECK (verified_count >= 0),
|
||||
rejected_count integer NOT NULL DEFAULT 0 CHECK (rejected_count >= 0),
|
||||
verification_attempts integer NOT NULL DEFAULT 0 CHECK (verification_attempts >= 0),
|
||||
last_error_code varchar(80),
|
||||
expires_at timestamptz NOT NULL,
|
||||
completed_at timestamptz,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
CONSTRAINT upload_batch_conversation_tenant_fk FOREIGN KEY (conversation_id, tenant_id)
|
||||
REFERENCES conversation (id, tenant_id),
|
||||
CONSTRAINT upload_batch_device_tenant_fk FOREIGN KEY (device_id, tenant_id)
|
||||
REFERENCES device (id, tenant_id),
|
||||
CONSTRAINT upload_batch_id_tenant_key UNIQUE (id, tenant_id),
|
||||
CONSTRAINT upload_batch_idempotency_key UNIQUE (device_id, conversation_id, idempotency_key)
|
||||
);
|
||||
CREATE INDEX upload_batch_device_status_idx ON upload_batch (device_id, status, updated_at DESC);
|
||||
CREATE INDEX upload_batch_conversation_time_idx ON upload_batch (tenant_id, conversation_id, created_at DESC);
|
||||
|
||||
CREATE TABLE media_segment (
|
||||
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,
|
||||
device_id uuid NOT NULL,
|
||||
track varchar(8) NOT NULL CHECK (track IN ('near', 'far')),
|
||||
sequence_no integer NOT NULL CHECK (sequence_no >= 0),
|
||||
codec varchar(32) NOT NULL,
|
||||
content_type varchar(100) NOT NULL,
|
||||
duration_ms integer NOT NULL CHECK (duration_ms > 0),
|
||||
expected_size bigint NOT NULL CHECK (expected_size > 0),
|
||||
expected_digest char(64) NOT NULL,
|
||||
object_ref varchar(700) UNIQUE,
|
||||
encryption_key_ref varchar(300) NOT NULL DEFAULT 'object-store-managed',
|
||||
status varchar(24) NOT NULL DEFAULT 'DECLARED'
|
||||
CHECK (status IN ('DECLARED', 'AUTHORIZED', 'UPLOADED', 'VERIFYING', 'VERIFIED', 'REJECTED', 'DELETED')),
|
||||
verification_attempts integer NOT NULL DEFAULT 0 CHECK (verification_attempts >= 0),
|
||||
last_error_code varchar(80),
|
||||
uploaded_at timestamptz,
|
||||
verified_at timestamptz,
|
||||
deleted_at timestamptz,
|
||||
local_delete_after timestamptz,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
CONSTRAINT media_segment_conversation_tenant_fk FOREIGN KEY (conversation_id, tenant_id)
|
||||
REFERENCES conversation (id, tenant_id),
|
||||
CONSTRAINT media_segment_device_tenant_fk FOREIGN KEY (device_id, tenant_id)
|
||||
REFERENCES device (id, tenant_id),
|
||||
CONSTRAINT media_segment_id_tenant_key UNIQUE (id, tenant_id),
|
||||
CONSTRAINT media_segment_track_sequence_key UNIQUE (conversation_id, track, sequence_no)
|
||||
);
|
||||
CREATE INDEX media_segment_conversation_track_idx ON media_segment (tenant_id, conversation_id, track, sequence_no);
|
||||
|
||||
CREATE TABLE upload_batch_segment (
|
||||
upload_batch_id uuid NOT NULL,
|
||||
media_segment_id uuid NOT NULL,
|
||||
tenant_id uuid NOT NULL REFERENCES tenant(id),
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (upload_batch_id, media_segment_id),
|
||||
CONSTRAINT upload_batch_segment_batch_tenant_fk FOREIGN KEY (upload_batch_id, tenant_id)
|
||||
REFERENCES upload_batch (id, tenant_id),
|
||||
CONSTRAINT upload_batch_segment_media_tenant_fk FOREIGN KEY (media_segment_id, tenant_id)
|
||||
REFERENCES media_segment (id, tenant_id)
|
||||
);
|
||||
CREATE INDEX upload_batch_segment_media_idx ON upload_batch_segment (media_segment_id, upload_batch_id);
|
||||
|
||||
CREATE TABLE recording_access_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),
|
||||
subject_id uuid NOT NULL,
|
||||
grantee_user_id uuid NOT NULL,
|
||||
permission varchar(16) NOT NULL CHECK (permission IN ('PLAY', 'DOWNLOAD')),
|
||||
purpose varchar(120) NOT NULL,
|
||||
granted_by uuid NOT NULL,
|
||||
granted_at timestamptz NOT NULL DEFAULT now(),
|
||||
expires_at timestamptz NOT NULL,
|
||||
revoked_at timestamptz,
|
||||
revoked_by uuid,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
CONSTRAINT recording_access_subject_tenant_fk FOREIGN KEY (subject_id, tenant_id)
|
||||
REFERENCES subject_profile (id, tenant_id),
|
||||
CONSTRAINT recording_access_grantee_tenant_fk FOREIGN KEY (grantee_user_id, tenant_id)
|
||||
REFERENCES user_account (id, tenant_id),
|
||||
CONSTRAINT recording_access_grantor_tenant_fk FOREIGN KEY (granted_by, tenant_id)
|
||||
REFERENCES user_account (id, tenant_id),
|
||||
CONSTRAINT recording_access_revoker_tenant_fk FOREIGN KEY (revoked_by, tenant_id)
|
||||
REFERENCES user_account (id, tenant_id),
|
||||
CONSTRAINT recording_access_expiry_check CHECK (expires_at > granted_at),
|
||||
CONSTRAINT recording_access_revoke_check CHECK (revoked_at IS NULL OR revoked_at >= granted_at),
|
||||
CONSTRAINT recording_access_id_tenant_key UNIQUE (id, tenant_id)
|
||||
);
|
||||
CREATE INDEX recording_access_lookup_idx
|
||||
ON recording_access_grant (tenant_id, subject_id, grantee_user_id, permission, expires_at DESC)
|
||||
WHERE revoked_at IS NULL;
|
||||
|
||||
CREATE TABLE media_access_log (
|
||||
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),
|
||||
actor_user_id uuid NOT NULL,
|
||||
conversation_id uuid NOT NULL,
|
||||
media_segment_id uuid NOT NULL,
|
||||
action varchar(16) NOT NULL CHECK (action IN ('PLAY', 'DOWNLOAD')),
|
||||
purpose varchar(120) NOT NULL,
|
||||
result varchar(16) NOT NULL CHECK (result IN ('SUCCESS', 'DENIED', 'FAILED')),
|
||||
reason_code varchar(80),
|
||||
request_id varchar(128),
|
||||
occurred_at timestamptz NOT NULL DEFAULT now(),
|
||||
CONSTRAINT media_access_actor_tenant_fk FOREIGN KEY (actor_user_id, tenant_id)
|
||||
REFERENCES user_account (id, tenant_id),
|
||||
CONSTRAINT media_access_conversation_tenant_fk FOREIGN KEY (conversation_id, tenant_id)
|
||||
REFERENCES conversation (id, tenant_id),
|
||||
CONSTRAINT media_access_segment_tenant_fk FOREIGN KEY (media_segment_id, tenant_id)
|
||||
REFERENCES media_segment (id, tenant_id)
|
||||
);
|
||||
CREATE INDEX media_access_resource_time_idx ON media_access_log (tenant_id, media_segment_id, occurred_at DESC);
|
||||
CREATE INDEX media_access_actor_time_idx ON media_access_log (tenant_id, actor_user_id, occurred_at DESC);
|
||||
|
||||
COMMIT;
|
||||
Reference in New Issue
Block a user