feat(export): adiciona colunas bootInfo e remove Fleet do inventario
All checks were successful
CI/CD Web + Desktop / Detect changes (push) Successful in 8s
CI/CD Web + Desktop / Deploy (VPS Linux) (push) Successful in 3m19s
CI/CD Web + Desktop / Deploy Convex functions (push) Has been skipped
Quality Checks / Lint, Test and Build (push) Successful in 3m45s

- Adiciona colunas lastBootTime, uptimeFormatted, bootCount30d
- Remove colunas fleetId, fleetTeam, fleetUpdatedAt (nao utilizadas)
- Adiciona funcao extractBootInfo() para extrair dados de extended.windows.bootInfo

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
rever-tecnologia 2025-12-18 10:39:39 -03:00
parent 1a75a69d4a
commit c2802b1a4d
2 changed files with 56 additions and 7 deletions

View file

@ -58,9 +58,9 @@ export const DEVICE_INVENTORY_COLUMN_METADATA: DeviceInventoryColumnMetadata[] =
{ key: "collaboratorName", label: "Colaborador (nome)", width: 24, default: true },
{ key: "collaboratorEmail", label: "Colaborador (e-mail)", width: 26, default: true },
{ key: "remoteAccessCount", label: "Acessos remotos", width: 18, default: true },
{ key: "fleetId", label: "Fleet ID", width: 18, default: true },
{ key: "fleetTeam", label: "Equipe Fleet", width: 18, default: true },
{ key: "fleetUpdatedAt", label: "Fleet atualizado em", width: 20, default: true },
{ key: "lastBootTime", label: "Último reinício", width: 20, default: true },
{ key: "uptimeFormatted", label: "Tempo ligado", width: 16, default: true },
{ key: "bootCount30d", label: "Reinícios (30d)", width: 16, default: true },
{ key: "managementMode", label: "Modo de gestão", width: 20, default: false },
{ key: "usbPolicy", label: "Política USB", width: 18, default: true },
{ key: "usbPolicyStatus", label: "Status política USB", width: 18, default: true },

View file

@ -94,6 +94,7 @@ type MachineDerivedData = {
collaborator: ReturnType<typeof extractCollaborator>
remoteAccessCount: number
fleetInfo: ReturnType<typeof extractFleetInfo>
bootInfo: BootInfo
customFieldByKey: Record<string, DeviceCustomField>
customFieldById: Record<string, DeviceCustomField>
}
@ -145,10 +146,10 @@ const COLUMN_VALUE_RESOLVERS: Record<string, (machine: MachineInventoryRecord, d
collaboratorName: (_machine, derived) => derived.collaborator?.name ?? null,
collaboratorEmail: (_machine, derived) => derived.collaborator?.email ?? null,
remoteAccessCount: (_machine, derived) => derived.remoteAccessCount,
fleetId: (_machine, derived) => derived.fleetInfo?.id ?? null,
fleetTeam: (_machine, derived) => derived.fleetInfo?.team ?? null,
fleetUpdatedAt: (_machine, derived) =>
derived.fleetInfo?.updatedAt ? formatDateTime(derived.fleetInfo.updatedAt) : null,
lastBootTime: (_machine, derived) =>
derived.bootInfo.lastBootTime ? formatDateTime(derived.bootInfo.lastBootTime) : null,
uptimeFormatted: (_machine, derived) => derived.bootInfo.uptimeFormatted,
bootCount30d: (_machine, derived) => derived.bootInfo.bootCount30d,
managementMode: (machine) => describeManagementMode(machine.managementMode),
usbPolicy: (machine) => describeUsbPolicy(machine.usbPolicy),
usbPolicyStatus: (machine) => describeUsbPolicyStatus(machine.usbPolicyStatus),
@ -186,6 +187,7 @@ function deriveMachineData(machine: MachineInventoryRecord): MachineDerivedData
const collaborator = extractCollaborator(machine, inventory)
const remoteAccessCount = collectRemoteAccessEntries(machine).length
const fleetInfo = extractFleetInfo(inventory)
const bootInfo = extractBootInfo(inventory)
const customFieldByKey: Record<string, DeviceCustomField> = {}
const customFieldById: Record<string, DeviceCustomField> = {}
for (const field of machine.customFields ?? []) {
@ -205,6 +207,7 @@ function deriveMachineData(machine: MachineInventoryRecord): MachineDerivedData
collaborator,
remoteAccessCount,
fleetInfo,
bootInfo,
customFieldByKey,
customFieldById,
}
@ -1561,6 +1564,52 @@ function extractSystemInfo(inventory: Record<string, unknown> | null): SystemInf
}
}
type BootInfo = {
lastBootTime: number | null
uptimeSeconds: number | null
uptimeFormatted: string | null
bootCount30d: number | null
}
function extractBootInfo(inventory: Record<string, unknown> | null): BootInfo {
const result: BootInfo = {
lastBootTime: null,
uptimeSeconds: null,
uptimeFormatted: null,
bootCount30d: null,
}
if (!inventory) return result
const extended = pickRecord(inventory, ["extended", "Extended"])
const windows = pickRecord(extended, ["windows", "Windows"])
const bootInfo = pickRecord(windows, ["bootInfo", "BootInfo"])
if (!bootInfo) return result
result.lastBootTime =
parseDateish(bootInfo["lastBootTimeUTC"]) ??
parseDateish(bootInfo["LastBootTimeUTC"]) ??
parseDateish(bootInfo["lastBootTime"]) ??
parseDateish(bootInfo["LastBootUpTime"])
const uptimeRaw = pickNumber(bootInfo, ["uptimeSeconds", "UptimeSeconds", "uptime"])
result.uptimeSeconds = uptimeRaw
const uptimeFmt = pickString(bootInfo, ["uptimeFormatted", "UptimeFormatted"])
if (uptimeFmt) {
result.uptimeFormatted = uptimeFmt
} else if (uptimeRaw !== null && uptimeRaw >= 0) {
const days = Math.floor(uptimeRaw / 86400)
const hours = Math.floor((uptimeRaw % 86400) / 3600)
const minutes = Math.floor((uptimeRaw % 3600) / 60)
result.uptimeFormatted = `${days}d ${hours}h ${minutes}m`
}
result.bootCount30d = pickNumber(bootInfo, ["bootCount30d", "BootCount30d", "bootCount"])
return result
}
type SoftwareEntryInternal = SoftwareEntry
function extractSoftwareEntries(hostname: string, inventory: Record<string, unknown> | null): SoftwareEntryInternal[] {