diff --git a/memento-note/app/actions/notes.ts b/memento-note/app/actions/notes.ts index b42ff97..bc0b45f 100644 --- a/memento-note/app/actions/notes.ts +++ b/memento-note/app/actions/notes.ts @@ -134,7 +134,8 @@ async function syncLabels(userId: string, noteLabels: string[] = [], notebookId? } } -/** Sync both Note.labels (JSON) AND labelRelations for a single note. */ +/** Sync both Note.labels (JSON) AND labelRelations for a single note. + * Also cleans up orphan labels in the same notebook scope. */ async function syncNoteLabels(noteId: string, labelNames: string[], notebookId: string | null, userId: string) { const uniqueNames = [...new Set(labelNames.map(n => n.trim()).filter(Boolean))] const labelRows = await syncLabels(userId, uniqueNames, notebookId) @@ -146,6 +147,46 @@ async function syncNoteLabels(noteId: string, labelNames: string[], notebookId: labelRelations: { set: labelIds.map(id => ({ id })) }, }, }) + + // Clean up orphan labels: labels in this notebook scope that are no longer + // referenced by any note (neither via JSON nor via labelRelations) + if (notebookId !== null) { + const allLabels = await prisma.label.findMany({ + where: { notebookId, userId }, + select: { id: true, name: true }, + }) + if (allLabels.length > 0) { + const labelIdsSet = new Set(allLabels.map(l => l.id)) + // Find notes in this notebook that have any label relation + const notesWithLabels = await prisma.note.findMany({ + where: { + notebookId, + userId, + labelRelations: { some: { id: { in: Array.from(labelIdsSet) } } }, + }, + select: { labels: true }, + }) + // Collect all label names still in use via JSON + const namesInUse = new Set() + for (const n of notesWithLabels) { + if (n.labels) { + try { + const parsed = JSON.parse(n.labels as string) + if (Array.isArray(parsed)) { + parsed.filter((x: any) => typeof x === 'string').forEach((x: string) => namesInUse.add(x.toLowerCase())) + } + } catch {} + } + } + // Delete labels not in use + const orphans = allLabels.filter(l => !namesInUse.has(l.name.toLowerCase())) + if (orphans.length > 0) { + await prisma.label.deleteMany({ + where: { id: { in: orphans.map(l => l.id) } }, + }) + } + } + } } /** Après déplacement via API : rattacher les étiquettes de la note au bon carnet */