Skip to content

Package delivery schedule and Web Push notifications#10

Merged
kiyarose merged 3 commits into
mainfrom
pillpackdate
May 23, 2026
Merged

Package delivery schedule and Web Push notifications#10
kiyarose merged 3 commits into
mainfrom
pillpackdate

Conversation

@kiyarose
Copy link
Copy Markdown
Member

Summary

  • Adds user-configurable package delivery (weekday + local time + timezone) and in-app notifications while the tab is open.
  • Adds optional Web Push via the existing Cloudflare Worker: subscribe/unsubscribe routes, 15-minute cron for delivery windows, web-push-neo (Workers-compatible), and PWA injectManifest service worker with push handlers.
  • Debug mode: notifications test panel, minimal dev-push-sw.js, and weekly-token auth when Firebase service account is not configured locally.

Operator setup (after merge)

Worker: VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, optional FIREBASE_SERVICE_ACCOUNT_JSON via wrangler secret put; deploy with npm run worker:deploy. Local dev uses worker/.dev.vars.

GitHub Pages Variables: VITE_VAPID_PUBLIC_KEY, VITE_PUSH_API_BASE (worker origin, no trailing slash). Push is skipped in the client build if these are unset.

Test plan

  • npm run build:check
  • cd worker && npm run types
  • Settings: delivery day/time, notifications on → foreground alert when package is due
  • With worker + env vars: subscribe (POST /push/subscribe 200), delayed push with tab closed
  • Debug panel: SW ready, sync push, schedule delayed push

Made with Cursor

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds configurable weekly package delivery timing (weekday + local time + timezone), foreground notifications when packages are generated while the app is open, and optional Web Push notifications via the existing Cloudflare Worker (including subscribe/unsubscribe endpoints and a 15-minute cron job to send “package ready” reminders).

Changes:

  • Adds delivery scheduling fields to app settings and uses them to decide when weekly packages are generated and when to show foreground notifications.
  • Adds PWA push-capable service worker (injectManifest) plus a debug-only minimal push SW to avoid dev precache issues.
  • Extends the Worker with push subscription storage in KV, test routes, Firebase ID token verification (optional), and a cron sender that checks Firestore for synced users.

Reviewed changes

Copilot reviewed 35 out of 38 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
worker/wrangler.jsonc Adds nodejs compat, cron trigger, and PUSH_KV binding for push subscriptions/dedupe.
worker/src/index.ts Routes new push endpoints and adds a scheduled cron handler.
worker/src/env.ts Defines Worker environment bindings for push, VAPID keys, and optional Firebase SA JSON.
worker/src/cors.ts Extracts shared CORS helpers used by weekly summary + push endpoints.
worker/src/weeklySummary.ts Moves weekly AI summary handler into its own module (existing behavior + rate limit).
worker/src/pushTypes.ts Defines types for push subscription payloads and stored subscriber records.
worker/src/pushSend.ts Adds Workers-compatible Web Push sender via web-push-neo + VAPID configuration.
worker/src/pushHandlers.ts Implements subscribe/unsubscribe/status/test routes and authorization logic.
worker/src/pushDelivery.ts Adds delivery window checks and last-completed-week range helpers for cron.
worker/src/pushCron.ts Implements 15-minute cron to send due notifications and Firestore checks for synced users.
worker/src/firebaseAuth.ts Adds Firebase ID token verification via Google JWKS (jose).
worker/src/firestoreAdmin.ts Adds minimal Firestore Admin queries using service account JWT flow.
worker/README.md Documents KV setup, VAPID/Firebase secrets, and push routes/cron behavior.
worker/.dev.vars.example Adds local dev env placeholders for VAPID keys and optional service account JSON.
worker/package.json Adds date-fns, jose, and web-push-neo dependencies for push + Firestore auth.
worker/package-lock.json Locks the new Worker dependencies.
vite.config.ts Switches PWA strategy to injectManifest, adds dev SW options, and adjusts precache patterns.
src/pwa/sw.ts Adds Workbox-based service worker with push + notification click handlers.
public/dev-push-sw.js Adds minimal push-only SW for debug mode to avoid Workbox dev precache issues.
src/pwa/registerDebugPushSw.ts Registers/unregisters the debug push SW in debug builds when configured.
src/pwa/pushSubscribe.ts Implements push subscription creation, sync to Worker, and debug/test helpers.
src/pwa/notifications.ts Adds settings-aware permission prompting and foreground notification helpers.
src/main.tsx Uses debug push SW in debug mode (when configured) and normal PWA registration otherwise.
src/vite-env.d.ts Adds VITE_VAPID_PUBLIC_KEY and VITE_PUSH_API_BASE env typings.
src/shared/settings/appSettings.ts Adds notification + delivery scheduling settings and sanitization/defaults.
src/features/settings/SettingsPage.tsx Adds UI controls for notifications and delivery schedule + permission state messaging.
src/features/packages/packageDelivery.ts Adds logic to compute when a week becomes deliverable based on schedule.
src/features/packages/packageGenerator.ts Generates weekly packages only when deliverable; returns newly created rows.
src/features/packages/runPackageDelivery.ts Runs delivery generation and shows foreground notification when packages appear.
src/features/debug/debugNotifications.ts Adds a debug snapshot/actions layer for push + SW + permission testing.
src/features/debug/DebugPanel.tsx Adds a notifications debug section (SW status, subscribe, test push, delayed push).
src/App.tsx Runs package delivery periodically while visible and prompts permission after submits when relevant.
docs/FIREBASE.md Documents optional push + Firestore service account setup and behavior.
AGENTS.md Updates repo/operator notes for debug push SW, delivery schedule, and push setup/testing.
.github/workflows/gh-pages.yml Plumbs VITE_VAPID_PUBLIC_KEY and VITE_PUSH_API_BASE into the Pages build.
.env.local.example Adds local env examples for Web Push configuration.
.env.example Adds Web Push env placeholders for production builds.
Files not reviewed (1)
  • worker/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/features/settings/SettingsPage.tsx Outdated
