From 84d36b76388c6d109115ad3ad3b28e3bcdf7d386 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Wed, 20 May 2026 12:07:18 -0400 Subject: [PATCH] =?UTF-8?q?Restore=20dashboard=20@page=20"/dashboard/X"=20?= =?UTF-8?q?directives=20=E2=80=94=20Server-020=20reversal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Server-020 incorrectly removed the duplicate `@page "/dashboard/X"` directive from each dashboard Razor page on the assumption that `MapGroup("/dashboard")` would prepend the prefix to Blazor SSR route matching. It does not — Blazor's `@page` template matcher operates on the full URL path, not relative to a MapGroup. The removal left the dashboard returning HTTP 500 with "Unable to find the provided template '/dashboard/'" from RouteTableFactory.CreateEntry on every page. Restored the eight `@page "/dashboard/X"` directives. The accompanying regression test still passes (it asserts the genuinely-double-prefixed shape `/dashboard/dashboard/X` never appears — it never did, since the original duplicates were `"/"` + `"/dashboard/"`, not `"/dashboard/"` repeated). XML doc on the test rewritten to record what was actually wrong with Server-020. Verified: gateway redeploy + `GET http://localhost:5130/dashboard` returns HTTP 200 7.3 KB; `/dashboard/sessions` also 200. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Components/Pages/ApiKeysPage.razor | 1 + .../Components/Pages/DashboardHome.razor | 1 + .../Components/Pages/EventsPage.razor | 1 + .../Components/Pages/GalaxyPage.razor | 1 + .../Components/Pages/SessionDetailsPage.razor | 1 + .../Components/Pages/SessionsPage.razor | 1 + .../Components/Pages/SettingsPage.razor | 1 + .../Components/Pages/WorkersPage.razor | 1 + .../Gateway/GatewayApplicationTests.cs | 19 ++++++++++++------- 9 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/MxGateway.Server/Dashboard/Components/Pages/ApiKeysPage.razor b/src/MxGateway.Server/Dashboard/Components/Pages/ApiKeysPage.razor index 545139c..9a058a3 100644 --- a/src/MxGateway.Server/Dashboard/Components/Pages/ApiKeysPage.razor +++ b/src/MxGateway.Server/Dashboard/Components/Pages/ApiKeysPage.razor @@ -1,4 +1,5 @@ @page "/apikeys" +@page "/dashboard/apikeys" @inherits DashboardPageBase @inject AuthenticationStateProvider AuthenticationStateProvider @inject IDashboardApiKeyManagementService ApiKeyManagementService diff --git a/src/MxGateway.Server/Dashboard/Components/Pages/DashboardHome.razor b/src/MxGateway.Server/Dashboard/Components/Pages/DashboardHome.razor index 919594d..0197588 100644 --- a/src/MxGateway.Server/Dashboard/Components/Pages/DashboardHome.razor +++ b/src/MxGateway.Server/Dashboard/Components/Pages/DashboardHome.razor @@ -1,4 +1,5 @@ @page "/" +@page "/dashboard/" @inherits DashboardPageBase MXAccess Gateway Dashboard diff --git a/src/MxGateway.Server/Dashboard/Components/Pages/EventsPage.razor b/src/MxGateway.Server/Dashboard/Components/Pages/EventsPage.razor index 0e0b687..e5401ec 100644 --- a/src/MxGateway.Server/Dashboard/Components/Pages/EventsPage.razor +++ b/src/MxGateway.Server/Dashboard/Components/Pages/EventsPage.razor @@ -1,4 +1,5 @@ @page "/events" +@page "/dashboard/events" @inherits DashboardPageBase Dashboard Events diff --git a/src/MxGateway.Server/Dashboard/Components/Pages/GalaxyPage.razor b/src/MxGateway.Server/Dashboard/Components/Pages/GalaxyPage.razor index 48e97e2..3c5e4a2 100644 --- a/src/MxGateway.Server/Dashboard/Components/Pages/GalaxyPage.razor +++ b/src/MxGateway.Server/Dashboard/Components/Pages/GalaxyPage.razor @@ -1,4 +1,5 @@ @page "/galaxy" +@page "/dashboard/galaxy" @inherits DashboardPageBase Dashboard Galaxy diff --git a/src/MxGateway.Server/Dashboard/Components/Pages/SessionDetailsPage.razor b/src/MxGateway.Server/Dashboard/Components/Pages/SessionDetailsPage.razor index 0eddbbc..569ad72 100644 --- a/src/MxGateway.Server/Dashboard/Components/Pages/SessionDetailsPage.razor +++ b/src/MxGateway.Server/Dashboard/Components/Pages/SessionDetailsPage.razor @@ -1,4 +1,5 @@ @page "/sessions/{SessionId}" +@page "/dashboard/sessions/{SessionId}" @inherits DashboardPageBase Dashboard Session diff --git a/src/MxGateway.Server/Dashboard/Components/Pages/SessionsPage.razor b/src/MxGateway.Server/Dashboard/Components/Pages/SessionsPage.razor index e8df4dc..5c60e20 100644 --- a/src/MxGateway.Server/Dashboard/Components/Pages/SessionsPage.razor +++ b/src/MxGateway.Server/Dashboard/Components/Pages/SessionsPage.razor @@ -1,4 +1,5 @@ @page "/sessions" +@page "/dashboard/sessions" @inherits DashboardPageBase Dashboard Sessions diff --git a/src/MxGateway.Server/Dashboard/Components/Pages/SettingsPage.razor b/src/MxGateway.Server/Dashboard/Components/Pages/SettingsPage.razor index 120aac0..ebf9930 100644 --- a/src/MxGateway.Server/Dashboard/Components/Pages/SettingsPage.razor +++ b/src/MxGateway.Server/Dashboard/Components/Pages/SettingsPage.razor @@ -1,4 +1,5 @@ @page "/settings" +@page "/dashboard/settings" @inherits DashboardPageBase Dashboard Settings diff --git a/src/MxGateway.Server/Dashboard/Components/Pages/WorkersPage.razor b/src/MxGateway.Server/Dashboard/Components/Pages/WorkersPage.razor index 4811852..80f8182 100644 --- a/src/MxGateway.Server/Dashboard/Components/Pages/WorkersPage.razor +++ b/src/MxGateway.Server/Dashboard/Components/Pages/WorkersPage.razor @@ -1,4 +1,5 @@ @page "/workers" +@page "/dashboard/workers" @inherits DashboardPageBase Dashboard Workers diff --git a/src/MxGateway.Tests/Gateway/GatewayApplicationTests.cs b/src/MxGateway.Tests/Gateway/GatewayApplicationTests.cs index f1b6dfe..eb3ac52 100644 --- a/src/MxGateway.Tests/Gateway/GatewayApplicationTests.cs +++ b/src/MxGateway.Tests/Gateway/GatewayApplicationTests.cs @@ -100,13 +100,18 @@ public sealed class GatewayApplicationTests } /// - /// Server-020 regression: every dashboard Razor page used to declare both - /// @page "/X" and @page "/dashboard/X", which — once - /// MapGroup("/dashboard") prepended the path base — produced both - /// /dashboard/X AND /dashboard/dashboard/X routes. The second - /// shape was almost certainly accidental and is no longer registered. The - /// check covers every dashboard page so a future page that brings back the - /// duplicated @page directive fails CI. + /// Server-020 regression guard. The original Server-020 finding incorrectly + /// concluded that the duplicate @page "/dashboard/X" directives were + /// redundant because MapGroup("/dashboard") would prepend the prefix + /// to all dashboard Razor pages. In practice Blazor SSR's @page + /// template matcher does NOT compose with MapGroup, so removing the + /// /dashboard/X directive left the dashboard unreachable at runtime + /// (every page returned HTTP 500 with "Unable to find the provided template + /// '/dashboard/'" from RouteTableFactory.CreateEntry). The duplicate + /// @page directives are restored. This test only confirms the + /// genuinely-double-prefixed shape (/dashboard/dashboard/X) never + /// appears — it never did, since the original duplicates were + /// "/" + "/dashboard/", not "/dashboard/" repeated. /// [Fact] public async Task Build_WhenDashboardEnabled_DoesNotRegisterDoubledDashboardPrefixRoutes()