const fs = require('fs') const path = require('path') const root = path.resolve(__dirname, '..') const fixtureDir = path.join(root, 'scripts', 'fixtures') const reportDir = path.join(root, 'reports') const sourceFile = process.env.MIGRATION_SOURCE || path.join(fixtureDir, 'opendb-news-articles.json') const outputFile = path.join(reportDir, 'cms-migration-dry-run.json') function readRows(file) { if (!fs.existsSync(file)) return [] const value = JSON.parse(fs.readFileSync(file, 'utf8')) if (!Array.isArray(value)) throw new Error(`fixture must be an array: ${file}`) return value } function toDelta(content) { if (content && typeof content === 'object' && Array.isArray(content.ops)) return content if (typeof content !== 'string' || !content) return { ops: [] } return { ops: [{ insert: content }, { insert: '\n' }] } } function mapArticle(row) { const thumbnail = Array.isArray(row.thumbnail) ? row.thumbnail : row.avatar ? [row.avatar] : [] return { _id: row._id, title: row.title || '', excerpt: row.excerpt || '', content: toDelta(row.content), category_id: row.category_id || '', user_id: row.user_id || '', thumbnail, article_status: Number.isInteger(row.article_status) ? row.article_status : 0, view_count: Number(row.view_count || 0), like_count: Number(row.like_count || 0), comment_status: Number(row.comment_status || 0), comment_count: Number(row.comment_count || 0), publish_date: row.publish_date || row.create_date || null, source_id: row._id, migration_source: 'opendb-news-articles' } } function main() { const source = readRows(sourceFile) const seen = new Set() const rows = [] const conflicts = [] for (const row of source) { if (!row || !row._id) { conflicts.push({ reason: 'missing _id', row }) continue } if (seen.has(row._id)) { conflicts.push({ reason: 'duplicate _id', id: row._id }) continue } seen.add(row._id) rows.push(mapArticle(row)) } const report = { mode: 'dry-run', source: path.relative(root, sourceFile).replace(/\\/g, '/'), target: 'uni-cms-articles', generatedAt: new Date().toISOString(), summary: { source: source.length, mapped: rows.length, conflicts: conflicts.length }, conflicts, rows } fs.mkdirSync(reportDir, { recursive: true }) fs.writeFileSync(outputFile, JSON.stringify(report, null, 2) + '\n') console.log(JSON.stringify(report.summary)) } main()