admin roadmap trips ops and payment ops

This commit is contained in:
2026-05-18 19:25:32 +07:00
parent e1966b69f1
commit 4bcb93e283
22 changed files with 1586 additions and 188 deletions
+40
View File
@@ -20,6 +20,46 @@ export const bookingRepo = {
});
},
/**
* Detail booking lengkap untuk admin investigation: payments (with raw
* callback), refunds, payout, trip + organizer, user. Dipakai oleh
* `/admin/bookings/[id]` untuk timeline lengkap money flow.
*/
async findByIdForAdmin(id: string) {
return prisma.booking.findUnique({
where: { id },
include: {
trip: {
select: {
id: true,
title: true,
destination: true,
location: true,
date: true,
endDate: true,
price: true,
status: true,
organizer: { select: { id: true, name: true, email: true } },
},
},
user: { select: { id: true, name: true, email: true, image: true } },
participant: true,
payments: { orderBy: { createdAt: "asc" } },
refunds: {
orderBy: { createdAt: "asc" },
include: {
reviewedBy: { select: { id: true, name: true, email: true } },
},
},
payout: {
include: {
processedBy: { select: { id: true, name: true, email: true } },
},
},
},
});
},
async create(
data: Pick<
Prisma.BookingUncheckedCreateInput,
+39
View File
@@ -191,6 +191,45 @@ export const tripRepo = {
});
},
/**
* Admin search lintas trip. Tidak filter berdasarkan status departure (admin
* boleh lihat semua: OPEN/FULL/CLOSED/COMPLETED). Include _count peserta
* aktif untuk indikator cepat.
*/
async searchForAdmin(filters: {
q?: string;
status?: "OPEN" | "FULL" | "CLOSED" | "COMPLETED";
}) {
const where: Prisma.TripWhereInput = {};
if (filters.status) {
where.status = filters.status;
}
if (filters.q) {
where.OR = [
{ title: { contains: filters.q, mode: "insensitive" } },
{ destination: { contains: filters.q, mode: "insensitive" } },
{ location: { contains: filters.q, mode: "insensitive" } },
{ organizer: { name: { contains: filters.q, mode: "insensitive" } } },
{ organizer: { email: { contains: filters.q, mode: "insensitive" } } },
];
}
return prisma.trip.findMany({
where,
include: {
organizer: { select: { id: true, name: true, email: true } },
images: { orderBy: { order: "asc" }, take: 1 },
_count: {
select: {
participants: { where: { status: { not: "CANCELLED" } } },
bookings: { where: { status: "PAID" } },
},
},
},
orderBy: { date: "desc" },
take: 100,
});
},
/** Semua trip yang dibuat user (semua status), terbaru dulu — untuk profil. */
async findByOrganizerId(organizerId: string) {
return prisma.trip.findMany({