create public layout and admin and fix escrow and refund

This commit is contained in:
arifal
2026-05-12 00:05:30 +07:00
parent a07942c4b4
commit 958514d575
48 changed files with 1928 additions and 18 deletions
+75
View File
@@ -34,6 +34,11 @@ model User {
reviewedRefunds Refund[] @relation("RefundReviewer")
/// Payout yang diterima user ini sebagai organizer (escrow trip selesai).
payouts Payout[] @relation("PayoutOrganizer")
/// Payout yang ditandai admin sebagai PAID/CANCELLED oleh user ini.
processedPayouts Payout[] @relation("PayoutProcessor")
profile UserProfile?
}
@@ -161,6 +166,7 @@ model Trip {
images TripImage[]
reviews TripReview[]
bookings Booking[]
payouts Payout[]
@@index([category, status, date])
@@index([vibe, status, date])
@@ -261,6 +267,7 @@ model Booking {
payments Payment[]
refunds Refund[]
payout Payout?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -436,3 +443,71 @@ enum RefundReporter {
PARTICIPANT
ORGANIZER
}
/// Escrow payout ke organizer. Uang peserta ditahan sejak Booking → PAID sampai
/// trip selesai + buffer beberapa hari, baru di-release untuk ditransfer admin.
///
/// State machine:
/// HELD → diciptakan saat booking PAID, heldUntil = endDate/date + 3 hari
/// RELEASED → cron flip setelah heldUntil lewat + trip COMPLETED
/// PAID → admin sudah transfer manual ke rekening organizer
/// CANCELLED → booking di-refund / trip dibatalkan; payout tidak jadi
///
/// Audit: 1-1 dengan Booking (unique). Refund SUCCEEDED mengurangi amount
/// (partial) atau membatalkan payout (full).
model Payout {
id String @id @default(cuid())
bookingId String @unique
booking Booking @relation(fields: [bookingId], references: [id], onDelete: Restrict)
tripId String
trip Trip @relation(fields: [tripId], references: [id])
organizerId String
organizer User @relation("PayoutOrganizer", fields: [organizerId], references: [id])
/// Nominal yg organizer terima (IDR integer). Default = booking.amount saat
/// payout dibuat. Refund SUCCEEDED memotong nilai ini supaya total payout +
/// total refund = uang yang dibayar peserta.
amount Int
currency String @default("IDR")
status PayoutStatus @default(HELD)
/// Tanggal payout boleh di-release ke organizer
/// (= trip.endDate ?? trip.date + buffer days).
heldUntil DateTime
releasedAt DateTime?
paidAt DateTime?
cancelledAt DateTime?
/// Snapshot bank info organizer dari OrganizerVerification saat payout dibuat.
/// Disimpan inline supaya audit-friendly walau organizer ganti bank nanti.
bankName String?
bankAccountNumber String?
bankAccountName String?
/// Catatan admin: referensi transfer manual, alasan cancel, dst.
adminNote String?
/// Admin yang menandai PAID/CANCELLED.
processedById String?
processedBy User? @relation("PayoutProcessor", fields: [processedById], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([organizerId, status])
@@index([status, heldUntil])
}
enum PayoutStatus {
/// Menunggu trip selesai + buffer beberapa hari sebelum boleh ditransfer.
HELD
/// Buffer lewat & trip COMPLETED, siap di-transfer admin ke rekening organizer.
RELEASED
/// Admin sudah transfer ke rekening organizer.
PAID
/// Booking di-refund penuh / trip dibatalkan — uang tidak jadi ke organizer.
CANCELLED
}