51 lines
1.6 KiB
TypeScript
51 lines
1.6 KiB
TypeScript
import { NextResponse } from "next/server";
|
|
import { prisma } from "@/lib/db";
|
|
import { getActiveAccountId } from "@/lib/account-context";
|
|
import { enqueueJob, findActiveJob } from "@/lib/jobs/runner";
|
|
import { scheduleBackgroundJob } from "@/lib/jobs/schedule";
|
|
|
|
export async function POST(request: Request) {
|
|
try {
|
|
const { topicId, brief } = (await request.json()) as {
|
|
topicId?: string;
|
|
brief?: string | null;
|
|
};
|
|
if (!topicId) {
|
|
return NextResponse.json({ error: "缺少 topicId" }, { status: 400 });
|
|
}
|
|
|
|
const accountId = await getActiveAccountId();
|
|
const topic = await prisma.topic.findUnique({ where: { id: topicId } });
|
|
if (!topic || (accountId && topic.accountId !== accountId)) {
|
|
return NextResponse.json({ error: "找不到主題" }, { status: 404 });
|
|
}
|
|
|
|
const existing = await findActiveJob(topicId, "analyze-topic");
|
|
if (existing) {
|
|
return NextResponse.json({
|
|
jobId: existing.id,
|
|
status: existing.status,
|
|
message: "已有分析任務在背景執行中",
|
|
});
|
|
}
|
|
|
|
const job = await enqueueJob({
|
|
type: "analyze-topic",
|
|
topicId,
|
|
label: `${topic.label} · AI 研究地圖`,
|
|
payload: { topicId, brief },
|
|
});
|
|
|
|
scheduleBackgroundJob(job.id);
|
|
|
|
return NextResponse.json({
|
|
jobId: job.id,
|
|
status: "pending",
|
|
message: "已於背景執行,可自由切換頁面",
|
|
});
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : "分析失敗";
|
|
return NextResponse.json({ error: message }, { status: 500 });
|
|
}
|
|
}
|