File Manager cards, search and sort keyed off file_metadata.print_name,
which ThreeMFParser lifts from the 3MF's <metadata name="Title">. That
title is the in-app project title — generic "Exported 3D Model" for any
Bambu Studio "Save As", a marketing title for a MakerWorld download —
and almost never the filename the user saved as. A card for
Whatever.3mf showed "Exported 3D Model"; correcting it needed a rename
round-trip, since the Rename dialog disables Save while the name is
unchanged.
The slicer-output write path already dropped print_name for this exact
reason; the four other paths that store parsed 3MF metadata onto a
LibraryFile did not — external-folder scan, managed multipart upload,
the multi-file ZIP-upload branch, and MakerWorld import.
Add a shared _without_print_name() helper and apply it at all four
import paths; switch the slicer path to it so there is one rule. A
LibraryFile's display name is its filename — only PrintArchive carries
a real print_name, which is untouched. Remove the now-redundant
filename->print_name mirroring in the rename route.
Add a one-time idempotent data migration (_migrate_drop_library_print_name,
SQLite json_remove / PostgreSQL jsonb key-removal branched on
is_sqlite()) so libraries imported before the fix correct themselves
without the rename workaround. No frontend change: print_name || filename
yields the filename once print_name is gone.
Tests: 6 new in test_library_print_name.py cover _without_print_name and
the migration (incl. idempotency, siblings preserved, null metadata).
SQLite migration branch verified by test; PostgreSQL branch verified
against a real Postgres instance.