import { NextResponse } from "next/server"; import { createAdminSupabaseClient } from "@/lib/supabase/admin"; import { createServerSupabaseClient } from "@/lib/supabase/server"; import { RectificationCaseServiceError, mapRectificationRpcError, openRectificationCase, } from "@/lib/rectification-agentic/v9/case-service"; import { parseOpenRectificationCaseRequest } from "@/lib/rectification-agentic/v9/open-request"; export const runtime = "nodejs"; function serviceErrorResponse(error: unknown) { if (error instanceof RectificationCaseServiceError) { const view = mapRectificationRpcError( new Error(`agentic_rectification_${error.code}`), ); return NextResponse.json({ error: view.message, code: view.code }, { status: view.status }); } return NextResponse.json( { error: "校正服务暂时不可用", code: "rectification_service_failed" }, { status: 500 }, ); } /** * POST /api/rectification/cases/open * * Browser sends only { intent, requestId } (+ sessionId for intent=session). * The server derives the user from the session, normalizes the profile and * decides resume-or-create. Double-click / multi-tab are idempotent. */ export async function POST(request: Request) { let supabase; let accounting; try { supabase = await createServerSupabaseClient(); accounting = createAdminSupabaseClient(); } catch { return NextResponse.json({ error: "服务尚未配置" }, { status: 503 }); } const { data: { user }, error: authError, } = await supabase.auth.getUser(); if (authError || !user) { return NextResponse.json({ error: "请先登录" }, { status: 401 }); } const parsed = parseOpenRectificationCaseRequest( await request.json().catch(() => null), ); if (!parsed) { return NextResponse.json( { error: "请求内容不正确", code: "invalid_open_request" }, { status: 400 }, ); } try { const response = await openRectificationCase(accounting, user.id, parsed); return NextResponse.json(response); } catch (error) { return serviceErrorResponse(error); } }