Reprocess a DDS record

Async orchestration that cuts a new version (v_{n+1}) of the record's current snapshot — re-resolving plots, re-running assessments, and optionally re-pinning deforestation against a new end_date. Each reprocess is tracked as a dds_record_task row under the hood; the wire endpoints retain /tasks for backwards compatibility but the user-facing concept is reprocess.

The only operation today is create_version (build v_{n+1} from v_n). Steps are documented in Create Reprocess: re-run assessments, optionally add unaccounted plots, optionally re-pin deforestation, then atomically insert v_{n+1}.

Endpoints

SeqMethodPathPurpose
1POST/dds/:recordId/tasksKick off a reprocess — 202 with the reprocess envelope
2GET/dds/:recordId/tasksPaginated history (newest first)
3GET/dds/:recordId/tasks/:taskIdSingle reprocess status

Concurrency

At most one reprocess per record. A second POST while a reprocess is pending or processing returns 409 CONFLICT. Once it reaches completed or failed the record is unlocked and a new one can be cut.

State machine

pending  →  processing  →  completed
                        ↘  failed

Failures leave the row in failed with error_message set. The orchestration is atomic on success: v_{n+1} is only inserted once every sub-step succeeds, so a failed reprocess never leaves a half-created version behind.

Visibility

Reprocess rows are scoped to the parent record's organization. A GET against a record (or reprocess id) the caller can't see returns 404 so existence isn't leaked across orgs.

Required scope: ingestions:write for the POST, ingestions:read for the GETs.