feat: improve machines inventory exports
This commit is contained in:
parent
d92c817e7b
commit
38b46f32ce
5 changed files with 858 additions and 222 deletions
69
src/app/api/admin/machines/[id]/inventory.xlsx/route.ts
Normal file
69
src/app/api/admin/machines/[id]/inventory.xlsx/route.ts
Normal 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 })
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue