diff --git a/src/app/api/admin/machines/rename/route.ts b/src/app/api/admin/machines/rename/route.ts new file mode 100644 index 0000000..7fea9f1 --- /dev/null +++ b/src/app/api/admin/machines/rename/route.ts @@ -0,0 +1,65 @@ +import { NextResponse } from "next/server" +import { z } from "zod" +import { ConvexHttpClient } from "convex/browser" + +import { assertAuthenticatedSession } from "@/lib/auth-server" +import { DEFAULT_TENANT_ID } from "@/lib/constants" +import { api } from "@/convex/_generated/api" + +export const runtime = "nodejs" + +const schema = z.object({ + machineId: z.string().min(1), + hostname: z.string().min(2), +}) + +export async function POST(request: Request) { + const session = await assertAuthenticatedSession() + if (!session) { + return NextResponse.json({ error: "Não autorizado" }, { status: 401 }) + } + + const convexUrl = process.env.NEXT_PUBLIC_CONVEX_URL + if (!convexUrl) { + return NextResponse.json({ error: "Convex não configurado" }, { status: 500 }) + } + + const payload = await request.json().catch(() => null) + const parsed = schema.safeParse(payload) + if (!parsed.success) { + return NextResponse.json({ error: "Payload inválido", details: parsed.error.flatten() }, { status: 400 }) + } + + const tenantId = session.user.tenantId ?? DEFAULT_TENANT_ID + + try { + // Garante usuário no Convex e obtém seu Id + const convex = new ConvexHttpClient(convexUrl) + const ensured = await convex.mutation(api.users.ensureUser, { + tenantId, + email: session.user.email, + name: session.user.name ?? session.user.email, + avatarUrl: session.user.avatarUrl ?? undefined, + role: session.user.role.toUpperCase(), + }) + const actorId = ensured?._id + if (!actorId) { + return NextResponse.json({ error: "Falha ao obter ID do usuário no Convex" }, { status: 500 }) + } + + // Chamada por string reference (evita depender do tipo gerado imediatamente) + const client = convex as unknown as { mutation: (name: string, args: unknown) => Promise } + await client.mutation("machines:rename", { + machineId: parsed.data.machineId, + actorId, + tenantId, + hostname: parsed.data.hostname, + }) + + return NextResponse.json({ ok: true }) + } catch (error) { + console.error("[machines.rename] Falha ao renomear", error) + return NextResponse.json({ error: "Falha ao renomear máquina" }, { status: 500 }) + } +} + diff --git a/src/components/admin/machines/admin-machines-overview.tsx b/src/components/admin/machines/admin-machines-overview.tsx index 984e369..7a9a7a6 100644 --- a/src/components/admin/machines/admin-machines-overview.tsx +++ b/src/components/admin/machines/admin-machines-overview.tsx @@ -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>)[0] ?? null - : (windowsExt?.cpu as Record | 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>)[0] ?? null + ? ((windowsExt?.videoControllers as Array)[0] as WinVideoController | undefined) ?? null : null const winDiskStats = Array.isArray(windowsExt?.disks) ? { - count: (windowsExt?.disks as Array>).length, + count: (windowsExt?.disks as Array).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(machine?.hostname ?? "") @@ -539,14 +550,19 @@ export function MachineDetails({ machine }: MachineDetailsProps) {