feat: add the TechLog Studio asset library route and screen
Adds TECH_LOG_STUDIO_ASSETS (/studio/assets) as a route reachable but excluded from primary Studio navigation (navigationLabel/navigationOrder null), plus the AssetLibrary screen that lists assets, shows usage, and lets an operator archive or hard-delete one. canHardDelete() is a pure gate mirroring the server's ASSET_IN_USE rule so the screen never offers an action the server would refuse. Adding a 28th route also required updating the route-scoped CI accessibility-evidence gate (FE-GATE-009 in config/ci/gates.json, plus its authority-baseline counts and shape digest in scripts/contracts/ci-gates.ts) and the Vite route-to-chunk map that scripts/generate-build-manifest.ts depends on, or test:unit and the production build both fail. See task-11-report.md for the full breakdown. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
073fda87eb
commit
b11aa94f1c
@@ -37,6 +37,7 @@ const expectedRoutes = [
|
||||
["TECH_LOG_STUDIO_DOCUMENT_PUBLISH", "/studio/documents/:id/publish", "STUDIO", "TechLogDocumentIdParams", null],
|
||||
["TECH_LOG_STUDIO_PUBLICATIONS", "/studio/publications", "STUDIO", null, null],
|
||||
["TECH_LOG_STUDIO_PUBLICATION_PREVIEW", "/studio/publications/:publicationEventId/preview", "STUDIO", "TechLogPublicationEventIdParams", null],
|
||||
["TECH_LOG_STUDIO_ASSETS", "/studio/assets", "STUDIO", null, null],
|
||||
["TECH_LOG_STUDIO_NOT_FOUND", "/studio/*", "STUDIO", "TechLogStudioSplat", null],
|
||||
["NOT_FOUND", "*", "PUBLIC", "NotFoundSplat", null],
|
||||
] as const;
|
||||
@@ -67,6 +68,7 @@ const expectedTitles = {
|
||||
TECH_LOG_STUDIO_DOCUMENT_PUBLISH: "게시",
|
||||
TECH_LOG_STUDIO_PUBLICATIONS: "게시 기록",
|
||||
TECH_LOG_STUDIO_PUBLICATION_PREVIEW: "게시 Snapshot",
|
||||
TECH_LOG_STUDIO_ASSETS: "Asset",
|
||||
TECH_LOG_STUDIO_NOT_FOUND: "Studio 화면을 찾을 수 없습니다",
|
||||
NOT_FOUND: "페이지를 찾을 수 없습니다.",
|
||||
} as const;
|
||||
@@ -140,7 +142,7 @@ describe("TechLog route boundary contract", () => {
|
||||
for (const locale of ["ko-KR", "en-US"] as const) {
|
||||
const catalog: Readonly<Record<string, string>> =
|
||||
TECH_LOG_MESSAGE_CATALOGS[locale];
|
||||
expect(Object.keys(catalog)).toHaveLength(54);
|
||||
expect(Object.keys(catalog)).toHaveLength(56);
|
||||
for (const [routeId, title] of Object.entries(expectedTitles)) {
|
||||
expect(catalog[`route.${routeId}.title`]).toBe(title);
|
||||
expect(catalog[`route.${routeId}.navigation`]).toBe(title);
|
||||
@@ -197,6 +199,16 @@ describe("TechLog route boundary contract", () => {
|
||||
).toThrow();
|
||||
});
|
||||
|
||||
it("registers the studio asset library outside primary navigation", () => {
|
||||
const route = TECH_LOG_ROUTE_REGISTRY.TECH_LOG_STUDIO_ASSETS;
|
||||
|
||||
expect(route).toBeTruthy();
|
||||
expect(route.path).toBe("/studio/assets");
|
||||
expect(route.layoutGroup).toBe("STUDIO");
|
||||
expect(route.navigationLabel).toBeNull();
|
||||
expect(route.navigationOrder).toBeNull();
|
||||
});
|
||||
|
||||
it("atomically installs the complete TechLog route and runtime inventories", () => {
|
||||
expect(Object.keys(ROUTE_REGISTRY)).toEqual(
|
||||
expectedRoutes.map(([routeId]) => routeId),
|
||||
|
||||
Reference in New Issue
Block a user