diff --git a/internal/server/static.go b/internal/server/static.go index aad2f468e..413f28966 100644 --- a/internal/server/static.go +++ b/internal/server/static.go @@ -170,7 +170,11 @@ func staticDirFromEnv() string { } // isStaticPath returns true if the path should be handled by the static file -// server rather than the API. API paths start with /api/ or are /health. +// server rather than the API. API paths start with /api/ or are /health or +// /version. /version is a public root-path endpoint (build metadata, no auth) +// registered in the API router table; it must not fall through to the SPA +// fallback on the Lambda path, matching the explicit mux.HandleFunc("/version") +// registration used on the HTTP/Cloud Run path in internal/server/http.go. // OIDC discovery paths (/.well-known/*) are intercepted earlier by the // transport layer via api.IsOIDCDiscoveryPath, so they never reach here. func isStaticPath(urlPath string) bool { @@ -183,6 +187,9 @@ func isStaticPath(urlPath string) bool { if clean == "/health" { return false } + if clean == "/version" { + return false + } return true } diff --git a/internal/server/static_test.go b/internal/server/static_test.go index b0de97288..c9480a2c2 100644 --- a/internal/server/static_test.go +++ b/internal/server/static_test.go @@ -94,6 +94,8 @@ func TestIsStaticPath(t *testing.T) { {"/app/dashboard", true}, {"//health", false}, // double-slash normalised to /health {"//api/test", false}, + {"/version", false}, // public build-metadata endpoint must reach API, not SPA + {"//version", false}, // double-slash normalised to /version } for _, tt := range tests { t.Run(tt.path, func(t *testing.T) {