From 085a2246f69e2e501f34f56615dbd3bc223f94c8 Mon Sep 17 00:00:00 2001 From: Antigravity Date: Sun, 10 May 2026 18:58:40 +0000 Subject: [PATCH] fix: enforce sub-notebook parentId, validate existingId, use getChatProvider, add move logging --- memento-note/app/actions/organize-notebook.ts | 43 ++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/memento-note/app/actions/organize-notebook.ts b/memento-note/app/actions/organize-notebook.ts index ab7cd4e..799cfa5 100644 --- a/memento-note/app/actions/organize-notebook.ts +++ b/memento-note/app/actions/organize-notebook.ts @@ -187,7 +187,7 @@ Format de réponse JSON attendu: /** * Execute an approved organization plan: - * - Creates missing sub-notebooks + * - Creates missing sub-notebooks (always as children of plan.notebookId) * - Moves notes to the correct sub-notebook */ export async function executeNotebookOrganization(plan: OrganizationPlan): Promise { @@ -202,17 +202,38 @@ export async function executeNotebookOrganization(plan: OrganizationPlan): Promi }) if (!notebook) return { success: false, created: 0, moved: 0, error: 'Carnet introuvable' } + console.log('[organize-notebook] Executing plan:', JSON.stringify({ + notebookId: plan.notebookId, + groups: plan.groups.map(g => ({ name: g.name, isNew: g.isNew, existingId: g.existingId, noteCount: g.notes.length })) + })) + let created = 0 let moved = 0 for (const group of plan.groups) { let targetNotebookId: string - if (!group.isNew && group.existingId) { - // Use existing sub-notebook - targetNotebookId = group.existingId - } else { - // Create new sub-notebook + // Validate existingId: must be a real sub-notebook of plan.notebookId (not the parent itself) + const validExistingId = group.existingId && group.existingId !== plan.notebookId + ? group.existingId + : undefined + + if (!group.isNew && validExistingId) { + // Verify it's actually a child of plan.notebookId + const verifiedSub = await prisma.notebook.findFirst({ + where: { id: validExistingId, parentId: plan.notebookId, userId: session.user.id, trashedAt: null }, + select: { id: true }, + }) + if (verifiedSub) { + targetNotebookId = verifiedSub.id + } else { + // Fall through to create a new sub-notebook + group.isNew = true + } + } + + if (group.isNew || !targetNotebookId!) { + // Create new sub-notebook — always as a child of plan.notebookId const highestOrder = await prisma.notebook.findFirst({ where: { parentId: plan.notebookId, userId: session.user.id }, orderBy: { order: 'desc' }, @@ -226,25 +247,27 @@ export async function executeNotebookOrganization(plan: OrganizationPlan): Promi icon: '📁', color: '#75B2D6', order: nextOrder, - parentId: plan.notebookId, + parentId: plan.notebookId, // always a sub-notebook userId: session.user.id, }, }) + console.log(`[organize-notebook] Created sub-notebook "${newSub.name}" (id: ${newSub.id}) under ${plan.notebookId}`) targetNotebookId = newSub.id created++ } - // Move notes + // Move notes — update notebookId to the target sub-notebook const noteIds = group.notes.map(n => n.id) if (noteIds.length > 0) { - await prisma.note.updateMany({ + const result = await prisma.note.updateMany({ where: { id: { in: noteIds }, userId: session.user.id, }, data: { notebookId: targetNotebookId }, }) - moved += noteIds.length + console.log(`[organize-notebook] Moved ${result.count} notes to "${group.name}"`) + moved += result.count } }