- Add complete migration guide with step-by-step instructions - Include platform-specific configuration examples (Android, iOS, Web) - Provide comprehensive enterprise callback examples - Cover analytics integration (GA4, Mixpanel) - Include CRM integration (Salesforce, HubSpot) - Add database operations (PostgreSQL, MongoDB) - Include monitoring & alerting (Datadog, New Relic) - Provide multi-service orchestration examples - Add error handling patterns (circuit breaker, retry logic) - Include performance optimization techniques - Add security best practices and authentication - Update main README with complete API reference - Include troubleshooting and testing guidance BREAKING CHANGE: Documentation structure updated with new migration path
437 lines
12 KiB
Markdown
437 lines
12 KiB
Markdown
# 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
|
|
<!-- Add new permissions -->
|
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
|
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
|
|
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
|
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
|
|
|
<!-- Register new receivers -->
|
|
<receiver android:name="com.timesafari.dailynotification.NotifyReceiver"
|
|
android:enabled="true"
|
|
android:exported="false" />
|
|
<receiver android:name="com.timesafari.dailynotification.BootReceiver"
|
|
android:enabled="true"
|
|
android:exported="false">
|
|
<intent-filter>
|
|
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
|
</intent-filter>
|
|
</receiver>
|
|
```
|
|
|
|
#### 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
|
|
<key>UIBackgroundModes</key>
|
|
<array>
|
|
<string>background-app-refresh</string>
|
|
<string>background-processing</string>
|
|
</array>
|
|
|
|
<key>BGTaskSchedulerPermittedIdentifiers</key>
|
|
<array>
|
|
<string>com.timesafari.dailynotification.content-fetch</string>
|
|
<string>com.timesafari.dailynotification.notification-delivery</string>
|
|
</array>
|
|
```
|
|
|
|
#### 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.
|