Files
setrip/prisma/seed.ts
T
2026-04-20 00:25:05 +07:00

342 lines
11 KiB
TypeScript

import "dotenv/config";
import { PrismaClient } from "../app/generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
import bcrypt from "bcryptjs";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
const prisma = new PrismaClient({ adapter });
async function main() {
console.log("🌱 Seeding database...\n");
// Clean existing data (order matters for FK)
await prisma.tripReview.deleteMany();
await prisma.tripParticipant.deleteMany();
await prisma.tripImage.deleteMany();
await prisma.trip.deleteMany();
await prisma.user.deleteMany();
// ==================== USERS ====================
const password = await bcrypt.hash("password123", 12);
// Organizer
const dede = await prisma.user.create({
data: {
name: "Dede Inoen",
email: "dede.inoen@setrip.id",
password,
},
});
const panji = await prisma.user.create({
data: {
name: "Panji Petualang",
email: "panji@setrip.id",
password,
},
});
const fiersa = await prisma.user.create({
data: {
name: "Fiersa Besari",
email: "fiersa@setrip.id",
password,
},
});
// User biasa (peserta)
const budi = await prisma.user.create({
data: {
name: "Budi Santoso",
email: "budi@gmail.com",
password,
},
});
const sari = await prisma.user.create({
data: {
name: "Sari Dewi",
email: "sari@gmail.com",
password,
},
});
const doni = await prisma.user.create({
data: {
name: "Doni Prasetyo",
email: "doni@gmail.com",
password,
},
});
const maya = await prisma.user.create({
data: {
name: "Maya Putri",
email: "maya@gmail.com",
password,
},
});
const raka = await prisma.user.create({
data: {
name: "Raka Aditya",
email: "raka@gmail.com",
password,
},
});
console.log("✅ Users created");
console.log(" Organizer: dede.inoen@setrip.id, panji@setrip.id, fiersa@setrip.id");
console.log(" Peserta: budi, sari, doni, maya, raka @gmail.com");
console.log(" Password semua: password123\n");
// ==================== TRIPS + IMAGES ====================
/**
* Tanggal disimpan eksplisit di UTC agar filter `from`/`to` (YYYY-MM-DD UTC)
* cocok dengan yang tampil di daftar.
*
* - Multi hari: isi `endDate` = hari terakhir trip (UTC).
* - Satu hari / night hike satu malam: `endDate` null — filter memakai instan `date`
* dalam rentang hari UTC yang sama (jam tetap masuk hari itu).
*/
const utc = (y: number, m0: number, d: number, h = 12, min = 0) =>
new Date(Date.UTC(y, m0, d, h, min, 0, 0));
// --- Trip 1: Papandayan (by Dede Inoen) — 2 hari ---
const trip1 = await prisma.trip.create({
data: {
title: "Open Trip Papandayan Weekend",
description: `Pendakian santai ke Gunung Papandayan, cocok untuk pemula!
📍 Meeting Point: Alun-alun Garut, 05:00 WIB
🎒 Fasilitas: Transport PP, guide, tenda, makan 3x
⚠️ Bawa: Sleeping bag, jaket, headlamp, air 2L
Itinerary:
- Sabtu: Berangkat → Basecamp → Summit → Camp
- Minggu: Sunrise → Turun → Pulang`,
mountain: "Gunung Papandayan",
location: "Garut, Jawa Barat",
date: utc(2026, 3, 23, 8, 0),
endDate: utc(2026, 3, 24, 18, 0),
maxParticipants: 10,
price: 250000,
status: "OPEN",
organizerId: dede.id,
images: {
create: [
{ url: "/images/seed/papandayan-1.svg", caption: "Kawah Papandayan", order: 0 },
{ url: "/images/seed/papandayan-2.svg", caption: "Track menuju puncak", order: 1 },
{ url: "/images/seed/papandayan-3.svg", caption: "Camping ground Pondok Salada", order: 2 },
],
},
},
});
// --- Trip 2: Ciremai (by Panji Petualang) — 2 hari ---
const trip2 = await prisma.trip.create({
data: {
title: "Pendakian Ciremai via Apuy",
description: `Trip ke puncak tertinggi Jawa Barat! 🏔️
📍 Meeting Point: Stasiun Kuningan, 04:00 WIB
🎒 Fasilitas: Transport lokal, guide, logistik
⚠️ Level: Menengah — perlu stamina baik
Itinerary:
- Hari 1: Basecamp → Pos 3 → Camp
- Hari 2: Summit attack → Turun → Pulang`,
mountain: "Gunung Ciremai",
location: "Kuningan, Jawa Barat",
date: utc(2026, 3, 25, 4, 0),
endDate: utc(2026, 3, 26, 18, 0),
maxParticipants: 8,
price: 350000,
status: "OPEN",
organizerId: panji.id,
images: {
create: [
{ url: "/images/seed/ciremai-1.svg", caption: "Puncak Ciremai 3.078 mdpl", order: 0 },
{ url: "/images/seed/ciremai-2.svg", caption: "Jalur pendakian via Apuy", order: 1 },
{ url: "/images/seed/ciremai-3.svg", caption: "Sunrise dari puncak", order: 2 },
],
},
},
});
// --- Trip 3: Gede-Pangrango (by Fiersa Besari) — 2 hari ---
const trip3 = await prisma.trip.create({
data: {
title: "Sunrise Trip Gede-Pangrango",
description: `Combo 2 puncak sekaligus! Gede + Pangrango.
📍 Meeting Point: Cibodas, 22:00 WIB (malam)
🎒 Fasilitas: Guide, tenda, makan
⚠️ Level: Advance — night hike
Start malam, summit saat sunrise. View epic dijamin!`,
mountain: "Gunung Gede",
location: "Bogor/Cianjur, Jawa Barat",
date: utc(2026, 3, 27, 22, 0),
endDate: utc(2026, 3, 28, 16, 0),
maxParticipants: 12,
price: 280000,
status: "OPEN",
organizerId: fiersa.id,
images: {
create: [
{ url: "/images/seed/gede-1.svg", caption: "Puncak Gunung Gede", order: 0 },
{ url: "/images/seed/gede-2.svg", caption: "Surya Kencana padang edelweis", order: 1 },
{ url: "/images/seed/gede-3.svg", caption: "Blue lake / Danau Biru", order: 2 },
{ url: "/images/seed/gede-4.svg", caption: "Night hike track Cibodas", order: 3 },
],
},
},
});
// --- Trip 4: Tangkuban Parahu (by Dede Inoen) — 1 hari ---
const trip4 = await prisma.trip.create({
data: {
title: "Trip Hemat Tangkuban Parahu",
description: `Trip santai ke kawah Tangkuban Parahu. Cocok buat first-timer!
📍 Meeting Point: Lembang, 07:00 WIB
🎒 Fasilitas: Transport, snack, guide
⚠️ Level: Easy — bisa pakai sandal gunung
Explore Kawah Ratu, Kawah Domas, foto-foto, terus makan sate maranggi!`,
mountain: "Gunung Tangkuban Parahu",
location: "Bandung, Jawa Barat",
date: utc(2026, 3, 22, 0, 0),
endDate: null,
maxParticipants: 15,
price: 120000,
status: "OPEN",
organizerId: dede.id,
images: {
create: [
{ url: "/images/seed/tangkuban-1.svg", caption: "Kawah Ratu", order: 0 },
{ url: "/images/seed/tangkuban-2.svg", caption: "Kawah Domas", order: 1 },
],
},
},
});
// --- Trip 5: Malabar (by Fiersa Besari) — 1 hari (night hike, `endDate` null) ---
const trip5 = await prisma.trip.create({
data: {
title: "Malabar Night Hike",
description: `Night hike ke Gunung Malabar — view kota Bandung dari atas!
📍 Meeting Point: Pangalengan, 20:00 WIB
🎒 Fasilitas: Guide, teh hangat di puncak
⚠️ Bawa: Headlamp WAJIB, jaket tebal
Trip ringan, 3-4 jam naik. Cocok buat yang mau healing malam-malam.`,
mountain: "Gunung Malabar",
location: "Bandung, Jawa Barat",
date: utc(2026, 3, 20, 14, 0),
endDate: null,
maxParticipants: 10,
price: 150000,
status: "OPEN",
organizerId: fiersa.id,
images: {
create: [
{ url: "/images/seed/malabar-1.svg", caption: "Puncak Malabar malam hari", order: 0 },
{ url: "/images/seed/malabar-2.svg", caption: "View Bandung dari atas", order: 1 },
{ url: "/images/seed/malabar-3.svg", caption: "Track pendakian", order: 2 },
],
},
},
});
// --- Trip 6: Guntur (by Panji Petualang) — 2 hari ---
const trip6 = await prisma.trip.create({
data: {
title: "Guntur Challenge Trip",
description: `Trip ke Gunung Guntur — jalur menantang tapi worth it!
📍 Meeting Point: Alun-alun Garut, 04:30 WIB
🎒 Fasilitas: Transport, guide, logistik
⚠️ Level: Hard — medan berbatu & terjal
Buat yang suka challenge. Pemandangan kawah aktif dari dekat!`,
mountain: "Gunung Guntur",
location: "Garut, Jawa Barat",
date: utc(2026, 3, 30, 4, 0),
endDate: utc(2026, 4, 1, 18, 0),
maxParticipants: 8,
price: 300000,
status: "OPEN",
organizerId: panji.id,
images: {
create: [
{ url: "/images/seed/guntur-1.svg", caption: "Kawah aktif Gunung Guntur", order: 0 },
{ url: "/images/seed/guntur-2.svg", caption: "Jalur berbatu menuju puncak", order: 1 },
{ url: "/images/seed/guntur-3.svg", caption: "View dari puncak", order: 2 },
],
},
},
});
console.log("✅ 6 Trips + images created (tanggal UTC + endDate untuk trip multi hari)\n");
console.log(
` Guntur: ${trip6.title} ${trip6.date.toISOString().slice(0, 10)}${trip6.endDate?.toISOString().slice(0, 10) ?? "-"}\n`
);
// ==================== PARTICIPANTS ====================
await prisma.tripParticipant.createMany({
data: [
// Papandayan — 4 peserta
{ tripId: trip1.id, userId: budi.id, status: "CONFIRMED" },
{ tripId: trip1.id, userId: sari.id, status: "CONFIRMED" },
{ tripId: trip1.id, userId: doni.id, status: "CONFIRMED" },
{ tripId: trip1.id, userId: raka.id, status: "CONFIRMED" },
// Ciremai — 2 peserta
{ tripId: trip2.id, userId: budi.id, status: "CONFIRMED" },
{ tripId: trip2.id, userId: maya.id, status: "CONFIRMED" },
// Gede — 5 peserta
{ tripId: trip3.id, userId: budi.id, status: "CONFIRMED" },
{ tripId: trip3.id, userId: sari.id, status: "CONFIRMED" },
{ tripId: trip3.id, userId: doni.id, status: "CONFIRMED" },
{ tripId: trip3.id, userId: maya.id, status: "CONFIRMED" },
{ tripId: trip3.id, userId: raka.id, status: "CONFIRMED" },
// Tangkuban Parahu — 5 peserta
{ tripId: trip4.id, userId: budi.id, status: "CONFIRMED" },
{ tripId: trip4.id, userId: sari.id, status: "CONFIRMED" },
{ tripId: trip4.id, userId: doni.id, status: "CONFIRMED" },
{ tripId: trip4.id, userId: maya.id, status: "CONFIRMED" },
{ tripId: trip4.id, userId: raka.id, status: "CONFIRMED" },
// Malabar — 2 peserta
{ tripId: trip5.id, userId: sari.id, status: "CONFIRMED" },
{ tripId: trip5.id, userId: maya.id, status: "CONFIRMED" },
// Guntur — 0 peserta
],
});
console.log("✅ Participants joined");
console.log(" Papandayan: 4/10 | Ciremai: 2/8 | Gede: 5/12");
console.log(" Tangkuban Parahu: 5/15 | Malabar: 2/10 | Guntur: 0/8\n");
console.log("🎉 Seed complete!");
}
main()
.catch((e) => {
console.error("❌ Seed failed:", e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});