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:
@@ -14,24 +14,24 @@ requirements: [NOTIF-01]
|
||||
must_haves:
|
||||
truths:
|
||||
- "Every minute the scheduler scans for SHARED (isShared=true) TIMED (allDay=false) events whose dtstartUtc is in [now+14min, now+16min] and dispatches a reminder to ALL members' subscriptions (NOTIF-01, D-05/D-06)"
|
||||
- "All-day events get no reminder (D-07); non-shared events get no reminder (D-05)"
|
||||
- "The same (eventUid, minuteBucket) never fires twice — in-memory dedup Set prevents the window-boundary double-fire (RESEARCH Pitfall 5 / Open Question 3)"
|
||||
- 'All-day events get no reminder (D-07); non-shared events get no reminder (D-05)'
|
||||
- 'The same (eventUid, minuteBucket) never fires twice — in-memory dedup Set prevents the window-boundary double-fire (RESEARCH Pitfall 5 / Open Question 3)'
|
||||
- "Reminder copy uses the event title: title '{EventTitle}', body 'Starts in 15 min' (D-02, depends on calendar_events.title)"
|
||||
- "An empty shared-calendar set (Family calendar not yet created per D-16) produces zero sends and no crash"
|
||||
- 'An empty shared-calendar set (Family calendar not yet created per D-16) produces zero sends and no crash'
|
||||
artifacts:
|
||||
- path: "apps/api/src/broker/reminderScheduler.ts"
|
||||
provides: "startReminderScheduler() + runReminderCheck() — node-cron 1-min shared-timed-event scan + dispatch"
|
||||
exports: ["startReminderScheduler", "runReminderCheck"]
|
||||
- path: 'apps/api/src/broker/reminderScheduler.ts'
|
||||
provides: 'startReminderScheduler() + runReminderCheck() — node-cron 1-min shared-timed-event scan + dispatch'
|
||||
exports: ['startReminderScheduler', 'runReminderCheck']
|
||||
min_lines: 40
|
||||
key_links:
|
||||
- from: "apps/api/src/broker/reminderScheduler.ts"
|
||||
to: "apps/api/src/lib/pushDispatcher.ts"
|
||||
via: "dispatchPush per subscription for each due shared timed event"
|
||||
pattern: "dispatchPush"
|
||||
- from: "apps/api/src/index.ts"
|
||||
to: "startReminderScheduler"
|
||||
via: "isMainModule startup guard"
|
||||
pattern: "startReminderScheduler"
|
||||
- from: 'apps/api/src/broker/reminderScheduler.ts'
|
||||
to: 'apps/api/src/lib/pushDispatcher.ts'
|
||||
via: 'dispatchPush per subscription for each due shared timed event'
|
||||
pattern: 'dispatchPush'
|
||||
- from: 'apps/api/src/index.ts'
|
||||
to: 'startReminderScheduler'
|
||||
via: 'isMainModule startup guard'
|
||||
pattern: 'startReminderScheduler'
|
||||
---
|
||||
|
||||
<objective>
|
||||
@@ -86,19 +86,21 @@ Output: reminderScheduler.ts (startReminderScheduler + runReminderCheck) wired i
|
||||
</feature>
|
||||
|
||||
<threat_model>
|
||||
|
||||
## Trust Boundaries
|
||||
|
||||
| Boundary | Description |
|
||||
|----------|-------------|
|
||||
| Boundary | Description |
|
||||
| ------------------------------ | -------------------------------------------------------------------- |
|
||||
| reminder query → push audience | reminder eligibility is decided by the SQL WHERE, not by any request |
|
||||
|
||||
## STRIDE Threat Register
|
||||
|
||||
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
||||
|-----------|----------|-----------|-------------|-----------------|
|
||||
| T-05-17 | Information Disclosure | reminder leaking a personal-calendar event | mitigate | D-05 enforced in the QUERY: WHERE calendars.isShared = true — personal events are never selected, not merely hidden in copy |
|
||||
| T-05-18 | Denial of Service | duplicate reminder storm at window boundary | mitigate | in-memory dedup Set keyed (uid, minuteBucket); per-event try/catch isolates failures |
|
||||
| T-05-19 | Denial of Service | one bad subscription aborting the cycle | mitigate | per-subscription try/catch; dispatchPush already swallows + prunes 410/404 |
|
||||
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
||||
| --------- | ---------------------- | ------------------------------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------- |
|
||||
| T-05-17 | Information Disclosure | reminder leaking a personal-calendar event | mitigate | D-05 enforced in the QUERY: WHERE calendars.isShared = true — personal events are never selected, not merely hidden in copy |
|
||||
| T-05-18 | Denial of Service | duplicate reminder storm at window boundary | mitigate | in-memory dedup Set keyed (uid, minuteBucket); per-event try/catch isolates failures |
|
||||
| T-05-19 | Denial of Service | one bad subscription aborting the cycle | mitigate | per-subscription try/catch; dispatchPush already swallows + prunes 410/404 |
|
||||
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
@@ -108,10 +110,11 @@ Output: reminderScheduler.ts (startReminderScheduler + runReminderCheck) wired i
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
|
||||
- Failing test committed (RED).
|
||||
- runReminderCheck + startReminderScheduler implemented; test passes (GREEN).
|
||||
- D-05 shared-only (query-enforced), D-07 all-day-excluded, dedup, empty-set no-op, title fallback all verified.
|
||||
</success_criteria>
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
Create `.planning/phases/05-web-push-notifications/05-06-SUMMARY.md` with RED/GREEN commits.
|
||||
|
||||
Reference in New Issue
Block a user