docs: audit housekeeping hotel workflows
This commit is contained in:
1 parent
4d9845b52f
commit
949e14c109
2 files changed
+779
No files matched your search
@@ -0,0 +1,120 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { PERMS } from "@/lib/permission-slugs";
|
||||
import { ownedLegacyPages } from "./discover-legacy-pages";
|
||||
import { hotelMigrationEntries } from "./hotel";
|
||||
import { validateMigrationEntries } from "./validate-matrix";
|
||||
|
||||
const HOTEL_PREFIXES = [
|
||||
"/admin/rooms",
|
||||
"/admin/navigation",
|
||||
"/admin/radio",
|
||||
"/admin/studio",
|
||||
] as const;
|
||||
|
||||
describe("hotelMigrationEntries", () => {
|
||||
it("maps all hotel tools below the hotel target root", () => {
|
||||
expect(
|
||||
validateMigrationEntries(
|
||||
ownedLegacyPages(HOTEL_PREFIXES),
|
||||
hotelMigrationEntries,
|
||||
),
|
||||
).toEqual([]);
|
||||
expect(
|
||||
hotelMigrationEntries.every(
|
||||
(row) =>
|
||||
row.targetPath === null || row.targetPath.startsWith("/admin/hotel/"),
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("preserves room ids while merging only the detail aliases", () => {
|
||||
expect(
|
||||
hotelMigrationEntries
|
||||
.filter((row) => row.legacyPath.startsWith("/admin/rooms"))
|
||||
.map(({ legacyPath, targetPath, decision }) => ({
|
||||
legacyPath,
|
||||
targetPath,
|
||||
decision,
|
||||
})),
|
||||
).toEqual([
|
||||
{
|
||||
legacyPath: "/admin/rooms",
|
||||
targetPath: "/admin/hotel/rooms",
|
||||
decision: "REBUILD",
|
||||
},
|
||||
{
|
||||
legacyPath: "/admin/rooms/:id",
|
||||
targetPath: "/admin/hotel/rooms/:id",
|
||||
decision: "MERGE",
|
||||
},
|
||||
{
|
||||
legacyPath: "/admin/rooms/:id/furni",
|
||||
targetPath: "/admin/hotel/rooms/:id/furni",
|
||||
decision: "REBUILD",
|
||||
},
|
||||
{
|
||||
legacyPath: "/admin/rooms/edit/:id",
|
||||
targetPath: "/admin/hotel/rooms/:id",
|
||||
decision: "MERGE",
|
||||
},
|
||||
{
|
||||
legacyPath: "/admin/rooms/show/:id",
|
||||
targetPath: "/admin/hotel/rooms/:id",
|
||||
decision: "MERGE",
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("keeps every audited workflow planned without parity claims", () => {
|
||||
expect(
|
||||
hotelMigrationEntries.every(
|
||||
(row) => row.status === "PLANNED" && row.parityEvidence.length === 0,
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("requires privileged audit and an explicit capability for every mutation", () => {
|
||||
const mutationRows = hotelMigrationEntries.filter(
|
||||
(row) => row.dependencies.mutations.length > 0,
|
||||
);
|
||||
|
||||
expect(mutationRows.length).toBeGreaterThan(0);
|
||||
expect(
|
||||
mutationRows.every(
|
||||
(row) =>
|
||||
row.capabilities.mutate.length > 0 &&
|
||||
row.auditRequirement === "PRIVILEGED_MUTATION",
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("records the actual permissions for room, radio, and Studio mutations", () => {
|
||||
expect(hotelMigrationEntries).toContainEqual(
|
||||
expect.objectContaining({
|
||||
legacyPath: "/admin/rooms/edit/:id",
|
||||
capabilities: {
|
||||
read: [PERMS.ROOMS_EDIT],
|
||||
mutate: [PERMS.ROOMS_EDIT, PERMS.ROOMS_DELETE],
|
||||
},
|
||||
}),
|
||||
);
|
||||
expect(hotelMigrationEntries).toContainEqual(
|
||||
expect.objectContaining({
|
||||
legacyPath: "/admin/radio/api-keys",
|
||||
capabilities: {
|
||||
read: [PERMS.RADIO_VIEW],
|
||||
mutate: [PERMS.RADIO_EDIT],
|
||||
},
|
||||
}),
|
||||
);
|
||||
expect(hotelMigrationEntries).toContainEqual(
|
||||
expect.objectContaining({
|
||||
legacyPath: "/admin/studio/sync",
|
||||
capabilities: {
|
||||
read: [PERMS.ASSETS_IMPORT],
|
||||
mutate: [PERMS.ASSETS_IMPORT],
|
||||
},
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user