import { type NextRequest, NextResponse } from "next/server"; import { auth } from "@/app/(auth)/auth"; import { AGENT_PSD_RENDER_TASK_POLL_AFTER_MS, agentPsdTemplateRenderRequestSchema, } from "@/lib/agents/psd-render-task-contract"; import { createAgentPsdRenderTask, enqueueAgentPsdRenderTask, getAgentPsdRenderTaskForUser, } from "@/lib/agents/psd-render-task-queue"; import { describeRemoteAssetLocation } from "@/lib/agents/psd-remote-asset"; import { type AgentPsdTemplateRenderResponse, type AgentPsdTemplateRenderStatus, } from "@/lib/agents/psd-template-config"; import { getFriendlyRateLimitMessage, getUserFacingRequestErrorMessage, isRateLimitError, } from "@/lib/request-error"; export const runtime = "nodejs"; function jsonError(status: number, error: string) { const payload: AgentPsdTemplateRenderResponse = { success: false, error, }; return NextResponse.json(payload, { status }); } function normalizeTaskStatus( status: string ): Extract { return status === "running" ? "running" : "pending"; } export async function GET(request: NextRequest) { const session = await auth().catch(() => null); if (!session?.user?.id) { return jsonError(401, "未登录"); } const { searchParams } = new URL(request.url); const taskId = String(searchParams.get("taskId") || "").trim(); if (!taskId) { return jsonError(400, "缺少 taskId 参数"); } try { const task = await getAgentPsdRenderTaskForUser({ taskId, userId: session.user.id, }); if (!task) { return jsonError(404, "导出任务不存在"); } if (task.status === "succeeded") { const result = task.result as AgentPsdTemplateRenderResponse["result"] | null; if (!result?.url) { return NextResponse.json( { success: false, status: "failed", taskId: task.id, error: "导出任务已完成,但未返回结果图", } satisfies AgentPsdTemplateRenderResponse ); } return NextResponse.json({ success: true, status: "succeeded", taskId: task.id, result, } satisfies AgentPsdTemplateRenderResponse); } if (task.status === "failed") { return NextResponse.json({ success: false, status: "failed", taskId: task.id, error: task.error || "PSD 模板渲染失败", } satisfies AgentPsdTemplateRenderResponse); } return NextResponse.json({ success: true, processing: true, status: normalizeTaskStatus(task.status), taskId: task.id, pollAfterMs: AGENT_PSD_RENDER_TASK_POLL_AFTER_MS, } satisfies AgentPsdTemplateRenderResponse); } catch (error) { console.error("[PSD Templates] render status failed:", { taskId, error }); return jsonError(500, "查询 PSD 导出任务失败"); } } export async function POST(request: NextRequest) { const session = await auth().catch(() => null); if (!session?.user?.id) { return jsonError(401, "未登录"); } let body: ReturnType; try { body = agentPsdTemplateRenderRequestSchema.parse(await request.json()); } catch { return jsonError(400, "渲染参数不合法"); } try { const task = await createAgentPsdRenderTask({ userId: session.user.id, request: body, }); await enqueueAgentPsdRenderTask(task.id); return NextResponse.json({ success: true, processing: true, status: normalizeTaskStatus(task.status), taskId: task.id, pollAfterMs: AGENT_PSD_RENDER_TASK_POLL_AFTER_MS, } satisfies AgentPsdTemplateRenderResponse); } catch (error) { console.error("[PSD Templates] render failed:", { templateId: body.templateId, sourceImage: body.sourceImageUrl ? describeRemoteAssetLocation(body.sourceImageUrl) : null, assignedImageCount: Object.keys(body.imageAssignments || {}).length, error, }); if (isRateLimitError(error)) { return NextResponse.json( { success: false, error: getFriendlyRateLimitMessage("当前操作过于频繁,请稍后再试"), } satisfies AgentPsdTemplateRenderResponse, { status: 429, headers: { "Retry-After": "10", }, } ); } const message = getUserFacingRequestErrorMessage(error, "PSD 模板渲染失败", { rateLimitMessage: getFriendlyRateLimitMessage("当前操作过于频繁,请稍后再试"), }); return jsonError(502, message); } }