feat: autotag mixed-bag splitting, search relevance fixes, and multi-library download imports
Autotag: detect "junk drawer" folders with no artist/album consensus and split them into synthetic per-cluster groups instead of forcing one match on an unrelated pile of tracks; repair tagging_items rows left behind by a prior scan orphan-cleanup gap. Explore: fix an exact artist-name search being drowned out by its own catalog entries in intent-prior scoring, and prune stale in_library bookkeeping left behind when a referenced library row is deleted. Download: fix a multi-library regression where every import failed with "no library root configured" — the importer resolved the library root from a legacy single-library config field that nothing populates in the current multi-library model. It now resolves the destination library per-request from the request's own library_id. Also widen the Soulseek search window (12s -> 20s), measured against real request history to be missing available peers on live queries. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y2Agd9af5hE7qzti2ackiS
This commit is contained in:
+35
-5
@@ -59,13 +59,36 @@ yet to test against. Confirm before relying on it.
|
||||
Also worth deciding deliberately: every install pulling from a personal
|
||||
Gitea makes its bandwidth and uptime a user-facing dependency.
|
||||
|
||||
## No migration chain
|
||||
## Migrations came back (2026-08-08), scoped to avoid the old failure mode
|
||||
|
||||
`applySchema` creates the whole schema from `sql/schemas/*.sql` on every
|
||||
open; all DDL is `IF NOT EXISTS`. A database written by an older build is
|
||||
not supported and there is no upgrade path by design.
|
||||
The "no migration chain" design below lasted until a real `make sandbox`
|
||||
DB (schema pre-dating the `tagging_items.synthetic`/`parent_group_key`
|
||||
columns) hit `no such column: parent_group_key` — `IF NOT EXISTS` had
|
||||
silently no-op'd the `CREATE TABLE` on the existing table, columns and
|
||||
all. A database written by an older build genuinely needed an upgrade
|
||||
path; there wasn't one.
|
||||
|
||||
Two things this replaced, worth not reintroducing:
|
||||
What came back is **not** the old 48-step chain. `sql/schemas/*.sql`
|
||||
stays the single source of truth for the current shape (still what sqlc
|
||||
reads, still what a fresh install gets verbatim). `sql/migrations/*.sql`
|
||||
holds small numbered files — `ALTER TABLE ADD COLUMN`, `CREATE INDEX`,
|
||||
etc. — that run after the schema files, tracked in `schema_migrations`,
|
||||
tolerating "duplicate column name" as a no-op so the exact same files run
|
||||
unconditionally on both a fresh database and an old one and converge on
|
||||
one shape. See the "Schema changes need two things, not one" section in
|
||||
CLAUDE.md for the column-order and index-placement gotchas this
|
||||
implies, and `backend/database/migrations_test.go` for the regression
|
||||
tests. Squashing `sql/migrations/` back into `sql/schemas/` and deleting
|
||||
the migration files is fine pre-1.0 (see CLAUDE.md); stop once real user
|
||||
databases exist.
|
||||
|
||||
The original decision this replaces, kept for why the old chain died:
|
||||
|
||||
`applySchema` created the whole schema from `sql/schemas/*.sql` on every
|
||||
open; all DDL was `IF NOT EXISTS`. A database written by an older build
|
||||
was not supported and there was no upgrade path, by design.
|
||||
|
||||
Two things that removal fixed, worth not reintroducing:
|
||||
|
||||
- The 48-step chain was ~3,700 of `database.go`'s 4,061 lines, plus
|
||||
helpers that existed only to serve it (`backupDatabase`,
|
||||
@@ -78,6 +101,13 @@ Two things this replaced, worth not reintroducing:
|
||||
generating against a stale schema and silently missed columns such as
|
||||
`audio_files.modified_at`.
|
||||
|
||||
The new design's answer to this specific risk: `sql/schemas/` is
|
||||
never edited to describe something migrations already did elsewhere
|
||||
— it's edited to directly declare the target shape, and migrations
|
||||
exist only to carry an old on-disk database to that same shape. There
|
||||
is exactly one hand-maintained description of "what does the schema
|
||||
look like", same as before; migrations don't add a second one.
|
||||
|
||||
**When regenerating schema files from a live database, remember the seed
|
||||
rows.** `file_types` (the four supported extensions), `player_state` and
|
||||
`queue` each carry `INSERT OR IGNORE` rows that `sqlite_master` does not
|
||||
|
||||
Reference in New Issue
Block a user