import { NextRequest, NextResponse } from 'next/server'; import { withAuth, withPermission } from '@/lib/api/helpers'; import { errorResponse, NotFoundError } from '@/lib/errors'; import { setValuesSchema } from '@/lib/validators/custom-fields'; import { getValues, setValues } from '@/lib/services/custom-fields.service'; // Custom-field values live on top of a port-scoped entity (client, yacht, // interest, berth, company). Reading the values is in scope for any role // that can view clients (the most common surface); writing requires the // equivalent edit permission. The service-layer also re-validates the // entityId against the field definition's entityType + portId so a // caller cannot poke values onto an arbitrary or foreign-port entity. export const GET = withAuth( withPermission('clients', 'view', async (_req: NextRequest, ctx, params) => { try { const { entityId } = params; if (!entityId) throw new NotFoundError('Entity'); const data = await getValues(entityId, ctx.portId); return NextResponse.json({ data }); } catch (error) { return errorResponse(error); } }), ); export const PUT = withAuth( withPermission('clients', 'edit', async (req: NextRequest, ctx, params) => { try { const { entityId } = params; if (!entityId) throw new NotFoundError('Entity'); const body = await req.json(); const { values } = setValuesSchema.parse(body); const result = await setValues( entityId, ctx.portId, ctx.userId, values as Array<{ fieldId: string; value: unknown }>, { userId: ctx.userId, portId: ctx.portId, ipAddress: ctx.ipAddress, userAgent: ctx.userAgent, }, ); return NextResponse.json({ data: result }); } catch (error) { return errorResponse(error); } }), );