65 lines
2.2 KiB
TypeScript
65 lines
2.2 KiB
TypeScript
import { NextResponse } from "next/server";
|
|
import { prisma } from "@/lib/db";
|
|
import { authErrorResponse } from "@/lib/auth/api";
|
|
import { requireSessionUser } from "@/lib/auth/session";
|
|
import { recoverStaleBackgroundJobs } from "@/lib/jobs/runner";
|
|
|
|
export async function GET(request: Request) {
|
|
try {
|
|
const user = await requireSessionUser();
|
|
const { searchParams } = new URL(request.url);
|
|
const activeOnly = searchParams.get("active") === "1";
|
|
const topicId = searchParams.get("topicId");
|
|
const limit = Math.min(parseInt(searchParams.get("limit") ?? "10", 10), 30);
|
|
|
|
const userAccounts = await prisma.account.findMany({
|
|
where: { userId: user.id },
|
|
select: { id: true },
|
|
});
|
|
const accountIds = userAccounts.map((account) => account.id);
|
|
if (accountIds.length === 0) {
|
|
return NextResponse.json({ jobs: [] });
|
|
}
|
|
|
|
if (activeOnly) {
|
|
await recoverStaleBackgroundJobs();
|
|
}
|
|
|
|
const baseWhere = {
|
|
accountId: { in: accountIds },
|
|
...(topicId ? { topicId } : {}),
|
|
};
|
|
const jobs = activeOnly
|
|
? await prisma.backgroundJob.findMany({
|
|
where: { ...baseWhere, status: { in: ["pending", "running"] } },
|
|
orderBy: { createdAt: "desc" },
|
|
})
|
|
: await Promise.all([
|
|
prisma.backgroundJob.findMany({
|
|
where: { ...baseWhere, status: { in: ["pending", "running"] } },
|
|
orderBy: { createdAt: "desc" },
|
|
}),
|
|
prisma.backgroundJob.findMany({
|
|
where: baseWhere,
|
|
orderBy: { createdAt: "desc" },
|
|
take: limit,
|
|
}),
|
|
]).then(([active, recent]) => {
|
|
const merged = new Map([...active, ...recent].map((job) => [job.id, job]));
|
|
return [...merged.values()].sort(
|
|
(a, b) => b.createdAt.getTime() - a.createdAt.getTime()
|
|
);
|
|
});
|
|
|
|
return NextResponse.json({ jobs });
|
|
} catch (error) {
|
|
const authRes = authErrorResponse(error);
|
|
if (authRes) return authRes;
|
|
console.error("[jobs GET]", error);
|
|
return NextResponse.json(
|
|
{ error: error instanceof Error ? error.message : "載入任務失敗", jobs: [] },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|