58 lines
1.8 KiB
TypeScript
58 lines
1.8 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";
|
|
import { runScanForAllActiveTopics } from "@/lib/services/scan";
|
|
|
|
export const maxDuration = 300;
|
|
|
|
export async function POST(request: Request) {
|
|
try {
|
|
const body = await request.json().catch(() => ({}));
|
|
const accountId = await getActiveAccountId();
|
|
const { topicId, useTags, selectedTags } = body as {
|
|
topicId?: string;
|
|
useTags?: boolean;
|
|
selectedTags?: string[];
|
|
};
|
|
|
|
if (topicId) {
|
|
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, "scan");
|
|
if (existing) {
|
|
return NextResponse.json({
|
|
jobId: existing.id,
|
|
status: existing.status,
|
|
message: "已有海巡任務在背景執行中",
|
|
});
|
|
}
|
|
|
|
const job = await enqueueJob({
|
|
type: "scan",
|
|
topicId,
|
|
label: `${topic.label} · 標籤海巡`,
|
|
payload: { topicId, useTags, selectedTags },
|
|
});
|
|
|
|
scheduleBackgroundJob(job.id);
|
|
|
|
return NextResponse.json({
|
|
jobId: job.id,
|
|
status: "pending",
|
|
message: "已於背景執行,可自由切換頁面",
|
|
});
|
|
}
|
|
|
|
const scans = await runScanForAllActiveTopics(accountId);
|
|
return NextResponse.json({ scans });
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : "海巡失敗";
|
|
return NextResponse.json({ error: message }, { status: 500 });
|
|
}
|
|
}
|