import { NextResponse } from 'next/server' import { FrappeError, METHODS, frappeCall, registrationEnabled } from '@/lib/lukenya-api' // The browser posts the form here; this route forwards it to Frappe. The backend // re-validates everything and decides the price, so nothing here is trusted for money. const ALLOWED = [ 'event_edition', 'race_category', 'residency', 'first_name', 'last_name', 'id_number', 'date_of_birth', 'gender', 'nationality', 'email', 'phone', 'whatsapp', 'shirt_size', 'emergency_contact_name', 'emergency_contact_phone', 'guardian_name', 'guardian_phone', 'indemnity_accepted', 'communication_consent', 'preferred_payment', 'emergency_contact_relationship', 'support_request', 'consents', ] as const const REQUIRED = [ 'race_category', 'first_name', 'last_name', 'email', 'phone', 'emergency_contact_name', 'emergency_contact_phone', ] as const export async function POST(req: Request) { if (!registrationEnabled()) { return NextResponse.json({ error: 'Online registration is not open yet.' }, { status: 403 }) } let body: Record try { body = await req.json() } catch { return NextResponse.json({ error: 'The form data could not be read.' }, { status: 400 }) } const payload: Record = {} for (const key of ALLOWED) { const value = body[key] if (value === undefined || value === null) continue payload[key] = typeof value === 'string' ? value.trim().slice(0, key === 'support_request' ? 1000 : 500) : value } payload.event_edition = payload.event_edition || process.env.FRAPPE_EDITION const missing = REQUIRED.filter((k) => !payload[k]) if (!payload.event_edition) missing.unshift('race edition' as never) if (payload.indemnity_accepted !== true) missing.push('indemnity acceptance' as never) if (missing.length) { return NextResponse.json({ error: `Please complete: ${missing.join(', ').replace(/_/g, ' ')}.` }, { status: 400 }) } try { const result = await frappeCall<{ registration: string amount_due: number currency: string payment_token?: string }>(METHODS.createRegistration, { args: { payload }, post: true }) return NextResponse.json({ registration: result.registration, amount_due: result.amount_due, currency: result.currency, payment_token: result.payment_token, }) } catch (err) { const status = err instanceof FrappeError && err.status < 500 ? 400 : 502 return NextResponse.json({ error: (err as Error).message }, { status }) } }