From 723eee9773e185bd017b5ecb23c18bc369382a32 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Sat, 2 May 2026 22:28:49 -0400 Subject: [PATCH] =?UTF-8?q?docs(m7):=20revise=20#372=20spec=20=E2=80=94=20?= =?UTF-8?q?Remove=20from=20library=20no=20longer=20goes=20via=20Lidarr?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Operator decision during Task 2 implementation: routing track removal through lidarrquarantine.DeleteViaLidarr is wrong because Lidarr is album-granular (no per-track delete). The original spec would have silently deleted sibling tracks. New shape: - Always delete file + DB row + cascade through Minstrel (os.Remove). - Confirm dialog asks "find a replacement?": Yes (default — no Lidarr call; monitoring re-imports on next scan) or No (call new Lidarr.UnmonitorTrack(mbid) primitive). - Lidarr unmonitor failure is non-fatal — sets lidarr_unmonitor_failed on the success envelope so the UI toasts a follow-up message. Adds a new internal/lidarr.UnmonitorTrack method (LookupTrack → PUT /api/v1/track/monitor with monitored:false) to Task 2's scope. Wire codes lidarr_unreachable / lidarr_unauthorized / lidarr_server_error no longer come back from this endpoint. --- ...2026-05-03-m7-track-actions-menu-design.md | 80 +++++++++++-------- 1 file changed, 45 insertions(+), 35 deletions(-) diff --git a/docs/superpowers/specs/2026-05-03-m7-track-actions-menu-design.md b/docs/superpowers/specs/2026-05-03-m7-track-actions-menu-design.md index 4141baff..ba2d5d56 100644 --- a/docs/superpowers/specs/2026-05-03-m7-track-actions-menu-design.md +++ b/docs/superpowers/specs/2026-05-03-m7-track-actions-menu-design.md @@ -20,7 +20,7 @@ Per-track kebab menu wherever `` or the `` track display is - "Like / Unlike" and "Hide / Unhide" entries duplicate functionality already on the row (heart and eye icon buttons). Reason: keyboard discoverability — once the kebab is focused, arrow-keys reach every action; mouse users still get one-tap heart/eye on the row. - "Add to playlist…" reserves the menu slot but the submenu of playlists is wired in #352, not here. The slot renders as disabled with a tooltip "Coming with playlists" until #352 ships. - "Go to artist" is single-target (`track.artistId`); compilation/feature artists aren't modeled in the schema today and that's a schema problem to solve before this entry needs a submenu. -- "Remove from library" is admin-only — gated client-side by `currentUser.is_admin`, server-side by the existing `auth.RequireAdmin()` middleware on the new `/api/admin/tracks/{id}` route. New backend endpoint deletes the track row, removes the file from disk (or via Lidarr for Lidarr-managed tracks), and cascades album → artist tidy-up if either becomes empty. +- "Remove from library" is admin-only — gated client-side by `currentUser.is_admin`, server-side by `auth.RequireAdmin()` on the new `/api/admin/tracks/{id}` route. The endpoint always deletes the file from disk via `os.Remove` (not via Lidarr, which is album-granular and has no per-track delete) plus the DB row, then cascades album → artist tidy-up. For Lidarr-managed tracks the operator chooses whether Lidarr should look for a replacement (default — no extra action; Lidarr's monitoring re-imports on next scan) or the track should be unmonitored (server calls `Lidarr.UnmonitorTrack(mbid)` to flip `monitored: false`). The `?unmonitor=true` query param drives this — unset / `false` = replace, `true` = unmonitor. - Keyboard accessibility: kebab is `