docs(quick-10): complete fix duplicate album merging bug plan
- Add 10-SUMMARY.md with full execution details - Update STATE.md with quick task 10 entry and session info
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
---
|
||||
phase: quick-10
|
||||
plan: 10
|
||||
subsystem: database, library
|
||||
tags: [bugfix, schema-migration, sqlite, entity-cache]
|
||||
dependency_graph:
|
||||
requires: []
|
||||
provides: [composite-unique-release-groups, migration-5]
|
||||
affects: [release_groups, library-scan, cover-grid]
|
||||
tech_stack:
|
||||
added: []
|
||||
patterns: [composite-unique-constraint, table-rebuild-migration, composite-cache-key]
|
||||
key_files:
|
||||
created: []
|
||||
modified:
|
||||
- backend/database/sql/schemas/release_groups.sql
|
||||
- backend/database/sql/queries/release_groups.sql
|
||||
- backend/database/sql/sqlcgen/release_groups.sql.go
|
||||
- backend/database/database.go
|
||||
- backend/library/library.go
|
||||
- backend/library/scan_test.go
|
||||
decisions:
|
||||
- "Rename GetReleaseGroupByName to GetReleaseGroupByNameAndArtist (no callers outside generated code)"
|
||||
- "Use null byte separator in composite cache key for safety"
|
||||
- "Drop and recreate track_metadata VIEW during migration to avoid SQLite VIEW dependency error"
|
||||
metrics:
|
||||
duration: 5m25s
|
||||
completed: "2026-03-05"
|
||||
tasks_completed: 2
|
||||
tasks_total: 2
|
||||
---
|
||||
|
||||
# Quick Task 10: Fix Duplicate Album Merging Bug
|
||||
|
||||
Composite unique constraint on (name, album_artist_credit_id) for release_groups, with migration 5 to rebuild existing tables and entity cache fix to key by album+artist.
|
||||
|
||||
## Task Summary
|
||||
|
||||
| # | Task | Commit | Key Changes |
|
||||
|---|------|--------|-------------|
|
||||
| 1 | Fix schema, queries, and regenerate sqlc | 999ab96 | UNIQUE(name, album_artist_credit_id) in schema; ON CONFLICT updated; GetReleaseGroupByNameAndArtist |
|
||||
| 2 | Add migration 5 and fix entity cache | d43ba7b | Migration 5 rebuilds table; cache keys by album+artistID; VIEW drop/recreate |
|
||||
|
||||
## What Changed
|
||||
|
||||
### Schema (`release_groups.sql`)
|
||||
- Removed `UNIQUE` from `name TEXT NOT NULL UNIQUE`
|
||||
- Added table-level `UNIQUE(name, album_artist_credit_id)` — SQLite treats NULL as unique, so albums without an artist won't collide
|
||||
|
||||
### Queries (`release_groups.sql`)
|
||||
- `UpsertReleaseGroup`: `ON CONFLICT(name)` → `ON CONFLICT(name, album_artist_credit_id)`
|
||||
- `GetReleaseGroupByName` → `GetReleaseGroupByNameAndArtist` with two params (name + album_artist_credit_id)
|
||||
|
||||
### Migration 5 (`database.go`)
|
||||
- Disables FK checks temporarily
|
||||
- Drops `track_metadata` VIEW (depends on release_groups)
|
||||
- Creates `release_groups_new` with composite unique constraint
|
||||
- Copies data, drops old, renames new
|
||||
- Recreates both indexes and the `track_metadata` VIEW
|
||||
- Re-enables FK checks, bumps user_version to 5
|
||||
|
||||
### Entity Cache (`library.go`)
|
||||
- Cache key changed from `tags.Album` to `fmt.Sprintf("%s\x00%d", tags.Album, artistID)` where artistID is -1 when no album artist credit exists
|
||||
- All 3 cache access points updated (lookup, cover art update, store after upsert)
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
### Auto-fixed Issues
|
||||
|
||||
**1. [Rule 1 - Bug] track_metadata VIEW blocking table rename**
|
||||
- **Found during:** Task 2
|
||||
- **Issue:** SQLite refuses to rename `release_groups_new` to `release_groups` when the `track_metadata` VIEW references the old table
|
||||
- **Fix:** Drop the VIEW before table rebuild, recreate it after rename (VIEW definition matches embedded schema exactly)
|
||||
- **Files modified:** backend/database/database.go
|
||||
- **Commit:** d43ba7b
|
||||
|
||||
**2. [Rule 1 - Bug] Tests using old cache key format**
|
||||
- **Found during:** Task 2
|
||||
- **Issue:** `TestResolveReleaseGroup` and `TestResolveReleaseGroup_CacheHit` use bare album name as cache key
|
||||
- **Fix:** Updated test assertions to use composite cache key format (`albumName\x00artistCreditID`)
|
||||
- **Files modified:** backend/library/scan_test.go
|
||||
- **Commit:** d43ba7b
|
||||
|
||||
## Verification
|
||||
|
||||
- `go build ./...` — passes
|
||||
- `go test ./...` — all 14 test packages pass
|
||||
- `go vet ./...` — no issues
|
||||
- Schema has `UNIQUE(name, album_artist_credit_id)` ✓
|
||||
- UpsertReleaseGroup uses `ON CONFLICT(name, album_artist_credit_id)` ✓
|
||||
- Migration 5 exists and rebuilds table ✓
|
||||
- Entity cache key includes artist credit ID ✓
|
||||
|
||||
## Notes
|
||||
|
||||
- **Existing databases**: Migration 5 changes the constraint but does NOT split already-merged albums. Users must trigger a full library rescan after upgrading.
|
||||
- **NULL handling**: SQLite's UNIQUE treats each NULL as distinct, so albums without `album_artist_credit_id` will each get their own row — this is desired behavior.
|
||||
Reference in New Issue
Block a user