const mongoose = require('mongoose'); const { migrateCompanies } = require('./migrate-companies'); const { migrateMessages } = require('./migrate-messages'); const { recreateTestUser } = require('./recreate-test-user'); require('dotenv').config(); const mongoUrl = process.env.MONGODB_URI || 'mongodb://admin:password@localhost:27017/procurement_db?authSource=admin'; // Migration history model const migrationSchema = new mongoose.Schema({ name: { type: String, unique: true, required: true }, executedAt: { type: Date, default: Date.now }, status: { type: String, enum: ['completed', 'failed'], default: 'completed' }, message: String }, { collection: 'migrations' }); const Migration = mongoose.model('Migration', migrationSchema); const migrations = [ { name: 'migrate-companies', fn: migrateCompanies }, { name: 'migrate-messages', fn: migrateMessages }, { name: 'recreate-test-user', fn: recreateTestUser } ]; async function runMigrations(shouldCloseConnection = false) { let mongooseConnected = false; try { console.log('\n' + '='.repeat(60)); console.log('šŸš€ Starting Database Migrations'); console.log('='.repeat(60) + '\n'); // Only connect if not already connected if (mongoose.connection.readyState === 0) { console.log('[Migrations] Connecting to MongoDB...'); await mongoose.connect(mongoUrl, { useNewUrlParser: true, useUnifiedTopology: true, serverSelectionTimeoutMS: 5000, connectTimeoutMS: 5000, }); mongooseConnected = true; console.log('[Migrations] āœ… Connected to MongoDB\n'); } else { console.log('[Migrations] āœ… Using existing MongoDB connection\n'); } for (const migration of migrations) { console.log(`[${migration.name}] Starting...`); try { // Check if already executed const existing = await Migration.findOne({ name: migration.name }); if (existing) { console.log(`[${migration.name}] ā„¹ļø Already executed at: ${existing.executedAt.toISOString()}`); console.log(`[${migration.name}] Status: ${existing.status}`); if (existing.message) console.log(`[${migration.name}] Message: ${existing.message}`); console.log(''); continue; } // Run migration await migration.fn(); // Record successful migration await Migration.create({ name: migration.name, status: 'completed', message: `${migration.name} executed successfully` }); console.log(`[${migration.name}] āœ… Completed and recorded\n`); } catch (error) { console.error(`[${migration.name}] āŒ Error: ${error.message}\n`); // Record failed migration try { await Migration.create({ name: migration.name, status: 'failed', message: error.message }); } catch (recordErr) { // Ignore if we can't record the failure } } } console.log('='.repeat(60)); console.log('āœ… All migrations processed'); console.log('='.repeat(60) + '\n'); } catch (error) { console.error('\nāŒ Fatal migration error:', error.message); console.error(error); if (shouldCloseConnection) { process.exit(1); } } finally { // Only close connection if we created it and requested to close if (mongooseConnected && shouldCloseConnection) { await mongoose.connection.close(); console.log('[Migrations] Disconnected from MongoDB\n'); } } } module.exports = { runMigrations, Migration }; // Run directly if called as script if (require.main === module) { runMigrations(true).catch(err => { console.error('Migration failed:', err); process.exit(1); }); }