require('dotenv').config(); const fs = require('fs').promises; const path = require('path'); const connectDB = require('../config/database'); const Travel = require('../models/travel'); const mongoose = require('mongoose'); /** * Migration: travel * Migrate Travel data từ travel.json * Created: 2025-12-13 */ async function migrate() { try { // Kết nối database await connectDB(); console.log('Starting migration: travel...'); // Đọc file travel.json const travelJsonPath = path.join(__dirname, '../data/travel.json'); console.log('Reading JSON file from:', travelJsonPath); const travelData = JSON.parse(await fs.readFile(travelJsonPath, 'utf8')); console.log('Travel data loaded successfully'); console.log('Data structure keys:', Object.keys(travelData)); // Thực hiện migration await migrateTravelData(travelData); console.log('Travel migration completed successfully!'); await mongoose.disconnect(); process.exit(0); } catch (error) { console.error('Migration error:', error); process.exit(1); } } /** * Custom migration logic cho travel data */ async function migrateTravelData(travelData) { try { console.log('Starting custom migration logic...'); // 1. Kiểm tra dữ liệu cũ const existingTravel = await Travel.findOne({}); if (existingTravel) { console.log(`Found existing travel document: ${existingTravel._id}`); console.log('Deleting existing travel data...'); await Travel.deleteMany({}); console.log('Cleared existing travel data'); } // 2. Chuyển đổi locations thành blog content blocks const contentBlocks = []; // If travelData already has posts (blog format), use the first post if (Array.isArray(travelData.posts) && travelData.posts.length > 0) { const firstPost = travelData.posts[0]; if (firstPost.content && Array.isArray(firstPost.content.blocks)) { contentBlocks.push(...firstPost.content.blocks); } } else { // Thêm general description (legacy format) if (travelData.general) { contentBlocks.push({ type: 'paragraph', data: { text: travelData.general.description } }); // Thêm additional info như conclusion if (travelData.general.additionalInfo) { contentBlocks.push({ type: 'conclusion', data: { text: travelData.general.additionalInfo, callToAction: { text: '', link: '' } } }); } } // Chuyển đổi từng location thành blog blocks if (travelData.locations && Array.isArray(travelData.locations)) { travelData.locations.forEach(location => { // Header cho location contentBlocks.push({ type: 'header', data: { text: location.title, level: 2 } }); // Address information const addressItems = []; if (location.address) { if (location.address.name) { addressItems.push(`Name: ${location.address.name}`); } if (location.address.line2) { addressItems.push(location.address.line2); } if (location.address.street) { addressItems.push(`Street: ${location.address.street}`); } if (location.address.postalCode && location.address.city) { const country = location.address.country ? `, ${location.address.country}` : ''; addressItems.push(`Location: ${location.address.postalCode} ${location.address.city}${country}`); } if (location.address.googleMapsUrl) { addressItems.push(`Google Maps: View on Map`); } } if (addressItems.length > 0) { contentBlocks.push({ type: 'list', data: { style: 'unordered', items: addressItems } }); } // Address note as conclusion if (location.address?.note) { contentBlocks.push({ type: 'conclusion', data: { text: location.address.note, callToAction: { text: '', link: '' } } }); } // Contact information const contactItems = []; if (location.contact) { if (location.contact.email) { contactItems.push(`Email: ${location.contact.email}`); } if (location.contact.phone) { contactItems.push(`Phone: ${location.contact.phone}`); } } if (contactItems.length > 0) { contentBlocks.push({ type: 'paragraph', data: { text: 'Contact Information:' } }); contentBlocks.push({ type: 'list', data: { style: 'unordered', items: contactItems } }); } // Schedule information const scheduleItems = []; if (location.schedule) { if (location.schedule.arrival) { scheduleItems.push(`Arrival: ${location.schedule.arrival}`); } if (location.schedule.departure) { scheduleItems.push(`Departure: ${location.schedule.departure}`); } } if (scheduleItems.length > 0) { contentBlocks.push({ type: 'paragraph', data: { text: 'Schedule:' } }); contentBlocks.push({ type: 'list', data: { style: 'unordered', items: scheduleItems } }); } }); } } // 3. Tạo document mới cho travel const travelDocument = new Travel({ hero: { title: travelData.hero?.title || 'Travel Information', backgroundImage: travelData.hero?.backgroundImage || '' }, page: { title: travelData.page?.title || travelData.general?.title || 'Go and Grow Camp Travel Information', description: travelData.page?.description || travelData.general?.description || '', year: travelData.page?.year || travelData.pageYear || undefined, metadata: { title: 'Travel Guide - Go and Grow Camp', description: 'Everything you need to know about traveling to our camps' } }, content: { blocks: contentBlocks }, enableScrollspy: true, lastUpdated: new Date() }); // 4. Lưu vào database await travelDocument.save(); console.log('Travel document saved successfully'); // 5. Log thông tin console.log(`Created travel document with ID: ${travelDocument._id}`); console.log(`Hero title: ${travelDocument.hero.title}`); console.log(`Page title: ${travelDocument.page.title}`); console.log(`Content blocks count: ${travelDocument.content.blocks.length}`); console.log(`Converted ${travelData.locations?.length || 0} locations to blog blocks`); } catch (error) { console.error('Error in migrateTravelData:', error); throw error; } } /** * Hàm backup data trước khi migration */ async function backupExistingData() { try { console.log('Creating backup of existing travel data...'); const existingTravel = await Travel.find({}); if (existingTravel.length > 0) { const backupPath = path.join(__dirname, '../backups/travel-backup-' + Date.now() + '.json'); // Tạo thư mục backup nếu chưa có await fs.mkdir(path.dirname(backupPath), { recursive: true }); await fs.writeFile(backupPath, JSON.stringify(existingTravel, null, 2)); console.log(`Backup created at: ${backupPath}`); } } catch (error) { console.error('Backup error:', error); } } // Chạy migration nếu được gọi trực tiếp if (require.main === module) { migrate(); } module.exports = { migrate, migrateTravelData };