import { prisma } from "@/lib/prisma"; import type { ParticipantStatus } from "@/app/generated/prisma/client"; export const participantRepo = { async findByTripAndUser(tripId: string, userId: string) { return prisma.tripParticipant.findUnique({ where: { tripId_userId: { tripId, userId } }, }); }, async findById(id: string) { return prisma.tripParticipant.findUnique({ where: { id } }); }, async create(tripId: string, userId: string) { return prisma.tripParticipant.create({ data: { tripId, userId, status: "PENDING" }, }); }, async setStatus(id: string, status: ParticipantStatus) { return prisma.tripParticipant.update({ where: { id }, data: { status }, }); }, async setStatusAndClearPayment(id: string, status: ParticipantStatus) { return prisma.tripParticipant.update({ where: { id }, data: { status, markedPaidAt: null, paymentConfirmedAt: null, }, }); }, async countByTrip(tripId: string) { return prisma.tripParticipant.count({ where: { tripId, status: { not: "CANCELLED" } }, }); }, async cancel(tripId: string, userId: string) { return prisma.tripParticipant.update({ where: { tripId_userId: { tripId, userId } }, data: { status: "CANCELLED", markedPaidAt: null, paymentConfirmedAt: null, }, }); }, async reactivate(tripId: string, userId: string) { return prisma.tripParticipant.update({ where: { tripId_userId: { tripId, userId } }, data: { status: "PENDING", markedPaidAt: null, paymentConfirmedAt: null, }, }); }, async markPaidByUser(tripId: string, userId: string) { return prisma.tripParticipant.update({ where: { tripId_userId: { tripId, userId } }, data: { markedPaidAt: new Date() }, }); }, /** * Satu baris update atomik — aman dari double-submit / race saat tandai bayar. */ async tryMarkPaidByUser(tripId: string, userId: string) { return prisma.tripParticipant.updateMany({ where: { tripId, userId, status: { not: "CANCELLED" }, markedPaidAt: null, paymentConfirmedAt: null, }, data: { markedPaidAt: new Date() }, }); }, async confirmPaymentByOrganizer(participantId: string) { return prisma.tripParticipant.update({ where: { id: participantId }, data: { paymentConfirmedAt: new Date() }, }); }, /** Konfirmasi pembayaran hanya jika masih eligible — idempotent terhadap double klik. */ async tryConfirmPaymentByOrganizer(participantId: string) { return prisma.tripParticipant.updateMany({ where: { id: participantId, markedPaidAt: { not: null }, paymentConfirmedAt: null, status: { not: "CANCELLED" }, }, data: { paymentConfirmedAt: new Date() }, }); }, /** Partisipasi user beserta trip (untuk profil & riwayat). */ async findWithTripForProfile(userId: string) { return prisma.tripParticipant.findMany({ where: { userId }, include: { trip: { include: { organizer: { select: { id: true, name: true } }, images: { orderBy: { order: "asc" }, take: 1 }, reviews: { where: { userId }, select: { id: true, rating: true }, }, }, }, }, orderBy: { createdAt: "desc" }, }); }, };