fix: ensure PrismaClient always instantiates with an adapter option
This commit is contained in:
@@ -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 });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+10
-10
@@ -8,18 +8,18 @@ declare global {
|
|||||||
// Guard: don't attempt a real DB connection at build time when env vars are absent.
|
// 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.
|
// During `next build` inside Docker, DB_HOST is not injected — only available at runtime.
|
||||||
function createPrismaClient(connectionLimit: number): PrismaClient {
|
function createPrismaClient(connectionLimit: number): PrismaClient {
|
||||||
if (!process.env.DB_HOST) {
|
const host = process.env.DB_HOST || 'localhost';
|
||||||
// Return a shell client with no adapter — all queries will throw and be caught
|
const port = Number(process.env.DB_PORT) || 3306;
|
||||||
// by the try/catch in callers (e.g. getSettings returns DEFAULT_SETTINGS).
|
const user = process.env.DB_USERNAME || 'dummy';
|
||||||
return new PrismaClient();
|
const password = process.env.DB_PASSWORD || 'dummy';
|
||||||
}
|
const database = process.env.DB_NAME || 'dummy';
|
||||||
|
|
||||||
const adapter = new PrismaMariaDb({
|
const adapter = new PrismaMariaDb({
|
||||||
host: process.env.DB_HOST,
|
host,
|
||||||
port: Number(process.env.DB_PORT) || 3306,
|
port,
|
||||||
user: process.env.DB_USERNAME,
|
user,
|
||||||
password: process.env.DB_PASSWORD,
|
password,
|
||||||
database: process.env.DB_NAME,
|
database,
|
||||||
connectionLimit,
|
connectionLimit,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user