Build urgent assignment alerts for reviewers 29 and 62 in separate organizations. A settings action explains the purpose before requesting browser permission; a current product preference decides whether the category is enabled. Denial leaves the in-app assignment inbox fully usable. The server binds each push subscription to a verified actor, tenant, and device record, ignoring forged identity fields from the browser. A shared tablet must not receive reviewer 29’s alerts after reviewer 62 signs in. The outgoing payload says New urgent assignment without case details that could appear on a lock screen. Clicking opens a safe route and fetches current assignments under server authorization. An outbox alert has one logical ID and a short expiry; the sender rechecks current preference and assignment before every attempt. If a case is reassigned, the stale alert is canceled. A push-service accepted response is recorded as Accepted, never as a proven display or read.
Project: private urgent assignment alerts
Build contract
- Test the permission request after a named settings action and verify the inbox after denial or missing API support.
- Register twice, forge account and tenant fields, then switch users on one browser and inspect subscription ownership.
- Inspect exact push payload, lock-screen text, click route, and current authorization after sign-out or reassignment.
- Fail push-service requests, expire an alert, replay the outbox, and verify one logical alert plus a durable inbox record.
Implementation checkpoint
function alertCanAttempt(alert, current) {
return current.now < alert.expiresAt && current.reviewerId === alert.reviewerId && current.optedIn;
}
console.log(alertCanAttempt({ expiresAt: 80, reviewerId: 29 }, { now: 47, reviewerId: 62, optedIn: true }));
// Output: falseCost and boundaries
For d devices the sender makes at least O(d) attempted deliveries per alert, with bounded retries adding further work. An indexed subscription lookup is approximately O(1), while a shared-device audit needs an explicit account-binding lifecycle. The in-app inbox retains current assignments under the product’s approved policy and remains queryable when push is unavailable. Short alert expiry lowers stale-notification risk but may miss a temporarily disconnected device; the inbox supplies the recovery path. Measure invalid endpoint cleanup, queue age, stale cancellations, opt-out latency, and inbox access. Do not calculate a delivered rate from push-service acceptance alone.
Failure drill
Request permission on page load and verify the test rejects that flow. Deny it and check the inbox still works. Try to bind reviewer 29’s endpoint to reviewer 62 through a forged POST; the server must ignore or reject the claim. Send an alert with the raw private case title and inspect the lock-screen output; the payload allowlist should fail the build. Sign out before clicking and verify the route does not reveal case 47. Reassign the case before a retry and confirm cancellation. Return an invalid endpoint response and remove its binding. Repeat the worker with the same event ID and confirm no duplicate logical alert appears.
Acceptance checks
- Browser permission and product preference both gate alerts without gating the inbox.
- Each subscription follows current verified account and device scope.
- Payload and click paths reveal no private case data without authorization.
- Expired and superseded alerts stop, and telemetry does not invent confirmed delivery.
Common Mistakes
- Equating browser permission with ongoing product opt-in.
- Trusting a client-supplied account ID when saving a subscription.
- Putting private case text in a lock-screen message.
- Retrying stale alerts and calling Accepted a read receipt.
Related lessons
Notification Opt-In and Channel Preference; Push Subscription Account Binding and Rotation; Private Notification Payload and Click Routing; Push Delivery Retries, Expiry, and Inbox Fallback.
