feat(B批收尾): B1门禁可信/B7-1菜单环防护/B2空值守卫/B7-2分页/B7-3字段清洗/B3空态/B4索引key/B5-3 comment三集合选A新建schema(漂移清零)/B6清理+admin配置+changelog
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
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()
|
||||
Reference in New Issue
Block a user