/** * Copy legacy `Event.website` microsite configuration into a default `EventMicrosite` row per event. * Sets `sourcePageId` to the event's Website Builder `home` page when present. * * Run: cd backend && node scripts/migrate-event-website-to-microsites.js */ const path = require('path'); require('dotenv').config({ path: path.join(__dirname, '..', '.env') }); const mongoose = require('mongoose'); const Event = require(path.join(__dirname, '..', 'src', 'models', 'Event')); const EventPage = require(path.join(__dirname, '..', 'src', 'models', 'EventPage')); const EventMicrosite = require(path.join(__dirname, '..', 'src', 'models', 'EventMicrosite')); const User = require(path.join(__dirname, '..', 'src', 'models', 'User')); function normalizeFolder(raw) { return String(raw || '') .trim() .toLowerCase() .replace(/[^a-z0-9-]/g, ''); } function registrationFormObjectId(raw) { if (raw == null || raw === '') return undefined; const s = String(raw).trim(); if (!mongoose.Types.ObjectId.isValid(s)) return undefined; return new mongoose.Types.ObjectId(s); } function websiteHasMicrositeContent(w) { if (!w || typeof w !== 'object') return false; if (normalizeFolder(w.folder)) return true; if (w.enabled === true) return true; if (typeof w.micrositeHtml === 'string' && w.micrositeHtml.trim()) return true; if (Array.isArray(w.micrositeSections) && w.micrositeSections.length > 0) return true; if (w.registrationFormId != null && String(w.registrationFormId).trim()) return true; if (typeof w.title === 'string' && w.title.trim()) return true; if (typeof w.logo === 'string' && w.logo.trim()) return true; if (Array.isArray(w.banners) && w.banners.some(Boolean)) return true; if (typeof w.primaryColor === 'string' && w.primaryColor.trim()) return true; return false; } async function pickCreatedBy(organizationId) { const u = await User.findOne({ organization: organizationId }).sort({ createdAt: 1 }).select('_id').lean(); return u?._id || null; } async function uniquePublishFolder(base) { let candidate = base || 'microsite'; let n = 0; // eslint-disable-next-line no-await-in-loop while (await EventMicrosite.findOne({ publishFolder: candidate }).select('_id').lean()) { n += 1; candidate = `${base || 'microsite'}-${n}`; } return candidate; } async function run() { const uri = process.env.MONGODB_URI; if (!uri) { console.error('MONGODB_URI is not set'); process.exit(1); } await mongoose.connect(uri); const events = await Event.find({}).lean(); let created = 0; let skipped = 0; for (const ev of events) { const w = ev.website; if (!websiteHasMicrositeContent(w)) { skipped += 1; continue; } // eslint-disable-next-line no-await-in-loop const existing = await EventMicrosite.countDocuments({ event: ev._id }); if (existing > 0) { skipped += 1; continue; } // eslint-disable-next-line no-await-in-loop const createdBy = await pickCreatedBy(ev.organization); if (!createdBy) { console.warn(`Event ${ev._id}: no user found for organization — skipped`); skipped += 1; continue; } let publishFolder = normalizeFolder(w.folder); if (!publishFolder) { publishFolder = await uniquePublishFolder(`e${String(ev._id).slice(-8)}`); } else { // eslint-disable-next-line no-await-in-loop publishFolder = await uniquePublishFolder(publishFolder); } // eslint-disable-next-line no-await-in-loop const home = await EventPage.findOne({ event: ev._id, type: 'home' }).select('_id').lean(); const doc = new EventMicrosite({ event: ev._id, name: 'Default', publishFolder, enabled: !!w.enabled, logo: w.logo, banners: Array.isArray(w.banners) ? w.banners : [], favicon: w.favicon, title: w.title, seoDescription: w.seoDescription, description: w.description, keywords: Array.isArray(w.keywords) ? w.keywords : [], templateId: w.templateId, layoutTemplate: w.layoutTemplate || 'conference', micrositeSections: Array.isArray(w.micrositeSections) ? w.micrositeSections : [], primaryColor: w.primaryColor, accentColor: w.accentColor, fontPair: w.fontPair, registrationUrl: w.registrationUrl, registrationFormId: registrationFormObjectId(w.registrationFormId), micrositeHtml: w.micrositeHtml, sourcePageId: home?._id, createdBy, }); try { // eslint-disable-next-line no-await-in-loop await doc.save(); created += 1; console.log(`Created EventMicrosite ${doc._id} for event ${ev._id} (folder=${publishFolder})`); } catch (e) { console.error(`Event ${ev._id}: save failed`, e.message || e); } } console.log(`Done. Created ${created} microsite template(s), skipped ${skipped} event row(s) (no content or already had templates).`); await mongoose.disconnect(); } run().catch((e) => { console.error(e); process.exit(1); });