refactor(admin/machines): remove all any casts; add typed helpers for metrics/Windows WMI; implement server route for rename to avoid client any; keep strict types

This commit is contained in:
Esdras Renan 2025-10-10 10:30:57 -03:00
parent 129407dbce
commit b5fbf69cc1
2 changed files with 101 additions and 13 deletions

View file

@ -2,7 +2,6 @@
import { useEffect, useMemo, useState } from "react"
import { useQuery } from "convex/react"
import { useMutation } from "convex/react"
import { format, formatDistanceToNowStrict } from "date-fns"
import { ptBR } from "date-fns/locale"
import { toast } from "sonner"
@ -368,18 +367,31 @@ export function MachineDetails({ machine }: MachineDetailsProps) {
const windowsExt = extended?.windows ?? null
const macosExt = extended?.macos ?? null
const winCpu = Array.isArray(windowsExt?.cpu)
? (windowsExt?.cpu as Array<Record<string, unknown>>)[0] ?? null
: (windowsExt?.cpu as Record<string, unknown> | null)
type WinCpuInfo = {
Name?: string
Manufacturer?: string
SocketDesignation?: string
NumberOfCores?: number
NumberOfLogicalProcessors?: number
L2CacheSize?: number
L3CacheSize?: number
MaxClockSpeed?: number
}
const winCpu = ((): WinCpuInfo | null => {
if (!windowsExt?.cpu) return null
if (Array.isArray(windowsExt.cpu)) return (windowsExt.cpu[0] as unknown as WinCpuInfo) ?? null
return windowsExt.cpu as unknown as WinCpuInfo
})()
const winMemTotal = Array.isArray(windowsExt?.memoryModules)
? (windowsExt?.memoryModules as Array<{ Capacity?: number }>).reduce((acc, m) => acc + Number(m?.Capacity ?? 0), 0)
: 0
type WinVideoController = { Name?: string; AdapterRAM?: number; DriverVersion?: string; PNPDeviceID?: string }
const winGpu = Array.isArray(windowsExt?.videoControllers)
? (windowsExt?.videoControllers as Array<Record<string, unknown>>)[0] ?? null
? ((windowsExt?.videoControllers as Array<unknown>)[0] as WinVideoController | undefined) ?? null
: null
const winDiskStats = Array.isArray(windowsExt?.disks)
? {
count: (windowsExt?.disks as Array<Record<string, unknown>>).length,
count: (windowsExt?.disks as Array<unknown>).length,
total: (windowsExt?.disks as Array<{ Size?: number }>).reduce((acc, d) => acc + Number(d?.Size ?? 0), 0),
}
: { count: 0, total: 0 }
@ -398,7 +410,6 @@ export function MachineDetails({ machine }: MachineDetailsProps) {
}
}
const renameMachine = useMutation(api.machines.rename as any)
const [renaming, setRenaming] = useState(false)
const [newName, setNewName] = useState<string>(machine?.hostname ?? "")
@ -539,14 +550,19 @@ export function MachineDetails({ machine }: MachineDetailsProps) {
<Button variant="outline" onClick={() => setRenaming(false)}>Cancelar</Button>
<Button
onClick={async () => {
if (!machine || !convexUserId) return
if (!machine) return
const name = (newName ?? "").trim()
if (name.length < 2) {
toast.error("Informe um nome válido")
return
}
try {
await renameMachine({ machineId: machine.id as Id<"machines">, actorId: convexUserId as Id<"users">, hostname: name })
const res = await fetch("/api/admin/machines/rename", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ machineId: machine.id, hostname: name }),
})
if (!res.ok) throw new Error(`HTTP ${res.status}`)
toast.success("Máquina renomeada")
setRenaming(false)
} catch (err) {
@ -1124,10 +1140,17 @@ function MachinesGrid({ machines }: { machines: MachinesQueryItem[] }) {
function MachineCard({ machine }: { machine: MachinesQueryItem }) {
const { className } = getStatusVariant(machine.status)
const lastHeartbeat = machine.lastHeartbeatAt ? new Date(machine.lastHeartbeatAt) : null
const memUsed = Number((machine.metrics as any)?.memoryUsedBytes ?? NaN)
const memTotal = Number((machine.metrics as any)?.memoryTotalBytes ?? NaN)
const memPct = Number((machine.metrics as any)?.memoryUsedPercent ?? (memUsed && memTotal ? (memUsed / memTotal) * 100 : NaN))
const cpuPct = Number((machine.metrics as any)?.cpuUsagePercent ?? NaN)
type AgentMetrics = {
memoryUsedBytes?: number
memoryTotalBytes?: number
memoryUsedPercent?: number
cpuUsagePercent?: number
}
const mm = (machine.metrics ?? null) as unknown as AgentMetrics | null
const memUsed = mm?.memoryUsedBytes ?? NaN
const memTotal = mm?.memoryTotalBytes ?? NaN
const memPct = mm?.memoryUsedPercent ?? (Number.isFinite(memUsed) && Number.isFinite(memTotal) ? (Number(memUsed) / Number(memTotal)) * 100 : NaN)
const cpuPct = mm?.cpuUsagePercent ?? NaN
return (
<Link href={`/admin/machines/${machine.id}`} className="group">