generator client { provider = "prisma-client" output = "../app/generated/prisma" } datasource db { provider = "postgresql" } model User { id String @id @default(cuid()) name String email String @unique password String image String? /// Apakah user telah menyetujui Syarat & Ketentuan dan Kebijakan Privasi acceptedTermsAndPrivacy Boolean @default(false) /// Waktu user menyetujui Syarat & Ketentuan dan Kebijakan Privasi acceptedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt trips Trip[] participations TripParticipant[] tripReviews TripReview[] organizerVerification OrganizerVerification? @relation("OrganizerVerificationOwner") reviewedVerifications OrganizerVerification[] @relation("OrganizerVerificationReviewer") } model OrganizerVerification { id String @id @default(cuid()) userId String @unique user User @relation("OrganizerVerificationOwner", fields: [userId], references: [id], onDelete: Cascade) /// Nama lengkap sesuai KTP fullName String /// Nomor Induk Kependudukan (PII — perlakukan sensitif) nik String @unique birthDate DateTime address String /// URL foto KTP (untuk MVP pakai hosting; pindah ke storage privat untuk produksi) ktpImageUrl String /// URL selfie memegang KTP selfieUrl String bankName String bankAccountNumber String bankAccountName String status VerificationStatus @default(PENDING) rejectionReason String? reviewedAt DateTime? reviewedById String? reviewedBy User? @relation("OrganizerVerificationReviewer", fields: [reviewedById], references: [id]) verifiedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } enum VerificationStatus { PENDING APPROVED REJECTED } model Trip { id String @id @default(cuid()) title String description String? mountain String location String /// Titik kumpul / meeting point (teks bebas) meetingPoint String? /// Itinerary hari per hari (teks bebas, bullet OK) itinerary String? /// Yang termasuk harga (teks bebas) whatsIncluded String? /// Yang tidak termasuk (teks bebas) whatsExcluded String? date DateTime endDate DateTime? maxParticipants Int price Int status TripStatus @default(OPEN) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt organizerId String organizer User @relation(fields: [organizerId], references: [id]) participants TripParticipant[] images TripImage[] reviews TripReview[] } model TripReview { id String @id @default(cuid()) rating Int comment String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt tripId String trip Trip @relation(fields: [tripId], references: [id], onDelete: Cascade) userId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@unique([tripId, userId]) } model TripImage { id String @id @default(cuid()) url String caption String? order Int @default(0) tripId String trip Trip @relation(fields: [tripId], references: [id], onDelete: Cascade) } model TripParticipant { id String @id @default(cuid()) status ParticipantStatus @default(PENDING) createdAt DateTime @default(now()) /// Peserta menekan "Saya sudah bayar" (pembayaran manual) markedPaidAt DateTime? /// Organizer mengonfirmasi uang sudah masuk paymentConfirmedAt DateTime? tripId String trip Trip @relation(fields: [tripId], references: [id]) userId String user User @relation(fields: [userId], references: [id]) @@unique([tripId, userId]) } enum TripStatus { OPEN FULL CLOSED COMPLETED } enum ParticipantStatus { PENDING CONFIRMED CANCELLED }