Files
3dtours/backend/scripts/checkIntegrity.js
T

97 lines
4.0 KiB
JavaScript

const mongoose = require('mongoose');
const fs = require('fs');
const path = require('path');
const connectDB = require('../config/db');
const Asset = require('../models/Asset');
const Scene = require('../models/Scene');
/**
* Script kiểm tra tính toàn vẹn dữ liệu
* So sánh sự đồng bộ giữa Database (MongoDB) và Filesystem (thư mục uploads)
*/
const checkIntegrity = async () => {
try {
console.log('=== KHỞI CHẠY KIỂM TRA TÍNH TOÀN VẸN HỆ THỐNG ===');
await connectDB();
const assets = await Asset.find().lean();
const scenes = await Scene.find().lean();
const uploadDir = path.resolve(__dirname, '../uploads');
const tempDir = path.resolve(uploadDir, 'temp');
const dbFilePaths = new Set();
const brokenAssets = [];
const assetIdsInDB = new Set(assets.map(a => a._id.toString()));
console.log(`\n1. Kiểm tra Database -> Filesystem (${assets.length} Assets):`);
for (const asset of assets) {
if (asset.filePath) {
const absolutePath = path.resolve(asset.filePath);
dbFilePaths.add(absolutePath);
if (!fs.existsSync(absolutePath)) {
brokenAssets.push({
id: asset._id,
path: asset.filePath,
user: asset.uploadedBy
});
}
}
}
if (brokenAssets.length > 0) {
console.error(` [!] CẢNH BÁO: Tìm thấy ${brokenAssets.length} bản ghi mất file vật lý:`);
brokenAssets.forEach(ba => console.error(` - Asset ID: ${ba.id} | Path: ${ba.path}`));
} else {
console.log(' [✓] Tất cả bản ghi Asset đều có file vật lý tương ứng.');
}
console.log(`\n2. Kiểm tra Filesystem -> Database:`);
let strayFilesCount = 0;
if (fs.existsSync(uploadDir)) {
const files = fs.readdirSync(uploadDir);
files.forEach(file => {
const fullPath = path.join(uploadDir, file);
// Bỏ qua thư mục temp và các thư mục con khác
if (fs.lstatSync(fullPath).isFile() && !file.startsWith('.')) {
if (!dbFilePaths.has(path.resolve(fullPath))) {
console.warn(` [?] File không có bản ghi DB: ${file}`);
strayFilesCount++;
}
}
});
}
console.log(` [i] Tìm thấy ${strayFilesCount} file mồ côi (không được quản lý bởi Asset).`);
console.log(`\n3. Kiểm tra Liên kết Scene -> Asset (${scenes.length} Scenes):`);
let brokenScenesCount = 0;
for (const scene of scenes) {
const assetId = scene.assetId?.toString();
if (assetId && !assetIdsInDB.has(assetId)) {
console.error(` [!] Scene "${scene.name || scene.title}" (ID: ${scene._id}) trỏ tới Asset ID không tồn tại: ${assetId}`);
brokenScenesCount++;
}
}
if (brokenScenesCount === 0) {
console.log(' [✓] Tất cả các Scene đều liên kết với Asset hợp lệ.');
} else {
console.error(` [!] Tìm thấy ${brokenScenesCount} Scene bị hỏng liên kết.`);
}
console.log('\n=== TỔNG KẾT ===');
console.log(`- Bản ghi Asset lỗi: ${brokenAssets.length}`);
console.log(`- File mồ côi: ${strayFilesCount}`);
console.log(`- Scene hỏng liên kết: ${brokenScenesCount}`);
console.log('================================================');
mongoose.connection.close();
process.exit(0);
} catch (err) {
console.error('Lỗi nghiêm trọng khi kiểm tra:', err.message);
if (mongoose.connection) mongoose.connection.close();
process.exit(1);
}
};
checkIntegrity();