#!/usr/bin/env node // One-time migration: copy SourceText and Slide from source cluster to target (APG5604) const mongoose = require('mongoose'); const SourceText = require('./models/SourceText'); const Slide = require('./models/Slide'); const SOURCE_URI = process.env.SOURCE_MONGODB_URI || 'mongodb+srv://nothingyu:wSg3lbO1PkHiRMq9@sandbox.ecysggv.mongodb.net/test?retryWrites=true&w=majority&appName=sandbox'; const TARGET_URI = process.env.MONGODB_URI || process.env.TARGET_MONGODB_URI || 'mongodb+srv://nothingyu_db_user:zjxVXtaIfUVBesdt@apg5604.tdavbvz.mongodb.net/?retryWrites=true&w=majority&appName=APG5604'; async function fetchAll(conn, modelName) { const docs = await conn.connection.db.collection(modelName.toLowerCase() + 's').find({}).toArray(); return docs; } async function upsertAll(conn, collectionName, docs) { if (!Array.isArray(docs) || docs.length === 0) return { inserted: 0, updated: 0 }; const col = conn.connection.db.collection(collectionName); let inserted = 0; let updated = 0; for (const doc of docs) { const _id = doc._id; // Remove _id to allow upsert by _id await col.updateOne({ _id }, { $set: { ...doc } }, { upsert: true }); } // Rough counts inserted = docs.length; return { inserted, updated }; } async function main() { console.log('Starting migration...'); console.log('Source:', SOURCE_URI.replace(/:[^@]+@/, ':***@')); console.log('Target:', TARGET_URI.replace(/:[^@]+@/, ':***@')); const source = await mongoose.createConnection(SOURCE_URI, { maxPoolSize: 5 }).asPromise(); const target = await mongoose.createConnection(TARGET_URI, { maxPoolSize: 5 }).asPromise(); try { // Slides const slideDocs = await source.db.collection('slides').find({}).toArray(); console.log('Slides to migrate:', slideDocs.length); const slideResult = await upsertAll({ connection: { db: target.db } }, 'slides', slideDocs); console.log('Slides migrated:', slideResult.inserted); // SourceText (tutorial + weekly-practice) const stDocs = await source.db.collection('sourcetexts').find({ category: { $in: ['tutorial', 'weekly-practice'] } }).toArray(); console.log('SourceTexts to migrate:', stDocs.length); const stResult = await upsertAll({ connection: { db: target.db } }, 'sourcetexts', stDocs); console.log('SourceTexts migrated:', stResult.inserted); // Optional: Week briefs if used const briefsExists = await source.db.listCollections({ name: 'weekbriefs' }).hasNext(); if (briefsExists) { const wbDocs = await source.db.collection('weekbriefs').find({}).toArray(); console.log('WeekBriefs to migrate:', wbDocs.length); await upsertAll({ connection: { db: target.db } }, 'weekbriefs', wbDocs); } console.log('Migration completed successfully.'); } catch (e) { console.error('Migration failed:', e); process.exitCode = 1; } finally { await source.close(); await target.close(); } } main();