Files
vendoo/tools/verify-platform-architecture-1.41.1.mjs
Masterluke77andGitHub 6f48827f4d Vendoo 1.41.2 – Git Ignore Boundary & Module Tracking Hotfix (#18)
* docs: prepare Vendoo 1.41.2 git-ignore boundary hotfix

* fix: track native source modules with root-anchored runtime ignores
2026-07-09 17:09:00 +02:00

64 lines
5.1 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { readFileSync } from 'node:fs';
import { dirname, join, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { ModuleRegistry } from '../app/kernel/module-registry.mjs';
import { PolicyEngine } from '../app/kernel/policy-engine.mjs';
import { RouteRegistry } from '../app/kernel/route-registry.mjs';
import { loadBuiltInModules } from '../app/modules/catalog.mjs';
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
const read = rel => readFileSync(join(root, rel), 'utf8');
const failures = [];
const assert = (condition, message) => { if (!condition) failures.push(message); };
const expectThrow = async (fn, code, message) => { try { await fn(); failures.push(message); } catch (error) { if (error.code !== code) failures.push(`${message} (${error.code || error.message})`); } };
const pkg = JSON.parse(read('package.json'));
assert(pkg.version === '1.41.1', `package.json ist ${pkg.version}`);
const modules = loadBuiltInModules();
assert(modules.length === 17, `Erwartet 17 Module, erhalten ${modules.length}`);
const nativeIds = modules.filter(item => item.manifest.status === 'native').map(item => item.manifest.id).sort();
for (const id of ['vendoo.auth','vendoo.users','vendoo.sessions','vendoo.settings','vendoo.security','vendoo.themes','vendoo.listings','vendoo.inventory','vendoo.media','vendoo.ai','vendoo.flux-studio','vendoo.quality','vendoo.publishing','vendoo.module-manager','vendoo.deployments']) {
assert(nativeIds.includes(id), `Natives Modul fehlt: ${id}`);
}
assert(nativeIds.length === 15, `Erwartet 15 native Module, erhalten ${nativeIds.length}`);
assert(modules.filter(item => item.manifest.status === 'legacy-bridge').length === 2, 'Es müssen 2 Legacy-Bridges verbleiben');
const registry = new ModuleRegistry();
for (const module of modules) registry.register(module);
let realGraph = null;
try { realGraph = registry.validateGraph(); } catch (error) { failures.push(`Realer Modulgraph ungültig: ${error.code || error.message} ${error.message}`); }
assert(registry.snapshot().length === 17, 'Modulregistrierung unvollständig');
assert(realGraph?.enabledModules.length === 17, 'Nicht alle 17 Module sind im realen Graph auflösbar');
assert(realGraph?.capabilities.includes('settings.configuration'), 'settings.configuration fehlt im realen Capability-Graph');
const cycle = new ModuleRegistry();
cycle.register({ manifest: { schemaVersion:1,id:'vendoo.a',name:'A',version:'1.0.0',type:'feature',status:'native',requires:['vendoo.b'],permissions:[],provides:['a.ready'],consumes:[],owns:['a.state'] } });
cycle.register({ manifest: { schemaVersion:1,id:'vendoo.b',name:'B',version:'1.0.0',type:'feature',status:'native',requires:['vendoo.a'],permissions:[],provides:['b.ready'],consumes:[],owns:['b.state'] } });
await expectThrow(() => cycle.startAll({}), 'MODULE_DEPENDENCY_CYCLE', 'Zyklus wurde nicht blockiert');
const policies = new PolicyEngine();
policies.register('test.read', ({ user }) => Boolean(user));
const routeModules = new ModuleRegistry();
routeModules.register({ manifest: { schemaVersion:1,id:'vendoo.test',name:'Test',version:'1.0.0',type:'feature',status:'native',requires:[],permissions:[],provides:[],consumes:[],owns:[] } }, { enabled: false });
const routes = new RouteRegistry({ policyEngine: policies, moduleRegistry: routeModules });
const fake = { get(_path, handler) { this.handler = handler; } };
routes.register(fake, { id:'test.route.read', method:'GET', path:'/x', owner:'vendoo.test', policy:'test.read', csrf:false, handler(_req,res){res.json({ok:true});} });
let status = 0; let payload = null;
await fake.handler({ user:{id:1}, requestId:'test' }, { headersSent:false, status(code){status=code;return this;}, json(value){payload=value;} }, () => {});
assert(status === 503 && payload?.code === 'MODULE_DISABLED', `Deaktiviertes Modul ergab ${status}`);
const kernel = read('app/kernel/platform-kernel.mjs');
for (const marker of ["policies.register('modules.manage'", "policies.register('updates.manage'", "features.define('deployments.coolify'", "features.define('modules.manager'", "features.define('publishing.native-module'", 'moduleStateStore', 'modulePackageStore']) assert(kernel.includes(marker), `Kernelvertrag fehlt: ${marker}`);
const catalog = read('app/modules/catalog.mjs');
for (const marker of ['createAiModule','createFluxStudioModule','createQualityModule','createPublishingModule','createModuleManagerModule','createDeploymentsModule']) assert(catalog.includes(marker), `Modulkatalog fehlt: ${marker}`);
assert(catalog.includes("const legacyModuleNames = ['system', 'operations']"), 'Legacy-Liste ist nicht auf System und Operations begrenzt');
const boundaries = JSON.parse(read('app/architecture-boundaries.json'));
assert(boundaries.architecture === 'modular-monolith', 'Architekturtyp wurde verändert');
if (failures.length) {
console.error(`Platform-Architecture-Gate 1.41.1 fehlgeschlagen (${failures.length}):`);
failures.forEach(item => console.error(`- ${item}`));
process.exit(1);
}
console.log('Platform-Architecture-Gate 1.41.1 erfolgreich: 17 Module, 15 native Module, 2 Legacy-Bridges, dynamische Zustände und Modul-Routensperre geprüft.');