Cache-busting : assets versionnés (?v=model_version) + pages HTML no-cache
Le navigateur gardait l'ancien CSS/JS (aucun Cache-Control). Les pages sont maintenant servies no-cache avec les URLs d'assets versionnées à la volée — chaque release devient visible immédiatement. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 changed file +26 −1
modified
backend/app/main.py
+26 −1
@@ -87,12 +87,37 @@ def health(): | ||
| 87 | 87 | PAGES = ["index", "aujourdhui", "carte", "circonscriptions", "sondages", |
| 88 | 88 | "signaux", "simulateur", "intelligence", "methodologie", "backtest", |
| 89 | 89 | "admin"] |
| 90 | + | |
| 91 | +# Cache-busting : la version du modèle est injectée dans les URLs d'assets | |
| 92 | +# (style.css?v=…, app.js?v=…) et les pages HTML sont servies en no-cache — | |
| 93 | +# chaque release est visible immédiatement, sans vider le cache du navigateur. | |
| 94 | +_page_cache: dict[str, tuple[float, str]] = {} | |
| 95 | + | |
| 96 | + | |
| 97 | +def _render_page(name: str) -> str: | |
| 98 | + f = FRONTEND_DIR / f"{name}.html" | |
| 99 | + mtime = f.stat().st_mtime | |
| 100 | + cached = _page_cache.get(name) | |
| 101 | + if cached and cached[0] == mtime: | |
| 102 | + return cached[1] | |
| 103 | + html = f.read_text() | |
| 104 | + v = settings.model_version | |
| 105 | + html = html.replace('href="/assets/style.css"', | |
| 106 | + f'href="/assets/style.css?v={v}"') | |
| 107 | + html = html.replace('src="/assets/app.js"', | |
| 108 | + f'src="/assets/app.js?v={v}"') | |
| 109 | + _page_cache[name] = (mtime, html) | |
| 110 | + return html | |
| 111 | + | |
| 112 | + | |
| 90 | 113 | for page in PAGES: |
| 91 | 114 | path = "/" if page == "index" else f"/{page}" |
| 92 | 115 | |
| 93 | 116 | def make_handler(p=page): |
| 94 | 117 | def handler(): |
| 95 | − return FileResponse(FRONTEND_DIR / f"{p}.html") | |
| 118 | + from fastapi.responses import HTMLResponse | |
| 119 | + return HTMLResponse(_render_page(p), | |
| 120 | + headers={"Cache-Control": "no-cache"}) | |
| 96 | 121 | return handler |
| 97 | 122 | app.get(path, include_in_schema=False)(make_handler()) |
| 98 | 123 | |
| 99 | 124 | |