diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 60bd8f3..5ccb10d 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -40,10 +40,10 @@ Requirements for v1.1 Multi-Library Support milestone. Each maps to roadmap phas ### Unified Presentation -- [ ] **VIEW-01**: Default view shows tracks from all libraries merged (unified presentation) -- [ ] **VIEW-02**: User can filter the track list to show only tracks from a specific library -- [ ] **VIEW-03**: Browse views (albums, artists, genres) work across all libraries or filtered to one -- [ ] **VIEW-04**: Search (FTS5) searches across all libraries or respects the active library filter +- [x] **VIEW-01**: Default view shows tracks from all libraries merged (unified presentation) +- [x] **VIEW-02**: User can filter the track list to show only tracks from a specific library +- [x] **VIEW-03**: Browse views (albums, artists, genres) work across all libraries or filtered to one +- [x] **VIEW-04**: Search (FTS5) searches across all libraries or respects the active library filter ### Playlists & Queue @@ -191,10 +191,10 @@ Which phases cover which requirements. Updated during roadmap creation. | LSCAN-03 | Phase 11 | Complete | | LSCAN-04 | Phase 11 | Complete | | LSCAN-05 | Phase 10 | Complete | -| VIEW-01 | Phase 13 | Pending | -| VIEW-02 | Phase 13 | Pending | -| VIEW-03 | Phase 13 | Pending | -| VIEW-04 | Phase 13 | Pending | +| VIEW-01 | Phase 13 | Complete | +| VIEW-02 | Phase 13 | Complete | +| VIEW-03 | Phase 13 | Complete | +| VIEW-04 | Phase 13 | Complete | | PLAY-01 | Phase 13 | Pending | | PLAY-02 | Phase 13 | Pending | | PLAY-03 | Phase 13 | Pending | diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index e650b05..02717df 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -108,7 +108,7 @@ Plans: 3. Search results respect the active library filter — searching with a library selected returns only matches from that library; with "All Libraries" selected, searches everything 4. Playlists can contain tracks from multiple libraries — adding tracks from different libraries to the same playlist works naturally 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 plans +**Plans:** 1/2 plans executed Plans: - [ ] 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 @@ -146,7 +146,7 @@ Plans: | 10. Schema & Migration | 2/2 | Complete | 2026-03-09 | - | | 11. Per-Library Scan Pipeline | 3/3 | Complete | 2026-03-09 | - | | 12. Library CRUD & Data Integrity | v1.1 | Complete | 2026-03-15 | 2026-03-15 | -| 13. Library Views & Phantom Tracks | v1.1 | 0/2 | Planned | - | +| 13. Library Views & Phantom Tracks | 1/2 | In Progress| | - | | 14. Performance Optimization | 4/4 | Complete | 2026-03-15 | - | --- diff --git a/.planning/STATE.md b/.planning/STATE.md index 1e93ddf..18256ea 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,12 +3,12 @@ gsd_state_version: 1.0 milestone: v1.1 milestone_name: Multi-Library Support status: unknown -last_updated: "2026-03-15T14:29:07.641Z" +last_updated: "2026-03-16T13:30:46.193Z" progress: - total_phases: 5 + total_phases: 6 completed_phases: 5 - total_plans: 16 - completed_plans: 16 + total_plans: 18 + completed_plans: 17 --- # YellowJacket — Project State @@ -22,11 +22,11 @@ See: .planning/PROJECT.md (updated 2026-03-08) ## Current Position -Phase: 12 — Library CRUD & Data Integrity (completed), 13 next -Plan: 2 of 2 in Phase 12 (complete) -Status: Plan 12-02 complete — frontend library management UI verified -Progress: ████████████████████ Phase 12 complete (2/2 plans), Phase 14 complete (4/4 plans) -Last activity: 2026-03-16 — Completed quick task 19: fix phantom playlist tracks +Phase: 13 — Library Views & Phantom Tracks (in progress) +Plan: 1 of 2 in Phase 13 (complete) +Status: Plan 13-01 complete — library-filtered backend queries +Progress: ██████████░░░░░░░░░░ Phase 13 in progress (1/2 plans) +Last activity: 2026-03-16 — Completed 13-01: library-filtered backend queries ### Phase Overview @@ -36,7 +36,7 @@ Last activity: 2026-03-16 — Completed quick task 19: fix phantom playlist trac | 10. Schema & Migration | Complete (2/2 plans) ✅ | | 11. Per-Library Scan Pipeline | Complete (3/3 plans) ✅ | | 12. Library CRUD & Data Integrity | Complete (2/2 plans) ✅ | -| 13. Library Views & Phantom Tracks | Not started | +| 13. Library Views & Phantom Tracks | In Progress (1/2 plans) | | 14. Performance Optimization | Complete (4/4 plans) ✅ | ## Performance Metrics @@ -62,6 +62,7 @@ Last activity: 2026-03-16 — Completed quick task 19: fix phantom playlist trac | Phase 14-01 P01 | 3 min | 2 tasks | 7 files | | Phase 14-04 P04 | 2 min | 2 tasks | 3 files | | Phase 12-02 P02 | 38 min | 3 tasks | 19 files | +| Phase 13 P01 | 5 min | 2 tasks | 10 files | ## Accumulated Context @@ -144,6 +145,13 @@ Decisions from v1.0 are archived in PROJECT.md Key Decisions table. Key patterns | RAF throttle over debounce for scroll saves | Saves position once per frame during scrolling, not just after stop; prevents lost positions on quick navigation | | Keep monkey-patch alongside overflow-anchor CSS | CSS overflow-anchor disables browser anchoring but not lit-virtualizer's internal _correctScrollError | +### Phase 13 Decisions + +| Decision | Rationale | +|----------|-----------| +| IN-subquery pattern for album/artist/genre library filtering | Entities are global, tracks belong to libraries; subquery filters entity IDs by library membership | +| Empty slice return (not error) for library with no tracks | Empty library is valid state, not error condition; callers handle empty UI | + ### Warnings (carry forward) - Player lock ordering (`p.mu` before `speaker.Lock()`, goroutine dispatch in beep callback) — carry forward @@ -169,10 +177,10 @@ Decisions from v1.0 are archived in PROJECT.md Key Decisions table. Key patterns ### Last Session -**Date:** 2026-03-15 -**What happened:** Finalized Plan 12-02 — frontend library management UI. Code was implemented across 25 commits in previous sessions; this session created SUMMARY.md after human verification checkpoint passed (all 9 checks approved). -**Where we stopped:** Completed 12-02-PLAN.md — Phase 12 complete (2/2 plans) -**Next action:** Plan Phase 13: Library Views & Phantom Tracks +**Date:** 2026-03-16 +**What happened:** Executed Plan 13-01 — added library-filtered backend queries (7 sqlc queries, 8 Go methods, 1 FTS search method). Two tasks, 10 files modified. +**Where we stopped:** Completed 13-01-PLAN.md — Phase 13 in progress (1/2 plans) +**Next action:** Execute Plan 13-02: frontend library selector UI and phantom track handling --- *State initialized: 2026-02-27* diff --git a/.planning/phases/13-library-views-phantom-tracks/13-01-SUMMARY.md b/.planning/phases/13-library-views-phantom-tracks/13-01-SUMMARY.md new file mode 100644 index 0000000..abfaa0b --- /dev/null +++ b/.planning/phases/13-library-views-phantom-tracks/13-01-SUMMARY.md @@ -0,0 +1,117 @@ +--- +phase: 13-library-views-phantom-tracks +plan: 01 +subsystem: database, api +tags: [sqlite, sqlc, fts5, library-filtering, go] + +# Dependency graph +requires: + - phase: 10-schema-migration + provides: library_id column on audio_files, libraries table + - phase: 11-per-library-scan-pipeline + provides: per-library scanning populates library_id +provides: + - Library-filtered sqlc queries for tracks, albums, artists, genres + - Library-filtered FTS5 search via SearchFTSTracksByLibrary + - Eight exported Go methods on Library struct for Wails binding +affects: [13-library-views-phantom-tracks, frontend-library-selector] + +# Tech tracking +tech-stack: + added: [] + patterns: + - ByLibrary query variants with subquery filtering for entity tables + - EXISTS/IN subquery pattern for cross-table library scoping + +key-files: + created: [] + modified: + - backend/database/sql/queries/audio_files.sql + - backend/database/sql/queries/release_groups.sql + - backend/database/sql/queries/artists.sql + - backend/database/sql/queries/genres.sql + - backend/database/sql/sqlcgen/audio_files.sql.go + - backend/database/sql/sqlcgen/release_groups.sql.go + - backend/database/sql/sqlcgen/artists.sql.go + - backend/database/sql/sqlcgen/genres.sql.go + - backend/database/search.go + - backend/library/query.go + +key-decisions: + - "IN-subquery pattern for album/artist/genre library filtering — entities are global, tracks belong to libraries" + - "Empty slice return (not error) for library with no tracks — valid state" + +patterns-established: + - "ByLibrary variant pattern: copy query, add WHERE af.library_id = ? or IN-subquery on entity IDs" + +requirements-completed: [VIEW-01, VIEW-02, VIEW-03, VIEW-04] + +# Metrics +duration: 5min +completed: 2026-03-16 +--- + +# Phase 13 Plan 01: Library-Filtered Backend Queries Summary + +**Seven ByLibrary sqlc query variants + eight Go wrapper methods + library-scoped FTS5 search enabling per-library browse views** + +## Performance + +- **Duration:** 5 min +- **Started:** 2026-03-16T13:24:17Z +- **Completed:** 2026-03-16T13:29:24Z +- **Tasks:** 2 +- **Files modified:** 10 + +## Accomplishments +- Added 7 ByLibrary SQL query variants for all browse views (tracks, albums, artists, genres) +- Added 8 exported Go methods on Library struct for Wails frontend binding +- Added SearchFTSTracksByLibrary on DB struct for library-scoped full-text search +- All existing unfiltered queries remain unchanged for "All Libraries" default view + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Add library-filtered sqlc queries for all browse views** - `5cc58ce` (feat) +2. **Task 2: Add library-filtered Go query methods and FTS search** - `5f7de50` (feat) + +## Files Created/Modified +- `backend/database/sql/queries/audio_files.sql` - GetAllTracksWithFullMetadataByLibrary, GetAudioFilesByReleaseGroupByLibrary +- `backend/database/sql/queries/release_groups.sql` - GetAllAlbumsWithDetailsByLibrary, GetAlbumsByArtistByLibrary +- `backend/database/sql/queries/artists.sql` - GetAlbumArtistsByLibrary +- `backend/database/sql/queries/genres.sql` - GetTracksByGenreByLibrary, GetAllGenresWithCountsByLibrary +- `backend/database/sql/sqlcgen/*.sql.go` - sqlc-generated Go code for all new queries +- `backend/database/search.go` - SearchFTSTracksByLibrary method +- `backend/library/query.go` - Eight ByLibrary wrapper methods on Library struct + +## Decisions Made +- Used IN-subquery pattern for album/artist/genre library filtering since entities are global but tracks belong to libraries +- Return empty slice (not error) when library has no tracks — empty library is valid state, not an error condition + +## Deviations from Plan + +None - plan executed exactly as written. + +## Issues Encountered +None + +## User Setup Required + +None - no external service configuration required. + +## Next Phase Readiness +- Backend library-filtered queries complete, ready for Plan 02 (frontend library selector UI and phantom track handling) +- All 8 new methods are Wails-bindable (exported, on exported Library struct) + +## Self-Check: PASSED + +- All 10 modified files exist on disk +- Both task commits found in git log (5cc58ce, 5f7de50) +- SUMMARY.md exists at expected path +- `go build -tags webkit2_41 ./...` compiles cleanly +- `make lint` passes with 0 issues + +--- +*Phase: 13-library-views-phantom-tracks* +*Completed: 2026-03-16* diff --git a/frontend/index.html b/frontend/index.html index f63921a..81c7bfb 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -15,6 +15,7 @@

YellowJacket

Music how it was meant to bee.

+