Fix library repair failing on playback session foreign keys.

Delete stale playback sessions before removing unavailable or duplicate media file rows.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jos Vooges | STH 2026-09-01 14:56:37 +02:00
parent d044106f77
commit 7c808e9167

View file

@ -910,11 +910,7 @@ export class MetadataService {
const seriesMerged = await this.mergeAllDuplicateSeries(); const seriesMerged = await this.mergeAllDuplicateSeries();
// Unavailable rows left after the /media/movies → /mnt/user migration // Unavailable rows left after the /media/movies → /mnt/user migration
const staleFilesRemoved = ( const staleFilesRemoved = await this.deleteUnavailableMediaFiles();
await prisma.mediaFile.deleteMany({
where: { available: false },
})
).count;
const duplicateFilesRemoved = await this.removeDuplicateMediaFiles(); const duplicateFilesRemoved = await this.removeDuplicateMediaFiles();
@ -1135,8 +1131,29 @@ export class MetadataService {
} }
if (toDelete.length === 0) return 0; if (toDelete.length === 0) return 0;
const result = await prisma.mediaFile.deleteMany({ where: { id: { in: toDelete } } }); return this.deleteMediaFilesSafely(toDelete);
return result.count; }
/** Remove playback sessions first — FK blocks direct media_file deletes. */
private async deleteMediaFilesSafely(ids: string[]): Promise<number> {
if (ids.length === 0) return 0;
const chunkSize = 500;
let deleted = 0;
for (let i = 0; i < ids.length; i += chunkSize) {
const chunk = ids.slice(i, i + chunkSize);
await prisma.playbackSession.deleteMany({ where: { mediaFileId: { in: chunk } } });
const result = await prisma.mediaFile.deleteMany({ where: { id: { in: chunk } } });
deleted += result.count;
}
return deleted;
}
private async deleteUnavailableMediaFiles(): Promise<number> {
const stale = await prisma.mediaFile.findMany({
where: { available: false },
select: { id: true },
});
return this.deleteMediaFilesSafely(stale.map((f) => f.id));
} }
/** Admin: search TMDB by title (or resolve a single IMDb id). */ /** Admin: search TMDB by title (or resolve a single IMDb id). */