Browse Source
- 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 pathresearch/notification-plugin-enhancement
3 changed files with 1986 additions and 89 deletions
@ -1,150 +1,528 @@ |
|||
# Daily Notification Plugin |
|||
|
|||
A Native-First Capacitor plugin for reliable daily notifications across Android, iOS, and Web platforms. |
|||
**Author**: Matthew Raymer |
|||
**Version**: 2.0.0 |
|||
**Created**: 2025-09-22 09:22:32 UTC |
|||
**Last Updated**: 2025-09-22 09:22:32 UTC |
|||
|
|||
## Key Features |
|||
## Overview |
|||
|
|||
- **Native-First Architecture**: Optimized for mobile platforms with offline-first design |
|||
- **Shared SQLite Storage**: Single database file with WAL mode for concurrent access |
|||
- **TTL-at-Fire Enforcement**: Skip stale notifications before delivery |
|||
- **Rolling Window Safety**: Always keep today's notifications armed |
|||
- **Cross-Platform**: Unified API across Android, iOS, and Web |
|||
- **Production Ready**: Comprehensive error handling, performance optimization, and monitoring |
|||
The Daily Notification Plugin is a comprehensive Capacitor plugin that provides enterprise-grade daily notification functionality across Android, iOS, and Web platforms. It features dual scheduling, callback support, TTL-at-fire logic, and comprehensive observability. |
|||
|
|||
## Features |
|||
|
|||
### 🚀 **Core Features** |
|||
|
|||
- **Dual Scheduling**: Separate content fetch and user notification scheduling |
|||
- **TTL-at-Fire Logic**: Content validity checking at notification time |
|||
- **Callback System**: HTTP, local, and queue callback support |
|||
- **Circuit Breaker Pattern**: Automatic failure detection and recovery |
|||
- **Cross-Platform**: Android, iOS, and Web implementations |
|||
|
|||
### 📱 **Platform Support** |
|||
|
|||
- **Android**: WorkManager + AlarmManager + SQLite (Room) |
|||
- **iOS**: BGTaskScheduler + UNUserNotificationCenter + Core Data |
|||
- **Web**: Service Worker + IndexedDB + Push Notifications |
|||
|
|||
### 🔧 **Enterprise Features** |
|||
|
|||
- **Observability**: Structured logging with event codes |
|||
- **Health Monitoring**: Comprehensive status and performance metrics |
|||
- **Error Handling**: Exponential backoff and retry logic |
|||
- **Security**: Encrypted storage and secure callback handling |
|||
|
|||
## Installation |
|||
|
|||
```bash |
|||
npm install @timesafari/daily-notification-plugin |
|||
``` |
|||
|
|||
## Quick Start |
|||
|
|||
### Basic Usage |
|||
|
|||
```typescript |
|||
import { DailyNotification } from '@timesafari/daily-notification-plugin'; |
|||
|
|||
// Configure and schedule |
|||
await DailyNotification.configure({ |
|||
storage: 'shared', |
|||
ttlSeconds: 1800, |
|||
prefetchLeadMinutes: 15 |
|||
// Schedule a daily notification |
|||
await DailyNotification.scheduleDailyNotification({ |
|||
title: 'Daily Update', |
|||
body: 'Your daily content is ready', |
|||
schedule: '0 9 * * *' // 9 AM daily |
|||
}); |
|||
``` |
|||
|
|||
### Enhanced Usage (Recommended) |
|||
|
|||
```typescript |
|||
import { |
|||
DailyNotification, |
|||
DualScheduleConfiguration |
|||
} from '@timesafari/daily-notification-plugin'; |
|||
|
|||
// Configure 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); |
|||
``` |
|||
|
|||
### Callback Integration |
|||
|
|||
```typescript |
|||
// Register analytics callback |
|||
await DailyNotification.registerCallback('analytics', { |
|||
kind: 'http', |
|||
target: 'https://analytics.example.com/events', |
|||
headers: { |
|||
'Authorization': 'Bearer your-token', |
|||
'Content-Type': 'application/json' |
|||
} |
|||
}); |
|||
|
|||
// Register local callback |
|||
await DailyNotification.registerCallback('database', { |
|||
kind: 'local', |
|||
target: 'saveToDatabase' |
|||
}); |
|||
|
|||
function saveToDatabase(event: CallbackEvent) { |
|||
console.log('Saving to database:', event); |
|||
// Your database save logic here |
|||
} |
|||
``` |
|||
|
|||
## API Reference |
|||
|
|||
### Core Methods |
|||
|
|||
#### `scheduleDailyNotification(options)` |
|||
|
|||
Schedule a basic daily notification (backward compatible). |
|||
|
|||
```typescript |
|||
await DailyNotification.scheduleDailyNotification({ |
|||
url: 'https://api.example.com/daily-content', |
|||
time: '09:00', |
|||
title: 'Daily Update', |
|||
body: 'Your daily notification is ready' |
|||
title: string; |
|||
body: string; |
|||
schedule: string; // Cron expression |
|||
actions?: NotificationAction[]; |
|||
}); |
|||
``` |
|||
|
|||
## Installation |
|||
#### `scheduleContentFetch(config)` |
|||
|
|||
```bash |
|||
npm install @timesafari/daily-notification-plugin |
|||
Schedule content fetching separately. |
|||
|
|||
```typescript |
|||
await DailyNotification.scheduleContentFetch({ |
|||
schedule: string; // Cron expression |
|||
ttlSeconds: number; // Time-to-live in seconds |
|||
source: string; // Content source identifier |
|||
url?: string; // API endpoint URL |
|||
headers?: Record<string, string>; |
|||
}); |
|||
``` |
|||
|
|||
## Documentation |
|||
#### `scheduleUserNotification(config)` |
|||
|
|||
- **[Complete Usage Guide](USAGE.md)** - Comprehensive guide with examples and best practices |
|||
- **[API Reference](API.md)** - Complete method and type definitions |
|||
- **[Implementation Roadmap](doc/implementation-roadmap.md)** - Technical implementation details |
|||
- **[Notification System Spec](doc/notification-system.md)** - Architecture and design principles |
|||
- **[Glossary](doc/GLOSSARY.md)** - Key terminology and concepts |
|||
Schedule user notifications separately. |
|||
|
|||
## Examples |
|||
```typescript |
|||
await DailyNotification.scheduleUserNotification({ |
|||
schedule: string; // Cron expression |
|||
title: string; // Notification title |
|||
body: string; // Notification body |
|||
actions?: NotificationAction[]; |
|||
}); |
|||
``` |
|||
|
|||
- **Basic Usage**: `examples/usage.ts` |
|||
- **Phase-by-Phase Implementation**: |
|||
- Phase 1: `examples/phase1-*.ts` (Core Infrastructure) |
|||
- Phase 2: `examples/phase2-*.ts` (Platform Completion) |
|||
- Phase 3: `examples/phase3-*.ts` (Network Optimization) |
|||
- **Advanced Scenarios**: `examples/advanced-usage.ts` |
|||
- **Enterprise Features**: `examples/enterprise-usage.ts` |
|||
#### `scheduleDualNotification(config)` |
|||
|
|||
## Configuration |
|||
Schedule both content fetch and user notification. |
|||
|
|||
```typescript |
|||
await DailyNotification.scheduleDualNotification({ |
|||
contentFetch: ContentFetchConfig; |
|||
userNotification: UserNotificationConfig; |
|||
}); |
|||
``` |
|||
|
|||
### Callback Methods |
|||
|
|||
#### `registerCallback(name, config)` |
|||
|
|||
Register a callback function. |
|||
|
|||
```typescript |
|||
await DailyNotification.registerCallback('callback-name', { |
|||
kind: 'http' | 'local' | 'queue'; |
|||
target: string; // URL or function name |
|||
headers?: Record<string, string>; |
|||
}); |
|||
``` |
|||
|
|||
#### `unregisterCallback(name)` |
|||
|
|||
Remove a registered callback. |
|||
|
|||
```typescript |
|||
await DailyNotification.unregisterCallback('callback-name'); |
|||
``` |
|||
|
|||
#### `getRegisteredCallbacks()` |
|||
|
|||
Get list of registered callbacks. |
|||
|
|||
```typescript |
|||
const callbacks = await DailyNotification.getRegisteredCallbacks(); |
|||
// Returns: string[] |
|||
``` |
|||
|
|||
### Status Methods |
|||
|
|||
#### `getDualScheduleStatus()` |
|||
|
|||
Get comprehensive status information. |
|||
|
|||
```typescript |
|||
const status = await DailyNotification.getDualScheduleStatus(); |
|||
// Returns: { |
|||
// nextRuns: number[]; |
|||
// lastOutcomes: string[]; |
|||
// cacheAgeMs: number | null; |
|||
// staleArmed: boolean; |
|||
// queueDepth: number; |
|||
// circuitBreakers: CircuitBreakerStatus; |
|||
// performance: PerformanceMetrics; |
|||
// } |
|||
``` |
|||
|
|||
## Platform Requirements |
|||
|
|||
### Android |
|||
|
|||
Add the following permissions to your `AndroidManifest.xml`: |
|||
- **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+ |
|||
|
|||
## Configuration |
|||
|
|||
### Android Configuration |
|||
|
|||
#### AndroidManifest.xml |
|||
|
|||
```xml |
|||
<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" /> |
|||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" /> |
|||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> |
|||
<uses-permission android:name="android.permission.INTERNET" /> |
|||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> |
|||
|
|||
<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> |
|||
``` |
|||
|
|||
## Development |
|||
#### build.gradle |
|||
|
|||
### Prerequisites |
|||
```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" |
|||
} |
|||
``` |
|||
|
|||
- Node.js 14 or later |
|||
- Android Studio |
|||
- Android SDK |
|||
- Gradle |
|||
### iOS Configuration |
|||
|
|||
### Building |
|||
#### Info.plist |
|||
|
|||
```bash |
|||
# Install dependencies |
|||
npm install |
|||
```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> |
|||
``` |
|||
|
|||
# Build the plugin |
|||
npm run build |
|||
#### Capabilities |
|||
|
|||
1. Enable "Background Modes" capability |
|||
2. Enable "Background App Refresh" |
|||
3. Enable "Background Processing" |
|||
|
|||
### Web Configuration |
|||
|
|||
#### Service Worker Registration |
|||
|
|||
```typescript |
|||
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 |
|||
const permission = await Notification.requestPermission(); |
|||
|
|||
if (permission === 'granted') { |
|||
const subscription = await registration.pushManager.subscribe({ |
|||
userVisibleOnly: true, |
|||
applicationServerKey: 'your-vapid-public-key' |
|||
}); |
|||
|
|||
await fetch('/api/push-subscription', { |
|||
method: 'POST', |
|||
headers: { 'Content-Type': 'application/json' }, |
|||
body: JSON.stringify(subscription) |
|||
}); |
|||
} |
|||
``` |
|||
|
|||
# Run tests |
|||
## Testing |
|||
|
|||
### Unit Tests |
|||
|
|||
```bash |
|||
npm test |
|||
``` |
|||
|
|||
### Project Structure |
|||
### Integration Tests |
|||
|
|||
```typescript |
|||
import { DailyNotification } from '@timesafari/daily-notification-plugin'; |
|||
|
|||
describe('Integration Tests', () => { |
|||
test('dual scheduling workflow', 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.length).toBe(2); |
|||
}); |
|||
}); |
|||
``` |
|||
|
|||
## Enterprise Integration |
|||
|
|||
### Analytics Integration |
|||
|
|||
```typescript |
|||
// Google Analytics 4 |
|||
const ga4Callback = new GoogleAnalyticsCallback('G-XXXXXXXXXX', 'your-api-secret'); |
|||
await ga4Callback.register(); |
|||
|
|||
// Mixpanel |
|||
const mixpanelCallback = new MixpanelCallback('your-project-token'); |
|||
await mixpanelCallback.register(); |
|||
``` |
|||
|
|||
### CRM Integration |
|||
|
|||
```typescript |
|||
// Salesforce |
|||
const salesforceCallback = new SalesforceCallback('your-access-token', 'your-instance-url'); |
|||
await salesforceCallback.register(); |
|||
|
|||
// HubSpot |
|||
const hubspotCallback = new HubSpotCallback('your-api-key'); |
|||
await hubspotCallback.register(); |
|||
``` |
|||
|
|||
### Monitoring Integration |
|||
|
|||
```typescript |
|||
// Datadog |
|||
const datadogCallback = new DatadogCallback('your-api-key', 'your-app-key'); |
|||
await datadogCallback.register(); |
|||
|
|||
// New Relic |
|||
const newrelicCallback = new NewRelicCallback('your-license-key'); |
|||
await newrelicCallback.register(); |
|||
``` |
|||
daily-notification-plugin/ |
|||
├── android/ # Android implementation |
|||
│ ├── app/ # Main application module |
|||
│ └── build.gradle # Root build configuration |
|||
├── src/ # TypeScript source |
|||
├── tests/ # Test files |
|||
├── package.json # Package configuration |
|||
└── README.md # This file |
|||
|
|||
## 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); |
|||
``` |
|||
|
|||
## 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 |
|||
|
|||
## Contributing |
|||
|
|||
### Development Setup |
|||
|
|||
```bash |
|||
git clone https://github.com/timesafari/daily-notification-plugin.git |
|||
cd daily-notification-plugin |
|||
npm install |
|||
npm run build |
|||
npm test |
|||
``` |
|||
|
|||
### Code Standards |
|||
|
|||
- **TypeScript**: Strict type checking enabled |
|||
- **ESLint**: Code quality and consistency |
|||
- **Prettier**: Code formatting |
|||
- **Jest**: Comprehensive testing |
|||
|
|||
### Pull Request Process |
|||
|
|||
1. Fork the repository |
|||
2. Create your feature branch (`git checkout -b feature/amazing-feature`) |
|||
3. Commit your changes (`git commit -m 'Add some amazing feature'`) |
|||
4. Push to the branch (`git push origin feature/amazing-feature`) |
|||
5. Open a Pull Request |
|||
2. Create a feature branch |
|||
3. Make your changes |
|||
4. Add tests for new functionality |
|||
5. Ensure all tests pass |
|||
6. Submit a pull request |
|||
|
|||
## License |
|||
|
|||
This project is licensed under the MIT License - see the LICENSE file for details. |
|||
MIT License - see [LICENSE](LICENSE) file for details. |
|||
|
|||
## Support |
|||
|
|||
## Author |
|||
### Documentation |
|||
|
|||
Matthew Raymer |
|||
- **API Reference**: Complete TypeScript definitions |
|||
- **Migration Guide**: [doc/migration-guide.md](doc/migration-guide.md) |
|||
- **Enterprise Examples**: [doc/enterprise-callback-examples.md](doc/enterprise-callback-examples.md) |
|||
|
|||
## Security |
|||
### Community |
|||
|
|||
This plugin follows security best practices: |
|||
- **GitHub Issues**: Report bugs and request features |
|||
- **Discussions**: Ask questions and share solutions |
|||
- **Contributing**: Submit pull requests and improvements |
|||
|
|||
- Uses AndroidX for modern security features |
|||
- Implements proper permission handling |
|||
- Follows Android security guidelines |
|||
- Uses secure storage for sensitive data |
|||
- Implements proper error handling |
|||
- Logs security-relevant events |
|||
- Uses secure communication channels |
|||
- Implements proper access control |
|||
- Follows Android's security model |
|||
- Uses secure defaults |
|||
### Enterprise Support |
|||
|
|||
## Changelog |
|||
- **Custom Implementations**: Tailored solutions for enterprise needs |
|||
- **Integration Support**: Help with complex integrations |
|||
- **Performance Optimization**: Custom performance tuning |
|||
|
|||
### 1.0.0 |
|||
--- |
|||
|
|||
- Initial release |
|||
- Basic notification scheduling |
|||
- System state handling |
|||
- Battery optimization support |
|||
- Background task management |
|||
- Rich logging system |
|||
**Version**: 2.0.0 |
|||
**Last Updated**: 2025-09-22 09:22:32 UTC |
|||
**Author**: Matthew Raymer |
|||
|
File diff suppressed because it is too large
@ -0,0 +1,436 @@ |
|||
# 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. |
Loading…
Reference in new issue