feat: allow company deletion by detaching dependents
This commit is contained in:
parent
2980885bf8
commit
7951bc25a3
3 changed files with 32 additions and 21 deletions
|
|
@ -23,6 +23,7 @@ Resultado: front/back sobem com o novo código sem editar o stack a cada release
|
|||
- Mount fixo: `/home/renan/apps/sistema.current:/app` (não interpolar APP_DIR).
|
||||
- Comando inline (sem script), com migrations na subida:
|
||||
- `command: ["bash","-lc","corepack enable && corepack prepare pnpm@9 --activate && pnpm exec prisma migrate deploy && pnpm start -p 3000"]`
|
||||
- **Se você optar por usar `/app/scripts/start-web.sh`** (como no workflow atual), ele já garante `pnpm@9` via Corepack/NPM antes de rodar Prisma/Next. Certifique-se de copiar esse arquivo para o build publicado; sem ele, a task cai com `pnpm: command not found`.
|
||||
- Env obrigatórias (URLs válidas):
|
||||
- `DATABASE_URL=file:/app/data/db.sqlite`
|
||||
- `NEXT_PUBLIC_CONVEX_URL=http://sistema_convex_backend:3210`
|
||||
|
|
@ -121,4 +122,3 @@ docker service scale sistema_web=1
|
|||
|
||||
- Como o stack monta `/home/renan/apps/sistema.current`, um novo release exige apenas atualizar o symlink e forçar a task. O `stack.yml` só precisa ser redeployado quando você altera labels/envs/serviços.
|
||||
- Se a UI parecer não mudar, valide o mount/args via inspect, confira logs da task atual e force hard‑reload no navegador.
|
||||
|
||||
|
|
|
|||
|
|
@ -77,23 +77,20 @@ export async function DELETE(_: Request, { params }: { params: Promise<{ id: str
|
|||
}
|
||||
|
||||
try {
|
||||
// Pré‑checagem para evitar 500 por FK: conta vínculos antes
|
||||
const [usersCount, ticketsCount] = await Promise.all([
|
||||
prisma.user.count({ where: { companyId: company.id } }),
|
||||
prisma.ticket.count({ where: { companyId: company.id } }),
|
||||
])
|
||||
if (usersCount > 0 || ticketsCount > 0) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: "Não é possível remover esta empresa pois existem registros vinculados.",
|
||||
details: { users: usersCount, tickets: ticketsCount },
|
||||
},
|
||||
{ status: 409 }
|
||||
)
|
||||
}
|
||||
const result = await prisma.$transaction(async (tx) => {
|
||||
const users = await tx.user.updateMany({
|
||||
where: { companyId: company.id, tenantId: company.tenantId },
|
||||
data: { companyId: null },
|
||||
})
|
||||
const tickets = await tx.ticket.updateMany({
|
||||
where: { companyId: company.id, tenantId: company.tenantId },
|
||||
data: { companyId: null },
|
||||
})
|
||||
await tx.company.delete({ where: { id: company.id } })
|
||||
return { detachedUsers: users.count, detachedTickets: tickets.count }
|
||||
})
|
||||
|
||||
await prisma.company.delete({ where: { id: company.id } })
|
||||
return NextResponse.json({ ok: true })
|
||||
return NextResponse.json({ ok: true, ...result })
|
||||
} catch (error) {
|
||||
if (error instanceof PrismaClientKnownRequestError && error.code === "P2003") {
|
||||
return NextResponse.json(
|
||||
|
|
|
|||
|
|
@ -184,11 +184,25 @@ export function AdminCompaniesManager({ initialCompanies }: { initialCompanies:
|
|||
method: "DELETE",
|
||||
credentials: "include",
|
||||
})
|
||||
if (!response.ok) {
|
||||
const data = await response.json().catch(() => ({}))
|
||||
throw new Error(data.error ?? "Falha ao excluir empresa")
|
||||
const data = (await response.json().catch(() => ({}))) as {
|
||||
error?: string
|
||||
detachedUsers?: number
|
||||
detachedTickets?: number
|
||||
}
|
||||
toast.success("Empresa removida")
|
||||
if (!response.ok) {
|
||||
throw new Error(data?.error ?? "Falha ao excluir empresa")
|
||||
}
|
||||
const detachedUsers = data?.detachedUsers ?? 0
|
||||
const detachedTickets = data?.detachedTickets ?? 0
|
||||
const details: string[] = []
|
||||
if (detachedUsers > 0) {
|
||||
details.push(`${detachedUsers} usuário${detachedUsers > 1 ? "s" : ""} desvinculado${detachedUsers > 1 ? "s" : ""}`)
|
||||
}
|
||||
if (detachedTickets > 0) {
|
||||
details.push(`${detachedTickets} ticket${detachedTickets > 1 ? "s" : ""} atualizado${detachedTickets > 1 ? "s" : ""}`)
|
||||
}
|
||||
const successMessage = details.length > 0 ? `Empresa removida (${details.join(", ")})` : "Empresa removida"
|
||||
toast.success(successMessage)
|
||||
if (editingId === deleteId) {
|
||||
resetForm()
|
||||
setEditingId(null)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue