From dbf370b18c3c80a7cb33249b31ad26cdf4c4a6ef Mon Sep 17 00:00:00 2001 From: Lucas Berger Date: Tue, 9 Jun 2026 18:43:43 -0400 Subject: [PATCH] docs(05): mark research open questions resolved --- .../phases/05-web-push-notifications/05-RESEARCH.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.planning/phases/05-web-push-notifications/05-RESEARCH.md b/.planning/phases/05-web-push-notifications/05-RESEARCH.md index 54cb79e..03fa2d8 100644 --- a/.planning/phases/05-web-push-notifications/05-RESEARCH.md +++ b/.planning/phases/05-web-push-notifications/05-RESEARCH.md @@ -721,22 +721,24 @@ Route tests in `tests/routes/` use a real MariaDB connection with `vi.mock('../. --- -## Open Questions +## Open Questions (RESOLVED) + +> All three questions were resolved during planning (Phase 5 plans, 2026-06-09). Resolutions locked below. 1. **Does event-change detection require a new syncCalendar hook or a separate table diff?** - What we know: `syncCalendar` does an `onDuplicateKeyUpdate` upsert but does not return which rows changed. - What's unclear: To detect NOTIF-03 changes (new vs modified vs deleted event), the sync must compare old vs new state. The current sync has no "what changed" output. - - Recommendation: Add a `pushChangedEvents()` side-effect callback parameter to `syncCalendar` (or a post-sync query comparing `updatedAt` timestamps) that returns newly upserted/deleted events for push dispatch. Alternatively, use a DB trigger or a separate "last_seen_etag" comparison in the scheduler. + - **RESOLVED (Plan 05-07):** Add an `onChanges` side-effect callback parameter to `syncCalendar`, consumed by the poller (external changes) and the outbox resync (this-member writes). The syncing userId is the actor and is suppressed from its own notifications. No DB trigger. 2. **Should VAPID_PUBLIC_KEY be injected at build time (VITE_VAPID_PUBLIC_KEY) or fetched at runtime (GET /api/push/vapid-public-key)?** - What we know: Build-time injection is simpler. Runtime fetch allows key rotation without rebuilds. - What's unclear: How often VAPID keys will rotate in practice. - - Recommendation: Use GET /api/push/vapid-public-key endpoint (unauthenticated). Fetched once by usePushSubscription hook before subscribe. Cached in sessionStorage. + - **RESOLVED (Plan 05-04):** Runtime fetch via `GET /api/push/vapid-public-key` (unauthenticated). Fetched once by the usePushSubscription hook before subscribe. Enables key rotation without a PWA rebuild. 3. **Reminder deduplication strategy: column flag vs separate table?** - What we know: The 1-min cron window approach risks double-firing for events at the window boundary. - What's unclear: Whether a `sent_reminders` table is overkill for a two-person household. - - Recommendation: Add a `sentAt` timestamp column to calendarEvents for reminder tracking, or use a simple in-memory Set of `${eventUid}:${minuteBucket}` pairs per process (acceptable for single-process deployment per D-12). + - **RESOLVED (Plan 05-06):** In-memory `Set<${eventUid}:${minuteBucket}>` per process (acceptable for the single-process deployment, per D-12). No `sent_reminders` table. Tradeoff accepted: a process restart loses the dedup set, so a reminder could re-fire once after a restart that coincides with the 2-minute send window — tolerable for a two-person household. ---