Self-heal a stale cached bundle via a build version

Phones kept running old JS because their cached index.html pointed at an old
hashed asset. Both images now bake the commit SHA as BUILD_VERSION; the backend
exposes it at GET /api/version and the client reloads once with a cache-busting
query when its own baked version differs. Guarded by sessionStorage so it cannot
loop. /api/version is unauthenticated like /api/health.
This commit is contained in:
matitos committed 2026-09-21 00:16:43 +00:00
1 parent 7ad14449ce
commit 7b97f010c9
11 files changed
+80 -4

No files matched your search

+7
View File
@@ -63,6 +63,13 @@ def health() -> dict[str, str]:
return {"status": "ok"}
@router.get("/version")
def version(request: Request) -> dict[str, str]:
"""Build version of the running backend, used by the client to self-heal
from a stale cached bundle after a deploy."""
return {"version": getattr(request.app.state, "build_version", "unknown")}
@router.get("/strategies", response_model=list[StrategyOut])
def strategies() -> list[StrategyOut]:
return [strategy_spec(cls) for cls in list_strategies()]
+4
View File
@@ -1,5 +1,6 @@
from __future__ import annotations
import os
from collections.abc import AsyncIterator
from contextlib import asynccontextmanager
@@ -27,6 +28,9 @@ def create_app(
await runtime.shutdown()
app = FastAPI(title=settings.app_name, lifespan=lifespan)
# Baked at build time (see Dockerfile); the frontend compares its own
# version against this to self-heal from a stale cache.
app.state.build_version = os.environ.get("BUILD_VERSION", "unknown")
app.add_middleware(
CORSMiddleware,
allow_origins=settings.cors_origin_list,