From 9eab00620cbd8641f177a2dd0dff03374c22348a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Weberru=C3=9F?= Date: Sat, 17 Oct 2026 00:18:22 +0000 Subject: [PATCH] fix(configurator): serve hosted deployment phase deep links Align the explicit compiled-UI route allowlist with existing workspace and deployment navigation. Cover direct API serving and preserve API/auth/asset and unknown-route errors; Vite history fallback is not hosted evidence. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- landing-zone-configurator/app/apps/api/src/app.ts | 5 +++++ landing-zone-configurator/app/tests/api.test.ts | 12 ++++++++++++ landing-zone-configurator/docs/development.md | 7 +++++++ 3 files changed, 24 insertions(+) diff --git a/landing-zone-configurator/app/apps/api/src/app.ts b/landing-zone-configurator/app/apps/api/src/app.ts index 5001657..a70af9f 100644 --- a/landing-zone-configurator/app/apps/api/src/app.ts +++ b/landing-zone-configurator/app/apps/api/src/app.ts @@ -270,11 +270,16 @@ export function buildApp( if (options.webRoot) { // Explicit SPA routes only: API/auth errors and missing assets must remain errors. for (const path of [ + "/workspaces", "/templates", "/repositories", "/configurations", "/credentials", "/deployments", + "/deployments/preparation", + "/deployments/plan", + "/deployments/apply", + "/deployments/history", "/organisation", "/applications", "/configurations/edit", diff --git a/landing-zone-configurator/app/tests/api.test.ts b/landing-zone-configurator/app/tests/api.test.ts index 567341b..5889a0c 100644 --- a/landing-zone-configurator/app/tests/api.test.ts +++ b/landing-zone-configurator/app/tests/api.test.ts @@ -48,6 +48,15 @@ it("serves the compiled UI without bypassing API authentication", async () => { "/repositories", "/configurations", "/configurations/edit/review", + "/deployments", + "/deployments/preparation", + "/deployments/plan", + "/deployments/apply", + "/deployments/history", + "/workspaces", + "/applications", + "/credentials", + "/organisation", ]) { const response = await app.inject(path); expect(response.statusCode).toBe(200); @@ -57,6 +66,9 @@ it("serves the compiled UI without bypassing API authentication", async () => { expect((await app.inject("/api/v1/unknown")).statusCode).toBe(404); expect((await app.inject("/assets/missing.js")).statusCode).toBe(404); expect((await app.inject("/templates/unknown")).statusCode).toBe(404); + expect((await app.inject("/deployments/unknown")).statusCode).toBe(404); + expect((await app.inject("/deployments/apply/extra")).statusCode).toBe(404); + expect((await app.inject("/workspaces/unknown")).statusCode).toBe(404); expect((await app.inject("/api/v1/unknown")).statusCode).not.toBe(200); } finally { await app.close(); diff --git a/landing-zone-configurator/docs/development.md b/landing-zone-configurator/docs/development.md index 8fe0ece..898d5a0 100644 --- a/landing-zone-configurator/docs/development.md +++ b/landing-zone-configurator/docs/development.md @@ -35,6 +35,13 @@ it cannot detach a focused input. Actual identity/workspace changes still reset the draft and scoped catalogue provider; never retain private catalogues across those boundaries. +Keep frontend navigation and the API's explicit SPA route allowlist aligned, +including workspace and deployment-phase URLs. Direct loads and reloads must +serve the compiled UI through the API, not just the development server's history +fallback. The static-serving API regression covers these paths while retaining +404 responses for unknown routes, API/auth paths and missing assets; do not +replace the allowlist with a catch-all. + ## Validation versus cloud operations | Workflow | Trigger and purpose |