feat(phase2): implement ActiveDid Integration & TimeSafari API Enhancement

- Enhanced ConfigureOptions with comprehensive TimeSafari activeDid configuration
- Extended ContentFetchConfig with Endorser.ch API endpoints and TimeSafari config
- Added detailed TimeSafari notification types (Offers, Projects, People, Items)
- Implemented Host-provided activeDid Plugin Configuration with auto-sync
- Enhanced Android retry logic with TimeSafari activeDid change detection
- Enhanced Web retry logic with Phase 2 ActiveDid change support
- Added comprehensive TimeSafari fallback content generation
- Implemented cross-platform ActiveDid change event tracking

Phase 2 delivers:
 Enhanced ConfigureOptions with host-provided activeDid patterns
 Extension of ContentFetchConfig with Endorser.ch endpoints
 Complete TimeSafari notification type definitions
 Host-provided activeDid Plugin Configuration implementation
 Enhanced Android retry logic with activeDid change detection
 Enhanced Web retry logic with session-based activeDid tracking
 TimeSafari-aware fallback content generation
 Comprehensive configuration storage and persistence

Ready for Phase 3: Background Enhancement & TimeSafari Coordination
This commit is contained in:
Matthew Raymer
2025-10-03 07:02:55 +00:00
parent ee772f136a
commit 0b6a8cdd39
4 changed files with 457 additions and 23 deletions

View File

@@ -160,12 +160,20 @@ export interface ConfigureOptions {
prefetchLeadMinutes?: number;
maxNotificationsPerDay?: number;
retentionDays?: number;
// Phase 1: ActiveDid Integration Enhancement
// Phase 2: TimeSafari ActiveDid Integration Enhancement
activeDidIntegration?: {
platform: 'android' | 'ios' | 'web' | 'electron';
storageType: 'plugin-managed' | 'host-managed';
jwtExpirationSeconds?: number;
apiServer?: string;
// Phase 2: Host-provided activeDid configuration
activeDid?: string; // Initial activeDid from host
hostCredentials?: {
platform?: string; // Platform identifier
accessToken?: string; // Optional access token
};
autoSync?: boolean; // Auto-sync activeDid changes
identityChangeGraceSeconds?: number; // Grace period for activeDid changes
};
}
@@ -189,6 +197,30 @@ export interface ContentFetchConfig {
contentHandler?: ContentHandler;
cachePolicy?: CachePolicy;
networkConfig?: NetworkConfig;
// Phase 2: TimeSafari Endorser.ch API configuration
timesafariConfig?: {
activeDid: string; // Required activeDid for authentication
endpoints?: {
offersToPerson?: string;
offersToPlans?: string;
projectsLastUpdated?: string;
};
syncConfig?: {
enableParallel?: boolean; // Enable parallel API requests
maxConcurrent?: number; // Max concurrent requests
batchSize?: number; // Batch size for requests
};
credentialConfig?: {
jwtSecret?: string; // JWT secret for signing
tokenExpirationMinutes?: number; // Token expiration
refreshThresholdMinutes?: number; // Refresh threshold
};
errorPolicy?: {
maxRetries?: number;
backoffMultiplier?: number;
activeDidChangeRetries?: number; // Special retry for activeDid changes
};
};
}
export interface UserNotificationConfig {
@@ -397,6 +429,116 @@ export interface PlanSummary {
url?: string;
};
// Phase 2: Detailed TimeSafari Notification Types
export interface TimeSafariNotificationBundle {
offersToPerson?: OffersResponse;
offersToProjects?: OffersToPlansResponse;
projectUpdates?: PlansLastUpdatedResponse;
fetchTimestamp: number;
success: boolean;
error?: string;
metadata?: {
activeDid: string;
fetchDurationMs: number;
cachedResponses: number;
networkResponses: number;
};
}
export interface TimeSafariUserConfig {
activeDid: string; // Required for all operations
lastKnownOfferId?: string;
lastKnownPlanId?: string;
starredPlanIds?: string[];
fetchOffersToPerson?: boolean;
fetchOffersToProjects?: boolean;
fetchProjectUpdates?: boolean;
notificationPreferences?: {
offers: boolean;
projects: boolean;
people: boolean;
items: boolean;
};
}
// Enhanced notification types per specification
export interface TimeSafariOfferNotification {
type: 'offer';
subtype: 'new_to_me' | 'changed_to_me' | 'new_to_projects' | 'changed_to_projects' | 'new_to_favorites' | 'changed_to_favorites';
offer: OfferSummaryRecord;
relevantProjects?: PlanSummary[];
notificationPriority: 'high' | 'medium' | 'low';
}
export interface TimeSafariProjectNotification {
type: 'project';
subtype: 'local_and_new' | 'local_and_changed' | 'with_content_and_new' | 'favorite_and_changed';
project: PlanSummary;
changes?: {
fields: string[];
previousValues?: Record<string, any>;
};
relevantOffers?: OfferSummaryRecord[];
notificationPriority: 'high' | 'medium' | 'low';
}
export interface TimeSafariPersonNotification {
type: 'person';
subtype: 'local_and_new' | 'local_and_changed' | 'with_content_and_new' | 'favorite_and_changed';
personDid: string;
changes?: {
fields: string[];
previousValues?: Record<string, any>;
};
relevantProjects?: PlanSummary[];
notificationPriority: 'high' | 'medium' | 'low';
}
export interface TimeSafariItemNotification {
type: 'item';
subtype: 'local_and_new' | 'local_and_changed' | 'favorite_and_changed';
itemId: string;
changes?: {
fields: string[];
previousValues?: Record<string, any>;
};
relevantContext?: 'project' | 'offer' | 'person';
notificationPriority: 'high' | 'medium' | 'low';
}
// Union type for TimeSafari notifications
export type TimeSafariNotification =
| TimeSafariOfferNotification
| TimeSafariProjectNotification
| TimeSafariPersonNotification
| TimeSafariItemNotification;
// Enhanced ActiveDid Management Events
export interface ActiveDidChangeEventEnhanced extends ActiveDidChangeEvent {
sourceComponent: string; // 'host' | 'plugin' | 'background' | 'sync'
changeReason: 'user_switch' | 'session_expired' | 'background_refresh' | 'setup';
transitionDurationMs?: number;
relatedNotifications?: TimeSafariNotification[];
}
// TimeSafari-specific Platform Configuration
export interface TimeSafariPlatformConfig {
platform: 'android' | 'ios' | 'web' | 'electron';
storageType: 'plugin-managed' | 'host-managed';
syncStrategy: 'immediate' | 'batched' | 'scheduled';
permissions: {
notifications: boolean;
backgroundRefresh: boolean;
networkAccess: boolean;
};
capabilities: {
pushNotifications: boolean;
backgroundTasks: boolean;
identityManagement: boolean;
cryptoSigning: boolean;
};
}
export interface ActiveDidIntegrationConfig {
platform: 'android' | 'ios' | 'web' | 'electron';
storageType: 'plugin-managed' | 'host-managed';