Files
sciagent/be0/migrations/019_imagehub_cloud_import.sql
T
Thinh Lam 688fac73e9
CI/CD / backend (push) Failing after 2m8s
CI/CD / frontend (push) Failing after 1m40s
CI/CD / deploy (push) Has been skipped
sciagent code + Gitea Actions CI/CD
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 09:38:30 +07:00

54 lines
2.7 KiB
SQL

-- ImageHub: Cloud Import — storage methods + external (referenced, not copied) dataset files.
-- A storage method holds verified credentials (config_encrypted, never returned to the client)
-- for an external bucket (S3/GCS/Azure). A dataset file is then EITHER a local content-addressed
-- blob (blob_sha256 set) OR an external reference (storage_method_id + external_path set) that
-- streams from the bucket and is never copied to our servers (privacy rule C4). Idempotent
-- (CREATE/ADD ... IF NOT EXISTS) so the startup runner can apply it to volumes that predate it.
-- Apply after 018 (no semicolons inside comments or string literals — the runner splitter is naive):
-- docker exec -i initiative-postgres psql -U initiative -d initiatives < be0/migrations/019_imagehub_cloud_import.sql
CREATE TABLE IF NOT EXISTS imagehub_storage_methods (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
owner_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
name TEXT NOT NULL,
provider TEXT NOT NULL CHECK (provider IN ('s3','gcs','azure')),
access_mode TEXT NOT NULL DEFAULT 'read' CHECK (access_mode IN ('read','readwrite')),
bucket TEXT NOT NULL,
region TEXT,
config_encrypted TEXT NOT NULL,
verification_status TEXT NOT NULL DEFAULT 'pending' CHECK (verification_status IN ('pending','verified','failed')),
verification_reason TEXT,
verification_checked_at TIMESTAMPTZ,
created_by UUID REFERENCES users(id) ON DELETE SET NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_imagehub_storage_methods_owner
ON imagehub_storage_methods (owner_id);
-- Allow a dataset file to be an external reference instead of a local blob. Existing rows keep
-- blob_sha256 set and the new columns NULL, so they satisfy the local-blob branch of the CHECK.
ALTER TABLE imagehub_dataset_files
ALTER COLUMN blob_sha256 DROP NOT NULL;
ALTER TABLE imagehub_dataset_files
ADD COLUMN IF NOT EXISTS storage_method_id UUID REFERENCES imagehub_storage_methods(id) ON DELETE RESTRICT;
ALTER TABLE imagehub_dataset_files
ADD COLUMN IF NOT EXISTS external_path TEXT;
-- A file is EITHER a local content-addressed blob OR an external reference, never both or neither.
ALTER TABLE imagehub_dataset_files
DROP CONSTRAINT IF EXISTS ck_imagehub_file_storage_mode;
ALTER TABLE imagehub_dataset_files
ADD CONSTRAINT ck_imagehub_file_storage_mode CHECK (
(blob_sha256 IS NOT NULL AND storage_method_id IS NULL AND external_path IS NULL)
OR
(blob_sha256 IS NULL AND storage_method_id IS NOT NULL AND external_path IS NOT NULL)
);
CREATE INDEX IF NOT EXISTS idx_imagehub_dataset_files_storage_method
ON imagehub_dataset_files (storage_method_id);