import { z } from "zod"; import { requireAdmin } from "@/lib/middleware/admin"; import { getAllSystemSettings, getSystemSetting, upsertSystemSetting, } from "@/lib/db/queries"; import { ChatSDKError } from "@/lib/errors"; import { probeBflModelSupport } from "@/lib/realtime/bfl-capability"; const settingSchema = z.object({ key: z.string(), value: z.any(), }); const DEFAULT_BFL_MODEL = "flux-2-klein-4b"; const DEFAULT_BFL_BASE_URL = "https://api.bfl.ai"; function isObjectLike(value: unknown): value is Record { return Boolean(value) && typeof value === "object" && !Array.isArray(value); } function mapProbeStatus(code: string) { if (code === "UPSTREAM_ERROR") return 502; return 400; } export async function GET(request: Request) { try { await requireAdmin(); const { searchParams } = new URL(request.url); const key = searchParams.get("key"); if (key) { const setting = await getSystemSetting({ key }); return Response.json({ setting }); } const settings = await getAllSystemSettings(); return Response.json({ settings }); } catch (error) { if (error instanceof ChatSDKError) { return error.toResponse(); } return new ChatSDKError("offline:admin").toResponse(); } } export async function POST(request: Request) { try { const session = await requireAdmin(); const body = await request.json(); const { key, value } = settingSchema.parse(body); let nextValue = value; if (key === "realtime_canvas_config") { if (!isObjectLike(value)) { return new ChatSDKError("bad_request:api", "realtime_canvas_config value 必须为对象").toResponse(); } const enabled = value.enabled !== false; const bflApiKey = String( value.bflApiKey || value.runwareApiKey || value.falApiKey || value.apiKey || "" ).trim(); const bflModel = String(value.bflModel || value.runwareModel || DEFAULT_BFL_MODEL).trim() || DEFAULT_BFL_MODEL; const bflBaseUrl = String(value.bflBaseUrl || DEFAULT_BFL_BASE_URL).trim() || DEFAULT_BFL_BASE_URL; const renderMode = value.renderMode === "strict-structure" || value.renderMode === "stylize" || value.renderMode === "balanced" ? value.renderMode : "balanced"; if (enabled) { if (!bflApiKey) { return new ChatSDKError("bad_request:api", "启用实时画布必须配置 BFL API Key").toResponse(); } const probeResult = await probeBflModelSupport({ apiKey: bflApiKey, modelId: bflModel, baseUrl: bflBaseUrl, }); if (!probeResult.supported) { return Response.json( { code: probeResult.code, message: probeResult.message, }, { status: mapProbeStatus(probeResult.code) } ); } } nextValue = { ...value, bflApiKey, bflModel, bflBaseUrl, runwareApiKey: bflApiKey, falApiKey: bflApiKey, apiKey: bflApiKey, runwareModel: bflModel, renderMode, }; } const setting = await upsertSystemSetting({ key, value: nextValue, updatedBy: session.user.id, }); return Response.json({ setting: setting[0] }); } catch (error) { if (error instanceof ChatSDKError) { return error.toResponse(); } if (error instanceof z.ZodError) { return new ChatSDKError("bad_request:api", error.message).toResponse(); } return new ChatSDKError("offline:admin").toResponse(); } }