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
@@ -12,19 +12,19 @@ requirements: [NOTIF-01, NOTIF-02, NOTIF-03]
must_haves:
truths:
- "dispatchPush sends a VAPID-signed push via webpush.sendNotification with the dual-format payload"
- "On a 410 or 404 from the push service, the subscription row is deleted from push_subscriptions (D-11 prune)"
- "On 201/transient errors the subscription is NOT deleted; the error is logged and dispatch continues"
- "The payload body carries both web_push:8030 + notification{} (iOS 18.4+ declarative) AND legacy title/body/tag/data (iOS 16.4-18.3 + Android)"
- 'dispatchPush sends a VAPID-signed push via webpush.sendNotification with the dual-format payload'
- 'On a 410 or 404 from the push service, the subscription row is deleted from push_subscriptions (D-11 prune)'
- 'On 201/transient errors the subscription is NOT deleted; the error is logged and dispatch continues'
- 'The payload body carries both web_push:8030 + notification{} (iOS 18.4+ declarative) AND legacy title/body/tag/data (iOS 16.4-18.3 + Android)'
artifacts:
- path: "apps/api/src/lib/pushDispatcher.ts"
provides: "dispatchPush(subscription, notification, dbRowId) — single send + prune helper"
exports: ["dispatchPush", "buildPushBody"]
- path: 'apps/api/src/lib/pushDispatcher.ts'
provides: 'dispatchPush(subscription, notification, dbRowId) — single send + prune helper'
exports: ['dispatchPush', 'buildPushBody']
min_lines: 30
key_links:
- from: "apps/api/src/lib/pushDispatcher.ts"
to: "push_subscriptions table"
via: "db.delete on 410/404"
- from: 'apps/api/src/lib/pushDispatcher.ts'
to: 'push_subscriptions table'
via: 'db.delete on 410/404'
pattern: "delete\\(pushSubscriptions\\)"
---
@@ -77,19 +77,21 @@ Output: `apps/api/src/lib/pushDispatcher.ts` with `dispatchPush` + `buildPushBod
</feature>
<threat_model>
## Trust Boundaries
| Boundary | Description |
|----------|-------------|
| Boundary | Description |
| ----------------------------- | ----------------------------------------------------------------- |
| API → push service (APNs/FCM) | server signs with VAPID private key; response status is untrusted |
## STRIDE Threat Register
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|-----------|----------|-----------|-------------|-----------------|
| T-05-03 | Cryptography misuse | VAPID signing | mitigate | Use web-push library only; never hand-roll (RESEARCH Don't Hand-Roll) |
| T-05-04 | Denial of Service | malformed push response / per-sub crash | mitigate | dispatchPush catches per-subscription; one failed send never aborts a fan-out loop |
| T-05-05 | Information Disclosure | error logs | mitigate | Log statusCode + err.message only, never the subscription keys or payload body |
| Threat ID | Category | Component | Disposition | Mitigation Plan |
| --------- | ---------------------- | --------------------------------------- | ----------- | ---------------------------------------------------------------------------------- |
| T-05-03 | Cryptography misuse | VAPID signing | mitigate | Use web-push library only; never hand-roll (RESEARCH Don't Hand-Roll) |
| T-05-04 | Denial of Service | malformed push response / per-sub crash | mitigate | dispatchPush catches per-subscription; one failed send never aborts a fan-out loop |
| T-05-05 | Information Disclosure | error logs | mitigate | Log statusCode + err.message only, never the subscription keys or payload body |
</threat_model>
<verification>
@@ -98,10 +100,11 @@ Output: `apps/api/src/lib/pushDispatcher.ts` with `dispatchPush` + `buildPushBod
</verification>
<success_criteria>
- Failing test written and committed (RED).
- dispatchPush + buildPushBody implemented; test passes (GREEN).
- 410/404 prune verified; transient/success no-prune verified.
</success_criteria>
</success_criteria>
<output>
Create `.planning/phases/05-web-push-notifications/05-02-SUMMARY.md` with RED/GREEN/REFACTOR commits.