docs(05): mark research open questions resolved

This commit is contained in:
Lucas Berger
2026-06-09 18:43:43 -04:00
parent 1ecca03f53
commit dbf370b18c
@@ -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?** 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 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. - 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)?** 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 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. - 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?** 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 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. - 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.
--- ---