mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 10:11:13 -05:00
305 lines
8.1 KiB
Markdown
305 lines
8.1 KiB
Markdown
# Migrating from Legacy to Novu Notifications
|
|
|
|
This guide covers migrating from the old notification system to the new Novu-powered system.
|
|
|
|
## Migration Overview
|
|
|
|
The new notification system:
|
|
- Uses Novu for multi-channel delivery
|
|
- Supports granular preferences per workflow
|
|
- Includes frequency controls
|
|
- Provides delivery tracking
|
|
- Backwards compatible with existing preferences
|
|
|
|
## Data Migration
|
|
|
|
### Step 1: Migrate Existing User Preferences
|
|
|
|
The system automatically migrates old preferences from `user_preferences.email_notifications` and `user_preferences.push_notifications` to the new `user_notification_preferences` table.
|
|
|
|
Run this migration script to batch migrate existing users:
|
|
|
|
```sql
|
|
-- Migrate existing users to new notification preferences
|
|
INSERT INTO user_notification_preferences (
|
|
user_id,
|
|
channel_preferences,
|
|
workflow_preferences,
|
|
frequency_settings
|
|
)
|
|
SELECT
|
|
user_id,
|
|
jsonb_build_object(
|
|
'in_app', true,
|
|
'email', COALESCE((email_notifications->>'system_announcements')::boolean, true),
|
|
'push', COALESCE((push_notifications->>'browser_enabled')::boolean, false),
|
|
'sms', false
|
|
),
|
|
jsonb_build_object(
|
|
'review-reply', COALESCE((email_notifications->>'review_replies')::boolean, true),
|
|
'new-follower', COALESCE((email_notifications->>'new_followers')::boolean, true),
|
|
'system-announcement', COALESCE((email_notifications->>'system_announcements')::boolean, true),
|
|
'weekly-digest', COALESCE((email_notifications->>'weekly_digest')::boolean, false),
|
|
'monthly-digest', COALESCE((email_notifications->>'monthly_digest')::boolean, true)
|
|
),
|
|
jsonb_build_object(
|
|
'digest', 'daily',
|
|
'max_per_hour', 10
|
|
)
|
|
FROM user_preferences
|
|
WHERE NOT EXISTS (
|
|
SELECT 1 FROM user_notification_preferences
|
|
WHERE user_notification_preferences.user_id = user_preferences.user_id
|
|
);
|
|
```
|
|
|
|
### Step 2: Create Novu Subscribers for Existing Users
|
|
|
|
Create a batch script to register all existing users as Novu subscribers:
|
|
|
|
```typescript
|
|
import { supabase } from '@/integrations/supabase/client';
|
|
import { notificationService } from '@/lib/notificationService';
|
|
|
|
async function migrateUsersToNovu() {
|
|
const { data: profiles, error } = await supabase
|
|
.from('profiles')
|
|
.select('user_id, username, display_name')
|
|
.is('banned', false);
|
|
|
|
if (error) {
|
|
console.error('Error fetching profiles:', error);
|
|
return;
|
|
}
|
|
|
|
for (const profile of profiles) {
|
|
// Get user's auth data for email
|
|
const { data: { user } } = await supabase.auth.admin.getUserById(profile.user_id);
|
|
|
|
if (user?.email) {
|
|
await notificationService.createSubscriber({
|
|
subscriberId: profile.user_id,
|
|
email: user.email,
|
|
firstName: profile.display_name?.split(' ')[0],
|
|
lastName: profile.display_name?.split(' ').slice(1).join(' '),
|
|
data: {
|
|
username: profile.username,
|
|
},
|
|
});
|
|
|
|
console.log(`Migrated user: ${profile.username}`);
|
|
|
|
// Rate limit to avoid overwhelming Novu API
|
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
}
|
|
}
|
|
|
|
console.log('Migration complete!');
|
|
}
|
|
```
|
|
|
|
## Code Migration
|
|
|
|
### Updating Notification Triggers
|
|
|
|
**Old Way:**
|
|
```typescript
|
|
// Direct database insert (legacy)
|
|
await supabase
|
|
.from('notifications')
|
|
.insert({
|
|
user_id: userId,
|
|
type: 'review_reply',
|
|
content: 'Someone replied to your review',
|
|
});
|
|
```
|
|
|
|
**New Way:**
|
|
```typescript
|
|
// Using Novu via notificationService
|
|
import { notificationService } from '@/lib/notificationService';
|
|
|
|
await notificationService.trigger({
|
|
workflowId: 'review-reply',
|
|
subscriberId: userId,
|
|
payload: {
|
|
reviewTitle: 'Great ride!',
|
|
replyAuthor: 'Jane Doe',
|
|
replyContent: 'Thanks for the review!',
|
|
reviewUrl: `/reviews/${reviewId}`,
|
|
},
|
|
});
|
|
```
|
|
|
|
### Updating Preference Management
|
|
|
|
**Old Way:**
|
|
```typescript
|
|
await supabase
|
|
.from('user_preferences')
|
|
.update({
|
|
email_notifications: {
|
|
review_replies: false,
|
|
},
|
|
})
|
|
.eq('user_id', userId);
|
|
```
|
|
|
|
**New Way:**
|
|
```typescript
|
|
import { notificationService } from '@/lib/notificationService';
|
|
|
|
await notificationService.updatePreferences(userId, {
|
|
channelPreferences: {
|
|
in_app: true,
|
|
email: true,
|
|
push: false,
|
|
sms: false,
|
|
},
|
|
workflowPreferences: {
|
|
'review-reply': false,
|
|
},
|
|
frequencySettings: {
|
|
digest: 'daily',
|
|
max_per_hour: 10,
|
|
},
|
|
});
|
|
```
|
|
|
|
## Rollback Plan
|
|
|
|
If you need to rollback to the old system:
|
|
|
|
1. **Keep Old Tables**: Don't drop `user_preferences.email_notifications` or `push_notifications` columns
|
|
2. **Disable Novu**: Clear `VITE_NOVU_APPLICATION_IDENTIFIER` environment variable
|
|
3. **Revert Code**: The notification service gracefully handles missing Novu config
|
|
|
|
## Testing the Migration
|
|
|
|
### Test Checklist
|
|
|
|
- [ ] All existing users have entries in `user_notification_preferences`
|
|
- [ ] User preferences match their previous settings
|
|
- [ ] Test users receive notifications on all enabled channels
|
|
- [ ] Webhook is receiving delivery events
|
|
- [ ] Notification logs are being created
|
|
- [ ] User preference changes sync to Novu
|
|
- [ ] Unsubscribe links work correctly
|
|
- [ ] Email templates render correctly
|
|
- [ ] Push notifications work in supported browsers
|
|
- [ ] In-app notifications display correctly
|
|
|
|
### Test Script
|
|
|
|
```typescript
|
|
// Test notification delivery
|
|
import { notificationService } from '@/lib/notificationService';
|
|
|
|
async function testNotifications(testUserId: string) {
|
|
console.log('Testing notification delivery...');
|
|
|
|
// Test each workflow
|
|
const workflows = [
|
|
{
|
|
id: 'review-reply',
|
|
payload: {
|
|
reviewTitle: 'Test Review',
|
|
replyAuthor: 'Test User',
|
|
replyContent: 'Test reply content',
|
|
reviewUrl: '/test',
|
|
},
|
|
},
|
|
{
|
|
id: 'new-follower',
|
|
payload: {
|
|
followerName: 'Test Follower',
|
|
followerProfile: '/profile/test',
|
|
},
|
|
},
|
|
];
|
|
|
|
for (const workflow of workflows) {
|
|
const result = await notificationService.trigger({
|
|
workflowId: workflow.id,
|
|
subscriberId: testUserId,
|
|
payload: workflow.payload,
|
|
});
|
|
|
|
console.log(`${workflow.id}: ${result.success ? '✓' : '✗'}`);
|
|
|
|
if (!result.success) {
|
|
console.error(`Error: ${result.error}`);
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Performance Considerations
|
|
|
|
### Batch Operations
|
|
|
|
When migrating large numbers of users:
|
|
|
|
1. **Rate Limiting**: Add delays between API calls
|
|
2. **Batch Size**: Process in chunks of 100-500 users
|
|
3. **Error Handling**: Log failures and retry
|
|
4. **Progress Tracking**: Store migration state
|
|
|
|
### Optimization Tips
|
|
|
|
1. **Cache Templates**: Load notification templates once at startup
|
|
2. **Async Processing**: Use edge functions for heavy operations
|
|
3. **Database Indexes**: Already created on `user_notification_preferences`
|
|
4. **Connection Pooling**: Supabase handles this automatically
|
|
|
|
## Monitoring Post-Migration
|
|
|
|
Track these metrics after migration:
|
|
|
|
```sql
|
|
-- Delivery success rate
|
|
SELECT
|
|
DATE(created_at) as date,
|
|
COUNT(*) FILTER (WHERE status = 'delivered') * 100.0 / COUNT(*) as success_rate
|
|
FROM notification_logs
|
|
WHERE created_at > NOW() - INTERVAL '7 days'
|
|
GROUP BY DATE(created_at)
|
|
ORDER BY date DESC;
|
|
|
|
-- Channel usage
|
|
SELECT
|
|
channel,
|
|
COUNT(*) as total_sent,
|
|
COUNT(*) FILTER (WHERE status = 'delivered') as delivered,
|
|
COUNT(*) FILTER (WHERE read_at IS NOT NULL) as read
|
|
FROM notification_logs
|
|
WHERE created_at > NOW() - INTERVAL '7 days'
|
|
GROUP BY channel;
|
|
|
|
-- User engagement
|
|
SELECT
|
|
COUNT(DISTINCT user_id) as active_users,
|
|
AVG(EXTRACT(EPOCH FROM (read_at - delivered_at))) as avg_time_to_read_seconds
|
|
FROM notification_logs
|
|
WHERE read_at IS NOT NULL
|
|
AND created_at > NOW() - INTERVAL '7 days';
|
|
```
|
|
|
|
## Support During Migration
|
|
|
|
1. **Backup Data**: Export old notification preferences before migration
|
|
2. **Phased Rollout**: Enable for a subset of users first
|
|
3. **Feature Flag**: Use admin settings to control Novu enablement
|
|
4. **User Communication**: Notify users of new notification features
|
|
5. **Monitor Logs**: Watch edge function logs during migration
|
|
|
|
## Timeline
|
|
|
|
Recommended migration timeline:
|
|
|
|
- **Week 1**: Test with internal users
|
|
- **Week 2**: Rollout to 10% of users
|
|
- **Week 3**: Rollout to 50% of users
|
|
- **Week 4**: Complete rollout
|
|
- **Week 5**: Remove legacy code (optional)
|