docs: Consolidate documentation structure (139 files, zero information loss)

Consolidate all markdown documentation into organized structure per
CONSOLIDATION_DIRECTIVE. All files preserved (canonical, merged, or archived).

- docs/integration/ - Integration documentation (7 files)
- docs/platform/ios/ - iOS platform docs (12 files)
- docs/platform/android/ - Android platform docs (9 files)
- docs/testing/ - Testing documentation (15 files)
- docs/design/ - Design & research (5 files)
- docs/ai/ - AI/ChatGPT artifacts (7 files)
- docs/archive/2025-legacy-doc/ - Historical docs (17 files)

- Integration: Root INTEGRATION_GUIDE.md → docs/integration/
- Platform: Separated iOS and Android into platform/ subdirectories
- Testing: Consolidated all testing docs to docs/testing/
- Legacy: Archived entire doc/ directory to archive/
- AI: Moved all ChatGPT artifacts to docs/ai/

- Added docs/00-INDEX.md - Central navigation hub
- Added docs/CONSOLIDATION_SOURCE_MAP.md - Complete audit trail
- Added docs/CONSOLIDATION_COMPLETE.md - Consolidation summary
- Updated README.md with links to documentation index

- All 139 files have destinations (see CONSOLIDATION_SOURCE_MAP.md)
- Zero information loss (all files preserved)
- Archive preserves original structure
- Index provides clear navigation

- 87 files moved/created/updated
- Root-level docs consolidated
- Legacy doc/ directory archived
- Test app docs remain with test apps (indexed)

Ref: CONSOLIDATION_DIRECTIVE
Author: Matthew Raymer
This commit is contained in:
Matthew Raymer
2025-12-18 09:12:11 +00:00
parent 37fd2629d1
commit c39bd7cec6
78 changed files with 720 additions and 18 deletions

View File

