sistema-de-chamados/convex/ops.ts
2025-12-10 14:43:13 -03:00

76 lines
2.1 KiB
TypeScript

import { ConvexError, v } from "convex/values"
import { query } from "./_generated/server"
import { getOfflineThresholdMs, getStaleThresholdMs } from "./machines"
const MACHINE_SCAN_LIMIT = 1200
export const healthSnapshot = query({
args: {
token: v.optional(v.string()),
},
handler: async (ctx, args) => {
const requiredToken = process.env["INTERNAL_HEALTH_TOKEN"] ?? process.env["REPORTS_CRON_SECRET"] ?? null
if (requiredToken && args.token !== requiredToken) {
throw new ConvexError("Nao autorizado")
}
const now = Date.now()
const offlineMs = getOfflineThresholdMs()
const staleMs = getStaleThresholdMs(offlineMs)
const machines = await ctx.db.query("machines").take(MACHINE_SCAN_LIMIT)
const heartbeats = await ctx.db.query("machineHeartbeats").collect()
let online = 0
let warning = 0
let offline = 0
let newest = 0
let oldest = 0
const withHeartbeat = new Set<string>()
for (const hb of heartbeats) {
const ageMs = now - hb.lastHeartbeatAt
withHeartbeat.add(String(hb.machineId))
if (newest === 0 || hb.lastHeartbeatAt > newest) {
newest = hb.lastHeartbeatAt
}
if (oldest === 0 || hb.lastHeartbeatAt < oldest) {
oldest = hb.lastHeartbeatAt
}
if (ageMs <= offlineMs) {
online += 1
} else if (ageMs <= staleMs) {
warning += 1
} else {
offline += 1
}
}
const withoutHeartbeat = machines.length - withHeartbeat.size
const totalOffline = offline + (withoutHeartbeat > 0 ? withoutHeartbeat : 0)
return {
totals: {
machines: machines.length,
heartbeats: heartbeats.length,
withoutHeartbeat: withoutHeartbeat > 0 ? withoutHeartbeat : 0,
truncated: machines.length === MACHINE_SCAN_LIMIT,
},
connectivity: {
online,
warning,
offline: totalOffline,
},
heartbeatAgeMs: {
newest: newest ? now - newest : null,
oldest: oldest ? now - oldest : null,
},
thresholds: {
offlineMs,
staleMs,
},
generatedAt: now,
}
},
})