fix(android): resolve SharedPreferences mismatch and document cross-platform storage pattern

- Fix TestNativeFetcher to read from same SharedPreferences as plugin
  - Changed PREFS_NAME from 'DailyNotificationPrefs' to 'daily_notification_timesafari'
  - Changed KEY_STARRED_PLAN_IDS from 'starred_plan_ids' to 'starredPlanIds'
  - Updated getStarredPlanIds() to read from plugin's SharedPreferences location
  - Added diagnostic logging for plan ID loading

- Add updateStarredPlans() call in App.vue mounted() hook
  - Ensures starred plan IDs are persisted to native storage on app startup
  - Allows native fetcher to read plan IDs from SharedPreferences
  - Added diagnostic logging for configuration flow

- Document cross-platform storage pattern
  - Created docs/CROSS_PLATFORM_STORAGE_PATTERN.md with architecture flow
  - Documented TypeScript → Capacitor bridge → Plugin → Native storage → Native fetcher flow
  - Added iOS implementation checklist with code examples
  - Clarified why native storage is needed (background workers can't use bridge)

- Add JWT generation logging to test-user-zero.ts
  - Log JWT algorithm (ES256K) and DID when token is generated
  - Helps diagnose JWT verification issues

Fixes:
- Empty planIds array in native fetcher requests
- SharedPreferences key mismatch between plugin and native fetcher
- Missing documentation for iOS implementation

All changes maintain backward compatibility.
This commit is contained in:
Matthew Raymer
2025-10-31 13:02:30 +00:00
parent d4bb902cbe
commit f256113ed9
4 changed files with 298 additions and 7 deletions

View File

@@ -94,6 +94,20 @@ class App extends Vue {
apiBaseUrl: apiBaseUrl.substring(0, 50) + '...',
activeDid: TEST_USER_ZERO_CONFIG.identity.did.substring(0, 30) + '...'
})
// Update starred plan IDs from config so native fetcher can use them
console.log('🔧 App.vue: Updating starred plan IDs...')
const planIds = [...TEST_USER_ZERO_CONFIG.starredProjects.planIds]
console.log('🔧 App.vue: Plan IDs to update:', planIds.length, 'plans')
const updateResult = await DailyNotification.updateStarredPlans({
planIds: planIds
})
console.log('✅ App.vue: Starred plans updated:', {
count: updateResult.planIdsCount,
updatedAt: new Date(updateResult.updatedAt).toISOString()
})
} catch (error) {
console.error('❌ App.vue: Failed to configure native fetcher:', error)
console.error('❌ App.vue: Error details:', error instanceof Error ? error.stack : String(error))

View File

@@ -267,6 +267,10 @@ export async function generateEndorserJWT(): Promise<string> {
expiresIn: expiresIn
});
const log = await getLogger();
log.custom("🔐", "JWT generated - Algorithm: ES256K, DID:", TEST_USER_ZERO_CONFIG.identity.did.substring(0, 30) + "...");
log.custom("🔐", "JWT length:", jwt.length, "characters");
return jwt;
} catch (error) {
const log = await getLogger();