Comment on lines +55 to +64
export function lastCompletedWeekRange(now: Date, timeZone: string) {
const todayKey = dateKeyInTimeZone(now, timeZone)
const today = parseISO(todayKey)
const lastCompleteWeekEnd = endOfWeek(subWeeks(today, 1), { weekStartsOn: 1 })
const lastCompleteWeekStart = startOfWeek(lastCompleteWeekEnd, { weekStartsOn: 1 })
return {
weekKey: format(lastCompleteWeekStart, "yyyy-'W'II"),
startKey: format(lastCompleteWeekStart, 'yyyy-MM-dd'),
endKey: format(lastCompleteWeekEnd, 'yyyy-MM-dd'),
}
Comment on lines +173 to +180
export async function handlePushStatus(request: Request, env: PushEnv) {
const origin = request.headers.get('Origin')
if (request.method === 'OPTIONS') return corsResponse(null, 204, env, origin)
if (request.method !== 'GET') {
return corsJson({ error: 'Method not allowed' }, 405, env, origin)
}
return corsJson({ vapidConfigured: vapidConfigured(env) }, 200, env, origin)
}
Comment thread worker/src/firestoreAdmin.ts Outdated
Comment on lines +27 to +30
const res = await fetch('https://oauth2.googleapis.com/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=${assertion}`,
Comment on lines +146 to +152
if (body.endpoint) {
const epKey = `ep:${await hashEndpoint(body.endpoint)}`
const mapped = await env.PUSH_KV.get(epKey)
if (mapped) await env.PUSH_KV.delete(mapped)
await env.PUSH_KV.delete(epKey)
}
await env.PUSH_KV.delete(key)
Comment on lines +50 to +54
function subscriberKey(uid: string | undefined, clientId: string | undefined) {
if (uid) return `sub:${uid}`
if (clientId) return `sub:cid:${clientId}`
return null
}
Comment thread worker/src/pushHandlers.ts
Comment thread src/features/packages/packageGenerator.ts Outdated
Comment thread worker/src/pushHandlers.ts
Copy link
Copy Markdown
Contributor

Copilot AI commented May 23, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • sparrow.cloudflare.com
    • Triggering command: /opt/hostedtoolcache/node/24.15.0/x64/bin/node /opt/hostedtoolcache/node/24.15.0/x64/bin/node --no-warnings --experimental-vm-modules /home/REDACTED/work/mentell/mentell/worker/node_modules/wrangler/wrangler-dist/cli.js types (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@kiyarose kiyarose enabled auto-merge May 23, 2026 03:32
@kiyarose kiyarose merged commit ef77b89 into main May 23, 2026
1 check passed
@kiyarose kiyarose deleted the pillpackdate branch May 23, 2026 03:33
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.

3 participants