feat: improve machines inventory exports

This commit is contained in:
codex-bot 2025-10-30 16:09:06 -03:00
parent d92c817e7b
commit 38b46f32ce
5 changed files with 858 additions and 222 deletions

View file

@ -0,0 +1,69 @@
import { NextResponse } from "next/server"
import { ConvexHttpClient } from "convex/browser"
import { api } from "@/convex/_generated/api"
import type { Id } from "@/convex/_generated/dataModel"
import { env } from "@/lib/env"
import { assertAuthenticatedSession } from "@/lib/auth-server"
import { DEFAULT_TENANT_ID } from "@/lib/constants"
import { buildMachinesInventoryWorkbook, type MachineInventoryRecord } from "@/server/machines/inventory-export"
export const runtime = "nodejs"
type RouteContext = {
params: Promise<{
id: string
}>
}
function sanitizeFilename(hostname: string, fallback: string): string {
const safe = hostname.replace(/[^a-z0-9_-]/gi, "-").replace(/-{2,}/g, "-").toLowerCase()
return safe || fallback
}
export async function GET(_request: Request, context: RouteContext) {
const session = await assertAuthenticatedSession()
if (!session) return NextResponse.json({ error: "Não autorizado" }, { status: 401 })
const convexUrl = env.NEXT_PUBLIC_CONVEX_URL
if (!convexUrl) {
return NextResponse.json({ error: "Convex não configurado" }, { status: 500 })
}
const { id } = await context.params
const machineId = id as Id<"machines">
const client = new ConvexHttpClient(convexUrl)
const tenantId = session.user.tenantId ?? DEFAULT_TENANT_ID
try {
const machine = (await client.query(api.machines.getById, {
id: machineId,
includeMetadata: true,
})) as MachineInventoryRecord | null
if (!machine || machine.tenantId !== tenantId) {
return NextResponse.json({ error: "Máquina não encontrada" }, { status: 404 })
}
const workbook = buildMachinesInventoryWorkbook([machine], {
tenantId,
generatedBy: session.user.name ?? session.user.email,
companyFilterLabel: machine.companyName ?? machine.companySlug ?? null,
generatedAt: new Date(),
})
const hostnameSafe = sanitizeFilename(machine.hostname, "machine")
const body = new Uint8Array(workbook)
return new NextResponse(body, {
headers: {
"Content-Type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"Content-Disposition": `attachment; filename="machine-inventory-${hostnameSafe}.xlsx"`,
"Cache-Control": "no-store",
},
})
} catch (error) {
console.error("Failed to export machine inventory", error)
return NextResponse.json({ error: "Falha ao gerar planilha da máquina" }, { status: 500 })
}
}