feat: adiciona informacoes de reinicio e melhora SLA global
All checks were successful
All checks were successful
- Agente Rust: captura LastBootTime, uptime e contagem de boots - Backend: extrai campos do extended (bootInfo, discos, RAM, etc) antes de salvar - Frontend /devices: exibe secao de ultimo reinicio - SLA global: adiciona campos de modo, threshold de alerta e status de pausa - Corrige acento em "destinatario" -> "destinatario" em automations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
d32b94c22d
commit
f39bd46c2b
7 changed files with 338 additions and 19 deletions
|
|
@ -331,9 +331,59 @@ async function getMachineLastHeartbeat(
|
|||
return hb?.lastHeartbeatAt ?? fallback ?? null
|
||||
}
|
||||
|
||||
// Campos do inventory que sao muito grandes e nao devem ser persistidos
|
||||
// para evitar OOM no Convex (documentos de ~100KB cada)
|
||||
const INVENTORY_BLOCKLIST = new Set(["software", "extended"])
|
||||
// Campo software é muito grande e é tratado separadamente via machineSoftware
|
||||
|
||||
// Extrai campos importantes do extended antes de bloqueá-lo
|
||||
function extractFromExtended(extended: unknown): JsonRecord {
|
||||
const result: JsonRecord = {}
|
||||
const sanitizedExtended = sanitizeRecord(extended)
|
||||
if (!sanitizedExtended) return result
|
||||
|
||||
// Extrair dados do Windows
|
||||
const windows = sanitizeRecord(sanitizedExtended["windows"])
|
||||
if (windows) {
|
||||
const windowsFields: JsonRecord = {}
|
||||
// bootInfo - informacoes de reinicio
|
||||
if (windows["bootInfo"]) {
|
||||
windowsFields["bootInfo"] = windows["bootInfo"] as JsonValue
|
||||
}
|
||||
// osInfo - informacoes do sistema operacional
|
||||
if (windows["osInfo"]) {
|
||||
windowsFields["osInfo"] = windows["osInfo"] as JsonValue
|
||||
}
|
||||
// cpu, baseboard, bios, memoryModules, videoControllers, disks
|
||||
for (const key of ["cpu", "baseboard", "bios", "memoryModules", "videoControllers", "disks", "bitLocker", "tpm", "secureBoot", "deviceGuard", "firewallProfiles", "windowsUpdate", "computerSystem", "azureAdStatus", "battery", "thermal", "networkAdapters", "monitors", "chassis", "defender", "hotfix"]) {
|
||||
if (windows[key]) {
|
||||
windowsFields[key] = windows[key] as JsonValue
|
||||
}
|
||||
}
|
||||
if (Object.keys(windowsFields).length > 0) {
|
||||
result["windows"] = windowsFields
|
||||
}
|
||||
}
|
||||
|
||||
// Extrair dados do Linux
|
||||
const linux = sanitizeRecord(sanitizedExtended["linux"])
|
||||
if (linux) {
|
||||
const linuxFields: JsonRecord = {}
|
||||
for (const key of ["lsblk", "smart", "lspci", "lsusb", "dmidecode"]) {
|
||||
if (linux[key]) {
|
||||
linuxFields[key] = linux[key] as JsonValue
|
||||
}
|
||||
}
|
||||
if (Object.keys(linuxFields).length > 0) {
|
||||
result["linux"] = linuxFields
|
||||
}
|
||||
}
|
||||
|
||||
// Extrair dados do macOS
|
||||
const macos = sanitizeRecord(sanitizedExtended["macos"])
|
||||
if (macos) {
|
||||
result["macos"] = macos as JsonValue
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
function mergeInventory(current: JsonRecord | null | undefined, patch: Record<string, unknown>): JsonRecord {
|
||||
const sanitizedPatch = sanitizeRecord(patch)
|
||||
|
|
@ -341,9 +391,10 @@ function mergeInventory(current: JsonRecord | null | undefined, patch: Record<st
|
|||
return current ? { ...current } : {}
|
||||
}
|
||||
const base: JsonRecord = current ? { ...current } : {}
|
||||
|
||||
for (const [key, value] of Object.entries(sanitizedPatch)) {
|
||||
// Filtrar campos volumosos que causam OOM
|
||||
if (INVENTORY_BLOCKLIST.has(key)) continue
|
||||
// Filtrar software (extended já foi processado em sanitizeInventoryPayload)
|
||||
if (key === "software") continue
|
||||
if (value === undefined) continue
|
||||
if (isObject(value) && isObject(base[key])) {
|
||||
base[key] = mergeInventory(base[key] as JsonRecord, value as Record<string, unknown>)
|
||||
|
|
@ -393,9 +444,20 @@ function ensureString(value: unknown): string | null {
|
|||
function sanitizeInventoryPayload(value: unknown): JsonRecord | null {
|
||||
const record = sanitizeRecord(value)
|
||||
if (!record) return null
|
||||
for (const blocked of INVENTORY_BLOCKLIST) {
|
||||
delete record[blocked]
|
||||
|
||||
// Extrair campos importantes do extended antes de deletá-lo
|
||||
if (record["extended"]) {
|
||||
const extractedExtended = extractFromExtended(record["extended"])
|
||||
if (Object.keys(extractedExtended).length > 0) {
|
||||
record["extended"] = extractedExtended
|
||||
} else {
|
||||
delete record["extended"]
|
||||
}
|
||||
}
|
||||
|
||||
// Deletar apenas software (extended já foi processado acima)
|
||||
delete record["software"]
|
||||
|
||||
return record
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue