Context
The SQL-on-FHIR spec (operations-common, as amended by HL7/sql-on-fhir#365) says servers SHOULD clean up any partial results when an export is cancelled via DELETE on the status URL.
Today, cancelling a $viewdefinition-export / $sqlquery-export job correctly transitions it to Cancelled (polls return 404, and as of the cancellation-race fix the background task can no longer resurrect it), but already-written output shards are never deleted and remain downloadable via GET /export/{job_id}/{filename} — read_shard checks tenant ownership only, not job status (crates/rest/src/export/in_memory.rs).
Proposed change
- Add a
delete_job(&self, job_id: &str) API to the ExportSink trait (crates/rest/src/export/sink.rs) and implement it for all three sinks:
FilesystemSink — remove_dir_all on the job directory
InMemorySink — drop matching keys
S3Sink — ListObjectsV2 on the {prefix}exports/{job_id}/ key prefix + delete objects
- Call it from the cancellation path (and from the background task when it finishes a job that was cancelled mid-run).
- Optionally also gate
read_shard on job status so cancelled jobs' files 404 even before deletion completes.
Severity
Spec SHOULD (not SHALL). Tenant isolation on the download route is already enforced, so this is a cleanup/storage-hygiene gap, not an access-control one.
Context
The SQL-on-FHIR spec (operations-common, as amended by HL7/sql-on-fhir#365) says servers SHOULD clean up any partial results when an export is cancelled via
DELETEon the status URL.Today, cancelling a
$viewdefinition-export/$sqlquery-exportjob correctly transitions it toCancelled(polls return 404, and as of the cancellation-race fix the background task can no longer resurrect it), but already-written output shards are never deleted and remain downloadable viaGET /export/{job_id}/{filename}—read_shardchecks tenant ownership only, not job status (crates/rest/src/export/in_memory.rs).Proposed change
delete_job(&self, job_id: &str)API to theExportSinktrait (crates/rest/src/export/sink.rs) and implement it for all three sinks:FilesystemSink—remove_dir_allon the job directoryInMemorySink— drop matching keysS3Sink—ListObjectsV2on the{prefix}exports/{job_id}/key prefix + delete objectsread_shardon job status so cancelled jobs' files 404 even before deletion completes.Severity
Spec SHOULD (not SHALL). Tenant isolation on the download route is already enforced, so this is a cleanup/storage-hygiene gap, not an access-control one.