/* eslint-disable no-console */ const path = require("path"); const fs = require("fs"); require("dotenv").config({ path: path.join(__dirname, "..", ".env") }); if (fs.existsSync(path.join(__dirname, "..", "creds", ".env"))) { require("dotenv").config({ path: path.join(__dirname, "..", "creds", ".env"), }); } const bcrypt = require("bcryptjs"); const { PrismaClient, Role, UserStatus, ListingStatus, } = require("@prisma/client"); const { PrismaPg } = require("@prisma/adapter-pg"); const { Pool } = require("pg"); if (!process.env.DATABASE_URL) { console.error("DATABASE_URL is not set; cannot seed."); process.exit(1); } const prisma = new PrismaClient({ adapter: new PrismaPg( new Pool({ connectionString: process.env.DATABASE_URL }), ), }); const SAMPLE_SLUG = "saimaa-lakeside-cabin"; const DEFAULT_LOCALE = "en"; const SAMPLE_EMAIL = "host@lomavuokraus.fi"; const SAMPLE_IMAGE_DIR = path.join(__dirname, "..", "sampleimages"); function detectMimeType(fileName) { const ext = path.extname(fileName).toLowerCase(); if (ext === ".png") return "image/png"; if (ext === ".webp") return "image/webp"; if (ext === ".gif") return "image/gif"; return "image/jpeg"; } function loadSampleImage(fileName) { if (!fileName) return null; const filePath = path.join(SAMPLE_IMAGE_DIR, fileName); if (!fs.existsSync(filePath)) { console.warn(`Sample image missing: ${filePath}`); return null; } const data = fs.readFileSync(filePath); return { data, size: data.length, mimeType: detectMimeType(fileName), }; } async function main() { const adminEmail = process.env.ADMIN_EMAIL; const adminPassword = process.env.ADMIN_INITIAL_PASSWORD; function buildImageCreates(item) { const results = []; const coverFile = loadSampleImage(item.cover.file); if (coverFile || item.cover.url) { results.push({ data: coverFile?.data, mimeType: coverFile?.mimeType || (item.cover.url ? null : undefined), size: coverFile?.size ?? null, url: coverFile ? null : (item.cover.url ?? null), altText: item.cover.altText ?? null, order: 1, isCover: true, }); } item.images.forEach((img) => { const file = loadSampleImage(img.file); const hasSource = file || img.url; if (!hasSource) return; results.push({ data: file?.data, mimeType: file?.mimeType || (img.url ? null : undefined), size: file?.size ?? null, url: file ? null : (img.url ?? null), altText: img.altText ?? null, order: results.length + 1, isCover: false, }); }); return results; } if (!adminEmail || !adminPassword) { console.warn( "ADMIN_EMAIL or ADMIN_INITIAL_PASSWORD missing; admin user will not be seeded.", ); } let adminUser = null; if (adminEmail && adminPassword) { const adminHash = await bcrypt.hash(adminPassword, 12); adminUser = await prisma.user.upsert({ where: { email: adminEmail }, update: { passwordHash: adminHash, role: Role.ADMIN, status: UserStatus.ACTIVE, emailVerifiedAt: new Date(), approvedAt: new Date(), }, create: { email: adminEmail, passwordHash: adminHash, role: Role.ADMIN, status: UserStatus.ACTIVE, emailVerifiedAt: new Date(), approvedAt: new Date(), }, }); } const sampleHostHash = await bcrypt.hash("changeme-sample", 12); const owner = await prisma.user.upsert({ where: { email: SAMPLE_EMAIL }, update: { name: "Sample Host", phone: "+358401234567", role: "USER", passwordHash: sampleHostHash, status: UserStatus.ACTIVE, emailVerifiedAt: new Date(), approvedAt: new Date(), }, create: { email: SAMPLE_EMAIL, name: "Sample Host", phone: "+358401234567", role: "USER", passwordHash: sampleHostHash, status: UserStatus.ACTIVE, emailVerifiedAt: new Date(), approvedAt: new Date(), }, }); let listings = [ { slug: SAMPLE_SLUG, isSample: true, city: "Punkaharju", region: "South Karelia", country: "Finland", streetAddress: "Saimaan rantatie 12", addressNote: "Lakeside trail, 5 min from main road", latitude: 61.756, longitude: 29.328, maxGuests: 6, bedrooms: 3, beds: 4, bathrooms: 1, hasSauna: true, hasFireplace: true, hasWifi: true, hasAirConditioning: false, hasKitchen: true, hasDishwasher: false, hasWashingMachine: false, hasBarbecue: false, hasMicrowave: true, hasFreeParking: true, petsAllowed: false, byTheLake: true, evChargingAvailable: true, hasSkiPass: false, priceWeekdayEuros: 145, priceWeekendEuros: 165, cover: { file: "saimaa-lakeside-cabin-cover.jpg", url: "https://images.unsplash.com/photo-1505691938895-1758d7feb511?auto=format&fit=crop&w=1600&q=80", altText: "Lakeside cabin with sauna", }, images: [ { file: "saimaa-lakeside-cabin-sauna.jpg", url: "https://images.unsplash.com/photo-1505693416388-ac5ce068fe85?auto=format&fit=crop&w=1600&q=80", altText: "Wood-fired sauna by the lake", }, { file: "saimaa-lakeside-cabin-lounge.jpg", url: "https://images.unsplash.com/photo-1470246973918-29a93221c455?auto=format&fit=crop&w=1600&q=80", altText: "Living area with fireplace", }, ], titleEn: "Saimaa lakeside cabin with sauna", teaserEn: "Sauna, lake view, private dock, and cozy fireplace.", descEn: "Classic timber cabin right on Lake Saimaa. Wood-fired sauna, private dock, and a short forest walk to the nearest village. Perfect for slow weekends and midsummer gatherings.", titleFi: "Saimaan rantamökki saunalla", teaserFi: "Puusauna, järvinäköala, oma laituri ja takka.", descFi: "Perinteinen hirsimökki Saimaan rannalla. Puusauna, oma laituri ja lyhyt metsäreitti kylään. Sopii täydellisesti viikonloppuihin ja juhannukseen.", }, { slug: "helsinki-design-loft", isSample: true, city: "Helsinki", region: "Uusimaa", country: "Finland", streetAddress: "Katajanokanranta 4", addressNote: "Buzz 12B, elevator to 5th floor", latitude: 60.1675, longitude: 24.9529, maxGuests: 4, bedrooms: 1, beds: 2, bathrooms: 1, hasSauna: false, hasFireplace: false, hasWifi: true, hasAirConditioning: true, hasKitchen: true, hasDishwasher: false, hasWashingMachine: false, hasBarbecue: false, hasMicrowave: true, hasFreeParking: false, petsAllowed: false, byTheLake: false, evChargingAvailable: true, hasSkiPass: false, priceWeekdayEuros: 165, priceWeekendEuros: 185, cover: { file: "helsinki-design-loft-cover.jpg", url: "https://images.unsplash.com/photo-1505693415763-3bd1620f58c3?auto=format&fit=crop&w=1600&q=80", altText: "Modern loft living room", }, images: [ { file: "helsinki-design-loft-balcony.jpg", url: "https://images.unsplash.com/photo-1505691938895-1758d7feb511?auto=format&fit=crop&w=1600&q=80", altText: "Balcony view", }, { file: "helsinki-design-loft-bedroom.jpg", url: "https://images.unsplash.com/photo-1505691938895-1758d7feb511?auto=format&fit=crop&w=1600&q=80", altText: "Cozy bedroom", }, ], titleEn: "Helsinki design loft with AC", teaserEn: "Top-floor loft, AC, fast Wi-Fi, tram at the door.", descEn: "Bright design loft near the harbor. Air conditioning, fiber Wi-Fi, and views over Katajanokka. Perfect city break base.", titleFi: "Helsingin design-lofti ilmastoinnilla", teaserFi: "Ylimmän kerroksen loft, ilmastointi ja nopea netti.", descFi: "Valoisa loft Katajanokalla. Ilmastointi, kuitunetti ja näkymä merelle. Täydellinen kaupunkiloma.", }, { slug: "turku-riverside-apartment", isSample: true, city: "Turku", region: "Varsinais-Suomi", country: "Finland", streetAddress: "Läntinen Rantakatu 10", addressNote: "Self check-in lockbox", latitude: 60.4518, longitude: 22.2666, maxGuests: 3, bedrooms: 1, beds: 2, bathrooms: 1, hasSauna: false, hasFireplace: false, hasWifi: true, hasAirConditioning: false, hasKitchen: true, hasDishwasher: false, hasWashingMachine: false, hasBarbecue: false, hasMicrowave: true, hasFreeParking: true, petsAllowed: true, byTheLake: false, evChargingAvailable: false, hasSkiPass: false, priceWeekdayEuros: 110, priceWeekendEuros: 125, cover: { file: "turku-riverside-apartment-cover.jpg", url: "https://images.unsplash.com/photo-1522708323590-d24dbb6b0267?auto=format&fit=crop&w=1600&q=80", altText: "Apartment living room", }, images: [ { file: "turku-riverside-apartment-kitchen.jpg", url: "https://images.unsplash.com/photo-1505691938895-1758d7feb511?auto=format&fit=crop&w=1600&q=80", altText: "Kitchen area", }, ], titleEn: "Riverside apartment in Turku", teaserEn: "By the Aura river, pet-friendly, cozy base.", descEn: "Compact one-bedroom next to the Aura river. Cafés outside, pet-friendly, fiber internet for workations.", titleFi: "Aurajoen varrella, lemmikkiystävällinen", teaserFi: "Aurajoen kupeessa, lemmikit sallittu.", descFi: "Kompakti yksiö Aurajoen varrella. Kahvilat vieressä, lemmikit sallittu, kuitunetti etätöihin.", }, { slug: "rovaniemi-aurora-cabin", isSample: true, city: "Rovaniemi", region: "Lapland", country: "Finland", streetAddress: "Ounasjoenkuja 8", addressNote: "Snow tires required in winter", latitude: 66.5039, longitude: 25.7294, maxGuests: 5, bedrooms: 2, beds: 4, bathrooms: 1, hasSauna: true, hasFireplace: true, hasWifi: true, hasAirConditioning: false, hasKitchen: true, hasDishwasher: false, hasWashingMachine: false, hasBarbecue: false, hasMicrowave: false, hasFreeParking: true, petsAllowed: false, byTheLake: true, evChargingAvailable: true, evChargingOnSite: true, hasSkiPass: true, priceWeekdayEuros: 189, priceWeekendEuros: 215, cover: { file: "rovaniemi-aurora-cabin-cover.jpg", url: "https://images.unsplash.com/photo-1505693416388-ac5ce068fe85?auto=format&fit=crop&w=1600&q=80", altText: "Aurora cabin by the river", }, images: [ { file: "rovaniemi-aurora-cabin-lounge.jpg", url: "https://images.unsplash.com/photo-1470246973918-29a93221c455?auto=format&fit=crop&w=1600&q=80", altText: "Fireplace lounge", }, ], titleEn: "Aurora riverside cabin", teaserEn: "Sauna, fireplace, river views, EV charging.", descEn: "Timber cabin on the Ounasjoki riverside. Wood sauna, fireplace, glass lounge for auroras, free EV charging.", titleFi: "Revontulikämppä joen rannalla", teaserFi: "Sauna, takka, jokinäkymä ja ilmainen lataus.", descFi: "Hirsimökki Ounasjoen rannalla. Puusauna, takka ja lasikuisti revontulien katseluun, ilmainen sähköauton lataus.", }, { slug: "tampere-sauna-studio", isSample: true, city: "Tampere", region: "Pirkanmaa", country: "Finland", streetAddress: "Hämeenkatu 25", addressNote: "Key pickup from lobby", latitude: 61.4981, longitude: 23.7608, maxGuests: 2, bedrooms: 0, beds: 1, bathrooms: 1, hasSauna: true, hasFireplace: false, hasWifi: true, hasAirConditioning: true, hasKitchen: true, hasDishwasher: false, hasWashingMachine: false, hasBarbecue: false, hasMicrowave: true, hasFreeParking: false, petsAllowed: false, byTheLake: false, evChargingAvailable: false, hasSkiPass: false, priceWeekdayEuros: 95, priceWeekendEuros: 110, cover: { file: "tampere-sauna-studio-cover.jpg", url: "https://images.unsplash.com/photo-1505691938895-1758d7feb511?auto=format&fit=crop&w=1600&q=80", altText: "Studio interior", }, images: [ { file: "tampere-sauna-studio-sauna.jpg", url: "https://images.unsplash.com/photo-1505691938895-1758d7feb511?auto=format&fit=crop&w=1600&q=80", altText: "Private sauna", }, ], titleEn: "Tampere studio with private sauna", teaserEn: "City center, private sauna, AC and fiber.", descEn: "Compact studio on Hämeenkatu with private electric sauna, air conditioning, and fiber internet. Steps from tram.", titleFi: "Tampereen keskustastudio saunalla", teaserFi: "Yksityinen sauna, ilmastointi, kuitu.", descFi: "Kompakti studio Hämeenkadulla. Oma sähkösauna, ilmastointi ja kuitunetti. Ratikka vieressä.", }, { slug: "vaasa-seaside-villa", isSample: true, city: "Vaasa", region: "Ostrobothnia", country: "Finland", streetAddress: "Rantakatu 3", addressNote: "Parking for 3 cars", latitude: 63.096, longitude: 21.6158, maxGuests: 8, bedrooms: 4, beds: 6, bathrooms: 2, hasSauna: true, hasFireplace: true, hasWifi: true, hasAirConditioning: false, hasKitchen: true, hasDishwasher: false, hasWashingMachine: false, hasBarbecue: false, hasMicrowave: true, hasFreeParking: true, petsAllowed: true, byTheLake: true, evChargingAvailable: true, evChargingOnSite: true, hasSkiPass: true, priceWeekdayEuros: 245, priceWeekendEuros: 275, cover: { file: "vaasa-seaside-villa-cover.jpg", url: "https://images.unsplash.com/photo-1505691938895-1758d7feb511?auto=format&fit=crop&w=1600&q=80", altText: "Seaside villa deck", }, images: [ { file: "vaasa-seaside-villa-lounge.jpg", url: "https://images.unsplash.com/photo-1505691938895-1758d7feb511?auto=format&fit=crop&w=1600&q=80", altText: "Seaside villa lounge", }, ], titleEn: "Seaside villa in Vaasa", teaserEn: "Deck, sauna, pet-friendly, paid EV charging.", descEn: "Spacious villa on the coast with large deck, wood sauna, fireplace lounge. Pets welcome; paid EV charger on site.", titleFi: "Rantahuvila Vaasassa", teaserFi: "Terassi, sauna, lemmikit ok, maksullinen lataus.", descFi: "Tilava huvila meren rannalla, iso terassi, puusauna ja takkahuone. Lemmikit sallittu; maksullinen latauspiste.", }, { slug: "kuopio-lakeside-apartment", isSample: true, city: "Kuopio", region: "Northern Savonia", country: "Finland", streetAddress: "Satamakatu 7", addressNote: "Underground parking", latitude: 62.8924, longitude: 27.6783, maxGuests: 4, bedrooms: 2, beds: 3, bathrooms: 1, hasSauna: true, hasFireplace: false, hasWifi: true, hasAirConditioning: false, hasKitchen: true, hasDishwasher: false, hasWashingMachine: false, hasBarbecue: false, hasMicrowave: true, hasFreeParking: true, petsAllowed: false, byTheLake: true, evChargingAvailable: true, evChargingOnSite: true, hasSkiPass: true, priceWeekdayEuros: 129, priceWeekendEuros: 149, cover: { file: "kuopio-lakeside-apartment-cover.jpg", url: "https://images.unsplash.com/photo-1470246973918-29a93221c455?auto=format&fit=crop&w=1600&q=80", altText: "Lake view balcony", }, images: [ { file: "kuopio-lakeside-apartment-sauna.jpg", url: "https://images.unsplash.com/photo-1470246973918-29a93221c455?auto=format&fit=crop&w=1600&q=80", altText: "Apartment sauna", }, ], titleEn: "Kuopio lakeside apartment with sauna", teaserEn: "Balcony to Kallavesi, sauna, free EV charging.", descEn: "Two-bedroom apartment overlooking Lake Kallavesi. Glass balcony, electric sauna, underground parking with free EV charging.", titleFi: "Kuopion järvinäkymä ja sauna", teaserFi: "Parveke Kallavedelle, sauna, ilmainen lataus.", descFi: "Kaksio Kallaveden rannalla. Lasitettu parveke, sähkösauna, hallipaikka ja ilmainen sähköauton lataus.", }, { slug: "porvoo-river-loft", isSample: true, city: "Porvoo", region: "Uusimaa", country: "Finland", streetAddress: "Mannerheiminkatu 12", addressNote: "Historic building, stairs only", latitude: 60.3943, longitude: 25.6659, maxGuests: 2, bedrooms: 1, beds: 1, bathrooms: 1, hasSauna: false, hasFireplace: true, hasWifi: true, hasAirConditioning: false, hasKitchen: true, hasDishwasher: false, hasWashingMachine: false, hasBarbecue: false, hasMicrowave: true, hasFreeParking: false, petsAllowed: false, byTheLake: false, evChargingAvailable: false, hasSkiPass: false, priceWeekdayEuros: 99, priceWeekendEuros: 115, cover: { file: "porvoo-river-loft-cover.jpg", url: "https://images.unsplash.com/photo-1505691938895-1758d7feb511?auto=format&fit=crop&w=1600&q=80", altText: "Loft interior", }, images: [ { file: "porvoo-river-loft-fireplace.jpg", url: "https://images.unsplash.com/photo-1505691938895-1758d7feb511?auto=format&fit=crop&w=1600&q=80", altText: "Fireplace corner", }, ], titleEn: "Porvoo old town river loft", teaserEn: "Historic charm, fireplace, steps from river.", descEn: "Cozy loft in Porvoo old town. Brick walls, fireplace, and views toward the riverside warehouses.", titleFi: "Porvoon jokilofti", teaserFi: "Takka ja vanhan kaupungin tunnelma.", descFi: "Kotoisa loft Porvoon vanhassa kaupungissa. Tiiliseinät, takka ja näkymä jokirantaan.", }, { slug: "oulu-tech-apartment", isSample: true, city: "Oulu", region: "Northern Ostrobothnia", country: "Finland", streetAddress: "Technopolis 2", addressNote: "Smart lock entry", latitude: 65.0121, longitude: 25.4651, maxGuests: 2, bedrooms: 1, beds: 1, bathrooms: 1, hasSauna: false, hasFireplace: false, hasWifi: true, hasAirConditioning: true, hasKitchen: true, hasDishwasher: false, hasWashingMachine: false, hasBarbecue: false, hasMicrowave: true, hasFreeParking: true, petsAllowed: false, byTheLake: false, evChargingAvailable: true, evChargingOnSite: true, priceWeekdayEuros: 105, priceWeekendEuros: 120, cover: { file: "oulu-tech-apartment-cover.jpg", url: "https://images.unsplash.com/photo-1522708323590-d24dbb6b0267?auto=format&fit=crop&w=1600&q=80", altText: "Modern apartment", }, images: [ { file: "oulu-tech-apartment-desk.jpg", url: "https://images.unsplash.com/photo-1522708323590-d24dbb6b0267?auto=format&fit=crop&w=1600&q=80", altText: "Work desk in apartment", }, ], titleEn: "Smart apartment in Oulu", teaserEn: "AC, smart lock, free EV charging in garage.", descEn: "Modern one-bedroom near Technopolis. Air conditioning, smart lock, desk for work, garage with free EV chargers.", titleFi: "Moderni Oulun yksiö", teaserFi: "Ilmastointi, älylukko, ilmainen lataus.", descFi: "Moderni yksiö Technopoliksen lähellä. Ilmastointi, älylukko, työpiste ja ilmaiset latauspaikat hallissa.", }, { slug: "mariehamn-harbor-flat", isSample: true, city: "Mariehamn", region: "Åland", country: "Finland", streetAddress: "Hamngatan 5", addressNote: "Ferry terminal 10 min walk", latitude: 60.0973, longitude: 19.9348, maxGuests: 3, bedrooms: 1, beds: 2, bathrooms: 1, hasSauna: false, hasFireplace: false, hasWifi: true, hasAirConditioning: false, hasKitchen: true, hasDishwasher: false, hasWashingMachine: false, hasBarbecue: false, hasMicrowave: true, hasFreeParking: true, petsAllowed: false, byTheLake: true, evChargingAvailable: true, hasSkiPass: true, priceWeekdayEuros: 115, priceWeekendEuros: 130, cover: { file: "mariehamn-harbor-flat-cover.jpg", url: "https://images.unsplash.com/photo-1470246973918-29a93221c455?auto=format&fit=crop&w=1600&q=80", altText: "Harbor view", }, images: [ { file: "mariehamn-harbor-flat-living.jpg", url: "https://images.unsplash.com/photo-1470246973918-29a93221c455?auto=format&fit=crop&w=1600&q=80", altText: "Harbor-facing living room", }, ], titleEn: "Harbor flat in Mariehamn", teaserEn: "Walk to ferries, harbor views, paid EV nearby.", descEn: "Bright flat near the harbor. Walk to ferries and restaurants, harbor-facing balcony, paid EV charging at the public lot.", titleFi: "Satamahuoneisto Maarianhaminassa", teaserFi: "Satamanäkymä, kävely lautoille.", descFi: "Valoisa huoneisto sataman tuntumassa. Parveke satamaan, ravintolat lähellä, maksullinen lataus viereisellä parkkipaikalla.", }, ]; // Fill in any missing amenities/prices with reasonable defaults const randBool = (p = 0.5) => Math.random() < p; listings = listings.map((item) => { const weekdayPrice = item.priceWeekdayEuros ?? Math.round(Math.random() * (220 - 90) + 90); const evChargingOnSite = item.evChargingOnSite ?? randBool(0.15); const evChargingAvailable = item.evChargingAvailable ?? evChargingOnSite ?? randBool(0.4); return { ...item, priceWeekdayEuros: weekdayPrice, priceWeekendEuros: item.priceWeekendEuros ?? (weekdayPrice ? weekdayPrice + 15 : null), hasKitchen: item.hasKitchen ?? randBool(0.9), hasDishwasher: item.hasDishwasher ?? randBool(0.6), hasWashingMachine: item.hasWashingMachine ?? randBool(0.6), hasBarbecue: item.hasBarbecue ?? randBool(0.5), hasMicrowave: item.hasMicrowave ?? randBool(0.7), hasFreeParking: item.hasFreeParking ?? randBool(0.6), evChargingOnSite, evChargingAvailable, wheelchairAccessible: item.wheelchairAccessible ?? randBool(0.25), hasSkiPass: item.hasSkiPass ?? randBool(0.2), }; }); for (const item of listings) { const existing = await prisma.listingTranslation.findFirst({ where: { slug: item.slug }, select: { listingId: true }, }); const imageCreates = buildImageCreates(item); if (!existing) { const created = await prisma.listing.create({ data: { ownerId: owner.id, status: ListingStatus.PUBLISHED, approvedAt: new Date(), approvedById: adminUser ? adminUser.id : owner.id, isSample: item.isSample ?? false, country: item.country, region: item.region, city: item.city, streetAddress: item.streetAddress, addressNote: item.addressNote, latitude: item.latitude, longitude: item.longitude, maxGuests: item.maxGuests, bedrooms: item.bedrooms, beds: item.beds, bathrooms: item.bathrooms, hasSauna: item.hasSauna, hasFireplace: item.hasFireplace, hasWifi: item.hasWifi, hasAirConditioning: item.hasAirConditioning, hasKitchen: item.hasKitchen ?? false, hasDishwasher: item.hasDishwasher ?? false, hasWashingMachine: item.hasWashingMachine ?? false, hasBarbecue: item.hasBarbecue ?? false, hasMicrowave: item.hasMicrowave ?? false, hasFreeParking: item.hasFreeParking ?? false, petsAllowed: item.petsAllowed, byTheLake: item.byTheLake, evChargingAvailable: item.evChargingAvailable ?? item.evChargingOnSite ?? false, evChargingOnSite: item.evChargingOnSite ?? false, wheelchairAccessible: item.wheelchairAccessible ?? false, priceWeekdayEuros: item.priceWeekdayEuros, priceWeekendEuros: item.priceWeekendEuros, contactName: "Sample Host", contactEmail: SAMPLE_EMAIL, contactPhone: owner.phone, published: true, translations: { createMany: { data: [ { locale: "en", slug: item.slug, title: item.titleEn, teaser: item.teaserEn, description: item.descEn, }, { locale: "fi", slug: item.slug, title: item.titleFi, teaser: item.teaserFi, description: item.descFi, }, ], }, }, images: imageCreates.length ? { create: imageCreates } : undefined, }, }); console.log("Seeded listing:", created.id, item.slug); continue; } const listingId = existing.listingId; await prisma.listing.update({ where: { id: listingId }, data: { isSample: item.isSample ?? false, country: item.country, region: item.region, city: item.city, streetAddress: item.streetAddress, addressNote: item.addressNote, latitude: item.latitude, longitude: item.longitude, maxGuests: item.maxGuests, bedrooms: item.bedrooms, beds: item.beds, bathrooms: item.bathrooms, hasSauna: item.hasSauna, hasFireplace: item.hasFireplace, hasWifi: item.hasWifi, hasAirConditioning: item.hasAirConditioning, hasKitchen: item.hasKitchen ?? false, hasDishwasher: item.hasDishwasher ?? false, hasWashingMachine: item.hasWashingMachine ?? false, hasBarbecue: item.hasBarbecue ?? false, hasMicrowave: item.hasMicrowave ?? false, hasFreeParking: item.hasFreeParking ?? false, petsAllowed: item.petsAllowed, byTheLake: item.byTheLake, evChargingAvailable: item.evChargingAvailable ?? item.evChargingOnSite ?? false, evChargingOnSite: item.evChargingOnSite ?? false, wheelchairAccessible: item.wheelchairAccessible ?? false, priceWeekdayEuros: item.priceWeekdayEuros, priceWeekendEuros: item.priceWeekendEuros, contactName: "Sample Host", contactEmail: SAMPLE_EMAIL, contactPhone: owner.phone, published: true, status: ListingStatus.PUBLISHED, approvedAt: new Date(), }, }); await prisma.listingTranslation.upsert({ where: { slug_locale: { slug: item.slug, locale: "en" } }, create: { listingId, locale: "en", slug: item.slug, title: item.titleEn, teaser: item.teaserEn, description: item.descEn, }, update: { title: item.titleEn, teaser: item.teaserEn, description: item.descEn, }, }); await prisma.listingTranslation.upsert({ where: { slug_locale: { slug: item.slug, locale: "fi" } }, create: { listingId, locale: "fi", slug: item.slug, title: item.titleFi, teaser: item.teaserFi, description: item.descFi, }, update: { title: item.titleFi, teaser: item.teaserFi, description: item.descFi, }, }); await prisma.listingImage.deleteMany({ where: { listingId } }); if (imageCreates.length) { await prisma.listingImage.createMany({ data: imageCreates.map((img) => ({ ...img, listingId, })), }); } console.log("Updated listing:", item.slug); } console.log("Seed completed for sample listings."); } main() .catch((e) => { console.error(e); process.exit(1); }) .finally(async () => { await prisma.$disconnect(); });