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
@@ -14,24 +14,24 @@ requirements: [NOTIF-02]
must_haves:
truths:
- "When member A adds/checks-off/deletes/renames an item or list, the OTHER member receives a coalesced push naming the actor + list + change count (NOTIF-02, D-01/D-02/D-03)"
- "Reorder (position) PATCHes do NOT trigger any push (D-01)"
- "The actor never receives a push for their own change — fan-out filters userId != actorId (D-03)"
- "List-change pushes are scoped: only members who can access the list (owner or list_shares) get the push — never broadcast to all members"
- 'When member A adds/checks-off/deletes/renames an item or list, the OTHER member receives a coalesced push naming the actor + list + change count (NOTIF-02, D-01/D-02/D-03)'
- 'Reorder (position) PATCHes do NOT trigger any push (D-01)'
- 'The actor never receives a push for their own change — fan-out filters userId != actorId (D-03)'
- 'List-change pushes are scoped: only members who can access the list (owner or list_shares) get the push — never broadcast to all members'
artifacts:
- path: "apps/api/src/lib/listChangeDispatcher.ts"
provides: "notifyListChange(listId, actorId) — resolves actor name + list name + accessible subscriptions, calls coalesceListPush"
exports: ["notifyListChange"]
- path: 'apps/api/src/lib/listChangeDispatcher.ts'
provides: 'notifyListChange(listId, actorId) — resolves actor name + list name + accessible subscriptions, calls coalesceListPush'
exports: ['notifyListChange']
min_lines: 25
key_links:
- from: "apps/api/src/routes/lists.ts"
to: "apps/api/src/lib/listChangeDispatcher.ts"
via: "notifyListChange called at each meaningful mutation (not reorder)"
pattern: "notifyListChange"
- from: "apps/api/src/lib/listChangeDispatcher.ts"
to: "apps/api/src/lib/pushCoalescer.ts"
via: "coalesceListPush with accessible-subscription dispatch + excludeUserId=actorId"
pattern: "coalesceListPush"
- from: 'apps/api/src/routes/lists.ts'
to: 'apps/api/src/lib/listChangeDispatcher.ts'
via: 'notifyListChange called at each meaningful mutation (not reorder)'
pattern: 'notifyListChange'
- from: 'apps/api/src/lib/listChangeDispatcher.ts'
to: 'apps/api/src/lib/pushCoalescer.ts'
via: 'coalesceListPush with accessible-subscription dispatch + excludeUserId=actorId'
pattern: 'coalesceListPush'
---
<objective>
@@ -112,19 +112,21 @@ Output: listChangeDispatcher.ts (notifyListChange) called from the list/item mut
</tasks>
<threat_model>
## Trust Boundaries
| Boundary | Description |
|----------|-------------|
| Boundary | Description |
| ----------------------------- | -------------------------------------------------------------- |
| list mutation → push audience | the audience must be derived from list access, not the request |
## STRIDE Threat Register
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|-----------|----------|-----------|-------------|-----------------|
| T-05-14 | Information Disclosure | list-change push to a non-member | mitigate | audience = owner list_shares only (same scope as SSE / GET /api/lists); never all users |
| T-05-15 | Information Disclosure | item text in payload | mitigate | D-02 generic copy — coalescer payload carries no item text, only actor + list name + count |
| T-05-16 | Spoofing | actor notified of own change | mitigate | excludeUserId = actorId; fan-out filters userId != actorId (D-03) |
| Threat ID | Category | Component | Disposition | Mitigation Plan |
| --------- | ---------------------- | -------------------------------- | ----------- | ------------------------------------------------------------------------------------------ |
| T-05-14 | Information Disclosure | list-change push to a non-member | mitigate | audience = owner list_shares only (same scope as SSE / GET /api/lists); never all users |
| T-05-15 | Information Disclosure | item text in payload | mitigate | D-02 generic copy — coalescer payload carries no item text, only actor + list name + count |
| T-05-16 | Spoofing | actor notified of own change | mitigate | excludeUserId = actorId; fan-out filters userId != actorId (D-03) |
</threat_model>
<verification>
@@ -133,10 +135,11 @@ Output: listChangeDispatcher.ts (notifyListChange) called from the list/item mut
</verification>
<success_criteria>
- Meaningful list/item mutations push a coalesced, generic, actor-attributed notification to accessible non-actor members.
- Reorder and list-create push nothing.
- Audience strictly scoped to list access; actor suppressed.
</success_criteria>
</success_criteria>
<output>
Create `.planning/phases/05-web-push-notifications/05-05-SUMMARY.md` when done.