import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library"; import { NextResponse } from "next/server"; import { serializeBank } from "@/features/banks/lib/serialize-bank"; import { bankInputSchema } from "@/features/banks/schemas/bank.schema"; import { createAuditTrailSafe } from "@/lib/audit-trail"; import { buildAuditChangeMetadata } from "@/lib/audit-trail-diff"; import { prisma } from "@/lib/prisma"; import { requireApiAccess } from "@/lib/authorization"; type RouteContext = { params: Promise<{ id: string }> }; function parseId(rawId: string) { try { return BigInt(rawId); } catch { return null; } } async function countBankUsage(bankName: string) { const customerCount = await prisma.buyer.count({ where: { bankName } }); return customerCount; } export async function GET(request: Request, context: RouteContext) { const auth = requireApiAccess(request); if (!auth.ok) return auth.response; const parsedId = parseId((await context.params).id); if (parsedId === null) return NextResponse.json({ message: "Invalid id" }, { status: 400 }); const bank = await prisma.bank.findUnique({ where: { id: parsedId } }); if (!bank) return NextResponse.json({ message: "Bank not found" }, { status: 404 }); return NextResponse.json({ data: serializeBank(bank) }); } export async function PUT(request: Request, context: RouteContext) { const auth = requireApiAccess(request); if (!auth.ok) return auth.response; const parsedId = parseId((await context.params).id); if (parsedId === null) return NextResponse.json({ message: "Invalid id" }, { status: 400 }); const parsed = bankInputSchema.safeParse(await request.json()); if (!parsed.success) { return NextResponse.json( { message: "Validasi gagal", errors: parsed.error.flatten().fieldErrors }, { status: 400 } ); } try { const existing = await prisma.bank.findUnique({ where: { id: parsedId } }); if (!existing) return NextResponse.json({ message: "Bank not found" }, { status: 404 }); const usageCount = await countBankUsage(existing.name); if (usageCount > 0 && existing.name !== parsed.data.name) { return NextResponse.json( { message: "Nama bank sedang dipakai di buyer dan tidak bisa diubah." }, { status: 409 } ); } const bank = await prisma.bank.update({ where: { id: parsedId }, data: { code: parsed.data.code, name: parsed.data.name, address: parsed.data.address || null, status: parsed.data.status } }); await createAuditTrailSafe({ userId: auth.user.id, action: "BANK_UPDATED", entityType: "BANK", entityId: bank.id, method: request.method, pathname: new URL(request.url).pathname, statusCode: 200, summary: `Bank ${bank.code} diubah`, metadata: buildAuditChangeMetadata( { code: existing.code, name: existing.name, address: existing.address, status: existing.status }, { code: bank.code, name: bank.name, address: bank.address, status: bank.status } ) }); return NextResponse.json({ data: serializeBank(bank) }); } catch (error) { if (error instanceof PrismaClientKnownRequestError && error.code === "P2025") { return NextResponse.json({ message: "Bank not found" }, { status: 404 }); } if (error instanceof PrismaClientKnownRequestError && error.code === "P2002") { return NextResponse.json( { message: "Validasi gagal", errors: { code: ["Kode atau nama bank sudah dipakai"] } }, { status: 409 } ); } throw error; } } export async function DELETE(request: Request, context: RouteContext) { const auth = requireApiAccess(request); if (!auth.ok) return auth.response; const parsedId = parseId((await context.params).id); if (parsedId === null) return NextResponse.json({ message: "Invalid id" }, { status: 400 }); try { const existing = await prisma.bank.findUnique({ where: { id: parsedId } }); if (!existing) return NextResponse.json({ message: "Bank not found" }, { status: 404 }); const usageCount = await countBankUsage(existing.name); if (usageCount > 0) { return NextResponse.json( { message: "Bank sedang dipakai di buyer dan tidak bisa dihapus." }, { status: 409 } ); } await prisma.bank.delete({ where: { id: parsedId } }); await createAuditTrailSafe({ userId: auth.user.id, action: "BANK_DELETED", entityType: "BANK", entityId: parsedId, method: request.method, pathname: new URL(request.url).pathname, statusCode: 200, summary: `Bank ${existing.code} dihapus` }); return NextResponse.json({ success: true }); } catch (error) { if (error instanceof PrismaClientKnownRequestError && error.code === "P2025") { return NextResponse.json({ message: "Bank not found" }, { status: 404 }); } throw error; } }