- 
- 
- 
This commit is contained in:
2026-05-18 18:31:16 +07:00
parent b599d01eea
commit c4efe4453b
36 changed files with 3057 additions and 1493 deletions
@@ -0,0 +1,20 @@
-- CreateTable
CREATE TABLE "TripItineraryItem" (
"id" TEXT NOT NULL,
"tripId" TEXT NOT NULL,
"day" INTEGER NOT NULL,
"startTime" TEXT NOT NULL,
"endTime" TEXT,
"activity" TEXT NOT NULL,
"order" INTEGER NOT NULL DEFAULT 0,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "TripItineraryItem_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "TripItineraryItem_tripId_day_order_idx" ON "TripItineraryItem"("tripId", "day", "order");
-- AddForeignKey
ALTER TABLE "TripItineraryItem" ADD CONSTRAINT "TripItineraryItem_tripId_fkey" FOREIGN KEY ("tripId") REFERENCES "Trip"("id") ON DELETE CASCADE ON UPDATE CASCADE;
+32 -6
View File
@@ -143,7 +143,8 @@ model Trip {
location String
/// Titik kumpul / meeting point (teks bebas)
meetingPoint String?
/// Itinerary hari per hari (teks bebas, bullet OK)
/// @deprecated — itinerary lama bentuk teks bebas, backward-compat untuk data
/// lama. Trip baru pakai `itineraryItems` (struktural per hari + jam).
itinerary String?
/// Yang termasuk harga (teks bebas)
whatsIncluded String?
@@ -162,16 +163,41 @@ model Trip {
organizerId String
organizer User @relation(fields: [organizerId], references: [id])
participants TripParticipant[]
images TripImage[]
reviews TripReview[]
bookings Booking[]
payouts Payout[]
participants TripParticipant[]
images TripImage[]
reviews TripReview[]
bookings Booking[]
payouts Payout[]
itineraryItems TripItineraryItem[]
@@index([category, status, date])
@@index([vibe, status, date])
}
/// Itinerary item terstruktur per hari + jam. Satu Trip punya banyak item;
/// dikelompokkan per `day` lalu diurutkan `order`. Format jam: "HH:mm" 24-jam.
model TripItineraryItem {
id String @id @default(cuid())
tripId String
trip Trip @relation(fields: [tripId], references: [id], onDelete: Cascade)
/// Hari ke-berapa, mulai dari 1.
day Int
/// Waktu mulai aktivitas, format "HH:mm".
startTime String
/// Waktu selesai (opsional), format "HH:mm".
endTime String?
/// Deskripsi aktivitas singkat.
activity String
/// Urutan dalam hari, untuk preserve order saat render.
order Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([tripId, day, order])
}
model TripReview {
id String @id @default(cuid())
rating Int
+238 -228
View File
@@ -27,231 +27,226 @@ const img = (id: string) =>
const SEED_PASSWORD = "password123";
// ============================================================================
// Itineraries — disimpan sebagai const supaya data trip tetap padat.
// Format: header `Hari N — <hari>` lalu bullet `• HH:MMHH:MM aktivitas`.
// Lokasi, pos, dan spot diambil dari kasus nyata (Papandayan via Cisurupan,
// Ciremai via Apuy, USS Liberty Tulamben, Karimun Jawa hopping, dst).
// Itineraries — array terstruktur per hari/jam. Setiap item: {day, startTime,
// endTime, activity}. Disimpan ke TripItineraryItem (lihat schema.prisma).
// ============================================================================
const ITIN_PAPANDAYAN = `Hari 1 — Sabtu
• 05:0005:30 Meeting & briefing di Alun-alun Garut
• 05:3007:00 Perjalanan menuju basecamp Cisurupan
• 07:0008:00 Sarapan + repacking + pemanasan
• 08:0011:00 Trekking Camp David — Hutan Mati — Pondok Salada
• 11:0012:30 Setup tenda di Pondok Salada
• 12:3014:00 ISHOMA + games kenalan grup
• 14:0017:00 Eksplor Tegal Alun & Hutan Mati (golden hour foto)
• 17:0019:00 Masak bareng + makan malam
• 19:0021:00 Api unggun, kopi, sharing rencana summit
• 21:00 Istirahat
interface SeedItineraryItem {
day: number;
startTime: string;
endTime?: string;
activity: string;
}
Hari 2 — Minggu
• 03:3004:00 Bangun + sarapan ringan + air panas
• 04:0005:30 Summit attack ke puncak Papandayan
• 05:3007:00 Sunrise + foto bareng di puncak
• 07:0009:00 Turun ke camp + sarapan utama
• 09:0011:00 Beres-beres tenda + repacking
• 11:0013:30 Turun ke basecamp Cisurupan
• 13:3014:30 Bersih-bersih + makan siang
• 14:3016:30 Perjalanan kembali ke Garut
• 16:30 Sampai Garut, bubar grup`;
const ITIN_PAPANDAYAN: SeedItineraryItem[] = [
{ day: 1, startTime: "05:00", endTime: "05:30", activity: "Meeting & briefing di Alun-alun Garut" },
{ day: 1, startTime: "05:30", endTime: "07:00", activity: "Perjalanan menuju basecamp Cisurupan" },
{ day: 1, startTime: "07:00", endTime: "08:00", activity: "Sarapan + repacking + pemanasan" },
{ day: 1, startTime: "08:00", endTime: "11:00", activity: "Trekking Camp David — Hutan Mati — Pondok Salada" },
{ day: 1, startTime: "11:00", endTime: "12:30", activity: "Setup tenda di Pondok Salada" },
{ day: 1, startTime: "12:30", endTime: "14:00", activity: "ISHOMA + games kenalan grup" },
{ day: 1, startTime: "14:00", endTime: "17:00", activity: "Eksplor Tegal Alun & Hutan Mati (golden hour foto)" },
{ day: 1, startTime: "17:00", endTime: "19:00", activity: "Masak bareng + makan malam" },
{ day: 1, startTime: "19:00", endTime: "21:00", activity: "Api unggun, kopi, sharing rencana summit" },
{ day: 1, startTime: "21:00", activity: "Istirahat" },
{ day: 2, startTime: "03:30", endTime: "04:00", activity: "Bangun + sarapan ringan + air panas" },
{ day: 2, startTime: "04:00", endTime: "05:30", activity: "Summit attack ke puncak Papandayan" },
{ day: 2, startTime: "05:30", endTime: "07:00", activity: "Sunrise + foto bareng di puncak" },
{ day: 2, startTime: "07:00", endTime: "09:00", activity: "Turun ke camp + sarapan utama" },
{ day: 2, startTime: "09:00", endTime: "11:00", activity: "Beres-beres tenda + repacking" },
{ day: 2, startTime: "11:00", endTime: "13:30", activity: "Turun ke basecamp Cisurupan" },
{ day: 2, startTime: "13:30", endTime: "14:30", activity: "Bersih-bersih + makan siang" },
{ day: 2, startTime: "14:30", endTime: "16:30", activity: "Perjalanan kembali ke Garut" },
{ day: 2, startTime: "16:30", activity: "Sampai Garut, bubar grup" },
];
const ITIN_CIREMAI = `Hari 1 — Sabtu
• 04:0004:30 Meeting & briefing di Stasiun Kuningan
• 04:3006:30 Perjalanan ke basecamp Apuy via Maja & Argapura
• 06:3007:30 Sarapan + registrasi simaksi + repacking
• 07:3010:30 Trek Pos 1 (Berod) → Pos 2 (Arban) → Pos 3 (Tegal Masawa)
• 10:3011:30 ISHOMA di Pos 4 (Tegal Jamuju)
• 11:3014:30 Lanjut Pos 5 (Sanghyang Rangkah) → Pos 6 (Goa Walet)
• 14:3016:00 Setup tenda di Pos 6
• 16:0018:00 Acara bebas + makan sore + persiapan summit
• 18:0020:00 Briefing summit + early dinner
• 20:00 Istirahat (bangun dini hari)
const ITIN_CIREMAI: SeedItineraryItem[] = [
{ day: 1, startTime: "04:00", endTime: "04:30", activity: "Meeting & briefing di Stasiun Kuningan" },
{ day: 1, startTime: "04:30", endTime: "06:30", activity: "Perjalanan ke basecamp Apuy via Maja & Argapura" },
{ day: 1, startTime: "06:30", endTime: "07:30", activity: "Sarapan + registrasi simaksi + repacking" },
{ day: 1, startTime: "07:30", endTime: "10:30", activity: "Trek Pos 1 (Berod) → Pos 2 (Arban) → Pos 3 (Tegal Masawa)" },
{ day: 1, startTime: "10:30", endTime: "11:30", activity: "ISHOMA di Pos 4 (Tegal Jamuju)" },
{ day: 1, startTime: "11:30", endTime: "14:30", activity: "Lanjut Pos 5 (Sanghyang Rangkah) → Pos 6 (Goa Walet)" },
{ day: 1, startTime: "14:30", endTime: "16:00", activity: "Setup tenda di Pos 6" },
{ day: 1, startTime: "16:00", endTime: "18:00", activity: "Acara bebas + makan sore + persiapan summit" },
{ day: 1, startTime: "18:00", endTime: "20:00", activity: "Briefing summit + early dinner" },
{ day: 1, startTime: "20:00", activity: "Istirahat (bangun dini hari)" },
{ day: 2, startTime: "02:00", endTime: "02:30", activity: "Bangun + cemilan + minuman hangat" },
{ day: 2, startTime: "02:30", endTime: "05:00", activity: "Summit attack ke puncak Sunan Cirebon (3.078 mdpl)" },
{ day: 2, startTime: "05:00", endTime: "06:30", activity: "Sunrise di puncak Ciremai" },
{ day: 2, startTime: "06:30", endTime: "08:30", activity: "Turun ke Pos 6 + sarapan" },
{ day: 2, startTime: "08:30", endTime: "10:30", activity: "Beres tenda + repacking" },
{ day: 2, startTime: "10:30", endTime: "14:00", activity: "Turun ke basecamp Apuy (track curam — hati-hati lutut)" },
{ day: 2, startTime: "14:00", endTime: "15:00", activity: "Bersih-bersih + makan siang di basecamp" },
{ day: 2, startTime: "15:00", endTime: "17:00", activity: "Kembali ke Stasiun Kuningan" },
{ day: 2, startTime: "17:00", activity: "Bubar grup" },
];
Hari 2 — Minggu
• 02:0002:30 Bangun + cemilan + minuman hangat
• 02:3005:00 Summit attack ke puncak Sunan Cirebon (3.078 mdpl)
• 05:0006:30 Sunrise di puncak Ciremai
• 06:3008:30 Turun ke Pos 6 + sarapan
• 08:3010:30 Beres tenda + repacking
• 10:3014:00 Turun ke basecamp Apuy (track curam — hati-hati lutut)
• 14:0015:00 Bersih-bersih + makan siang di basecamp
• 15:0017:00 Kembali ke Stasiun Kuningan
• 17:00 Bubar grup`;
const ITIN_CAMPING: SeedItineraryItem[] = [
{ day: 1, startTime: "13:00", endTime: "13:30", activity: "Meeting di Pertigaan Pasar Lembang" },
{ day: 1, startTime: "13:30", endTime: "15:00", activity: "Perjalanan ke Ranca Upas via Ciwidey" },
{ day: 1, startTime: "15:00", endTime: "16:00", activity: "Check-in + setup tenda dome (sudah disiapkan tim)" },
{ day: 1, startTime: "16:00", endTime: "17:30", activity: "Tour camp area + ketemu rusa-rusa" },
{ day: 1, startTime: "17:30", endTime: "19:00", activity: "Persiapan BBQ + nyalakan api unggun" },
{ day: 1, startTime: "19:00", endTime: "21:00", activity: "Makan malam BBQ" },
{ day: 1, startTime: "21:00", endTime: "23:00", activity: "Live music akustik + games" },
{ day: 1, startTime: "23:00", activity: "Istirahat" },
{ day: 2, startTime: "06:00", endTime: "07:00", activity: "Sunrise + foto di hutan pinus" },
{ day: 2, startTime: "07:00", endTime: "08:30", activity: "Sarapan (nasi goreng + roti bakar + kopi)" },
{ day: 2, startTime: "08:30", endTime: "10:00", activity: "Memberi makan rusa + sesi foto" },
{ day: 2, startTime: "10:00", endTime: "11:00", activity: "Beres tenda + bersih-bersih" },
{ day: 2, startTime: "11:00", endTime: "11:30", activity: "Pulang menuju Lembang" },
{ day: 2, startTime: "12:00", activity: "Sampai Lembang, bubar grup" },
];
const ITIN_CAMPING = `Hari 1 — Sabtu
• 13:0013:30 Meeting di Pertigaan Pasar Lembang
• 13:3015:00 Perjalanan ke Ranca Upas via Ciwidey
• 15:0016:00 Check-in + setup tenda dome (sudah disiapkan tim)
• 16:0017:30 Tour camp area + ketemu rusa-rusa
• 17:3019:00 Persiapan BBQ + nyalakan api unggun
• 19:0021:00 Makan malam BBQ
• 21:0023:00 Live music akustik + games
• 23:00 Istirahat
const ITIN_PAHAWANG: SeedItineraryItem[] = [
{ day: 1, startTime: "07:00", endTime: "07:30", activity: "Meeting di Dermaga Ketapang, Lampung Selatan" },
{ day: 1, startTime: "07:30", endTime: "08:30", activity: "Briefing safety + fitting alat snorkel" },
{ day: 1, startTime: "08:30", endTime: "09:30", activity: "Sailing menuju Pulau Pahawang Kecil" },
{ day: 1, startTime: "09:30", endTime: "11:30", activity: "Snorkeling spot Cukuh Bedil — terumbu warna-warni" },
{ day: 1, startTime: "11:30", endTime: "12:30", activity: "Pindah spot ke Pulau Kelagian Kecil" },
{ day: 1, startTime: "12:30", endTime: "14:00", activity: "Makan siang + istirahat di pasir putih" },
{ day: 1, startTime: "14:00", endTime: "15:30", activity: "Snorkeling Tanjung Putus + sesi foto underwater" },
{ day: 1, startTime: "15:30", endTime: "16:30", activity: "Sailing kembali ke dermaga" },
{ day: 1, startTime: "16:30", endTime: "17:00", activity: "Bersih-bersih + bubar grup" },
];
Hari 2 — Minggu
• 06:0007:00 Sunrise + foto di hutan pinus
• 07:0008:30 Sarapan (nasi goreng + roti bakar + kopi)
• 08:3010:00 Memberi makan rusa + sesi foto
• 10:0011:00 Beres tenda + bersih-bersih
• 11:0011:30 Pulang menuju Lembang
• 12:00 Sampai Lembang, bubar grup`;
const ITIN_DIVING: SeedItineraryItem[] = [
{ day: 1, startTime: "06:30", endTime: "07:00", activity: "Meeting di dive shop Tulamben + welcome coffee" },
{ day: 1, startTime: "07:00", endTime: "08:00", activity: "Briefing dive plan + cek sertifikasi + fitting gear" },
{ day: 1, startTime: "08:00", endTime: "09:00", activity: "Surface interval + pengecekan tank/regulator" },
{ day: 1, startTime: "09:00", endTime: "10:30", activity: "Dive #1 — USS Liberty Wreck (528m, ~50 menit bottom time)" },
{ day: 1, startTime: "10:30", endTime: "12:00", activity: "Surface interval + brunch + log dive" },
{ day: 1, startTime: "12:00", endTime: "13:30", activity: "Dive #2 — Coral Garden / Drop Off (~50 menit)" },
{ day: 1, startTime: "13:30", endTime: "15:00", activity: "Debrief + makan siang" },
{ day: 1, startTime: "15:00", endTime: "17:00", activity: "Acara bebas (rest atau eksplor desa Tulamben)" },
{ day: 1, startTime: "17:00", endTime: "19:00", activity: "Sunset di pantai Tulamben + dinner" },
{ day: 1, startTime: "19:00", activity: "Istirahat di homestay (mandiri)" },
{ day: 2, startTime: "06:00", endTime: "06:30", activity: "Bangun + kopi" },
{ day: 2, startTime: "06:30", endTime: "07:30", activity: "Briefing dive #3 (early morning visibility tinggi)" },
{ day: 2, startTime: "07:30", endTime: "09:00", activity: "Dive #3 — Liberty Wreck pagi" },
{ day: 2, startTime: "09:00", endTime: "10:30", activity: "Surface interval + sarapan + log" },
{ day: 2, startTime: "10:30", endTime: "12:00", activity: "Dive #4 (opsional, fun dive shallow reef)" },
{ day: 2, startTime: "12:00", endTime: "13:00", activity: "Bersih gear + debrief akhir" },
{ day: 2, startTime: "13:00", endTime: "14:00", activity: "Makan siang penutupan" },
{ day: 2, startTime: "14:00", activity: "Bubar grup" },
];
const ITIN_PAHAWANG = `Hari 1 — Sabtu (one-day trip)
• 07:0007:30 Meeting di Dermaga Ketapang, Lampung Selatan
• 07:3008:30 Briefing safety + fitting alat snorkel
• 08:3009:30 Sailing menuju Pulau Pahawang Kecil
• 09:3011:30 Snorkeling spot Cukuh Bedil — terumbu warna-warni
• 11:3012:30 Pindah spot ke Pulau Kelagian Kecil
• 12:3014:00 Makan siang + istirahat di pasir putih
• 14:0015:30 Snorkeling Tanjung Putus + sesi foto underwater
• 15:3016:30 Sailing kembali ke dermaga
• 16:3017:00 Bersih-bersih + bubar grup`;
const ITIN_ISLANDHOP: SeedItineraryItem[] = [
{ day: 1, startTime: "07:00", endTime: "07:30", activity: "Meeting di Pelabuhan Kartini Jepara" },
{ day: 1, startTime: "07:30", endTime: "13:00", activity: "Penyeberangan kapal feri Jepara → Karimun Jawa" },
{ day: 1, startTime: "13:00", endTime: "14:00", activity: "Tiba di Pelabuhan Karimun + transfer homestay" },
{ day: 1, startTime: "14:00", endTime: "15:00", activity: "Check-in homestay + ISHOMA" },
{ day: 1, startTime: "15:00", endTime: "17:30", activity: "Sunset di Bukit Love + foto-foto" },
{ day: 1, startTime: "17:30", endTime: "19:00", activity: "Bersih-bersih + makan malam" },
{ day: 1, startTime: "19:00", endTime: "21:00", activity: "Alun-alun Karimun + jajan kuliner" },
{ day: 1, startTime: "21:00", activity: "Istirahat" },
{ day: 2, startTime: "06:30", endTime: "07:30", activity: "Sarapan + briefing hopping" },
{ day: 2, startTime: "07:30", endTime: "09:30", activity: "Boat ke Pulau Menjangan Kecil — snorkeling spot terumbu" },
{ day: 2, startTime: "09:30", endTime: "11:30", activity: "Pulau Menjangan Besar — interaksi hiu (penangkaran)" },
{ day: 2, startTime: "11:30", endTime: "13:00", activity: "Makan siang BBQ ikan di Pulau Cemara Besar" },
{ day: 2, startTime: "13:00", endTime: "15:00", activity: "Pulau Cemara Kecil + foto pasir putih" },
{ day: 2, startTime: "15:00", endTime: "17:00", activity: "Pulau Cilik — sunset + snorkel terakhir" },
{ day: 2, startTime: "17:00", endTime: "18:30", activity: "Kembali ke homestay + bersih-bersih" },
{ day: 2, startTime: "18:30", endTime: "20:00", activity: "Makan malam seafood" },
{ day: 2, startTime: "20:00", activity: "Acara bebas" },
{ day: 3, startTime: "06:00", endTime: "07:00", activity: "Sunrise di Tanjung Gelam" },
{ day: 3, startTime: "07:00", endTime: "09:00", activity: "Sarapan + pack-up" },
{ day: 3, startTime: "09:00", endTime: "10:00", activity: "Belanja oleh-oleh di pelabuhan" },
{ day: 3, startTime: "10:00", endTime: "16:00", activity: "Penyeberangan kapal feri Karimun → Jepara" },
{ day: 3, startTime: "16:00", endTime: "17:00", activity: "Tiba di Pelabuhan Kartini, bubar grup" },
];
const ITIN_DIVING = `Hari 1 — Sabtu
• 06:3007:00 Meeting di dive shop Tulamben + welcome coffee
• 07:0008:00 Briefing dive plan + cek sertifikasi + fitting gear
• 08:0009:00 Surface interval + pengecekan tank/regulator
• 09:0010:30 Dive #1 — USS Liberty Wreck (528m, ~50 menit bottom time)
• 10:3012:00 Surface interval + brunch + log dive
• 12:0013:30 Dive #2 — Coral Garden / Drop Off (~50 menit)
• 13:3015:00 Debrief + makan siang
• 15:0017:00 Acara bebas (rest atau eksplor desa Tulamben)
• 17:0019:00 Sunset di pantai Tulamben + dinner
• 19:00 Istirahat di homestay (mandiri)
const ITIN_CITYTRIP: SeedItineraryItem[] = [
{ day: 1, startTime: "08:00", endTime: "08:30", activity: "Meeting di Stasiun Tugu Yogyakarta" },
{ day: 1, startTime: "08:30", endTime: "10:00", activity: "Sarapan Gudeg Yu Djum + briefing rute" },
{ day: 1, startTime: "10:00", endTime: "12:00", activity: "Kotagede — kerajinan perak + Masjid Mataram" },
{ day: 1, startTime: "12:00", endTime: "13:30", activity: "Makan siang Sate Klathak Pak Pong" },
{ day: 1, startTime: "13:30", endTime: "16:00", activity: "Tamansari — pemandian Sultan + sumur Gumuling" },
{ day: 1, startTime: "16:00", endTime: "17:30", activity: "Coffee break di kedai lokal Prawirotaman" },
{ day: 1, startTime: "17:30", endTime: "19:30", activity: "Sunset di Bukit Bintang (Jl. Imogiri)" },
{ day: 1, startTime: "19:30", endTime: "21:30", activity: "Angkringan Lik Man — kopi joss + nasi kucing" },
{ day: 1, startTime: "21:30", activity: "Drop ke penginapan masing-masing" },
{ day: 2, startTime: "06:00", endTime: "07:00", activity: "Pickup dari penginapan" },
{ day: 2, startTime: "07:00", endTime: "09:30", activity: "Perjalanan ke Kalibiru, Kulon Progo" },
{ day: 2, startTime: "09:30", endTime: "11:30", activity: "Kalibiru — spot foto rumah pohon di tebing" },
{ day: 2, startTime: "11:30", endTime: "13:00", activity: "Makan siang pecel di warung lokal" },
{ day: 2, startTime: "13:00", endTime: "15:00", activity: "Pinus Pengger — instalasi seni alam" },
{ day: 2, startTime: "15:00", endTime: "16:30", activity: "Heha Sky View (opsional, cek cuaca)" },
{ day: 2, startTime: "16:30", endTime: "18:00", activity: "Kembali ke kota — drop di Stasiun Tugu / Bandara" },
{ day: 2, startTime: "18:00", activity: "Bubar grup" },
];
Hari 2 — Minggu
• 06:0006:30 Bangun + kopi
• 06:3007:30 Briefing dive #3 (early morning visibility tinggi)
• 07:3009:00 Dive #3 — Liberty Wreck pagi
• 09:0010:30 Surface interval + sarapan + log
• 10:3012:00 Dive #4 (opsional, fun dive shallow reef)
• 12:0013:00 Bersih gear + debrief akhir
• 13:0014:00 Makan siang penutupan
• 14:00 Bubar grup`;
const ITIN_CULINARY: SeedItineraryItem[] = [
{ day: 1, startTime: "09:00", endTime: "09:30", activity: "Meeting di Stasiun Bandung pintu utara + briefing rute" },
{ day: 1, startTime: "09:30", endTime: "10:15", activity: "Stop 1: Surabi Enhaii (sarapan tradisional)" },
{ day: 1, startTime: "10:15", endTime: "11:00", activity: "Stop 2: Lotek Kalipah Apo" },
{ day: 1, startTime: "11:00", endTime: "11:45", activity: "Stop 3: Mie Kocok Mang Dadeng (Kebon Jukut)" },
{ day: 1, startTime: "11:45", endTime: "12:30", activity: "Stop 4: Bakso Akung (cabang Burangrang)" },
{ day: 1, startTime: "12:30", endTime: "13:30", activity: "Istirahat + jalan santai di Cihampelas" },
{ day: 1, startTime: "13:30", endTime: "14:15", activity: "Stop 5: Batagor Kingsley" },
{ day: 1, startTime: "14:15", endTime: "15:00", activity: "Stop 6: Cuanki Serayu" },
{ day: 1, startTime: "15:00", endTime: "15:45", activity: "Stop 7: Es Cendol Elizabeth" },
{ day: 1, startTime: "15:45", endTime: "16:30", activity: "Stop 8: Roti Gempol & Kopi Anjis (penutup)" },
{ day: 1, startTime: "16:30", endTime: "17:00", activity: "Closing + foto bareng di Braga" },
];
const ITIN_ISLANDHOP = `Hari 1 — Jumat
• 07:0007:30 Meeting di Pelabuhan Kartini Jepara
• 07:3013:00 Penyeberangan kapal feri Jepara → Karimun Jawa
• 13:0014:00 Tiba di Pelabuhan Karimun + transfer homestay
• 14:0015:00 Check-in homestay + ISHOMA
• 15:0017:30 Sunset di Bukit Love + foto-foto
• 17:3019:00 Bersih-bersih + makan malam
• 19:0021:00 Alun-alun Karimun + jajan kuliner
• 21:00 Istirahat
const ITIN_CONCERT: SeedItineraryItem[] = [
{ day: 1, startTime: "17:00", endTime: "17:30", activity: "Meeting di Plaza GBK, depan loket Cat 1" },
{ day: 1, startTime: "17:30", endTime: "18:30", activity: "Foto bareng pre-show + obrolan singkat" },
{ day: 1, startTime: "18:30", endTime: "19:00", activity: "Masuk venue bareng (kategori tetap masing-masing)" },
{ day: 1, startTime: "19:00", endTime: "22:30", activity: "Konser Coldplay — Music of the Spheres" },
{ day: 1, startTime: "22:30", endTime: "23:00", activity: "Berkumpul lagi di luar gerbang utama GBK" },
{ day: 1, startTime: "23:00", activity: "After-party dinner di Senayan (resto TBA via grup WA)" },
];
Hari 2 — Sabtu
• 06:3007:30 Sarapan + briefing hopping
• 07:3009:30 Boat ke Pulau Menjangan Kecil — snorkeling spot terumbu
• 09:3011:30 Pulau Menjangan Besar — interaksi hiu (penangkaran)
• 11:3013:00 Makan siang BBQ ikan di Pulau Cemara Besar
• 13:0015:00 Pulau Cemara Kecil + foto pasir putih
• 15:0017:00 Pulau Cilik — sunset + snorkel terakhir
• 17:0018:30 Kembali ke homestay + bersih-bersih
• 18:3020:00 Makan malam seafood
• 20:00 Acara bebas
const ITIN_WORKSHOP: SeedItineraryItem[] = [
{ day: 1, startTime: "04:00", endTime: "04:30", activity: "Meeting di Alun-alun Pangalengan" },
{ day: 1, startTime: "04:30", endTime: "05:30", activity: "Briefing teknis + setup peralatan" },
{ day: 1, startTime: "05:30", endTime: "07:30", activity: "Sunrise shoot di Perkebunan Teh Malabar" },
{ day: 1, startTime: "07:30", endTime: "09:00", activity: "Sarapan + sesi review foto bareng mentor" },
{ day: 1, startTime: "09:00", endTime: "11:00", activity: "Materi indoor: long exposure & filter ND" },
{ day: 1, startTime: "11:00", endTime: "13:00", activity: "ISHOMA + transfer ke Situ Cileunca" },
{ day: 1, startTime: "13:00", endTime: "16:00", activity: "Workshop on-field di Situ Cileunca (panorama, refleksi)" },
{ day: 1, startTime: "16:00", endTime: "18:00", activity: "Golden hour shoot di Bukit Nini" },
{ day: 1, startTime: "18:00", endTime: "19:30", activity: "Makan malam di villa" },
{ day: 1, startTime: "19:30", endTime: "22:00", activity: "Sesi malam — milky way / star trail (cuaca permitting)" },
{ day: 1, startTime: "22:00", activity: "Istirahat di villa" },
{ day: 2, startTime: "05:00", endTime: "07:00", activity: "Sunrise shoot di Pangalengan + foto siluet" },
{ day: 2, startTime: "07:00", endTime: "08:30", activity: "Sarapan + diskusi hasil" },
{ day: 2, startTime: "08:30", endTime: "11:00", activity: "Sesi editing Lightroom (laptop pribadi)" },
{ day: 2, startTime: "11:00", endTime: "12:00", activity: "Review akhir + sertifikat" },
{ day: 2, startTime: "12:00", endTime: "13:00", activity: "Makan siang penutupan" },
{ day: 2, startTime: "13:00", endTime: "15:00", activity: "Kembali ke Alun-alun Pangalengan" },
{ day: 2, startTime: "15:00", activity: "Bubar grup" },
];
Hari 3 — Minggu
• 06:0007:00 Sunrise di Tanjung Gelam
• 07:0009:00 Sarapan + pack-up
• 09:0010:00 Belanja oleh-oleh di pelabuhan
• 10:0016:00 Penyeberangan kapal feri Karimun → Jepara
• 16:0017:00 Tiba di Pelabuhan Kartini, bubar grup`;
const ITIN_CITYTRIP = `Hari 1 — Sabtu
• 08:0008:30 Meeting di Stasiun Tugu Yogyakarta
• 08:3010:00 Sarapan Gudeg Yu Djum + briefing rute
• 10:0012:00 Kotagede — kerajinan perak + Masjid Mataram
• 12:0013:30 Makan siang Sate Klathak Pak Pong
• 13:3016:00 Tamansari — pemandian Sultan + sumur Gumuling
• 16:0017:30 Coffee break di kedai lokal Prawirotaman
• 17:3019:30 Sunset di Bukit Bintang (Jl. Imogiri)
• 19:3021:30 Angkringan Lik Man — kopi joss + nasi kucing
• 21:30 Drop ke penginapan masing-masing
Hari 2 — Minggu
• 06:0007:00 Pickup dari penginapan
• 07:0009:30 Perjalanan ke Kalibiru, Kulon Progo
• 09:3011:30 Kalibiru — spot foto rumah pohon di tebing
• 11:3013:00 Makan siang pecel di warung lokal
• 13:0015:00 Pinus Pengger — instalasi seni alam
• 15:0016:30 Heha Sky View (opsional, cek cuaca)
• 16:3018:00 Kembali ke kota — drop di Stasiun Tugu / Bandara
• 18:00 Bubar grup`;
const ITIN_CULINARY = `Hari 1 — Sabtu (one-day food tour)
• 09:0009:30 Meeting di Stasiun Bandung pintu utara + briefing rute
• 09:3010:15 Stop 1: Surabi Enhaii (sarapan tradisional)
• 10:1511:00 Stop 2: Lotek Kalipah Apo
• 11:0011:45 Stop 3: Mie Kocok Mang Dadeng (Kebon Jukut)
• 11:4512:30 Stop 4: Bakso Akung (cabang Burangrang)
• 12:3013:30 Istirahat + jalan santai di Cihampelas
• 13:3014:15 Stop 5: Batagor Kingsley
• 14:1515:00 Stop 6: Cuanki Serayu
• 15:0015:45 Stop 7: Es Cendol Elizabeth
• 15:4516:30 Stop 8: Roti Gempol & Kopi Anjis (penutup)
• 16:3017:00 Closing + foto bareng di Braga`;
const ITIN_CONCERT = `Hari 1 — Sabtu (showtime)
• 17:0017:30 Meeting di Plaza GBK, depan loket Cat 1
• 17:3018:30 Foto bareng pre-show + obrolan singkat
• 18:3019:00 Masuk venue bareng (kategori tetap masing-masing)
• 19:0022:30 Konser Coldplay — Music of the Spheres
• 22:3023:00 Berkumpul lagi di luar gerbang utama GBK
• 23:0000:30 After-party dinner di Senayan (resto TBA via grup WA)
• 00:30 Bubar`;
const ITIN_WORKSHOP = `Hari 1 — Sabtu
• 04:0004:30 Meeting di Alun-alun Pangalengan
• 04:3005:30 Briefing teknis + setup peralatan
• 05:3007:30 Sunrise shoot di Perkebunan Teh Malabar
• 07:3009:00 Sarapan + sesi review foto bareng mentor
• 09:0011:00 Materi indoor: long exposure & filter ND
• 11:0013:00 ISHOMA + transfer ke Situ Cileunca
• 13:0016:00 Workshop on-field di Situ Cileunca (panorama, refleksi)
• 16:0018:00 Golden hour shoot di Bukit Nini
• 18:0019:30 Makan malam di villa
• 19:3022:00 Sesi malam — milky way / star trail (cuaca permitting)
• 22:00 Istirahat di villa
Hari 2 — Minggu
• 05:0007:00 Sunrise shoot di Pangalengan + foto siluet
• 07:0008:30 Sarapan + diskusi hasil
• 08:3011:00 Sesi editing Lightroom (laptop pribadi)
• 11:0012:00 Review akhir + sertifikat
• 12:0013:00 Makan siang penutupan
• 13:0015:00 Kembali ke Alun-alun Pangalengan
• 15:00 Bubar grup`;
const ITIN_RETREAT = `Hari 1 — Jumat
• 14:0015:00 Check-in Villa Sawah Ubud + welcome drink (jamu)
• 15:0016:00 Tour fasilitas + pembagian welcome kit
• 16:0017:30 Yin Yoga pembuka — release perjalanan
• 17:3018:30 Journaling: niat & ekspektasi retreat
• 18:3020:00 Dinner vegan (set menu)
• 20:0021:00 Circle pengenalan + meditasi singkat
• 21:00 Lights-out
Hari 2 — Sabtu
• 06:0007:30 Hatha Yoga matahari terbit
• 07:3009:00 Sarapan vegan + tea ceremony
• 09:0010:30 Meditasi guided: body scan
• 10:3012:00 Pranayama (latihan napas)
• 12:0013:30 Lunch + acara bebas (sawah walk)
• 13:3015:00 Sound healing dengan singing bowl
• 15:0016:30 Workshop: mindful eating + jamu making
• 16:3018:00 Yin Yoga sore + savasana panjang
• 18:0019:30 Dinner vegan
• 19:3021:00 Sharing circle + meditasi malam
• 21:00 Lights-out
Hari 3 — Minggu
• 06:0007:30 Vinyasa Flow penutupan
• 07:3009:00 Sarapan + closing journaling
• 09:0010:30 Closing circle + tukar pesan
• 10:3011:30 Check-out + pelukan perpisahan
• 11:3014:00 Acara bebas (rekomendasi spa/cafe sekitar)
• 14:00 Trip resmi ditutup`;
const ITIN_RETREAT: SeedItineraryItem[] = [
{ day: 1, startTime: "14:00", endTime: "15:00", activity: "Check-in Villa Sawah Ubud + welcome drink (jamu)" },
{ day: 1, startTime: "15:00", endTime: "16:00", activity: "Tour fasilitas + pembagian welcome kit" },
{ day: 1, startTime: "16:00", endTime: "17:30", activity: "Yin Yoga pembuka — release perjalanan" },
{ day: 1, startTime: "17:30", endTime: "18:30", activity: "Journaling: niat & ekspektasi retreat" },
{ day: 1, startTime: "18:30", endTime: "20:00", activity: "Dinner vegan (set menu)" },
{ day: 1, startTime: "20:00", endTime: "21:00", activity: "Circle pengenalan + meditasi singkat" },
{ day: 1, startTime: "21:00", activity: "Lights-out" },
{ day: 2, startTime: "06:00", endTime: "07:30", activity: "Hatha Yoga matahari terbit" },
{ day: 2, startTime: "07:30", endTime: "09:00", activity: "Sarapan vegan + tea ceremony" },
{ day: 2, startTime: "09:00", endTime: "10:30", activity: "Meditasi guided: body scan" },
{ day: 2, startTime: "10:30", endTime: "12:00", activity: "Pranayama (latihan napas)" },
{ day: 2, startTime: "12:00", endTime: "13:30", activity: "Lunch + acara bebas (sawah walk)" },
{ day: 2, startTime: "13:30", endTime: "15:00", activity: "Sound healing dengan singing bowl" },
{ day: 2, startTime: "15:00", endTime: "16:30", activity: "Workshop: mindful eating + jamu making" },
{ day: 2, startTime: "16:30", endTime: "18:00", activity: "Yin Yoga sore + savasana panjang" },
{ day: 2, startTime: "18:00", endTime: "19:30", activity: "Dinner vegan" },
{ day: 2, startTime: "19:30", endTime: "21:00", activity: "Sharing circle + meditasi malam" },
{ day: 2, startTime: "21:00", activity: "Lights-out" },
{ day: 3, startTime: "06:00", endTime: "07:30", activity: "Vinyasa Flow penutupan" },
{ day: 3, startTime: "07:30", endTime: "09:00", activity: "Sarapan + closing journaling" },
{ day: 3, startTime: "09:00", endTime: "10:30", activity: "Closing circle + tukar pesan" },
{ day: 3, startTime: "10:30", endTime: "11:30", activity: "Check-out + pelukan perpisahan" },
{ day: 3, startTime: "11:30", endTime: "14:00", activity: "Acara bebas (rekomendasi spa/cafe sekitar)" },
{ day: 3, startTime: "14:00", activity: "Trip resmi ditutup" },
];
// ============================================================================
// 1. Cleanup — urutan FK aware (Payment → Booking → Review → Image →
@@ -260,10 +255,15 @@ Hari 3 — Minggu
// ============================================================================
async function cleanup() {
// Refund & Payout pakai onDelete: Restrict ke Booking/Payment, jadi mereka
// wajib dihapus duluan sebelum Booking/Payment bisa dibersihkan.
await prisma.refund.deleteMany();
await prisma.payout.deleteMany();
await prisma.payment.deleteMany();
await prisma.booking.deleteMany();
await prisma.tripReview.deleteMany();
await prisma.tripImage.deleteMany();
await prisma.tripItineraryItem.deleteMany();
await prisma.tripParticipant.deleteMany();
await prisma.trip.deleteMany();
await prisma.organizerVerification.deleteMany();
@@ -556,7 +556,7 @@ interface SeedTrip {
title: string;
description: string;
meetingPoint?: string;
itinerary?: string;
itineraryItems?: SeedItineraryItem[];
whatsIncluded?: string;
whatsExcluded?: string;
destination: string;
@@ -580,7 +580,7 @@ const SEED_TRIPS: SeedTrip[] = [
title: "Open Trip Papandayan — Maret 2026",
description: `Pendakian santai ke Gunung Papandayan, batch Maret. Cocok untuk pemula.`,
meetingPoint: "Alun-alun Garut, 05:00 WIB",
itinerary: ITIN_PAPANDAYAN,
itineraryItems: ITIN_PAPANDAYAN,
destination: "Gunung Papandayan",
location: "Garut, Jawa Barat",
date: utc(2026, 2, 14, 22, 0),
@@ -601,7 +601,7 @@ const SEED_TRIPS: SeedTrip[] = [
title: "Snorkeling Pulau Pahawang — Februari 2026",
description: `Trip snorkeling batch Februari. Cuaca bersahabat, visibility 10m+.`,
meetingPoint: "Dermaga Ketapang, Lampung Selatan, 07:00 WIB",
itinerary: ITIN_PAHAWANG,
itineraryItems: ITIN_PAHAWANG,
destination: "Pulau Pahawang Kecil",
location: "Lampung Selatan, Lampung",
date: utc(2026, 1, 21, 0, 0),
@@ -621,7 +621,7 @@ const SEED_TRIPS: SeedTrip[] = [
title: "Kulineran Street Food Bandung — April 2026",
description: `Food tour batch April. 8 spot legend dilibas dalam satu hari.`,
meetingPoint: "Stasiun Bandung pintu utara, 09:00 WIB",
itinerary: ITIN_CULINARY,
itineraryItems: ITIN_CULINARY,
destination: "Street Food Tour Bandung",
location: "Bandung, Jawa Barat",
date: utc(2026, 3, 12, 0, 0),
@@ -662,7 +662,7 @@ const SEED_TRIPS: SeedTrip[] = [
⚠️ Bawa: Sleeping bag, jaket, headlamp, air 2L`,
meetingPoint: "Alun-alun Garut, Sabtu 05:00 WIB — detail grup WA.",
itinerary: ITIN_PAPANDAYAN,
itineraryItems: ITIN_PAPANDAYAN,
whatsIncluded: `• Transport PP Garutbasecamp
• Guide lokal
• Tenda tim
@@ -693,7 +693,7 @@ const SEED_TRIPS: SeedTrip[] = [
📍 Meeting Point: Stasiun Kuningan, 04:00 WIB
⚠️ Level: Menengah — perlu stamina baik`,
meetingPoint: "Stasiun Kuningan, Sabtu 04:00 WIB",
itinerary: ITIN_CIREMAI,
itineraryItems: ITIN_CIREMAI,
destination: "Gunung Ciremai",
location: "Kuningan, Jawa Barat",
date: utc(2026, 5, 23, 4, 0),
@@ -718,7 +718,7 @@ const SEED_TRIPS: SeedTrip[] = [
🎒 Fasilitas: Tenda dome, sleeping bag, BBQ, api unggun
🔥 Bonus: Live music akustik malam hari`,
meetingPoint: "Pertigaan Pasar Lembang, Sabtu 13:00 WIB",
itinerary: ITIN_CAMPING,
itineraryItems: ITIN_CAMPING,
whatsIncluded: `• Tenda + sleeping bag + matras
• Logistik camp
• Makan malam BBQ + sarapan
@@ -748,7 +748,7 @@ const SEED_TRIPS: SeedTrip[] = [
🤿 Pemula friendly — guide profesional
📷 Underwater photo session included`,
meetingPoint: "Dermaga Ketapang, Lampung Selatan, 07:00 WIB",
itinerary: ITIN_PAHAWANG,
itineraryItems: ITIN_PAHAWANG,
whatsIncluded: `• Boat PP
• Alat snorkel (masker, fin, life vest)
• Guide & pemandu underwater
@@ -777,7 +777,7 @@ const SEED_TRIPS: SeedTrip[] = [
⚠️ Sertifikasi minimal: Open Water (PADI/SSI)`,
meetingPoint: "Dive shop Tulamben, 06:30 WITA",
itinerary: ITIN_DIVING,
itineraryItems: ITIN_DIVING,
whatsIncluded: `• 2x dive guided
• Full gear rental
• Tank & weight
@@ -807,7 +807,7 @@ const SEED_TRIPS: SeedTrip[] = [
🏝️ Cocok untuk solo traveler & couple`,
meetingPoint: "Pelabuhan Kartini Jepara, Jumat 07:00 WIB",
itinerary: ITIN_ISLANDHOP,
itineraryItems: ITIN_ISLANDHOP,
whatsIncluded: `• Tiket kapal feri PP JeparaKarimun
• Homestay 2 malam (twin sharing)
• Boat hopping 2 hari
@@ -837,7 +837,7 @@ const SEED_TRIPS: SeedTrip[] = [
🚐 Mobil grup, bukan tour bus`,
meetingPoint: "Stasiun Tugu Yogyakarta, Sabtu 08:00 WIB",
itinerary: ITIN_CITYTRIP,
itineraryItems: ITIN_CITYTRIP,
whatsIncluded: `• Transport mobil grup 2 hari
• Tour leader lokal
• Makan 3x (kuliner lokal)
@@ -866,7 +866,7 @@ const SEED_TRIPS: SeedTrip[] = [
🍜 Cocok buat foodie & first-timer`,
meetingPoint: "Stasiun Bandung pintu utara, 09:00 WIB",
itinerary: ITIN_CULINARY,
itineraryItems: ITIN_CULINARY,
whatsIncluded: `• Transport angkot/grup
• Tour leader food explorer
• Sample setiap spot (8 tempat)`,
@@ -893,7 +893,7 @@ const SEED_TRIPS: SeedTrip[] = [
🎤 Tiket BUKAN termasuk — peserta bawa tiket masing-masing
🤝 Grup hanya untuk koordinasi meet-up & after-party`,
meetingPoint: "Plaza GBK, depan loket Cat 1, 17:00 WIB",
itinerary: ITIN_CONCERT,
itineraryItems: ITIN_CONCERT,
whatsIncluded: `• Koordinasi grup
• Foto bareng pre-show
• After-party dinner di Senayan`,
@@ -921,7 +921,7 @@ const SEED_TRIPS: SeedTrip[] = [
📷 Bawa kamera DSLR/mirrorless + tripod
👨‍🏫 Mentor: fotografer pro (10+ tahun pengalaman)`,
meetingPoint: "Alun-alun Pangalengan, Sabtu 04:00 WIB",
itinerary: ITIN_WORKSHOP,
itineraryItems: ITIN_WORKSHOP,
whatsIncluded: `• Materi workshop (briefing + on-field)
• Tour leader & mentor
• Penginapan villa 1 malam
@@ -951,7 +951,7 @@ const SEED_TRIPS: SeedTrip[] = [
🧘 Untuk yang lagi burnout & butuh reset
👥 Grup kecil (max 8) — pengalaman akrab`,
meetingPoint: "Villa Sawah Ubud (alamat dikirim H-3 via WA)",
itinerary: ITIN_RETREAT,
itineraryItems: ITIN_RETREAT,
whatsIncluded: `• Penginapan villa 2 malam
• Yoga 4 sesi + meditasi 6 sesi
• Sound healing (1 sesi)
@@ -990,7 +990,6 @@ async function seedTrips(users: UserMap): Promise<TripMap> {
title: t.title,
description: t.description,
meetingPoint: t.meetingPoint,
itinerary: t.itinerary,
whatsIncluded: t.whatsIncluded,
whatsExcluded: t.whatsExcluded,
destination: t.destination,
@@ -1011,6 +1010,17 @@ async function seedTrips(users: UserMap): Promise<TripMap> {
})),
}
: undefined,
itineraryItems: t.itineraryItems?.length
? {
create: t.itineraryItems.map((item, order) => ({
day: item.day,
startTime: item.startTime,
endTime: item.endTime ?? null,
activity: item.activity,
order,
})),
}
: undefined,
},
});
map[t.key] = { id: created.id, price: created.price, status: t.status };