Conversation
WalkthroughAdds Aadhaar QR onboarding flow via a new SDK hook, centralizes error messaging, wires new success/failure events with navigation handlers, updates event typings, refactors Aadhaar screens to use the hook, and introduces duplicate public exports in passportDataProvider. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor U as User
participant AUS as AadhaarUploadScreen
participant H as useAadhaar Hook
participant V as Validators
participant P as passportDataProvider
participant C as SDK Client
participant SCP as SelfClientProvider
participant Nav as Navigation
U->>AUS: Select QR image
AUS->>H: processAadhaarQRCode(qrText)
H->>V: validate format + parse + timestamp
alt Valid
H->>P: storePassportData(AadhaarData)
alt Store OK
H->>C: emit PROVING_AADHAAR_UPLOAD_SUCCESS
C-->>SCP: Event dispatched
SCP->>Nav: Navigate to AadhaarUploadSuccess
else Store Error
H->>C: emit PROVING_AADHAAR_UPLOAD_FAILURE{general}
C-->>SCP: Event dispatched
SCP->>Nav: Navigate to AadhaarUploadError{general}
end
else Invalid or Expired
H->>C: emit PROVING_AADHAAR_UPLOAD_FAILURE{expired|general}
C-->>SCP: Event dispatched
SCP->>Nav: Navigate to AadhaarUploadError{expired|general}
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45–70 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app/src/screens/document/aadhaar/AadhaarUploadScreen.tsx (1)
114-129: Stop overriding SDK-driven Aadhaar failure navigation.
processAadhaarQRCodenow raisesPROVING_AADHAAR_UPLOAD_FAILUREwith anerrorType. This catch immediately callsnavigation.navigate(..., { errorType: 'general' }), so the listener we just wired inSelfClientProviderloses the specific'expired' | 'general'payload and the user only sees the generic copy. Gate this branch to library-scan errors (e.g. “No QR code found”) and let the SDK listener drive navigation for processing failures.- if ( - errorMessage.includes('No QR code found') || - errorMessage.includes('QR code') || - errorMessage.includes('Failed to process') || - errorMessage.includes('Invalid') - ) { - (navigation.navigate as any)('AadhaarUploadError', { - errorType: 'general' as const, - }); - return; - } - - // Handle any other errors by showing error screen - (navigation.navigate as any)('AadhaarUploadError', { - errorType: 'general' as const, - }); + if (errorMessage.includes('No QR code found')) { + (navigation.navigate as any)('AadhaarUploadError', { + errorType: 'general' as const, + }); + return; + } + + // Let PROVING_AADHAAR_UPLOAD_FAILURE listener handle SDK processing errors so we keep its errorType payload. + return;
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
app/src/providers/passportDataProvider.tsx(2 hunks)app/src/providers/selfClientProvider.tsx(1 hunks)app/src/screens/document/aadhaar/AadhaarUploadErrorScreen.tsx(2 hunks)app/src/screens/document/aadhaar/AadhaarUploadScreen.tsx(3 hunks)packages/mobile-sdk-alpha/src/flows/onboarding/import-aadhaar.ts(1 hunks)packages/mobile-sdk-alpha/src/types/events.ts(3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
app/src/**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
app/src/**/*.{ts,tsx,js,jsx}: Review React Native TypeScript code for:
- Component architecture and reusability
- State management patterns
- Performance optimizations
- TypeScript type safety
- React hooks usage and dependencies
- Navigation patterns
Files:
app/src/providers/selfClientProvider.tsxapp/src/screens/document/aadhaar/AadhaarUploadErrorScreen.tsxapp/src/screens/document/aadhaar/AadhaarUploadScreen.tsxapp/src/providers/passportDataProvider.tsx
packages/mobile-sdk-alpha/**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
packages/mobile-sdk-alpha/**/*.{ts,tsx,js,jsx}: Review alpha mobile SDK code for:
- API consistency with core SDK
- Platform-neutral abstractions
- Performance considerations
- Clear experimental notes or TODOs
Files:
packages/mobile-sdk-alpha/src/flows/onboarding/import-aadhaar.tspackages/mobile-sdk-alpha/src/types/events.ts
🧠 Learnings (1)
📚 Learning: 2025-09-10T14:47:40.945Z
Learnt from: shazarre
PR: selfxyz/self#1041
File: app/src/providers/passportDataProvider.tsx:297-301
Timestamp: 2025-09-10T14:47:40.945Z
Learning: In app/src/providers/passportDataProvider.tsx: The deleteDocumentDirectlyFromKeychain function is a low-level utility used by the DocumentsAdapter and should not include error handling since callers like deleteDocument() already implement appropriate try/catch with logging for Keychain operations.
Applied to files:
app/src/providers/passportDataProvider.tsx
| const currentTimestamp = new Date().getTime(); | ||
| const timestampDate = new Date(timestamp); | ||
| const timestampTimestamp = timestampDate.getTime(); | ||
| const diff = currentTimestamp - timestampTimestamp; | ||
| const diffMinutes = diff / (1000 * 60); | ||
|
|
||
| const allowedWindow = await getAadharRegistrationWindow(); | ||
| const isValid = diffMinutes <= allowedWindow; | ||
|
|
There was a problem hiding this comment.
Fix timestamp parsing to avoid false expiry
new Date(timestamp) cannot reliably parse the 'YYYY-MM-DD HH:MM' string we get from the QR data. On React Native’s JavaScriptCore (iOS) this returns Invalid Date, so every valid QR fails the window check and is reported as expired. Normalize the string to ISO (e.g. replace the space with T) and guard against unparseable or missing values before computing the diff.
- const timestampDate = new Date(timestamp);
- const timestampTimestamp = timestampDate.getTime();
- const diff = currentTimestamp - timestampTimestamp;
- const diffMinutes = diff / (1000 * 60);
+ if (!timestamp) {
+ selfClient.trackEvent(AadhaarEvents.TIMESTAMP_VALIDATION_FAILED);
+ return false;
+ }
+
+ const isoTimestamp = timestamp.replace(' ', 'T');
+ const timestampDate = new Date(isoTimestamp);
+ const timestampTimestamp = timestampDate.getTime();
+ if (Number.isNaN(timestampTimestamp)) {
+ selfClient.trackEvent(AadhaarEvents.TIMESTAMP_VALIDATION_FAILED);
+ return false;
+ }
+
+ const diff = currentTimestamp - timestampTimestamp;
+ const diffMinutes = diff / (1000 * 60);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const currentTimestamp = new Date().getTime(); | |
| const timestampDate = new Date(timestamp); | |
| const timestampTimestamp = timestampDate.getTime(); | |
| const diff = currentTimestamp - timestampTimestamp; | |
| const diffMinutes = diff / (1000 * 60); | |
| const allowedWindow = await getAadharRegistrationWindow(); | |
| const isValid = diffMinutes <= allowedWindow; | |
| const currentTimestamp = new Date().getTime(); | |
| if (!timestamp) { | |
| selfClient.trackEvent(AadhaarEvents.TIMESTAMP_VALIDATION_FAILED); | |
| return false; | |
| } | |
| const isoTimestamp = timestamp.replace(' ', 'T'); | |
| const timestampDate = new Date(isoTimestamp); | |
| const timestampTimestamp = timestampDate.getTime(); | |
| if (Number.isNaN(timestampTimestamp)) { | |
| selfClient.trackEvent(AadhaarEvents.TIMESTAMP_VALIDATION_FAILED); | |
| return false; | |
| } | |
| const diff = currentTimestamp - timestampTimestamp; | |
| const diffMinutes = diff / (1000 * 60); | |
| const allowedWindow = await getAadharRegistrationWindow(); | |
| const isValid = diffMinutes <= allowedWindow; |
also
Summary by CodeRabbit