diff --git a/app/api/user-questions/[id]/answer/route.ts b/app/api/user-questions/[id]/answer/route.ts new file mode 100644 index 0000000..6b8304b --- /dev/null +++ b/app/api/user-questions/[id]/answer/route.ts @@ -0,0 +1,62 @@ +import { NextRequest, NextResponse } from 'next/server' +import { z } from 'zod' + +import { authenticateApiRequest } from '@/lib/api-auth' +import { prisma } from '@/lib/prisma' + +interface RouteContext { + params: Promise<{ id: string }> +} + +const bodySchema = z.object({ + answer: z.string().min(1).max(8000), +}) + +export async function POST(request: NextRequest, ctx: RouteContext) { + const auth = await authenticateApiRequest(request) + if ('error' in auth) { + return NextResponse.json({ error: auth.error }, { status: auth.status }) + } + + const { id } = await ctx.params + + let body: unknown + try { + body = await request.json() + } catch { + return NextResponse.json({ error: 'Malformed JSON' }, { status: 400 }) + } + + const parsed = bodySchema.safeParse(body) + if (!parsed.success) { + return NextResponse.json({ error: 'Ongeldige invoer', details: parsed.error.flatten() }, { status: 422 }) + } + + const uq = await prisma.userQuestion.findFirst({ + where: { id }, + select: { id: true, idea_id: true, status: true }, + }) + if (!uq) { + return NextResponse.json({ error: 'UserQuestion niet gevonden' }, { status: 404 }) + } + if (uq.status !== 'pending') { + return NextResponse.json({ error: 'Vraag is al beantwoord' }, { status: 409 }) + } + + await prisma.userQuestion.update({ + where: { id }, + data: { answer: parsed.data.answer, status: 'answered' }, + }) + + await prisma.$executeRaw` + SELECT pg_notify('scrum4me_changes', ${JSON.stringify({ + op: 'U', + entity: 'user_question', + id, + idea_id: uq.idea_id, + status: 'answered', + })}::text) + ` + + return NextResponse.json({ ok: true }) +}