import { NextResponse } from 'next/server'; import { z } from 'zod'; import { withAuth } from '@/lib/api/helpers'; import { parseBody } from '@/lib/api/route-helpers'; import { errorResponse } from '@/lib/errors'; import { getPublicOcrConfig, saveOcrConfig, OCR_MODELS } from '@/lib/services/ocr-config.service'; const saveSchema = z.object({ /** When 'global', requires super_admin and stores at port_id=null. */ scope: z.enum(['port', 'global']), provider: z.enum(['openai', 'claude']), model: z.string().min(1), apiKey: z.string().optional(), clearApiKey: z.boolean().optional(), useGlobal: z.boolean().optional(), aiEnabled: z.boolean().optional(), }); export const GET = withAuth(async (req, ctx) => { try { const url = new URL(req.url); const scope = url.searchParams.get('scope') ?? 'port'; if (scope === 'global' && !ctx.isSuperAdmin) { return NextResponse.json({ error: 'Super admin only' }, { status: 403 }); } const config = await getPublicOcrConfig(scope === 'global' ? null : ctx.portId); return NextResponse.json({ data: config, models: OCR_MODELS }); } catch (error) { return errorResponse(error); } }); export const PUT = withAuth(async (req, ctx) => { try { const body = await parseBody(req, saveSchema); if (body.scope === 'global' && !ctx.isSuperAdmin) { return NextResponse.json({ error: 'Super admin only' }, { status: 403 }); } const validModels = OCR_MODELS[body.provider]; if (!validModels.includes(body.model)) { return NextResponse.json( { error: `Invalid model for provider ${body.provider}` }, { status: 400 }, ); } await saveOcrConfig( body.scope === 'global' ? null : ctx.portId, { provider: body.provider, model: body.model, apiKey: body.apiKey, clearApiKey: body.clearApiKey, useGlobal: body.useGlobal, aiEnabled: body.aiEnabled, }, ctx.userId, ); return NextResponse.json({ ok: true }); } catch (error) { return errorResponse(error); } });