Browse Source

enhance: Update BACKGROUND_DATA_FETCHING_PLAN.md to align with current implementation

- Added Current Implementation Baseline section documenting existing functionality
- Updated authentication examples to enhance existing DailyNotificationETagManager.java
- Modified HTTP request implementation to extend existing DailyNotificationFetcher.java
- Updated plugin interface to extend current DailyNotificationPlugin rather than replace
- Corrected implementation phases to build upon existing infrastructure:
  * Phase 1: Extend core infrastructure (not rebuild)
  * Phase 2: Add activeDid integration to existing methods
  * Phase 3: Enhance existing background integration
  * Phase 4: Add TimeSafari-specific features
- Updated Android examples to show enhancement of existing SQLite + SharedPreferences
- Updated Web examples to enhance existing IndexedDB (no host delegation initially)
- Changed status from 'implementation plan' to 'enhancement plan for existing implementation'
- Aligned dependencies with existing plugin infrastructure rather than new requirements

The plan now accurately reflects building upon our working plugin instead of
rebuilding from scratch, providing a realistic enhancement roadmap.
research/notification-plugin-enhancement
Matthew Raymer 18 hours ago
parent
commit
2f02e5661b
  1. 225
      doc/BACKGROUND_DATA_FETCHING_PLAN.md

225
doc/BACKGROUND_DATA_FETCHING_PLAN.md

