rtrips-online/prisma/seed-demo.ts

194 lines
6.6 KiB
TypeScript

import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
const DEMO_SLUG = 'alpine-explorer-2026';
async function main() {
// Idempotent — skip if already seeded
const existing = await prisma.trip.findUnique({ where: { slug: DEMO_SLUG } });
if (existing) {
console.log(`Demo trip "${DEMO_SLUG}" already exists (id: ${existing.id}). Skipping.`);
return;
}
console.log('Seeding demo trip: Alpine Explorer 2026...');
// Create demo users
const memberData = [
{ name: 'Alex', did: 'did:demo:alex-001' },
{ name: 'Sam', did: 'did:demo:sam-002' },
{ name: 'Jordan', did: 'did:demo:jordan-003' },
{ name: 'Riley', did: 'did:demo:riley-004' },
{ name: 'Casey', did: 'did:demo:casey-005' },
{ name: 'Morgan', did: 'did:demo:morgan-006' },
];
const users = await Promise.all(
memberData.map((m) =>
prisma.user.upsert({
where: { did: m.did },
update: { username: m.name },
create: { did: m.did, username: m.name },
})
)
);
// Create trip
const trip = await prisma.trip.create({
data: {
title: 'Alpine Explorer 2026',
slug: DEMO_SLUG,
description: 'Chamonix → Zermatt → Dolomites',
rawInput:
'2 weeks in the Alps with 6 friends. Hiking, via ferrata, mountain biking, kayaking, paragliding. Mix of camping, huts, and Airbnb. Budget ~€4500.',
startDate: new Date('2026-07-06'),
endDate: new Date('2026-07-20'),
budgetTotal: 4500,
budgetCurrency: 'EUR',
status: 'PLANNING',
},
});
// Add collaborators
await prisma.tripCollaborator.createMany({
data: users.map((u, i) => ({
userId: u.id,
tripId: trip.id,
role: i === 0 ? 'OWNER' : 'MEMBER',
})),
});
// Create destinations
const destinations = await Promise.all([
prisma.destination.create({
data: {
tripId: trip.id,
name: 'Chamonix',
country: 'France',
lat: 45.9237,
lng: 6.8694,
arrivalDate: new Date('2026-07-06'),
departureDate: new Date('2026-07-11'),
notes: 'Base camp for Mont Blanc region. Book mountain hut in advance.',
sortOrder: 0,
},
}),
prisma.destination.create({
data: {
tripId: trip.id,
name: 'Zermatt',
country: 'Switzerland',
lat: 46.0207,
lng: 7.7491,
arrivalDate: new Date('2026-07-12'),
departureDate: new Date('2026-07-16'),
notes: 'Car-free village. Take train from Täsch. Matterhorn views!',
sortOrder: 1,
},
}),
prisma.destination.create({
data: {
tripId: trip.id,
name: 'Dolomites',
country: 'Italy',
lat: 46.4102,
lng: 11.8440,
arrivalDate: new Date('2026-07-17'),
departureDate: new Date('2026-07-20'),
notes: 'Tre Cime di Lavaredo circuit is a must. Lake Braies for kayaking.',
sortOrder: 2,
},
}),
]);
// Create itinerary items (one per trip day)
const itineraryItems = [
{ date: '2026-07-06', title: 'Fly to Geneva', category: 'FLIGHT', destIdx: 0 },
{ date: '2026-07-07', title: 'Chamonix check-in', category: 'ACCOMMODATION', destIdx: 0 },
{ date: '2026-07-08', title: 'Mont Blanc hike', category: 'ACTIVITY', destIdx: 0 },
{ date: '2026-07-09', title: 'Rest / explore town', category: 'FREE_TIME', destIdx: 0 },
{ date: '2026-07-10', title: 'Mer de Glace trek', category: 'ACTIVITY', destIdx: 0 },
{ date: '2026-07-11', title: 'Via ferrata', category: 'ACTIVITY', destIdx: 0 },
{ date: '2026-07-12', title: 'Train to Zermatt', category: 'TRANSPORT', destIdx: 1 },
{ date: '2026-07-13', title: 'Matterhorn viewpoint', category: 'ACTIVITY', destIdx: 1 },
{ date: '2026-07-14', title: 'Mountain biking', category: 'ACTIVITY', destIdx: 1 },
{ date: '2026-07-15', title: 'Gorner Gorge hike', category: 'ACTIVITY', destIdx: 1 },
{ date: '2026-07-16', title: 'Paragliding!', category: 'ACTIVITY', destIdx: 1 },
{ date: '2026-07-17', title: 'Travel to Dolomites', category: 'TRANSPORT', destIdx: 2 },
{ date: '2026-07-18', title: 'Tre Cime circuit', category: 'ACTIVITY', destIdx: 2 },
{ date: '2026-07-19', title: 'Lake Braies kayaking', category: 'ACTIVITY', destIdx: 2 },
{ date: '2026-07-20', title: 'Fly home', category: 'FLIGHT', destIdx: 2 },
];
await prisma.itineraryItem.createMany({
data: itineraryItems.map((item, i) => ({
tripId: trip.id,
destinationId: destinations[item.destIdx].id,
title: item.title,
date: new Date(item.date),
category: item.category as never,
sortOrder: i,
})),
});
// Create expenses
const expenseData = [
{ desc: 'Geneva → Chamonix shuttle', who: 0, amount: 186, cat: 'TRANSPORT' },
{ desc: 'Mountain hut (2 nights)', who: 1, amount: 420, cat: 'ACCOMMODATION' },
{ desc: 'Via ferrata gear rental', who: 2, amount: 144, cat: 'ACTIVITY' },
{ desc: 'Groceries (Zermatt)', who: 4, amount: 93, cat: 'FOOD' },
{ desc: 'Paragliding deposit', who: 3, amount: 360, cat: 'ACTIVITY' },
];
await prisma.expense.createMany({
data: expenseData.map((e) => ({
tripId: trip.id,
paidById: users[e.who].id,
description: e.desc,
amount: e.amount,
currency: 'EUR',
category: e.cat as never,
date: new Date('2026-07-08'),
splitType: 'EQUAL',
})),
});
// Create packing items
const packingData = [
{ name: 'Hiking boots (broken in!)', cat: 'Footwear', packed: true },
{ name: 'Rain jacket & layers', cat: 'Clothing', packed: true },
{ name: 'Headlamp + spare batteries', cat: 'Gear', packed: true },
{ name: 'First aid kit', cat: 'Safety', packed: false },
{ name: 'Sunscreen SPF 50', cat: 'Personal', packed: true },
{ name: 'Trekking poles', cat: 'Gear', packed: false },
{ name: 'Refillable water bottle', cat: 'Gear', packed: true },
{ name: 'Via ferrata gloves', cat: 'Gear', packed: false },
];
await prisma.packingItem.createMany({
data: packingData.map((p, i) => ({
tripId: trip.id,
addedById: users[0].id,
name: p.name,
category: p.cat,
packed: p.packed,
sortOrder: i,
})),
});
console.log(`Demo trip created: id=${trip.id}, slug=${trip.slug}`);
console.log(` - ${users.length} collaborators`);
console.log(` - ${destinations.length} destinations`);
console.log(` - ${itineraryItems.length} itinerary items`);
console.log(` - ${expenseData.length} expenses`);
console.log(` - ${packingData.length} packing items`);
}
main()
.catch((e) => {
console.error('Seed failed:', e);
process.exit(1);
})
.finally(() => prisma.$disconnect());