feat(docs): complete P2.6 type safety cleanup and P2.7 system invariants

P2.6: Type Safety Cleanup
- Replaced 'any' return types in vite-plugin.ts with concrete types (UserConfig, transform return type)
- Documented TypeScript mixin 'any[]' exception in PlatformServiceMixin.ts
- Audit confirmed: zero 'any' in codebase except documented TS mixin limitation
- All external boundaries use 'unknown', all data payloads use 'Record<string, unknown>'

P2.7: System Invariants Documentation
- Created SYSTEM_INVARIANTS.md documenting all 6 enforced invariants
- Added to docs/00-INDEX.md under Policy & Contracts section
- Each invariant includes: What, Why, How, Where

Progress Docs Updates:
- Updated 00-STATUS.md: marked P2.6/P2.7 complete, added type safety invariant note
- Updated 01-CHANGELOG-WORK.md: added 2025-12-22 entries for P2.6/P2.7
- Updated 03-TEST-RUNS.md: added P2.6 type safety audit test run
- Updated P2-DESIGN.md: marked P2.6 acceptance criteria complete
- Updated SYSTEM_INVARIANTS.md: added Type Safety Notes section

Baseline Tag:
- Created v1.0.11-p0-p1.4-p1.5-p2.6-p2.7-complete

TypeScript compilation:  PASSES
Build:  PASSES
CI:  All checks pass
This commit is contained in:
Matthew Raymer
2025-12-22 10:56:00 +00:00
parent 3f15352d8f
commit eb1fc9f220
85 changed files with 5199 additions and 10989 deletions

View File

