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:
302
NOTIFICATION_SYSTEM_IMPLEMENTATION.md
Normal file
302
NOTIFICATION_SYSTEM_IMPLEMENTATION.md
Normal file
@@ -0,0 +1,302 @@
|
||||
# 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`:
|
||||
|
||||
```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:
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:3005/api/notifications \
|
||||
-H "Authorization: Bearer YOUR_TOKEN"
|
||||
```
|
||||
|
||||
### Get Unread Count
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:3005/api/notifications/unread-count \
|
||||
-H "Authorization: Bearer YOUR_TOKEN"
|
||||
```
|
||||
|
||||
### Mark as Read
|
||||
|
||||
```bash
|
||||
curl -X PATCH http://localhost:3005/api/notifications/NOTIFICATION_ID/read \
|
||||
-H "Authorization: Bearer YOUR_TOKEN"
|
||||
```
|
||||
|
||||
### Mark All as Read
|
||||
|
||||
```bash
|
||||
curl -X PATCH http://localhost:3005/api/notifications/read-all \
|
||||
-H "Authorization: Bearer YOUR_TOKEN"
|
||||
```
|
||||
|
||||
## Database Schema
|
||||
|
||||
```sql
|
||||
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.
|
||||
Reference in New Issue
Block a user