sistema-de-chamados/src/app/api/admin/companies/route.ts
2025-11-19 13:24:08 -03:00

79 lines
2.6 KiB
TypeScript

import { NextResponse } from "next/server"
import { randomBytes } from "crypto"
import { ZodError } from "zod"
import { Prisma } from "@/lib/prisma"
import { prisma } from "@/lib/prisma"
import { assertStaffSession } from "@/lib/auth-server"
import { isAdmin } from "@/lib/authz"
import { syncConvexCompany } from "@/server/companies-sync"
import {
buildCompanyData,
fetchCompaniesByTenant,
formatZodError,
normalizeCompany,
sanitizeCompanyInput,
} from "@/server/company-service"
export const runtime = "nodejs"
const DEFAULT_TENANT_ID = "tenant-atlas"
export async function GET() {
const session = await assertStaffSession()
if (!session) return NextResponse.json({ error: "Não autorizado" }, { status: 401 })
const tenantId = session.user.tenantId ?? DEFAULT_TENANT_ID
const companies = await fetchCompaniesByTenant(tenantId)
return NextResponse.json({ companies: companies.map(normalizeCompany) })
}
export async function POST(request: Request) {
const session = await assertStaffSession()
if (!session) return NextResponse.json({ error: "Não autorizado" }, { status: 401 })
if (!isAdmin(session.user.role)) {
return NextResponse.json({ error: "Apenas administradores podem criar empresas" }, { status: 403 })
}
try {
const rawBody = await request.json()
const tenantId = session.user.tenantId ?? DEFAULT_TENANT_ID
const form = sanitizeCompanyInput(rawBody, tenantId)
const provisioningCode = randomBytes(32).toString("hex")
const createData = buildCompanyData(form, tenantId)
const company = await prisma.company.create({
data: {
...createData,
provisioningCode,
},
})
if (company.provisioningCode) {
const synced = await syncConvexCompany({
tenantId: company.tenantId,
slug: company.slug,
name: company.name,
provisioningCode: company.provisioningCode,
})
if (!synced) {
console.warn("[admin.companies] Convex não configurado; empresa criada apenas no Prisma.")
}
}
return NextResponse.json({ company: normalizeCompany(company) })
} catch (error) {
if (error instanceof ZodError) {
return NextResponse.json({ error: "Dados inválidos", issues: formatZodError(error) }, { status: 422 })
}
if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === "P2002") {
return NextResponse.json(
{ error: "Já existe uma empresa com este slug ou código de provisionamento." },
{ status: 409 }
)
}
console.error("Failed to create company", error)
return NextResponse.json({ error: "Falha ao criar empresa" }, { status: 500 })
}
}