import mongoose from "mongoose"; import dotenv from "dotenv"; import { connectDB } from "../server/utils/mongoose.js"; import Event from "../server/models/event.js"; dotenv.config(); function generateSlug(title, startDate) { const titleSlug = title .toLowerCase() .replace(/[^a-z0-9]+/g, "-") .replace(/^-+|-+$/g, ""); if (startDate) { const d = new Date(startDate); const year = d.getUTCFullYear(); const month = String(d.getUTCMonth() + 1).padStart(2, "0"); const day = String(d.getUTCDate()).padStart(2, "0"); return `${year}-${month}-${day}-${titleSlug}`; } return titleSlug; } async function migrateEventSlugs() { try { await connectDB(); console.log("Connected to database\n"); const events = await Event.find({}).sort({ startDate: 1 }).lean(); console.log(`Found ${events.length} event(s) to process\n`); if (events.length === 0) { console.log("No events found."); return; } // Build new slugs first so uniqueness checks don't conflict with slugs // we're about to replace in the same run. const updates = []; const usedSlugs = new Set(); for (const event of events) { let baseSlug = generateSlug(event.title, event.startDate); let slug = baseSlug; let counter = 1; // Ensure slug is unique within this batch and across the DB // (excluding the current event's own existing slug) while ( usedSlugs.has(slug) || (await Event.findOne({ slug, _id: { $ne: event._id } }).lean()) ) { slug = `${baseSlug}-${counter}`; counter++; } usedSlugs.add(slug); updates.push({ event, oldSlug: event.slug, newSlug: slug }); } // Apply updates let changed = 0; let skipped = 0; for (const { event, oldSlug, newSlug } of updates) { if (oldSlug === newSlug) { console.log(` — ${event.title}`); console.log(` slug unchanged: ${newSlug}`); skipped++; } else { // Use updateOne to bypass the pre-save hook (avoids re-triggering slug generation) await Event.updateOne({ _id: event._id }, { $set: { slug: newSlug } }); console.log(` ✓ ${event.title}`); console.log(` ${oldSlug || "(none)"} → ${newSlug}`); changed++; } } console.log(`\nDone. ${changed} updated, ${skipped} already correct.`); } catch (error) { console.error("\nMigration failed:", error); process.exit(1); } finally { await mongoose.connection.close(); console.log("Database connection closed."); } } migrateEventSlugs();