EventBuzz_Backend/scripts/setup-goa-7-8-microsite.js

257 lines
9.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Align Goa 7–8 Aug microsite with Goa 8–9 Aug format and publish.
*
* Usage:
* node scripts/setup-goa-7-8-microsite.js [--publish]
*/
const path = require('path');
require('dotenv').config({ path: path.join(__dirname, '..', '.env') });
const mongoose = require('mongoose');
const { connectDB } = require('../src/config/database');
const Event = require('../src/models/Event');
const Form = require('../src/models/Form');
const EventStaticMicrosite = require('../src/models/EventStaticMicrosite');
const MicrositeV2Template = require('../src/models/MicrositeV2Template');
const User = require('../src/models/User');
const { normalizeSubdomain, subdomainAvailability } = require('../src/utils/subdomainAvailability');
const { publishStaticMicrosite } = require('../src/utils/publishStaticMicrosite');
const SOURCE_SUBDOMAIN = 'novel2026-goa-8-9-aug';
const TARGET_EVENT_ID = '6a43e05fdc940a0d6e057f7b';
const TARGET_SUBDOMAIN = 'novel2026-goa-7-8-aug';
const SOURCE_EVENT_ID = '6a4cb75a7475c040cc6f2dd7';
const PUBLIC_WEB_BASE = (process.env.PUBLIC_WEB_BASE || 'https://web.eventbuzz.live').replace(/\/$/, '');
const TARGET = {
name: 'NOVEL Lung Health Summit - Goa - 7th & 8th August 2026',
shortPlace: 'Goa',
dateLabel: '7th & 8th August 2026',
dateShort: 'Aug 7–8, 2026',
countdownDate: '2026-08-07',
scheduleDay1: 'August 7, 2026',
scheduleDay2: 'August 8, 2026',
location: 'DoubleTree by Hilton Panjim, Goa',
mapQuery: 'DoubleTree+by+Hilton+Goa+Panaji,+Chimbel,+Goa',
};
function deepClone(obj) {
return JSON.parse(JSON.stringify(obj));
}
function replaceAllStrings(obj, replacements) {
if (obj == null) return obj;
if (typeof obj === 'string') {
let out = obj;
for (const [from, to] of replacements) {
if (from) out = out.split(from).join(to);
}
return out;
}
if (Array.isArray(obj)) return obj.map((item) => replaceAllStrings(item, replacements));
if (typeof obj === 'object') {
const out = {};
for (const [k, v] of Object.entries(obj)) out[k] = replaceAllStrings(v, replacements);
return out;
}
return obj;
}
async function findForm(eventId, type) {
return Form.findOne({ event: eventId, type, 'settings.isActive': { $ne: false } })
.sort({ createdAt: 1 })
.select('_id name')
.lean();
}
async function findContactForm(eventId) {
return Form.findOne({ event: eventId, type: 'other', name: /contact/i, 'settings.isActive': { $ne: false } })
.sort({ createdAt: 1 })
.select('_id name')
.lean();
}
async function findPublishUser() {
const platform = await User.findOne({ platform_admin: 'yes', isActive: { $ne: false } }).sort({ createdAt: 1 });
if (platform) return platform;
const superAdmin = await User.findOne({ role: 'super_admin' }).sort({ createdAt: 1 });
if (superAdmin) return superAdmin;
throw new Error('No user found for publish');
}
function applyTargetOverrides(config, targetEventId, forms, heroBannerUrl) {
const next = deepClone(config);
next.meta = next.meta || {};
next.meta.title = TARGET.name;
next.meta.eventId = String(targetEventId);
const regUrl = forms.registration
? `${PUBLIC_WEB_BASE}/event/${targetEventId}/form/${forms.registration._id}`
: `${PUBLIC_WEB_BASE}/event/${targetEventId}/register`;
const feedbackUrl = forms.feedback
? `${PUBLIC_WEB_BASE}/event/${targetEventId}/form/${forms.feedback._id}`
: null;
const sections = next.sections || {};
if (sections.hero) {
sections.hero.event_name = `${TARGET.shortPlace} - ${TARGET.dateLabel}`;
sections.hero.date_venue = TARGET.location;
if (heroBannerUrl && sections.hero.image) {
sections.hero.image.url = heroBannerUrl;
}
if (sections.hero.cta) {
sections.hero.cta.url = regUrl;
sections.hero.cta.target = '_blank';
}
if (sections.hero.countdown) {
sections.hero.countdown.date = TARGET.countdownDate;
}
}
if (sections.informationBar?.items) {
for (const item of sections.informationBar.items) {
if (item.label === 'Location') item.value = TARGET.location;
if (item.label === 'Date & Time') {
item.value = TARGET.dateShort;
if (item.calendar) {
item.calendar.title = TARGET.name;
item.calendar.start = TARGET.countdownDate;
item.calendar.end = '2026-08-08';
item.calendar.location = TARGET.location;
}
}
}
}
if (sections.event_schedule?.days) {
if (sections.event_schedule.days[0]) sections.event_schedule.days[0].date = TARGET.scheduleDay1;
if (sections.event_schedule.days[1]) sections.event_schedule.days[1].date = TARGET.scheduleDay2;
}
if (sections.map) {
sections.map.embedUrl = `https://maps.google.com/maps?q=${TARGET.mapQuery}&hl=en&z=15&output=embed`;
}
if (sections.contact && forms.contact) {
sections.contact.show = true;
sections.contact.formId = String(forms.contact._id);
sections.contact.apiBaseUrl = sections.contact.apiBaseUrl || 'https://api.eventbuzz.live/api';
}
if (sections.feedback && feedbackUrl) {
sections.feedback.url = feedbackUrl;
}
if (sections.footer?.links) {
for (const link of sections.footer.links) {
if (link.text && /register/i.test(link.text)) {
link.url = regUrl;
link.target = '_blank';
}
if (link.text && /feedback/i.test(link.text) && feedbackUrl) {
link.url = feedbackUrl;
link.target = '_blank';
}
}
}
next.sections = sections;
return next;
}
async function main() {
const shouldPublish = process.argv.includes('--publish');
await connectDB();
const targetEvent = await Event.findById(TARGET_EVENT_ID).lean();
if (!targetEvent) throw new Error(`Target event not found: ${TARGET_EVENT_ID}`);
const sourceSite = await EventStaticMicrosite.findOne({ subdomain: SOURCE_SUBDOMAIN }).populate('template').lean();
if (!sourceSite) throw new Error(`Source microsite not found: ${SOURCE_SUBDOMAIN}`);
const existingTarget = await EventStaticMicrosite.findOne({ event: TARGET_EVENT_ID });
const previousTarget = existingTarget ? deepClone(existingTarget.config) : null;
const heroBannerUrl = previousTarget?.sections?.hero?.image?.url || null;
const subdomain = normalizeSubdomain(TARGET_SUBDOMAIN);
const avail = await subdomainAvailability(subdomain, TARGET_EVENT_ID, existingTarget?._id?.toString());
if (!avail.available) throw new Error(avail.message || 'Subdomain not available');
const [registration, feedback, contact] = await Promise.all([
findForm(TARGET_EVENT_ID, 'registration'),
findForm(TARGET_EVENT_ID, 'feedback'),
findContactForm(TARGET_EVENT_ID),
]);
const sourceForms = await Promise.all([
findForm(SOURCE_EVENT_ID, 'registration'),
findForm(SOURCE_EVENT_ID, 'feedback'),
findContactForm(SOURCE_EVENT_ID),
]);
const replacements = [
[SOURCE_EVENT_ID, TARGET_EVENT_ID],
[sourceForms[0]?._id ? String(sourceForms[0]._id) : '', registration?._id ? String(registration._id) : ''],
[sourceForms[1]?._id ? String(sourceForms[1]._id) : '', feedback?._id ? String(feedback._id) : ''],
['NOVEL Lung Health Summit - Goa - 8th & 9th August 2026', TARGET.name],
['Goa - 8th & 9th August 2026', `${TARGET.shortPlace} - ${TARGET.dateLabel}`],
['Aug 8–9, 2026', TARGET.dateShort],
].filter(([from]) => from);
let config = replaceAllStrings(sourceSite.config, replacements);
config = applyTargetOverrides(config, TARGET_EVENT_ID, { registration, feedback, contact }, heroBannerUrl);
const user = shouldPublish ? await findPublishUser() : null;
const templateId = sourceSite.template?._id || sourceSite.template;
const payload = {
event: targetEvent._id,
organization: targetEvent.organization,
subdomain,
template: templateId,
config,
updatedBy: user?._id,
};
let siteDoc;
if (existingTarget) {
Object.assign(existingTarget, payload);
existingTarget.markModified('config');
await existingTarget.save();
siteDoc = existingTarget;
console.log(`Updated microsite ${existingTarget._id}`);
} else {
siteDoc = await EventStaticMicrosite.create({ ...payload, status: 'draft' });
console.log(`Created microsite ${siteDoc._id}`);
}
console.log(`Event: ${targetEvent.name}`);
console.log(`Subdomain: ${subdomain}`);
console.log(`Template: ${sourceSite.template?.slug || templateId}`);
console.log(`Reg form: ${registration?._id || '(none)'}`);
console.log(`Feedback: ${feedback?._id || '(none)'}`);
console.log(`Contact: ${contact?._id || '(none)'}`);
if (shouldPublish) {
const populated = await EventStaticMicrosite.findById(siteDoc._id).populate('template');
const result = await publishStaticMicrosite({
staticMicrosite: populated,
template: populated.template,
userId: user._id,
});
Object.assign(populated, result);
await populated.save();
console.log(`Published: ${result.publicUrl}`);
} else {
console.log('Saved as draft. Re-run with --publish to publish.');
}
await mongoose.disconnect();
}
main().catch((err) => {
console.error(err);
process.exit(1);
});