From e8d3cd804f7607c9836ad7847b08eb7b2a895f8c Mon Sep 17 00:00:00 2001 From: Rio Date: Thu, 18 Jun 2026 14:35:03 +0700 Subject: [PATCH] fix: ensure PrismaClient always instantiates with an adapter option --- src/app/api/webhook/pakasir/route.ts | 57 ---------------------------- src/lib/db.ts | 20 +++++----- 2 files changed, 10 insertions(+), 67 deletions(-) diff --git a/src/app/api/webhook/pakasir/route.ts b/src/app/api/webhook/pakasir/route.ts index 8354ee9..e69de29 100644 --- a/src/app/api/webhook/pakasir/route.ts +++ b/src/app/api/webhook/pakasir/route.ts @@ -1,57 +0,0 @@ -import { NextResponse } from 'next/server'; -import { prisma } from '@/lib/db'; -import { getSettings } from '@/lib/settings'; -import { sendTicketEmail } from '@/lib/email'; - -export async function POST(request: Request) { - try { - const body = await request.json(); - const { amount, order_id, project, status, payment_method, completed_at } = body; - - // Validate request body - if (!order_id || !amount || !status) { - return NextResponse.json({ error: 'Payload tidak valid' }, { status: 400 }); - } - - // Verify project matches configured slug - const settings = await getSettings(); - if (project !== settings.pakasirSlug) { - return NextResponse.json({ error: 'Slug proyek tidak cocok' }, { status: 400 }); - } - - // Find booking - const booking = await prisma.booking.findUnique({ - where: { bookingCode: order_id }, - }); - - if (!booking) { - return NextResponse.json({ error: 'Pemesanan tidak ditemukan' }, { status: 404 }); - } - - // Verify amount matches - const expectedAmount = Math.round(Number(booking.totalPrice)); - if (expectedAmount !== Math.round(Number(amount))) { - return NextResponse.json({ error: 'Nominal pembayaran tidak sesuai' }, { status: 400 }); - } - - if (status === 'completed') { - await prisma.booking.update({ - where: { bookingCode: order_id }, - data: { - status: 'PAID', - paymentMethod: 'QRIS', - paymentTime: completed_at ? new Date(completed_at) : new Date(), - }, - }); - console.log(`Webhook: Booking ${order_id} lunas via Pakasir.`); - - // Send receipt email - await sendTicketEmail(booking.id); - } - - return NextResponse.json({ success: true }); - } catch (error) { - console.error('Webhook error:', error); - return NextResponse.json({ error: 'Internal server error' }, { status: 500 }); - } -} diff --git a/src/lib/db.ts b/src/lib/db.ts index e76c47e..9bdde18 100644 --- a/src/lib/db.ts +++ b/src/lib/db.ts @@ -8,18 +8,18 @@ declare global { // Guard: don't attempt a real DB connection at build time when env vars are absent. // During `next build` inside Docker, DB_HOST is not injected — only available at runtime. function createPrismaClient(connectionLimit: number): PrismaClient { - if (!process.env.DB_HOST) { - // Return a shell client with no adapter — all queries will throw and be caught - // by the try/catch in callers (e.g. getSettings returns DEFAULT_SETTINGS). - return new PrismaClient(); - } + const host = process.env.DB_HOST || 'localhost'; + const port = Number(process.env.DB_PORT) || 3306; + const user = process.env.DB_USERNAME || 'dummy'; + const password = process.env.DB_PASSWORD || 'dummy'; + const database = process.env.DB_NAME || 'dummy'; const adapter = new PrismaMariaDb({ - host: process.env.DB_HOST, - port: Number(process.env.DB_PORT) || 3306, - user: process.env.DB_USERNAME, - password: process.env.DB_PASSWORD, - database: process.env.DB_NAME, + host, + port, + user, + password, + database, connectionLimit, });