- 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
2.5 KiB
2.5 KiB
Stack Research: Multi-Library Support
Researched: 2026-03-08 Confidence: HIGH
Summary
Zero new Go packages needed. The existing stack handles everything required for multi-library support.
Existing Stack (No Changes)
| Component | Package | Version | Role in Multi-Library |
|---|---|---|---|
| Database | modernc.org/sqlite | v1.46.1 | ALTER TABLE, new tables, migration 6 |
| Query Gen | sqlc | v1.30.0 | New query files for libraries CRUD + filtered queries |
| Config | BurntSushi/toml | v1.6.0 | Migration source (DirectoryPath to DB) |
| Desktop | Wails | v2.10.2 | Binding patterns for library CRUD |
| Frontend | Lit | 3.2.1 | Reactive controllers for library state |
| Audio | gopxl/beep | v2 | No changes needed |
Do NOT Add
- No ORM or query builder (fights existing sqlc architecture)
- No migration framework (goose, golang-migrate) — PRAGMA user_version works well with 5 existing migrations
- No UUID package — INTEGER PRIMARY KEY is the pattern
SQLite Migration Patterns
Adding library_id to audio_files
ALTER TABLE audio_files ADD COLUMN library_id INTEGER NOT NULL DEFAULT 0;
CREATE INDEX IF NOT EXISTS idx_audio_files_library_id ON audio_files(library_id);
SQLite limitation: ALTER TABLE ADD COLUMN cannot add FK constraints. Enforce at application level.
track_metadata VIEW
Must DROP VIEW + CREATE VIEW (SQLite doesn't support ALTER VIEW). Add af.library_id to SELECT list. Follows migration 5 pattern exactly.
playlist_tracks Table Rebuild
Change ON DELETE CASCADE to ON DELETE SET NULL on audio_file_id. Requires full table rebuild (migration 5 pattern: PRAGMA foreign_keys OFF -> create _new -> copy -> drop -> rename -> PRAGMA foreign_keys ON).
sqlc Query Patterns
- Create
sql/queries/libraries.sqlfor CRUD - Create
ByLibraryvariants of key queries (GetAllTracksWithFullMetadataByLibrary, GetAllAlbumsWithDetailsByLibrary, etc.) - Separate queries preferred over dynamic WHERE (cleaner types, better query plans)
- Hand-crafted FTS5 queries get
AND tm.library_id = ?filter
Frontend Patterns
LibraryStoregainsselectedLibraryIdstate (null = all libraries)- Backend filtering (not frontend) — don't load 150K tracks when viewing one library
- Persist selection in localStorage
invalidate()on library switch triggers refetch
Config Migration
Libraries stored in SQLite (not TOML). Config [Library].DirectoryPath read once during migration, then deprecated. All library management through DB-backed methods.