Archives created from prints Bambuddy didn't archive (cloud / Handy /
SD-card prints) carry file_path="". The two source-upload routes
computed the destination as (base_dir / archive.file_path).parent /
"source", which collapsed to base_dir.parent / "source" for fallback
rows — sending the file to /app/source/ (outside the data volume,
orphaned on container restart) and raising 500 on the final
relative_to.
Centralise the destination math in _resolve_source_3mf_path. Normal
archives keep the <archive>/source/<filename> layout. Fallback
archives land at <base_dir>/archive/no_source/<id>/<filename>, which
stays inside the data volume and is addressable by every existing
read site. The helper also asserts the resolved directory is under
base_dir.resolve() so a corrupted row fails with a clear message
instead of writing outside the volume.
Both upload routes (upload_source_3mf and upload_source_3mf_by_name)
now route through the helper. Two regression tests in
TestUploadSourceThreeMF pin both branches.