feat: 添加MSW模拟服务和数据源集成
refactor: 重构页面组件移除冗余Layout组件 feat: 实现WebSocket和事件总线系统 feat: 添加队列和调度系统 docs: 更新架构文档和服务映射 style: 清理重复接口定义使用数据源 chore: 更新依赖项配置 feat: 添加运行时系统和领域引导 ci: 配置ESLint边界检查规则 build: 添加Redis和WebSocket依赖 test: 添加MSW浏览器环境入口 perf: 优化数据获取逻辑使用统一数据源 fix: 修复类型定义和状态管理问题
This commit is contained in:
421
scripts/deployment-check.js
Normal file
421
scripts/deployment-check.js
Normal file
@@ -0,0 +1,421 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const { execSync } = require('child_process');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const COLORS = {
|
||||
reset: '\x1b[0m',
|
||||
bright: '\x1b[1m',
|
||||
red: '\x1b[31m',
|
||||
green: '\x1b[32m',
|
||||
yellow: '\x1b[33m',
|
||||
blue: '\x1b[34m',
|
||||
magenta: '\x1b[35m',
|
||||
cyan: '\x1b[36m',
|
||||
};
|
||||
|
||||
function log(message, color = COLORS.reset) {
|
||||
console.log(`${color}${message}${COLORS.reset}`);
|
||||
}
|
||||
|
||||
function logStep(step, message) {
|
||||
console.log(`\n${COLORS.cyan}[${step}]${COLORS.reset} ${message}`);
|
||||
}
|
||||
|
||||
function logSuccess(message) {
|
||||
console.log(`${COLORS.green}✅${COLORS.reset} ${message}`);
|
||||
}
|
||||
|
||||
function logError(message) {
|
||||
console.log(`${COLORS.red}❌${COLORS.reset} ${message}`);
|
||||
}
|
||||
|
||||
function logWarning(message) {
|
||||
console.log(`${COLORS.yellow}⚠️${COLORS.reset} ${message}`);
|
||||
}
|
||||
|
||||
function executeCommand(command, description) {
|
||||
try {
|
||||
logStep('EXEC', description);
|
||||
const result = execSync(command, {
|
||||
encoding: 'utf8',
|
||||
stdio: 'inherit'
|
||||
});
|
||||
logSuccess(description);
|
||||
return true;
|
||||
} catch (error) {
|
||||
logError(`${description} failed: ${error.message}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function checkFileExists(filePath, description) {
|
||||
try {
|
||||
const exists = fs.existsSync(filePath);
|
||||
if (exists) {
|
||||
logSuccess(`${description} exists`);
|
||||
} else {
|
||||
logError(`${description} not found`);
|
||||
}
|
||||
return exists;
|
||||
}
|
||||
}
|
||||
|
||||
function checkDirectoryStructure() {
|
||||
logStep(1, 'Checking Directory Structure');
|
||||
|
||||
const requiredDirectories = [
|
||||
'server/src',
|
||||
'dashboard/src',
|
||||
'client/src',
|
||||
'extension/src',
|
||||
'docs',
|
||||
'.trae/rules'
|
||||
];
|
||||
|
||||
let allExist = true;
|
||||
requiredDirectories.forEach(dir => {
|
||||
const exists = checkFileExists(dir, `Directory ${dir}`);
|
||||
if (!exists) allExist = false;
|
||||
});
|
||||
|
||||
return allExist;
|
||||
}
|
||||
|
||||
function checkConfigurationFiles() {
|
||||
logStep(2, 'Checking Configuration Files');
|
||||
|
||||
const requiredConfigs = [
|
||||
'server/package.json',
|
||||
'dashboard/package.json',
|
||||
'client/package.json',
|
||||
'extension/package.json',
|
||||
'server/tsconfig.json',
|
||||
'dashboard/tsconfig.json',
|
||||
'server/.eslintrc.js'
|
||||
];
|
||||
|
||||
let allExist = true;
|
||||
requiredConfigs.forEach(config => {
|
||||
const exists = checkFileExists(config, `Config ${config}`);
|
||||
if (!exists) allExist = false;
|
||||
});
|
||||
|
||||
return allExist;
|
||||
}
|
||||
|
||||
function checkDatabaseSchema() {
|
||||
logStep(3, 'Checking Database Schema');
|
||||
|
||||
const schemaFile = 'server/src/database/DatabaseSchema.ts';
|
||||
const exists = checkFileExists(schemaFile, 'Database Schema');
|
||||
|
||||
if (exists) {
|
||||
const schema = require(path.join(process.cwd(), schemaFile));
|
||||
|
||||
const requiredTables = [
|
||||
'cf_product',
|
||||
'cf_order',
|
||||
'cf_customer',
|
||||
'cf_tenant',
|
||||
'cf_shop',
|
||||
'cf_invoice',
|
||||
'cf_settlement'
|
||||
];
|
||||
|
||||
let allTablesExist = true;
|
||||
requiredTables.forEach(table => {
|
||||
if (schema.tables && schema.tables[table]) {
|
||||
logSuccess(`Table ${table} exists in schema`);
|
||||
} else {
|
||||
logError(`Table ${table} missing from schema`);
|
||||
allTablesExist = false;
|
||||
}
|
||||
});
|
||||
|
||||
return allTablesExist;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkCoreServices() {
|
||||
logStep(4, 'Checking Core Services');
|
||||
|
||||
const requiredServices = [
|
||||
'server/src/core/auth/RBACEngine.ts',
|
||||
'server/src/core/cache/RedisService.ts',
|
||||
'server/src/core/engine/CoreEngineService.ts',
|
||||
'server/src/core/runtime/DomainEventBus.ts',
|
||||
'server/src/core/telemetry/AlertService.ts'
|
||||
];
|
||||
|
||||
let allExist = true;
|
||||
requiredServices.forEach(service => {
|
||||
const exists = checkFileExists(service, `Service ${service}`);
|
||||
if (!exists) allExist = false;
|
||||
});
|
||||
|
||||
return allExist;
|
||||
}
|
||||
|
||||
function checkAPIControllers() {
|
||||
logStep(5, 'Checking API Controllers');
|
||||
|
||||
const requiredControllers = [
|
||||
'server/src/api/controllers/AuthController.ts',
|
||||
'server/src/api/controllers/ProductController.ts',
|
||||
'server/src/api/controllers/OrderController.ts',
|
||||
'server/src/api/controllers/PricingController.ts',
|
||||
'server/src/api/controllers/BillingController.ts',
|
||||
'server/src/api/controllers/AnalyticsController.ts'
|
||||
];
|
||||
|
||||
let allExist = true;
|
||||
requiredControllers.forEach(controller => {
|
||||
const exists = checkFileExists(controller, `Controller ${controller}`);
|
||||
if (!exists) allExist = false;
|
||||
});
|
||||
|
||||
return allExist;
|
||||
}
|
||||
|
||||
function checkFrontendPages() {
|
||||
logStep(6, 'Checking Frontend Pages');
|
||||
|
||||
const requiredPages = [
|
||||
'dashboard/src/pages/DashboardPage.tsx',
|
||||
'dashboard/src/pages/Product/index.tsx',
|
||||
'dashboard/src/pages/Orders/index.tsx',
|
||||
'dashboard/src/pages/TaskCenter/index.tsx',
|
||||
'dashboard/src/pages/Compliance/index.tsx',
|
||||
'dashboard/src/pages/Settings/SystemSettings.tsx',
|
||||
'dashboard/src/pages/Analytics/index.tsx',
|
||||
'dashboard/src/pages/Reports/index.tsx'
|
||||
];
|
||||
|
||||
let allExist = true;
|
||||
requiredPages.forEach(page => {
|
||||
const exists = checkFileExists(page, `Page ${page}`);
|
||||
if (!exists) allExist = false;
|
||||
});
|
||||
|
||||
return allExist;
|
||||
}
|
||||
|
||||
function checkDocumentation() {
|
||||
logStep(7, 'Checking Documentation');
|
||||
|
||||
const requiredDocs = [
|
||||
'docs/00_Business/Business_Blueprint.md',
|
||||
'docs/00_Business/Business_ClosedLoops.md',
|
||||
'docs/01_Architecture/System_Architecture.md',
|
||||
'docs/01_Architecture/SERVICE_MAP.md',
|
||||
'docs/01_Architecture/STATE_MACHINE.md',
|
||||
'docs/02_Backend/API_Specs/Data_API_Specs.md',
|
||||
'docs/03_Frontend/Frontend_Design.md',
|
||||
'docs/05_AI/AI_Strategy.md',
|
||||
'.trae/rules/project-specific-rules.md'
|
||||
];
|
||||
|
||||
let allExist = true;
|
||||
requiredDocs.forEach(doc => {
|
||||
const exists = checkFileExists(doc, `Documentation ${doc}`);
|
||||
if (!exists) allExist = false;
|
||||
});
|
||||
|
||||
return allExist;
|
||||
}
|
||||
|
||||
function checkSecurityConfiguration() {
|
||||
logStep(8, 'Checking Security Configuration');
|
||||
|
||||
const securityFiles = [
|
||||
'server/src/core/guards/rbac.guard.ts',
|
||||
'server/src/core/guards/service.guard.ts',
|
||||
'server/src/core/guards/sla.guard.ts',
|
||||
'server/src/core/security/SecurityProfilingService.ts',
|
||||
'server/src/core/security/DataComplianceService.ts'
|
||||
];
|
||||
|
||||
let allExist = true;
|
||||
securityFiles.forEach(file => {
|
||||
const exists = checkFileExists(file, `Security ${file}`);
|
||||
if (!exists) allExist = false;
|
||||
});
|
||||
|
||||
return allExist;
|
||||
}
|
||||
|
||||
function checkPluginSystem() {
|
||||
logStep(9, 'Checking Plugin System');
|
||||
|
||||
const pluginFiles = [
|
||||
'server/src/core/runtime/PluginManager.ts',
|
||||
'server/src/core/connectors/AmazonConnector.ts',
|
||||
'server/src/core/connectors/eBayConnector.ts',
|
||||
'server/src/core/connectors/ShopifyConnector.ts',
|
||||
'extension/src/background/DOMParser.ts',
|
||||
'extension/src/background/FingerprintManager.ts'
|
||||
];
|
||||
|
||||
let allExist = true;
|
||||
pluginFiles.forEach(file => {
|
||||
const exists = checkFileExists(file, `Plugin ${file}`);
|
||||
if (!exists) allExist = false;
|
||||
});
|
||||
|
||||
return allExist;
|
||||
}
|
||||
|
||||
function checkTestingInfrastructure() {
|
||||
logStep(10, 'Checking Testing Infrastructure');
|
||||
|
||||
const testFiles = [
|
||||
'server/src/tests/system-integration.test.ts',
|
||||
'dashboard/src/tests/frontend.functional.test.ts',
|
||||
'dashboard/src/tests/frontend.integration.test.ts'
|
||||
];
|
||||
|
||||
let allExist = true;
|
||||
testFiles.forEach(file => {
|
||||
const exists = checkFileExists(file, `Test ${file}`);
|
||||
if (!exists) allExist = false;
|
||||
});
|
||||
|
||||
return allExist;
|
||||
}
|
||||
|
||||
function checkRuntimeComponents() {
|
||||
logStep(11, 'Checking Runtime Components');
|
||||
|
||||
const runtimeFiles = [
|
||||
'server/src/core/runtime/DomainEventBus.ts',
|
||||
'server/src/core/scheduler/AdaptiveScheduler.ts',
|
||||
'server/src/core/telemetry/GlobalTracingService.ts',
|
||||
'server/src/core/workers/WorkerHub.ts'
|
||||
];
|
||||
|
||||
let allExist = true;
|
||||
runtimeFiles.forEach(file => {
|
||||
const exists = checkFileExists(file, `Runtime ${file}`);
|
||||
if (!exists) allExist = false;
|
||||
});
|
||||
|
||||
return allExist;
|
||||
}
|
||||
|
||||
function checkDeploymentReadiness() {
|
||||
logStep(12, 'Checking Deployment Readiness');
|
||||
|
||||
const deploymentFiles = [
|
||||
'.github/workflows/ci-cd.yml',
|
||||
'scripts/db-init.sql',
|
||||
'scripts/env-config.sh',
|
||||
'server/package.json',
|
||||
'dashboard/package.json'
|
||||
];
|
||||
|
||||
let allExist = true;
|
||||
deploymentFiles.forEach(file => {
|
||||
const exists = checkFileExists(file, `Deployment ${file}`);
|
||||
if (!exists) allExist = false;
|
||||
});
|
||||
|
||||
return allExist;
|
||||
}
|
||||
|
||||
function generateDeploymentReport() {
|
||||
logStep(13, 'Generating Deployment Report');
|
||||
|
||||
const report = {
|
||||
timestamp: new Date().toISOString(),
|
||||
system: {
|
||||
name: 'Crawlful Hub',
|
||||
version: '1.0.0',
|
||||
environment: process.env.NODE_ENV || 'development'
|
||||
},
|
||||
checks: {
|
||||
directoryStructure: checkDirectoryStructure(),
|
||||
configurationFiles: checkConfigurationFiles(),
|
||||
databaseSchema: checkDatabaseSchema(),
|
||||
coreServices: checkCoreServices(),
|
||||
apiControllers: checkAPIControllers(),
|
||||
frontendPages: checkFrontendPages(),
|
||||
documentation: checkDocumentation(),
|
||||
securityConfiguration: checkSecurityConfiguration(),
|
||||
pluginSystem: checkPluginSystem(),
|
||||
testingInfrastructure: checkTestingInfrastructure(),
|
||||
runtimeComponents: checkRuntimeComponents(),
|
||||
deploymentReadiness: checkDeploymentReadiness()
|
||||
},
|
||||
summary: {
|
||||
totalChecks: 12,
|
||||
passedChecks: 0,
|
||||
failedChecks: 0,
|
||||
readiness: 'unknown'
|
||||
}
|
||||
};
|
||||
|
||||
report.summary.passedChecks = Object.values(report.checks).filter(Boolean).length;
|
||||
report.summary.failedChecks = Object.values(report.checks).filter(val => !val).length;
|
||||
report.summary.readiness = report.summary.passedChecks === report.summary.totalChecks ? 'READY' : 'NOT_READY';
|
||||
|
||||
const reportPath = path.join(process.cwd(), 'deployment-report.json');
|
||||
fs.writeFileSync(reportPath, JSON.stringify(report, null, 2));
|
||||
|
||||
logSuccess(`Deployment report generated: ${reportPath}`);
|
||||
|
||||
if (report.summary.readiness === 'READY') {
|
||||
logSuccess('🚀 System is READY for deployment!');
|
||||
} else {
|
||||
logWarning(`⚠️ System is NOT ready for deployment. ${report.summary.failedChecks} checks failed.`);
|
||||
}
|
||||
|
||||
return report.summary.readiness === 'READY';
|
||||
}
|
||||
|
||||
function main() {
|
||||
console.log(`${COLORS.bright}${COLORS.cyan}
|
||||
╔════════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ CRAWLFUL HUB - SYSTEM DEPLOYMENT CHECKER ║
|
||||
║ ║
|
||||
║ Comprehensive System Validation & Deployment Prep ║
|
||||
║ ║
|
||||
╚════════════════════════════════════════════════════════════╝
|
||||
${COLORS.reset}`);
|
||||
|
||||
logStep('START', 'Starting comprehensive system validation...\n');
|
||||
|
||||
const isReady = generateDeploymentReport();
|
||||
|
||||
console.log(`\n${COLORS.bright}${COLORS.cyan}
|
||||
════════════════════════════════════════════════════════════
|
||||
VALIDATION COMPLETE
|
||||
════════════════════════════════════════════════════════════
|
||||
${COLORS.reset}`);
|
||||
|
||||
process.exit(isReady ? 0 : 1);
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
main();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
checkDirectoryStructure,
|
||||
checkConfigurationFiles,
|
||||
checkDatabaseSchema,
|
||||
checkCoreServices,
|
||||
checkAPIControllers,
|
||||
checkFrontendPages,
|
||||
checkDocumentation,
|
||||
checkSecurityConfiguration,
|
||||
checkPluginSystem,
|
||||
checkTestingInfrastructure,
|
||||
checkRuntimeComponents,
|
||||
checkDeploymentReadiness,
|
||||
generateDeploymentReport
|
||||
};
|
||||
Reference in New Issue
Block a user