-
-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Description
Implement a scheduled push notification system that sends users a notification around 7 PM (19:00) each day to remind them about their training sessions scheduled for the next day. This helps athletes prepare and stay on track with their training plans.
Current State
- Push notification infrastructure exists:
PushNotificationService(apps/api/src/modules/notification/services/push-notification.service.ts)- Firebase Functions for sending notifications (
apps/firebase-functions/src/index.ts) - Push notification initialization in web app (
apps/web/src/utils/push-notifications.ts)
- Scheduled tasks are implemented using
@nestjs/schedule:MessageNotificationSchedulerruns every minuteProviderExportSchedulerruns daily at 00:10 UTC
- Events/Training sessions are stored in the
EventandEventTrainingmodels - Users have
pushTokenfield in theUsermodel
Requirements
Backend (NestJS API)
-
Scheduled Notification Service
- Create a new service:
NextDaySessionNotificationScheduler - Schedule a cron job to run daily at 19:00 (7 PM) in user's local timezone
- Note: Since users may be in different timezones, consider:
- Running the job multiple times per day (e.g., every hour) and checking if it's 7 PM in the user's timezone
- Or running at 7 PM UTC and allowing users to configure their preferred notification time
- Query all users who have:
- A valid
pushToken - Training sessions (
Eventwithtype = TRAINING) scheduled for tomorrow - Notification preferences enabled (if we add this feature)
- A valid
- Create a new service:
-
Notification Content
- Query tomorrow's training sessions for each user:
// Pseudo-code const tomorrow = start of next day in user's timezone const sessions = await prisma.event.findMany({ where: { athleteId: user.athleteId, type: 'TRAINING', startDate: { gte: tomorrow, lt: dayAfterTomorrow } }, include: { training: { include: { sport: true } } } })
- Generate notification message based on sessions:
- Single session: "You have a [SPORT] training session tomorrow at [TIME]"
- Multiple sessions: "You have [N] training sessions tomorrow"
- Include session details (sport, time, name) if space allows
- Support i18n (French and English based on
user.language)
- Query tomorrow's training sessions for each user:
-
Notification Service Integration
- Use existing
PushNotificationService.sendPushNotification()method - Batch notifications for efficiency
- Handle errors gracefully (log failures, don't crash the scheduler)
- Use existing
-
User Preferences (Optional but Recommended)
- Add notification preferences to user settings:
- Enable/disable next-day session notifications
- Preferred notification time (default: 19:00)
- Timezone preference
- Database schema update:
model User { // ... existing fields notificationPreferences Json? // Store preferences as JSON // Or create a separate NotificationPreferences model }
- Add notification preferences to user settings:
-
Error Handling & Logging
- Log successful notifications
- Log failures with user ID and reason
- Don't send duplicate notifications (track last notification sent)
- Handle edge cases:
- Users without push tokens
- Users without athlete profiles
- Sessions that were cancelled/deleted after notification was queued
Frontend (React/Web)
-
Notification Preferences UI (Optional)
- Add settings page/section for notification preferences
- Allow users to:
- Enable/disable next-day session notifications
- Set preferred notification time
- Set timezone
-
Notification Handling (If needed)
- Handle notification tap to navigate to calendar/day view
- Deep linking to specific session (if supported)
Technical Implementation
Cron Schedule Options
Option 1: Run every hour, check timezone
@Cron('0 * * * *') // Every hour
async sendNextDayNotifications() {
// Check if it's 7 PM in each user's timezone
// Send notifications accordingly
}Option 2: Run at 7 PM UTC, allow timezone preference
@Cron('0 19 * * *', { timeZone: 'UTC' }) // 7 PM UTC
async sendNextDayNotifications() {
// Send to all users (they can set preferred time in settings)
}Option 3: Multiple scheduled jobs for different timezones
- More complex but more accurate
- Run jobs at 7 PM for major timezones
Recommendation: Start with Option 2, add timezone support later
Notification Message Examples
English (single session):
Tomorrow's Training
You have a Running session at 8:00 AM
English (multiple sessions):
Tomorrow's Training
You have 3 training sessions scheduled
French (single session):
Entraînement de demain
Vous avez une séance de Course à 8h00
French (multiple sessions):
Entraînement de demain
Vous avez 3 séances d'entraînement prévues
Acceptance Criteria
- Scheduled job runs daily at 7 PM (or configured time)
- Notifications are sent to users with training sessions tomorrow
- Notification content is accurate and includes session details
- Notifications support both French and English
- Users without push tokens are skipped gracefully
- Errors are logged and don't crash the scheduler
- No duplicate notifications are sent
- Notification preferences are respected (if implemented)
- Performance is acceptable (batch processing for many users)
Related Files
apps/api/src/modules/notification/services/push-notification.service.ts- Push notification serviceapps/api/src/modules/notification/services/notification.service.ts- Notification serviceapps/api/src/modules/messages/services/message-notification.scheduler.ts- Example scheduler implementationapps/api/src/modules/providers-sync/scheduler.service.ts- Another scheduler exampleapps/firebase-functions/src/index.ts- Firebase Functions for sending notificationslibs/database/prisma/schema/event.prisma- Event and EventTraining modelslibs/database/prisma/schema/core.prisma- User model with pushToken
Future Enhancements
- Allow users to customize notification time
- Support for different notification types (competitions, notes)
- Rich notifications with action buttons (e.g., "View Calendar", "Reschedule")
- Notification history/log
- Email fallback for users without push notifications enabled