docs: add DailyNotification setup guide and practical example
- Add comprehensive setup guide showing exact configuration for TimeSafari PWA - Provide step-by-step instructions for integrating with existing loadNewStarredProjectChanges() - Include complete working example with all configuration options - Show Vue.js component integration patterns - Add troubleshooting and testing guidance - Demonstrate how to maintain existing interfaces while adding plugin features This provides a practical, copy-paste ready setup for TimeSafari PWA integration.
This commit is contained in:
387
docs/daily-notification-setup-guide.md
Normal file
387
docs/daily-notification-setup-guide.md
Normal file
@@ -0,0 +1,387 @@
|
||||
# DailyNotification Setup Guide for TimeSafari PWA
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Version**: 1.0.0
|
||||
**Created**: 2025-10-08 06:24:57 UTC
|
||||
|
||||
## Overview
|
||||
|
||||
This guide shows you exactly how to set up the DailyNotification plugin in your existing TimeSafari PWA to work with your current `loadNewStarredProjectChanges()` and `getStarredProjectsWithChanges()` methods.
|
||||
|
||||
## Step-by-Step Setup
|
||||
|
||||
### Step 1: Install the Plugin
|
||||
|
||||
```bash
|
||||
# In your TimeSafari PWA project
|
||||
npm install ssh://git@173.199.124.46:222/trent_larson/daily-notification-plugin.git
|
||||
```
|
||||
|
||||
### Step 2: Import the Plugin
|
||||
|
||||
```typescript
|
||||
// In your TimeSafari PWA file (e.g., HomeView.vue or main.ts)
|
||||
import { DailyNotification } from '@timesafari/daily-notification-plugin';
|
||||
import { TimeSafariIntegrationService } from '@timesafari/daily-notification-plugin';
|
||||
```
|
||||
|
||||
### Step 3: Configure the Plugin
|
||||
|
||||
Add this configuration to your existing TimeSafari PWA code:
|
||||
|
||||
```typescript
|
||||
// In your TimeSafari PWA class/component
|
||||
async setupDailyNotification() {
|
||||
try {
|
||||
// Configure the plugin with your existing TimeSafari settings
|
||||
await DailyNotification.configure({
|
||||
// Basic configuration
|
||||
storage: 'tiered',
|
||||
ttlSeconds: 1800,
|
||||
enableETagSupport: true,
|
||||
|
||||
// TimeSafari-specific configuration
|
||||
timesafariConfig: {
|
||||
// Your existing activeDid
|
||||
activeDid: this.activeDid,
|
||||
|
||||
// Your existing API endpoints
|
||||
endpoints: {
|
||||
offersToPerson: `${this.apiServer}/api/v2/offers/person`,
|
||||
offersToPlans: `${this.apiServer}/api/v2/offers/plans`,
|
||||
projectsLastUpdated: `${this.apiServer}/api/v2/report/plansLastUpdatedBetween`
|
||||
},
|
||||
|
||||
// Configure starred projects fetching (matches your existing pattern)
|
||||
starredProjectsConfig: {
|
||||
enabled: true,
|
||||
starredPlanHandleIds: this.starredPlanHandleIds,
|
||||
lastAckedJwtId: this.lastAckedStarredPlanChangesJwtId,
|
||||
fetchInterval: '0 8 * * *', // Daily at 8 AM
|
||||
maxResults: 50,
|
||||
hitLimitHandling: 'warn'
|
||||
}
|
||||
},
|
||||
|
||||
// Network configuration using your existing axios instance
|
||||
networkConfig: {
|
||||
httpClient: this.axios, // Your existing axios instance
|
||||
baseURL: this.apiServer, // Your existing API server
|
||||
timeout: 30000,
|
||||
retryAttempts: 3
|
||||
},
|
||||
|
||||
// Content fetch configuration (replaces your existing method)
|
||||
contentFetch: {
|
||||
enabled: true,
|
||||
schedule: '0 8 * * *', // Daily at 8 AM
|
||||
|
||||
// Your existing request pattern
|
||||
requestConfig: {
|
||||
method: 'POST',
|
||||
url: `${this.apiServer}/api/v2/report/plansLastUpdatedBetween`,
|
||||
headers: {
|
||||
'Authorization': 'Bearer ${jwt}',
|
||||
'X-User-DID': '${activeDid}',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: {
|
||||
planIds: '${starredPlanHandleIds}',
|
||||
afterId: '${lastAckedJwtId}'
|
||||
}
|
||||
},
|
||||
|
||||
// Callbacks that match your existing error handling
|
||||
callbacks: {
|
||||
onSuccess: this.handleStarredProjectsSuccess.bind(this),
|
||||
onError: this.handleStarredProjectsError.bind(this)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize TimeSafari Integration Service
|
||||
this.integrationService = TimeSafariIntegrationService.getInstance();
|
||||
await this.integrationService.initialize({
|
||||
activeDid: this.activeDid,
|
||||
storageAdapter: this.getTimeSafariStorageAdapter(),
|
||||
endorserApiBaseUrl: this.apiServer
|
||||
});
|
||||
|
||||
console.log('DailyNotification setup completed successfully!');
|
||||
|
||||
} catch (error) {
|
||||
console.error('Failed to setup DailyNotification:', error);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4: Replace Your Existing Method
|
||||
|
||||
Replace your existing `loadNewStarredProjectChanges()` method with this enhanced version:
|
||||
|
||||
```typescript
|
||||
// Enhanced version of your existing method
|
||||
async loadNewStarredProjectChanges() {
|
||||
if (this.activeDid && this.starredPlanHandleIds.length > 0) {
|
||||
try {
|
||||
// Use plugin's enhanced fetching with same interface as your existing code
|
||||
const starredProjectChanges = await this.integrationService.getStarredProjectsWithChanges(
|
||||
this.activeDid,
|
||||
this.starredPlanHandleIds,
|
||||
this.lastAckedStarredPlanChangesJwtId
|
||||
);
|
||||
|
||||
// Same handling as your existing code
|
||||
this.numNewStarredProjectChanges = starredProjectChanges.data.length;
|
||||
this.newStarredProjectChangesHitLimit = starredProjectChanges.hitLimit;
|
||||
|
||||
} catch (error) {
|
||||
// Same error handling as your existing code
|
||||
console.warn('[HomeView] Failed to load starred project changes:', error);
|
||||
this.numNewStarredProjectChanges = 0;
|
||||
this.newStarredProjectChangesHitLimit = false;
|
||||
}
|
||||
} else {
|
||||
this.numNewStarredProjectChanges = 0;
|
||||
this.newStarredProjectChangesHitLimit = false;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 5: Add Callback Handlers
|
||||
|
||||
Add these callback handlers that match your existing error handling patterns:
|
||||
|
||||
```typescript
|
||||
// Callback handlers that match your existing error handling
|
||||
async handleStarredProjectsSuccess(data: { data: Array<PlanSummaryAndPreviousClaim>; hitLimit: boolean }) {
|
||||
// Same handling as your existing code
|
||||
this.numNewStarredProjectChanges = data.data.length;
|
||||
this.newStarredProjectChangesHitLimit = data.hitLimit;
|
||||
|
||||
// Update UI (your existing method)
|
||||
this.updateStarredProjectsUI(data);
|
||||
}
|
||||
|
||||
async handleStarredProjectsError(error: Error) {
|
||||
// Same error handling as your existing code
|
||||
console.warn('[HomeView] Failed to load starred project changes:', error);
|
||||
this.numNewStarredProjectChanges = 0;
|
||||
this.newStarredProjectChangesHitLimit = false;
|
||||
}
|
||||
```
|
||||
|
||||
### Step 6: Initialize in Your Component
|
||||
|
||||
Add the setup to your existing TimeSafari PWA component:
|
||||
|
||||
```typescript
|
||||
// In your existing TimeSafari PWA component (e.g., HomeView.vue)
|
||||
export default defineComponent({
|
||||
name: 'HomeView',
|
||||
|
||||
data() {
|
||||
return {
|
||||
// Your existing data
|
||||
activeDid: '',
|
||||
starredPlanHandleIds: [] as string[],
|
||||
lastAckedStarredPlanChangesJwtId: '',
|
||||
numNewStarredProjectChanges: 0,
|
||||
newStarredProjectChangesHitLimit: false,
|
||||
|
||||
// Plugin integration
|
||||
integrationService: null as TimeSafariIntegrationService | null
|
||||
};
|
||||
},
|
||||
|
||||
async mounted() {
|
||||
// Setup DailyNotification when component mounts
|
||||
await this.setupDailyNotification();
|
||||
},
|
||||
|
||||
methods: {
|
||||
// Add the setupDailyNotification method from Step 3
|
||||
async setupDailyNotification() { /* ... */ },
|
||||
|
||||
// Replace your existing loadNewStarredProjectChanges with Step 4 version
|
||||
async loadNewStarredProjectChanges() { /* ... */ },
|
||||
|
||||
// Add callback handlers from Step 5
|
||||
async handleStarredProjectsSuccess(data) { /* ... */ },
|
||||
async handleStarredProjectsError(error) { /* ... */ },
|
||||
|
||||
// Your existing methods (unchanged)
|
||||
updateStarredProjectsUI(data) { /* ... */ },
|
||||
getTimeSafariStorageAdapter() { /* ... */ }
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Complete Example
|
||||
|
||||
Here's a complete example showing how to integrate the plugin into your existing TimeSafari PWA:
|
||||
|
||||
```typescript
|
||||
// Complete integration example
|
||||
import { DailyNotification } from '@timesafari/daily-notification-plugin';
|
||||
import { TimeSafariIntegrationService } from '@timesafari/daily-notification-plugin';
|
||||
|
||||
class TimeSafariHomeView {
|
||||
// Your existing properties
|
||||
activeDid: string = '';
|
||||
starredPlanHandleIds: string[] = [];
|
||||
lastAckedStarredPlanChangesJwtId: string = '';
|
||||
numNewStarredProjectChanges: number = 0;
|
||||
newStarredProjectChangesHitLimit: boolean = false;
|
||||
apiServer: string = 'https://endorser.ch';
|
||||
axios: AxiosInstance;
|
||||
|
||||
// Plugin integration
|
||||
private integrationService: TimeSafariIntegrationService | null = null;
|
||||
|
||||
constructor(axiosInstance: AxiosInstance) {
|
||||
this.axios = axiosInstance;
|
||||
}
|
||||
|
||||
async setupDailyNotification() {
|
||||
await DailyNotification.configure({
|
||||
timesafariConfig: {
|
||||
activeDid: this.activeDid,
|
||||
endpoints: {
|
||||
projectsLastUpdated: `${this.apiServer}/api/v2/report/plansLastUpdatedBetween`
|
||||
},
|
||||
starredProjectsConfig: {
|
||||
enabled: true,
|
||||
starredPlanHandleIds: this.starredPlanHandleIds,
|
||||
lastAckedJwtId: this.lastAckedStarredPlanChangesJwtId,
|
||||
fetchInterval: '0 8 * * *'
|
||||
}
|
||||
},
|
||||
networkConfig: {
|
||||
httpClient: this.axios,
|
||||
baseURL: this.apiServer,
|
||||
timeout: 30000
|
||||
},
|
||||
contentFetch: {
|
||||
enabled: true,
|
||||
schedule: '0 8 * * *',
|
||||
callbacks: {
|
||||
onSuccess: this.handleStarredProjectsSuccess.bind(this),
|
||||
onError: this.handleStarredProjectsError.bind(this)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.integrationService = TimeSafariIntegrationService.getInstance();
|
||||
await this.integrationService.initialize({
|
||||
activeDid: this.activeDid,
|
||||
storageAdapter: this.getTimeSafariStorageAdapter(),
|
||||
endorserApiBaseUrl: this.apiServer
|
||||
});
|
||||
}
|
||||
|
||||
async loadNewStarredProjectChanges() {
|
||||
if (this.activeDid && this.starredPlanHandleIds.length > 0) {
|
||||
try {
|
||||
const starredProjectChanges = await this.integrationService!.getStarredProjectsWithChanges(
|
||||
this.activeDid,
|
||||
this.starredPlanHandleIds,
|
||||
this.lastAckedStarredPlanChangesJwtId
|
||||
);
|
||||
|
||||
this.numNewStarredProjectChanges = starredProjectChanges.data.length;
|
||||
this.newStarredProjectChangesHitLimit = starredProjectChanges.hitLimit;
|
||||
|
||||
} catch (error) {
|
||||
console.warn('[HomeView] Failed to load starred project changes:', error);
|
||||
this.numNewStarredProjectChanges = 0;
|
||||
this.newStarredProjectChangesHitLimit = false;
|
||||
}
|
||||
} else {
|
||||
this.numNewStarredProjectChanges = 0;
|
||||
this.newStarredProjectChangesHitLimit = false;
|
||||
}
|
||||
}
|
||||
|
||||
async handleStarredProjectsSuccess(data: { data: Array<PlanSummaryAndPreviousClaim>; hitLimit: boolean }) {
|
||||
this.numNewStarredProjectChanges = data.data.length;
|
||||
this.newStarredProjectChangesHitLimit = data.hitLimit;
|
||||
this.updateStarredProjectsUI(data);
|
||||
}
|
||||
|
||||
async handleStarredProjectsError(error: Error) {
|
||||
console.warn('[HomeView] Failed to load starred project changes:', error);
|
||||
this.numNewStarredProjectChanges = 0;
|
||||
this.newStarredProjectChangesHitLimit = false;
|
||||
}
|
||||
|
||||
// Your existing methods (unchanged)
|
||||
private updateStarredProjectsUI(data: { data: Array<PlanSummaryAndPreviousClaim>; hitLimit: boolean }) {
|
||||
// Your existing UI update logic
|
||||
}
|
||||
|
||||
private getTimeSafariStorageAdapter() {
|
||||
// Your existing storage adapter
|
||||
return {};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## What You Get
|
||||
|
||||
After following this setup, you'll have:
|
||||
|
||||
✅ **Same Interface**: Your existing `loadNewStarredProjectChanges()` method works exactly the same
|
||||
✅ **Enhanced Features**: Background fetching, structured logging, metrics
|
||||
✅ **Better Error Handling**: Enhanced error handling with retry logic
|
||||
✅ **Performance Improvements**: Caching, batching, and optimization
|
||||
✅ **Observability**: Structured logging with event IDs and metrics
|
||||
✅ **Background Notifications**: Daily notifications with your starred projects data
|
||||
|
||||
## Testing
|
||||
|
||||
Test the integration by calling your existing method:
|
||||
|
||||
```typescript
|
||||
// Test the enhanced method
|
||||
await homeView.loadNewStarredProjectChanges();
|
||||
|
||||
// Check the results (same as before)
|
||||
console.log('New starred project changes:', homeView.numNewStarredProjectChanges);
|
||||
console.log('Hit limit:', homeView.newStarredProjectChangesHitLimit);
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Plugin not found**: Make sure you've installed the plugin correctly
|
||||
2. **Configuration errors**: Check that all required fields are provided
|
||||
3. **Network errors**: Verify your axios instance and API server URL
|
||||
4. **Authentication errors**: Check your JWT token and activeDid
|
||||
|
||||
### Debug Mode
|
||||
|
||||
Enable debug logging to troubleshoot issues:
|
||||
|
||||
```typescript
|
||||
await DailyNotification.configure({
|
||||
logging: {
|
||||
level: 'DEBUG',
|
||||
enableRequestLogging: true,
|
||||
enableResponseLogging: true,
|
||||
enableErrorLogging: true
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Test the integration** with your existing TimeSafari PWA code
|
||||
2. **Compare results** between your existing method and the plugin-enhanced version
|
||||
3. **Gradually migrate** other request methods to use the plugin
|
||||
4. **Leverage advanced features** like background fetching and observability
|
||||
|
||||
---
|
||||
|
||||
**That's it!** Your TimeSafari PWA now has enhanced daily notification capabilities while maintaining the same interface and behavior you're already familiar with.
|
||||
Reference in New Issue
Block a user