@@ -0,0 +1,698 @@
# Background Data Fetching Implementation Plan
**Author**: Matthew Raymer
**Version**: 1.0.0
**Created**: 2025-10-02 07:47:04 UTC
**Last Updated**: 2025-10-02 12:45:00 UTC
## Overview
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 Enhancement**: ActiveDid-aware authentication on existing infrastructure
- **TimeSafari Integration**: PlatformServiceMixin coordination with current plugin
- **Authentication Layer**: JWT/DID support over existing HTTP callback system
- **Database Enhancement**: Extend current storage with activeDid management
- **Event & Change Management**: Identity change detection on existing notification system
- **API Integration**: Endorser.ch endpoints through current ContentFetchConfig
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
```
TimeSafari Host App
↓ (provides activeDid)
Daily Notification Plugin → Native Background Executor
HTTP Client + Auth
API Server Response
Parse & Cache Data (plugin storage)
Trigger Notifications
```
### **Option A: Host Always Provides activeDid**
**Core Principle**: Host application queries its own database and provides activeDid to plugin.
### **Why Option A Is Superior:**
1. **Clear Separation**: Host owns identity management, plugin owns notifications
2. **No Database Conflicts**: Zero shared database access between host and plugin
3. **Security Isolation**: Plugin data physically separated from user data
4. **Platform Independence**: Works consistently regardless of host's database technology
5. **Simplified Implementation**: Fewer moving parts, clearer debugging
## Android Implementation Strategy
### A. Background Execution Framework
- **Use WorkManager** for reliable background HTTP requests
- **Enhance** existing Native HTTP clients (already implemented):
- Extend `DailyNotificationETagManager.java` with JWT headers
- Add JWT authentication to `DailyNotificationFetcher.java`
- **Handle Android-specific constraints**: Doze mode, app standby, battery optimization
### B. Authentication Enhancement - Extend Current Infrastructure
**Goal**: Enhance existing `DailyNotificationETagManager.java` and `DailyNotificationFetcher.java` with JWT authentication
```kotlin
// Enhance existing Android infrastructure with JWT authentication
class DailyNotificationJWTManager {
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(
"exp" to (System.currentTimeMillis() / 1000 + expiresInSeconds),
"iat" to (System.currentTimeMillis() / 1000),
"iss" to activeDid,
"aud" to "timesafari.notifications",
"sub" to activeDid
)
return signWithDID(payload, activeDid)
}
// Enhance existing HTTP client with JWT headers
fun enhanceHttpClientWithJWT(connection: HttpURLConnection, activeDid: String) {
val jwt = generateJWTForActiveDid(activeDid, 60)
connection.setRequestProperty("Authorization", "Bearer $jwt")
connection.setRequestProperty("Content-Type", "application/json")
}
}
### C. HTTP Request Enhancement - Extend Existing Fetcher
**Goal**: Enhance existing `DailyNotificationFetcher.java` with Endorser.ch API support
```kotlin
// Enhance existing DailyNotificationFetcher.java with TimeSafari APIs
class EnhancedDailyNotificationFetcher : DailyNotificationFetcher {
private val jwtManager: DailyNotificationJWTManager
suspend fun fetchEndorserOffers(activeDid: String, afterId: String?): Result {
val connection = HttpURLConnection("$apiServer/api/v2/report/offers")
// Add JWT authentication to existing connection
jwtManager.enhanceHttpClientWithJWT(connection, activeDid)
// Add Endorser.ch specific parameters
connection.setRequestProperty("recipientDid", activeDid)
if (afterId != null) {
connection.setRequestProperty("afterId", afterId)
}
// Use existing storeAndScheduleNotification method
return fetchAndStoreContent(connection)
}
}
```
## iOS Implementation Strategy
### A. Background Execution Framework
- **Use BGTaskScheduler** for background HTTP requests
- **Replace axios** with native iOS HTTP clients:
- URLSession for HTTP requests
- Combine framework for async/await patterns
### B. Authentication Implementation
```swift
// JWT Generation in iOS
class JWTHelper {
func generateJWT(userDid: String, expiresInSeconds: Int) -> String {
let payload: [String: Any] = [
"exp": Int(Date().timeIntervalSince1970) + expiresInSeconds,
"iat": Int(Date().timeIntervalSince1970),
"iss": userDid
]
return signWithDID(payload, userDid)
}
}
```
### C. HTTP Request Implementation
```swift
// Background HTTP Task
class DataFetchTask {
func fetchData() async {
let jwt = generateJWT(userDid: activeDid, expiresInSeconds: 60)
var request = URLRequest(url: apiURL)
request.setValue("Bearer \(jwt)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
do {
let (data, _) = try await URLSession.shared.data(for: request)
let offersResponse = try JSONDecoder().decode(OffersResponse.self, from: data)
await scheduleNotification(with: offersResponse.data)
} catch {
// Handle errors
}
}
}
```
## Data Models & Type Safety
### Shared TypeScript Interfaces
```typescript
// Definitions for native bridge
interface OffersResponse {
data: OfferSummaryRecord[];
hitLimit: boolean;
}
interface OfferSummaryRecord {
jwtId: string;
handleId: string;
issuedAt: string;
offeredByDid: string;
recipientDid: string;
unit: string;
amount: number;
// ... other fields
}
```
### Native Implementations
- **Kotlin sealed classes** for type-safe responses
- **Swift Codable structs** for JSON parsing
- **Shared error handling** patterns
## Configuration Management
### Plugin Configuration
```typescript
interface PluginConfig {
apiServer: string;
jwtExpirationSeconds: number;
requestTimeoutMs: number;
retryAttempts: number;
activeDid: string; // Simplified to single active DID
lastKnownOfferId?: string;
lastKnownPlanId?: string;
}
```
### Platform-Specific Settings
- **Android**: Manage API keys in `AndroidManifest.xml`, use SharedPreferences for runtime config
- **iOS**: Use `Info.plist` for static config, UserDefaults for runtime settings
## Error Handling & Resilience
### Network Error Handling
- **Connectivity checks** before making requests
- **Exponential backoff** for retry scenarios
- **Circuit breaker pattern** for API failures
- **Graceful degradation** when offline
### Authentication Error Handling
- **Token refresh** mechanisms
- **Fallback to anonymous** requests when authentication fails
- **Secure credential storage** using platform keychains
## Cache & State Management
### Data Persistence
#### **Platform-Specific Storage Architecture**
**Android/Electron Platforms:**
- **@capacitor-community/sqlite** plugin integration for native SQLite access
- **Shared plugin database** - Plugin manages its own SQLite database instance
- **Direct SQL execution** via plugin's `dbExec()` methods for complex queries
- **Background worker integration** for database operations during content fetch
**Web Platform:**
- **absurd-sql** for SQLite support in browser (managed by host application)
- **Plugin delegation pattern** - Plugin provides SQL queries, host executes them
- **IndexedDB fallback** for basic caching when SQLite unavailable
**iOS Platform:**
- **Core Data integration** via native Swift implementation
- **Background task compatibility** with iOS background refresh constraints
### State Synchronization
- **JavaScript → Native** configuration updates
- **Native → JavaScript** status reporting
- **Cross-platform state consistency**
- **Background ↔ Foreground** state synchronization
- **Database logging** for audit trails and debugging
### Enhanced Caching Strategy
Based on TimeSafari's optimization patterns:
- **Batch-oriented processing** for API requests to reduce overhead
- **Intelligent batching** with configurable timing (max 100ms wait, max 10 items)
- **Memory-optimized caching** with automatic cleanup (keep last 1000 log entries)
- **Request deduplication** to prevent redundant API calls
- **Performance monitoring** with operation timing and metrics collection
## Performance Optimizations
### Request Optimization
- **Deduplication** of identical requests
- **Batch requests** when possible
- **Intelligent polling** based on user activity
### Memory Management
- **Background memory limits** enforcement
- **Cache cleanup** on memory pressure
- **Resource lifecycle** management
## Critical Requirement: Plugin Must Know When activeDid Changes
### **Security Implications of Missing ActiveDid Change Detection**
**Without immediate activeDid change detection, the plugin faces severe risks:**
- **Cross-User Data Exposure**: Plugin fetches notifications for wrong user after identity switch
- **Unauthorized API Access**: JWT tokens valid for incorrect user context
- **Background Task Errors**: Content fetching operates with wrong identity
### **Event-Based Solution**
**Host Application Responsibility**: Dispatch `activeDidChanged` event
```typescript
// TimeSafari PlatformServiceMixin modification
async $updateActiveDid(newDid: string | null): Promise<void> {
// Update TimeSafari's active_identity table (existing logic)
await this.$dbExec(
"UPDATE active_identity SET activeDid = ?, lastUpdated = datetime('now') WHERE id = 1",
[newDid || ""]
);
// CRITICAL: Notify plugin of change IMMEDIATELY
document.dispatchEvent(new CustomEvent('activeDidChanged', {
detail: { activeDid: newDid }
}));
}
```
**Plugin Responsibility**: Listen and respond to changes
```typescript
// Plugin service layer implementation
plugin.onActiveDidChange(async (newActiveDid) => {
// 1. Clear all cached content for previous identity
await plugin.clearCacheForNewIdentity();
// 2. Refresh authentication tokens with new activeDid
await plugin.refreshAuthenticationForNewIdentity(newActiveDid);
// 3. Restart background tasks with correct identity
await plugin.updateBackgroundTaskIdentity(newActiveDid);
logger.info(`[DailyNotificationService] ActiveDid updated to: ${newActiveDid}`);
});
```
## TimeSafari Integration Patterns
### **ActiveDid Management Analysis**
**TimeSafari's Database Architecture:**
- **Table**: `active_identity` (single row with `id = 1`)
- **Content**: `activeDid TEXT`, `lastUpdated DATETIME`
- **Purpose**: Single source of truth for active user identity
**Access via PlatformServiceMixin:**
```typescript
// Retrieving activeDid in TimeSafari components
const activeIdentity = await this.$getActiveIdentity();
const activeDid = activeIdentity.activeDid;
// Updating activeDid via PlatformServiceMixin
async $updateActiveDid(newDid: string | null): Promise<void> {
await this.$dbExec(
"UPDATE active_identity SET activeDid = ?, lastUpdated = datetime('now') WHERE id = 1",
[newDid || ""]
);
}
```
### **Plugin Hosting Strategy**
**Existing Plugin Usage**: TimeSafari already uses Capacitor plugins extensively via `CapacitorPlatformService.ts`
**Recommended Integration Architecture:**
- Plugin integrates as standard Capacitor plugin
- Host provides activeDid via event-driven pattern
- Plugin manages own isolated storage
- Clear separation of responsibilities maintained
## Integration Points
### Enhanced Plugin Interface for Host Application Integration
#### **Database Integration Patterns**
**Android/Electron: Host-Provided activeDid Approach (Option A)**
```typescript
// Host queries its own database and provides activeDid
const activeIdentity = await this.$getActiveIdentity(); // Uses host's CapacitorSQLite
await plugin.setActiveDidFromHost(activeIdentity.activeDid);
// Plugin configures its own isolated database
await plugin.configureDatabase({
platform: 'android',
storageType: 'plugin-managed' // Plugin owns its storage
});
// Set up activeDid change listener for future changes
plugin.onActiveDidChange(async (newActiveDid) => {
await plugin.clearCacheForNewIdentity();
await plugin.refreshAuthenticationForNewIdentity(newActiveDid);
logger.info(`[TimeSafari] ActiveDid changed to: ${newActiveDid}`);
});
```
**Web: Host-Provided activeDid Approach (Option A)**
```typescript
// Host queries its absurd-sql database and provides activeDid
const activeIdentity = await this.$getActiveIdentity(); // Uses host's absurd-sql
await plugin.setActiveDidFromHost(activeIdentity.activeDid);
// Plugin uses host-delegated storage for its own data
await plugin.configureDatabase({
platform: 'web',
storageType: 'host-managed' // Plugin delegates to host for storage
});
// Plugin operates independently with provided activeDid
const results = await plugin.executeContentFetch(contentConfig);
```
**iOS: Host-Provided activeDid Approach (Option A)**
```typescript
// Host queries its CapacitorSQLite database and provides activeDid
const activeIdentity = await this.$getActiveIdentity(); // Uses host's CapacitorSQLite
await plugin.setActiveDidFromHost(activeIdentity.activeDid);
// Plugin configures its own Core Data storage
await plugin.configureDatabase({
platform: 'ios',
storageType: 'plugin-managed' // Plugin owns Core Data storage
});
// Plugin operates with provided activeDid, no database sharing needed
const results = await plugin.executeBackgroundContentFetch();
```
#### **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
interface EnhancedDailyNotificationPlugin extends DailyNotificationPlugin {
// Enhanced configuration with activeDid support
configure(options: ConfigureOptions & {
activeDidIntegration?: {
platform: 'android' | 'ios' | 'web' | 'electron';
storageType: 'plugin-managed' | 'host-managed';
};
}): Promise<void>;
// Host-provided activeDid Management (Option A Implementation)
setActiveDidFromHost(activeDid: string): Promise<void>;
// Critical: ActiveDid Change Handling
onActiveDidChange(callback: (newActiveDid: string) => Promise<void>): void;
refreshAuthenticationForNewIdentity(activeDid: string): Promise<void>;
}
```
### Background Scheduling with Hybrid activeDid Management
- **Integrate** with existing WorkManager/BGTaskScheduler
- **Coordinate** API fetch timing with notification schedules
- **Handle** app lifecycle events (background/foreground)
- **Implement** host-provided activeDid access (Option A):
- **Always**: Host provides activeDid via `setActiveDidFromHost()`
- **No Database Sharing**: Plugin never accesses TimeSafari's active_identity table
- **Critical**: Plugin **MUST** know when activeDid changes for:
- **Event-Based Notification**: Host dispatches `activeDidChanged` events
- **Cache Invalidation**: Clear cached content when user switches identity
- **Token Refresh**: Generate new JWT tokens with updated active Did
- **Background Task Coordination**: Restart tasks with new identity context
- **Maintain** clear separation: Host owns identity management, plugin owns notifications
## Migration & Testing Strategy
### Gradual Migration
1. **Phase 1**: Implement basic HTTP + JWT authentication
2. **Phase 2**: Add caching and state management
3. **Phase 3**: Integrate with notification scheduling
4. **Phase 4**: Add passkey authentication support
### Testing Approach with Host-Provided activeDid Management
- **Unit tests** for JWT generation and HTTP clients with activeDid
- **Integration tests** for API endpoint interactions using TimeSafari active_identity patterns
- **Host-provided activeDid testing**:
- Test `setActiveDidFromHost()` with TimeSafari PlatformServiceMixin
- Test host event dispatch and plugin event listening
- **Critical**: Test `onActiveDidChange()` listener with identity switches
- Test cache invalidation and token refresh during activeDid changes
- Verify database isolation between host and plugin
- **Background testing** on real devices (doze mode, app backgrounding)
- **Authentication testing** with actual DID credentials from TimeSafari active_identity table
- **Cross-platform testing** for Android/Electron (SQLite access) vs Web (host delegation) patterns
## API Endpoints to Support
### Offers to User Endpoint
```
GET {apiServer}/api/v2/report/offers?recipientDid={userDid}&afterId={jwtId}&beforeId={jwtId}
```
**Response Structure:**
```json
{
"data": Array<OfferSummaryRecord>,
"hitLimit": boolean
}
```
### Offers to User Projects Endpoint
```
GET {apiServer}/api/v2/report/offersToPlansOwnedByMe?afterId={jwtId}&beforeId={jwtId}
```
**Response Structure:**
```json
{
"data": Array<OfferToPlanSummaryRecord>,
"hitLimit": boolean
}
```
## Authentication Implementation Strategy
### Option 1: Simple DID Authentication (Basic)
- Generate traditional JWT using DID signing
- Short-lived tokens (60 seconds)
- Suitable for basic notification data fetching
- Use `did-jwt` library for token generation and verification
- Based on TimeSafari's existing JWT implementation patterns
### Option 2: Enhanced Passkey Authentication (Advanced)
- Leverage device biometrics/security keys
- Longer-lived tokens with automatic refresh
- Support for cached authentication state
- Better user experience for frequent polling
- Integrate with SimpleWebAuthn for cross-platform biometric support
- Support JWANT tokens (JWT + WebAuthn) for enhanced security
## Platform-Specific Considerations
### Android Considerations
- Use OkHttp or native Android HTTP clients
- Handle certificate pinning if required
- Support Android Keystore for secure key storage
- Handle biometric prompt integration for passkeys
### iOS Considerations
- Use URLSession for HTTP requests
- Support iOS Keychain for authentication tokens
- Handle Face ID/Touch ID integration for passkeys
- Support certificate pinning if required
- Use BGTaskScheduler for reliable background execution
- Handle iOS-specific background refresh restrictions
- Support Core Data for notification metadata persistence
## Data Flow Integration Points
### Token Generation
- Accept activeDid as input
- Generate JWT authentication token using DID signing
- Include activeDid as both issuer (`iss`) and subject (`sub`)
- Return token for immediate use or caching
### Request Execution
- Construct full API URLs with query parameters
- Apply authentication headers
- Execute HTTP requests with proper error handling
- Return structured response data
### Caching Strategy
- Support token caching with expiration management
- Implement request deduplication for same endpoints
- Support cache invalidation for authentication failures
## Implementation Phases
### Phase 1: Extend Core Infrastructure (Building on Existing)
- **Extend existing** Android `DailyNotificationFetcher.java` with JWT authentication
- **Enhance existing** iOS implementation (when added) with authentication layer
- **Add JWT generation** to existing `DailyNotificationETagManager.java`
- **Enhance current** `ConfigureOptions` with activeDid integration
- **Build on existing** error handling (circuit breaker already implemented)
### Phase 2: ActiveDid Integration & TimeSafari API Enhancement
- **Add** host-provided activeDid management to existing plugin interface
- **Extend** existing `configure()` method with activeDid options
- **Enhance** existing `ContentFetchConfig` with Endorser.ch API endpoints
- **Add** `setActiveDidFromHost()` and `onActiveDidChange()` to existing interface
- **Integrate** existing `callback-registry.ts` with activeDid-aware callbacks
- **Enhance** existing platform storage:
- **Android**: Extend existing SQLite with activeDid-aware JWT storage
- **Web**: Enhance existing IndexedDB with activeDid support (no host delegation needed initially)
### Phase 3: Background Enhancement & TimeSafari Coordination
- **Enhance** existing WorkManager integration with activeDid-aware workers
- **Coordinate** existing notification scheduling with TimeSafari PlatformServiceMixin
- **Extend** existing app lifecycle handling with activeDid change detection
- **Enhance** existing state synchronization with identity management
- **Critical: Enhance retry policies** for activeDid changes:
- **Android**: Modify `DailyNotificationFetchWorker.java` retry logic to detect activeDid changes during retry sequence
- **Web**: Enhance `callback-registry.ts` to refresh authentication before retry attempts
- **Unify**: Standardize retry delays across platforms (Android 1min→1hour vs Web 1sec→1min)
- **Integrate activeDid change detection** into existing circuit breaker and error handling systems
### Phase 4: TimeSafari Integration & Advanced Features
- **Integrate** with TimeSafari's existing PlatformServiceMixin patterns
- **Add** Endorser.ch API endpoint support to existing `ContentFetchConfig`
- **Implement** DID-based authentication alongside existing callback system
- **Enhance** existing testing with TimeSafari-specific scenarios
## Current Scheduled Event Update Policies
### ✅ **Existing Consistent Policies**
- **Retry Logic**: Exponential backoff with platform-specific limits (Android: 5 retries, Web: 5 retries)
- **Circuit Breaker**: Opens after 5 consecutive failures
- **Fallback Content**: Uses cached/emergency content when all retries fail
- **ETag Updates**: Conditional requests with 304 Not Modified handling
- **Error Classification**: Network/Storage errors retryable, Permission/Config errors not retryable
### ⚠️ **Enhancement Required for TimeSafari Integration**
- **ActiveDid Change Detection**: Handle identity switches during scheduled events
- **Authentication Refresh**: Update JWT tokens for ongoing retry attempts
- **Cache Invalidation**: Clear cached content when activeDid changes
- **Platform Policy Unification**: Standardize retry delays and fallback mechanisms
### **TimeSafari-Aware Update Policy**
```typescript
interface TimeSafariUpdatePolicy extends ContentFetchConfig {
activeDidAwareRetry?: {
maxRetriesDuringActiveDidChange: number; // More retries during identity change
authenticationRefreshDelay: number; // Time to refresh auth before retry
cacheInvalidationOnChange: boolean; // Clear cache when activeDid changes
};
}
```
## Success Criteria
- [ ] **Functional Requirements**: API data fetching works reliably in background with activeDid awareness
- [ ] **Performance Requirements**: Requests complete within 30 seconds, including authentication refresh
- [ ] **Security Requirements**: ActiveDid-based authentication with token refresh during retries
- [ ] **Reliability Requirements**: Enhanced retry policies that handle activeDid changes gracefully
- [ ] **Integration Requirements**: Seamless integration with existing plugin APIs + TimeSafari patterns
- [ ] **Testing Requirements**: Comprehensive test coverage including activeDid change scenarios
- [ ] **Authentication Requirements**: DID-based JWT with automatic refresh during scheduled events
- [ ] **Optimization Requirements**: Intelligent retry policies based on error type and activeDid state
- [ ] **Logging Requirements**: Structured logging with activeDid context and retry state tracking
- [ ] **Cross-Platform Requirements**: Unified activeDid-aware retry and fallback mechanisms
## Risks & Mitigation
### Technical Risks
- **Background execution limits**: Mitigated by using platform-specific background task systems
- **Authentication complexity**: Mitigated by implementing gradual migration path
- **Cross-platform consistency**: Mitigated by shared interfaces and careful API design
### Timeline Risks
- **Platform-specific complexity**: Mitigated by prioritizing Android first, then iOS
- **Testing complexity**: Mitigated by automated testing and CI/CD integration
- **Integration challenges**: Mitigated by maintaining backward compatibility
---
**Status**: Enhancement plan for existing implementation (Option A) - Ready for implementation
**Next Steps**: Begin Phase 1 - enhance existing Android HTTP infrastructure with JWT authentication
**Dependencies**: Existing plugin infrastructure, Android Studio, Capacitor CLI, TimeSafari PlatformServiceMixin
**Enhancement Approach**:
- **Build on Existing**: Leverage current SQLite, IndexedDB, callback system, and dual scheduling
- **Option A Integration**: Add activeDid management to existing configuration and HTTP layers
- **TimeSafari Enhancement**: Extend current ContentFetchConfig with Endorser.ch API endpoints
- **Authentication Layer**: Add JWT/DID authentication over existing HTTP infrastructure
- **Event Integration**: Enhance existing callback system with activeDid change detection