@@ -0,0 +1,423 @@
# iOS Recovery Scenario Mapping: Android → iOS Equivalents
**Author**: Matthew Raymer
**Date**: 2025-12-08
**Status**: 🎯 **ACTIVE** - Recovery Scenario Mapping Reference
**Version**: 1.0.0
**Last Synced With Plugin Version**: v1.1.0
## Purpose
This document maps Android recovery scenarios to their iOS equivalents, providing a clear translation guide for implementing iOS recovery logic based on Android patterns.
**Reference**:
- [Android Implementation Directive](./android-implementation-directive.md) - Android scenarios
- [iOS Implementation Directive](./ios-implementation-directive.md) - iOS scenarios
- [Platform Capability Reference](./alarms/01-platform-capability-reference.md) - OS-level facts
---
## 1. Scenario Mapping Overview
### 1.1 Direct Mappings
| Android Scenario | iOS Equivalent | Detection Method | Recovery Action |
| ---------------- | -------------- | ---------------- | --------------- |
| `COLD_START` | App Launch After Termination | Compare UNUserNotificationCenter vs DB | Detect missed, verify future |
| `FORCE_STOP` | App Terminated by System | DB has schedules, no notifications | Full recovery of all schedules |
| `BOOT` | Device Reboot | BGTaskScheduler registration | Reschedule all notifications |
| `WARM_START` | App Resume (Foreground) | Notifications match DB state | No recovery needed (optimization) |
| `NONE` | First Launch / No Recovery | Empty database | No action needed |
### 1.2 Key Differences
**iOS Advantages**:
- ✅ Notifications persist across termination (OS-guaranteed)
- ✅ Notifications persist across reboot (OS-guaranteed)
- ❌ No user-facing "force stop" equivalent
**iOS Challenges**:
- ❌ App code does NOT run when notification fires
- ❌ Must detect missed notifications on app launch
- ❌ Background execution severely limited
---
## 2. Detailed Scenario Mappings
### 2.1 COLD_START → App Launch After Termination
**Android Definition**:
- Process killed, alarms may or may not exist
- Database still populated
- Alarms may have been cleared by OS
**iOS Equivalent**:
- App terminated by system or user
- Notifications may still exist (OS-guaranteed persistence)
- Database still populated
- Need to verify notification state matches database
**Detection Logic**:
**Android**:
```kotlin
// Check if alarms exist in AlarmManager
val alarmsExist = alarmManager.hasAlarm(pendingIntent)
if (alarmsExist && dbHasSchedules) {
return COLD_START
}
```
**iOS**:
```swift
// Check if notifications exist in UNUserNotificationCenter
let pendingNotifications = try await notificationCenter.pendingNotificationRequests()
let dbSchedules = try database.getEnabledSchedules()
if !pendingNotifications.isEmpty && !dbSchedules.isEmpty {
// Compare notification IDs with DB state
let dbIds = Set(dbSchedules.flatMap { $0.getScheduledNotificationIds() })
let pendingIds = Set(pendingNotifications.map { $0.identifier })
if dbIds != pendingIds {
return .coldStart // Mismatch indicates recovery needed
}
}
```
**Recovery Actions**:
1. Detect missed notifications (scheduled_time < now, not delivered)
2. Mark missed notifications in database
3. Verify future notifications are scheduled
4. Reschedule missing future notifications
**Platform Reference**: [iOS §3.1.1](./alarms/01-platform-capability-reference.md#311-notifications-survive-app-termination)
---
### 2.2 FORCE_STOP → App Terminated by System
**Android Definition**:
- User force-stopped app via Settings
- All alarms cleared
- Database still populated
- Boot receiver blocked until user launches app
**iOS Equivalent**:
- App terminated by system (low memory, etc.)
- Notifications may be missing (system cleared them)
- Database still populated
- No user-facing force stop equivalent
**Key Difference**: iOS doesn't have a user-facing "force stop" option. System termination is the closest equivalent.
**Detection Logic**:
**Android**:
```kotlin
// Check if alarms exist
val alarmsExist = alarmManager.hasAlarm(pendingIntent)
if (!alarmsExist && dbHasSchedules && !isBootRecent) {
return FORCE_STOP
}
```
**iOS**:
```swift
// Check if notifications exist
let pendingNotifications = try await notificationCenter.pendingNotificationRequests()
let dbSchedules = try database.getEnabledSchedules()
if pendingNotifications.isEmpty && !dbSchedules.isEmpty {
// DB has schedules but no notifications scheduled
return .termination
}
```
**Recovery Actions**:
1. Detect all missed notifications
2. Mark all missed notifications in database
3. Reschedule all future notifications
4. Reschedule all fetch schedules (if applicable)
**Platform Reference**: [iOS §3.2.1](./alarms/01-platform-capability-reference.md#321-app-code-does-not-run-when-notification-fires)
---
### 2.3 BOOT → Device Reboot
**Android Definition**:
- Device rebooted
- All alarms wiped (OS behavior)
- Database still populated
- Boot receiver executes after boot completes
**iOS Equivalent**:
- Device rebooted
- Notifications persist automatically (OS-guaranteed)
- Database still populated
- BGTaskScheduler may execute (system-controlled)
**Key Difference**: iOS automatically persists notifications across reboot. Android requires manual rescheduling.
**Detection Logic**:
**Android**:
```kotlin
// Check boot flag (set by BootReceiver)
val bootFlag = sharedPreferences.getLong("last_boot_time", 0)
val currentTime = System.currentTimeMillis()
if (bootFlag > 0 && (currentTime - bootFlag) < 60000) {
return BOOT
}
```
**iOS**:
```swift
// BGTaskScheduler registration handles boot
// Check if this is a boot-triggered background task
if isBootBackgroundTask {
return .boot
}
// Or detect on app launch after reboot
let lastLaunchTime = UserDefaults.standard.double(forKey: "last_launch_time")
let bootTime = ProcessInfo.processInfo.systemUptime
if lastLaunchTime > 0 && bootTime < 60 {
return .boot
}
```
**Recovery Actions**:
1. Verify notifications still exist (iOS usually handles this)
2. Detect any missed notifications during reboot window
3. Reschedule any missing notifications
4. Update next run times for repeating schedules
**Platform Reference**: [iOS §3.1.2](./alarms/01-platform-capability-reference.md#312-notifications-persist-across-device-reboot)
---
### 2.4 WARM_START → App Resume (Foreground)
**Android Definition**:
- App resumed from background
- Alarms still exist
- Database matches alarm state
- No recovery needed (optimization)
**iOS Equivalent**:
- App resumed from background
- Notifications still exist
- Database matches notification state
- No recovery needed (optimization)
**Detection Logic**:
**Android**:
```kotlin
// Check if alarms exist and match DB
val alarmsExist = alarmManager.hasAlarm(pendingIntent)
if (alarmsExist && dbMatchesAlarms) {
return WARM_START
}
```
**iOS**:
```swift
// Check if notifications exist and match DB
let pendingNotifications = try await notificationCenter.pendingNotificationRequests()
let dbSchedules = try database.getEnabledSchedules()
let dbIds = Set(dbSchedules.flatMap { $0.getScheduledNotificationIds() })
let pendingIds = Set(pendingNotifications.map { $0.identifier })
if dbIds == pendingIds {
return .warmStart // Match indicates warm resume
}
```
**Recovery Actions**:
- None (optimization only)
- May perform lightweight verification
- May update metrics
---
### 2.5 NONE → First Launch / No Recovery
**Android Definition**:
- First app launch
- Empty database
- No schedules configured
- No recovery needed
**iOS Equivalent**:
- First app launch
- Empty database
- No schedules configured
- No recovery needed
**Detection Logic**:
**Android**:
```kotlin
// Check if database is empty
val schedules = database.scheduleDao().getEnabled()
if (schedules.isEmpty()) {
return NONE
}
```
**iOS**:
```swift
// Check if database is empty
let schedules = try database.getEnabledSchedules()
if schedules.isEmpty {
return .none
}
```
**Recovery Actions**:
- None
---
## 3. Recovery Action Mapping
### 3.1 Missed Notification Detection
**Android**:
- Query AlarmManager for past alarms
- Check database for undelivered notifications
- Mark as missed in database
**iOS**:
- Query database for past scheduled notifications
- Check delivery status
- Mark as missed in database
**Key Difference**: iOS cannot query past notifications from UNUserNotificationCenter. Must rely on database state.
### 3.2 Future Notification Verification
**Android**:
- Query AlarmManager for future alarms
- Compare with database schedules
- Reschedule missing alarms
**iOS**:
- Query UNUserNotificationCenter for pending notifications
- Compare with database schedules
- Reschedule missing notifications
**Key Difference**: iOS uses UNUserNotificationCenter instead of AlarmManager.
### 3.3 Full Recovery
**Android**:
- Reschedule all notify schedules
- Reschedule all fetch schedules (WorkManager)
- Mark past notifications as missed
**iOS**:
- Reschedule all notify schedules
- Reschedule all fetch schedules (BGTaskScheduler)
- Mark past notifications as missed
**Key Difference**: iOS uses BGTaskScheduler instead of WorkManager.
---
## 4. Implementation Checklist
### 4.1 Phase 1: Cold Start Recovery
- [ ] Implement scenario detection (cold start)
- [ ] Implement missed notification detection
- [ ] Implement future notification verification
- [ ] Test cold start recovery
### 4.2 Phase 2: Termination Detection
- [ ] Implement termination detection
- [ ] Implement full recovery logic
- [ ] Test termination recovery
### 4.3 Phase 3: Boot Recovery
- [ ] Implement BGTaskScheduler registration
- [ ] Implement boot detection
- [ ] Test boot recovery
---
## 5. Platform-Specific Notes
### 5.1 iOS Advantages
1. **Notification Persistence**: iOS automatically persists notifications across termination and reboot
2. **No Force Stop**: iOS doesn't have user-facing force stop, reducing complexity
3. **Simplified Recovery**: Less recovery needed due to OS persistence
### 5.2 iOS Challenges
1. **No Code Execution on Fire**: App code doesn't run when notification fires
2. **Background Limits**: Severely limited background execution
3. **Timing Tolerance**: ±180 second tolerance for calendar triggers
### 5.3 Android Advantages
1. **Code Execution on Fire**: PendingIntent can execute code when alarm fires
2. **WorkManager**: More reliable background execution
3. **Exact Timing**: Can achieve exact timing with permission
### 5.4 Android Challenges
1. **No Persistence**: Alarms don't persist across reboot
2. **Force Stop**: Hard kill that cannot be bypassed
3. **Boot Recovery**: Must implement boot receiver
---
## 6. Testing Strategy
### 6.1 Scenario Testing
**Cold Start**:
1. Terminate app (swipe away)
2. Wait for notification time to pass
3. Launch app
4. Verify missed notification detection
5. Verify future notifications rescheduled
**Termination**:
1. Schedule notifications
2. Terminate app
3. Clear notifications (simulate system clearing)
4. Launch app
5. Verify full recovery
**Boot**:
1. Schedule notifications
2. Reboot device (or simulate)
3. Launch app
4. Verify notifications still exist
5. Verify any missed notifications detected
---
## 7. References
- [Android Implementation Directive](./android-implementation-directive.md) - Android scenarios
- [iOS Implementation Directive](./ios-implementation-directive.md) - iOS scenarios
- [Platform Capability Reference](./alarms/01-platform-capability-reference.md) - OS-level facts
- [Plugin Requirements](./alarms/03-plugin-requirements.md) - Requirements
---
**Document Version**: 1.0.0
**Last Updated**: 2025-12-08
**Next Review**: After Phase 1 implementation