docs: restructure v1.1 milestone for multi-library support

- Rename milestone from 'Features & Extensibility' to 'Multi-Library Support'
- Replace old phases 10-14 (TAG/SMRT/GAP/MB/LAYOUT/PLUG) with 20 multi-library requirements (LIB/LSCAN/VIEW/PLAY/DATA)
- Move deferred features to Future Requirements
- Update research files with multi-library research (Stack, Features, Architecture, Pitfalls)
- Architecture: hybrid model (library_id on audio_files only), libraries in DB, sequential scanning, phantom tracks
This commit is contained in:
2026-03-08 11:54:37 -04:00
parent 595b5e1529
commit cdf8bff01a
9 changed files with 452 additions and 2721 deletions
+114 -91
View File
@@ -5,15 +5,15 @@
## v1.1 Requirements
Requirements for v1.1 Features & Extensibility milestone. Each maps to roadmap phases.
Requirements for v1.1 Multi-Library Support milestone. Each maps to roadmap phases.
### Scan Cancellation
### Scan Cancellation (Phase 9 — Complete)
- [x] **SCAN-01**: User can cancel an in-progress library scan via a cancel button
- [x] **SCAN-02**: Cancelled scan stops gracefully without corrupting the database
- [x] **SCAN-03**: User can pause a library scan and resume it without re-scanning processed files
### Keyboard Shortcuts
### Keyboard Shortcuts (Phase 9 — Complete)
- [x] **KEY-01**: Default keybindings work out of box (play/pause, next/prev, volume, search focus, queue toggle, shuffle, repeat)
- [x] **KEY-02**: User can customize all keyboard shortcuts via a visual settings UI
@@ -21,63 +21,58 @@ Requirements for v1.1 Features & Extensibility milestone. Each maps to roadmap p
- [x] **KEY-04**: Shortcuts are scoped — different bindings apply based on focused component (track list vs player vs global)
- [x] **KEY-05**: Shortcuts are disabled when text input has focus (except Escape to blur)
### Tag Editing
### Library Management
- [ ] **TAG-01**: User can edit a single track's metadata (title, artist, album, genre, year, track number)
- [ ] **TAG-02**: User can batch edit multiple selected tracks' shared fields
- [ ] **TAG-03**: Tag changes are written to actual audio files (MP3 via ID3v2, FLAC via Vorbis Comments)
- [ ] **TAG-04**: Database and FTS5 search index update after tag writes without requiring a full rescan
- [ ] **TAG-05**: User can set or replace embedded cover art from an image file
- [ ] **TAG-06**: Tag writes use write-to-temp-then-rename to prevent file corruption
- [ ] **TAG-07**: Tag editing is blocked for currently-playing files (queued for after playback stops)
- [ ] **LIB-01**: User can add a new library directory via a folder picker dialog
- [ ] **LIB-02**: User can rename a library (display name)
- [ ] **LIB-03**: User can remove a library — tracks are deleted from DB, shared entities (artists, albums, genres) are cleaned up only if no other library references them
- [ ] **LIB-04**: Libraries are stored in SQLite (not TOML config) with CRUD through the UI
- [ ] **LIB-05**: Existing single-directory config is migrated seamlessly to the libraries table on first run after upgrade
- [ ] **LIB-06**: Library list is displayed in a management UI (settings or sidebar section)
### Smart Playlists
### Library Scanning
- [ ] **SMRT-01**: User can create a smart playlist with filter rules (genre, year, artist, album, title)
- [ ] **SMRT-02**: Multiple rules combine with AND logic
- [ ] **SMRT-03**: User can set random ordering and result limit ("Random 50 Jazz tracks")
- [ ] **SMRT-04**: Smart playlists appear in the sidebar alongside regular playlists
- [ ] **SMRT-05**: Smart playlist rules are persisted and survive app restart
- [ ] **LSCAN-01**: User can trigger a scan for a specific library (not all-or-nothing)
- [ ] **LSCAN-02**: Scanning is sequential — only one library scans at a time (SQLite single-writer)
- [ ] **LSCAN-03**: Scan progress UI shows which library is being scanned
- [ ] **LSCAN-04**: Existing scan cancellation and pause/resume work per-library
- [ ] **LSCAN-05**: Audio files are associated with their library via `library_id` foreign key
### Gapless Playback
### Unified Presentation
- [ ] **GAP-01**: Tracks transition seamlessly with no audible silence gap (gapless playback)
- [ ] **GAP-02**: Next track is pre-decoded before current track ends
- [ ] **GAP-03**: User can enable/disable crossfade with configurable duration (1-10 seconds)
- [ ] **GAP-04**: Crossfade only applies on auto-advance, not manual skip
- [ ] **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
### MusicBrainz Browser
### Playlists & Queue
- [ ] **MB-01**: User can search for artists by name and view results
- [ ] **MB-02**: User can browse an artist's discography (release groups — albums, EPs, singles)
- [ ] **MB-03**: User can view tracks on a specific release
- [ ] **MB-04**: User can view different editions of a release group (pressings, reissues)
- [ ] **MB-05**: API responses are cached in SQLite (24hr for searches, 7 days for entities)
- [ ] **MB-06**: Album cover art is displayed from the Cover Art Archive
- [ ] **MB-07**: Rate limiting (1 req/sec) is enforced with proper User-Agent header
- [ ] **PLAY-01**: Playlists can contain tracks from multiple libraries (cross-library playlists)
- [ ] **PLAY-02**: When a library is removed, playlist entries for that library's tracks become phantom tracks (preserved with cached metadata, not cascade-deleted)
- [ ] **PLAY-03**: Phantom tracks are visually distinguished in playlist views (e.g., greyed out, icon indicator)
- [ ] **PLAY-04**: Queue tracks from a removed library are cascade-deleted (queue is ephemeral)
### Layout Customization
### Data Integrity
- [ ] **LAYOUT-01**: User can resize sidebar and queue panels via drag handles
- [ ] **LAYOUT-02**: Panel sizes persist across app restarts
- [ ] **LAYOUT-03**: User can show/hide sidebar sections and queue panel
- [ ] **LAYOUT-04**: User can choose which component is displayed in each layout section (MusicBee-style)
- [ ] **LAYOUT-05**: Components declare size constraints (min/max dimensions, aspect ratio compatibility)
- [ ] **LAYOUT-06**: Layout presets available (Compact, Full, Mini player) with quick switch
### Plugin System
- [ ] **PLUG-01**: Plugin API is defined — plugins can access events, player state, queue, library data
- [ ] **PLUG-02**: JS/TS plugin bundles are loaded from user plugin directory at runtime
- [ ] **PLUG-03**: Plugins can register UI components into the layout system
- [ ] **PLUG-04**: Plugin manifest file defines name, version, permissions, hooks, and UI components
- [ ] **PLUG-05**: Plugins can have their own persistent configuration
- [ ] **PLUG-06**: One example plugin ships demonstrating the API
- [ ] **DATA-01**: Schema migration adds `libraries` table and `library_id` FK on `audio_files`
- [ ] **DATA-02**: Orphan cleanup after library removal: reference-counting bottom-up deletes for artists, albums, genres only referenced by removed library's tracks
- [ ] **DATA-03**: FTS5 index entries for removed tracks are cleaned up (handling contentless table limitations)
- [ ] **DATA-04**: All library operations are transactional — no partial state on failure
## Future Requirements
Deferred to future milestones. Tracked but not in current roadmap.
### Tag Editing (Deferred from v1.1)
- **TAG-01**: User can edit a single track's metadata (title, artist, album, genre, year, track number)
- **TAG-02**: User can batch edit multiple selected tracks' shared fields
- **TAG-03**: Tag changes are written to actual audio files (MP3 via ID3v2, FLAC via Vorbis Comments)
- **TAG-04**: Database and FTS5 search index update after tag writes without requiring a full rescan
- **TAG-05**: User can set or replace embedded cover art from an image file
- **TAG-06**: Tag writes use write-to-temp-then-rename to prevent file corruption
- **TAG-07**: Tag editing is blocked for currently-playing files (queued for after playback stops)
### Tag Editing (v2+)
- **TAG-F01**: Undo/redo for tag edits
@@ -85,6 +80,14 @@ Deferred to future milestones. Tracked but not in current roadmap.
- **TAG-F03**: Filename-to-tag inference (parse "Artist - Title.mp3" patterns)
- **TAG-F04**: Tag-to-filename rename based on template
### Smart Playlists (Deferred from v1.1)
- **SMRT-01**: User can create a smart playlist with filter rules (genre, year, artist, album, title)
- **SMRT-02**: Multiple rules combine with AND logic
- **SMRT-03**: User can set random ordering and result limit ("Random 50 Jazz tracks")
- **SMRT-04**: Smart playlists appear in the sidebar alongside regular playlists
- **SMRT-05**: Smart playlist rules are persisted and survive app restart
### Smart Playlists (v2+)
- **SMRT-F01**: Play count tracking for smart playlist rules
@@ -93,21 +96,51 @@ Deferred to future milestones. Tracked but not in current roadmap.
- **SMRT-F04**: Sort order control in rule definition
- **SMRT-F05**: Auto-update smart playlists on library changes
### Gapless Playback (Deferred from v1.1)
- **GAP-01**: Tracks transition seamlessly with no audible silence gap (gapless playback)
- **GAP-02**: Next track is pre-decoded before current track ends
- **GAP-03**: User can enable/disable crossfade with configurable duration (1-10 seconds)
- **GAP-04**: Crossfade only applies on auto-advance, not manual skip
### Gapless Playback (v2+)
- **GAP-F01**: Per-album gapless (disable crossfade within albums)
- **GAP-F02**: ReplayGain normalization
- **GAP-F03**: Fade-in on play, fade-out on pause
### MusicBrainz Browser (v2+)
### MusicBrainz Browser (Deferred from v1.1)
- **MB-F01**: Link local tracks to MusicBrainz recordings (MBID association)
- **MB-F02**: Search recordings (find specific songs across releases)
- **MB-01**: User can search for artists by name and view results
- **MB-02**: User can browse an artist's discography (release groups — albums, EPs, singles)
- **MB-03**: User can view tracks on a specific release
- **MB-04**: User can view different editions of a release group (pressings, reissues)
- **MB-05**: API responses are cached in SQLite (24hr for searches, 7 days for entities)
- **MB-06**: Album cover art is displayed from the Cover Art Archive
- **MB-07**: Rate limiting (1 req/sec) is enforced with proper User-Agent header
### Layout Customization (Deferred from v1.1)
- **LAYOUT-01**: User can resize sidebar and queue panels via drag handles
- **LAYOUT-02**: Panel sizes persist across app restarts
- **LAYOUT-03**: User can show/hide sidebar sections and queue panel
- **LAYOUT-04**: User can choose which component is displayed in each layout section (MusicBee-style)
- **LAYOUT-05**: Components declare size constraints (min/max dimensions, aspect ratio compatibility)
- **LAYOUT-06**: Layout presets available (Compact, Full, Mini player) with quick switch
### Layout Customization (v2+)
- **LAYOUT-F01**: Detachable panels (pop out to separate window)
### Plugin System (Deferred from v1.1)
- **PLUG-01**: Plugin API is defined — plugins can access events, player state, queue, library data
- **PLUG-02**: JS/TS plugin bundles are loaded from user plugin directory at runtime
- **PLUG-03**: Plugins can register UI components into the layout system
- **PLUG-04**: Plugin manifest file defines name, version, permissions, hooks, and UI components
- **PLUG-05**: Plugins can have their own persistent configuration
- **PLUG-06**: One example plugin ships demonstrating the API
### Plugin System (v2+)
- **PLUG-F01**: Plugin marketplace/registry for discovery and installation
@@ -120,16 +153,18 @@ Explicitly excluded. Documented to prevent scope creep.
| Feature | Reason |
|---------|--------|
| Separate databases per library | Defeats unified presentation, overly complex |
| Auto-dedup across libraries | Complex matching logic, not table stakes |
| User access control per library | Desktop app, single user |
| Parallel library scanning | SQLite single-writer makes it pointless |
| OGG Vorbis tag writing | No mature pure-Go write library exists |
| WAV metadata editing | Rarely needed, low priority |
| Auto-tag from MusicBrainz | Complex matching logic — Picard's domain, not a browser feature |
| Write data to MusicBrainz | Requires OAuth and community guidelines compliance |
| Auto-tag from MusicBrainz | Complex matching logic — Picard's domain |
| DSP effects chain (equalizer, reverb) | Scope explosion — separate feature area |
| Go `plugin` package for backend plugins | Linux-only, version-fragile, widely considered broken |
| Free-form drag-and-drop layout | Overwhelming complexity; section-based approach is better |
| Global OS-level hotkeys | Platform-specific, conflicts with OS shortcuts; MPRIS2 handles media keys |
| Mobile-responsive layout | Desktop app with fixed minimum size |
| Plugin binary distribution | Source-based (JS bundles) is safer and more portable |
## Traceability
@@ -145,47 +180,35 @@ Which phases cover which requirements. Updated during roadmap creation.
| KEY-03 | Phase 9 | Complete |
| KEY-04 | Phase 9 | Complete |
| KEY-05 | Phase 9 | Complete |
| TAG-01 | Phase 10 | Pending |
| TAG-02 | Phase 10 | Pending |
| TAG-03 | Phase 10 | Pending |
| TAG-04 | Phase 10 | Pending |
| TAG-05 | Phase 10 | Pending |
| TAG-06 | Phase 10 | Pending |
| TAG-07 | Phase 10 | Pending |
| SMRT-01 | Phase 11 | Pending |
| SMRT-02 | Phase 11 | Pending |
| SMRT-03 | Phase 11 | Pending |
| SMRT-04 | Phase 11 | Pending |
| SMRT-05 | Phase 11 | Pending |
| GAP-01 | Phase 12 | Pending |
| GAP-02 | Phase 12 | Pending |
| GAP-03 | Phase 12 | Pending |
| GAP-04 | Phase 12 | Pending |
| MB-01 | Phase 13 | Pending |
| MB-02 | Phase 13 | Pending |
| MB-03 | Phase 13 | Pending |
| MB-04 | Phase 13 | Pending |
| MB-05 | Phase 13 | Pending |
| MB-06 | Phase 13 | Pending |
| MB-07 | Phase 13 | Pending |
| LAYOUT-01 | Phase 14 | Pending |
| LAYOUT-02 | Phase 14 | Pending |
| LAYOUT-03 | Phase 14 | Pending |
| LAYOUT-04 | Phase 14 | Pending |
| LAYOUT-05 | Phase 14 | Pending |
| LAYOUT-06 | Phase 14 | Pending |
| PLUG-01 | Phase 14 | Pending |
| PLUG-02 | Phase 14 | Pending |
| PLUG-03 | Phase 14 | Pending |
| PLUG-04 | Phase 14 | Pending |
| PLUG-05 | Phase 14 | Pending |
| PLUG-06 | Phase 14 | Pending |
| LIB-01 | TBD | Pending |
| LIB-02 | TBD | Pending |
| LIB-03 | TBD | Pending |
| LIB-04 | TBD | Pending |
| LIB-05 | TBD | Pending |
| LIB-06 | TBD | Pending |
| LSCAN-01 | TBD | Pending |
| LSCAN-02 | TBD | Pending |
| LSCAN-03 | TBD | Pending |
| LSCAN-04 | TBD | Pending |
| LSCAN-05 | TBD | Pending |
| VIEW-01 | TBD | Pending |
| VIEW-02 | TBD | Pending |
| VIEW-03 | TBD | Pending |
| VIEW-04 | TBD | Pending |
| PLAY-01 | TBD | Pending |
| PLAY-02 | TBD | Pending |
| PLAY-03 | TBD | Pending |
| PLAY-04 | TBD | Pending |
| DATA-01 | TBD | Pending |
| DATA-02 | TBD | Pending |
| DATA-03 | TBD | Pending |
| DATA-04 | TBD | Pending |
**Coverage:**
- v1.1 requirements: 43 total
- Mapped to phases: 43
- Unmapped: 0 ✓
- v1.1 requirements: 28 total (8 complete + 20 pending)
- Mapped to phases: 8 (Phase 9 complete)
- Awaiting roadmap: 20
---
*Requirements defined: 2026-03-06*
*Last updated: 2026-03-06traceability updated with phase mappings*
*Last updated: 2026-03-08restructured for multi-library support, deferred TAG/SMRT/GAP/MB/LAYOUT/PLUG*