Files
Momento/Momento-main/momento/memento-note/app/api/notes/[id]/move/route.ts
Sepehr Ramezani ed807d3b2a
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 5s
Add safe database migration workflow and note history infrastructure.
This introduces guarded migrations with automatic backups, fixes note creation after DB reset, and wires snapshot/restore history across notes surfaces.
2026-04-28 17:14:26 +02:00

111 lines
3.1 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server'
import prisma from '@/lib/prisma'
import { auth } from '@/auth'
import { reconcileLabelsAfterNoteMove } from '@/app/actions/notes'
import { createNoteHistorySnapshot, isNoteHistoryEnabledForUser } from '@/lib/note-history'
// POST /api/notes/[id]/move - Move a note to a notebook (or to Inbox)
export async function POST(
request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
const session = await auth()
if (!session?.user?.id) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
try {
const { id } = await params
const body = await request.json()
const { notebookId } = body
// Get the note
const note = await prisma.note.findUnique({
where: { id },
select: {
id: true,
userId: true,
notebookId: true
}
})
if (!note) {
return NextResponse.json(
{ success: false, error: 'Note not found' },
{ status: 404 }
)
}
// Verify ownership
if (note.userId !== session.user.id) {
return NextResponse.json(
{ success: false, error: 'Forbidden' },
{ status: 403 }
)
}
// If notebookId is provided, verify it exists and belongs to the user
if (notebookId !== null && notebookId !== '') {
const notebook = await prisma.notebook.findUnique({
where: { id: notebookId },
select: { userId: true }
})
if (!notebook || notebook.userId !== session.user.id) {
return NextResponse.json(
{ success: false, error: 'Notebook not found or unauthorized' },
{ status: 403 }
)
}
}
// Update the note's notebook
// notebookId = null or "" means move to Inbox (Notes générales)
const targetNotebookId = notebookId && notebookId !== '' ? notebookId : null
const updatedNote = await prisma.note.update({
where: { id },
data: {
notebookId: targetNotebookId
},
include: {
notebook: {
select: { id: true, name: true }
}
}
})
await reconcileLabelsAfterNoteMove(id, targetNotebookId)
try {
const historyEnabled = await isNoteHistoryEnabledForUser(session.user.id)
if (historyEnabled) {
await createNoteHistorySnapshot({
noteId: id,
userId: session.user.id,
reason: 'move-notebook',
})
}
} catch (snapshotError) {
console.error('[HISTORY] Failed to create snapshot after notebook move:', snapshotError)
}
// No revalidatePath('/') here — the client-side triggerRefresh() in
// notebooks-context.tsx handles the refresh. Avoiding server-side
// revalidation prevents a double-refresh (server + client).
return NextResponse.json({
success: true,
data: updatedNote,
message: notebookId && notebookId !== ''
? `Note moved to "${updatedNote.notebook?.name || 'notebook'}"`
: 'Note moved to Inbox'
})
} catch (error) {
return NextResponse.json(
{ success: false, error: 'Failed to move note' },
{ status: 500 }
)
}
}