You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

66 lines
1.8 KiB

import { parseAdminAuth } from "@/lib/api/admin-auth-context";
import { fail, ok } from "@/lib/response";
import { AuthError } from "@/modules/auth/errors";
import { requirePermission } from "@/modules/auth/rbac";
import { isCircuitOpen } from "@/modules/cache/circuit-breaker";
import { prisma } from "@/lib/prisma";
import { getQueueDepth } from "@/workers/rpa/queue";
import {
getWorkerPauseRemaining,
listWorkerHeartbeats,
} from "@/workers/rpa/worker-state";
export async function GET(request: Request) {
let auth;
try {
auth = parseAdminAuth(request);
requirePermission(auth, "rpa:operate");
} catch (error) {
if (error instanceof AuthError) {
return fail(error.code, error.message, error.httpStatus);
}
throw error;
}
void auth;
const since24h = new Date(Date.now() - 24 * 60 * 60 * 1_000);
const [circuitOpen, queueDepth, heartbeats, total24h, success24h] =
await Promise.all([
isCircuitOpen(),
getQueueDepth(),
listWorkerHeartbeats(),
prisma.quoteRecord.count({
where: { createdAt: { gte: since24h }, sourceType: "rpa" },
}),
prisma.quoteRecord.count({
where: {
createdAt: { gte: since24h },
sourceType: "rpa",
status: "done",
},
}),
]);
const workers = await Promise.all(
heartbeats.map(async (item) => ({
worker_id: item.workerId,
last_seen_ms: item.lastSeenMs,
paused_seconds: await getWorkerPauseRemaining(item.workerId),
online:
item.lastSeenMs !== null &&
Date.now() - item.lastSeenMs < 30_000,
})),
);
const successRate24h =
total24h > 0 ? Math.round((success24h / total24h) * 10_000) / 100 : 100;
return ok({
workers,
queue_depth: queueDepth,
circuit_open: circuitOpen,
success_rate_24h: successRate24h,
});
}