# Daily Notification Plugin **Author**: Matthew Raymer **Version**: 2.2.0 **Created**: 2025-09-22 09:22:32 UTC **Last Updated**: 2025-10-08 06:02:45 UTC ## Overview The Daily Notification Plugin is a comprehensive Capacitor plugin that provides enterprise-grade daily notification functionality across Android, iOS, and Electron platforms. It features dual scheduling, callback support, TTL-at-fire logic, and comprehensive observability. ### ๐ŸŽฏ **Native-First Architecture** The plugin has been optimized for **native-first deployment** with the following key improvements: **Platform Support:** - โœ… **Android**: WorkManager + AlarmManager + SQLite - โœ… **iOS**: BGTaskScheduler + UNUserNotificationCenter + Core Data - โœ… **Electron**: Desktop notifications + SQLite/LocalStorage - โŒ **Web (PWA)**: Removed for native-first focus **Key Benefits:** - **Simplified Architecture**: Focused on mobile and desktop platforms - **Better Performance**: Optimized for native platform capabilities - **Reduced Complexity**: Fewer platform-specific code paths - **Cleaner Codebase**: Removed unused web-specific code (~90 lines) ## Implementation Status ### โœ… **Phase 2 Complete - Production Ready** | Component | Status | Implementation | |-----------|--------|----------------| | **Android Core** | โœ… Complete | WorkManager + AlarmManager + SQLite | | **iOS Parity** | โœ… Complete | BGTaskScheduler + UNUserNotificationCenter | | **Web Service Worker** | โŒ Removed | Web support dropped for native-first architecture | | **Callback Registry** | โœ… Complete | Circuit breaker + retry logic | | **Observability** | โœ… Complete | Structured logging + health monitoring | | **Documentation** | โœ… Complete | Migration guides + enterprise examples | **All platforms are fully implemented with complete feature parity and enterprise-grade functionality.** ### ๐Ÿงช **Testing & Quality** - **Test Coverage**: 58 tests across 4 test suites โœ… - **Build Status**: TypeScript compilation and Rollup bundling โœ… - **Code Quality**: ESLint and Prettier compliance โœ… - **Cross-Platform**: Unified API surface across all platforms โœ… ## 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 - **Static Daily Reminders**: Simple daily notifications without network content - **Cross-Platform**: Android, iOS, and Electron implementations ### ๐Ÿ“ฑ **Platform Support** - **Android**: WorkManager + AlarmManager + SQLite (Room) - **iOS**: BGTaskScheduler + UNUserNotificationCenter + Core Data - **Web**: โŒ Removed (native-first architecture) ### ๐Ÿ”ง **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 ### โฐ **Static Daily Reminders** - **No Network Required**: Completely offline reminder notifications - **Simple Scheduling**: Easy daily reminder setup with HH:mm time format - **Rich Customization**: Customizable title, body, sound, vibration, and priority - **Persistent Storage**: Survives app restarts and device reboots - **Cross-Platform**: Consistent API across Android, iOS, and Electron - **Management**: Full CRUD operations for reminder management ## Installation ```bash npm install @timesafari/daily-notification-plugin ``` ## Quick Start ### Basic Usage ```typescript import { DailyNotification } from '@timesafari/daily-notification-plugin'; // 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 } ``` ### Static Daily Reminders For simple daily reminders that don't require network content: ```typescript import { DailyNotification } from '@timesafari/daily-notification-plugin'; // Schedule a simple daily reminder await DailyNotification.scheduleDailyReminder({ id: 'morning_checkin', title: 'Good Morning!', body: 'Time to check your TimeSafari community updates', time: '09:00', // HH:mm format sound: true, vibration: true, priority: 'normal', repeatDaily: true }); // Get all scheduled reminders const result = await DailyNotification.getScheduledReminders(); console.log('Scheduled reminders:', result.reminders); // Update an existing reminder await DailyNotification.updateDailyReminder('morning_checkin', { title: 'Updated Morning Reminder', time: '08:30' }); // Cancel a reminder await DailyNotification.cancelDailyReminder('morning_checkin'); ``` **Key Benefits of Static Reminders:** - โœ… **No network dependency** - works completely offline - โœ… **No content cache required** - direct notification display - โœ… **Simple API** - easy to use for basic reminder functionality - โœ… **Persistent** - survives app restarts and device reboots ## API Reference ### Core Methods #### `scheduleDailyNotification(options)` Schedule a basic daily notification (backward compatible). ```typescript await DailyNotification.scheduleDailyNotification({ title: string; body: string; schedule: string; // Cron expression actions?: NotificationAction[]; }); ``` #### `scheduleContentFetch(config)` 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; }); ``` #### `scheduleUserNotification(config)` Schedule user notifications separately. ```typescript await DailyNotification.scheduleUserNotification({ schedule: string; // Cron expression title: string; // Notification title body: string; // Notification body actions?: NotificationAction[]; }); ``` #### `scheduleDualNotification(config)` 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; }); ``` #### `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; // } ``` ## Capacitor Compatibility Matrix | Plugin Version | Capacitor Version | Status | Notes | |----------------|-------------------|--------|-------| | 1.0.0+ | 6.2.1+ | โœ… **Recommended** | Latest stable, full feature support | | 1.0.0+ | 6.0.0 - 6.2.0 | โœ… **Supported** | Full feature support | | 1.0.0+ | 5.7.8 | โš ๏ธ **Legacy** | Deprecated, upgrade recommended | ### Quick Smoke Test For immediate validation of plugin functionality: - **Android**: [Manual Smoke Test - Android](./docs/manual_smoke_test.md#android-platform-testing) - **iOS**: [Manual Smoke Test - iOS](./docs/manual_smoke_test.md#ios-platform-testing) - **Electron**: [Manual Smoke Test - Electron](./docs/manual_smoke_test.md#electron-platform-testing) ### Manual Smoke Test Documentation Complete testing procedures: [docs/manual_smoke_test.md](./docs/manual_smoke_test.md) ## 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 ### Electron - **Minimum Version**: Electron 20+ - **Desktop Notifications**: Native desktop notification APIs - **Storage**: SQLite or LocalStorage fallback - **Permissions**: Desktop notification permissions ## Capacitor Compatibility Matrix | Plugin Version | Capacitor Version | Android | iOS | Electron | Status | |----------------|-------------------|---------|-----|----------|--------| | 2.2.x | 6.2.x | โœ… | โœ… | โœ… | **Current** | | 2.1.x | 6.1.x | โœ… | โœ… | โœ… | Supported | | 2.0.x | 6.0.x | โœ… | โœ… | โœ… | Supported | | 1.x.x | 5.x.x | โš ๏ธ | โš ๏ธ | โŒ | Deprecated | ### Installation Guide **For TimeSafari PWA Integration:** ```bash # Install the plugin npm install @timesafari/daily-notification-plugin # For workspace development (recommended) npm install --save-dev @timesafari/daily-notification-plugin ``` **Workspace Linking (Development):** ```bash # Link plugin for local development npm link @timesafari/daily-notification-plugin # Or use pnpm workspace pnpm add @timesafari/daily-notification-plugin --filter timesafari-app ``` **Capacitor Integration:** ```typescript // In your Capacitor app import { DailyNotification } from '@timesafari/daily-notification-plugin'; // Initialize the plugin await DailyNotification.configure({ storage: 'tiered', ttlSeconds: 1800, enableETagSupport: true }); ``` ### Static Daily Reminder Methods #### `scheduleDailyReminder(options)` Schedule a simple daily reminder without network content. ```typescript await DailyNotification.scheduleDailyReminder({ id: string; // Unique reminder identifier title: string; // Notification title body: string; // Notification body time: string; // Time in HH:mm format (e.g., "09:00") sound?: boolean; // Enable sound (default: true) vibration?: boolean; // Enable vibration (default: true) priority?: 'low' | 'normal' | 'high'; // Priority level (default: 'normal') repeatDaily?: boolean; // Repeat daily (default: true) timezone?: string; // Optional timezone }); ``` #### `cancelDailyReminder(reminderId)` Cancel a scheduled daily reminder. ```typescript await DailyNotification.cancelDailyReminder('morning_checkin'); ``` #### `getScheduledReminders()` Get all scheduled reminders. ```typescript const result = await DailyNotification.getScheduledReminders(); console.log('Reminders:', result.reminders); ``` #### `updateDailyReminder(reminderId, options)` Update an existing daily reminder. ```typescript await DailyNotification.updateDailyReminder('morning_checkin', { title: 'Updated Title', time: '08:30', priority: 'high' }); ``` ## Configuration ### Android Configuration #### AndroidManifest.xml ```xml ``` #### 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 Configuration #### Info.plist ```xml UIBackgroundModes background-app-refresh background-processing BGTaskSchedulerPermittedIdentifiers com.timesafari.dailynotification.content-fetch com.timesafari.dailynotification.notification-delivery ``` #### 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) }); } ``` ## Testing ### Unit Tests ```bash npm test ``` ### 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(); ``` ## 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 - **Web Support**: Web platform support was removed for native-first architecture ### 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**: โŒ Removed (native-first architecture) ### 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 a feature branch 3. Make your changes 4. Add tests for new functionality 5. Ensure all tests pass 6. Submit a pull request ## License MIT License - see [LICENSE](LICENSE) file for details. ## Support ### Documentation - **API Reference**: Complete TypeScript definitions - **Migration Guide**: [doc/migration-guide.md](doc/migration-guide.md) - **Integration Guide**: [INTEGRATION_GUIDE.md](INTEGRATION_GUIDE.md) - Complete integration instructions - **Implementation Guide**: [doc/STARRED_PROJECTS_POLLING_IMPLEMENTATION.md](doc/STARRED_PROJECTS_POLLING_IMPLEMENTATION.md) - Generic polling interface - **UI Requirements**: [doc/UI_REQUIREMENTS.md](doc/UI_REQUIREMENTS.md) - Complete UI component requirements - **Host App Examples**: [examples/hello-poll.ts](examples/hello-poll.ts) - Generic polling integration - **Background Data Fetching Plan**: [doc/BACKGROUND_DATA_FETCHING_PLAN.md](doc/BACKGROUND_DATA_FETCHING_PLAN.md) - Complete Option A implementation guide ### 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 --- **Version**: 2.0.0 **Last Updated**: 2025-09-22 09:22:32 UTC **Status**: Phase 2 Complete - Production Ready **Author**: Matthew Raymer