Rebuilds internal/library atop store, audiotag, and events and aligns the v1 spine (upstream/v1) around fail-fast entry validation, canonicalized invariants, and single-layer boundaries across 4 reviewable CLs:
refactor(models): use explicit identifier names on music domain models— Replaces ambiguous.ID/.Pathfields on multi-source music domain and view structs (Release,LibraryRelease,LibraryTrack,Track,Artist,ReleaseCard,TrackProgress,downloaderprogress/error structs) with explicit identifiers (QobuzReleaseID,QobuzTrackID,QobuzArtistID,MBReleaseID,MBReleaseGroupID,MBRecordingID,LocalTrackID,ReleaseKey,FilePath,FolderPath).refactor(web): rename /downloads routes and package to /library— Renames/downloadsroutes, templates, CSS, middleware quiet-log paths, andinternal/web/downloadstointernal/web/library(/library).refactor(library): back library index, provenance, and ownership with sqlite— Replaces RAM/directory-based library scanning with a track-first SQLite-cached index (library_tracks,library_sidecar_covers), 4-tier deterministicReleaseKeyprecedence (qobuz:→mb:→upc:→tag:),release_provenance, and multi-userrelease_owners.refactor: enforce entry validation, canonical invariants, and single-layer boundaries— Constrains the valid state space up front, propagates canonical invariants once at entry boundaries, and splits cross-layer responsibilities acrosslibrary(library.go,fs.go,scan.go,store.go,snapshot.go,cover.go,match.go,thumbnail.go) and thev1spine:- Constrained folder & sidecar contracts: Resolves root symlinks and enforces disjoint folders once at startup (
Config.ResolveFolders()), ignores intra-folder symlinks, abortsScanbefore mutating SQLite if any root folder is inaccessible, constrains sidecar covers to configuredcover_namesstems (defaulting to["cover"]), and omits bulk/librarydelete-all in favor of explicit per-release deletion. - Entry-boundary canonicalization & validation: Validates
config.inisettings, format templates, CLI arguments,db_path(LoadDBPath()), UUIDs/ISRCs/GTINs, and image headers/dimensions (audiotag.ValidateImage) once on entry so downstreamLibrary,Downloader, and web handlers trust validated invariants without redundant re-cleaning or re-parsing. - Single-layer orchestration & Goosefoot coordination: Eliminates hidden DB writes from constructors/getters (
auth.NewService,auth.GetSession), removes path math fromweb/library, coordinates atomic Goosefoot tagging eligibility and reservation viaLibrary.InspectTagTarget/TryStartTagging(409 Conflictagainst concurrent tagging or deletion), detaches post-import SQLite reconciliation from SSE client disconnects, and wires selectiveThumbnailCacheinvalidation viaevents.Bus.
- Constrained folder & sidecar contracts: Resolves root symlinks and enforces disjoint folders once at startup (