metadata: StarTrack ratings should survive a Radarr upgrade without a hand re-key #350

Open
opened 2026-10-01 13:35:47 -04:00 by mysticalsoap · 0 comments
Owner

StarTrack keys everything (ratings, diary, lists, watchlist, likes) by Jellyfin item id, and Jellyfin hashes that id from the file path. Every Radarr upgrade therefore leaves the rating on an id that no longer exists. #340 made featured_sync.py report each orphan once with its OLD=NEW pair and added startrack_rekey.py, but the re-key is still a hand step: stop Jellyfin, run the script as uid 948, start Jellyfin, because the plugin holds its json in memory and rewrites it whole on save. Four orphans were re-keyed on 2026-10-01 and a fifth (Wolf Children) appeared the same day, so this recurs at the upgrade rate.

Pieces, in order of how much they settle:

  1. Provider-id ledger in the pipeline (pipeline only, do first). Each night record item id -> ProviderIds (Tmdb/Imdb/Tvdb), name, year, type for every item StarTrack has a rating on, into state/startrack_ledger.json. Today the mapping leans on movie_poster_state.json, which only knows movies the poster sync processed: one orphan (4c443647…, a 4.5★ Letterboxd import from 2026-05-04) has no record anywhere and is unrecoverable. With the ledger, series and anime resolve too, and nothing rated after this lands can go unidentified.

  2. Re-link inside the plugin (upstream, durable). StarTrack already resolves items through ILibraryManager. Either subscribe to ItemRemoved/ItemAdded and move entries when provider ids match, or store provider ids beside each rating at submit time and resolve lazily on read. No restart, no host step, and it fixes it for every StarTrack user. The upstream tracker has nothing on it (8 open issues as of 2026-09-27); #25 there (persist unmatched Letterboxd ratings) is adjacent.

  3. Admin re-key endpoint (upstream, smaller). POST /Plugins/StarTrack/Rekey {old, new} behind RequiresElevation, so the nightly job can finish the move itself with the server API key and the in-memory store stays consistent. A fallback if 2 is too much.

Not worth it: a Dagu step that stops Jellyfin, edits the json and starts it again. It puts a nightly outage and a docker socket on the path to fix a plugin-shaped problem.

StarTrack keys everything (ratings, diary, lists, watchlist, likes) by Jellyfin item id, and Jellyfin hashes that id from the file path. Every Radarr upgrade therefore leaves the rating on an id that no longer exists. #340 made `featured_sync.py` report each orphan once with its `OLD=NEW` pair and added `startrack_rekey.py`, but the re-key is still a hand step: stop Jellyfin, run the script as uid 948, start Jellyfin, because the plugin holds its json in memory and rewrites it whole on save. Four orphans were re-keyed on 2026-10-01 and a fifth (Wolf Children) appeared the same day, so this recurs at the upgrade rate. Pieces, in order of how much they settle: 1. **Provider-id ledger in the pipeline** (pipeline only, do first). Each night record `item id -> ProviderIds (Tmdb/Imdb/Tvdb), name, year, type` for every item StarTrack has a rating on, into `state/startrack_ledger.json`. Today the mapping leans on `movie_poster_state.json`, which only knows movies the poster sync processed: one orphan (`4c443647…`, a 4.5★ Letterboxd import from 2026-05-04) has no record anywhere and is unrecoverable. With the ledger, series and anime resolve too, and nothing rated after this lands can go unidentified. 2. **Re-link inside the plugin** (upstream, durable). StarTrack already resolves items through `ILibraryManager`. Either subscribe to `ItemRemoved`/`ItemAdded` and move entries when provider ids match, or store provider ids beside each rating at submit time and resolve lazily on read. No restart, no host step, and it fixes it for every StarTrack user. The upstream tracker has nothing on it (8 open issues as of 2026-09-27); #25 there (persist unmatched Letterboxd ratings) is adjacent. 3. **Admin re-key endpoint** (upstream, smaller). `POST /Plugins/StarTrack/Rekey {old, new}` behind `RequiresElevation`, so the nightly job can finish the move itself with the server API key and the in-memory store stays consistent. A fallback if 2 is too much. Not worth it: a Dagu step that stops Jellyfin, edits the json and starts it again. It puts a nightly outage and a docker socket on the path to fix a plugin-shaped problem.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
mysticalsoap/docker#350
No description provided.