Add integration guides and update API documentation with new Android diagnostic methods. Emphasize critical NotifyReceiver registration requirement that was causing notification delivery failures. Documentation Updates: - API.md: Document isAlarmScheduled(), getNextAlarmTime(), testAlarm() - README.md: Add Quick Integration section and Android diagnostic methods - notification-testing-procedures.md: Add BroadcastReceiver troubleshooting New Integration Guides: - QUICK_INTEGRATION.md: Step-by-step guide for human developers - AI_INTEGRATION_GUIDE.md: Machine-readable guide with verification steps - TODO.md: Task tracking for pending improvements Key Improvements: - Explicit NotifyReceiver registration requirement highlighted - Complete troubleshooting flow for BroadcastReceiver issues - Diagnostic method examples for debugging alarm scheduling - AI-friendly integration instructions with verification commands Fixes notification delivery issues caused by missing NotifyReceiver registration in host app AndroidManifest.xml files.
394 lines
10 KiB
Markdown
394 lines
10 KiB
Markdown
# TimeSafari Daily Notification Plugin API Reference
|
|
|
|
**Author**: Matthew Raymer
|
|
**Version**: 2.2.0
|
|
**Last Updated**: 2025-11-06 09:51:00 UTC
|
|
|
|
## Overview
|
|
|
|
This API reference provides comprehensive documentation for the TimeSafari Daily Notification Plugin, optimized for **native-first architecture** supporting Android, iOS, and Electron platforms.
|
|
|
|
### Platform Support
|
|
- ✅ **Android**: WorkManager + AlarmManager + SQLite
|
|
- ✅ **iOS**: BGTaskScheduler + UNUserNotificationCenter + Core Data
|
|
- ✅ **Electron**: Desktop notifications + SQLite/LocalStorage
|
|
- ❌ **Web (PWA)**: Removed for native-first focus
|
|
|
|
## DailyNotificationPlugin Interface
|
|
|
|
### Configuration
|
|
|
|
#### `configure(options: ConfigureOptions): Promise<void>`
|
|
|
|
Configure the plugin with storage, TTL, and optimization settings.
|
|
|
|
**Parameters:**
|
|
|
|
- `options.storage`: `'shared'` | `'tiered'` - Storage mode
|
|
- `options.ttlSeconds`: `number` - TTL in seconds (default: 1800)
|
|
- `options.prefetchLeadMinutes`: `number` - Prefetch lead time (default: 15)
|
|
- `options.enableETagSupport`: `boolean` - Enable ETag conditional requests
|
|
- `options.enableErrorHandling`: `boolean` - Enable advanced error handling
|
|
- `options.enablePerformanceOptimization`: `boolean` - Enable performance optimization
|
|
|
|
### Core Methods
|
|
|
|
#### `scheduleDailyNotification(options: NotificationOptions): Promise<void>`
|
|
|
|
Schedule a daily notification with content fetching.
|
|
|
|
**Parameters:**
|
|
|
|
- `options.url`: `string` - Content endpoint URL
|
|
- `options.time`: `string` - Time in HH:MM format
|
|
- `options.title`: `string` - Notification title
|
|
- `options.body`: `string` - Notification body
|
|
- `options.sound`: `boolean` - Enable sound (optional)
|
|
- `options.retryConfig`: `RetryConfiguration` - Custom retry settings (optional)
|
|
|
|
#### `getLastNotification(): Promise<NotificationResponse | null>`
|
|
|
|
Get the last scheduled notification.
|
|
|
|
#### `cancelAllNotifications(): Promise<void>`
|
|
|
|
Cancel all scheduled notifications.
|
|
|
|
### Platform-Specific Methods
|
|
|
|
#### Android Only
|
|
|
|
##### `getExactAlarmStatus(): Promise<ExactAlarmStatus>`
|
|
|
|
Get exact alarm permission and capability status.
|
|
|
|
##### `requestExactAlarmPermission(): Promise<void>`
|
|
|
|
Request exact alarm permission from user.
|
|
|
|
##### `openExactAlarmSettings(): Promise<void>`
|
|
|
|
Open exact alarm settings in system preferences.
|
|
|
|
##### `getRebootRecoveryStatus(): Promise<RecoveryStatus>`
|
|
|
|
Get reboot recovery status and statistics.
|
|
|
|
##### `isAlarmScheduled(options: { triggerAtMillis: number }): Promise<{ scheduled: boolean; triggerAtMillis: number }>`
|
|
|
|
Check if an alarm is scheduled for a specific trigger time. Useful for debugging and verification.
|
|
|
|
**Parameters:**
|
|
- `options.triggerAtMillis`: `number` - The trigger time in milliseconds (Unix timestamp)
|
|
|
|
**Returns:**
|
|
- `scheduled`: `boolean` - Whether the alarm is currently scheduled
|
|
- `triggerAtMillis`: `number` - The trigger time that was checked
|
|
|
|
**Example:**
|
|
```typescript
|
|
const result = await DailyNotification.isAlarmScheduled({
|
|
triggerAtMillis: 1762421400000
|
|
});
|
|
console.log(`Alarm scheduled: ${result.scheduled}`);
|
|
```
|
|
|
|
##### `getNextAlarmTime(): Promise<{ scheduled: boolean; triggerAtMillis?: number }>`
|
|
|
|
Get the next scheduled alarm time from AlarmManager. Requires Android 5.0+ (API 21+).
|
|
|
|
**Returns:**
|
|
- `scheduled`: `boolean` - Whether any alarm is scheduled
|
|
- `triggerAtMillis`: `number | undefined` - The next alarm trigger time (if scheduled)
|
|
|
|
**Example:**
|
|
```typescript
|
|
const result = await DailyNotification.getNextAlarmTime();
|
|
if (result.scheduled) {
|
|
const nextAlarm = new Date(result.triggerAtMillis);
|
|
console.log(`Next alarm: ${nextAlarm.toLocaleString()}`);
|
|
}
|
|
```
|
|
|
|
##### `testAlarm(options?: { secondsFromNow?: number }): Promise<{ scheduled: boolean; secondsFromNow: number; triggerAtMillis: number }>`
|
|
|
|
Schedule a test alarm that fires in a few seconds. Useful for verifying alarm delivery works correctly.
|
|
|
|
**Parameters:**
|
|
- `options.secondsFromNow`: `number` (optional) - Seconds from now to fire the alarm (default: 5)
|
|
|
|
**Returns:**
|
|
- `scheduled`: `boolean` - Whether the alarm was scheduled successfully
|
|
- `secondsFromNow`: `number` - The delay used
|
|
- `triggerAtMillis`: `number` - The trigger time in milliseconds
|
|
|
|
**Example:**
|
|
```typescript
|
|
const result = await DailyNotification.testAlarm({ secondsFromNow: 10 });
|
|
console.log(`Test alarm scheduled for ${result.secondsFromNow} seconds`);
|
|
```
|
|
|
|
### Management Methods
|
|
|
|
#### `maintainRollingWindow(): Promise<void>`
|
|
|
|
Manually trigger rolling window maintenance.
|
|
|
|
#### `getRollingWindowStats(): Promise<RollingWindowStats>`
|
|
|
|
Get rolling window statistics and status.
|
|
|
|
### Optimization Methods
|
|
|
|
#### `optimizeDatabase(): Promise<void>`
|
|
|
|
Optimize database performance with indexes and settings.
|
|
|
|
#### `optimizeMemory(): Promise<void>`
|
|
|
|
Optimize memory usage and perform cleanup.
|
|
|
|
#### `optimizeBattery(): Promise<void>`
|
|
|
|
Optimize battery usage and background CPU.
|
|
|
|
### Metrics and Monitoring
|
|
|
|
#### `getPerformanceMetrics(): Promise<PerformanceMetrics>`
|
|
|
|
Get comprehensive performance metrics.
|
|
|
|
#### `getErrorMetrics(): Promise<ErrorMetrics>`
|
|
|
|
Get error handling metrics and statistics.
|
|
|
|
#### `getNetworkMetrics(): Promise<NetworkMetrics>`
|
|
|
|
Get network efficiency metrics (ETag support).
|
|
|
|
#### `getMemoryMetrics(): Promise<MemoryMetrics>`
|
|
|
|
Get memory usage metrics and statistics.
|
|
|
|
#### `getObjectPoolMetrics(): Promise<ObjectPoolMetrics>`
|
|
|
|
Get object pooling efficiency metrics.
|
|
|
|
### Utility Methods
|
|
|
|
#### `resetPerformanceMetrics(): Promise<void>`
|
|
|
|
Reset all performance metrics to zero.
|
|
|
|
#### `resetErrorMetrics(): Promise<void>`
|
|
|
|
Reset error handling metrics.
|
|
|
|
#### `clearRetryStates(): Promise<void>`
|
|
|
|
Clear all retry states and operations.
|
|
|
|
#### `cleanExpiredETags(): Promise<void>`
|
|
|
|
Clean expired ETag cache entries.
|
|
|
|
## Data Types
|
|
|
|
### ConfigureOptions
|
|
|
|
```typescript
|
|
interface ConfigureOptions {
|
|
storage?: 'shared' | 'tiered';
|
|
ttlSeconds?: number;
|
|
prefetchLeadMinutes?: number;
|
|
enableETagSupport?: boolean;
|
|
enableErrorHandling?: boolean;
|
|
enablePerformanceOptimization?: boolean;
|
|
maxRetries?: number;
|
|
baseRetryDelay?: number;
|
|
maxRetryDelay?: number;
|
|
backoffMultiplier?: number;
|
|
memoryWarningThreshold?: number;
|
|
memoryCriticalThreshold?: number;
|
|
objectPoolSize?: number;
|
|
maxObjectPoolSize?: number;
|
|
}
|
|
```
|
|
|
|
### NotificationOptions
|
|
|
|
```typescript
|
|
interface NotificationOptions {
|
|
url: string;
|
|
time: string;
|
|
title: string;
|
|
body: string;
|
|
sound?: boolean;
|
|
retryConfig?: RetryConfiguration;
|
|
}
|
|
```
|
|
|
|
### ExactAlarmStatus (Android)
|
|
|
|
```typescript
|
|
interface ExactAlarmStatus {
|
|
supported: boolean;
|
|
enabled: boolean;
|
|
canSchedule: boolean;
|
|
fallbackWindow: string;
|
|
}
|
|
```
|
|
|
|
### PerformanceMetrics
|
|
|
|
```typescript
|
|
interface PerformanceMetrics {
|
|
overallScore: number;
|
|
databasePerformance: number;
|
|
memoryEfficiency: number;
|
|
batteryEfficiency: number;
|
|
objectPoolEfficiency: number;
|
|
totalDatabaseQueries: number;
|
|
averageMemoryUsage: number;
|
|
objectPoolHits: number;
|
|
backgroundCpuUsage: number;
|
|
totalNetworkRequests: number;
|
|
recommendations: string[];
|
|
}
|
|
```
|
|
|
|
### ErrorMetrics
|
|
|
|
```typescript
|
|
interface ErrorMetrics {
|
|
totalErrors: number;
|
|
networkErrors: number;
|
|
storageErrors: number;
|
|
schedulingErrors: number;
|
|
permissionErrors: number;
|
|
configurationErrors: number;
|
|
systemErrors: number;
|
|
unknownErrors: number;
|
|
cacheHitRatio: number;
|
|
}
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
All methods return promises that reject with descriptive error messages. The plugin includes comprehensive error categorization and retry logic.
|
|
|
|
### Common Error Types
|
|
|
|
- **Network Errors**: Connection timeouts, DNS failures
|
|
- **Storage Errors**: Database corruption, disk full
|
|
- **Permission Errors**: Missing exact alarm permission
|
|
- **Configuration Errors**: Invalid parameters, unsupported settings
|
|
- **System Errors**: Out of memory, platform limitations
|
|
|
|
## Platform Differences
|
|
|
|
### Android
|
|
|
|
- Requires `SCHEDULE_EXACT_ALARM` permission for precise timing
|
|
- Falls back to windowed alarms (±10m) if exact permission denied
|
|
- Supports reboot recovery with broadcast receivers
|
|
- Full performance optimization features
|
|
|
|
### iOS
|
|
|
|
- Uses `BGTaskScheduler` for background prefetch
|
|
- Limited to 64 pending notifications
|
|
- Automatic background task management
|
|
- Battery optimization built-in
|
|
|
|
### Electron
|
|
|
|
- Desktop notification support
|
|
- SQLite or LocalStorage fallback
|
|
- Native desktop notification APIs
|
|
- Cross-platform desktop compatibility
|
|
|
|
## TimeSafari-Specific Integration Examples
|
|
|
|
### Basic TimeSafari Integration
|
|
|
|
```typescript
|
|
import { DailyNotification } from '@timesafari/daily-notification-plugin';
|
|
import { TimeSafariIntegrationService } from '@timesafari/daily-notification-plugin';
|
|
|
|
// Initialize TimeSafari integration
|
|
const integrationService = TimeSafariIntegrationService.getInstance();
|
|
|
|
// Configure with TimeSafari-specific settings
|
|
await integrationService.initialize({
|
|
activeDid: 'did:example:timesafari-user-123',
|
|
storageAdapter: timeSafariStorageAdapter,
|
|
endorserApiBaseUrl: 'https://endorser.ch/api/v1'
|
|
});
|
|
|
|
// Schedule TimeSafari community notifications
|
|
await DailyNotification.scheduleDailyNotification({
|
|
title: 'New Community Update',
|
|
body: 'You have new offers and project updates',
|
|
time: '09:00',
|
|
channel: 'timesafari_community_updates'
|
|
});
|
|
```
|
|
|
|
### TimeSafari Community Features
|
|
|
|
```typescript
|
|
// Fetch community data with rate limiting
|
|
const communityService = new TimeSafariCommunityIntegrationService();
|
|
|
|
await communityService.initialize({
|
|
maxRequestsPerMinute: 30,
|
|
maxRequestsPerHour: 1000,
|
|
basePollingIntervalMs: 300000, // 5 minutes
|
|
adaptivePolling: true
|
|
});
|
|
|
|
// Fetch community data
|
|
const bundle = await communityService.fetchCommunityDataWithRateLimit({
|
|
activeDid: 'did:example:timesafari-user-123',
|
|
fetchOffersToPerson: true,
|
|
fetchOffersToProjects: true,
|
|
fetchProjectUpdates: true,
|
|
starredPlanIds: ['plan-1', 'plan-2', 'plan-3']
|
|
});
|
|
```
|
|
|
|
### DID-Signed Payloads
|
|
|
|
```typescript
|
|
// Generate DID-signed notification payloads
|
|
const samplePayloads = integrationService.generateSampleDidPayloads();
|
|
|
|
for (const payload of samplePayloads) {
|
|
// Verify signature
|
|
const isValid = await integrationService.verifyDidSignature(
|
|
JSON.stringify(payload.payload),
|
|
payload.signature
|
|
);
|
|
|
|
console.log(`Payload ${payload.type} signature valid: ${isValid}`);
|
|
}
|
|
```
|
|
|
|
### Privacy-Preserving Storage
|
|
|
|
```typescript
|
|
// Configure privacy-preserving storage
|
|
const storageAdapter = new TimeSafariStorageAdapterImpl(
|
|
nativeStorage,
|
|
'timesafari_notifications'
|
|
);
|
|
|
|
// Store with TTL and redaction
|
|
await storageAdapter.store('community_data', bundle, 3600); // 1 hour TTL
|
|
|
|
// Get data retention policy
|
|
const policy = integrationService.getDataRetentionPolicy();
|
|
console.log('Data retention policy:', policy);
|
|
```
|