17 KiB
Daily Notification Plugin - Implementation Roadmap
📝 SANITY CHECK IMPROVEMENTS APPLIED: This document has been updated to clarify current implementation status and distinguish between existing infrastructure and planned T–lead logic.
Status: Ready for implementation
Date: 2025-01-27
Author: Matthew Raymer
Assessment Date: 2025-01-27
Executive Summary
This document outlines the implementation roadmap to bring the current Daily Notification Plugin (65% complete) to full compliance with the Native-First Notification System specification. The implementation is organized into three phases, with Phase 1 containing critical infrastructure components required for core functionality.
Current State Assessment
- Overall Completion: 65% of specification requirements
- Critical Gaps: SQLite database sharing, TTL-at-fire enforcement, rolling window safety
- Current Storage: SharedPreferences (Android) / UserDefaults (iOS) + in-memory cache
- Background Infrastructure: Basic WorkManager (Android) exists, but lacks T–lead logic
- Critical Path: Data persistence → Freshness enforcement → Platform completion
Current Implementation Status Clarification
Background Fetch Infrastructure
Current State: Basic infrastructure exists but lacks T–lead logic
- Android:
DailyNotificationFetchWorker.java
(WorkManager) exists - Android:
DailyNotificationFetcher.java
with scheduling logic exists - Missing: T–lead calculation, TTL enforcement, ETag support
- Status: Infrastructure ready, T–lead logic needs implementation
iOS Implementation Status
Current State: Basic plugin structure with power management
- Implemented: Plugin skeleton, power management, UserDefaults storage
- Missing: BGTaskScheduler, background tasks, T–lead prefetch
- Status: Foundation exists, background execution needs implementation
Gate: No further freshness or scheduling work merges to main until shared SQLite (see Glossary → Shared DB) is in place and reading/writing under WAL (see Glossary → WAL), with UI hot-read verified.
Dependencies: None
1.1 SQLite Database Sharing Implementation
Priority: CRITICAL
Requirements
- Migrate from SharedPreferences/UserDefaults to shared SQLite database (see Glossary → Shared DB)
- WAL mode configuration for concurrent access (see Glossary → WAL)
- Schema version checking and compatibility validation (see Glossary → PRAGMA user_version)
- Required tables:
notif_contents
,notif_deliveries
,notif_config
- Migration Strategy: Gradual migration from current tiered storage (see Glossary → Tiered Storage)
Implementation Tasks
-
Migration from Current Storage
- Create migration utilities from SharedPreferences to SQLite
- Implement data migration from UserDefaults to SQLite (iOS)
- Add backward compatibility during transition
- Preserve existing notification data during migration
-
SQLite Setup (Android)
- Create
DailyNotificationDatabase.java
with WAL mode (see Glossary → WAL) - Implement schema version checking (
PRAGMA user_version
) (see Glossary → PRAGMA user_version) - Add database connection management with proper error handling
- Create
-
Database Configuration
- Add
dbPath: string
toConfigureOptions
interface - Implement database path resolution (absolute vs platform alias)
- Add
storage: 'shared'
configuration option - Extend existing
NotificationOptions
with database settings
- Add
-
Database Schema
-- notif_contents: keep history, newest-first reads CREATE TABLE IF NOT EXISTS notif_contents( id INTEGER PRIMARY KEY AUTOINCREMENT, slot_id TEXT NOT NULL, payload_json TEXT NOT NULL, fetched_at INTEGER NOT NULL, -- epoch ms etag TEXT, UNIQUE(slot_id, fetched_at) ); CREATE INDEX IF NOT EXISTS notif_idx_contents_slot_time ON notif_contents(slot_id, fetched_at DESC); -- notif_deliveries: track many deliveries per slot/time CREATE TABLE IF NOT EXISTS notif_deliveries( id INTEGER PRIMARY KEY AUTOINCREMENT, slot_id TEXT NOT NULL, fire_at INTEGER NOT NULL, -- intended fire time (epoch ms) delivered_at INTEGER, -- when actually shown (epoch ms) status TEXT NOT NULL DEFAULT 'scheduled', -- scheduled|shown|error|canceled error_code TEXT, error_message TEXT ); -- notif_config: generic configuration KV CREATE TABLE IF NOT EXISTS notif_config( k TEXT PRIMARY KEY, v TEXT NOT NULL );
Acceptance Criteria
- App and plugin can open the same SQLite file
- WAL mode enables concurrent reads during writes
- Schema version checking prevents compatibility issues
- All required tables exist and are accessible
- Shared DB visibility: UI reads updated rows immediately
- WAL overlap shows no UI blocking during background writes
- UI can read a row written by a background job within the same second (WAL hot-read)
- Plugin refuses to write if
PRAGMA user_version
< expected
1.2 TTL-at-Fire Enforcement
Priority: CRITICAL
Requirements
- Skip arming notifications if
(T - fetchedAt) > ttlSeconds
(see Glossary → TTL) - Validate freshness before scheduling
- Log TTL violations for debugging
- Current State: Not implemented - needs to be added to existing scheduling logic
- Shared DB (single file): App owns migrations (
PRAGMA user_version
) (see Glossary → PRAGMA user_version); plugin opens the same path; enablejournal_mode=WAL
(see Glossary → WAL),synchronous=NORMAL
,busy_timeout=5000
,foreign_keys=ON
; background writes are short & serialized.
Implementation Tasks
-
TTL Validation Logic
- Insert TTL check into the scheduler path before any arm/re-arm
- Add log code
TTL_VIOLATION
- Implement freshness validation before arming
- Before arming, if
(T − fetchedAt) > ttlSeconds
, skip arming and logTTL_VIOLATION
- Add TTL configuration to
NotificationOptions
-
Freshness Checking
- Create
isContentFresh()
method - Implement TTL calculation logic
- Add logging for TTL violations
- Create
-
Configuration Integration
- Add
ttlSeconds
toNotificationOptions
interface - Implement default TTL values (3600 seconds = 1 hour)
- Add TTL validation in option validation
- Add
Acceptance Criteria
- Notifications are skipped if content is stale
- TTL violations are logged with timestamps
- Default TTL values are applied when not specified
- Freshness checking works across all platforms
- No armed notification violates TTL-at-fire
- No armed row violates TTL at T across platforms
1.3 Rolling Window Safety
Priority: CRITICAL
Requirements
- Keep today's remaining notifications armed
- Keep tomorrow's notifications armed (within iOS caps) (see Glossary → Rolling window)
- Ensure closed-app delivery reliability
- Current State: Basic scheduling exists, but no rolling window logic
Implementation Tasks
-
Rolling Window Logic (see Glossary → Rolling window)
- Implement
armRollingWindow()
method - Calculate today's remaining slots
- Calculate tomorrow's slots within iOS limits
- Account for iOS pending-notification limits; arm tomorrow only if within cap
- Implement
-
iOS Capacity Management
- Implement iOS pending notification limit checking
- Add capacity-aware scheduling logic
- Handle capacity overflow gracefully
-
Window Maintenance
- Create
maintainRollingWindow()
method - Implement automatic re-arming logic
- Add window state persistence
- Create
Acceptance Criteria
- Today's remaining notifications stay armed
- Tomorrow's notifications are armed within iOS caps
- Closed-app delivery works reliably
- Window maintenance runs automatically
- Today always armed; tomorrow armed when within iOS cap
1.4 Configuration API Enhancement
Priority: HIGH
Requirements
- Add
dbPath
configuration option - Implement database path resolution
- Add storage mode configuration
- Current State: No database path configuration exists
Implementation Tasks
-
Interface Updates
- Extend
ConfigureOptions
withdbPath: string
- Add
storage: 'shared'
option - Update validation logic
- Extend
-
Path Resolution
- Implement absolute path handling
- Add platform-specific path resolution
- Create path validation logic
Acceptance Criteria
dbPath
can be configured via API- Path resolution works on all platforms
- Configuration validation prevents invalid paths
Phase 2: Platform Completion (High Priority)
Dependencies: Phase 1 completion - CRITICAL: Phase 2 cannot start until SQLite sharing + TTL enforcement are finished
2.1 iOS Background Tasks Implementation
Priority: HIGH
Requirements
BGTaskScheduler
for T-lead prefetch (see Glossary → T–lead)- Silent push nudge support
- Background execution budget management
- Schedule prefetch at T–lead = T − prefetchLeadMinutes (see Glossary → T–lead)
- On wake, perform one ETag-aware fetch with 12s timeout; never fetch at delivery
- Optionally (re)arm if still within TTL-at-fire (see Glossary → TTL)
- Single attempt at T–lead; 12s timeout; no delivery-time fetch; (re)arm only if within TTL-at-fire. (Planned)
Implementation Tasks
-
BGTaskScheduler Integration
- Create
DailyNotificationBackgroundTask.swift
- Implement background task registration
- Add task expiration handling
- Create
-
Silent Push Support
- Add silent push notification handling
- Implement push-to-background task bridge
- Add push token management
-
Budget Management
- Implement execution budget tracking
- Add budget-aware scheduling
- Handle budget exhaustion gracefully
Acceptance Criteria
- Background tasks run at T-lead (see Glossary → T–lead)
- Silent push can trigger background execution
- Budget management prevents system penalties
- Background execution works when app is closed
- iOS BGTask best-effort at T–lead; closed-app still delivers via rolling window (see Glossary → Rolling window)
2.2 Android Fallback Completion
Priority: HIGH
Requirements
- Complete ±10 minute windowed alarm implementation (see Glossary → Windowed alarm)
- Finish reboot/time change recovery
- Improve exact alarm fallback handling (see Glossary → Exact alarm)
- Finalize ±10m windowed alarm; reboot/time-change recovery; deep-link to Exact Alarm permission. (Planned)
Implementation Tasks
-
Windowed Alarm Implementation
- Complete
scheduleInexactAlarm()
method - Implement ±10 minute window targeting
- Add window size configuration
- Complete
-
Recovery Mechanisms
- Complete
BOOT_COMPLETED
receiver - Implement
TIMEZONE_CHANGED
handling - Add
TIME_SET
recovery logic
- Complete
-
Fallback Logic
- Improve exact alarm permission checking
- Add graceful degradation to windowed alarms
- Implement fallback logging
Acceptance Criteria
- Windowed alarms target ±10 minute windows
- Reboot recovery re-arms next 24h
- Time change recovery recomputes schedules
- Fallback works seamlessly
- Android exact permission path verified with fallback ±10m
2.3 Electron Platform Support
Priority: MEDIUM
Requirements
- Notifications while app is running
- Start-on-Login support
- Best-effort background scheduling
Implementation Tasks
-
Electron Integration
- Create
DailyNotificationElectron.ts
- Implement notification API
- Add Start-on-Login support
- Create
-
Background Limitations
- Document Electron limitations
- Implement best-effort scheduling
- Add fallback mechanisms
Acceptance Criteria
- Notifications work while app is running
- Start-on-Login enables post-reboot delivery
- Limitations are clearly documented
- Best-effort scheduling is implemented
Phase 3: Network Optimization (Medium Priority)
Dependencies: Phase 1 completion - CRITICAL: Phase 3 cannot start until SQLite sharing + TTL enforcement are finished
3.1 ETag Support Implementation
Priority: MEDIUM
Requirements
- ETag headers in fetch requests
- 304 response handling
- Network efficiency optimization
Implementation Tasks
-
ETag Headers
- Add ETag to fetch requests
- Implement ETag storage in database
- Add ETag validation logic
-
304 Response Handling
- Implement 304 response processing
- Add conditional request logic
- Handle ETag mismatches
-
Network Optimization
- Add request caching
- Implement conditional fetching
- Add network efficiency metrics
Acceptance Criteria
- ETag headers are sent with requests
- 304 responses are handled correctly
- Network efficiency is improved
- Conditional requests work reliably
3.2 Advanced Error Handling
Priority: MEDIUM
Requirements
- Comprehensive error categorization
- Retry logic with exponential backoff
- Error reporting and telemetry
Implementation Tasks
-
Error Categories
- Define error types and codes
- Implement error classification
- Add error severity levels
-
Retry Logic
- Implement exponential backoff
- Add retry limit configuration
- Create retry state management
-
Telemetry
- Add error reporting
- Implement success/failure metrics
- Create debugging information
Acceptance Criteria
- Errors are properly categorized
- Retry logic works with backoff
- Telemetry provides useful insights
- Debugging information is comprehensive
3.3 Performance Optimization
Priority: LOW
Requirements
- Database query optimization
- Memory usage optimization
- Battery usage optimization
Implementation Tasks
-
Database Optimization
- Add database indexes
- Optimize query performance
- Implement connection pooling
-
Memory Optimization
- Reduce memory footprint
- Implement object pooling
- Add memory usage monitoring
-
Battery Optimization
- Minimize background CPU usage
- Optimize network requests
- Add battery usage tracking
Acceptance Criteria
- Database queries are optimized
- Memory usage is minimized
- Battery usage is optimized
- Performance metrics are tracked
Implementation Guidelines
Development Standards
- Code Quality: Follow existing code style and documentation standards
- Testing: Write unit tests for all new functionality
- Documentation: Update documentation for all API changes
- Logging: Add comprehensive logging with proper tagging
- Security: Follow security best practices for database access
Testing Requirements
- Unit Tests: All new methods must have unit tests
- Integration Tests: Test database sharing functionality
- Platform Tests: Test on Android, iOS, and Electron
- Edge Cases: Test TTL violations, network failures, and recovery scenarios
Documentation Updates
- API Documentation: Update TypeScript definitions
- Implementation Guide: Update implementation documentation
- Troubleshooting: Add troubleshooting guides for common issues
- Examples: Create usage examples for new features
Success Metrics
Phase 1 Success Criteria
- SQLite database sharing works reliably
- TTL-at-fire enforcement prevents stale notifications
- Rolling window ensures closed-app delivery
- Configuration API supports all required options
Phase 2 Success Criteria
- iOS background tasks run at T-lead
- Android fallback works seamlessly
- Electron notifications work while running
- All platforms support the unified API
Phase 3 Success Criteria
- ETag support improves network efficiency
- Error handling is comprehensive and robust
- Performance is optimized across all platforms
- System meets all specification requirements
Risk Mitigation
Technical Risks
- Database Compatibility: Test schema version checking thoroughly
- Platform Differences: Implement platform-specific fallbacks
- Background Execution: Handle iOS background execution limitations
- Permission Changes: Monitor Android permission policy changes
Implementation Risks
- Scope Creep: Stick to specification requirements
- Testing Coverage: Ensure comprehensive testing
- Documentation: Keep documentation up-to-date
- Performance: Monitor performance impact
Conclusion
This roadmap provides a structured approach to completing the Daily Notification Plugin implementation. Phase 1 addresses the critical infrastructure gaps, Phase 2 completes platform-specific functionality, and Phase 3 optimizes the system for production use.
The implementation should follow the existing code patterns and maintain the high quality standards established in the current codebase. Regular testing and documentation updates are essential for success.
Next Steps:
- Review and approve this roadmap
- Begin Phase 1 implementation
- Set up testing infrastructure
- Create implementation tracking system