feat(scan): embed Switch title IDs into file names during scan - #3883
feat(scan): embed Switch title IDs into file names during scan#3883lucid-void wants to merge 1 commit into
Conversation
Add an opt-in capability (ENABLE_SWITCH_TITLE_ID_RENAME) that renames flat Switch/Switch 2 ROMs lacking a title ID by resolving it from the game name against the cached TitleDB, e.g. `Super Mario Odyssey.nsp` -> `Super Mario Odyssey [0100000000010000][v0].nsp`, so tools that parse title IDs out of the file name (e.g. CyberFoil) can index them. The Switch TitleDB update task now also builds a reverse index (romm:switch_name_to_id) mapping a normalized base-game name to its title ID, keeping only names that resolve to a single base title so ambiguous names are never auto-renamed to the wrong game. The scan hook is conservative: it skips files that already carry an ID, non-served extensions, nested folders, and unresolved/ambiguous names, and moves an already-tracked DB entry and its files onto the new name. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Greptile SummaryThis PR adds optional Switch title ID embedding during scans. The main changes are:
Confidence Score: 4/5The reverse-index refresh can preserve invalid mappings and needs a fix before merging.
backend/tasks/scheduled/update_switch_titledb.py Important Files Changed
Prompt To Fix All With AIFix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
backend/tasks/scheduled/update_switch_titledb.py:114-115
**Stale Name Mappings Survive Refreshes**
This only upserts the current mappings, so a name removed from TitleDB or newly marked ambiguous remains in the Redis hash. A later scan can use that obsolete mapping and permanently rename a ROM with a title ID that the current data no longer considers valid or unique.
Reviews (1): Last reviewed commit: "feat(scan): embed Switch title IDs into ..." | Re-trigger Greptile |
| for name_batch in batched(name_to_id.items(), 2000, strict=False): | ||
| await pipe.hset(SWITCH_NAME_TO_ID_KEY, mapping=dict(name_batch)) |
There was a problem hiding this comment.
Stale Name Mappings Survive Refreshes
This only upserts the current mappings, so a name removed from TitleDB or newly marked ambiguous remains in the Redis hash. A later scan can use that obsolete mapping and permanently rename a ROM with a title ID that the current data no longer considers valid or unique.
Prompt To Fix With AI
This is a comment left during a code review.
Path: backend/tasks/scheduled/update_switch_titledb.py
Line: 114-115
Comment:
**Stale Name Mappings Survive Refreshes**
This only upserts the current mappings, so a name removed from TitleDB or newly marked ambiguous remains in the Redis hash. A later scan can use that obsolete mapping and permanently rename a ROM with a title ID that the current data no longer considers valid or unique.
How can I resolve this? If you propose a fix, please make it concise.|
Thanks for the PRs, this one and #3876. This overlaps with something I already had in progress: a native library ( The filename embedding your PR is going for did make it in, as an opt-in config flag that renames Switch files to embed the id and version for external tools that read it out of the name. That said, I'd rather clients and users pull this from the API than transform or rename files on disk, so the rename is off by default. It's all in #3925. |
Description
Adds an opt-in capability that automatically embeds Nintendo Switch title IDs into ROM file names during a scan, so external tools that parse the title ID out of the file name (e.g. CyberFoil) can index them:
Super Mario Odyssey.nsp → Super Mario Odyssey [0100000000010000][v0].nsp
RomM already caches the blawar TitleDB and pulls a title ID out of file names for metadata matching. This adds the reverse direction (name → title ID) and uses it to rename files that don't yet have one.
How it works
Conservative by design — it skips files that already carry a title ID, non-served extensions, nested/multi-file folders, and any name that is unknown or ambiguous. Requires no Nintendo keys.
Scope / follow-ups
AI assistance disclosure
This PR was written with substantial AI assistance (Claude Code / Claude Opus 4.8): design, implementation, and tests were AI-generated and human-reviewed.
Checklist