import { PrismaClient } from '@prisma/client'; import bcrypt from 'bcryptjs'; const prisma = new PrismaClient(); async function main() { // -- Settings singleton -- await prisma.settings.upsert({ where: { id: 'singleton' }, update: {}, create: { id: 'singleton', pickupEnabled: true }, }); console.log('✓ Settings singleton ensured'); // -- Initial admin -- const email = (process.env.SEED_ADMIN_EMAIL ?? 'admin@example.com').toLowerCase(); const password = process.env.SEED_ADMIN_PASSWORD ?? 'change-me'; const name = process.env.SEED_ADMIN_NAME ?? 'Admin'; const passwordHash = await bcrypt.hash(password, 12); await prisma.admin.upsert({ where: { email }, update: {}, create: { email, name, passwordHash }, }); console.log(`✓ Admin ensured: ${email}`); // -- Products (example LPG cylinders) -- const products = [ { sku: 'P6', nameSv: 'Gasoltub P6', nameEn: 'LPG cylinder P6', descriptionSv: '6 kg gasol — för mindre kök och campingkök.', descriptionEn: '6 kg LPG — for smaller stoves and camping cooktops.', priceOre: 39900, // 399 kr sortOrder: 10, }, { sku: 'P11', nameSv: 'Gasoltub P11', nameEn: 'LPG cylinder P11', descriptionSv: '11 kg gasol — vanligaste storleken för matlagning på läger.', descriptionEn: '11 kg LPG — most common size for cooking at camps.', priceOre: 64900, // 649 kr sortOrder: 20, }, { sku: 'P19', nameSv: 'Gasoltub P19', nameEn: 'LPG cylinder P19', descriptionSv: '19 kg gasol — för större kök eller längre vistelse.', descriptionEn: '19 kg LPG — for larger kitchens or longer stays.', priceOre: 99900, // 999 kr sortOrder: 30, }, ]; for (const p of products) { await prisma.product.upsert({ where: { sku: p.sku }, update: { nameSv: p.nameSv, nameEn: p.nameEn, descriptionSv: p.descriptionSv, descriptionEn: p.descriptionEn, priceOre: p.priceOre, sortOrder: p.sortOrder, }, create: { ...p, active: true, vatBp: 2500 }, }); } console.log(`✓ Seeded ${products.length} products`); // -- Pickup slots (example: 3 days × 2 slots) -- const existing = await prisma.pickupSlot.count(); if (existing === 0) { const baseDay = new Date(); baseDay.setUTCHours(8, 0, 0, 0); // Place slots ~6 months out so they don't expire immediately. baseDay.setUTCMonth(baseDay.getUTCMonth() + 6); const slots = [ { offsetDays: 0, startH: 9, endH: 12, labelSv: 'Dag 1 — Förmiddag', labelEn: 'Day 1 — Morning' }, { offsetDays: 0, startH: 13, endH: 17, labelSv: 'Dag 1 — Eftermiddag', labelEn: 'Day 1 — Afternoon' }, { offsetDays: 1, startH: 9, endH: 12, labelSv: 'Dag 2 — Förmiddag', labelEn: 'Day 2 — Morning' }, { offsetDays: 1, startH: 13, endH: 17, labelSv: 'Dag 2 — Eftermiddag', labelEn: 'Day 2 — Afternoon' }, { offsetDays: 2, startH: 9, endH: 12, labelSv: 'Dag 3 — Förmiddag', labelEn: 'Day 3 — Morning' }, ]; for (const s of slots) { const startsAt = new Date(baseDay); startsAt.setUTCDate(baseDay.getUTCDate() + s.offsetDays); startsAt.setUTCHours(s.startH, 0, 0, 0); const endsAt = new Date(startsAt); endsAt.setUTCHours(s.endH, 0, 0, 0); await prisma.pickupSlot.create({ data: { labelSv: s.labelSv, labelEn: s.labelEn, startsAt, endsAt, capacity: 50, active: true, }, }); } console.log(`✓ Seeded ${slots.length} pickup slots`); } else { console.log(`• Pickup slots already exist (${existing}) — skipping`); } } main() .catch((e) => { console.error(e); process.exit(1); }) .finally(async () => { await prisma.$disconnect(); });