import { existsSync, readdirSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; import { describe, expect, it } from 'vitest'; import CertManagerLayout from './cert-manager/layout'; import DkvFleetLayout from './dkv-fleet/layout'; import DomaincheckLayout from './domaincheck/layout'; import TenderRadarLayout from './tender-radar/layout'; /** * Covers T-e8k-01, T-e8k-03, and T-e8k-04 (WINDOWS #10, PERM-04): * * - Each module-owned layout wraps children in ModuleAccessGate with the * slug that exactly matches its directory name — a copy-paste mistake * between the four near-identical files would flip the wrong module's * gate (T-e8k-03). * - Every non-dynamic module directory has a layout.tsx — a future module * directory added without one would run past the gate again exactly * like the four routes this plan fixes (T-e8k-04). */ const modulesDir = dirname(fileURLToPath(import.meta.url)); /** * Ordner ohne ModuleAccessGate, bewusst (quick-260929-9wc): `custom/` traegt * die Rahmen-Seiten der „Eigenen Module“. Das sind keine Zeilen der Tabelle * `Module` und haengen an keiner Aktivierung oder Freigabe — sie sind fuer * ALLE angemeldeten Benutzer sichtbar (D-01). Jeder weitere Eintrag hier ist * eine bewusste Ausnahme von T-e8k-04 und gehoert begruendet. */ const DIRS_WITHOUT_GATE: readonly string[] = ['custom']; const placeholderChild =