feat: implement notification system with Mailgun email integration
- Add notifications table with migration - Create NotificationService with area-of-interest matching - Integrate Mailgun for email delivery - Add notification API endpoints (get, mark as read, unread count) - Create scheduled jobs for event reminders and cleanup - Build NotificationBell component for frontend - Add notification triggers for reports and events - Implement comprehensive test script - Update Header with notification bell - Add email templates with HTML formatting Requirements satisfied: - 10.1: Users can define areas of interest (1-50km radius) - 10.2: Notifications sent within 10 minutes - 10.3: Notifications for new reports/events in user area - 10.4: Configurable notification preferences (email/in-app) Task 33 completed
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
import cron, { ScheduledTask } from 'node-cron';
|
||||
import { analyticsService } from './analyticsService';
|
||||
import { notificationService } from './notificationService';
|
||||
|
||||
/**
|
||||
* Initialize all scheduled jobs
|
||||
@@ -28,9 +29,38 @@ export function initializeScheduledJobs() {
|
||||
|
||||
console.log('[Scheduled Jobs] ✓ Hotspot calculation job scheduled (every 5 minutes)');
|
||||
|
||||
// Event reminder job - runs every 10 minutes
|
||||
// Requirement 10.2: Send notifications within 10 minutes
|
||||
const eventReminderJob = cron.schedule('*/10 * * * *', async () => {
|
||||
try {
|
||||
console.log('[Scheduled Jobs] Checking for event reminders...');
|
||||
const reminders = await notificationService.sendEventReminders();
|
||||
console.log(`[Scheduled Jobs] Event reminders sent: ${reminders.length} notifications`);
|
||||
} catch (error: any) {
|
||||
console.error('[Scheduled Jobs] Error in event reminder job:', error.message);
|
||||
}
|
||||
});
|
||||
|
||||
console.log('[Scheduled Jobs] ✓ Event reminder job scheduled (every 10 minutes)');
|
||||
|
||||
// Notification cleanup job - runs daily at 2 AM
|
||||
const notificationCleanupJob = cron.schedule('0 2 * * *', async () => {
|
||||
try {
|
||||
console.log('[Scheduled Jobs] Cleaning up old notifications...');
|
||||
const count = await notificationService.cleanupOldNotifications();
|
||||
console.log(`[Scheduled Jobs] Notification cleanup completed: ${count} notifications deleted`);
|
||||
} catch (error: any) {
|
||||
console.error('[Scheduled Jobs] Error in notification cleanup job:', error.message);
|
||||
}
|
||||
});
|
||||
|
||||
console.log('[Scheduled Jobs] ✓ Notification cleanup job scheduled (daily at 2 AM)');
|
||||
|
||||
// Return job instances for potential management
|
||||
return {
|
||||
hotspotJob,
|
||||
eventReminderJob,
|
||||
notificationCleanupJob,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -38,13 +68,27 @@ export function initializeScheduledJobs() {
|
||||
* Stop all scheduled jobs
|
||||
* Useful for graceful shutdown
|
||||
*/
|
||||
export function stopScheduledJobs(jobs: { hotspotJob: ScheduledTask }) {
|
||||
export function stopScheduledJobs(jobs: {
|
||||
hotspotJob: ScheduledTask;
|
||||
eventReminderJob: ScheduledTask;
|
||||
notificationCleanupJob: ScheduledTask;
|
||||
}) {
|
||||
console.log('[Scheduled Jobs] Stopping all scheduled jobs...');
|
||||
|
||||
if (jobs.hotspotJob) {
|
||||
jobs.hotspotJob.stop();
|
||||
console.log('[Scheduled Jobs] ✓ Hotspot calculation job stopped');
|
||||
}
|
||||
|
||||
if (jobs.eventReminderJob) {
|
||||
jobs.eventReminderJob.stop();
|
||||
console.log('[Scheduled Jobs] ✓ Event reminder job stopped');
|
||||
}
|
||||
|
||||
if (jobs.notificationCleanupJob) {
|
||||
jobs.notificationCleanupJob.stop();
|
||||
console.log('[Scheduled Jobs] ✓ Notification cleanup job stopped');
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
|
||||
Reference in New Issue
Block a user