Unify media_key and item_key — use item_key everywhere
media_key was a lossy shortening of item_key (libraryId:lastSegment) that introduced a real collision bug: two TV episodes from different series with the same filename would share the same media_key and each other's tags. - DB migration converts existing media_tags rows from short format to full item_key by joining against media_items; ambiguous/orphaned rows are dropped - media_tags column renamed media_key → item_key - Removed itemKeyToMediaKey() from scanner; reconcileAndPrune now passes item_key directly to reKeyMediaItem - DB reader functions (tv, movies, games) now expose item_key on returned entities; frontend components use entity.item_key instead of constructing the short libraryId:id form - MixedView now constructs the full mixed_file: item_key format - Tag API renamed mediaKey param → itemKey throughout Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -81,7 +81,7 @@ export default function GamesView({ libraryId }: Props) {
|
||||
if (!searchMatch) return false
|
||||
if (selectedTagIds.size > 0) {
|
||||
return item.games.some((g) => {
|
||||
const gameTags = assignments[`${libraryId}:${g.id}`] ?? []
|
||||
const gameTags = assignments[g.item_key!] ?? []
|
||||
return [...selectedTagIds].every((id) => gameTags.includes(id))
|
||||
})
|
||||
}
|
||||
@@ -89,7 +89,7 @@ export default function GamesView({ libraryId }: Props) {
|
||||
}
|
||||
if (search && !item.title.toLowerCase().includes(search.toLowerCase())) return false
|
||||
if (selectedTagIds.size > 0) {
|
||||
const gameTags = assignments[`${libraryId}:${item.id}`] ?? []
|
||||
const gameTags = assignments[item.item_key!] ?? []
|
||||
if (![...selectedTagIds].every((id) => gameTags.includes(id))) return false
|
||||
}
|
||||
return true
|
||||
|
||||
Reference in New Issue
Block a user