Files
Jyotisha/frontend/src/app/api/rectification/cases/open/route.ts
T

67 lines
2.1 KiB
TypeScript

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);
}
}