Repository navigation
Description
This was generated by AI during triage.
Split from #50 (offline data capture). #50 bundles two different-sized things: making the SPA installable, and making capture work offline. The first is a thin slice — manifest, icons, a service worker that caches the app shell. The second is the hard part — IndexedDB mutation queue, replay, conflict rules — and it is gated on the responsive pass (#49) and parked in Phase 1.5. This issue carves out the baseline so installability doesn't wait on the offline machinery.
Why
This came out of the React Native question: the answer was no port — the cheap path to "an app on the phone" is a PWA. Installed from the browser, the SPA gets a home-screen icon, its own window without browser chrome, and app-like presence on barn phones. That is most of the perceived value of "a mobile app" for a fraction of the cost, and every piece of it is a prerequisite #50 needs anyway.
Scope
- Manifest — name, short name, theme/background colors consistent with the aubergine identity (both themes), icons (maskable + standard sizes),
display: standalone. - Icons — app icon set +
apple-touch-iconfor iOS, which ignores most of the manifest. - Service worker — precache the built app shell (JS/CSS/fonts), cache-first for static assets. API requests bypass the worker entirely — no stale shared state.
vite-plugin-pwais the obvious fit for the Vite build; hand-rolled only if it fights us. - Update flow — decide and implement: auto-update on next load vs. "new version available — reload" prompt. A stale cached shell talking to a newer API is the classic PWA footgun; the issue is not done until a deploy visibly propagates.
- Secure-context guard — SW registration and install only exist on HTTPS. Registration must no-op cleanly on plain HTTP (the SPA is a black screen on any plain-HTTP origin: crypto.randomUUID is secure-context only #138 black screen came from exactly this class of assumption). Barn phones currently reaching the app over plain HTTP get today's behavior, nothing worse.
Out of scope (stays in #50)
- Offline mutation queue (Dexie/IndexedDB, replay, Idempotency-Key), conflict rules, offline auth window.
- Reference-data caching — Offline data capture (PWA) — tech spec KD-4/§6 #50 layers it on this worker.
- Push notifications.
Checklist
- Manifest + icon set, both themes verified
- Service worker precaching app shell; API routes bypass; registration no-ops on non-secure origins
- Update propagation decision implemented and observable (deploy → clients get new version)
- Vitest: registration wrapper (secure-context guard, register/no-op paths), update-prompt component if we build one
- Install verified on Android Chrome and iOS Safari — home-screen icon, standalone window, correct theme color
-
specs/product/GLOSSARY.md+ SPA Help page, per the standing docs rule
Related
- Offline data capture (PWA) — tech spec KD-4/§6 #50 — offline data capture; narrows to the mutation-queue work on top of this baseline
- F9: Responsive/mobile pass — usable on phones and tablets #49 — responsive pass; barn phones are the device this exists for
- Static asset Cache-Control headers + Cloudflare-in-front CDN strategy #141 — Cache-Control/CDN strategy; SW caching and HTTP caching need to agree, whoever lands second reconciles
Note on sizing
Small-to-medium — mostly configuration and verification, one real design decision (update flow). Filed under Phase 1.5 with its parent, but unlike #50 it has no prereq on #49 and is cheap to pull forward if installability is wanted sooner.
Activity
chore: narrow CodeQL to security-extended, dropping quality-query noi…
F142: installable PWA baseline — manifest, icons, app-shell service w…
F142: installable PWA baseline — manifest, icons, app-shell service w…
feat(web): serve a per-request CSP nonce so Emotion's styles apply un…