# Plugin Requirements & Implementation Directive **Author**: Matthew Raymer **Date**: November 2025 **Status**: Active Requirements - Implementation Guide ## Purpose This document defines the **rules the plugin must follow** to behave predictably across Android and iOS platforms. It specifies: * Persistence requirements * Recovery strategies * JS/TS API contract and caveats * Missed alarm handling * Platform-specific requirements * Testing requirements **This document should be updated** after exploration findings are documented. **Reference**: See [Platform Capability Reference](./platform-capability-reference.md) for OS-level facts. --- ## 1. Core Requirements ### 1.1 Plugin Behavior Guarantees The plugin **must** guarantee the following behaviors: | Behavior | Android | iOS | Implementation Required | | -------- | ------- | --- | ----------------------- | | Notification fires after swipe/termination | ✅ Yes | ✅ Yes | OS-guaranteed (verify) | | Notification fires after reboot | ⚠️ Only if rescheduled | ✅ Yes | Android: Boot receiver required | | Missed alarm detection | ✅ Required | ✅ Required | Both: App launch recovery | | Force stop recovery | ✅ Required | N/A | Android: App restart recovery | | Exact timing | ✅ With permission | ⚠️ ±180s tolerance | Android: Permission check | ### 1.2 Plugin Behavior Limitations The plugin **cannot** guarantee: | Limitation | Platform | Reason | | ---------- | -------- | ------ | | Notification after Force Stop (Android) | Android | OS hard kill | | App code execution on iOS notification fire | iOS | OS limitation | | Background execution timing (iOS) | iOS | System-controlled | | Exact timing (iOS) | iOS | ±180s tolerance | --- ## 2. Persistence Requirements ### 2.1 Required Persistence Items The plugin **must** persist the following for each scheduled alarm/notification: | Field | Type | Required | Purpose | | ----- | ---- | -------- | ------- | | `alarm_id` | String | ✅ Yes | Unique identifier | | `trigger_time` | Long/TimeInterval | ✅ Yes | When to fire | | `repeat_rule` | String/Enum | ✅ Yes | NONE, DAILY, WEEKLY, CUSTOM | | `channel_id` | String | ✅ Yes | Notification channel (Android) | | `priority` | String/Int | ✅ Yes | Notification priority | | `title` | String | ✅ Yes | Notification title | | `body` | String | ✅ Yes | Notification body | | `sound_enabled` | Boolean | ✅ Yes | Sound preference | | `vibration_enabled` | Boolean | ✅ Yes | Vibration preference | | `payload` | String/JSON | ⚠️ Optional | Additional content | | `created_at` | Long/TimeInterval | ✅ Yes | Creation timestamp | | `updated_at` | Long/TimeInterval | ✅ Yes | Last update timestamp | | `enabled` | Boolean | ✅ Yes | Whether alarm is active | ### 2.2 Storage Implementation **Android**: * **Primary**: Room database (`DailyNotificationDatabase`) * **Location**: `android/src/main/java/com/timesafari/dailynotification/` * **Entities**: `Schedule`, `NotificationContentEntity`, `ContentCache` **iOS**: * **Primary**: UNUserNotificationCenter (OS-managed) * **Secondary**: Plugin storage (UserDefaults, CoreData, or files) * **Location**: `ios/Plugin/` * **Component**: `DailyNotificationStorage?` ### 2.3 Persistence Validation The plugin **must**: * Validate persistence on every alarm schedule * Log persistence failures * Handle persistence errors gracefully * Provide recovery mechanism if persistence fails --- ## 3. Recovery Requirements ### 3.1 Required Recovery Points The plugin **must** implement recovery at the following points: #### 3.1.1 Boot Event (Android Only) **Trigger**: `BOOT_COMPLETED` broadcast **Required Actions**: 1. Load all enabled alarms from persistent storage 2. Reschedule each alarm using AlarmManager 3. Detect missed alarms (trigger_time < now) 4. Generate missed alarm events/notifications 5. Log recovery actions **Code Reference**: `BootReceiver.kt` line 24 **Implementation Status**: ☐ Implemented / ☐ Missing --- #### 3.1.2 App Cold Start **Trigger**: App launched from terminated state **Required Actions**: 1. Load all enabled alarms from persistent storage 2. Verify active alarms match stored alarms 3. Detect missed alarms (trigger_time < now) 4. Reschedule future alarms 5. Generate missed alarm events/notifications 6. Log recovery actions **Implementation Status**: ☐ Implemented / ☐ Missing **Code Location**: Check plugin initialization (`DailyNotificationPlugin.load()` or equivalent) --- #### 3.1.3 App Warm Start **Trigger**: App returning from background **Required Actions**: 1. Verify active alarms are still scheduled 2. Detect missed alarms (trigger_time < now) 3. Reschedule if needed 4. Log recovery actions **Implementation Status**: ☐ Implemented / ☐ Missing --- #### 3.1.4 User Taps Notification **Trigger**: User interaction with notification **Required Actions**: 1. Launch app (OS handles) 2. Detect if notification was missed 3. Handle notification action 4. Update alarm state if needed **Implementation Status**: ☐ Implemented / ☐ Missing --- ### 3.2 Missed Alarm Handling The plugin **must** detect and handle missed alarms: **Definition**: An alarm is "missed" if: * `trigger_time < now` * Alarm was not fired (or firing status unknown) * Alarm is still enabled **Required Actions**: 1. **Detect** missed alarms during recovery 2. **Generate** missed alarm event/notification 3. **Reschedule** future occurrences (if repeating) 4. **Log** missed alarm for debugging 5. **Update** alarm state (mark as missed or reschedule) **Implementation Requirements**: * Must run on app launch (cold/warm start) * Must run on boot (Android) * Must not duplicate missed alarm notifications * Must handle timezone changes **Code Location**: To be implemented in recovery logic --- ## 4. JS/TS API Contract ### 4.1 API Guarantees The plugin **must** document and guarantee the following behaviors to JavaScript/TypeScript developers: #### 4.1.1 `scheduleDailyNotification(options)` **Guarantees**: * ✅ Notification will fire if app is swiped from recents * ✅ Notification will fire if app is terminated by OS * ⚠️ Notification will fire after reboot **only if**: * Android: Boot receiver is registered and working * iOS: Automatic (OS handles) * ❌ Notification will **NOT** fire after Android Force Stop until app is opened * ⚠️ iOS notifications have ±180s timing tolerance **Caveats**: * Android requires `SCHEDULE_EXACT_ALARM` permission on Android 12+ * Android requires `RECEIVE_BOOT_COMPLETED` permission for reboot recovery * iOS requires notification authorization **Error Codes**: * `EXACT_ALARM_PERMISSION_REQUIRED` - Android 12+ exact alarm permission needed * `NOTIFICATIONS_DENIED` - Notification permission denied * `SCHEDULE_FAILED` - Scheduling failed (check logs) --- #### 4.1.2 `scheduleDailyReminder(options)` **Guarantees**: * Same as `scheduleDailyNotification()` above * Static reminder (no content dependency) * Fires even if content fetch fails --- #### 4.1.3 `getNotificationStatus()` **Guarantees**: * Returns current notification status * Includes pending notifications * Includes last notification time * May include missed alarm information --- ### 4.2 API Warnings The plugin **must** document the following warnings: **Android**: * "Notifications will not fire after device reboot unless the app is opened at least once" * "Force Stop will prevent all notifications until the app is manually opened" * "Exact alarm permission is required on Android 12+ for precise timing" **iOS**: * "Notifications have ±180 seconds timing tolerance" * "App code does not run when notifications fire (unless user interacts)" * "Background execution is system-controlled and not guaranteed" **Cross-Platform**: * "Missed alarms are detected on app launch, not at trigger time" * "Repeating alarms must be rescheduled for each occurrence" --- ### 4.3 API Error Handling The plugin **must**: * Return clear error messages * Include error codes for programmatic handling * Open system settings when permission is needed * Provide actionable guidance in error messages **Example Error Response**: ```typescript { code: "EXACT_ALARM_PERMISSION_REQUIRED", message: "Exact alarm permission required. Please grant 'Alarms & reminders' permission in Settings, then try again.", action: "opened_settings" // or "permission_denied" } ``` --- ## 5. Platform-Specific Requirements ### 5.1 Android Requirements #### 5.1.1 Permissions **Required Permissions**: * `RECEIVE_BOOT_COMPLETED` - Boot receiver * `SCHEDULE_EXACT_ALARM` - Android 12+ (API 31+) for exact alarms * `POST_NOTIFICATIONS` - Android 13+ (API 33+) for notifications **Permission Handling**: * Check permission before scheduling * Request permission if not granted * Open system settings if permission denied * Provide clear error messages **Code Reference**: `DailyNotificationPlugin.kt` line 1309 --- #### 5.1.2 Manifest Entries **Required Manifest Entries**: ```xml ``` **Location**: Test app manifest: `test-apps/android-test-app/app/src/main/AndroidManifest.xml` --- #### 5.1.3 Notification Channels **Required Channels**: * `timesafari.daily` - Primary notification channel * `daily_reminders` - Reminder notifications (if used) **Channel Configuration**: * Importance: HIGH (for alarms), DEFAULT (for reminders) * Sound: Enabled by default * Vibration: Enabled by default * Show badge: Enabled **Code Reference**: `ChannelManager.java` or `NotifyReceiver.kt` line 454 --- #### 5.1.4 Alarm Scheduling **Required API Usage**: * `setAlarmClock()` for Android 5.0+ (preferred) * `setExactAndAllowWhileIdle()` for Android 6.0+ (fallback) * `setExact()` for older versions (fallback) **Code Reference**: `NotifyReceiver.kt` line 219, 223, 231 --- ### 5.2 iOS Requirements #### 5.2.1 Permissions **Required Permissions**: * Notification authorization (requested at runtime) **Permission Handling**: * Request permission before scheduling * Handle authorization status * Provide clear error messages --- #### 5.2.2 Background Tasks **Required Background Task Identifiers**: * `com.timesafari.dailynotification.fetch` - Background fetch * `com.timesafari.dailynotification.notify` - Notification task (if used) **Background Task Registration**: * Register in `Info.plist`: ```xml BGTaskSchedulerPermittedIdentifiers com.timesafari.dailynotification.fetch ``` **Code Reference**: `DailyNotificationPlugin.swift` line 31-32 --- #### 5.2.3 Notification Scheduling **Required API Usage**: * `UNUserNotificationCenter.add()` - Schedule notifications * `UNCalendarNotificationTrigger` - Calendar-based triggers (preferred) * `UNTimeIntervalNotificationTrigger` - Time interval triggers **Code Reference**: `DailyNotificationScheduler.swift` line 185 --- #### 5.2.4 Notification Categories **Required Categories**: * `DAILY_NOTIFICATION` - Primary notification category **Category Configuration**: * Actions: Configure as needed * Options: Custom sound, custom actions **Code Reference**: `DailyNotificationScheduler.swift` line 62+ --- ## 6. Testing Requirements ### 6.1 Required Test Scenarios The plugin **must** be tested for: **Android**: * [ ] Base case (alarm fires on time) * [ ] Swipe from recents * [ ] OS kill (memory pressure) * [ ] Device reboot (with and without app launch) * [ ] Force stop (with app restart) * [ ] Exact alarm permission (Android 12+) * [ ] Boot receiver functionality * [ ] Missed alarm detection **iOS**: * [ ] Base case (notification fires on time) * [ ] Swipe app away * [ ] Device reboot (without app launch) * [ ] Hard termination and relaunch * [ ] Background execution limits * [ ] Missed notification detection **Cross-Platform**: * [ ] Timezone changes * [ ] Clock adjustments * [ ] Multiple simultaneous alarms * [ ] Repeating alarms * [ ] Alarm cancellation --- ### 6.2 Test Harness Requirements **Required Test Tools**: * Real devices (not just emulators) * ADB commands for Android testing * Xcode for iOS testing * Log monitoring tools **Required Test Documentation**: * Test results matrix * Log snippets for failures * Screenshots/videos for UI issues * Performance metrics --- ## 7. Versioning Requirements ### 7.1 Breaking Changes Any change to alarm behavior is **breaking** and requires: * **MAJOR version bump** (semantic versioning) * **Migration guide** for existing users * **Deprecation warnings** (if applicable) * **Clear changelog entry** ### 7.2 Non-Breaking Changes Non-breaking changes include: * Bug fixes * Performance improvements * Additional features (backward compatible) * Documentation updates --- ## 8. Implementation Checklist ### 8.1 Android Implementation - [ ] Boot receiver registered in manifest - [ ] Boot receiver reschedules alarms from database - [ ] Exact alarm permission checked and requested - [ ] Notification channels created - [ ] Alarm scheduling uses correct API (`setAlarmClock` preferred) - [ ] Persistence implemented (Room database) - [ ] Missed alarm detection on app launch - [ ] Force stop recovery on app restart - [ ] Error handling and user guidance ### 8.2 iOS Implementation - [ ] Notification authorization requested - [ ] Background tasks registered in Info.plist - [ ] Notification scheduling uses UNUserNotificationCenter - [ ] Calendar triggers used (not just time interval) - [ ] Plugin-side persistence (if needed for missed detection) - [ ] Missed notification detection on app launch - [ ] Background task limitations documented - [ ] Error handling and user guidance ### 8.3 Cross-Platform Implementation - [ ] JS/TS API contract documented - [ ] Platform-specific caveats documented - [ ] Error codes standardized - [ ] Test scenarios covered - [ ] Migration guide (if breaking changes) --- ## 9. Open Questions / TODOs **To be filled after exploration**: | Question | Platform | Priority | Status | | -------- | -------- | -------- | ------ | | Does boot receiver work correctly? | Android | High | ☐ | | Is missed alarm detection implemented? | Both | High | ☐ | | Are all required fields persisted? | Both | Medium | ☐ | | Is force stop recovery implemented? | Android | High | ☐ | | Does iOS plugin persist state separately? | iOS | Medium | ☐ | --- ## Related Documentation - [Platform Capability Reference](./platform-capability-reference.md) - OS-level facts - [Plugin Behavior Exploration Template](./plugin-behavior-exploration-template.md) - Exploration template - [Improve Alarm Directives](./improve-alarm-directives.md) - Improvement directive - [Boot Receiver Testing Guide](./boot-receiver-testing-guide.md) - Testing procedures - [App Startup Recovery Solution](./app-startup-recovery-solution.md) - Recovery mechanisms --- ## Version History - **v1.0** (November 2025): Initial requirements document - Persistence requirements - Recovery requirements - JS/TS API contract - Platform-specific requirements - Testing requirements