add payment, trust badge, handle race condition, fix booking schema
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import type { ParticipantStatus } from "@/app/generated/prisma/client";
|
||||
|
||||
export const participantRepo = {
|
||||
async findByTripAndUser(tripId: string, userId: string) {
|
||||
@@ -7,9 +8,31 @@ export const participantRepo = {
|
||||
});
|
||||
},
|
||||
|
||||
async findById(id: string) {
|
||||
return prisma.tripParticipant.findUnique({ where: { id } });
|
||||
},
|
||||
|
||||
async create(tripId: string, userId: string) {
|
||||
return prisma.tripParticipant.create({
|
||||
data: { tripId, userId, status: "CONFIRMED" },
|
||||
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,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -22,14 +45,65 @@ export const participantRepo = {
|
||||
async cancel(tripId: string, userId: string) {
|
||||
return prisma.tripParticipant.update({
|
||||
where: { tripId_userId: { tripId, userId } },
|
||||
data: { status: "CANCELLED" },
|
||||
data: {
|
||||
status: "CANCELLED",
|
||||
markedPaidAt: null,
|
||||
paymentConfirmedAt: null,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
async reactivate(tripId: string, userId: string) {
|
||||
return prisma.tripParticipant.update({
|
||||
where: { tripId_userId: { tripId, userId } },
|
||||
data: { status: "CONFIRMED" },
|
||||
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() },
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -92,7 +92,15 @@ export const tripRepo = {
|
||||
return prisma.trip.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
organizer: { select: { id: true, name: true, email: true, image: true } },
|
||||
organizer: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
email: true,
|
||||
image: true,
|
||||
isVerified: true,
|
||||
},
|
||||
},
|
||||
images: { orderBy: { order: "asc" } },
|
||||
participants: {
|
||||
include: { user: { select: { id: true, name: true, image: true } } },
|
||||
|
||||
Reference in New Issue
Block a user