import { NextRequest, NextResponse } from 'next/server' import prisma from '@/lib/prisma' import { auth } from '@/auth' import { z } from 'zod' import { logActivity } from '@/lib/brainstorm-collab' import { emitToSession } from '@/lib/socket-emit' const convertSchema = z.object({ ideaId: z.string().min(1), }) export async function POST( request: NextRequest, { params }: { params: Promise<{ sessionId: string }> } ) { const session = await auth() if (!session?.user?.id) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } try { const { sessionId } = await params const body = await request.json() const { ideaId } = convertSchema.parse(body) const brainstormSession = await prisma.brainstormSession.findFirst({ where: { id: sessionId, OR: [ { userId: session.user.id }, { participants: { some: { userId: session.user.id } } }, ], }, }) if (!brainstormSession) { return NextResponse.json({ error: 'Session not found' }, { status: 404 }) } const idea = await prisma.brainstormIdea.findFirst({ where: { id: ideaId, sessionId }, include: { noteRefs: { include: { note: true } } }, }) if (!idea) { return NextResponse.json({ error: 'Idea not found' }, { status: 404 }) } if (idea.status === 'converted') { return NextResponse.json({ error: 'Already converted' }, { status: 400 }) } let sourceSection = '' let targetNotebookId: string | null = null if (brainstormSession.exportedNoteId) { const exportedNote = await prisma.note.findUnique({ where: { id: brainstormSession.exportedNoteId }, select: { notebookId: true }, }) if (exportedNote?.notebookId) { targetNotebookId = exportedNote.notebookId } } if (!targetNotebookId && brainstormSession.sourceNoteId) { const sourceNote = await prisma.note.findUnique({ where: { id: brainstormSession.sourceNoteId }, select: { title: true, id: true, notebookId: true }, }) if (sourceNote) { sourceSection = `\n\n**Source note**: [${sourceNote.title || 'Untitled'}](note:${sourceNote.id})` targetNotebookId = sourceNote.notebookId } } if (!targetNotebookId) { const notebookName = brainstormSession.seedIdea.length > 40 ? brainstormSession.seedIdea.substring(0, 40).trim() + '…' : brainstormSession.seedIdea let notebook = await prisma.notebook.findFirst({ where: { userId: session.user.id, name: notebookName, trashedAt: null }, }) if (!notebook) { const notebookCount = await prisma.notebook.count({ where: { userId: session.user.id, trashedAt: null } }) notebook = await prisma.notebook.create({ data: { userId: session.user.id, name: notebookName, order: notebookCount, icon: 'wind' }, }) } targetNotebookId = notebook.id } let originSection = '' const validRefs = idea.noteRefs.filter(r => r.noteId && r.note) if (validRefs.length > 0) { originSection = '\n\n## Origin\n' for (const ref of validRefs) { const relLabel = { derived_from: 'Derived from', opposes: 'In opposition with', extends: 'Extends', synthesizes: 'Synthesizes', transposes: 'Transposes', }[ref.relation] || 'Related to' originSection += `- **${relLabel}** [${ref.note?.title || 'Untitled'}](note:${ref.noteId}): ${ref.explanation}\n` } } const noteContent = `# ${idea.title}\n\n${idea.description}\n\n---\n\n**Connection to seed**: ${idea.connectionToSeed || 'N/A'}\n**Novelty score**: ${idea.noveltyScore || 'N/A'}/10\n\n**Source brainstorm**: "${brainstormSession.seedIdea}"${sourceSection}${originSection}` const note = await prisma.note.create({ data: { userId: session.user.id, title: idea.title, content: noteContent, type: 'markdown', labels: JSON.stringify(['brainstorm', 'idée']), notebookId: targetNotebookId, }, }) const tagPromises: Promise[] = [] tagPromises.push( prisma.brainstormIdea.update({ where: { id: ideaId }, data: { status: 'converted', convertedToNoteId: note.id, }, }) ) tagPromises.push( prisma.brainstormNoteRef.updateMany({ where: { ideaId }, data: { verdict: 'accepted' }, }) ) for (const ref of validRefs) { const existingLabels: string[] = (() => { try { return JSON.parse((ref.note as any)?.labels || '[]') } catch { return [] } })() if (!existingLabels.includes('brainstorm-fruitful')) { existingLabels.push('brainstorm-fruitful') tagPromises.push( prisma.note.update({ where: { id: ref.noteId! }, data: { labels: JSON.stringify(existingLabels) }, }) ) } } await prisma.$transaction(tagPromises) await logActivity(sessionId, 'idea_converted', session.user.id, { ideaTitle: idea.title, ideaId: idea.id, noteId: note.id }) await emitToSession(sessionId, 'activity:new', { action: 'idea_converted', userId: session.user.id, userName: session.user.name || 'Guest', details: { ideaTitle: idea.title, ideaId: idea.id, noteId: note.id } }) return NextResponse.json({ success: true, data: note }, { status: 201 }) } catch (error: any) { if (error instanceof z.ZodError) { return NextResponse.json({ error: error.issues }, { status: 400 }) } console.error('Error converting idea:', error) return NextResponse.json( { error: error.message || 'Failed to convert idea' }, { status: 500 } ) } }