-- ImageHub: per-file work TASKS that flow through a dataset's pipeline stages (single-user MVP). -- A task is a NEW join row (one per dataset file) carrying its pipeline position (current_stage_id -- + pipeline_state), per-user queue status, assignee, priority, and the Ground-Truth reference flag. -- The file row itself (imagehub_dataset_files) stays a pure storage record. Membership / multi-labeler -- assignment is a later phase, so for now task access reuses the dataset owner-or-admin gate. -- Idempotent (CREATE ... IF NOT EXISTS) so the startup runner can apply it to volumes that predate it. -- Apply after 020 (no semicolons inside comments or string literals — the runner splitter is naive): -- docker exec -i initiative-postgres psql -U initiative -d initiatives < be0/migrations/021_imagehub_task_pipeline.sql CREATE TABLE IF NOT EXISTS imagehub_tasks ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), dataset_id UUID NOT NULL REFERENCES imagehub_datasets(id) ON DELETE CASCADE, dataset_file_id UUID NOT NULL REFERENCES imagehub_dataset_files(id) ON DELETE CASCADE, name TEXT NOT NULL DEFAULT '', current_stage_id UUID REFERENCES imagehub_dataset_stages(id) ON DELETE SET NULL, pipeline_state TEXT NOT NULL DEFAULT 'inLabel' CHECK (pipeline_state IN ('inLabel','inReview','groundTruth','issue')), queue_status TEXT NOT NULL DEFAULT 'assigned' CHECK (queue_status IN ('assigned','saved','pendingFinalization','skipped')), assignee_user_id UUID REFERENCES users(id) ON DELETE SET NULL, assignment_mode TEXT NOT NULL DEFAULT 'auto' CHECK (assignment_mode IN ('auto','manual')), priority DOUBLE PRECISION NOT NULL DEFAULT 0 CHECK (priority >= 0 AND priority <= 1), is_reference_standard BOOLEAN NOT NULL DEFAULT FALSE, skipped_seq BIGINT, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); -- One task per file (MVP simplification — droppable later for multi-task-per-file). CREATE UNIQUE INDEX IF NOT EXISTS uq_imagehub_tasks_file ON imagehub_tasks (dataset_file_id); -- Queue scan: a dataset's tasks at a given stage and status, highest priority first. CREATE INDEX IF NOT EXISTS idx_imagehub_tasks_queue ON imagehub_tasks (dataset_id, current_stage_id, queue_status, priority DESC); -- A user's personal labeling queue across datasets. CREATE INDEX IF NOT EXISTS idx_imagehub_tasks_assignee ON imagehub_tasks (assignee_user_id, queue_status);