fix(machines): derive machine id from router params

This commit is contained in:
Esdras Renan 2025-10-22 22:08:53 -03:00
parent 1017d563b5
commit 2a359b7a65

View file

@ -2,7 +2,7 @@
import { useEffect, useMemo, useState } from "react" import { useEffect, useMemo, useState } from "react"
import { useQuery } from "convex/react" import { useQuery } from "convex/react"
import { useRouter } from "next/navigation" import { useParams, useRouter } from "next/navigation"
import { api } from "@/convex/_generated/api" import { api } from "@/convex/_generated/api"
import { import {
MachineDetails, MachineDetails,
@ -15,10 +15,14 @@ import { Button } from "@/components/ui/button"
import type { Id } from "@/convex/_generated/dataModel" import type { Id } from "@/convex/_generated/dataModel"
import { ConvexHttpClient } from "convex/browser" import { ConvexHttpClient } from "convex/browser"
export function AdminMachineDetailsClient({ tenantId: _tenantId, machineId }: { tenantId: string; machineId: string }) { export function AdminMachineDetailsClient({ tenantId: _tenantId, machineId }: { tenantId: string; machineId?: string }) {
const router = useRouter() const router = useRouter()
const queryArgs = machineId const params = useParams<{ id?: string | string[] }>()
? ({ id: machineId as Id<"machines">, includeMetadata: true } as const) const routeMachineId = Array.isArray(params?.id) ? params?.id[0] : params?.id
const effectiveMachineId = machineId ?? routeMachineId ?? ""
const queryArgs = effectiveMachineId
? ({ id: effectiveMachineId as Id<"machines">, includeMetadata: true } as const)
: "skip" : "skip"
const single = useQuery(api.machines.getById, queryArgs) const single = useQuery(api.machines.getById, queryArgs)
@ -27,7 +31,7 @@ export function AdminMachineDetailsClient({ tenantId: _tenantId, machineId }: {
const [fallback, setFallback] = useState<Record<string, unknown> | null | undefined>(undefined) const [fallback, setFallback] = useState<Record<string, unknown> | null | undefined>(undefined)
const [loadError, setLoadError] = useState<string | null>(null) const [loadError, setLoadError] = useState<string | null>(null)
const [retryTick, setRetryTick] = useState(0) const [retryTick, setRetryTick] = useState(0)
const shouldLoad = fallback === undefined && Boolean(machineId) const shouldLoad = fallback === undefined && Boolean(effectiveMachineId)
const [isHydrated, setIsHydrated] = useState(false) const [isHydrated, setIsHydrated] = useState(false)
useEffect(() => { useEffect(() => {
@ -36,53 +40,53 @@ export function AdminMachineDetailsClient({ tenantId: _tenantId, machineId }: {
useEffect(() => { useEffect(() => {
if (!shouldLoad) { if (!shouldLoad) {
console.debug("[admin-machine-details] Skipping probe", { shouldLoad, machineId, fallback, single }) console.debug("[admin-machine-details] Skipping probe", { shouldLoad, machineId: effectiveMachineId, fallback, single })
} else { } else {
console.debug("[admin-machine-details] Starting probe", { machineId, retryTick }) console.debug("[admin-machine-details] Starting probe", { machineId: effectiveMachineId, retryTick })
} }
}, [shouldLoad, machineId, fallback, single, retryTick]) }, [shouldLoad, effectiveMachineId, fallback, single, retryTick])
useEffect(() => { useEffect(() => {
if (!shouldLoad) return if (!shouldLoad) return
let cancelled = false let cancelled = false
const probe = async () => { const probe = async () => {
console.debug("[admin-machine-details] Probe invocation", { machineId, retryTick }) console.debug("[admin-machine-details] Probe invocation", { machineId: effectiveMachineId, retryTick })
try { try {
const convexUrl = process.env.NEXT_PUBLIC_CONVEX_URL const convexUrl = process.env.NEXT_PUBLIC_CONVEX_URL
if (convexUrl) { if (convexUrl) {
try { try {
console.debug("[admin-machine-details] Convex probe begin", { machineId, convexUrl }) console.debug("[admin-machine-details] Convex probe begin", { machineId: effectiveMachineId, convexUrl })
const http = new ConvexHttpClient(convexUrl) const http = new ConvexHttpClient(convexUrl)
const data = (await http.query(api.machines.getById, { const data = (await http.query(api.machines.getById, {
id: machineId as Id<"machines">, id: effectiveMachineId as Id<"machines">,
includeMetadata: true, includeMetadata: true,
})) as Record<string, unknown> | null })) as Record<string, unknown> | null
if (cancelled) return if (cancelled) return
if (data) { if (data) {
console.info("[admin-machine-details] Convex query succeeded", { machineId }) console.info("[admin-machine-details] Convex query succeeded", { machineId: effectiveMachineId })
setFallback(data) setFallback(data)
setLoadError(null) setLoadError(null)
return return
} }
if (data === null) { if (data === null) {
console.info("[admin-machine-details] Convex query returned null", { machineId }) console.info("[admin-machine-details] Convex query returned null", { machineId: effectiveMachineId })
setFallback(null) setFallback(null)
setLoadError(null) setLoadError(null)
return return
} }
} catch (err) { } catch (err) {
if (cancelled) return if (cancelled) return
console.warn("[admin-machine-details] Convex probe failed, falling back to API route", { machineId, err }) console.warn("[admin-machine-details] Convex probe failed, falling back to API route", { machineId: effectiveMachineId, err })
} }
} }
try { try {
console.debug("[admin-machine-details] HTTP fallback begin", { machineId }) console.debug("[admin-machine-details] HTTP fallback begin", { machineId: effectiveMachineId })
const res = await fetch(`/api/admin/machines/${machineId}/details`, { const res = await fetch(`/api/admin/machines/${effectiveMachineId}/details`, {
credentials: "include", credentials: "include",
cache: "no-store", cache: "no-store",
}) })
@ -97,7 +101,7 @@ export function AdminMachineDetailsClient({ tenantId: _tenantId, machineId }: {
} }
if (res.ok) { if (res.ok) {
console.info("[admin-machine-details] HTTP fallback succeeded", { machineId }) console.info("[admin-machine-details] HTTP fallback succeeded", { machineId: effectiveMachineId })
setFallback(payload ?? null) setFallback(payload ?? null)
setLoadError(null) setLoadError(null)
return return
@ -109,11 +113,11 @@ export function AdminMachineDetailsClient({ tenantId: _tenantId, machineId }: {
: `Falha ao carregar (HTTP ${res.status})` : `Falha ao carregar (HTTP ${res.status})`
if (res.status === 404) { if (res.status === 404) {
console.info("[admin-machine-details] HTTP fallback returned 404", { machineId }) console.info("[admin-machine-details] HTTP fallback returned 404", { machineId: effectiveMachineId })
setFallback(null) setFallback(null)
setLoadError(null) setLoadError(null)
} else { } else {
console.error("[admin-machine-details] HTTP fallback failed", { machineId, status: res.status, message }) console.error("[admin-machine-details] HTTP fallback failed", { machineId: effectiveMachineId, status: res.status, message })
setLoadError(message) setLoadError(message)
} }
} catch (err) { } catch (err) {
@ -138,10 +142,10 @@ export function AdminMachineDetailsClient({ tenantId: _tenantId, machineId }: {
}) })
return () => { return () => {
console.debug("[admin-machine-details] Cancelling probe", { machineId }) console.debug("[admin-machine-details] Cancelling probe", { machineId: effectiveMachineId })
cancelled = true cancelled = true
} }
}, [shouldLoad, machineId, retryTick]) }, [shouldLoad, effectiveMachineId, retryTick])
// Timeout de proteção: se depois de X segundos ainda estiver carregando e sem fallback, mostra erro claro // Timeout de proteção: se depois de X segundos ainda estiver carregando e sem fallback, mostra erro claro
useEffect(() => { useEffect(() => {
@ -152,7 +156,7 @@ export function AdminMachineDetailsClient({ tenantId: _tenantId, machineId }: {
) )
}, 10_000) }, 10_000)
return () => clearTimeout(timeout) return () => clearTimeout(timeout)
}, [shouldLoad, machineId, retryTick]) }, [shouldLoad, effectiveMachineId, retryTick])
const machine: MachinesQueryItem | null = useMemo(() => { const machine: MachinesQueryItem | null = useMemo(() => {
const source = single ?? (fallback === undefined ? undefined : fallback) const source = single ?? (fallback === undefined ? undefined : fallback)