fix(artwork): don't stamp the album hash onto multi-disc tracks

The hydration fallback assigned a found album hash to every fallback track, but a
multi-disc track's CoverArtID emits a dc- id served from disc-specific art whose hash
is unknown at hydration time. Advertising dc-..._<albumHash> gave clients a content-
version that never changes when the disc image does, breaking id-based refresh. Only
stamp the album hash for single-disc tracks (DiscNumber == 0); multi-disc tracks stay
unhashed and rely on the correct ETag returned by the served response.
This commit is contained in:
Deluan 2026-07-23 09:24:15 -04:00
parent 3eaa21229d
commit e9c15d7fcb
2 changed files with 18 additions and 2 deletions

View File

@ -249,6 +249,17 @@ var _ = Describe("Artwork hydration", func() {
Expect(byID["1003"].ImageAbsent).To(BeTrue())
})
It("does not stamp a found album hash onto a multi-disc track (its dc- id is disc-served)", func() {
putInfo("al", "104", "alh104foundxxxxx") // songs 2002/2004 album is found
byID := getByID()
// 2002 is multi-disc (DiscNumber>0); CoverArtID emits a dc- id served from disc art of
// unknown identity, so it must not advertise the album's hash as its content-version.
Expect(byID["2002"].ImageHash).To(BeEmpty())
Expect(byID["2002"].ImageAbsent).To(BeFalse())
})
It("keeps a multi-disc track requestable when its album is absent (disc art may resolve)", func() {
putInfo("al", "104", "") // songs 2002/2004 album known-absent

View File

@ -247,9 +247,14 @@ func (r *mediaFileRepository) hydrateArtwork(mfs model.MediaFiles) {
mf.ImageHash = ownInfo.Hash // own resolved art wins
continue
}
// Fallback (see MediaFile.CoverArtID): inherit a found album hash for optimistic caching.
// Fallback (see MediaFile.CoverArtID): inherit a found album hash for optimistic caching,
// but only for a single-disc track. A multi-disc track emits a dc- id served from
// disc-specific art of unknown identity, so stamping the album hash would advertise a
// wrong content-version; leave it bare (the served response still carries a correct ETag).
if album, ok := albumInfos[mf.AlbumID]; ok && !album.Absent() {
mf.ImageHash = album.Hash
if mf.DiscNumber == 0 {
mf.ImageHash = album.Hash
}
continue
}
// Nothing found. Mark absent only when serving would definitively yield a placeholder: