import { NextRequest, NextResponse } from 'next/server' import { auth } from '@/auth' import { prisma } from '@/lib/prisma' import { isValidPropertyType, serializePropertyValue } from '@/lib/structured-views/property-utils' import { parseStoredPropertyValue } from '@/lib/structured-views/property-utils' export async function PATCH( request: NextRequest, { params }: { params: Promise<{ id: string }> }, ) { const session = await auth() if (!session?.user?.id) { return NextResponse.json({ success: false, error: 'Unauthorized' }, { status: 401 }) } try { const { id: noteId } = await params const note = await prisma.note.findFirst({ where: { id: noteId, userId: session.user.id, trashedAt: null }, select: { id: true, notebookId: true }, }) if (!note?.notebookId) { return NextResponse.json({ success: false, error: 'Note not found' }, { status: 404 }) } const schema = await prisma.notebookSchema.findUnique({ where: { notebookId: note.notebookId }, include: { properties: true }, }) if (!schema) { return NextResponse.json({ success: false, error: 'Schema not found' }, { status: 404 }) } const body = await request.json() const updates = body.properties && typeof body.properties === 'object' ? body.properties as Record : null if (!updates) { return NextResponse.json({ success: false, error: 'Invalid payload' }, { status: 400 }) } const propertyById = new Map(schema.properties.map((p) => [p.id, p])) const result: Record = {} for (const [propertyId, value] of Object.entries(updates)) { const prop = propertyById.get(propertyId) if (!prop || !isValidPropertyType(prop.type)) continue const serialized = serializePropertyValue(prop.type, value) if (serialized == null) { await prisma.noteProperty.deleteMany({ where: { noteId, propertyId } }) result[propertyId] = parseStoredPropertyValue(prop.type, null) } else { await prisma.noteProperty.upsert({ where: { noteId_propertyId: { noteId, propertyId } }, create: { noteId, propertyId, value: serialized }, update: { value: serialized }, }) result[propertyId] = parseStoredPropertyValue(prop.type, serialized) } } return NextResponse.json({ success: true, data: { values: result } }) } catch (error) { console.error('PATCH note properties:', error) return NextResponse.json({ success: false, error: 'Failed to update properties' }, { status: 500 }) } } export async function GET( _request: NextRequest, { params }: { params: Promise<{ id: string }> }, ) { const session = await auth() if (!session?.user?.id) { return NextResponse.json({ success: false, error: 'Unauthorized' }, { status: 401 }) } try { const { id: noteId } = await params const note = await prisma.note.findFirst({ where: { id: noteId, userId: session.user.id }, select: { id: true }, }) if (!note) { return NextResponse.json({ success: false, error: 'Note not found' }, { status: 404 }) } const rows = await prisma.noteProperty.findMany({ where: { noteId }, include: { property: { select: { type: true } } }, }) const values: Record = {} for (const row of rows) { if (!isValidPropertyType(row.property.type)) continue values[row.propertyId] = parseStoredPropertyValue(row.property.type, row.value) } return NextResponse.json({ success: true, data: { values } }) } catch (error) { console.error('GET note properties:', error) return NextResponse.json({ success: false, error: 'Failed to load properties' }, { status: 500 }) } }