test(architecture): ratchet top-level layer direction and mutual imports (#10584)

* test(architecture): ratchet top-level layer direction and mutual imports

Declare a layer for every top-level src/ directory and root source file
(domain, contracts, foundation, providers, application, composition,
adapters) in scripts/lib/module-layers.mjs. verify:module-boundaries now also
builds the production import graph between those units and compares it with
a counted baseline: 45 unit pairs import a higher layer (248 imports) and 23
unit pairs import each other. A new upward pair, more imports on a recorded
pair, a new mutual import, or an undeclared unit fails; shrinkage is
reported so the baseline can be lowered.

* fix(architecture): enforce layers for isolated units
This commit is contained in:
morluto authored and GitHub committed 2026-11-15 08:37:04 +08:00
1 parent 351c2f4a03
commit 8c052bdec5
8 files changed
+472 -9

No files matched your search

+24 -6
View File
@@ -148,18 +148,36 @@ const failedBoundary = (file, target, typeOnly) => {
return undefined;
};
/** Check resolved source ownership, including type imports and reexports. */
export const inspectModuleBoundaries = (file, source, root) => {
/** Each own-source import of a file, resolved to its repository path. */
export const resolveModuleImports = (file, source, root) => {
const absoluteFile = resolve(root, file);
const importer = repositoryPath(root, absoluteFile);
const violations = [];
const imports = [];
for (const { specifier, line, typeOnly } of readImportSpecifiers(source)) {
const resolved = sourceTarget(root, absoluteFile, specifier);
if (resolved === undefined) continue;
const target = repositoryPath(root, resolved);
const boundary = failedBoundary(importer, target, typeOnly);
imports.push({
file: importer,
line,
specifier,
typeOnly,
target: repositoryPath(root, resolved),
});
}
return imports;
};
/** Check resolved source ownership, including type imports and reexports. */
export const inspectModuleBoundaries = (file, source, root) =>
inspectResolvedModuleBoundaries(resolveModuleImports(file, source, root));
/** Check already resolved imports, as returned by resolveModuleImports. */
export const inspectResolvedModuleBoundaries = (imports) => {
const violations = [];
for (const { file, line, specifier, typeOnly, target } of imports) {
const boundary = failedBoundary(file, target, typeOnly);
if (boundary !== undefined)
violations.push({ file: importer, line, specifier, target, boundary });
violations.push({ file, line, specifier, target, boundary });
}
return violations;
};