diff --git a/server/backend/internal/httpapi/playerstatus.go b/server/backend/internal/httpapi/playerstatus.go index 365190f..e865a47 100644 --- a/server/backend/internal/httpapi/playerstatus.go +++ b/server/backend/internal/httpapi/playerstatus.go @@ -243,21 +243,45 @@ var ( errInvalidStale = errors.New("invalid stale") ) -func writeOverviewQueryError(w http.ResponseWriter, err error) { +// overviewQueryErrorCode returns the machine-readable error code for query +// validation errors. It is used by both the JSON and HTML error paths. +func overviewQueryErrorCode(err error) string { switch err { case errInvalidUpdatedSince: - writeError(w, http.StatusBadRequest, "invalid_updated_since", "updated_since ist kein gueltiger RFC3339-Zeitstempel", nil) + return "invalid_updated_since" case errInvalidLimit: - writeError(w, http.StatusBadRequest, "invalid_limit", "limit muss eine positive Ganzzahl sein", nil) + return "invalid_limit" case errInvalidServerConnectivity: - writeError(w, http.StatusBadRequest, "invalid_server_connectivity", "server_connectivity muss online, offline, degraded oder unknown sein", nil) + return "invalid_server_connectivity" case errInvalidStale: - writeError(w, http.StatusBadRequest, "invalid_stale", "stale muss true oder false sein", nil) + return "invalid_stale" default: - writeError(w, http.StatusBadRequest, "invalid_query", "ungueltige Query-Parameter", nil) + return "invalid_query" } } +// overviewQueryErrorMessage returns the human-readable message for query +// validation errors. It is used by both the JSON and HTML error paths so +// that the wording stays consistent regardless of response format. +func overviewQueryErrorMessage(err error) string { + switch err { + case errInvalidUpdatedSince: + return "updated_since ist kein gueltiger RFC3339-Zeitstempel" + case errInvalidLimit: + return "limit muss eine positive Ganzzahl sein" + case errInvalidServerConnectivity: + return "server_connectivity muss online, offline, degraded oder unknown sein" + case errInvalidStale: + return "stale muss true oder false sein" + default: + return "ungueltige Query-Parameter" + } +} + +func writeOverviewQueryError(w http.ResponseWriter, err error) { + writeError(w, http.StatusBadRequest, overviewQueryErrorCode(err), overviewQueryErrorMessage(err), nil) +} + func validateOptionalRFC3339(value string) error { if strings.TrimSpace(value) == "" { return nil diff --git a/server/backend/internal/httpapi/router_test.go b/server/backend/internal/httpapi/router_test.go index adaa783..7e70106 100644 --- a/server/backend/internal/httpapi/router_test.go +++ b/server/backend/internal/httpapi/router_test.go @@ -218,6 +218,7 @@ func TestRouterScreenDetailPageRoute(t *testing.T) { "← All screens", "Timing", "Endpoints", + "", } { if !strings.Contains(body, want) { t.Fatalf("body missing %q", want) diff --git a/server/backend/internal/httpapi/statuspage.go b/server/backend/internal/httpapi/statuspage.go index 39719d0..00d1757 100644 --- a/server/backend/internal/httpapi/statuspage.go +++ b/server/backend/internal/httpapi/statuspage.go @@ -34,6 +34,7 @@ type statusFilterLink struct { type screenDetailPageData struct { GeneratedAt string + RefreshSeconds int Record playerStatusRecord StatusPagePath string } @@ -606,6 +607,7 @@ var screenDetailTemplate = template.Must(template.New("screen-detail").Funcs(sta + {{.Record.ScreenID}} – Screen Status ` + statusPageCSSBlock + ` @@ -768,6 +770,7 @@ func handleScreenDetailPage(store playerStatusStore) http.HandlerFunc { data := screenDetailPageData{ GeneratedAt: store.Now().Format(time.RFC3339), + RefreshSeconds: 15, Record: record, StatusPagePath: "/status", } @@ -875,24 +878,6 @@ func writeStatusPageQueryError(w http.ResponseWriter, queryErr error) { } } -// overviewQueryErrorMessage returns a human-readable message for the given -// overview query validation error. It is shared between the HTML and JSON -// error paths to keep messages consistent. -func overviewQueryErrorMessage(err error) string { - switch err { - case errInvalidUpdatedSince: - return "updated_since ist kein gueltiger RFC3339-Zeitstempel." - case errInvalidLimit: - return "limit muss eine positive Ganzzahl sein." - case errInvalidServerConnectivity: - return "server_connectivity muss online, offline, degraded oder unknown sein." - case errInvalidStale: - return "stale muss true oder false sein." - default: - return "Ungueltige Query-Parameter." - } -} - func statusClass(value string) string { trimmed := strings.TrimSpace(value) if trimmed == "" {