@ -7,16 +7,34 @@
## Overview ## Overview
This document outlines the **complete implementation plan** for background data fetching in the Capacitor Daily Notification Plugin, replacing web push implementations with native platform solutions. This consolidated plan includes: This document outlines the **enhancement plan** for background data fetching in the Daily Notification Plugin to support TimeSafari integration with Option A architecture. This plan builds upon our existing implementation and adds:
- **Option A Architecture**: Host always provides activeDid approach - **Option A Enhancement**: ActiveDid-aware authentication on existing infrastructure
- **TimeSafari Integration**: PlatformServiceMixin coordination patterns - **TimeSafari Integration**: PlatformServiceMixin coordination with current plugin
- **Cross-Platform Implementation**: Android/Electron, iOS, Web specifications - **Authentication Layer**: JWT/DID support over existing HTTP callback system
- **Database Access Patterns**: Clear separation between host and plugin storage - **Database Enhancement**: Extend current storage with activeDid management
- **ActiveDid Change Management**: Event-based notification and cache invalidation - **Event & Change Management**: Identity change detection on existing notification system
- **Security Requirements**: Data isolation and authentication patterns - **API Integration**: Endorser.ch endpoints through current ContentFetchConfig
This document consolidates all previous analysis documents to provide a single source of truth for implementation. This document serves as the enhancement roadmap for adding TimeSafari capabilities to our existing, working plugin.
## Current Implementation Baseline
### ✅ Already Implemented & Working
- **Android Storage**: SharedPreferences + SQLite with migration (`DailyNotificationStorage.java`, `DailyNotificationDatabase.java`)
- **Web Storage**: IndexedDB with comprehensive service worker (`sw.ts`, `IndexedDBManager`)
- **Callback System**: HTTP/local callbacks with circuit breaker (`callback-registry.ts`)
- **Configuration**: Database path, TTL, retention settings (`ConfigureOptions`)
- **ETag Support**: Conditional HTTP requests (`DailyNotificationETagManager.java`)
- **Dual Scheduling**: Content fetch + user notification separation
- **Cross-Platform API**: Unified TypeScript interface (`DailyNotificationPlugin`)
### ⚠️ Enhancement Required for TimeSafari
- **ActiveDid Integration**: Add activeDid-awareness to existing authentication
- **JWT Generation**: Enhance HTTP layer with DID-based tokens
- **Identity Change Detection**: Add event listeners to existing callback system
- **Endorser.ch APIs**: Extend `ContentFetchConfig` with TimeSafari endpoints
- **Platform Auth**: Add Android Keystore/iOS Keychain to existing storage
## Consolidated Architecture: Option A Platform Overview ## Consolidated Architecture: Option A Platform Overview
@ -50,61 +68,64 @@ Daily Notification Plugin → Native Background Executor
### A. Background Execution Framework ### A. Background Execution Framework
- **Use WorkManager** for reliable background HTTP requests - **Use WorkManager** for reliable background HTTP requests
- **Replace axios** with native Android HTTP clients: - **Enhance** existing Native HTTP clients (already implemented):
- OkHttp for synchronous requests - Extend `DailyNotificationETagManager.java` with JWT headers
- Retrofit for type-safe API interfaces - Add JWT authentication to `DailyNotificationFetcher.java`
- **Handle Android-specific constraints**: Doze mode, app standby, battery optimization - **Handle Android-specific constraints**: Doze mode, app standby, battery optimization
### B. Authentication Implementation ### B. Authentication Enhancement - Extend Current Infrastructure
**Goal**: Enhance existing `DailyNotificationETagManager.java` and `DailyNotificationFetcher.java` with JWT authentication
```kotlin ```kotlin
// JWT Generation in Android - Enhanced with DID support // Enhance existing Android infrastructure with JWT authentication
class JWTHelper { class DailyNotificationJWTManager {
fun generateJWT(userDid: String, expiresInSeconds: Int): String { private val storage: DailyNotificationStorage
private val currentActiveDid: String? = null
// Add JWT generation to existing fetcher
fun generateJWTForActiveDid(activeDid: String, expiresInSeconds: Int): String {
val payload = mapOf( val payload = mapOf(
"exp" to (System.currentTimeMillis() / 1000 + expiresInSeconds), "exp" to (System.currentTimeMillis() / 1000 + expiresInSeconds),
"iat" to (System.currentTimeMillis() / 1000), "iat" to (System.currentTimeMillis() / 1000),
"iss" to userDid, "iss" to activeDid,
// Include DID-specific claims for verification
"aud" to "timesafari.notifications", "aud" to "timesafari.notifications",
"sub" to userDid "sub" to activeDid
) )
return signWithDID(payload, userDid) return signWithDID(payload, activeDid)
} }
// Enhanced authentication with Passkey support // Enhance existing HTTP client with JWT headers
fun generateJWANT(userDid: String, biometricData: ByteArray): String { fun enhanceHttpClientWithJWT(connection: HttpURLConnection, activeDid: String) {
val payload = mapOf( val jwt = generateJWTForActiveDid(activeDid, 60)
"exp" to (System.currentTimeMillis() / 1000 + 3600), // 1 hour connection.setRequestProperty("Authorization", "Bearer $jwt")
"iat" to (System.currentTimeMillis() / 1000), connection.setRequestProperty("Content-Type", "application/json")
"iss" to userDid,
"aud" to "timesafari.notifications",
"sub" to userDid,
"auth_data" to android.util.Base64.encodeToString(biometricData, android.util.Base64.NO_WRAP)
)
return signWithDIDPasskey(payload, userDid, biometricData)
} }
} }
### C. HTTP Request Implementation ### C. HTTP Request Enhancement - Extend Existing Fetcher
**Goal**: Enhance existing `DailyNotificationFetcher.java` with Endorser.ch API support
```kotlin ```kotlin
// Background HTTP Worker // Enhance existing DailyNotificationFetcher.java with TimeSafari APIs
class DataFetchWorker : CoroutineWorker { class EnhancedDailyNotificationFetcher : DailyNotificationFetcher {
suspend fun doWork(): Result { private val jwtManager: DailyNotificationJWTManager
val jwt = generateJWT(activeDid, 60)
val headers = mapOf( suspend fun fetchEndorserOffers(activeDid: String, afterId: String?): Result {
"Authorization" to "Bearer $jwt", val connection = HttpURLConnection("$apiServer/api/v2/report/offers")
"Content-Type" to "application/json"
)
val offersResponse = httpClient.get("$apiServer/api/v2/report/offers") { // Add JWT authentication to existing connection
headers { headers.forEach { append(it.key, it.value) } } jwtManager.enhanceHttpClientWithJWT(connection, activeDid)
parameter("recipientId", activeDid) // Use activeDid for recipient filtering
parameter("afterId", lastKnownOfferId) // Add Endorser.ch specific parameters
connection.setRequestProperty("recipientDid", activeDid)
if (afterId != null) {
connection.setRequestProperty("afterId", afterId)
} }
return storeAndScheduleNotification(offersResponse.body()) // Use existing storeAndScheduleNotification method
return fetchAndStoreContent(connection)
} }
} }
``` ```
@ -411,40 +432,34 @@ await plugin.configureDatabase({
const results = await plugin.executeBackgroundContentFetch(); const results = await plugin.executeBackgroundContentFetch();
``` ```
#### **New Plugin Methods Required** #### **Enhancement Required: Extend Current Plugin Interface**
**Current Interface** (already implemented):
```typescript
interface DailyNotificationPlugin {
configure(options: ConfigureOptions): Promise<void>;
scheduleContentFetch(config: ContentFetchConfig): Promise<void>;
scheduleUserNotification(config: UserNotificationConfig): Promise<void>;
// ... existing methods (see definitions.ts)
}
```
**Enhancement Required** (add to existing interface):
```typescript ```typescript
interface EnhancedDailyNotificationPlugin { interface EnhancedDailyNotificationPlugin extends DailyNotificationPlugin {
// Database configuration - Simplified Option A approach // Enhanced configuration with activeDid support
configureDatabase(options: { configure(options: ConfigureOptions & {
platform: 'android' | 'ios' | 'web' | 'electron'; activeDidIntegration?: {
storageType: 'plugin-managed' | 'host-managed'; platform: 'android' | 'ios' | 'web' | 'electron';
dbPath?: string; storageType: 'plugin-managed' | 'host-managed';
encryption?: boolean; };
}): Promise<void>; }): Promise<void>;
// Host-provided activeDid Management (Option A Implementation) // Host-provided activeDid Management (Option A Implementation)
setActiveDidFromHost(activeDid: string): Promise<void>; setActiveDidFromHost(activeDid: string): Promise<void>;
// Content fetch with database integration
fetchAndStoreContent(config: ContentFetchConfig): Promise<ContentFetchResult>;
// Data access for host application
getStoredContent(query: string, params?: any[]): Promise<any[]>;
clearStoredContent(options?: { olderThan?: number }): Promise<void>;
// Background task coordination
getBackgroundTaskStatus(): Promise<BackgroundTaskStatus>;
pauseBackgroundTasks(): Promise<void>;
resumeBackgroundTasks(): Promise<void>;
// TimeSafari Integration Methods
initializeFromTimeSafari(): Promise<void>;
listenForActiveDidChanges(): Promise<void>;
// Critical: ActiveDid Change Handling // Critical: ActiveDid Change Handling
onActiveDidChange(callback: (newActiveDid: string) => Promise<void>): void; onActiveDidChange(callback: (newActiveDid: string) => Promise<void>): void;
clearCacheForNewIdentity(): Promise<void>;
refreshAuthenticationForNewIdentity(activeDid: string): Promise<void>; refreshAuthenticationForNewIdentity(activeDid: string): Promise<void>;
} }
``` ```
@ -579,38 +594,38 @@ GET {apiServer}/api/v2/report/offersToPlansOwnedByMe?afterId={jwtId}&beforeId={j
## Implementation Phases ## Implementation Phases
### Phase 1: Core Infrastructure (Weeks 1-2) ### Phase 1: Extend Core Infrastructure (Building on Existing)
- Set up native HTTP clients for Android/iOS - **Extend existing** Android `DailyNotificationFetcher.java` with JWT authentication
- Implement basic JWT generation - **Enhance existing** iOS implementation (when added) with authentication layer
- Create plugin configuration interfaces - **Add JWT generation** to existing `DailyNotificationETagManager.java`
- Set up basic error handling - **Enhance current** `ConfigureOptions` with activeDid integration
- **Build on existing** error handling (circuit breaker already implemented)
### Phase 2: Host-Provided activeDid Integration & API Access (Weeks 3-4) ### Phase 2: ActiveDid Integration & TimeSafari API Enhancement
- Implement host-provided activeDid management (Option A approach) - **Add** host-provided activeDid management to existing plugin interface
- Add `setActiveDidFromHost()` method (no database access needed) - **Extend** existing `configure()` method with activeDid options
- Remove database sharing complexity - host always provides activeDid - **Enhance** existing `ContentFetchConfig` with Endorser.ch API endpoints
- Integrate API endpoint calls with activeDid-based authentication - **Add** `setActiveDidFromHost()` and `onActiveDidChange()` to existing interface
- Add response parsing and validation - **Integrate** existing `callback-registry.ts` with activeDid-aware callbacks
- Implement platform-specific database integration: - **Enhance** existing platform storage:
- **Android/Electron**: Plugin-managed @capacitor-community/sqlite (no host database access) - **Android**: Extend existing SQLite with activeDid-aware JWT storage
- **Web**: Host-managed storage delegation (plugin doesn't access absurd-sql directly) - **Web**: Enhance existing IndexedDB with activeDid support (no host delegation needed initially)
- **iOS**: Plugin-managed Core Data (no host database access)
### Phase 3: Background Integration (Weeks 5-6) ### Phase 3: Background Enhancement & TimeSafari Coordination
- Integrate with WorkManager/BGTaskScheduler - **Enhance** existing WorkManager integration with activeDid-aware workers
- Coordinate with notification scheduling - **Coordinate** existing notification scheduling with TimeSafari PlatformServiceMixin
- Handle app lifecycle events - **Extend** existing app lifecycle handling with activeDid change detection
- Implement state synchronization - **Enhance** existing state synchronization with identity management
### Phase 4: Advanced Features (Weeks 7-8) ### Phase 4: TimeSafari Integration & Advanced Features
- Add passkey authentication support - **Integrate** with TimeSafari's existing PlatformServiceMixin patterns
- Implement advanced caching strategies - **Add** Endorser.ch API endpoint support to existing `ContentFetchConfig`
- Optimize performance and memory usage - **Implement** DID-based authentication alongside existing callback system
- Add comprehensive testing - **Enhance** existing testing with TimeSafari-specific scenarios
## Success Criteria ## Success Criteria
@ -641,12 +656,12 @@ GET {apiServer}/api/v2/report/offersToPlansOwnedByMe?afterId={jwtId}&beforeId={j
--- ---
**Status**: Host-provided activeDid implementation plan (Option A) - Ready for implementation **Status**: Enhancement plan for existing implementation (Option A) - Ready for implementation
**Next Steps**: Begin Phase 1 implementation with Android HTTP client setup **Next Steps**: Begin Phase 1 - enhance existing Android HTTP infrastructure with JWT authentication
**Dependencies**: Android Studio, Xcode, Capacitor CLI, existing plugin infrastructure, @capacitor-community/sqlite **Dependencies**: Existing plugin infrastructure, Android Studio, Capacitor CLI, TimeSafari PlatformServiceMixin
**Option A Features**: **Enhancement Approach**:
- **Simplified Architecture**: Host always provides activeDid, no database sharing - **Build on Existing**: Leverage current SQLite, IndexedDB, callback system, and dual scheduling
- **TimeSafari Integration**: PlatformServiceMixin coordination without database access - **Option A Integration**: Add activeDid management to existing configuration and HTTP layers
- **Cross-Platform**: Android/Electron plugin-managed SQLite, Web host-managed storage, iOS plugin-managed Core Data - **TimeSafari Enhancement**: Extend current ContentFetchConfig with Endorser.ch API endpoints
- **Authentication**: DID-based JWT with host-provided activeDid - **Authentication Layer**: Add JWT/DID authentication over existing HTTP infrastructure
- **Background Tasks**: Event-based activeDid changes, clear separation of concerns - **Event Integration**: Enhance existing callback system with activeDid change detection

Loading…
Cancel
Save