CREATE TABLE IF NOT EXISTS task_artifacts ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE, task_id uuid NOT NULL REFERENCES tasks(id) ON DELETE CASCADE, execution_id uuid NOT NULL REFERENCES task_attempts(id) ON DELETE CASCADE, artifact_index integer NOT NULL CHECK (artifact_index >= 0), artifact_type text NOT NULL, file_name text NOT NULL, content_type text NOT NULL, byte_size bigint NOT NULL CHECK (byte_size > 0), sha256 text NOT NULL CHECK (sha256 ~ '^[a-f0-9]{64}$'), storage_backend text NOT NULL DEFAULT 'database' CHECK (storage_backend IN ('database', 'oss')), storage_key text, content_ciphertext text, created_at timestamptz NOT NULL DEFAULT now(), UNIQUE (task_id, execution_id, artifact_index), CHECK ( (storage_backend = 'database' AND content_ciphertext IS NOT NULL AND storage_key IS NULL) OR (storage_backend = 'oss' AND storage_key IS NOT NULL AND content_ciphertext IS NULL) ) ); CREATE INDEX IF NOT EXISTS task_artifacts_org_task_idx ON task_artifacts (organization_id, task_id, created_at DESC);