style(13-03): apply Prettier formatting across repo

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.
This commit is contained in:
Lucas Berger
2026-06-11 20:35:18 -04:00
parent 4bc0445173
commit 982438dc10
398 changed files with 19050 additions and 16382 deletions
@@ -3,7 +3,7 @@ phase: 03-event-write-back-pwa-install
plan: 07
type: execute
wave: 3
depends_on: ["03-01"]
depends_on: ['03-01']
files_modified:
- apps/pwa/vite.config.ts
- apps/pwa/index.html
@@ -18,27 +18,27 @@ user_setup: []
must_haves:
truths:
- "The production build emits a valid manifest.webmanifest with name/icons/display:standalone/scope:/ and a service worker"
- 'The production build emits a valid manifest.webmanifest with name/icons/display:standalone/scope:/ and a service worker'
- "The service worker's navigateFallbackDenylist excludes /callback, /api/, /health so the OIDC redirect is never intercepted (Gate 2 risk)"
- "On iOS Safari non-standalone, a first-visit install banner appears with a 5-step annotated Add-to-Home-Screen walkthrough"
- "On Android, an Install banner appears only when beforeinstallprompt fires and triggers the native prompt"
- "Neither install surface renders when the app is already installed (display-mode: standalone)"
- 'On iOS Safari non-standalone, a first-visit install banner appears with a 5-step annotated Add-to-Home-Screen walkthrough'
- 'On Android, an Install banner appears only when beforeinstallprompt fires and triggers the native prompt'
- 'Neither install surface renders when the app is already installed (display-mode: standalone)'
artifacts:
- path: "apps/pwa/vite.config.ts"
provides: "VitePWA manifest + SW config with auth-safe denylist"
contains: "navigateFallbackDenylist"
- path: "apps/pwa/src/components/InstallPrompt.tsx"
provides: "iOS walkthrough banner/sheet + Android beforeinstallprompt banner"
- path: 'apps/pwa/vite.config.ts'
provides: 'VitePWA manifest + SW config with auth-safe denylist'
contains: 'navigateFallbackDenylist'
- path: 'apps/pwa/src/components/InstallPrompt.tsx'
provides: 'iOS walkthrough banner/sheet + Android beforeinstallprompt banner'
min_lines: 80
key_links:
- from: "apps/pwa/vite.config.ts"
to: "OIDC /callback"
via: "navigateFallbackDenylist excludes /callback"
pattern: "callback"
- from: "apps/pwa/src/components/InstallPrompt.tsx"
to: "iOS standalone detection"
via: "isIOSSafariNonStandalone + display-mode media query"
pattern: "standalone"
- from: 'apps/pwa/vite.config.ts'
to: 'OIDC /callback'
via: 'navigateFallbackDenylist excludes /callback'
pattern: 'callback'
- from: 'apps/pwa/src/components/InstallPrompt.tsx'
to: 'iOS standalone detection'
via: 'isIOSSafariNonStandalone + display-mode media query'
pattern: 'standalone'
---
<objective>
@@ -84,6 +84,7 @@ Output: configured VitePWA build, install icons + meta, InstallPrompt mounted in
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.
</action>
<verify>
<automated>cd /home/luc/Projects/familysync && pnpm --filter @familysync/pwa build && test -f apps/pwa/dist/manifest.webmanifest && node -e "const m=require('./apps/pwa/dist/manifest.webmanifest');if(m.display!=='standalone'||m.scope!=='/'||!m.icons.some(i=>i.sizes==='512x512'))process.exit(1)" && grep -q "navigateFallbackDenylist" apps/pwa/vite.config.ts && grep -q "apple-touch-icon" apps/pwa/index.html</automated>
@@ -128,19 +129,21 @@ Output: configured VitePWA build, install icons + meta, InstallPrompt mounted in
</tasks>
<threat_model>
## Trust Boundaries
| Boundary | Description |
|----------|-------------|
| 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 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>
<verification>
@@ -150,10 +153,11 @@ Output: configured VitePWA build, install icons + meta, InstallPrompt mounted in
</verification>
<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 `/callback` is never SW-intercepted (Gate 2 prerequisite).
</success_criteria>
</success_criteria>
<output>
Create `.planning/phases/03-event-write-back-pwa-install/03-07-SUMMARY.md` when done.