commit
This commit is contained in:
96
scripts/check-architecture.js
Normal file
96
scripts/check-architecture.js
Normal file
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const ROOT = process.cwd();
|
||||
const dashboardRoot = path.join(ROOT, 'src', 'app', 'dashboard');
|
||||
const requiredGuardPattern =
|
||||
/require(Employee|HRD|IT|UserManagement|SuperAdmin|Permission)DashboardAccess/;
|
||||
const allowedWithoutGuard = new Set([
|
||||
'src/app/dashboard/layout.tsx',
|
||||
'src/app/dashboard/page.tsx',
|
||||
'src/app/dashboard/overview/layout.tsx',
|
||||
'src/app/dashboard/organizers/page.tsx'
|
||||
]);
|
||||
const legacyRoutePrefixes = [
|
||||
'src/app/dashboard/billing/',
|
||||
'src/app/dashboard/chat/',
|
||||
'src/app/dashboard/elements/',
|
||||
'src/app/dashboard/exclusive/',
|
||||
'src/app/dashboard/forms/',
|
||||
'src/app/dashboard/kanban/',
|
||||
'src/app/dashboard/profile/',
|
||||
'src/app/dashboard/product/',
|
||||
'src/app/dashboard/react-query/',
|
||||
'src/app/dashboard/workspaces/'
|
||||
];
|
||||
const guardedByLayoutPrefixes = ['src/app/dashboard/overview/'];
|
||||
|
||||
function walk(dir, results = []) {
|
||||
if (!fs.existsSync(dir)) {
|
||||
return results;
|
||||
}
|
||||
|
||||
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||
const fullPath = path.join(dir, entry.name);
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
walk(fullPath, results);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.name === 'page.tsx' || entry.name === 'layout.tsx') {
|
||||
results.push(fullPath);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
function isLegacy(relativePath) {
|
||||
return legacyRoutePrefixes.some((prefix) => relativePath.startsWith(prefix));
|
||||
}
|
||||
|
||||
function isGuardedByParentLayout(relativePath) {
|
||||
return guardedByLayoutPrefixes.some(
|
||||
(prefix) => relativePath.startsWith(prefix) && relativePath !== `${prefix}layout.tsx`
|
||||
);
|
||||
}
|
||||
|
||||
function main() {
|
||||
const files = walk(dashboardRoot);
|
||||
const missingGuards = [];
|
||||
|
||||
for (const filePath of files) {
|
||||
const relativePath = path.relative(ROOT, filePath).replace(/\\/g, '/');
|
||||
|
||||
if (
|
||||
allowedWithoutGuard.has(relativePath) ||
|
||||
isLegacy(relativePath) ||
|
||||
isGuardedByParentLayout(relativePath)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const content = fs.readFileSync(filePath, 'utf8');
|
||||
|
||||
if (!requiredGuardPattern.test(content)) {
|
||||
missingGuards.push(relativePath);
|
||||
}
|
||||
}
|
||||
|
||||
if (missingGuards.length === 0) {
|
||||
console.log('check-architecture: passed');
|
||||
return;
|
||||
}
|
||||
|
||||
console.error('check-architecture: dashboard entrypoints missing shared page guards');
|
||||
for (const relativePath of missingGuards) {
|
||||
console.error(`- ${relativePath}`);
|
||||
}
|
||||
|
||||
process.exitCode = 1;
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user