docs(13-02): complete library filter UI & phantom resolution plan

- SUMMARY.md updated with checkpoint approval and all bugfix commits
- STATE.md updated with Phase 13 completion and new decisions
- ROADMAP.md plan checkboxes and milestone status updated
- REQUIREMENTS.md coverage updated: 31/31 v1.1 requirements complete
This commit is contained in:
2026-03-16 13:03:35 -04:00
parent 9f595b7ac1
commit 0a5877c177
4 changed files with 153 additions and 80 deletions
+4 -3
View File
@@ -205,10 +205,11 @@ Which phases cover which requirements. Updated during roadmap creation.
| DATA-04 | Phase 10 | Complete | | DATA-04 | Phase 10 | Complete |
**Coverage:** **Coverage:**
- v1.1 requirements: 31 total (20 complete + 11 pending) - v1.1 requirements: 31 total (31 complete)
- Mapped to phases: 31/31 ✓ (Phase 9: 8, Phase 10: 5, Phase 11: 4, Phase 12: 7 of 7 — 11 pending in Phase 13) - Mapped to phases: 31/31 ✓ (Phase 9: 8, Phase 10: 5, Phase 11: 4, Phase 12: 7, Phase 13: 7)
- No orphaned requirements - No orphaned requirements
- All v1.1 requirements complete as of 2026-03-16
--- ---
*Requirements defined: 2026-03-06* *Requirements defined: 2026-03-06*
*Last updated: 2026-03-08restructured for multi-library support, deferred TAG/SMRT/GAP/MB/LAYOUT/PLUG* *Last updated: 2026-03-16all v1.1 requirements complete (31/31)*
+14 -14
View File
@@ -7,8 +7,8 @@
## Milestones ## Milestones
-**v1.0 Consolidation** — Phases 1-8 (shipped 2026-03-05) — [archive](milestones/v1.0-ROADMAP.md) -**v1.0 Consolidation** — Phases 1-8 (shipped 2026-03-05) — [archive](milestones/v1.0-ROADMAP.md)
- 🔄 **v1.1 Multi-Library Support** — Phase 9 complete, Phases 10-13 in progress - **v1.1 Multi-Library Support** — Phases 9-13 complete (shipped 2026-03-16)
- 🔄 **Performance Optimization** — Phase 14 (cross-cutting, parallel to v1.1) - **Performance Optimization** — Phase 14 complete (shipped 2026-03-15)
## Phases ## Phases
@@ -110,8 +110,8 @@ Plans:
5. When a library is removed, its tracks in playlists become phantom entries — visually distinguished (greyed out / icon) with preserved title, artist, album metadata instead of disappearing 5. When a library is removed, its tracks in playlists become phantom entries — visually distinguished (greyed out / icon) with preserved title, artist, album metadata instead of disappearing
**Plans:** 2/2 plans complete **Plans:** 2/2 plans complete
Plans: Plans:
- [ ] 13-01-PLAN.md — Backend library-filtered sqlc queries + Go methods + FTS search - [x] 13-01-PLAN.md — Backend library-filtered sqlc queries + Go methods + FTS search
- [ ] 13-02-PLAN.md — Frontend library filter store + dropdown UI + all view/search wiring + verification - [x] 13-02-PLAN.md — Frontend library filter store + dropdown UI + all view/search wiring + verification
### Phase 14: Performance Optimization ### Phase 14: Performance Optimization
**Goal:** Scrolling, navigation, and rendering are as smooth and fast as possible — scrolling feels like a native animation, navigation is instant, no unnecessary re-renders **Goal:** Scrolling, navigation, and rendering are as smooth and fast as possible — scrolling feels like a native animation, navigation is instant, no unnecessary re-renders
@@ -125,10 +125,10 @@ Plans:
5. A profiling guide documents how to diagnose performance issues using pprof (backend) and DevTools (frontend) 5. A profiling guide documents how to diagnose performance issues using pprof (backend) and DevTools (frontend)
**Plans:** 4/4 plans complete **Plans:** 4/4 plans complete
Plans: Plans:
- [ ] 14-01-PLAN.md — CSS containment + GPU layer promotion on all scroll containers - [x] 14-01-PLAN.md — CSS containment + GPU layer promotion on all scroll containers
- [ ] 14-02-PLAN.md — View caching navigation system (replace innerHTML destruction) - [x] 14-02-PLAN.md — View caching navigation system (replace innerHTML destruction)
- [ ] 14-03-PLAN.md — Render hot-path optimization (closure elimination, store granularity) - [x] 14-03-PLAN.md — Render hot-path optimization (closure elimination, store granularity)
- [ ] 14-04-PLAN.md — Scroll event optimization, profiling guide, performance verification checkpoint - [x] 14-04-PLAN.md — Scroll event optimization, profiling guide, performance verification checkpoint
## Progress ## Progress
@@ -143,12 +143,12 @@ Plans:
| 7. Backend Performance | v1.0 | 2/2 | Complete | 2026-03-05 | | 7. Backend Performance | v1.0 | 2/2 | Complete | 2026-03-05 |
| 8. Frontend Performance & UX | v1.0 | 4/4 | Complete | 2026-03-05 | | 8. Frontend Performance & UX | v1.0 | 4/4 | Complete | 2026-03-05 |
| 9. Scan Cancellation & Keyboard Shortcuts | v1.1 | 5/5 | Complete | 2026-03-07 | | 9. Scan Cancellation & Keyboard Shortcuts | v1.1 | 5/5 | Complete | 2026-03-07 |
| 10. Schema & Migration | 2/2 | Complete | 2026-03-09 | - | | 10. Schema & Migration | v1.1 | 2/2 | Complete | 2026-03-09 |
| 11. Per-Library Scan Pipeline | 3/3 | Complete | 2026-03-09 | - | | 11. Per-Library Scan Pipeline | v1.1 | 3/3 | Complete | 2026-03-09 |
| 12. Library CRUD & Data Integrity | v1.1 | Complete | 2026-03-15 | 2026-03-15 | | 12. Library CRUD & Data Integrity | v1.1 | 2/2 | Complete | 2026-03-15 |
| 13. Library Views & Phantom Tracks | 2/2 | Complete | 2026-03-16 | - | | 13. Library Views & Phantom Tracks | v1.1 | 2/2 | Complete | 2026-03-16 |
| 14. Performance Optimization | 4/4 | Complete | 2026-03-15 | - | | 14. Performance Optimization | Perf | 4/4 | Complete | 2026-03-15 |
--- ---
*Roadmap created: 2026-02-27* *Roadmap created: 2026-02-27*
*Last updated: 2026-03-14Phase 14 (Performance Optimization) added with 4 plans* *Last updated: 2026-03-16v1.1 milestone complete (Phases 9-14 all done)*
+6 -3
View File
@@ -155,6 +155,9 @@ Decisions from v1.0 are archived in PROJECT.md Key Decisions table. Key patterns
| Client-side search with filtered data source | rankTracks filters already-loaded tracks; no backend SearchTracksByLibrary call needed | | Client-side search with filtered data source | rankTracks filters already-loaded tracks; no backend SearchTracksByLibrary call needed |
| Native select for library filter dropdown | Compact, accessible, matches top bar height; no custom component overhead | | Native select for library filter dropdown | Compact, accessible, matches top bar height; no custom component overhead |
| getAlbumsByArtistNameCached returns null when filter active | Avoids stale cross-library data; forces backend query for consistency | | getAlbumsByArtistNameCached returns null when filter active | Avoids stale cross-library data; forces backend query for consistency |
| ScanHooks callback for phantom resolution | Mirrors RemovalHooks/RescanHooks pattern; avoids circular dependency between library and playlist packages |
| phantom_file_path column on playlist_tracks | Stored at removal time for post-scan matching; enables automatic phantom resolution |
| M3U8-based phantom resolution over SQL-only | Reads playlist files to match by position and file path; handles both pre-existing and new phantoms |
### Warnings (carry forward) ### Warnings (carry forward)
@@ -182,9 +185,9 @@ Decisions from v1.0 are archived in PROJECT.md Key Decisions table. Key patterns
### Last Session ### Last Session
**Date:** 2026-03-16 **Date:** 2026-03-16
**What happened:** Executed Plan 13-02 — added library filter dropdown to top bar, wired all browse/detail views to respect library filter via ByLibrary conditional queries. 1 task (auto), 12 files modified. Checkpoint pending for human verification. **What happened:** Completed Plan 13-02 — library filter dropdown in top bar, all views wired to ByLibrary queries, phantom track auto-resolution via ScanHooks. Checkpoint APPROVED — all 7 requirements verified (VIEW-0104, PLAY-0103). Additional bugfixes: virtualizer event delegation race condition, phantom auto-resolution after re-scan.
**Where we stopped:** Completed 13-02-PLAN.md — Phase 13 complete (2/2 plans), awaiting human verification **Where we stopped:** Completed 13-02-PLAN.md — Phase 13 complete (2/2 plans), v1.1 milestone complete
**Next action:** Human verification of library filter, cross-library playlists, and phantom tracks **Next action:** v1.1 milestone shipped — all phases (9-14) complete
--- ---
*State initialized: 2026-02-27* *State initialized: 2026-02-27*
@@ -1,32 +1,40 @@
--- ---
phase: 13-library-views-phantom-tracks phase: 13-library-views-phantom-tracks
plan: 02 plan: 02
subsystem: frontend, ui subsystem: ui, api
tags: [lit, wails, library-filter, dropdown, multi-library] tags: [lit, wails, library-filter, phantom-tracks, playlist-resolution, typescript]
# Dependency graph # Dependency graph
requires: requires:
- phase: 13-library-views-phantom-tracks - phase: 13-library-views-phantom-tracks
provides: Library-filtered Go query methods and Wails bindings plan: 01
provides: Library-filtered sqlc queries and Go methods for tracks, albums, artists, genres, search
- phase: 12-library-crud-data-integrity
provides: Library CRUD API, orphan cleanup, phantom track metadata pre-population
- phase: 10-schema-migration
provides: Libraries table, library_id FK, phantom columns on playlist_tracks
provides: provides:
- Library filter dropdown component in top bar - Library filter dropdown UI in top bar with All Libraries default
- All browse views (tracks, albums, artists, genres) filter by selected library - All browse views (tracks, albums, artists, genres) respect active library filter
- Detail views (artist-details, genre-details) respect library filter - Search respects active library filter
- Search results respect library filter (via filtered data source) - Detail views (artist-details, genre-details, album tracks) respect library filter
- Playlists remain unfiltered (cross-library by design) - Phantom track auto-resolution after library scan via ScanHooks callback
affects: [frontend-navigation, queue-context] - phantom_file_path column on playlist_tracks for phantom-to-track matching
affects: [multi-library-complete, v1.1-milestone]
# Tech tracking # Tech tracking
tech-stack: tech-stack:
added: [] added: []
patterns: patterns:
- Conditional ByLibrary/unfiltered call pattern in library-store - "Conditional Wails binding dispatch: store methods call ByLibrary variant when filter active, default variant otherwise"
- Library filter state as store singleton (null = All Libraries) - "ScanHooks callback for cross-package phantom resolution (mirrors RemovalHooks/RescanHooks pattern)"
- Native select dropdown for compact filter UI - "Deferred event delegation retry in updated() for virtualizer race condition"
- "phantom_file_path stored on removal for post-scan matching"
key-files: key-files:
created: created:
- frontend/src/components/library-filter/library-filter.ts - frontend/src/components/library-filter/library-filter.ts
- backend/playlist/playlist.go (ResolvePhantomTracksAfterScan)
modified: modified:
- frontend/src/store/library-store.ts - frontend/src/store/library-store.ts
- frontend/src/store/controllers/library-controller.ts - frontend/src/store/controllers/library-controller.ts
@@ -37,73 +45,111 @@ key-files:
- frontend/src/components/artists-view/artists-view.ts - frontend/src/components/artists-view/artists-view.ts
- frontend/src/components/genres-view/genres-view.ts - frontend/src/components/genres-view/genres-view.ts
- frontend/src/components/genre-details/genre-details.ts - frontend/src/components/genre-details/genre-details.ts
- frontend/wailsjs/go/library/Library.d.ts - frontend/src/components/track-list/track-list.ts
- frontend/wailsjs/go/library/Library.js - frontend/src/components/queue-panel/queue-panel.ts
- backend/library/crud.go
- backend/library/library.go
- backend/database/database.go
- backend/database/sql/schemas/playlist_tracks.sql
- backend/app.go
key-decisions: key-decisions:
- "Client-side search with library-filtered data source — no backend SearchTracksByLibrary needed since search is already client-side via rankTracks" - "Client-side search with filtered data source — rankTracks filters already-loaded tracks; no backend SearchTracksByLibrary call needed"
- "Null selectedLibraryId = All Libraries (no persistence, resets on restart)" - "Native select for library filter dropdown — compact, accessible, matches top bar height; no custom component overhead"
- "Native select element for dropdown — compact, accessible, no custom widget overhead" - "getAlbumsByArtistNameCached returns null when filter active — avoids stale cross-library data; forces backend query"
- "getAlbumsByArtistNameCached returns null when library filter active — forces backend query for consistency" - "ScanHooks callback pattern for phantom resolution — mirrors RemovalHooks/RescanHooks for cross-package communication"
- "phantom_file_path column on playlist_tracks — enables post-scan matching of phantoms to re-added tracks"
- "M3U8-based phantom resolution — reads playlist files to match phantoms by position and file path"
patterns-established: patterns-established:
- "ByLibrary conditional call pattern: check selectedLibraryId, call ByLibrary or unfiltered variant" - "Conditional ByLibrary dispatch: check selectedLibraryId, call ByLibrary variant or unfiltered default"
- "ScanHooks pattern: cross-package callbacks registered at app init to avoid circular imports"
- "Deferred delegation guard: retry event delegation in updated() when virtualizer not ready on firstUpdated()"
requirements-completed: [VIEW-01, VIEW-02, VIEW-03, VIEW-04, PLAY-01, PLAY-02, PLAY-03] requirements-completed: [VIEW-01, VIEW-02, VIEW-03, VIEW-04, PLAY-01, PLAY-02, PLAY-03]
# Metrics # Metrics
duration: 9min duration: 45min
completed: 2026-03-16 completed: 2026-03-16
--- ---
# Phase 13 Plan 02: Library Filter UI & View Wiring Summary # Phase 13 Plan 02: Library Filter UI & Phantom Track Resolution Summary
**Library filter dropdown in top bar with conditional ByLibrary queries across all browse views, detail views, and search — playlists remain unfiltered** **Library filter dropdown in top bar with conditional ByLibrary queries across all views, plus ScanHooks-based phantom track auto-resolution after library re-scan**
## Performance ## Performance
- **Duration:** 9 min - **Duration:** ~45 min (including checkpoint verification and bugfixes)
- **Started:** 2026-03-16T13:32:45Z - **Started:** 2026-03-16T13:32:45Z
- **Completed:** 2026-03-16T13:41:49Z - **Completed:** 2026-03-16T14:18:00Z
- **Tasks:** 1 (of 2 — Task 2 is human verification checkpoint) - **Tasks:** 2 (1 auto + 1 checkpoint:human-verify — APPROVED)
- **Files modified:** 12 - **Files modified:** 33 (across 4 code commits)
## Accomplishments ## Accomplishments
- Created library-filter dropdown component that loads library list from backend and sets store filter - Created `<library-filter>` dropdown component in top bar — shows "All Libraries" default plus all configured libraries
- Modified library-store to conditionally call ByLibrary or unfiltered queries based on selectedLibraryId - Wired all browse views (tracks, albums, artists, genres) and detail views (artist-details, genre-details, album track expansion) to respect active library filter via conditional ByLibrary Wails binding calls
- Wired all browse views (tracks, albums, artists, genres) to automatically use filtered data - Search inherits library filter automatically — client-side rankTracks operates on filtered track data
- Wired detail views (genre-details direct Wails call, artist-details via store, cover-grid album dropdown) to respect filter - Playlists remain unfiltered (cross-library by design) — verified during checkpoint
- Updated album-selection helper for library-aware drag/context-menu file path resolution - Fixed pre-existing virtualizer event delegation race condition from Phase 14-03 optimization
- Verified playlists use separate PlaylistStore — not affected by library filter - Added phantom track auto-resolution: ScanHooks callback triggers M3U8-based phantom matching after library scan
- Verified search is client-side (rankTracks on loaded data) — inherits filter automatically - Added `phantom_file_path` column (migration 7) to playlist_tracks for reliable phantom→track matching
- All 7 Phase 13 requirements verified end-to-end: VIEW-01 through VIEW-04, PLAY-01 through PLAY-03
## Task Commits ## Task Commits
Each task was committed atomically: Each task was committed atomically:
1. **Task 1: Add library filter state + dropdown + wire all views** - `42b8cf9` (feat) 1. **Task 1: Add library filter state + dropdown + wire all views** - `42b8cf9` (feat)
2. **Task 2: Verify library filter, cross-library playlists, and phantom tracks** - Checkpoint APPROVED
**Task 2:** checkpoint:human-verify (pending user verification) ### Bugfix Commits (during checkpoint verification)
3. **Fix: Defer virtualizer event delegation until element exists** - `f05d2bb` (fix)
4. **Fix: Auto-resolve phantom playlist tracks after library scan** - `93262b9` (fix)
5. **Fix: Resolve phantom playlist tracks using M3U8 paths after scan** - `9f595b7` (fix)
**Plan metadata:** `70e3814` (docs: complete library filter UI plan)
## Files Created/Modified ## Files Created/Modified
- `frontend/src/components/library-filter/library-filter.ts` - NEW: Library filter dropdown component
- `frontend/src/store/library-store.ts` - selectedLibraryId state, ByLibrary conditional calls, getLibraries() ### Frontend — Library filter UI (Task 1)
- `frontend/src/store/controllers/library-controller.ts` - Pass-through for selectedLibraryId, setSelectedLibrary, getLibraries - `frontend/src/components/library-filter/library-filter.ts` — NEW: Library filter dropdown component (native select, design tokens)
- `frontend/index.html` - Added `<library-filter>` to top bar - `frontend/src/store/library-store.ts` — selectedLibraryId state, conditional ByLibrary dispatch, getLibraries(), invalidation
- `frontend/index.ts` - Import library-filter component - `frontend/src/store/controllers/library-controller.ts` — Pass-through for selectedLibraryId, setSelectedLibrary, getLibraries
- `frontend/src/components/cover-grid/cover-grid.ts` - GetAlbumTracksByLibrary in dropdown - `frontend/index.html``<library-filter>` element added to top bar header
- `frontend/src/components/cover-grid/album-selection.ts` - Library-aware fetchAlbumTracks helper - `frontend/index.ts` — Import for library-filter component
- `frontend/src/components/artists-view/artists-view.ts` - GetAlbumsByArtistByLibrary + GetAlbumTracksByLibrary - `frontend/src/components/cover-grid/cover-grid.ts` GetAlbumTracksByLibrary for album expansion dropdown
- `frontend/src/components/genres-view/genres-view.ts` - GetTracksByGenreByLibrary for context menu - `frontend/src/components/cover-grid/album-selection.ts` — Library-aware fetchAlbumTracks helper
- `frontend/src/components/genre-details/genre-details.ts` - GetTracksByGenreByLibrary for track loading - `frontend/src/components/artists-view/artists-view.ts` GetAlbumsByArtistByLibrary + GetAlbumTracksByLibrary
- `frontend/wailsjs/go/library/Library.d.ts` - Regenerated with ByLibrary bindings - `frontend/src/components/genres-view/genres-view.ts` — GetTracksByGenreByLibrary for context menu
- `frontend/wailsjs/go/library/Library.js` - Regenerated with ByLibrary bindings - `frontend/src/components/genre-details/genre-details.ts` — GetTracksByGenreByLibrary for track loading
- `frontend/wailsjs/go/library/Library.d.ts` — Regenerated with ByLibrary bindings
- `frontend/wailsjs/go/library/Library.js` — Regenerated with ByLibrary bindings
### Frontend — Virtualizer race condition fix
- `frontend/src/components/track-list/track-list.ts` — Deferred event delegation with guard flag in updated()
- `frontend/src/components/queue-panel/queue-panel.ts` — Deferred event delegation with guard flag in updated()
### Backend — Phantom track auto-resolution
- `backend/database/database.go` — Migration 7: phantom_file_path column on playlist_tracks
- `backend/database/sql/schemas/playlist_tracks.sql` — phantom_file_path column definition
- `backend/database/sql/sqlcgen/models.go` — Generated model with PhantomFilePath field
- `backend/database/sql/sqlcgen/playlists.sql.go` — Generated query updates
- `backend/library/crud.go` — Store file_path as phantom_file_path on RemoveLibrary
- `backend/library/library.go` — ScanHooks registration, phantom resolution trigger after scan
- `backend/playlist/playlist.go` — ResolvePhantomTracksAfterScan: M3U8-based phantom matching
- `backend/app.go` — ScanHooks wiring at app initialization
- `frontend/wailsjs/go/models.ts` — Updated generated models
- `frontend/wailsjs/go/playlist/Service.d.ts` — Updated generated bindings
- `frontend/wailsjs/go/playlist/Service.js` — Updated generated bindings
## Decisions Made ## Decisions Made
- Search is entirely client-side (rankTracks filters already-loaded tracks), so no backend SearchTracksByLibrary call needed — the library filter naturally scopes search results via the filtered track list - **Client-side search filtering:** rankTracks already operates on filtered track data from library store — no separate backend SearchTracksByLibrary call needed
- Used native `<select>` element for dropdown rather than a custom Lit component — compact, accessible, matches search bar height - **Native `<select>` for library filter:** Compact, accessible, 32px height matching search bar, no custom dropdown overhead
- Library filter resets on app restart (no localStorage persistence) per CONTEXT.md requirement - **getAlbumsByArtistNameCached returns null when filter active:** Forces backend query to avoid showing stale cross-library cached albums
- `getAlbumsByArtistNameCached` returns null when library filter active to avoid stale cross-library data - **ScanHooks callback for phantom resolution:** Mirrors established RemovalHooks/RescanHooks pattern — avoids circular dependency between library and playlist packages
- **M3U8-based phantom resolution over SQL-only:** Reads playlist files to match phantoms by both position and phantom_file_path — handles pre-existing phantoms (match by position) and new ones (match by stored path)
- **phantom_file_path column:** Stored at removal time so post-scan resolution can match even when M3U8 position changes
## Deviations from Plan ## Deviations from Plan
@@ -111,36 +157,59 @@ Each task was committed atomically:
**1. [Rule 3 - Blocking] Wails bindings not yet generated for ByLibrary methods** **1. [Rule 3 - Blocking] Wails bindings not yet generated for ByLibrary methods**
- **Found during:** Task 1 (start) - **Found during:** Task 1 (start)
- **Issue:** Plan 13-01 added Go methods but bindings weren't regenerated - **Issue:** Plan 13-01 added Go methods but Wails bindings weren't regenerated
- **Fix:** Ran `wails generate module` before implementation - **Fix:** Ran `wails generate module` before implementation
- **Files modified:** frontend/wailsjs/go/library/Library.d.ts, Library.js - **Files modified:** frontend/wailsjs/go/library/Library.d.ts, Library.js
- **Verification:** All ByLibrary imports resolve correctly - **Verification:** All ByLibrary imports resolve correctly
- **Committed in:** 42b8cf9 - **Committed in:** `42b8cf9`
**2. [Rule 1 - Bug] Info type uses lowercase property names (id, name) not uppercase** **2. [Rule 1 - Bug] Info type uses lowercase property names**
- **Found during:** Task 1 (TypeScript typecheck) - **Found during:** Task 1 (TypeScript typecheck)
- **Issue:** library-filter.ts used `lib.ID` and `lib.Name` but Wails-generated Info type uses `lib.id` and `lib.name` - **Issue:** library-filter.ts used `lib.ID` and `lib.Name` but Wails-generated Info type uses `lib.id` and `lib.name`
- **Fix:** Changed to lowercase property access - **Fix:** Changed to lowercase property access
- **Files modified:** frontend/src/components/library-filter/library-filter.ts - **Files modified:** frontend/src/components/library-filter/library-filter.ts
- **Verification:** `tsc --noEmit` passes cleanly - **Verification:** `tsc --noEmit` passes cleanly
- **Committed in:** 42b8cf9 - **Committed in:** `42b8cf9`
**3. [Rule 1 - Bug] Virtualizer event delegation race condition**
- **Found during:** Checkpoint verification (Task 2)
- **Issue:** Pre-existing race from Phase 14-03 — event delegation on virtualizer failed when element wasn't rendered yet on firstUpdated()
- **Fix:** Added retry in updated() with guard flag; delegation happens once virtualizer exists
- **Files modified:** frontend/src/components/track-list/track-list.ts, frontend/src/components/queue-panel/queue-panel.ts
- **Verification:** Track list and queue panel click/context-menu events work reliably on app launch
- **Committed in:** `f05d2bb`
**4. [Rule 2 - Missing Critical] Phantom track auto-resolution after library scan**
- **Found during:** Checkpoint verification (Task 2)
- **Issue:** Phantom tracks not auto-resolved when library re-added and scanned — users would need to manually resolve each one
- **Fix:** Added phantom_file_path column (migration 7), store file_path on removal, ResolvePhantomTracksAfterScan via ScanHooks callback with M3U8 path comparison
- **Files modified:** backend/database/database.go, backend/database/sql/schemas/playlist_tracks.sql, backend/library/crud.go, backend/library/library.go, backend/playlist/playlist.go, backend/app.go
- **Verification:** Remove library → re-add → scan → phantoms automatically resolve to real tracks
- **Committed in:** `93262b9`, `9f595b7`
--- ---
**Total deviations:** 2 auto-fixed (1 blocking, 1 bug) **Total deviations:** 4 auto-fixed (2 bugs, 1 blocking, 1 missing critical)
**Impact on plan:** Both fixes required for compilation. No scope creep. **Impact on plan:** All fixes essential for correctness. Virtualizer fix resolved pre-existing race condition exposed by multi-library testing. Phantom auto-resolution is critical UX — users should not need to manually fix playlist tracks after re-adding a library.
## Issues Encountered ## Issues Encountered
None None beyond the deviations documented above.
## User Setup Required ## User Setup Required
None - no external service configuration required. None - no external service configuration required.
## Next Phase Readiness ## Next Phase Readiness
- All automated implementation complete — awaiting human verification checkpoint (Task 2) - **Phase 13 complete**All 7 requirements verified (VIEW-01 through VIEW-04, PLAY-01 through PLAY-03)
- After verification: Phase 13 complete, multi-library support fully delivered - **v1.1 Multi-Library Support milestone complete** — Phases 9-13 all done
- v1.1 milestone only needs final Phase 13 checkpoint approval - **Phase 14 (Performance Optimization) already complete** — executed in parallel during v1.1 development
- All browse views, search, playlists, and phantom tracks working correctly in multi-library context
## Self-Check: PASSED
- All 10 key files exist on disk
- All 5 commits found in git log (42b8cf9, f05d2bb, 93262b9, 9f595b7, 70e3814)
- SUMMARY.md exists at expected path
--- ---
*Phase: 13-library-views-phantom-tracks* *Phase: 13-library-views-phantom-tracks*