feat(server): /healthz returns min_client_version
Lets the M7 Flutter client refuse to operate against an incompatible server (e.g., new endpoints the client depends on, breaking schema shifts). The version constant is bumped on each release where the client/server contract changes; old clients show the user a blocking "update required" modal pointed at the latest APK / TestFlight build.
This commit is contained in:
@@ -103,7 +103,10 @@ func (s *Server) Router() http.Handler {
|
||||
func (s *Server) handleHealthz(w http.ResponseWriter, _ *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_ = json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
|
||||
_ = json.NewEncoder(w).Encode(map[string]string{
|
||||
"status": "ok",
|
||||
"min_client_version": MinClientVersion,
|
||||
})
|
||||
}
|
||||
|
||||
// handleAdminScan runs a scan synchronously and returns the resulting stats.
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/auth"
|
||||
@@ -45,6 +46,32 @@ func TestHealthz(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHealthz_IncludesMinClientVersion(t *testing.T) {
|
||||
t.Parallel()
|
||||
s := &Server{}
|
||||
r := chi.NewRouter()
|
||||
r.Get("/healthz", s.handleHealthz)
|
||||
ts := httptest.NewServer(r)
|
||||
defer ts.Close()
|
||||
|
||||
resp, err := http.Get(ts.URL + "/healthz")
|
||||
if err != nil {
|
||||
t.Fatalf("GET /healthz: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var body map[string]string
|
||||
if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
|
||||
t.Fatalf("decode: %v", err)
|
||||
}
|
||||
if body["status"] != "ok" {
|
||||
t.Errorf("status: got %q want \"ok\"", body["status"])
|
||||
}
|
||||
if body["min_client_version"] == "" {
|
||||
t.Error("min_client_version is empty; clients can't enforce pairing")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouter_ServesSPAAtRoot(t *testing.T) {
|
||||
s := New(slog.New(slog.NewTextHandler(io.Discard, nil)), nil, nil, subsonic.Config{}, config.EventsConfig{}, config.RecommendationConfig{})
|
||||
ts := httptest.NewServer(s.Router())
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package server
|
||||
|
||||
// MinClientVersion is the lowest mobile-client semver that this server
|
||||
// accepts. Bump it when a server change requires a paired client update;
|
||||
// older clients see version_too_old at /healthz and refuse to operate.
|
||||
const MinClientVersion = "0.1.0"
|
||||
Reference in New Issue
Block a user