Files
HiveGrid-Wireframes/hivegrid-cloud/apps/web/app/application/architectureClosureDocs.test.ts
T

134 lines
5.4 KiB
TypeScript

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" },
});
});
});