257 lines
9.0 KiB
JavaScript
257 lines
9.0 KiB
JavaScript
/**
|
||
* 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);
|
||
});
|