Add /api/version capability endpoint for FE/BE version negotiation
Claude-Session: https://claude.ai/code/session_01RdARHDJaYC1wSQRTYM6t3Z
This commit is contained in:
parent
8eb3ffbb6b
commit
3a2f507353
2 changed files with 24 additions and 0 deletions
|
|
@ -58,6 +58,14 @@ def test_grade_is_aliased_across_api_versions(client):
|
|||
def test_query_validation_rejects_out_of_range(client):
|
||||
assert client.get("/thermograph/api/v2/grade",
|
||||
params={"lat": 999, "lon": 0}).status_code == 422
|
||||
|
||||
|
||||
def test_api_version_reports_backend_contract(client):
|
||||
r = client.get("/thermograph/api/version")
|
||||
assert r.status_code == 200
|
||||
body = r.json()
|
||||
assert {"backend_version", "min_frontend", "payload_ver"} <= body.keys()
|
||||
assert body["backend_version"] == "2"
|
||||
assert client.get("/thermograph/api/v2/grade",
|
||||
params={**Q, "days": 0}).status_code == 422
|
||||
|
||||
|
|
|
|||
16
web/app.py
16
web/app.py
|
|
@ -212,6 +212,22 @@ def healthz():
|
|||
return {"status": "ok", "role": ROLE}
|
||||
|
||||
|
||||
API_CONTRACT_VERSION = "2" # bump only on a breaking change to any /api/v{N} route or payload shape
|
||||
MIN_SUPPORTED_FRONTEND = "1" # oldest frontend contract version this backend still serves correctly
|
||||
|
||||
|
||||
@app.get(f"{BASE}/api/version")
|
||||
def api_version():
|
||||
"""Capability/version-negotiation endpoint: lets a split-out frontend detect at
|
||||
boot whether the backend it's talking to still supports its contract.
|
||||
Deliberately does no I/O, same posture as /healthz."""
|
||||
return {
|
||||
"backend_version": API_CONTRACT_VERSION,
|
||||
"min_frontend": MIN_SUPPORTED_FRONTEND,
|
||||
"payload_ver": payloads.PAYLOAD_VER,
|
||||
}
|
||||
|
||||
|
||||
def _client_ip(request) -> "str | None":
|
||||
"""The real client IP: the left-most X-Forwarded-For hop when a proxy fronts us
|
||||
(Caddy on prod sets it), otherwise the direct peer address (LAN dev)."""
|
||||
|
|
|
|||
Loading…
Reference in a new issue