Mechanical reformat — no logic changes. 398 files changed, 19125 insertions(+), 16457 deletions(-). Prettier 3.8.4 with .prettierrc (singleQuote:true, semi:true, tabWidth:2, trailingComma:all, printWidth:100). Isolated per D-13-08 for reviewability.
12 KiB
12 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, user_setup, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | user_setup | must_haves | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 03-event-write-back-pwa-install | 07 | execute | 3 |
|
|
true |
|
|
Purpose: PWA-01/02 are prerequisites for Phase 5 Web Push — the non-technical member must
be able to install unassisted. The single hard constraint is that the service worker MUST
NOT intercept the OIDC /callback (Gate 2 / Pitfall 1) or break iOS standalone login.
Output: configured VitePWA build, install icons + meta, InstallPrompt mounted in the shell.
<execution_context> @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md </execution_context>
@.planning/phases/03-event-write-back-pwa-install/03-UI-SPEC.md @.planning/phases/03-event-write-back-pwa-install/03-RESEARCH.md @.planning/phases/03-event-write-back-pwa-install/03-PATTERNS.md @apps/pwa/vite.config.ts Task 1: VitePWA manifest + service worker (auth-safe denylist) + iOS head/icons apps/pwa/vite.config.ts, apps/pwa/index.html, apps/pwa/public/icon-192.png, apps/pwa/public/icon-512.png, apps/pwa/public/apple-touch-icon.png - apps/pwa/vite.config.ts (existing — keep the proxy block incl. /callback verbatim; add VitePWA to plugins) - .planning/phases/03-event-write-back-pwa-install/03-RESEARCH.md (§Pattern 5 — full VitePWA config; required icons; head meta; §Pitfall 1 /callback denylist; §Pitfall 6 dev-mode SW caveat) - .planning/phases/03-event-write-back-pwa-install/03-UI-SPEC.md (§PWA Manifest Contract — exact field values; §SW critical denylist) - apps/pwa/index.html (existing head to extend) Add the `VitePWA` plugin to the existing `plugins` array in vite.config.ts per RESEARCH.md Pattern 5: `registerType:'autoUpdate'`; `workbox.navigateFallback:'/index.html'`; `workbox.navigateFallbackDenylist: [/^\/callback/, /^\/api\//, /^\/health/]` (CRITICAL — OIDC + API must reach the server); `workbox.runtimeCaching: []` (no API caching). `manifest`: name "FamilySync", short_name "FamilySync", description "Family calendar and lists", theme_color "#4A90D9", background_color "#FFFFFF", display "standalone", scope "/", start_url "/", icons 192/512/512-maskable per the contract. Keep the existing `server.proxy` block (including `/callback`) exactly as-is.Generate the three icon PNGs into apps/pwa/public/: `icon-192.png` (192×192), `icon-512.png` (512×512), `apple-touch-icon.png` (180×180). Create a simple solid `#4A90D9` background with a white "F" / calendar glyph using an available CLI tool (ImageMagick `convert`, `sharp` via a one-off node script, or similar). If no image tool is available, set autonomous:false is NOT needed — emit minimal valid PNGs programmatically (node Buffer / sharp). The icons must be valid PNGs at the exact pixel dimensions.
Add to apps/pwa/index.html `<head>` the five entries from RESEARCH.md Pattern 5: apple-touch-icon link (180×180), theme-color meta (#4A90D9), apple-mobile-web-app-capable yes, apple-mobile-web-app-status-bar-style default, apple-mobile-web-app-title FamilySync.
<threat_model>
Trust Boundaries
| Boundary | Description |
|---|---|
| service worker → navigation | The SW can intercept navigations including the OIDC callback |
STRIDE Threat Register
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|---|---|---|---|---|
| T-03-20 | Spoofing | SW serving a cached shell for /callback, breaking OIDC code exchange / iOS standalone login | mitigate | navigateFallbackDenylist: [/^\/callback/, /^\/api\//, /^\/health/]; verified against a production build (Pitfall 1/6); Gate 2 confirms end-to-end (Plan 08) |
| T-03-21 | Tampering | SW caching authenticated API responses | mitigate | runtimeCaching: [] — no /api caching; /api in denylist |
| T-03-22 | Information Disclosure | manifest/icons leaking nothing sensitive | accept | Static public assets only; no secrets in manifest |
</threat_model>
- `pnpm --filter @familysync/pwa build` emits valid manifest.webmanifest + SW. - `/callback`, `/api/`, `/health` all in navigateFallbackDenylist. - `pnpm --filter @familysync/pwa test` green (InstallPrompt + existing); tsc --noEmit passes.<success_criteria>
- PWA-01: app installs to Home Screen (manifest + SW, standalone) on iOS and Android.
- PWA-02: first-time guided install (iOS walkthrough + Android prompt); never shown when installed.
- OIDC
/callbackis never SW-intercepted (Gate 2 prerequisite). </success_criteria>