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, }); }