|
@ -26,7 +26,7 @@ import { |
|
|
// Enhanced ConfigLoader for Phase 4
|
|
|
// Enhanced ConfigLoader for Phase 4
|
|
|
class ConfigLoader { |
|
|
class ConfigLoader { |
|
|
private static instance: ConfigLoader; |
|
|
private static instance: ConfigLoader; |
|
|
private config: any; |
|
|
private config: Record<string, unknown>; |
|
|
|
|
|
|
|
|
static getInstance(): ConfigLoader { |
|
|
static getInstance(): ConfigLoader { |
|
|
if (!this.instance) { |
|
|
if (!this.instance) { |
|
@ -74,7 +74,7 @@ class ConfigLoader { |
|
|
}; |
|
|
}; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
getConfig(): any { |
|
|
getConfig(): Record<string, unknown> { |
|
|
return this.config; |
|
|
return this.config; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -121,7 +121,7 @@ class ConfigLoader { |
|
|
}; |
|
|
}; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
getAuthHeaders(): any { |
|
|
getAuthHeaders(): Record<string, string> { |
|
|
return { |
|
|
return { |
|
|
'Authorization': `Bearer ${this.config.endorser.apiKey}`, |
|
|
'Authorization': `Bearer ${this.config.endorser.apiKey}`, |
|
|
'Content-Type': 'application/json' |
|
|
'Content-Type': 'application/json' |
|
@ -130,17 +130,17 @@ class ConfigLoader { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
class MockDailyNotificationService { |
|
|
class MockDailyNotificationService { |
|
|
constructor(config: any) { |
|
|
constructor(config: Record<string, unknown>) { |
|
|
this.config = config; |
|
|
this.config = config; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private config: any; |
|
|
private config: Record<string, unknown>; |
|
|
|
|
|
|
|
|
async initialize(): Promise<void> { |
|
|
async initialize(): Promise<void> { |
|
|
console.log('Mock notification service initialized'); |
|
|
console.log('Mock notification service initialized'); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
async scheduleDualNotification(config: any): Promise<void> { |
|
|
async scheduleDualNotification(config: Record<string, unknown>): Promise<void> { |
|
|
console.log('Mock dual notification scheduled:', config); |
|
|
console.log('Mock dual notification scheduled:', config); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -161,15 +161,15 @@ class TestLogger { |
|
|
console.log('Mock logger initialized with level:', level); |
|
|
console.log('Mock logger initialized with level:', level); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
info(message: string, data?: any) { |
|
|
info(message: string, data?: Record<string, unknown>) { |
|
|
console.log(`[INFO] ${message}`, data); |
|
|
console.log(`[INFO] ${message}`, data); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
error(message: string, data?: any) { |
|
|
error(message: string, data?: Record<string, unknown>) { |
|
|
console.error(`[ERROR] ${message}`, data); |
|
|
console.error(`[ERROR] ${message}`, data); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
debug(message: string, data?: any) { |
|
|
debug(message: string, data?: Record<string, unknown>) { |
|
|
console.log(`[DEBUG] ${message}`, data); |
|
|
console.log(`[DEBUG] ${message}`, data); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -195,7 +195,7 @@ class PermissionManager { |
|
|
this.renderStatus(mockStatus); |
|
|
this.renderStatus(mockStatus); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private renderStatus(status: any): void { |
|
|
private renderStatus(status: Record<string, unknown>): void { |
|
|
const statusClass = status.granted ? 'status-granted' : 'status-denied'; |
|
|
const statusClass = status.granted ? 'status-granted' : 'status-denied'; |
|
|
const statusText = status.granted ? 'Granted' : 'Denied'; |
|
|
const statusText = status.granted ? 'Granted' : 'Denied'; |
|
|
|
|
|
|
|
@ -674,11 +674,11 @@ class TimeSafariAndroidTestApp { |
|
|
retryAttempts: 3, |
|
|
retryAttempts: 3, |
|
|
retryDelay: 5000, |
|
|
retryDelay: 5000, |
|
|
callbacks: { |
|
|
callbacks: { |
|
|
onSuccess: async (data: any) => { |
|
|
onSuccess: async (data: Record<string, unknown>) => { |
|
|
this.log('✅ Content fetch successful', data); |
|
|
this.log('✅ Content fetch successful', data); |
|
|
await this.processEndorserNotificationBundle(data); |
|
|
await this.processEndorserNotificationBundle(data); |
|
|
}, |
|
|
}, |
|
|
onError: async (error: any) => { |
|
|
onError: async (error: Record<string, unknown>) => { |
|
|
this.log('❌ Content fetch failed', error); |
|
|
this.log('❌ Content fetch failed', error); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -769,25 +769,25 @@ class TimeSafariAndroidTestApp { |
|
|
// const config = this.configLoader.getConfig();
|
|
|
// const config = this.configLoader.getConfig();
|
|
|
|
|
|
|
|
|
// Register offers callback
|
|
|
// Register offers callback
|
|
|
await this.notificationService.registerCallback('offers', async (event: any) => { |
|
|
await this.notificationService.registerCallback('offers', async (event: Record<string, unknown>) => { |
|
|
this.log('📨 Offers callback triggered', event); |
|
|
this.log('📨 Offers callback triggered', event); |
|
|
await this.handleOffersNotification(event); |
|
|
await this.handleOffersNotification(event); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
// Register projects callback
|
|
|
// Register projects callback
|
|
|
await this.notificationService.registerCallback('projects', async (event: any) => { |
|
|
await this.notificationService.registerCallback('projects', async (event: Record<string, unknown>) => { |
|
|
this.log('📨 Projects callback triggered', event); |
|
|
this.log('📨 Projects callback triggered', event); |
|
|
await this.handleProjectsNotification(event); |
|
|
await this.handleProjectsNotification(event); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
// Register people callback
|
|
|
// Register people callback
|
|
|
await this.notificationService.registerCallback('people', async (event: any) => { |
|
|
await this.notificationService.registerCallback('people', async (event: Record<string, unknown>) => { |
|
|
this.log('📨 People callback triggered', event); |
|
|
this.log('📨 People callback triggered', event); |
|
|
await this.handlePeopleNotification(event); |
|
|
await this.handlePeopleNotification(event); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
// Register items callback
|
|
|
// Register items callback
|
|
|
await this.notificationService.registerCallback('items', async (event: any) => { |
|
|
await this.notificationService.registerCallback('items', async (event: Record<string, unknown>) => { |
|
|
this.log('📨 Items callback triggered', event); |
|
|
this.log('📨 Items callback triggered', event); |
|
|
await this.handleItemsNotification(event); |
|
|
await this.handleItemsNotification(event); |
|
|
}); |
|
|
}); |
|
@ -837,7 +837,7 @@ class TimeSafariAndroidTestApp { |
|
|
/** |
|
|
/** |
|
|
* Process Endorser.ch notification bundle using parallel API requests |
|
|
* Process Endorser.ch notification bundle using parallel API requests |
|
|
*/ |
|
|
*/ |
|
|
private async processEndorserNotificationBundle(data: any): Promise<void> { |
|
|
private async processEndorserNotificationBundle(data: Record<string, unknown>): Promise<void> { |
|
|
try { |
|
|
try { |
|
|
this.log('Processing Endorser.ch notification bundle...'); |
|
|
this.log('Processing Endorser.ch notification bundle...'); |
|
|
|
|
|
|
|
@ -859,12 +859,12 @@ class TimeSafariAndroidTestApp { |
|
|
/** |
|
|
/** |
|
|
* Handle offers notification events from Endorser.ch API |
|
|
* Handle offers notification events from Endorser.ch API |
|
|
*/ |
|
|
*/ |
|
|
private async handleOffersNotification(event: any): Promise<void> { |
|
|
private async handleOffersNotification(event: Record<string, unknown>): Promise<void> { |
|
|
this.log('Handling offers notification:', event); |
|
|
this.log('Handling offers notification:', event); |
|
|
|
|
|
|
|
|
if (event.data && event.data.length > 0) { |
|
|
if (event.data && event.data.length > 0) { |
|
|
// Process OfferSummaryArrayMaybeMoreBody format
|
|
|
// Process OfferSummaryArrayMaybeMoreBody format
|
|
|
event.data.forEach((offer: any) => { |
|
|
event.data.forEach((offer: Record<string, unknown>) => { |
|
|
this.log('Processing offer:', { |
|
|
this.log('Processing offer:', { |
|
|
jwtId: offer.jwtId, |
|
|
jwtId: offer.jwtId, |
|
|
handleId: offer.handleId, |
|
|
handleId: offer.handleId, |
|
@ -885,12 +885,12 @@ class TimeSafariAndroidTestApp { |
|
|
/** |
|
|
/** |
|
|
* Handle projects notification events from Endorser.ch API |
|
|
* Handle projects notification events from Endorser.ch API |
|
|
*/ |
|
|
*/ |
|
|
private async handleProjectsNotification(event: any): Promise<void> { |
|
|
private async handleProjectsNotification(event: Record<string, unknown>): Promise<void> { |
|
|
this.log('Handling projects notification:', event); |
|
|
this.log('Handling projects notification:', event); |
|
|
|
|
|
|
|
|
if (event.data && event.data.length > 0) { |
|
|
if (event.data && event.data.length > 0) { |
|
|
// Process PlanSummaryAndPreviousClaimArrayMaybeMore format
|
|
|
// Process PlanSummaryAndPreviousClaimArrayMaybeMore format
|
|
|
event.data.forEach((planData: any) => { |
|
|
event.data.forEach((planData: Record<string, unknown>) => { |
|
|
const { plan, wrappedClaimBefore } = planData; |
|
|
const { plan, wrappedClaimBefore } = planData; |
|
|
this.log('Processing project change:', { |
|
|
this.log('Processing project change:', { |
|
|
jwtId: plan.jwtId, |
|
|
jwtId: plan.jwtId, |
|
@ -912,7 +912,7 @@ class TimeSafariAndroidTestApp { |
|
|
/** |
|
|
/** |
|
|
* Handle people notification events |
|
|
* Handle people notification events |
|
|
*/ |
|
|
*/ |
|
|
private async handlePeopleNotification(event: any): Promise<void> { |
|
|
private async handlePeopleNotification(event: Record<string, unknown>): Promise<void> { |
|
|
this.log('Handling people notification:', event); |
|
|
this.log('Handling people notification:', event); |
|
|
// Implementation would process people data and update local state
|
|
|
// Implementation would process people data and update local state
|
|
|
} |
|
|
} |
|
@ -920,12 +920,12 @@ class TimeSafariAndroidTestApp { |
|
|
/** |
|
|
/** |
|
|
* Handle items notification events |
|
|
* Handle items notification events |
|
|
*/ |
|
|
*/ |
|
|
private async handleItemsNotification(event: any): Promise<void> { |
|
|
private async handleItemsNotification(event: Record<string, unknown>): Promise<void> { |
|
|
this.log('Handling items notification:', event); |
|
|
this.log('Handling items notification:', event); |
|
|
// Implementation would process items data and update local state
|
|
|
// Implementation would process items data and update local state
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private log(message: string, data?: any) { |
|
|
private log(message: string, data?: Record<string, unknown>) { |
|
|
const timestamp = new Date().toLocaleTimeString(); |
|
|
const timestamp = new Date().toLocaleTimeString(); |
|
|
const logEntry = document.createElement('div'); |
|
|
const logEntry = document.createElement('div'); |
|
|
logEntry.innerHTML = `<span class="timestamp">[${timestamp}]</span> ${message}`; |
|
|
logEntry.innerHTML = `<span class="timestamp">[${timestamp}]</span> ${message}`; |
|
@ -1159,14 +1159,14 @@ class TimeSafariAndroidTestApp { |
|
|
limit: 100 |
|
|
limit: 100 |
|
|
}, |
|
|
}, |
|
|
responseSchema: { |
|
|
responseSchema: { |
|
|
validate: (data: any): data is StarredProjectsResponse => { |
|
|
validate: (data: unknown): data is StarredProjectsResponse => { |
|
|
return data && |
|
|
return data && |
|
|
Array.isArray(data.data) && |
|
|
Array.isArray(data.data) && |
|
|
typeof data.hitLimit === 'boolean' && |
|
|
typeof data.hitLimit === 'boolean' && |
|
|
data.pagination && |
|
|
data.pagination && |
|
|
typeof data.pagination.hasMore === 'boolean'; |
|
|
typeof data.pagination.hasMore === 'boolean'; |
|
|
}, |
|
|
}, |
|
|
transformError: (error: any) => ({ |
|
|
transformError: (error: unknown) => ({ |
|
|
code: 'VALIDATION_ERROR', |
|
|
code: 'VALIDATION_ERROR', |
|
|
message: error.message || 'Validation failed', |
|
|
message: error.message || 'Validation failed', |
|
|
retryable: false |
|
|
retryable: false |
|
@ -1227,10 +1227,10 @@ class TimeSafariAndroidTestApp { |
|
|
limit: 100 |
|
|
limit: 100 |
|
|
}, |
|
|
}, |
|
|
responseSchema: { |
|
|
responseSchema: { |
|
|
validate: (data: any): data is StarredProjectsResponse => { |
|
|
validate: (data: unknown): data is StarredProjectsResponse => { |
|
|
return data && Array.isArray(data.data); |
|
|
return data && Array.isArray(data.data); |
|
|
}, |
|
|
}, |
|
|
transformError: (error: any) => ({ |
|
|
transformError: (error: unknown) => ({ |
|
|
code: 'VALIDATION_ERROR', |
|
|
code: 'VALIDATION_ERROR', |
|
|
message: error.message, |
|
|
message: error.message, |
|
|
retryable: false |
|
|
retryable: false |
|
|