Restore dashboard @page "/dashboard/X" directives — Server-020 reversal

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) <noreply@anthropic.com>
This commit is contained in:
Joseph Doherty
2026-05-20 12:07:18 -04:00
parent 1aafd6bde4
commit 84d36b7638
9 changed files with 20 additions and 7 deletions
@@ -1,4 +1,5 @@
@page "/apikeys" @page "/apikeys"
@page "/dashboard/apikeys"
@inherits DashboardPageBase @inherits DashboardPageBase
@inject AuthenticationStateProvider AuthenticationStateProvider @inject AuthenticationStateProvider AuthenticationStateProvider
@inject IDashboardApiKeyManagementService ApiKeyManagementService @inject IDashboardApiKeyManagementService ApiKeyManagementService
@@ -1,4 +1,5 @@
@page "/" @page "/"
@page "/dashboard/"
@inherits DashboardPageBase @inherits DashboardPageBase
<PageTitle>MXAccess Gateway Dashboard</PageTitle> <PageTitle>MXAccess Gateway Dashboard</PageTitle>
@@ -1,4 +1,5 @@
@page "/events" @page "/events"
@page "/dashboard/events"
@inherits DashboardPageBase @inherits DashboardPageBase
<PageTitle>Dashboard Events</PageTitle> <PageTitle>Dashboard Events</PageTitle>
@@ -1,4 +1,5 @@
@page "/galaxy" @page "/galaxy"
@page "/dashboard/galaxy"
@inherits DashboardPageBase @inherits DashboardPageBase
<PageTitle>Dashboard Galaxy</PageTitle> <PageTitle>Dashboard Galaxy</PageTitle>
@@ -1,4 +1,5 @@
@page "/sessions/{SessionId}" @page "/sessions/{SessionId}"
@page "/dashboard/sessions/{SessionId}"
@inherits DashboardPageBase @inherits DashboardPageBase
<PageTitle>Dashboard Session</PageTitle> <PageTitle>Dashboard Session</PageTitle>
@@ -1,4 +1,5 @@
@page "/sessions" @page "/sessions"
@page "/dashboard/sessions"
@inherits DashboardPageBase @inherits DashboardPageBase
<PageTitle>Dashboard Sessions</PageTitle> <PageTitle>Dashboard Sessions</PageTitle>
@@ -1,4 +1,5 @@
@page "/settings" @page "/settings"
@page "/dashboard/settings"
@inherits DashboardPageBase @inherits DashboardPageBase
<PageTitle>Dashboard Settings</PageTitle> <PageTitle>Dashboard Settings</PageTitle>
@@ -1,4 +1,5 @@
@page "/workers" @page "/workers"
@page "/dashboard/workers"
@inherits DashboardPageBase @inherits DashboardPageBase
<PageTitle>Dashboard Workers</PageTitle> <PageTitle>Dashboard Workers</PageTitle>
@@ -100,13 +100,18 @@ public sealed class GatewayApplicationTests
} }
/// <summary> /// <summary>
/// Server-020 regression: every dashboard Razor page used to declare both /// Server-020 regression guard. The original Server-020 finding incorrectly
/// <c>@page "/X"</c> and <c>@page "/dashboard/X"</c>, which — once /// concluded that the duplicate <c>@page "/dashboard/X"</c> directives were
/// <c>MapGroup("/dashboard")</c> prepended the path base — produced both /// redundant because <c>MapGroup("/dashboard")</c> would prepend the prefix
/// <c>/dashboard/X</c> AND <c>/dashboard/dashboard/X</c> routes. The second /// to all dashboard Razor pages. In practice Blazor SSR's <c>@page</c>
/// shape was almost certainly accidental and is no longer registered. The /// template matcher does NOT compose with <c>MapGroup</c>, so removing the
/// check covers every dashboard page so a future page that brings back the /// <c>/dashboard/X</c> directive left the dashboard unreachable at runtime
/// duplicated <c>@page</c> directive fails CI. /// (every page returned HTTP 500 with "Unable to find the provided template
/// '/dashboard/'" from <c>RouteTableFactory.CreateEntry</c>). The duplicate
/// <c>@page</c> directives are restored. This test only confirms the
/// genuinely-double-prefixed shape (<c>/dashboard/dashboard/X</c>) never
/// appears — it never did, since the original duplicates were
/// <c>"/"</c> + <c>"/dashboard/"</c>, not <c>"/dashboard/"</c> repeated.
/// </summary> /// </summary>
[Fact] [Fact]
public async Task Build_WhenDashboardEnabled_DoesNotRegisterDoubledDashboardPrefixRoutes() public async Task Build_WhenDashboardEnabled_DoesNotRegisterDoubledDashboardPrefixRoutes()