Tuesday, April 7, 2026

Push Notifications & PWA Enhancements

Push Notifications & PWA Enhancements

Canadian Elite Volleyball Academy — Development Update • April 7, 2026

Push Notifications & PWA Enhancements

Context

The academy platform currently has in-app notifications (stored in DB, polled every 30s via NotificationBell component) and email reminders via Resend. A basic PWA shell exists (manifest, service worker with offline caching, install prompt hook) but there is NO Web Push notification support. The goal is to add real-time browser push notifications so parents, coaches, and admins get instant alerts for important events.

Current Infrastructure

  • In-app notifications: table, polled via
  • Email: Resend integration via , triggered by scheduler and route handlers
  • PWA: , (offline caching only),
  • Notification settings: (email preferences only)
  • Notification creation utility: in
  • Scheduler: runs tasks on time-based intervals
  • Auth field: (NOT clerkId). field (NOT .email)

Key Trigger Points for Push (already create in-app notifications)

1. New direct messages → POST 2. Event reminders (tomorrow) → checkUpcomingEventReminders 3. Schedule changes / event updates → 4. Role approval/rejection → , 5. Payment reminders → checkOverduePaymentReminders 6. Marketplace interest → 7. Evaluation summaries → 8. Re-enrollment nudges → 9. Registration threshold alerts →

Technical Approach

  • Use the npm package for VAPID-based push notifications
  • Store VAPID keys as environment secrets (VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, VAPID_SUBJECT)
  • New table linking browser subscriptions to userId
  • Server-side utility called alongside existing
  • Frontend: use PushManager API to subscribe, send subscription to backend
  • Service worker: handle and events
  • Notification settings page: add push notification toggle and per-category preferences

---

Task #65: Push Notification Backend Infrastructure

Objective

Set up the server-side foundation for Web Push notifications: schema, VAPID key management, subscription CRUD API, and a reusable utility.

Steps

1. Add table to : - (serial PK), (text, references users), (integer, nullable) - (text, unique), (text), (text) - (text, nullable), (timestamp) - Add insert schema + types 2. Run to apply schema 3. Install npm package + 4. Generate VAPID keys and store as secrets (VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, VAPID_SUBJECT=mailto:) 5. Add storage methods: , , , , 6. Create API routes in a new : - — returns public key for frontend - — save subscription (endpoint, keys, userId) - — remove subscription by endpoint - — check if current user has any active subscriptions 7. Create utility: - — looks up all subscriptions for user, sends to each, removes expired/invalid ones - — same but by personId - Handle 410 Gone responses by auto-removing dead subscriptions 8. Add push notification preferences to notification settings (new columns on academy_people or a separate preferences table): , , , ,

Key Files

-
  • (new)
  • (new)
-
  • (register new route module)

---

Task #66: Service Worker & Frontend Push Integration

Objective

Update the service worker to handle push events, add frontend UI for requesting push permission and managing subscriptions, and update the notification settings page.

Steps

1. Update : - Add event listener: parse payload, show notification with title/body/icon/badge/data - Add event listener: focus existing window or open URL from notification data, close notification - Add event listener: re-subscribe and notify backend 2. Create : - Check browser support for Push API - Get current permission state (granted/denied/default) - Request permission via - Subscribe via using VAPID public key from - Send subscription to - Unsubscribe and call - Return 3. Update : - Add "Push Notifications" section with master enable/disable toggle - Show per-category toggles (Messages, Event Reminders, Payments, Announcements) - Show browser permission status with helpful messaging - Handle denied permission state gracefully (link to browser settings instructions) 4. Add a one-time push notification prompt: - After login, if user hasn't been asked before, show a non-intrusive banner/toast asking to enable push notifications - Store dismissal in localStorage to avoid repeated prompts - Link to notification settings for granular control 5. Update the NotificationBell component to show a small indicator if push is not enabled (optional gentle nudge)

Key Files

-
  • (new)
- -

Dependencies

  • Needs Task #65 complete for endpoints and VAPID key

---

Task #67: Wire Push Notifications to Key Events

Objective

Integrate into the most impactful existing notification trigger points so users receive real-time push alerts.

Steps

1. Update helper: - After creating the in-app notification, also call if the user has push enabled for that notification category - This is the single integration point that covers most triggers automatically 2. Wire push into direct messaging (): - When a message is sent, push to the recipient: "New message from {senderName}" with link to /messages - Respect preference 3. Wire push into scheduler triggers (): - Event reminders: "Reminder: {eventName} is tomorrow at {time}" - Payment reminders: "Payment reminder: {amount} due for {eventName}" - Evaluation summaries: "New evaluation report available for {athleteName}" - Respect per-category preferences 4. Wire push into marketplace (): - Interest notifications: "Someone is interested in your listing: {title}" 5. Wire push into role management: - Role approved: "Your {role} role has been approved!" 6. Wire push into event updates (): - Schedule changes: "Schedule update for {eventName}" - Event cancellation: "{eventName} has been cancelled" 7. Add logging: track push delivery success/failure counts for admin visibility 8. Handle edge cases: - User with multiple devices (multiple subscriptions) — send to all - Subscription cleanup for users who uninstall the app - Rate limiting: don't flood users with push for bulk operations

Key Files

- - - - - -

Dependencies

  • Needs Task #65 (backend infrastructure) complete
  • Needs Task #66 (frontend integration) complete

Canadian Elite Volleyball Academy
elitevolleyball.training

No comments:

Post a Comment