Browse Source
- Add detailed host request configuration guide with examples - Add quick reference guide for common configurations - Include TimeSafari-specific configuration patterns - Add platform-specific configuration examples (Android, iOS, Electron) - Include security, authentication, and observability configurations - Add troubleshooting and debugging guidance - Provide Vue.js integration examples These guides show how the TimeSafari PWA host should configure HTTP requests and network settings for the Daily Notification Plugin.master
2 changed files with 1113 additions and 0 deletions
@ -0,0 +1,741 @@ |
|||||
|
# TimeSafari Daily Notification Plugin - Host Request Configuration Guide |
||||
|
|
||||
|
**Author**: Matthew Raymer |
||||
|
**Version**: 1.0.0 |
||||
|
**Created**: 2025-10-08 06:24:57 UTC |
||||
|
|
||||
|
## Overview |
||||
|
|
||||
|
This guide explains how the TimeSafari PWA host application should configure HTTP requests and network settings for the Daily Notification Plugin. The plugin uses a **host-managed request pattern** where the host provides network configuration and the plugin handles the actual requests. |
||||
|
|
||||
|
## Request Configuration Architecture |
||||
|
|
||||
|
### Plugin Request Pattern |
||||
|
``` |
||||
|
Host Application (TimeSafari PWA) |
||||
|
↓ (provides configuration) |
||||
|
Plugin Network Layer |
||||
|
↓ (executes requests) |
||||
|
External APIs (Endorser.ch, etc.) |
||||
|
``` |
||||
|
|
||||
|
### Key Principles |
||||
|
1. **Host-Managed Configuration**: Host provides all network settings |
||||
|
2. **Plugin Execution**: Plugin handles actual HTTP requests |
||||
|
3. **Structured Logging**: All requests are logged with event IDs |
||||
|
4. **Circuit Breaker**: Built-in failure handling and retry logic |
||||
|
5. **ETag Support**: Conditional requests for efficient caching |
||||
|
|
||||
|
## Host Configuration Options |
||||
|
|
||||
|
### 1. Basic Network Configuration |
||||
|
|
||||
|
```typescript |
||||
|
// In TimeSafari PWA main configuration |
||||
|
import { DailyNotification } from '@timesafari/daily-notification-plugin'; |
||||
|
|
||||
|
await DailyNotification.configure({ |
||||
|
// Basic network settings |
||||
|
networkConfig: { |
||||
|
timeout: 30000, // 30 second timeout |
||||
|
retryAttempts: 3, // 3 retry attempts |
||||
|
retryDelay: 1000, // 1 second initial delay |
||||
|
maxConcurrent: 5, // Max 5 concurrent requests |
||||
|
userAgent: 'TimeSafari-PWA/1.0.0' |
||||
|
}, |
||||
|
|
||||
|
// Request headers |
||||
|
headers: { |
||||
|
'Accept': 'application/json', |
||||
|
'Accept-Language': 'en-US,en;q=0.9', |
||||
|
'Cache-Control': 'no-cache' |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### 2. TimeSafari-Specific Configuration |
||||
|
|
||||
|
```typescript |
||||
|
// TimeSafari Endorser.ch API configuration |
||||
|
await DailyNotification.configure({ |
||||
|
timesafariConfig: { |
||||
|
// Required: Active DID for authentication |
||||
|
activeDid: userDid, |
||||
|
|
||||
|
// API endpoints (optional - defaults provided) |
||||
|
endpoints: { |
||||
|
offersToPerson: 'https://endorser.ch/api/v1/offers/person', |
||||
|
offersToPlans: 'https://endorser.ch/api/v1/offers/plans', |
||||
|
projectsLastUpdated: 'https://endorser.ch/api/v1/projects/last-updated' |
||||
|
}, |
||||
|
|
||||
|
// Sync configuration |
||||
|
syncConfig: { |
||||
|
enableParallel: true, // Enable parallel API requests |
||||
|
maxConcurrent: 3, // Max 3 concurrent requests |
||||
|
batchSize: 10 // Batch size for requests |
||||
|
}, |
||||
|
|
||||
|
// Credential configuration |
||||
|
credentialConfig: { |
||||
|
jwtSecret: process.env.JWT_SECRET, |
||||
|
tokenExpirationMinutes: 60, |
||||
|
refreshThresholdMinutes: 10 |
||||
|
}, |
||||
|
|
||||
|
// Error handling policy |
||||
|
errorPolicy: { |
||||
|
maxRetries: 3, |
||||
|
backoffMultiplier: 2, |
||||
|
activeDidChangeRetries: 5 // Special retry for DID changes |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### 3. Content Fetch Configuration |
||||
|
|
||||
|
```typescript |
||||
|
// Configure content fetching |
||||
|
await DailyNotification.configure({ |
||||
|
contentFetch: { |
||||
|
enabled: true, |
||||
|
schedule: '0 8 * * *', // Daily at 8 AM |
||||
|
|
||||
|
// Request configuration |
||||
|
url: 'https://endorser.ch/api/v1/community/updates', |
||||
|
headers: { |
||||
|
'Authorization': `Bearer ${authToken}`, |
||||
|
'X-User-DID': userDid, |
||||
|
'X-Client-Version': '1.0.0' |
||||
|
}, |
||||
|
timeout: 15000, |
||||
|
retryAttempts: 2, |
||||
|
retryDelay: 2000, |
||||
|
|
||||
|
// Callback configuration |
||||
|
callbacks: { |
||||
|
apiService: 'https://api.timesafari.com/notifications/callback', |
||||
|
database: 'local://notification-storage', |
||||
|
reporting: 'https://analytics.timesafari.com/events' |
||||
|
}, |
||||
|
|
||||
|
// Cache policy |
||||
|
cachePolicy: { |
||||
|
maxAge: 3600, // 1 hour cache |
||||
|
staleWhileRevalidate: 1800, // 30 minutes stale |
||||
|
etagSupport: true |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
## Platform-Specific Request Configuration |
||||
|
|
||||
|
### Android Configuration |
||||
|
|
||||
|
```typescript |
||||
|
// Android-specific network configuration |
||||
|
await DailyNotification.configure({ |
||||
|
platform: 'android', |
||||
|
|
||||
|
// Android network settings |
||||
|
androidConfig: { |
||||
|
// WorkManager constraints |
||||
|
workManagerConstraints: { |
||||
|
requiresNetworkType: 'CONNECTED', |
||||
|
requiresBatteryNotLow: false, |
||||
|
requiresCharging: false, |
||||
|
requiresDeviceIdle: false, |
||||
|
requiresStorageNotLow: false |
||||
|
}, |
||||
|
|
||||
|
// Network security |
||||
|
networkSecurityConfig: { |
||||
|
cleartextTrafficPermitted: false, |
||||
|
certificatePinning: true, |
||||
|
trustedCertificates: ['endorser.ch', 'api.timesafari.com'] |
||||
|
}, |
||||
|
|
||||
|
// Request configuration |
||||
|
requestConfig: { |
||||
|
connectTimeout: 30000, |
||||
|
readTimeout: 30000, |
||||
|
writeTimeout: 30000, |
||||
|
followRedirects: true, |
||||
|
followSslRedirects: true |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### iOS Configuration |
||||
|
|
||||
|
```typescript |
||||
|
// iOS-specific network configuration |
||||
|
await DailyNotification.configure({ |
||||
|
platform: 'ios', |
||||
|
|
||||
|
// iOS network settings |
||||
|
iosConfig: { |
||||
|
// Background task configuration |
||||
|
backgroundTasks: { |
||||
|
'com.timesafari.daily-notification-fetch': { |
||||
|
identifier: 'com.timesafari.daily-notification-fetch', |
||||
|
requiresNetworkConnectivity: true, |
||||
|
requiresExternalPower: false, |
||||
|
requiresDeviceIdle: false |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// URL session configuration |
||||
|
urlSessionConfig: { |
||||
|
timeoutIntervalForRequest: 30, |
||||
|
timeoutIntervalForResource: 60, |
||||
|
allowsCellularAccess: true, |
||||
|
allowsConstrainedNetworkAccess: true, |
||||
|
allowsExpensiveNetworkAccess: true |
||||
|
}, |
||||
|
|
||||
|
// App transport security |
||||
|
atsConfig: { |
||||
|
allowsArbitraryLoads: false, |
||||
|
allowsLocalNetworking: false, |
||||
|
exceptionDomains: { |
||||
|
'endorser.ch': { |
||||
|
nstExceptionAllowsInsecureHTTPLoads: false, |
||||
|
nstExceptionMinimumTLSVersion: 'TLSv1.2' |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### Electron Configuration |
||||
|
|
||||
|
```typescript |
||||
|
// Electron-specific network configuration |
||||
|
await DailyNotification.configure({ |
||||
|
platform: 'electron', |
||||
|
|
||||
|
// Electron network settings |
||||
|
electronConfig: { |
||||
|
// Session configuration |
||||
|
sessionConfig: { |
||||
|
userAgent: 'TimeSafari-Desktop/1.0.0', |
||||
|
acceptLanguages: ['en-US', 'en'], |
||||
|
cacheEnabled: true, |
||||
|
cacheSize: 100 * 1024 * 1024 // 100MB cache |
||||
|
}, |
||||
|
|
||||
|
// Request configuration |
||||
|
requestConfig: { |
||||
|
timeout: 30000, |
||||
|
maxRedirects: 5, |
||||
|
followRedirects: true, |
||||
|
validateSSL: true |
||||
|
}, |
||||
|
|
||||
|
// Proxy configuration (if needed) |
||||
|
proxyConfig: { |
||||
|
enabled: false, |
||||
|
type: 'http', |
||||
|
host: '', |
||||
|
port: 0, |
||||
|
username: '', |
||||
|
password: '' |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
## Advanced Request Configuration |
||||
|
|
||||
|
### 1. Circuit Breaker Configuration |
||||
|
|
||||
|
```typescript |
||||
|
// Circuit breaker for fault tolerance |
||||
|
await DailyNotification.configure({ |
||||
|
circuitBreaker: { |
||||
|
failureThreshold: 5, // Open after 5 failures |
||||
|
recoveryTimeout: 30000, // 30 second recovery timeout |
||||
|
monitoringPeriod: 60000 // 1 minute monitoring period |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### 2. Rate Limiting Configuration |
||||
|
|
||||
|
```typescript |
||||
|
// Rate limiting configuration |
||||
|
await DailyNotification.configure({ |
||||
|
rateLimiting: { |
||||
|
maxRequestsPerMinute: 30, |
||||
|
maxRequestsPerHour: 1000, |
||||
|
burstLimit: 10, |
||||
|
backoffStrategy: 'exponential', |
||||
|
jitterEnabled: true |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### 3. Authentication Configuration |
||||
|
|
||||
|
```typescript |
||||
|
// Authentication configuration |
||||
|
await DailyNotification.configure({ |
||||
|
authentication: { |
||||
|
// JWT configuration |
||||
|
jwt: { |
||||
|
secret: process.env.JWT_SECRET, |
||||
|
algorithm: 'HS256', |
||||
|
expirationMinutes: 60, |
||||
|
refreshThresholdMinutes: 10 |
||||
|
}, |
||||
|
|
||||
|
// API key configuration |
||||
|
apiKey: { |
||||
|
header: 'X-API-Key', |
||||
|
value: process.env.API_KEY |
||||
|
}, |
||||
|
|
||||
|
// OAuth configuration |
||||
|
oauth: { |
||||
|
clientId: process.env.OAUTH_CLIENT_ID, |
||||
|
clientSecret: process.env.OAUTH_CLIENT_SECRET, |
||||
|
tokenEndpoint: 'https://auth.timesafari.com/oauth/token', |
||||
|
scope: 'notifications:read notifications:write' |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
## Request Monitoring and Observability |
||||
|
|
||||
|
### 1. Structured Logging Configuration |
||||
|
|
||||
|
```typescript |
||||
|
// Configure structured logging |
||||
|
await DailyNotification.configure({ |
||||
|
logging: { |
||||
|
level: 'INFO', |
||||
|
enableRequestLogging: true, |
||||
|
enableResponseLogging: true, |
||||
|
enableErrorLogging: true, |
||||
|
enablePerformanceLogging: true, |
||||
|
|
||||
|
// Log formatting |
||||
|
logFormat: 'json', |
||||
|
includeHeaders: false, // Don't log sensitive headers |
||||
|
includeBody: false, // Don't log request/response bodies |
||||
|
redactSensitiveData: true |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### 2. Metrics Configuration |
||||
|
|
||||
|
```typescript |
||||
|
// Configure metrics collection |
||||
|
await DailyNotification.configure({ |
||||
|
metrics: { |
||||
|
enabled: true, |
||||
|
collectionInterval: 60000, // 1 minute |
||||
|
|
||||
|
// Metrics to collect |
||||
|
requestMetrics: { |
||||
|
count: true, |
||||
|
duration: true, |
||||
|
statusCodes: true, |
||||
|
errorRates: true |
||||
|
}, |
||||
|
|
||||
|
// Performance metrics |
||||
|
performanceMetrics: { |
||||
|
cacheHitRate: true, |
||||
|
networkLatency: true, |
||||
|
retryCount: true, |
||||
|
circuitBreakerState: true |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
## Error Handling Configuration |
||||
|
|
||||
|
### 1. Retry Configuration |
||||
|
|
||||
|
```typescript |
||||
|
// Retry configuration |
||||
|
await DailyNotification.configure({ |
||||
|
retry: { |
||||
|
// Exponential backoff |
||||
|
strategy: 'exponential', |
||||
|
initialDelay: 1000, // 1 second |
||||
|
maxDelay: 30000, // 30 seconds |
||||
|
multiplier: 2, |
||||
|
jitter: true, |
||||
|
|
||||
|
// Retry conditions |
||||
|
retryOn: { |
||||
|
networkErrors: true, |
||||
|
timeoutErrors: true, |
||||
|
serverErrors: true, // 5xx errors |
||||
|
clientErrors: false // Don't retry 4xx errors |
||||
|
}, |
||||
|
|
||||
|
// Max retries per request type |
||||
|
maxRetries: { |
||||
|
contentFetch: 3, |
||||
|
notificationDelivery: 2, |
||||
|
callbackDelivery: 1 |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### 2. Fallback Configuration |
||||
|
|
||||
|
```typescript |
||||
|
// Fallback configuration |
||||
|
await DailyNotification.configure({ |
||||
|
fallback: { |
||||
|
// Content fallbacks |
||||
|
contentFallbacks: [ |
||||
|
{ |
||||
|
condition: 'network_unavailable', |
||||
|
action: 'use_cached_content', |
||||
|
maxAge: 3600 // 1 hour |
||||
|
}, |
||||
|
{ |
||||
|
condition: 'api_error', |
||||
|
action: 'use_emergency_content', |
||||
|
content: { |
||||
|
title: 'TimeSafari Community Update', |
||||
|
body: 'Check back later for the latest updates!' |
||||
|
} |
||||
|
} |
||||
|
], |
||||
|
|
||||
|
// Notification fallbacks |
||||
|
notificationFallbacks: [ |
||||
|
{ |
||||
|
condition: 'permission_denied', |
||||
|
action: 'show_in_app_notification' |
||||
|
}, |
||||
|
{ |
||||
|
condition: 'platform_unsupported', |
||||
|
action: 'log_warning' |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
## Security Configuration |
||||
|
|
||||
|
### 1. SSL/TLS Configuration |
||||
|
|
||||
|
```typescript |
||||
|
// SSL/TLS configuration |
||||
|
await DailyNotification.configure({ |
||||
|
security: { |
||||
|
// Certificate pinning |
||||
|
certificatePinning: { |
||||
|
enabled: true, |
||||
|
pins: [ |
||||
|
{ |
||||
|
hostname: 'endorser.ch', |
||||
|
pins: [ |
||||
|
'sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=', |
||||
|
'sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=' |
||||
|
] |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
|
||||
|
// TLS configuration |
||||
|
tls: { |
||||
|
minVersion: '1.2', |
||||
|
maxVersion: '1.3', |
||||
|
cipherSuites: [ |
||||
|
'TLS_AES_256_GCM_SHA384', |
||||
|
'TLS_CHACHA20_POLY1305_SHA256', |
||||
|
'TLS_AES_128_GCM_SHA256' |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### 2. Data Protection Configuration |
||||
|
|
||||
|
```typescript |
||||
|
// Data protection configuration |
||||
|
await DailyNotification.configure({ |
||||
|
dataProtection: { |
||||
|
// Encryption at rest |
||||
|
encryption: { |
||||
|
enabled: true, |
||||
|
algorithm: 'AES-256-GCM', |
||||
|
keyDerivation: 'PBKDF2' |
||||
|
}, |
||||
|
|
||||
|
// Data redaction |
||||
|
redaction: { |
||||
|
enabled: true, |
||||
|
patterns: [ |
||||
|
'password', |
||||
|
'token', |
||||
|
'secret', |
||||
|
'key', |
||||
|
'authorization' |
||||
|
] |
||||
|
}, |
||||
|
|
||||
|
// Data retention |
||||
|
retention: { |
||||
|
maxAge: 30 * 24 * 60 * 60 * 1000, // 30 days |
||||
|
autoCleanup: true |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
## Integration Examples |
||||
|
|
||||
|
### 1. TimeSafari PWA Integration |
||||
|
|
||||
|
```typescript |
||||
|
// In TimeSafari PWA main.ts |
||||
|
import { DailyNotification } from '@timesafari/daily-notification-plugin'; |
||||
|
import { TimeSafariIntegrationService } from '@timesafari/daily-notification-plugin'; |
||||
|
|
||||
|
// Initialize with TimeSafari configuration |
||||
|
const initializeDailyNotifications = async () => { |
||||
|
try { |
||||
|
// Configure plugin with TimeSafari settings |
||||
|
await DailyNotification.configure({ |
||||
|
// Basic configuration |
||||
|
storage: 'tiered', |
||||
|
ttlSeconds: 1800, |
||||
|
enableETagSupport: true, |
||||
|
|
||||
|
// TimeSafari-specific configuration |
||||
|
timesafariConfig: { |
||||
|
activeDid: userDid, |
||||
|
endpoints: { |
||||
|
offersToPerson: 'https://endorser.ch/api/v1/offers/person', |
||||
|
offersToPlans: 'https://endorser.ch/api/v1/offers/plans' |
||||
|
}, |
||||
|
syncConfig: { |
||||
|
enableParallel: true, |
||||
|
maxConcurrent: 3, |
||||
|
batchSize: 10 |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// Network configuration |
||||
|
networkConfig: { |
||||
|
timeout: 30000, |
||||
|
retryAttempts: 3, |
||||
|
retryDelay: 1000, |
||||
|
maxConcurrent: 5 |
||||
|
}, |
||||
|
|
||||
|
// Authentication |
||||
|
authentication: { |
||||
|
jwt: { |
||||
|
secret: process.env.JWT_SECRET, |
||||
|
algorithm: 'HS256', |
||||
|
expirationMinutes: 60 |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// Observability |
||||
|
logging: { |
||||
|
level: 'INFO', |
||||
|
enableRequestLogging: true, |
||||
|
redactSensitiveData: true |
||||
|
}, |
||||
|
|
||||
|
// Security |
||||
|
security: { |
||||
|
certificatePinning: { |
||||
|
enabled: true, |
||||
|
pins: [ |
||||
|
{ |
||||
|
hostname: 'endorser.ch', |
||||
|
pins: ['sha256/...'] |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
// Initialize TimeSafari integration |
||||
|
const integrationService = TimeSafariIntegrationService.getInstance(); |
||||
|
await integrationService.initialize({ |
||||
|
activeDid: userDid, |
||||
|
storageAdapter: timeSafariStorageAdapter, |
||||
|
endorserApiBaseUrl: 'https://endorser.ch/api/v1' |
||||
|
}); |
||||
|
|
||||
|
console.log('Daily notifications configured successfully'); |
||||
|
|
||||
|
} catch (error) { |
||||
|
console.error('Failed to configure daily notifications:', error); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
// Initialize on app startup |
||||
|
initializeDailyNotifications(); |
||||
|
``` |
||||
|
|
||||
|
### 2. Vue.js Component Integration |
||||
|
|
||||
|
```typescript |
||||
|
// In TimeSafari PWA Vue component |
||||
|
import { defineComponent } from 'vue'; |
||||
|
import { DailyNotification } from '@timesafari/daily-notification-plugin'; |
||||
|
|
||||
|
export default defineComponent({ |
||||
|
name: 'DailyNotificationSettings', |
||||
|
|
||||
|
async mounted() { |
||||
|
// Configure notifications for this component |
||||
|
await DailyNotification.configure({ |
||||
|
// Component-specific configuration |
||||
|
contentFetch: { |
||||
|
enabled: true, |
||||
|
schedule: '0 9 * * *', // 9 AM daily |
||||
|
url: 'https://endorser.ch/api/v1/community/updates', |
||||
|
headers: { |
||||
|
'Authorization': `Bearer ${this.authToken}`, |
||||
|
'X-User-DID': this.userDid |
||||
|
}, |
||||
|
callbacks: { |
||||
|
onSuccess: async (data) => { |
||||
|
// Handle successful fetch |
||||
|
this.updateNotificationContent(data); |
||||
|
}, |
||||
|
onError: async (error) => { |
||||
|
// Handle fetch error |
||||
|
this.handleNotificationError(error); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
async updateNotificationContent(data: Record<string, unknown>) { |
||||
|
// Update UI with new content |
||||
|
this.notificationData = data; |
||||
|
}, |
||||
|
|
||||
|
async handleNotificationError(error: Error) { |
||||
|
// Handle error in UI |
||||
|
this.showError(error.message); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
## Troubleshooting |
||||
|
|
||||
|
### Common Configuration Issues |
||||
|
|
||||
|
#### 1. Network Timeout Issues |
||||
|
```typescript |
||||
|
// Increase timeout for slow networks |
||||
|
await DailyNotification.configure({ |
||||
|
networkConfig: { |
||||
|
timeout: 60000, // 60 seconds |
||||
|
retryAttempts: 5, |
||||
|
retryDelay: 2000 |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
#### 2. Authentication Issues |
||||
|
```typescript |
||||
|
// Debug authentication |
||||
|
await DailyNotification.configure({ |
||||
|
logging: { |
||||
|
level: 'DEBUG', |
||||
|
enableRequestLogging: true, |
||||
|
includeHeaders: true // Temporarily enable for debugging |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
#### 3. Certificate Issues |
||||
|
```typescript |
||||
|
// Disable certificate pinning for development |
||||
|
await DailyNotification.configure({ |
||||
|
security: { |
||||
|
certificatePinning: { |
||||
|
enabled: false // Only for development |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### Debugging Request Issues |
||||
|
|
||||
|
#### 1. Enable Debug Logging |
||||
|
```typescript |
||||
|
// Enable comprehensive logging |
||||
|
await DailyNotification.configure({ |
||||
|
logging: { |
||||
|
level: 'DEBUG', |
||||
|
enableRequestLogging: true, |
||||
|
enableResponseLogging: true, |
||||
|
enableErrorLogging: true, |
||||
|
enablePerformanceLogging: true |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
#### 2. Monitor Request Metrics |
||||
|
```typescript |
||||
|
// Get request statistics |
||||
|
const stats = await DailyNotification.getRequestStats(); |
||||
|
console.log('Request Statistics:', stats); |
||||
|
|
||||
|
// Get error statistics |
||||
|
const errors = await DailyNotification.getErrorStats(); |
||||
|
console.log('Error Statistics:', errors); |
||||
|
``` |
||||
|
|
||||
|
## Best Practices |
||||
|
|
||||
|
### 1. Configuration Management |
||||
|
- **Environment Variables**: Use environment variables for sensitive data |
||||
|
- **Configuration Validation**: Validate configuration on startup |
||||
|
- **Graceful Degradation**: Provide fallbacks for missing configuration |
||||
|
- **Configuration Updates**: Support runtime configuration updates |
||||
|
|
||||
|
### 2. Security Best Practices |
||||
|
- **Certificate Pinning**: Enable for production environments |
||||
|
- **Data Redaction**: Always redact sensitive data in logs |
||||
|
- **Token Management**: Use secure token storage and rotation |
||||
|
- **Network Security**: Use HTTPS for all requests |
||||
|
|
||||
|
### 3. Performance Best Practices |
||||
|
- **Connection Pooling**: Reuse HTTP connections |
||||
|
- **Request Batching**: Batch multiple requests when possible |
||||
|
- **Caching**: Use ETag support for efficient caching |
||||
|
- **Rate Limiting**: Implement appropriate rate limits |
||||
|
|
||||
|
### 4. Monitoring Best Practices |
||||
|
- **Structured Logging**: Use structured logs with event IDs |
||||
|
- **Metrics Collection**: Collect relevant performance metrics |
||||
|
- **Error Tracking**: Track and analyze error patterns |
||||
|
- **Health Checks**: Implement health check endpoints |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
**Note**: This configuration guide should be updated as the plugin evolves. Regular review and updates are recommended to ensure accuracy and completeness. |
@ -0,0 +1,372 @@ |
|||||
|
# TimeSafari Daily Notification Plugin - Request Configuration Quick Reference |
||||
|
|
||||
|
**Author**: Matthew Raymer |
||||
|
**Version**: 1.0.0 |
||||
|
**Created**: 2025-10-08 06:24:57 UTC |
||||
|
|
||||
|
## Quick Setup for TimeSafari PWA |
||||
|
|
||||
|
### Basic Configuration |
||||
|
```typescript |
||||
|
import { DailyNotification } from '@timesafari/daily-notification-plugin'; |
||||
|
|
||||
|
await DailyNotification.configure({ |
||||
|
// Required: Active DID for TimeSafari integration |
||||
|
timesafariConfig: { |
||||
|
activeDid: userDid |
||||
|
}, |
||||
|
|
||||
|
// Basic network settings |
||||
|
networkConfig: { |
||||
|
timeout: 30000, |
||||
|
retryAttempts: 3, |
||||
|
maxConcurrent: 5 |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### Complete TimeSafari Configuration |
||||
|
```typescript |
||||
|
await DailyNotification.configure({ |
||||
|
// TimeSafari integration |
||||
|
timesafariConfig: { |
||||
|
activeDid: userDid, |
||||
|
endpoints: { |
||||
|
offersToPerson: 'https://endorser.ch/api/v1/offers/person', |
||||
|
offersToPlans: 'https://endorser.ch/api/v1/offers/plans' |
||||
|
}, |
||||
|
syncConfig: { |
||||
|
enableParallel: true, |
||||
|
maxConcurrent: 3, |
||||
|
batchSize: 10 |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// Network configuration |
||||
|
networkConfig: { |
||||
|
timeout: 30000, |
||||
|
retryAttempts: 3, |
||||
|
retryDelay: 1000, |
||||
|
maxConcurrent: 5, |
||||
|
userAgent: 'TimeSafari-PWA/1.0.0' |
||||
|
}, |
||||
|
|
||||
|
// Authentication |
||||
|
authentication: { |
||||
|
jwt: { |
||||
|
secret: process.env.JWT_SECRET, |
||||
|
algorithm: 'HS256', |
||||
|
expirationMinutes: 60 |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// Observability |
||||
|
logging: { |
||||
|
level: 'INFO', |
||||
|
enableRequestLogging: true, |
||||
|
redactSensitiveData: true |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
## Platform-Specific Quick Configs |
||||
|
|
||||
|
### Android |
||||
|
```typescript |
||||
|
await DailyNotification.configure({ |
||||
|
platform: 'android', |
||||
|
androidConfig: { |
||||
|
workManagerConstraints: { |
||||
|
requiresNetworkType: 'CONNECTED', |
||||
|
requiresBatteryNotLow: false |
||||
|
}, |
||||
|
requestConfig: { |
||||
|
connectTimeout: 30000, |
||||
|
readTimeout: 30000 |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### iOS |
||||
|
```typescript |
||||
|
await DailyNotification.configure({ |
||||
|
platform: 'ios', |
||||
|
iosConfig: { |
||||
|
backgroundTasks: { |
||||
|
'com.timesafari.daily-notification-fetch': { |
||||
|
requiresNetworkConnectivity: true |
||||
|
} |
||||
|
}, |
||||
|
urlSessionConfig: { |
||||
|
timeoutIntervalForRequest: 30, |
||||
|
allowsCellularAccess: true |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### Electron |
||||
|
```typescript |
||||
|
await DailyNotification.configure({ |
||||
|
platform: 'electron', |
||||
|
electronConfig: { |
||||
|
sessionConfig: { |
||||
|
userAgent: 'TimeSafari-Desktop/1.0.0', |
||||
|
cacheEnabled: true |
||||
|
}, |
||||
|
requestConfig: { |
||||
|
timeout: 30000, |
||||
|
maxRedirects: 5 |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
## Common Request Patterns |
||||
|
|
||||
|
### 1. Content Fetching |
||||
|
```typescript |
||||
|
await DailyNotification.configure({ |
||||
|
contentFetch: { |
||||
|
enabled: true, |
||||
|
schedule: '0 8 * * *', // Daily at 8 AM |
||||
|
url: 'https://endorser.ch/api/v1/community/updates', |
||||
|
headers: { |
||||
|
'Authorization': `Bearer ${authToken}`, |
||||
|
'X-User-DID': userDid |
||||
|
}, |
||||
|
timeout: 15000, |
||||
|
retryAttempts: 2 |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### 2. Callback Configuration |
||||
|
```typescript |
||||
|
await DailyNotification.configure({ |
||||
|
callbacks: { |
||||
|
apiService: 'https://api.timesafari.com/notifications/callback', |
||||
|
database: 'local://notification-storage', |
||||
|
reporting: 'https://analytics.timesafari.com/events', |
||||
|
onSuccess: async (data) => { |
||||
|
// Handle successful fetch |
||||
|
console.log('Content fetched:', data); |
||||
|
}, |
||||
|
onError: async (error) => { |
||||
|
// Handle error |
||||
|
console.error('Fetch error:', error); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### 3. Circuit Breaker |
||||
|
```typescript |
||||
|
await DailyNotification.configure({ |
||||
|
circuitBreaker: { |
||||
|
failureThreshold: 5, |
||||
|
recoveryTimeout: 30000, |
||||
|
monitoringPeriod: 60000 |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### 4. Rate Limiting |
||||
|
```typescript |
||||
|
await DailyNotification.configure({ |
||||
|
rateLimiting: { |
||||
|
maxRequestsPerMinute: 30, |
||||
|
maxRequestsPerHour: 1000, |
||||
|
burstLimit: 10, |
||||
|
backoffStrategy: 'exponential' |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
## Security Quick Configs |
||||
|
|
||||
|
### Certificate Pinning |
||||
|
```typescript |
||||
|
await DailyNotification.configure({ |
||||
|
security: { |
||||
|
certificatePinning: { |
||||
|
enabled: true, |
||||
|
pins: [ |
||||
|
{ |
||||
|
hostname: 'endorser.ch', |
||||
|
pins: ['sha256/YOUR_PIN_HERE'] |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### Data Protection |
||||
|
```typescript |
||||
|
await DailyNotification.configure({ |
||||
|
dataProtection: { |
||||
|
encryption: { |
||||
|
enabled: true, |
||||
|
algorithm: 'AES-256-GCM' |
||||
|
}, |
||||
|
redaction: { |
||||
|
enabled: true, |
||||
|
patterns: ['password', 'token', 'secret'] |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
## Debugging Configs |
||||
|
|
||||
|
### Enable Debug Logging |
||||
|
```typescript |
||||
|
await DailyNotification.configure({ |
||||
|
logging: { |
||||
|
level: 'DEBUG', |
||||
|
enableRequestLogging: true, |
||||
|
enableResponseLogging: true, |
||||
|
enableErrorLogging: true |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### Disable Security for Development |
||||
|
```typescript |
||||
|
await DailyNotification.configure({ |
||||
|
security: { |
||||
|
certificatePinning: { |
||||
|
enabled: false // Only for development |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
## Error Handling Quick Configs |
||||
|
|
||||
|
### Retry Configuration |
||||
|
```typescript |
||||
|
await DailyNotification.configure({ |
||||
|
retry: { |
||||
|
strategy: 'exponential', |
||||
|
initialDelay: 1000, |
||||
|
maxDelay: 30000, |
||||
|
multiplier: 2, |
||||
|
maxRetries: { |
||||
|
contentFetch: 3, |
||||
|
notificationDelivery: 2 |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### Fallback Configuration |
||||
|
```typescript |
||||
|
await DailyNotification.configure({ |
||||
|
fallback: { |
||||
|
contentFallbacks: [ |
||||
|
{ |
||||
|
condition: 'network_unavailable', |
||||
|
action: 'use_cached_content', |
||||
|
maxAge: 3600 |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
## Vue.js Integration Example |
||||
|
|
||||
|
```typescript |
||||
|
// In your Vue component |
||||
|
import { defineComponent } from 'vue'; |
||||
|
import { DailyNotification } from '@timesafari/daily-notification-plugin'; |
||||
|
|
||||
|
export default defineComponent({ |
||||
|
name: 'NotificationSettings', |
||||
|
|
||||
|
async mounted() { |
||||
|
await DailyNotification.configure({ |
||||
|
timesafariConfig: { |
||||
|
activeDid: this.userDid |
||||
|
}, |
||||
|
contentFetch: { |
||||
|
enabled: true, |
||||
|
schedule: '0 9 * * *', |
||||
|
callbacks: { |
||||
|
onSuccess: this.handleSuccess, |
||||
|
onError: this.handleError |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
handleSuccess(data: Record<string, unknown>) { |
||||
|
this.notificationData = data; |
||||
|
}, |
||||
|
|
||||
|
handleError(error: Error) { |
||||
|
this.showError(error.message); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
## Environment Variables |
||||
|
|
||||
|
### Required Environment Variables |
||||
|
```bash |
||||
|
# TimeSafari configuration |
||||
|
JWT_SECRET=your_jwt_secret_here |
||||
|
API_KEY=your_api_key_here |
||||
|
|
||||
|
# Optional configuration |
||||
|
OAUTH_CLIENT_ID=your_oauth_client_id |
||||
|
OAUTH_CLIENT_SECRET=your_oauth_client_secret |
||||
|
``` |
||||
|
|
||||
|
### Development Environment |
||||
|
```bash |
||||
|
# Development settings |
||||
|
NODE_ENV=development |
||||
|
LOG_LEVEL=DEBUG |
||||
|
CERTIFICATE_PINNING=false |
||||
|
``` |
||||
|
|
||||
|
## Common Issues and Solutions |
||||
|
|
||||
|
### Issue: Network Timeout |
||||
|
**Solution**: Increase timeout |
||||
|
```typescript |
||||
|
networkConfig: { |
||||
|
timeout: 60000 // 60 seconds |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
### Issue: Authentication Errors |
||||
|
**Solution**: Check JWT configuration |
||||
|
```typescript |
||||
|
authentication: { |
||||
|
jwt: { |
||||
|
secret: process.env.JWT_SECRET, |
||||
|
algorithm: 'HS256' |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
### Issue: Certificate Errors |
||||
|
**Solution**: Disable pinning for development |
||||
|
```typescript |
||||
|
security: { |
||||
|
certificatePinning: { |
||||
|
enabled: false |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
**For detailed configuration options, see**: `docs/host-request-configuration.md` |
Loading…
Reference in new issue