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:
@@ -15,26 +15,26 @@ requirements: [NOTIF-01, NOTIF-02, NOTIF-03]
|
||||
|
||||
must_haves:
|
||||
truths:
|
||||
- "A single master on/off toggle in a Settings sheet (opened from the avatar) enables/disables all FamilySync push notifications (D-09)"
|
||||
- "On app open, if OS permission is still granted but the push subscription is missing/expired, the app silently re-subscribes — no user action (D-10)"
|
||||
- "If the OS permission itself was revoked (denied) and notifications were previously enabled, a persistent permission-denied banner appears with OS-specific re-enable instructions (D-10)"
|
||||
- "The avatar in AppNav (phone + desktop) is a real button opening the Settings sheet (a11y: aria-label, 44px target)"
|
||||
- 'A single master on/off toggle in a Settings sheet (opened from the avatar) enables/disables all FamilySync push notifications (D-09)'
|
||||
- 'On app open, if OS permission is still granted but the push subscription is missing/expired, the app silently re-subscribes — no user action (D-10)'
|
||||
- 'If the OS permission itself was revoked (denied) and notifications were previously enabled, a persistent permission-denied banner appears with OS-specific re-enable instructions (D-10)'
|
||||
- 'The avatar in AppNav (phone + desktop) is a real button opening the Settings sheet (a11y: aria-label, 44px target)'
|
||||
artifacts:
|
||||
- path: "apps/pwa/src/components/SettingsSheet.tsx"
|
||||
provides: "Settings bottom sheet with the master NotificationToggle (D-09)"
|
||||
exports: ["SettingsSheet"]
|
||||
- path: "apps/pwa/src/components/PermissionDeniedBanner.tsx"
|
||||
provides: "persistent OS-revoked banner with re-enable instructions (D-10)"
|
||||
exports: ["PermissionDeniedBanner"]
|
||||
- path: 'apps/pwa/src/components/SettingsSheet.tsx'
|
||||
provides: 'Settings bottom sheet with the master NotificationToggle (D-09)'
|
||||
exports: ['SettingsSheet']
|
||||
- path: 'apps/pwa/src/components/PermissionDeniedBanner.tsx'
|
||||
provides: 'persistent OS-revoked banner with re-enable instructions (D-10)'
|
||||
exports: ['PermissionDeniedBanner']
|
||||
key_links:
|
||||
- from: "apps/pwa/src/hooks/usePushSubscription.ts"
|
||||
to: "pushManager.getSubscription"
|
||||
via: "mount health-check → silent re-subscribe when permission granted but no subscription"
|
||||
pattern: "getSubscription"
|
||||
- from: "apps/pwa/src/components/AppNav.tsx"
|
||||
to: "apps/pwa/src/components/SettingsSheet.tsx"
|
||||
via: "avatar button onClick opens settings"
|
||||
pattern: "onOpenSettings"
|
||||
- from: 'apps/pwa/src/hooks/usePushSubscription.ts'
|
||||
to: 'pushManager.getSubscription'
|
||||
via: 'mount health-check → silent re-subscribe when permission granted but no subscription'
|
||||
pattern: 'getSubscription'
|
||||
- from: 'apps/pwa/src/components/AppNav.tsx'
|
||||
to: 'apps/pwa/src/components/SettingsSheet.tsx'
|
||||
via: 'avatar button onClick opens settings'
|
||||
pattern: 'onOpenSettings'
|
||||
---
|
||||
|
||||
<objective>
|
||||
@@ -140,19 +140,21 @@ Output: usePushSubscription gains the mount health-check + permission state; Set
|
||||
</tasks>
|
||||
|
||||
<threat_model>
|
||||
|
||||
## Trust Boundaries
|
||||
|
||||
| Boundary | Description |
|
||||
|----------|-------------|
|
||||
| Boundary | Description |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| client permission state → UI | Notification.permission + localStorage drive which surface shows; no server trust involved |
|
||||
|
||||
## STRIDE Threat Register
|
||||
|
||||
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
||||
|-----------|----------|-----------|-------------|-----------------|
|
||||
| T-05-23 | Tampering | silent re-subscribe without permission | mitigate | health-check only re-subscribes when Notification.permission==='granted'; never forces an OS dialog |
|
||||
| T-05-24 | Information Disclosure | XSS via copy | mitigate | all copy is plain-text JSX children (no dangerouslySetInnerHTML), matching existing InstallPrompt convention |
|
||||
| T-05-25 | Repudiation | toggle off leaves stale server subscription | mitigate | setEnabled off calls DELETE /api/push/subscription (Plan 05-04) so the server prunes the row |
|
||||
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
||||
| --------- | ---------------------- | ------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------ |
|
||||
| T-05-23 | Tampering | silent re-subscribe without permission | mitigate | health-check only re-subscribes when Notification.permission==='granted'; never forces an OS dialog |
|
||||
| T-05-24 | Information Disclosure | XSS via copy | mitigate | all copy is plain-text JSX children (no dangerouslySetInnerHTML), matching existing InstallPrompt convention |
|
||||
| T-05-25 | Repudiation | toggle off leaves stale server subscription | mitigate | setEnabled off calls DELETE /api/push/subscription (Plan 05-04) so the server prunes the row |
|
||||
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
@@ -161,10 +163,11 @@ Output: usePushSubscription gains the mount health-check + permission state; Set
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
|
||||
- Single master toggle (D-09) in an avatar-opened Settings sheet.
|
||||
- Silent re-subscribe on app open when permission still granted (D-10).
|
||||
- Permission-denied banner only in the OS-revoked-after-enabled case (D-10), with re-enable instructions.
|
||||
</success_criteria>
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
Create `.planning/phases/05-web-push-notifications/05-08-SUMMARY.md` when done.
|
||||
|
||||
Reference in New Issue
Block a user