feat: update push notification subscription flow and remove deprecated opt-in component
All checks were successful
Chore App Build, Test, and Push Docker Images / build-and-push (push) Successful in 2m43s
All checks were successful
Chore App Build, Test, and Push Docker Images / build-and-push (push) Successful in 2m43s
This commit is contained in:
10
.github/specs/feat-parent-chore-notifications.md
vendored
10
.github/specs/feat-parent-chore-notifications.md
vendored
@@ -181,8 +181,8 @@ email_digest_enabled: boolean;
|
||||
- `title`, `body`, and a `data` object containing `child_id`, `entity_id`, `entity_type`, `approve_token`, and `deny_token`
|
||||
- An `actions` array: `[{ action: 'approve', title: 'Approve' }, { action: 'deny', title: 'Deny' }]`
|
||||
- Note: the `actions` field is silently ignored by browsers that do not support it (e.g. iOS Safari); the notification body tap still works normally.
|
||||
3. On parent mount (e.g., `ParentLayout.vue` or `App.vue`), request notification permission and, if granted, retrieve the `PushSubscription` from the browser and `POST` it to `/api/push-subscription`, including the user's IANA timezone string: `Intl.DateTimeFormat().resolvedOptions().timeZone`.
|
||||
4. Clean up: if permission is denied or revoked, call `DELETE /api/push-subscription` with `{ endpoint }` in the body to remove that specific subscription.
|
||||
3. In `LoginButton.vue` (`submit()`), after a successful PIN authentication, call `subscribeToPushWithResult()` (fire-and-forget, not awaited) — the PIN submit button click satisfies the browser's user-gesture requirement. If the parent has already granted permission, the browser returns the existing subscription silently and the call is idempotent. No floating opt-in banner is displayed anywhere in the app.
|
||||
4. Clean up: The **Push Notifications** toggle in `UserProfile.vue` handles explicit unsubscription — toggling off calls `unsubscribeFromPush()` which sends `DELETE /api/push-subscription` with `{ endpoint }` in the body, removing that specific subscription for the current user.
|
||||
5. The Service Worker's `notificationclick` handler must:
|
||||
- Close the notification with `event.notification.close()`
|
||||
- If `event.action === 'approve'`: `fetch('/api/digest-action/<approve_token>')` (GET, no credentials needed — the signed token IS the credential).
|
||||
@@ -210,7 +210,7 @@ email_digest_enabled: boolean;
|
||||
- [ ] Tapping the reward notification body opens the app, scrolls to the pending reward within the rewards section of `ParentView`
|
||||
- [ ] If the app is already open in another tab, tapping the notification body focuses that tab and navigates it (no duplicate window opened)
|
||||
- [ ] No browser notification is shown for a reward request the child cannot afford
|
||||
- [x] Notification permission is requested on parent login/mount
|
||||
- [x] Notification permission is requested on parent PIN entry (LoginButton.vue submit)
|
||||
- [x] If permission is denied, no subscription is posted to the backend
|
||||
- [x] Push subscription `POST` body includes the browser's IANA timezone string
|
||||
- [x] User Profile page shows an "Email Digest" toggle
|
||||
@@ -286,8 +286,8 @@ The plan covers 9 scenario groups (41 automated test cases + 1 manual QA checkli
|
||||
|
||||
- [x] PWA manifest (`public/manifest.json`) is present and linked in `index.html`
|
||||
- [x] Service Worker is registered and handles `push` and `notificationclick` events
|
||||
- [x] Parent is prompted for notification permission on mount
|
||||
- [x] Subscription is posted to the backend on permission grant and removed on revoke/deny
|
||||
- [x] Parent is prompted for notification permission on PIN entry (LoginButton.vue)
|
||||
- [x] Subscription is posted to the backend on PIN entry when permission is granted; removed on explicit toggle-off in UserProfile
|
||||
- [ ] Native notification appears when a chore is completed with the tab backgrounded, with "Approve" and "Deny" action buttons
|
||||
- [ ] Native notification appears when a child requests an affordable reward with the tab backgrounded, with "Approve" and "Deny" action buttons
|
||||
- [ ] No native notification appears for a reward request the child cannot afford
|
||||
|
||||
Reference in New Issue
Block a user