- Update domain to sandbox1835a1917b07443f8c1ca858689c42ea.mailgun.org - Set test email to psbailey31@gmail.com - Add comprehensive Mailgun setup guide - Document sandbox authorization requirements - Create email testing script - Update troubleshooting documentation Note: Sandbox domains require recipient authorization in Mailgun dashboard
11 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_notificationsadds 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 countPATCH /api/notifications/:id/read- Mark notification as readPATCH /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:
-
Users define areas of interest with:
- Latitude/longitude coordinates
- Radius in kilometers (1-50km)
-
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
-
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
- API Key:
dd27be7a81dd7b0980ada31fec9a9bd9-e80d8b76-fd80c63b - Domain:
sandbox1835a1917b07443f8c1ca858689c42ea.mailgun.org - From Email:
Beach Litter Platform <noreply@sandbox1835a1917b07443f8c1ca858689c42ea.mailgun.org>
Sandbox Mode Authorization
IMPORTANT: Mailgun sandbox domains require you to authorize recipient email addresses before sending.
To authorize recipients:
- Go to https://app.mailgun.com/
- Navigate to Sending → Domains
- Click on your sandbox domain:
sandbox1835a1917b07443f8c1ca858689c42ea.mailgun.org - Go to "Authorized Recipients" section
- Add email addresses you want to test with (e.g.,
psbailey31@gmail.com) - Recipients will receive a confirmation email - they must click the link to authorize
For Production: Use a verified custom domain instead of sandbox to send to any email address without authorization.
Testing
Test Script
Run the comprehensive test script:
cd server
npx tsx src/scripts/testNotifications.ts
The script tests:
- Email service connection
- Notification creation
- Fetching notifications
- Unread count
- Mark as read functionality
- Area-of-interest matching
- Report notifications
- Event notifications
- Event reminders
- Mark all as read
- Direct email sending
Manual Testing
-
Create a Report:
- Submit a new litter report
- Users with matching areas of interest receive notifications
- Check email inbox for notification email
-
Create an Event:
- Create a new cleanup event
- Users with matching areas of interest receive notifications
- Check email inbox for notification email
-
View Notifications:
- Click the bell icon in the header
- See list of notifications
- Click to view related content
-
Mark as Read:
- Click a notification to mark it as read
- Badge count decreases
- Notification appearance changes
Notification Types
-
new_report 📍
- Triggered when a report is created
- Sent to users with matching areas of interest
- Links to map view with report details
-
new_event 🗓️
- Triggered when an event is created
- Sent to users with matching areas of interest
- Links to events page with event details
-
event_reminder ⏰
- Triggered 24 hours before event
- Sent to registered participants
- Links to event details
-
report_verified ✅
- Triggered when report is verified
- Sent to report author
- Links to report details
-
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
- Async Processing: Notifications are sent asynchronously to avoid blocking API responses
- Batch Processing: Email sending is batched for efficiency
- Caching: Frontend uses React Query for caching and automatic refetching
- Indexes: Database indexes optimize notification queries
- 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
- Push Notifications: Add web push notifications for real-time alerts
- SMS Notifications: Integrate Twilio for SMS alerts
- Notification Preferences: More granular control (by litter type, event type, etc.)
- Digest Emails: Daily/weekly summary emails
- Real-time Updates: WebSocket integration for instant notifications
- Rich Notifications: Include images and maps in notifications
- Notification History: Archive and search old notifications
Troubleshooting
Emails Not Sending
- Check Mailgun API key is correct: Verify in
.envfile - Verify domain is configured: Should be
sandbox1835a1917b07443f8c1ca858689c42ea.mailgun.org - Authorize recipients for sandbox:
- Go to https://app.mailgun.com/
- Navigate to your sandbox domain
- Add authorized recipients (they must confirm via email)
- Error "Forbidden" means recipient is not authorized
- Review server logs: Check for detailed error messages
- Test email service: Run
npx tsx src/scripts/testEmail.ts - For production: Use a verified custom domain to avoid sandbox restrictions
Notifications Not Appearing
- Verify user has notification preferences enabled
- Check areas of interest are configured
- Verify location is within radius
- Check scheduled jobs are running
- Review server logs for errors
Performance Issues
- Check database indexes are created
- Monitor notification table size
- Verify cleanup job is running
- Consider increasing cleanup frequency
- 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.