9.3 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| quick-10 | 10 | execute | 1 |
|
true |
|
Purpose: Two users' "Classics" albums (Aphex Twin and Ratatat) should appear as separate entries in the cover grid, each with correct cover art, artist name, and track listing.
Output: Schema migration, updated SQL queries, regenerated sqlc code, and fixed entity cache.
<execution_context> @/home/caleb/.config/opencode/get-shit-done/workflows/execute-plan.md @/home/caleb/.config/opencode/get-shit-done/templates/summary.md </execution_context>
@.planning/STATE.md @backend/database/sql/schemas/release_groups.sql @backend/database/sql/queries/release_groups.sql @backend/database/database.go @backend/library/library.go Task 1: Fix schema, queries, and regenerate sqlc backend/database/sql/schemas/release_groups.sql backend/database/sql/queries/release_groups.sql backend/database/sql/sqlcgen/release_groups.sql.go 1. **Update `release_groups.sql` schema** (line 3): Remove `UNIQUE` from the `name` column definition. Add a composite unique constraint at the table level: ```sql name TEXT NOT NULL, ``` And after the FOREIGN KEY lines, before the closing `);`: ```sql UNIQUE(name, album_artist_credit_id) ```IMPORTANT: SQLite treats each NULL as unique in UNIQUE constraints, so albums without an album_artist_credit_id will each get their own row. This is the desired behavior — an album with no tagged artist should not conflict with named-artist albums.
-
Update
release_groups.sqlqueries:UpsertReleaseGroup(line 22): ChangeON CONFLICT(name)toON CONFLICT(name, album_artist_credit_id). This ensures upsert only matches when BOTH album name and artist match.GetReleaseGroupByName(lines 15-17): Add analbum_artist_credit_idparameter. Rename toGetReleaseGroupByNameAndArtist:Check first: grep codebase for any callers of-- name: GetReleaseGroupByNameAndArtist :one SELECT * FROM release_groups WHERE name = ? AND album_artist_credit_id = ? LIMIT 1;GetReleaseGroupByName. If there are callers, update them to pass the artist credit ID. If no callers exist outside generated code, safe to rename.
-
Regenerate sqlc: Run
sqlc generatefrombackend/database/directory:cd backend/database && sqlc generateVerify the generated
release_groups.sql.gohas the updated function signatures (UpsertReleaseGroup params unchanged since it already takes album_artist_credit_id; GetReleaseGroupByNameAndArtist now takes two params).
SAFETY NOTE (hand-crafted SQL follows in Task 2): The schema file change only affects NEW databases. Existing databases need the migration in Task 2.
- sqlc generate completes without errors from backend/database/
- go build ./... passes from project root
- Schema file has UNIQUE(name, album_artist_credit_id) instead of name TEXT NOT NULL UNIQUE
- UpsertReleaseGroup query uses ON CONFLICT(name, album_artist_credit_id)
Schema and queries updated for composite uniqueness, sqlc regenerated, project compiles.
Migration 5 must:
- SAFETY: This is hand-crafted SQL for a schema migration. SQLite cannot ALTER a UNIQUE constraint, so we must rebuild the table.
- Create
release_groups_newwith the corrected schema (matching the updatedrelease_groups.sqlexactly — same columns, same foreign keys, butUNIQUE(name, album_artist_credit_id)instead ofUNIQUE(name)). - Copy all data:
INSERT INTO release_groups_new SELECT * FROM release_groups - Drop old table:
DROP TABLE release_groups - Rename:
ALTER TABLE release_groups_new RENAME TO release_groups - Recreate both indexes:
CREATE INDEX IF NOT EXISTS idx_release_groups_cover_art_id ON release_groups(cover_art_id); CREATE INDEX IF NOT EXISTS idx_release_groups_album_artist_credit_id ON release_groups(album_artist_credit_id); - Set
PRAGMA user_version = 5 - Log:
"applying migration 5: release_groups composite unique constraint" - Log completion:
"migration 5 complete"
NOTE: The migration does NOT split already-merged albums. That requires a full library rescan which the user triggers manually. The migration just removes the bad constraint so future scans work correctly.
NOTE: The release_group_recordings table has a foreign key REFERENCES release_groups(id). Since we're dropping and recreating, we need to handle this. SQLite defers FK checks by default when foreign_keys is ON. Wrap the migration in:
// Temporarily disable FK checks for table rebuild.
db.ExecContext(ctx, "PRAGMA foreign_keys = OFF")
// ... migration steps ...
db.ExecContext(ctx, "PRAGMA foreign_keys = ON")
- Fix entity cache in
library.go:- Line 44: Change cache type from
map[string]sqlcgen.ReleaseGrouptomap[string]sqlcgen.ReleaseGroup(type stays same, but key semantics change). - In
resolveReleaseGroup()(lines 1253-1327): Change all cache key accesses fromtags.Albumto a composite key. Create a helper or inline:// Build composite cache key: "albumName\x00artistCreditID" (or "albumName\x00-1" if no artist). artistID := int64(-1) if albumArtistCreditID.Valid { artistID = albumArtistCreditID.Int64 } cacheKey := fmt.Sprintf("%s\x00%d", tags.Album, artistID) - Replace all 3 occurrences of
cache.releaseGroups[tags.Album]withcache.releaseGroups[cacheKey]:- Line 1265: cache lookup
- Line 1283: cache update after cover art
- Line 1324: cache store after upsert
go build ./...passesgo test ./backend/database/...passes (existing migration tests should still work since migration 5 is additive)go test ./backend/library/...passesgo vet ./...passes Migration 5 rebuilds release_groups with composite unique constraint. Entity cache uses composite key (album name + artist credit ID). Existing databases upgraded on next app start. User triggers full rescan to split previously merged albums.
- Line 44: Change cache type from
<success_criteria>
- Two albums named "Classics" by different artists stored as separate release_groups rows after rescan
- Each album shows only its own tracks when opened
- Cover grid displays both albums as distinct entries
- Existing databases migrated safely (constraint changed, rescan needed to split merged data) </success_criteria>