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 "/dashboard/apikeys"
@inherits DashboardPageBase
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject IDashboardApiKeyManagementService ApiKeyManagementService
@@ -1,4 +1,5 @@
@page "/"
@page "/dashboard/"
@inherits DashboardPageBase
<PageTitle>MXAccess Gateway Dashboard</PageTitle>
@@ -1,4 +1,5 @@
@page "/events"
@page "/dashboard/events"
@inherits DashboardPageBase
<PageTitle>Dashboard Events</PageTitle>
@@ -1,4 +1,5 @@
@page "/galaxy"
@page "/dashboard/galaxy"
@inherits DashboardPageBase
<PageTitle>Dashboard Galaxy</PageTitle>
@@ -1,4 +1,5 @@
@page "/sessions/{SessionId}"
@page "/dashboard/sessions/{SessionId}"
@inherits DashboardPageBase
<PageTitle>Dashboard Session</PageTitle>
@@ -1,4 +1,5 @@
@page "/sessions"
@page "/dashboard/sessions"
@inherits DashboardPageBase
<PageTitle>Dashboard Sessions</PageTitle>
@@ -1,4 +1,5 @@
@page "/settings"
@page "/dashboard/settings"
@inherits DashboardPageBase
<PageTitle>Dashboard Settings</PageTitle>
@@ -1,4 +1,5 @@
@page "/workers"
@page "/dashboard/workers"
@inherits DashboardPageBase
<PageTitle>Dashboard Workers</PageTitle>
@@ -100,13 +100,18 @@ public sealed class GatewayApplicationTests
}
/// <summary>
/// Server-020 regression: every dashboard Razor page used to declare both
/// <c>@page "/X"</c> and <c>@page "/dashboard/X"</c>, which — once
/// <c>MapGroup("/dashboard")</c> prepended the path base — produced both
/// <c>/dashboard/X</c> AND <c>/dashboard/dashboard/X</c> 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 <c>@page</c> directive fails CI.
/// Server-020 regression guard. The original Server-020 finding incorrectly
/// concluded that the duplicate <c>@page "/dashboard/X"</c> directives were
/// redundant because <c>MapGroup("/dashboard")</c> would prepend the prefix
/// to all dashboard Razor pages. In practice Blazor SSR's <c>@page</c>
/// template matcher does NOT compose with <c>MapGroup</c>, so removing the
/// <c>/dashboard/X</c> directive left the dashboard unreachable at runtime
/// (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>
[Fact]
public async Task Build_WhenDashboardEnabled_DoesNotRegisterDoubledDashboardPrefixRoutes()