feat: 完成sys模块迁移,对齐PHP/Java框架
- 重构sys模块架构,严格按admin/api/core分层 - 对齐所有sys实体与数据库表结构 - 实现完整的adminapi控制器,匹配PHP/Java契约 - 修复依赖注入问题,确保服务正确注册 - 添加自动迁移工具和契约验证 - 完善多租户支持和审计功能 - 统一命名规范,与PHP业务逻辑保持一致
This commit is contained in:
66
tools/check-routes.js
Normal file
66
tools/check-routes.js
Normal file
@@ -0,0 +1,66 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// naive scan for @Controller and @Get/@Post/@Put/@Delete decorations
|
||||
function scanControllers(rootDir) {
|
||||
const results = [];
|
||||
function walk(dir) {
|
||||
for (const entry of fs.readdirSync(dir)) {
|
||||
const full = path.join(dir, entry);
|
||||
const stat = fs.statSync(full);
|
||||
if (stat.isDirectory()) walk(full);
|
||||
else if (entry.endsWith('.ts') && full.includes(path.join('controllers', 'adminapi'))) {
|
||||
const txt = fs.readFileSync(full, 'utf8');
|
||||
const controllerPrefixMatch = txt.match(/@Controller\(['"]([^'\"]+)['"]\)/);
|
||||
const prefix = controllerPrefixMatch ? controllerPrefixMatch[1] : '';
|
||||
const routeRegex = /@(Get|Post|Put|Delete)\(['"]([^'\"]*)['"]\)/g;
|
||||
let m;
|
||||
while ((m = routeRegex.exec(txt))) {
|
||||
const method = m[1].toUpperCase();
|
||||
const suffix = m[2];
|
||||
const fullPath = suffix ? `${prefix}/${suffix}` : prefix;
|
||||
results.push({ method, path: fullPath.replace(/\/:/g, '/:') });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
walk(rootDir);
|
||||
return results;
|
||||
}
|
||||
|
||||
function main() {
|
||||
const contract = JSON.parse(
|
||||
fs.readFileSync(path.join(__dirname, 'contracts', 'routes.json'), 'utf8'),
|
||||
);
|
||||
const impl = scanControllers(path.join(__dirname, '..', 'wwjcloud', 'src', 'common'));
|
||||
|
||||
function normalizePath(p) {
|
||||
// convert ${ var } or ${ params.var } to :var
|
||||
return String(p).replace(/\$\{\s*(?:params\.)?([a-zA-Z_][\w]*)\s*\}/g, ':$1');
|
||||
}
|
||||
|
||||
const toKey = (r) => `${r.method} ${normalizePath(r.path)}`;
|
||||
const contractSet = new Set(contract.map(toKey));
|
||||
const implSet = new Set(impl.map(toKey));
|
||||
|
||||
const missing = contract.filter((r) => !implSet.has(toKey(r)));
|
||||
const extra = impl.filter((r) => !contractSet.has(toKey(r)));
|
||||
|
||||
if (missing.length || extra.length) {
|
||||
console.error('Route contract mismatches found.');
|
||||
if (missing.length) {
|
||||
console.error('Missing routes:');
|
||||
for (const r of missing) console.error(` ${r.method} ${r.path}`);
|
||||
}
|
||||
if (extra.length) {
|
||||
console.error('Extra routes:');
|
||||
for (const r of extra) console.error(` ${r.method} ${r.path}`);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
console.log('All routes match contract.');
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user