Summary
When uploading a file, let the caller optionally name a pipeline so detection (the detect step) starts immediately, instead of requiring a separate run-start call.
Today it's two round-trips: upload the file, then POST a run referencing it. For the common "upload → analyze now" flow, folding the pipeline selection into the upload removes a step and the client-side orchestration between them.
Current state
- Upload —
upload_file (crates/nvisy-server/src/handler/files.rs), Multipart, Permission::UploadFiles. Can carry more than one file per request; returns the created file rows.
- Run start (detect) —
create_pipeline_run (crates/nvisy-server/src/handler/pipeline_runs.rs), route .../pipelines/{pipelineSlug}/runs/. Takes the pipeline from the path and CreatePipelineRun { file_id } in the body; supports Idempotency-Key; creates the run (Running) and analyzes.
So both halves already exist independently — this issue wires an optional trigger from upload into the existing run-start path.
Proposal
Add an optional pipeline selector to the upload request (multipart field, e.g. pipeline_slug). When present:
- Upload/persist the file(s) as today.
- For each uploaded file, start a detection run against the named pipeline — reusing the existing
create_pipeline_run logic (do not duplicate it), including the policy-derived catalog and the empty-policies rejection.
- Return the created file(s) and the started run(s) so the client gets both handles in one response.
Absent the field, upload behaves exactly as today (no run).
Open questions
- Multi-file uploads — upload accepts several files; a pipeline selection would fan out one run per file. Confirm that's the intended semantics (vs. rejecting multi-file + pipeline together).
- Partial failure — file uploaded but run-start fails (e.g. pipeline has no policies → the 400 from #policy-owned-labels work, or pipeline not found). Options: keep the uploaded file and report a per-file run error, or make it transactional. Leaning toward: keep the file, surface a per-file run status in the response (upload succeeded, run failed with reason).
- Permissions — caller now needs both
UploadFiles and RunPipelines; authorize both up front.
- Idempotency — the standalone run endpoint honors
Idempotency-Key; decide how/whether that applies when triggered via upload (one key, many files?).
- Response shape — extend the upload response to include started runs, or return a combined
{ files, runs } envelope. Should stay backward-shaped when no pipeline is selected.
- Async — detection can be slow; confirm the run is started/queued and returned (not awaited) so upload stays responsive.
Out of scope
- Auto-selecting a pipeline (no explicit choice) — this is an opt-in selector, not a default.
- The redact step; this triggers detection only, matching the standalone run-start behavior.
🤖 Generated with Claude Code
Summary
When uploading a file, let the caller optionally name a pipeline so detection (the detect step) starts immediately, instead of requiring a separate run-start call.
Today it's two round-trips: upload the file, then POST a run referencing it. For the common "upload → analyze now" flow, folding the pipeline selection into the upload removes a step and the client-side orchestration between them.
Current state
upload_file(crates/nvisy-server/src/handler/files.rs),Multipart,Permission::UploadFiles. Can carry more than one file per request; returns the created file rows.create_pipeline_run(crates/nvisy-server/src/handler/pipeline_runs.rs), route.../pipelines/{pipelineSlug}/runs/. Takes the pipeline from the path andCreatePipelineRun { file_id }in the body; supportsIdempotency-Key; creates the run (Running) and analyzes.So both halves already exist independently — this issue wires an optional trigger from upload into the existing run-start path.
Proposal
Add an optional pipeline selector to the upload request (multipart field, e.g.
pipeline_slug). When present:create_pipeline_runlogic (do not duplicate it), including the policy-derived catalog and the empty-policies rejection.Absent the field, upload behaves exactly as today (no run).
Open questions
UploadFilesandRunPipelines; authorize both up front.Idempotency-Key; decide how/whether that applies when triggered via upload (one key, many files?).{ files, runs }envelope. Should stay backward-shaped when no pipeline is selected.Out of scope
🤖 Generated with Claude Code