Background
frontend/nginx.conf (removed in 0e86c00) had a cache-header bug: only /index.html
was exact-matched for no-store, so other HTML entry points (editor.html,
taskpane.html, etc.) fell through to the SPA-fallback location / block, which set
no Cache-Control at all — leaving them open to browser heuristic caching. This let
at least one client keep referencing old, since-moved backend endpoints after a prod
deploy. backend/src/static.ts (introduced in 0e86c00) now correctly sends
no-store, must-revalidate for all .html files and manifest.xml, so this
particular bug is fixed.
However, HTTP cache headers only govern new fetches. They don't help a client that
already has the old JS loaded and running — most notably Office/Google-Docs task
panes, which can stay open (and never reload) for long stretches. For those, only an
explicit reload picks up a new build.
Proposal
GET /api/ping already returns { timestamp, gitCommit }
(backend/src/app.ts:186). Use gitCommit as a cheap build-version signal:
- On load, the frontend records the
gitCommit it booted with.
- Poll
/api/ping periodically (or check on relevant user actions) and compare to
the booted value.
- On mismatch: first surface a low-friction "an update is available — reload" prompt;
if it persists past some grace period/interaction count, force a reload
automatically so users don't get stuck silently talking to stale/removed endpoints.
Open questions
- Poll interval / trigger (timer vs. on-focus vs. on-API-error).
- Grace period before forcing vs. just prompting indefinitely.
- Whether to piggyback the version check on existing API calls instead of a separate
poll, to avoid extra requests from long-lived idle panes.
Not urgent
This is a mitigation for an edge case (already-open long-lived sessions) — the root
cache-header bug that caused the originally observed staleness is already fixed.
Background
frontend/nginx.conf(removed in 0e86c00) had a cache-header bug: only/index.htmlwas exact-matched for
no-store, so other HTML entry points (editor.html,taskpane.html, etc.) fell through to the SPA-fallbacklocation /block, which setno
Cache-Controlat all — leaving them open to browser heuristic caching. This letat least one client keep referencing old, since-moved backend endpoints after a prod
deploy.
backend/src/static.ts(introduced in 0e86c00) now correctly sendsno-store, must-revalidatefor all.htmlfiles andmanifest.xml, so thisparticular bug is fixed.
However, HTTP cache headers only govern new fetches. They don't help a client that
already has the old JS loaded and running — most notably Office/Google-Docs task
panes, which can stay open (and never reload) for long stretches. For those, only an
explicit reload picks up a new build.
Proposal
GET /api/pingalready returns{ timestamp, gitCommit }(
backend/src/app.ts:186). UsegitCommitas a cheap build-version signal:gitCommitit booted with./api/pingperiodically (or check on relevant user actions) and compare tothe booted value.
if it persists past some grace period/interaction count, force a reload
automatically so users don't get stuck silently talking to stale/removed endpoints.
Open questions
poll, to avoid extra requests from long-lived idle panes.
Not urgent
This is a mitigation for an edge case (already-open long-lived sessions) — the root
cache-header bug that caused the originally observed staleness is already fixed.