Files
ocean-cleanup/NOTIFICATION_SYSTEM_IMPLEMENTATION.md
Paul Bailey d61c21c54d 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
2025-11-17 00:31:23 +00:00

9.7 KiB

Notification System Implementation

Overview

The notification system enables real-time user engagement by notifying users about new reports and events in their areas of interest. It includes in-app notifications and email delivery using Mailgun.

Features Implemented

1. Database Schema

  • Notification Model: Stores all notifications with type, title, message, related content, location, and read status
  • Migration: 20251117000000_add_notifications adds the notifications table
  • Indexes: Optimized for user queries, date filtering, and read status

2. Backend Services

NotificationService (server/src/services/notificationService.ts)

  • createNotification: Create individual notifications
  • findInterestedUsers: Match locations to user areas of interest using distance calculations
  • notifyNewReport: Automatically notify users when reports are created in their areas
  • notifyNewEvent: Automatically notify users when events are created in their areas
  • notifyReportVerification: Notify report authors about verifications/disputes
  • sendEventReminders: Send reminders for events happening within 24 hours
  • getUserNotifications: Fetch user's notifications with filtering
  • markAsRead: Mark individual notifications as read
  • markAllAsRead: Mark all user notifications as read
  • getUnreadCount: Get count of unread notifications
  • cleanupOldNotifications: Remove read notifications older than 30 days

EmailService (server/src/services/emailService.ts)

  • Mailgun Integration: Uses Mailgun API for email delivery
  • sendEmail: Generic email sending function
  • sendNotificationEmail: Formatted notification emails with HTML templates
  • testConnection: Verify email configuration
  • HTML Templates: Professional email templates with branding

3. API Endpoints

Notification Routes (/api/notifications)

  • GET /api/notifications - Get user's notifications (with optional unreadOnly filter)
  • GET /api/notifications/unread-count - Get unread notification count
  • PATCH /api/notifications/:id/read - Mark notification as read
  • PATCH /api/notifications/read-all - Mark all notifications as read

All routes require authentication via Clerk middleware.

4. Scheduled Jobs

Event Reminders (Every 10 minutes)

  • Checks for events happening within 24 hours
  • Sends reminders to registered participants
  • Prevents duplicate reminders

Notification Cleanup (Daily at 2 AM)

  • Removes read notifications older than 30 days
  • Keeps database size manageable

5. Frontend Components

NotificationBell (src/components/common/NotificationBell.tsx)

  • Bell Icon: Shows unread count badge
  • Dropdown: Displays recent notifications
  • Real-time Updates: Polls for new notifications every 30 seconds
  • Mark as Read: Click to mark individual notifications as read
  • Navigation: Click notifications to view related reports/events
  • Responsive: Works on mobile and desktop

Integration

  • Added to Header component for authenticated users
  • Uses React Query for data fetching and caching
  • Automatic refetching on mutations

6. Area of Interest Matching

The system uses spatial calculations to match notifications to users:

  1. Users define areas of interest with:

    • Latitude/longitude coordinates
    • Radius in kilometers (1-50km)
  2. When a report or event is created:

    • System finds all users with areas of interest
    • Calculates distance from event to each area center
    • Notifies users if distance ≤ radius
  3. Distance calculation uses the Haversine formula for accuracy

Configuration

Environment Variables

Add to server/.env:

# Email Notifications (Mailgun)
MAILGUN_API_KEY="dd27be7a81dd7b0980ada31fec9a9bd9-e80d8b76-fd80c63b"
MAILGUN_DOMAIN="sandbox-123.mailgun.org"
FROM_EMAIL="Beach Litter Platform <noreply@beachlitter.ie>"
FRONTEND_URL="http://localhost:5173"
TEST_EMAIL="test@example.com"

Mailgun Setup

  1. API Key: Provided - dd27be7a81dd7b0980ada31fec9a9bd9-e80d8b76-fd80c63b
  2. Domain: Configure your Mailgun domain (currently using sandbox)
  3. From Email: Set your sender email address
  4. Sandbox Mode: For testing, add authorized recipients in Mailgun dashboard

Testing

Test Script

Run the comprehensive test script:

cd server
npx tsx src/scripts/testNotifications.ts

The script tests:

  1. Email service connection
  2. Notification creation
  3. Fetching notifications
  4. Unread count
  5. Mark as read functionality
  6. Area-of-interest matching
  7. Report notifications
  8. Event notifications
  9. Event reminders
  10. Mark all as read
  11. Direct email sending

