fix: key melody binary storage on pid instead of uid, add migration script
melody.uid is never actually populated anywhere in MelodyForm.jsx, so keying local .bsm storage on it (as the previous commit did) would silently break for every existing melody. pid is the correct key anyway: it identifies the underlying archetype binary, and multiple melodies legitimately share one pid (each remaps the same note sequence to different bells/speed/duration via its own settings). Deletion is now share-aware — a melody's binary is only removed from disk once no other melody still references its pid. Also adds backend/scripts/migrate_melody_binaries_to_local.py to backfill existing melodies from their old Firebase URLs to local storage, with --dry-run support and a warning list for pids whose melodies point at different source files (a pre-existing data issue, flagged for manual review via each melody's playback button rather than silently resolved). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -151,8 +151,9 @@ async def upload_file(
|
||||
|
||||
if file_type == "binary":
|
||||
content_type = "application/octet-stream"
|
||||
if not melody.pid:
|
||||
raise HTTPException(status_code=400, detail="Melody must have a PID before uploading a binary")
|
||||
url = service.save_binary_for_melody(
|
||||
melody_uid=melody.uid,
|
||||
pid=melody.pid,
|
||||
file_bytes=contents,
|
||||
)
|
||||
@@ -191,7 +192,7 @@ async def delete_file(
|
||||
raise HTTPException(status_code=400, detail="file_type must be 'binary' or 'preview'")
|
||||
|
||||
melody = await service.get_melody(melody_id)
|
||||
service.delete_file(melody_id, file_type, melody.uid)
|
||||
await service.delete_file(melody_id, file_type, melody.uid, melody.pid)
|
||||
|
||||
|
||||
@router.get("/{melody_id}/files")
|
||||
@@ -228,7 +229,7 @@ async def download_binary_file(
|
||||
):
|
||||
"""Download current melody binary with a PID-based filename."""
|
||||
melody = await service.get_melody(melody_id)
|
||||
file_bytes, content_type = service.get_binary_file_bytes(melody_id, melody.uid)
|
||||
file_bytes, content_type = service.get_binary_file_bytes(melody_id, melody.pid)
|
||||
filename = f"{(melody.pid or 'binary')}.bsm"
|
||||
headers = {"Content-Disposition": f'attachment; filename="{filename}"'}
|
||||
return Response(content=file_bytes, media_type=content_type, headers=headers)
|
||||
|
||||
Reference in New Issue
Block a user