97 lines
2.4 KiB
JavaScript
97 lines
2.4 KiB
JavaScript
#!/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();
|