TorbatYar/frontend/scripts/validate-healthcare-circular.mjs
Mortezakoohjani 6f4a484051 Migrate Beauty, Healthcare, and Accounting frontend to modular src/modules architecture.
Move business logic out of App Router into module packages, add boundary validation scripts, and keep all routes as thin re-exports without changing URLs or API behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-26 22:28:27 +03:30

80 lines
2.2 KiB
JavaScript

#!/usr/bin/env node
/** Simple import-graph cycle detection for src/modules/healthcare. */
import { readFileSync, readdirSync, statSync } from "node:fs";
import { join, relative } from "node:path";
import { fileURLToPath } from "node:url";
const ROOT = join(fileURLToPath(new URL(".", import.meta.url)), "..");
const MODULE = join(ROOT, "src", "modules", "healthcare");
const importRe = /from\s+["'](@\/[^"']+)["']/g;
const graph = new Map();
function walk(dir) {
for (const e of readdirSync(dir)) {
const f = join(dir, e);
if (statSync(f).isDirectory()) walk(f);
else if (/\.tsx?$/.test(e)) {
const rel = relative(ROOT, f).replace(/\\/g, "/");
const deps = [];
const content = readFileSync(f, "utf8");
let m;
importRe.lastIndex = 0;
while ((m = importRe.exec(content)) !== null) {
if (m[1].startsWith("@/src/modules/healthcare/")) deps.push(m[1]);
}
graph.set(rel, deps);
}
}
}
walk(MODULE);
function resolve(importPath) {
const base = importPath.replace("@/", "").replace(/\/$/, "");
const candidates = [
`${base}.tsx`,
`${base}.ts`,
`${base}/index.tsx`,
`${base}/index.ts`,
];
for (const c of candidates) {
if (graph.has(c)) return c;
}
return null;
}
function findCycles() {
const cycles = [];
const visited = new Set();
const stack = new Set();
function dfs(node, path) {
if (stack.has(node)) {
cycles.push([...path, node]);
return;
}
if (visited.has(node)) return;
visited.add(node);
stack.add(node);
for (const dep of graph.get(node) ?? []) {
const resolved = resolve(dep);
if (resolved) dfs(resolved, [...path, node]);
}
stack.delete(node);
}
for (const node of graph.keys()) dfs(node, []);
return cycles;
}
const cycles = findCycles();
console.log("Circular Dependency Check (healthcare module)\n");
if (cycles.length) {
console.error("❌ Cycles found:");
for (const c of cycles) console.error(" ", c.join(" → "));
process.exit(1);
}
console.log(`✅ No cycles in ${graph.size} healthcare module files`);
process.exit(0);