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:
MessageNotificationScheduler runs every minute
ProviderExportScheduler runs daily at 00:10 UTC
- Events/Training sessions are stored in the
Event and EventTraining models
- Users have
pushToken field in the User model
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 (
Event with type = TRAINING) scheduled for tomorrow
- Notification preferences enabled (if we add this feature)
-
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)
-
Notification Service Integration
- Use existing
PushNotificationService.sendPushNotification() method
- Batch notifications for efficiency
- Handle errors gracefully (log failures, don't crash the scheduler)
-
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
}
-
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
Related Files
apps/api/src/modules/notification/services/push-notification.service.ts - Push notification service
apps/api/src/modules/notification/services/notification.service.ts - Notification service
apps/api/src/modules/messages/services/message-notification.scheduler.ts - Example scheduler implementation
apps/api/src/modules/providers-sync/scheduler.service.ts - Another scheduler example
apps/firebase-functions/src/index.ts - Firebase Functions for sending notifications
libs/database/prisma/schema/event.prisma - Event and EventTraining models
libs/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
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
PushNotificationService(apps/api/src/modules/notification/services/push-notification.service.ts)apps/firebase-functions/src/index.ts)apps/web/src/utils/push-notifications.ts)@nestjs/schedule:MessageNotificationSchedulerruns every minuteProviderExportSchedulerruns daily at 00:10 UTCEventandEventTrainingmodelspushTokenfield in theUsermodelRequirements
Backend (NestJS API)
Scheduled Notification Service
NextDaySessionNotificationSchedulerpushTokenEventwithtype = TRAINING) scheduled for tomorrowNotification Content
user.language)Notification Service Integration
PushNotificationService.sendPushNotification()methodUser Preferences (Optional but Recommended)
Error Handling & Logging
Frontend (React/Web)
Notification Preferences UI (Optional)
Notification Handling (If needed)
Technical Implementation
Cron Schedule Options
Option 1: Run every hour, check timezone
Option 2: Run at 7 PM UTC, allow timezone preference
Option 3: Multiple scheduled jobs for different timezones
Recommendation: Start with Option 2, add timezone support later
Notification Message Examples
English (single session):
English (multiple sessions):
French (single session):
French (multiple sessions):
Acceptance Criteria
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 pushTokenFuture Enhancements