BDMS-884: App refresh banner — notify users when a new version is deployed#292
BDMS-884: App refresh banner — notify users when a new version is deployed#292jeremyzilar wants to merge 8 commits into
Conversation
…s deployed Adds a non-intrusive top banner that appears when a new build has been deployed while a user has the app open. Detects new versions by polling /version.json every 5 minutes and comparing against the build time captured at initial load. - vite.config.ts: new write-version-json plugin writes public/version.json with the current ISO build time at the start of every build - public/version.json: placeholder file for local dev (contains "dev") - src/hooks/useNewVersion.ts: polls /version.json, returns isNewVersionAvailable and dismiss(); stops detecting once the user dismisses the banner - src/components/NewVersionBanner.tsx: full-width indigo banner with "We just made Ocotillo 5% better. Refresh to get the good stuff!", a Refresh Now button that reloads the page, and an X to dismiss - src/components/AppShell.tsx: banner rendered above AppLayout in a flex-col wrapper so it takes only the space it needs and the shell fills the rest
Preview DeploymentPreview URL: https://preview-bdms-884-app-refresh-bar-auejgdbofq-uc.a.run.app Note: This preview uses the staging API endpoints. |
Preview DeploymentPreview URL: https://preview-bdms-884-app-refresh-bar-auejgdbofq-uc.a.run.app Note: This preview uses the staging API endpoints. |
2 similar comments
Preview DeploymentPreview URL: https://preview-bdms-884-app-refresh-bar-auejgdbofq-uc.a.run.app Note: This preview uses the staging API endpoints. |
Preview DeploymentPreview URL: https://preview-bdms-884-app-refresh-bar-auejgdbofq-uc.a.run.app Note: This preview uses the staging API endpoints. |
Preview DeploymentPreview URL: https://preview-bdms-884-app-refresh-bar-auejgdbofq-uc.a.run.app Note: This preview uses the staging API endpoints. |
Preview DeploymentPreview URL: https://preview-bdms-884-app-refresh-bar-auejgdbofq-uc.a.run.app Note: This preview uses the staging API endpoints. |
Preview DeploymentPreview URL: https://preview-bdms-884-app-refresh-bar-auejgdbofq-uc.a.run.app Note: This preview uses the staging API endpoints. |
Preview DeploymentPreview URL: https://preview-bdms-884-app-refresh-bar-auejgdbofq-uc.a.run.app Note: This preview uses the staging API endpoints. |
Why
Field staff and hydrogeologists keep Ocotillo open for extended periods. Without a notification, they can stay on a stale version for hours after a deploy — potentially missing bug fixes or new features, or hitting broken experiences. This adds a visible banner that prompts them to reload.
How version detection works
There is nothing to manually increment. The system uses a build timestamp, not a version number.
Every time code is merged to
stagingorproduction, the CI/CD pipeline runsnpm run build:ci. During that build, a Vite plugin runs before any code is compiled and writes this file to the output:The timestamp is set to the exact moment the build ran. No two builds produce the same value.
When a user loads Ocotillo, the app fetches
/version.jsonand stores that timestamp as its baseline. Every 5 minutes it fetches/version.jsonagain. If the timestamp has changed, a new version is live and the banner appears.The full sequence for a production deploy:
productionbranchCD deploy production to GAEnpm run build:ciruns — the Vite plugin writes a newversion.jsonwith the current timestampversion.json) is deployed to App EngineThe same sequence applies to
stagingviaCD deploy staging to GAE.The
Cache-Control: no-storeheader inapp.yamlandapp-staging.yamlensures App Engine never serves a cached copy ofversion.json. Every poll hits the live file.The version number in the sidebar
The
v1.0.1shown at the bottom of the sidebar is a separate thing. It comes frompackage.jsonand is bumped manually by the team when cutting a named release (e.g.,v1.1.0). It is not involved in banner detection — it is just there for reference so users and support staff can quickly see which release is running.What changed
vite.config.tswrite-version-jsonplugin writespublic/version.jsonat build startpublic/version.json{"buildTime":"dev"})src/hooks/useNewVersion.ts?preview-refresh-bannerURL param forces it visible for testingsrc/components/NewVersionBanner.tsxButton)src/components/AppShell.tsxAppContentabove the header; sidebar footer showsv{version}frompackage.jsonapp.yaml/app-staging.yamlCache-Control: no-storehandler for/version.jsonso GAE never caches itBanner text
Behaviour
window.location.reload()Testing locally
Append
?preview-refresh-bannerto any URL to force the banner visible without waiting for a real deploy: