- Add platform capability reference (Android & iOS OS-level facts) - Add plugin behavior exploration template (executable test matrices) - Add plugin requirements & implementation directive - Add Android-specific implementation directive with detailed test procedures - Add exploration findings from code inspection - Add improvement directive for refining documentation structure - Add Android alarm persistence directive (OS capabilities) All documents include: - File locations, function references, and line numbers - Detailed test procedures with ADB commands - Cross-platform comparisons - Implementation checklists and code examples
553 lines
16 KiB
Markdown
553 lines
16 KiB
Markdown
# 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
|
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
|
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
|
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
|
|
|
<receiver
|
|
android:name="com.timesafari.dailynotification.BootReceiver"
|
|
android:enabled="true"
|
|
android:exported="true">
|
|
<intent-filter>
|
|
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
|
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
|
|
</intent-filter>
|
|
</receiver>
|
|
|
|
<receiver
|
|
android:name="com.timesafari.dailynotification.DailyNotificationReceiver"
|
|
android:enabled="true"
|
|
android:exported="false">
|
|
<intent-filter>
|
|
<action android:name="com.timesafari.daily.NOTIFICATION" />
|
|
</intent-filter>
|
|
</receiver>
|
|
```
|
|
|
|
**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
|
|
<key>BGTaskSchedulerPermittedIdentifiers</key>
|
|
<array>
|
|
<string>com.timesafari.dailynotification.fetch</string>
|
|
</array>
|
|
```
|
|
|
|
**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
|
|
|