fix(housekeeping): canonicalize live cutover links

This commit is contained in:
Simo committed 2026-09-02 21:53:19 +02:00
1 parent 1f10e15c1c
commit c841595458
15 files changed
+107 -30

No files matched your search

@@ -1,4 +1,5 @@
import { existsSync, readFileSync } from "node:fs";
import { existsSync, readdirSync, readFileSync } from "node:fs";
import { join, posix } from "node:path";
import { describe, expect, it } from "vitest";
const PREVIEW_ENTRYPOINTS = [
@@ -14,13 +15,25 @@ const PREMATURE_UI_ROOTS = [
["src/app/admin", "-next"].join(""),
["src/app", "ase"].join("/"),
] as const;
const STABLE_GLOBAL_SOURCES = [
const CUTOVER_GLOBAL_SOURCES = [
"src/lib/admin/guard.ts",
"src/lib/proxy-access.ts",
"src/components/navigation.tsx",
"src/components/top-header.tsx",
] as const;
function liveSourceFiles(root: string): readonly string[] {
return readdirSync(root, { withFileTypes: true }).flatMap((entry) => {
const path = posix.normalize(join(root, entry.name).replaceAll("\\", "/"));
if (entry.isDirectory()) {
if (path === "src/features/housekeeping/migration") return [];
return liveSourceFiles(path);
}
if (!/\.(?:ts|tsx)$/u.test(entry.name) || entry.name.includes(".test.")) {
return [];
}
return [path];
});
}
describe("gated Housekeeping preview coexistence", () => {
it("publishes the /ase-next entrypoints and dispatcher", () => {
for (const path of PREVIEW_ENTRYPOINTS) {
@@ -58,9 +71,9 @@ describe("gated Housekeeping preview coexistence", () => {
expect(gate).toContain("input.flag");
});
it("leaves stable global links and authorization fallbacks on /admin and /mod", () => {
for (const path of STABLE_GLOBAL_SOURCES) {
expect(readFileSync(path, "utf8"), path).not.toContain("/ase-next");
it("canonicalizes Housekeeping links while retaining /admin and /mod", () => {
for (const path of CUTOVER_GLOBAL_SOURCES) {
expect(readFileSync(path, "utf8"), path).toContain("/ase-next");
}
expect(readFileSync("src/components/top-header.tsx", "utf8")).toContain(
'href="/admin"',
@@ -78,4 +91,24 @@ describe("gated Housekeeping preview coexistence", () => {
);
}
});
it("keeps live Housekeeping links on the canonical namespace", () => {
const staleRoute = new RegExp(
[
"/",
"ase",
"(?:[/?#]|[",
'"',
"'",
String.fromCharCode(96),
"]|$)",
].join(""),
"u",
);
const violations = liveSourceFiles("src").filter((path) =>
staleRoute.test(readFileSync(path, "utf8")),
);
expect(violations).toEqual([]);
});
});