194 lines
6.6 KiB
TypeScript
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());
|