From ce6b3b1d3b848bb6b39111aba00f3f1b463033fe Mon Sep 17 00:00:00 2001 From: dank Date: Sat, 31 Oct 2026 00:10:50 -0700 Subject: [PATCH] docs(media): how to prove a relayout landed, read from both servers' tables A scan answers 204 whether or not it found anything, so proof is the journal replayed against Jellyfin's BaseItems.Path and Plex's media_parts.file: every move has a row at its dst, no row names its src. Records the four wrong doors: no sqlite3 binary on the hosts or in either container, Jellyfin's single BaseItems table (no MediaItems), its container-side /data path prefix, and Plex's HTTPD closing on ?path= / on /search matching titles not paths. --- .../Dankserver/Media Relayout.md | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/serverAppConfigs-docs/Dankserver/Media Relayout.md b/serverAppConfigs-docs/Dankserver/Media Relayout.md index 00f2ecd..dd17018 100644 --- a/serverAppConfigs-docs/Dankserver/Media Relayout.md +++ b/serverAppConfigs-docs/Dankserver/Media Relayout.md @@ -111,6 +111,30 @@ shred -u /tmp/jf.hdr `204` is acceptance; the scan then runs on the server's own schedule. +### Proving the move landed + +A scan answers `204` whether or not it finds anything, so proof is the journal +replayed against both servers' own tables: every `move` row has a row at its +`dst`, and **zero** rows still name its `src`. There is no `sqlite3` binary on +these hosts and none inside either container — read the DBs with the host +`python3` and `mode=ro&immutable=1`, which takes no lock while the server runs. + +| | path | path column | shape | +|---|---|---|---| +| Jellyfin | `/home/dank/Containers/jellyfin/config/data/jellyfin.db` | `BaseItems.Path` | one `BaseItems` table; `Type` holds the .NET class (`…Entities.TV.Episode`). There is no `MediaItems`/`TypedItems`. | +| Plex | `/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db` | `media_parts.file` | join `media_parts → media_items → metadata_items`; filter `deleted_at is null` on **both** or deleted scans pollute the count. | + +**Jellyfin stores container-side paths.** The share binds `/mnt/entropy → /data` +in that container, so a journal `src` of `/mnt/entropy/TVShows/…` is stored as +`/data/TVShows/…`. Plex is bound at the same path it has on the host, so its +rows match the journal verbatim. + +Three doors that look right and are not: `GET /search?query=` matches metadata +titles, never file paths; `?path=` on `/library/sections/N/all` makes Plex's +HTTPD close without a single byte; and the same HTTPD drops requests that carry +no `Accept` and client-identifier header (see the scan block above for the form +that works). + ## TV in the movie library A box set that arrives in the movie share stays there until someone moves it: