Status: Proposed (becomes Accepted on Phase 3 activation perDocumentation Index
Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
Use this file to discover all available pages before exploring further.
MICROFRONTENDS_RUNBOOK.md)
Date: 2026-04-22
Participants: Platform Architecture (cloud agent draft, Jeremy Bloom approval at activation)
Related: ADR-013 (amended by this ADR), ADR-008, Phase 3 of docs/recommendations/DEV_VELOCITY_AND_ARCHITECTURE_PLAN_2026-04-22.md (PR #137)
Context
ADR-013 established the platform’s PWA strategy: a single Workbox service worker registered at scope /, with CacheFirst for static assets, NetworkFirst for REST, and NetworkOnly for auth. That ADR assumes a single app generating one sw.js and one precache manifest.
Phase 3 (docs/development/MICROFRONTENDS_RUNBOOK.md) introduces a second Vercel project (encoreos-public) that handles /auth, /employee-setup, /pending-activation, /pm/kiosk/:siteId/*, /portal/*, /p/:token, /packet/:token, /gr/whistleblower-report, /chatbot/widget. Both projects use vite-plugin-pwa today, so each will independently generate a sw.js.
The problem: only one service worker can claim scope / per origin. If both Vercel projects emit sw.js at the root with scope: '/', whichever one installs second will fail (or, worse, supersede the first and start serving cached chunks from the wrong project).
This is a real, known issue with Vite + microfrontends and is the headline reason the recommendations doc (§ 3.5) flagged the PWA scope problem as a “non-trivial migration cost”.
Options Considered
Option A: Keep encoreos-app SW at scope /; disable SW on encoreos-public
encoreos-appcontinues to emitsw.jsatscope: '/'exactly as today.encoreos-publicremovesvite-plugin-pwa(or setsregisterType: 'none').- Result: the public zone has no offline support, no PWA install prompt, no precache. That is acceptable for the public zone because:
- Auth pages are short-lived and use
NetworkOnlyfor the auth endpoint anyway. - The kiosk hardware is wall-powered, on a known network, and reloads on tap — offline is not a real requirement.
- Public form portals (
/p/*,/packet/*,/portal/*) need server reachability to submit anyway.
- Auth pages are short-lived and use
Option B: Each zone owns a sub-scope SW
encoreos-appkeepsscope: '/'.encoreos-publicregisterssw.jsatscope: '/auth/',scope: '/portal/', etc. — one SW registration per route family.- Vercel’s microfrontends asset prefix machinery handles routing the SW file requests correctly per zone.
/pm/kiosk/...) is awkward — the literal scope must match the kiosk route, which today is /pm/kiosk/:siteId, so the scope would be /pm/kiosk/ (which is fine, but a single missing trailing slash breaks it). High testing surface for low value.
Option C: A single shared SW lives in encoreos-app; precaches both zones’ assets
- Only
encoreos-appgenerates a SW. It precaches its own chunks AND fetches and precachesencoreos-public’s critical chunks via the Vercel asset-prefix URLs. - Requires custom Workbox plugin work to discover
encoreos-public’s manifest at build time.
Decision
Adopt Option A. At Phase 3 activation, the wiring PR will:- Leave
encoreos-app’svite.config.tsPWA configuration unchanged. It continues to registersw.jsat scope/exactly as documented in ADR-013. - In
encoreos-public’s build config (when that project is created with its ownvite.config.tsor a shared config gated onVERCEL_PROJECT_ID), disablevite-plugin-pwaentirely. Concretely: skip theVitePWA({...})plugin invocation when the build target isencoreos-public. - The
encoreos-publicindex.htmldoes NOT include<link rel="manifest">and does NOT register a service worker. - The Workbox
runtimeCachingrule already in place that excludes/auth/*from caching becomes redundant (the SW does not run on those routes anymore onceencoreos-publicowns them) but stays in place as defense-in-depth.
Consequences
Positive
- ADR-013’s behavior in the authenticated zone (which is where ~100% of PWA usage actually happens today) is preserved unchanged. Zero risk to existing PWA install base.
- No multi-SW complexity. Only one origin-level SW exists at any time.
- The smallest possible delta between today’s behavior and Phase 3 activation.
Negative
- Users cannot install
encoreos-publicas a standalone PWA. (Not a stated requirement; revisit if it becomes one.) - The kiosk experience loses the precache and offline behavior that ADR-013 provides for the authenticated app. Since kiosks are wall-powered and on a known network, this is acceptable. If a specific kiosk deployment ever needs offline, that’s a future ADR amendment scoped to that one route.
Mitigations
- Add a startup-time assertion in
encoreos-public’s entry script that warns if a SW is somehow already registered for the origin (e.g., a stale install from before activation) and unregisters it. Keeps users from getting stuck on stale chunks during the rollout window. - The Phase 3 cutover plan (
MICROFRONTENDS_RUNBOOK.mdstep 4) explicitly soaks the preview deployment for ≥24 hours to surface any cross-zone SW interactions before production cutover.
Related Documents
ADR-013— preserved; this ADR amends only the multi-zone scenarioADR-008— preserveddocs/development/MICROFRONTENDS_RUNBOOK.md— operational runbook for activationdocs/recommendations/DEV_VELOCITY_AND_ARCHITECTURE_PLAN_2026-04-22.md§ 3.5 — the original problem statement (lands via PR #137)- Vercel Microfrontends docs — local development
- Workbox — registering a service worker with scope