Files
SciMesh/coordinator/migrations/0003_artifacts.up.sql
Efremenko Arhip dbf578c500 feat(coordinator): artifact storage foundation (CTX-05, part 1)
Introduce durable, coordinator-owned artifacts — the model the master plan
requires instead of trusting worker-supplied result URIs.

- migration 0003: artifacts table + artifact_kind enum, plus nullable
  input/result_artifact_id columns on jobs and tasks.
- domain.Artifact with NewArtifact/SetContent; storage keys derive from a
  fresh UUID, never from a client filename (no path traversal).
- BlobStore and ArtifactRepository ports.
- blob.FSStore: filesystem blob storage that streams while hashing (SHA-256),
  fsyncs, and atomically renames into place — a failed upload leaves neither a
  committed artifact nor a staging file. Covered by unit tests.
- ArtifactRepo (squirrel) and COORDINATOR_STORAGE_DIR config.

HTTP upload/download handlers and the switch of result submission to
artifact_id come in the next parts.
2026-07-23 14:06:19 +03:00

32 lines
1.5 KiB
PL/PgSQL

BEGIN;
CREATE TYPE artifact_kind AS ENUM ('input','shard','partial_result','final_result','log');
-- A durable file the coordinator owns: input, shard, partial/final result, log.
-- The database is the source of truth; files are found through this metadata,
-- never by scanning directories.
CREATE TABLE artifacts (
id uuid PRIMARY KEY,
job_id uuid NOT NULL REFERENCES jobs(id) ON DELETE CASCADE,
task_id uuid REFERENCES tasks(id) ON DELETE CASCADE, -- null for job-level inputs
kind artifact_kind NOT NULL,
filename text NOT NULL,
storage_key text NOT NULL UNIQUE, -- coordinator-generated, never a client path
content_type text NOT NULL DEFAULT 'application/octet-stream',
size_bytes bigint NOT NULL CHECK (size_bytes >= 0),
sha256 text NOT NULL,
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX ix_artifacts_job ON artifacts (job_id);
CREATE INDEX ix_artifacts_task ON artifacts (task_id);
-- Jobs and tasks reference their artifacts. Nullable during the transition from
-- URI-based inputs/results to artifact-based ones.
ALTER TABLE jobs ADD COLUMN input_artifact_id uuid REFERENCES artifacts(id);
ALTER TABLE jobs ADD COLUMN result_artifact_id uuid REFERENCES artifacts(id);
ALTER TABLE tasks ADD COLUMN input_artifact_id uuid REFERENCES artifacts(id);
ALTER TABLE tasks ADD COLUMN result_artifact_id uuid REFERENCES artifacts(id);
COMMIT;