fix: clean up orphan labels when syncing note labels
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 43s
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 43s
After syncing a note's labels, detect and delete labels in the same notebook that are no longer referenced by any note (neither via JSON nor labelRelations). Prevents phantom labels from accumulating. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -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<string>()
|
||||
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 */
|
||||
|
||||
Reference in New Issue
Block a user