import { parseAdminAuth } from "@/lib/api/admin-auth-context"; import { fail, ok } from "@/lib/response"; import { writeAudit } from "@/modules/audit/service"; import { AuthError } from "@/modules/auth/errors"; import { createHostCustomer, listHostCustomers, } from "@/modules/customer/customer-service"; function parsePagination(searchParams: URLSearchParams): { page: number; size: number; } | null { const pageRaw = searchParams.get("page"); const sizeRaw = searchParams.get("size"); if (!pageRaw || !sizeRaw) { return null; } const page = Number(pageRaw); const size = Number(sizeRaw); if ( !Number.isInteger(page) || !Number.isInteger(size) || page < 1 || size < 1 || size > 100 ) { return null; } return { page, size }; } export async function GET(request: Request) { try { parseAdminAuth(request); } catch (error) { if (error instanceof AuthError) { return fail(error.code, error.message, error.httpStatus); } throw error; } const url = new URL(request.url); const pagination = parsePagination(url.searchParams); if (!pagination) { return fail("VALIDATION_FAILED", "请提供有效的 page 和 size 参数", 400); } const keyword = url.searchParams.get("keyword") ?? undefined; const data = await listHostCustomers({ page: pagination.page, size: pagination.size, keyword, }); return ok(data); } export async function POST(request: Request) { let auth; try { auth = parseAdminAuth(request); } catch (error) { if (error instanceof AuthError) { return fail(error.code, error.message, error.httpStatus); } throw error; } let body: unknown; try { body = await request.json(); } catch { return fail("VALIDATION_FAILED", "请求体格式无效", 400); } const name = typeof (body as { name?: unknown }).name === "string" ? (body as { name: string }).name : ""; const remark = typeof (body as { remark?: unknown }).remark === "string" ? (body as { remark: string }).remark : undefined; const embedPassword = typeof (body as { embed_password?: unknown }).embed_password === "string" ? (body as { embed_password: string }).embed_password : undefined; try { const created = await createHostCustomer({ name, remark, embed_password: embedPassword, }); await writeAudit("customer:create", auth.userId, created.customer_id, { name: created.name, key_prefix: created.api_keys[0]?.key_prefix, }); return ok(created); } catch (error) { const message = error instanceof Error ? error.message : "创建客户失败"; return fail("VALIDATION_FAILED", message, 400); } }