Manual Testing

  1. Create a Report:

    • Submit a new litter report
    • Users with matching areas of interest receive notifications
    • Check email inbox for notification email
  2. Create an Event:

    • Create a new cleanup event
    • Users with matching areas of interest receive notifications
    • Check email inbox for notification email
  3. View Notifications:

    • Click the bell icon in the header
    • See list of notifications
    • Click to view related content
  4. Mark as Read:

    • Click a notification to mark it as read
    • Badge count decreases
    • Notification appearance changes

Notification Types

  1. new_report 📍

    • Triggered when a report is created
    • Sent to users with matching areas of interest
    • Links to map view with report details
  2. new_event 🗓️

    • Triggered when an event is created
    • Sent to users with matching areas of interest
    • Links to events page with event details
  3. event_reminder ⏰

    • Triggered 24 hours before event
    • Sent to registered participants
    • Links to event details
  4. report_verified ✅

    • Triggered when report is verified
    • Sent to report author
    • Links to report details
  5. report_disputed ⚠️

    • Triggered when report is disputed
    • Sent to report author
    • Links to report details

Email Templates

Emails include:

  • Professional HTML formatting
  • Beach Litter Platform branding
  • Clear call-to-action buttons
  • Links to view details
  • Notification preference management link
  • Responsive design for mobile

Performance Considerations

  1. Async Processing: Notifications are sent asynchronously to avoid blocking API responses
  2. Batch Processing: Email sending is batched for efficiency
  3. Caching: Frontend uses React Query for caching and automatic refetching
  4. Indexes: Database indexes optimize notification queries
  5. Cleanup: Old notifications are automatically removed

Requirements Satisfied

✅ Requirement 10.1: Users can define geographical areas of interest (1-50km radius) ✅ Requirement 10.2: Notifications sent within 10 minutes (scheduled job runs every 10 minutes) ✅ Requirement 10.3: Notifications for new reports and events in user's area ✅ Requirement 10.4: Users can configure notification preferences (email/in-app)

Future Enhancements

  1. Push Notifications: Add web push notifications for real-time alerts
  2. SMS Notifications: Integrate Twilio for SMS alerts
  3. Notification Preferences: More granular control (by litter type, event type, etc.)
  4. Digest Emails: Daily/weekly summary emails
  5. Real-time Updates: WebSocket integration for instant notifications
  6. Rich Notifications: Include images and maps in notifications
  7. Notification History: Archive and search old notifications

Troubleshooting

Emails Not Sending

  1. Check Mailgun API key is correct
  2. Verify domain is configured in Mailgun
  3. Check sandbox mode restrictions (add authorized recipients)
  4. Review server logs for error messages
  5. Test email service with test script

Notifications Not Appearing

  1. Verify user has notification preferences enabled
  2. Check areas of interest are configured
  3. Verify location is within radius
  4. Check scheduled jobs are running
  5. Review server logs for errors

Performance Issues

  1. Check database indexes are created
  2. Monitor notification table size
  3. Verify cleanup job is running
  4. Consider increasing cleanup frequency
  5. Review query performance with EXPLAIN

API Examples

Get Notifications

curl -X GET http://localhost:3005/api/notifications \
  -H "Authorization: Bearer YOUR_TOKEN"

Get Unread Count

curl -X GET http://localhost:3005/api/notifications/unread-count \
  -H "Authorization: Bearer YOUR_TOKEN"

Mark as Read

curl -X PATCH http://localhost:3005/api/notifications/NOTIFICATION_ID/read \
  -H "Authorization: Bearer YOUR_TOKEN"

Mark All as Read

curl -X PATCH http://localhost:3005/api/notifications/read-all \
  -H "Authorization: Bearer YOUR_TOKEN"

Database Schema

CREATE TABLE notifications (
  id VARCHAR(36) PRIMARY KEY,
  user_id VARCHAR(36) NOT NULL,
  type ENUM('new_report', 'new_event', 'event_reminder', 'report_verified', 'report_disputed'),
  title VARCHAR(255) NOT NULL,
  message TEXT NOT NULL,
  related_id VARCHAR(36),
  related_type ENUM('report', 'event'),
  latitude DECIMAL(10, 8),
  longitude DECIMAL(11, 8),
  read BOOLEAN DEFAULT FALSE,
  email_sent BOOLEAN DEFAULT FALSE,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  
  INDEX idx_user_id (user_id),
  INDEX idx_created_at (created_at),
  INDEX idx_read (read),
  INDEX idx_type (type),
  INDEX idx_lat_lng (latitude, longitude),
  
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

Conclusion

The notification system is fully implemented and tested, providing users with timely updates about environmental activities in their areas of interest. The system uses Mailgun for reliable email delivery and includes comprehensive in-app notifications with a polished UI.