import fs from "node:fs"; import path from "node:path"; import { describe, expect, it } from "vitest"; import { repoPathExists } from "~/utils/testing/repoPaths"; type FeatureManifest = { id: string; classification: string; pruning: { action: string; }; }; const rootDir = process.cwd(); const docs = { migrationStatus: "docs/architecture-migration-status.md", featureInventory: "docs/feature-inventory.md", manifestReadme: "docs/feature-manifests/README.md", agentEntrypoints: "docs/agent-entrypoints.md", } as const; const requiredArchitectureClosureSources = [ "docs/architecture-migration-status.md", "docs/feature-inventory.md", "docs/feature-manifests/", ]; const documentedS04Evidence = ["apps/web/app/utils/build/bundleScan.ts", "apps/web/app/utils/build/manualChunks.ts"]; const requiredS04Evidence = [...documentedS04Evidence, "apps/web/app/utils/build/viteConfigIntegration.test.ts"]; function readProjectFile(filePath: string) { return fs.readFileSync(path.join(rootDir, filePath), "utf8"); } function readManifest(fileName: string) { return JSON.parse(readProjectFile(path.join("docs/feature-manifests", fileName))) as FeatureManifest; } describe("Architecture Closure closure documentation", () => { it("keeps architecture status anchored to boundaries, pruning manifests and S04 evidence", () => { const status = readProjectFile(docs.migrationStatus); expect(status).toContain("## Architecture Closure final closure status"); expect(status).toMatch(/handoff contract/i); expect(status).toContain("apps/api"); expect(status).toContain("apps/worker"); expect(status).toContain("packages/db"); expect(status).toContain("packages/mail"); expect(status).toContain("docs/feature-manifests/"); expect(status).toContain("docs/feature-inventory.md"); expect(status).toContain("core`, `plugin-candidate`, `remove-candidate"); documentedS04Evidence.forEach((evidencePath) => { expect(status, evidencePath).toContain(evidencePath); }); }); it("keeps the feature inventory aligned with Architecture Closure status and pruning actions", () => { const inventory = readProjectFile(docs.featureInventory); expect(inventory).toContain("docs/architecture-migration-status.md"); expect(inventory).toContain("docs/feature-manifests/"); expect(inventory).toContain("`core` bleibt die aktive Boilerplate-Basis"); expect(inventory).toContain("`product-core` beschreibt Blueprint-, Plan-, Custom-Plan-, Tenant-Override- und Tenant-Rollen-Gates"); expect(inventory).toContain("`plugin-candidate` beschreibt nur noch Extraktionsvertraege"); expect(inventory).toContain("`remove-candidate` beschreibt Loesch- oder Review-Vertraege"); expect(inventory).toContain("API-Split"); expect(inventory).toContain("Worker/API/Mail-Split"); }); it("documents the executor-facing manifest contract and source alignment", () => { const readme = readProjectFile(docs.manifestReadme); requiredArchitectureClosureSources.forEach((sourcePath) => { expect(readme, sourcePath).toContain(sourcePath); }); expect(readme).toContain("current API, worker, package, pruning, and bundle handoff status"); expect(readme).toContain("machine-readable Core/Plugin/Removal contract"); expect(readme).toContain("ownership, dependencies, configuration, provider, worker, UAT, and pruning boundaries"); expect(readme).toContain("pruning.action"); expect(readme).toContain("keep`, `extract-plugin`, `remove`, or `review"); }); it("points agents at every canonical Architecture Closure planning source before feature work", () => { const entrypoints = readProjectFile(docs.agentEntrypoints); expect(entrypoints).toContain("Architecture Closure closure/status contract"); expect(entrypoints).toContain("docs/architecture-migration-status.md"); expect(entrypoints).toContain("docs/feature-inventory.md"); expect(entrypoints).toContain("docs/feature-manifests/*.json"); expect(entrypoints).toContain("before planning implementation, extraction, or removal work"); }); it("keeps the complete S04 bundle evidence set present for future verification", () => { requiredS04Evidence.forEach((evidencePath) => { expect(repoPathExists(evidencePath), evidencePath).toBe(true); }); }); }); describe("Architecture Closure feature manifest pruning contract", () => { const manifestDir = path.join(rootDir, "docs/feature-manifests"); const manifestFiles = fs .readdirSync(manifestDir) .filter((file) => file.endsWith(".json") && file !== "schema.json") .sort(); it("keeps every non-schema feature manifest JSON-parseable", () => { expect(manifestFiles.length).toBeGreaterThan(0); manifestFiles.forEach((file) => { expect(() => JSON.parse(readProjectFile(path.join("docs/feature-manifests", file))), file).not.toThrow(); }); }); it("exposes the canonical core/plugin/removal pruning actions", () => { expect(readManifest("core.json")).toMatchObject({ id: "core", classification: "core", pruning: { action: "keep" }, }); expect(readManifest("plugin-candidates.json")).toMatchObject({ id: "plugin-candidates", classification: "plugin-candidate", pruning: { action: "extract-plugin" }, }); expect(readManifest("remove-candidates.json")).toMatchObject({ id: "remove-candidates", classification: "remove-candidate", pruning: { action: "remove" }, }); }); });