Skip to content

feat(push): 2-hourly push-scan cron so imminent moments/reminders aren't missed - #226

Merged
NewWorldVenture merged 1 commit into
mainfrom
claude/connect-8ysp00
Jul 5, 2026
Merged

NewWorldVenture merged 1 commit into
mainfrom
claude/connect-8ysp00

Conversation

@NewWorldVenture

Copy link
Copy Markdown
Owner

What & why

Closes the last actionable item on the friction backlog — #5 push notifications — by fixing its one real gap: delivery timing.

The web-push delivery path already existed and is fully wired:

  • lib/server/push.ts — web-push (VAPID) + native FCM dispatch, prunes stale subscriptions
  • push_devices table (migration 0035), public/sw.js service worker, subscribe/unsubscribe routes, settings toggle
  • imminentMomentNotices (imminent moment / leave-by / birthday) already feeds generateFamilyNotifications

The gap: those pushes were only dispatched by the once-daily /api/cron/notifications run (11:00 UTC), which also runs the email digest. One cadence for both channels means a moment or reminder added after the daily run for later that same day was missed entirely until the next day — after it mattered. You can't just bump the shared cron: that would email families up to 8× a day.

Change

  • New /api/cron/push-scan (app/api/cron/push-scan/route.ts) running every 2h (0 */2 * * *, added to vercel.json). It regenerates each family's notifications and dispatches any un-pushed ones only — deliberately no email, so the digest stays daily on /api/cron/notifications.
  • Safe to overlap the daily cron: generation dedups permanently by related_id, push is gated on pushed_at and email on sent_at, so nothing double-sends.
  • Live delivery still degrades honestly when VAPID/FCM keys are absent (sends are skipped and reported, never faked).

No schema change, no new dependency — reuses the exported generateFamilyNotifications + dispatchPendingPushes.

Docs

Verification

  • tsc --noEmit — clean
  • eslint — clean
  • vitest run — 1649 passed
  • next build — compiled successfully; route registered as ƒ /api/cron/push-scan

Remaining (human-owned, unchanged)

Apply pending prod migrations (docs/PENDING_PROD_MIGRATIONS.md); set NEXT_PUBLIC_VAPID_PUBLIC_KEY/VAPID_PRIVATE_KEY (web) or FCM_SERVER_KEY (native) to light up live push; maps/ETA key (#6); GIF provider key; Stripe Issuing.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VJs1Px4GTVtA1jmzDZ4ShU


Generated by Claude Code

…n't missed

Friction #5 (push notifications) — the web-push delivery path already existed
(lib/server/push.ts, push_devices, service worker, subscribe routes, settings
toggle) and imminentMomentNotices was wired into generateFamilyNotifications,
but pushes were only dispatched by the once-daily /api/cron/notifications run,
which also owns the email digest. Same cadence for both meant a moment or
reminder added after the daily run for later that day was missed until the
next day — after it mattered.

Add /api/cron/push-scan (every 2h) that regenerates notifications and
dispatches pending pushes only — no email, so the digest stays daily. Safe to
overlap the daily cron: generation dedups by related_id, push is gated on
pushed_at and email on sent_at, so nothing double-sends. Live delivery still
degrades honestly when VAPID/FCM keys are absent (skips, never fakes success).

Also reconcile FRICTION_BACKLOG.md: #2/#4/#7/#10 were shipped but still read
"Todo"; marked done with their landing files. Update AGENT_HANDOFF.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VJs1Px4GTVtA1jmzDZ4ShU
@vercel

vercel Bot commented Jul 5, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
familyos Ready Ready Preview, Comment Jul 5, 2026 1:31am

Request Review

@NewWorldVenture
NewWorldVenture marked this pull request as ready for review July 5, 2026 01:31
@NewWorldVenture
NewWorldVenture merged commit 2891285 into main Jul 5, 2026
4 checks passed

This branch was successfully deployed

2 active deployments
Production — 8e1412ba Deployed Jul 5, 2026 by vercel[bot]
Preview — 8e1412ba Deployed Jul 5, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants