# Daily Notification Plugin Migration Guide **Author**: Matthew Raymer **Version**: 2.0.0 **Created**: 2025-09-22 09:22:32 UTC **Last Updated**: 2025-09-22 09:22:32 UTC ## Overview This migration guide helps you transition from the basic daily notification plugin to the enhanced version with dual scheduling, callback support, and comprehensive observability. ## Breaking Changes ### API Changes #### New Methods Added - `scheduleContentFetch()` - Schedule content fetching separately - `scheduleUserNotification()` - Schedule user notifications separately - `scheduleDualNotification()` - Schedule both content fetch and notification - `getDualScheduleStatus()` - Get comprehensive status information - `registerCallback()` - Register callback functions - `unregisterCallback()` - Remove callback functions - `getRegisteredCallbacks()` - List registered callbacks #### Enhanced Configuration - New `DualScheduleConfiguration` interface - Enhanced `NotificationOptions` with callback support - New `ContentFetchConfig` and `UserNotificationConfig` interfaces ### Platform Requirements #### Android - **Minimum SDK**: API 21 (Android 5.0) - **Target SDK**: API 34 (Android 14) - **Permissions**: `POST_NOTIFICATIONS`, `SCHEDULE_EXACT_ALARM`, `USE_EXACT_ALARM` - **Dependencies**: Room 2.6.1+, WorkManager 2.9.0+ #### iOS - **Minimum Version**: iOS 13.0 - **Background Modes**: Background App Refresh, Background Processing - **Permissions**: Notification permissions required - **Dependencies**: Core Data, BGTaskScheduler #### Web - **Service Worker**: Required for background functionality - **HTTPS**: Required for Service Worker and push notifications - **Browser Support**: Chrome 40+, Firefox 44+, Safari 11.1+ ## Migration Steps ### Step 1: Update Dependencies ```bash npm install @timesafari/daily-notification-plugin@^2.0.0 ``` ### Step 2: Update Import Statements ```typescript // Before import { DailyNotification } from '@timesafari/daily-notification-plugin'; // After import { DailyNotification, DualScheduleConfiguration, ContentFetchConfig, UserNotificationConfig, CallbackEvent } from '@timesafari/daily-notification-plugin'; ``` ### Step 3: Update Configuration #### Basic Migration (Minimal Changes) ```typescript // Before await DailyNotification.scheduleDailyNotification({ title: 'Daily Update', body: 'Your daily content is ready', schedule: '0 9 * * *' }); // After (backward compatible) await DailyNotification.scheduleDailyNotification({ title: 'Daily Update', body: 'Your daily content is ready', schedule: '0 9 * * *' }); ``` #### Enhanced Migration (Recommended) ```typescript // After (enhanced with dual scheduling) const config: DualScheduleConfiguration = { contentFetch: { schedule: '0 8 * * *', // Fetch at 8 AM ttlSeconds: 3600, // 1 hour TTL source: 'api', url: 'https://api.example.com/daily-content' }, userNotification: { schedule: '0 9 * * *', // Notify at 9 AM title: 'Daily Update', body: 'Your daily content is ready', actions: [ { id: 'view', title: 'View' }, { id: 'dismiss', title: 'Dismiss' } ] } }; await DailyNotification.scheduleDualNotification(config); ``` ### Step 4: Add Callback Support ```typescript // Register callbacks for external integrations await DailyNotification.registerCallback('analytics', { kind: 'http', target: 'https://analytics.example.com/events', headers: { 'Authorization': 'Bearer your-token', 'Content-Type': 'application/json' } }); await DailyNotification.registerCallback('database', { kind: 'local', target: 'saveToDatabase' }); // Local callback function function saveToDatabase(event: CallbackEvent) { console.log('Saving to database:', event); // Your database save logic here } ``` ### Step 5: Update Status Monitoring ```typescript // Before const status = await DailyNotification.getNotificationStatus(); // After (enhanced status) const status = await DailyNotification.getDualScheduleStatus(); console.log('Next runs:', status.nextRuns); console.log('Cache age:', status.cacheAgeMs); console.log('Circuit breakers:', status.circuitBreakers); console.log('Performance:', status.performance); ``` ## Platform-Specific Migration ### Android Migration #### Update AndroidManifest.xml ```xml ``` #### Update build.gradle ```gradle dependencies { implementation "androidx.room:room-runtime:2.6.1" implementation "androidx.work:work-runtime-ktx:2.9.0" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3" annotationProcessor "androidx.room:room-compiler:2.6.1" } ``` ### iOS Migration #### Update Info.plist ```xml UIBackgroundModes background-app-refresh background-processing BGTaskSchedulerPermittedIdentifiers com.timesafari.dailynotification.content-fetch com.timesafari.dailynotification.notification-delivery ``` #### Update Capabilities 1. Enable "Background Modes" capability 2. Enable "Background App Refresh" 3. Enable "Background Processing" ### Web Migration #### Service Worker Registration ```typescript // Register Service Worker if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js') .then(registration => { console.log('Service Worker registered:', registration); }) .catch(error => { console.error('Service Worker registration failed:', error); }); } ``` #### Push Notification Setup ```typescript // Request notification permission const permission = await Notification.requestPermission(); if (permission === 'granted') { // Subscribe to push notifications const subscription = await registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: 'your-vapid-public-key' }); // Send subscription to your server await fetch('/api/push-subscription', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(subscription) }); } ``` ## Testing Migration ### Unit Tests ```typescript import { DailyNotification } from '@timesafari/daily-notification-plugin'; describe('Migration Tests', () => { test('backward compatibility', async () => { // Test that old API still works await DailyNotification.scheduleDailyNotification({ title: 'Test', body: 'Test body', schedule: '0 9 * * *' }); }); test('new dual scheduling', async () => { const config = { contentFetch: { schedule: '0 8 * * *', ttlSeconds: 3600 }, userNotification: { schedule: '0 9 * * *', title: 'Test' } }; await DailyNotification.scheduleDualNotification(config); const status = await DailyNotification.getDualScheduleStatus(); expect(status.nextRuns).toBeDefined(); }); test('callback registration', async () => { await DailyNotification.registerCallback('test', { kind: 'local', target: 'testCallback' }); const callbacks = await DailyNotification.getRegisteredCallbacks(); expect(callbacks).toContain('test'); }); }); ``` ### Integration Tests ```typescript describe('Integration Tests', () => { test('end-to-end dual scheduling', async () => { // Schedule content fetch await DailyNotification.scheduleContentFetch({ schedule: '0 8 * * *', ttlSeconds: 3600, source: 'api', url: 'https://api.example.com/content' }); // Schedule notification await DailyNotification.scheduleUserNotification({ schedule: '0 9 * * *', title: 'Daily Update', body: 'Content ready' }); // Verify status const status = await DailyNotification.getDualScheduleStatus(); expect(status.nextRuns.length).toBe(2); }); }); ``` ## Troubleshooting ### Common Issues #### Android - **Permission Denied**: Ensure all required permissions are declared - **WorkManager Not Running**: Check battery optimization settings - **Database Errors**: Verify Room database schema migration #### iOS - **Background Tasks Not Running**: Check Background App Refresh settings - **Core Data Errors**: Verify Core Data model compatibility - **Notification Permissions**: Request notification permissions #### Web - **Service Worker Not Registering**: Ensure HTTPS and proper file paths - **Push Notifications Not Working**: Verify VAPID keys and server setup - **IndexedDB Errors**: Check browser compatibility and storage quotas ### Debug Commands ```typescript // Get comprehensive status const status = await DailyNotification.getDualScheduleStatus(); console.log('Status:', status); // Check registered callbacks const callbacks = await DailyNotification.getRegisteredCallbacks(); console.log('Callbacks:', callbacks); // Test callback firing await DailyNotification.registerCallback('debug', { kind: 'local', target: 'debugCallback' }); function debugCallback(event: CallbackEvent) { console.log('Debug callback fired:', event); } ``` ## Performance Considerations ### Memory Usage - **Android**: Room database with connection pooling - **iOS**: Core Data with lightweight contexts - **Web**: IndexedDB with efficient indexing ### Battery Optimization - **Android**: WorkManager with battery-aware constraints - **iOS**: BGTaskScheduler with system-managed execution - **Web**: Service Worker with efficient background sync ### Network Usage - **Circuit Breaker**: Prevents excessive retry attempts - **TTL-at-Fire**: Reduces unnecessary network calls - **Exponential Backoff**: Intelligent retry scheduling ## Security Considerations ### Permissions - **Minimal Permissions**: Only request necessary permissions - **Runtime Checks**: Verify permissions before operations - **Graceful Degradation**: Handle permission denials gracefully ### Data Protection - **Local Storage**: Encrypted local storage on all platforms - **Network Security**: HTTPS-only for all network operations - **Callback Security**: Validate callback URLs and headers ### Privacy - **No Personal Data**: Plugin doesn't collect personal information - **Local Processing**: All processing happens locally - **User Control**: Users can disable notifications and callbacks ## Support ### Documentation - **API Reference**: Complete TypeScript definitions - **Examples**: Comprehensive usage examples - **Troubleshooting**: Common issues and solutions ### Community - **GitHub Issues**: Report bugs and request features - **Discussions**: Ask questions and share solutions - **Contributing**: Submit pull requests and improvements ### Enterprise Support - **Custom Implementations**: Tailored solutions for enterprise needs - **Integration Support**: Help with complex integrations - **Performance Optimization**: Custom performance tuning --- **Next Steps**: After migration, explore the [Enterprise Callback Examples](./enterprise-callback-examples.md) for advanced integration patterns.