# 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