Skip to content

Conversation

@transphorm
Copy link
Member

@transphorm transphorm commented Jan 7, 2026

Motivation

  • Ensure users pick which document to use before entering the proving flow so expired/unregistered documents cannot be used.
  • Make QR scan and deeplink entry points consistent by routing them through a single selector screen prior to Prove.
  • Reuse existing document selection components and state logic to avoid duplicating validation (expiry/registration).

Description

  • Add screen app/src/screens/verification/DocumentSelectorForProvingScreen.tsx which loads the document catalog, auto-selects a valid document, shows empty/error states, and exposes a Continue to Proof action that sets the selected document and navigates to Prove.
  • Wire the new screen into navigation by registering DocumentSelectorForProving in app/src/navigation/verification.ts and adding it to RootStackParamList in app/src/navigation/index.tsx.
  • Route QR and deeplink flows (and related entry points) to the selector by updating QRCodeViewFinderScreen.tsx, deeplinks.ts, useEarnPointsFlow.ts, and HomeNavBar.tsx to navigate to DocumentSelectorForProving instead of Prove.
  • Add unit tests app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx, update deeplink expectations in app/tests/src/navigation/deeplinks.test.ts, and add a Maestro e2e flow stub at app/tests/e2e/proof-request.flow.yaml.

Testing

  • Added unit tests: app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx which exercise loading, selection, disabled states, continue behavior, empty and error states.
  • Updated existing deeplink test app/tests/src/navigation/deeplinks.test.ts to assert navigation to DocumentSelectorForProving instead of Prove.
  • Added a Maestro e2e flow stub app/tests/e2e/proof-request.flow.yaml (placeholder; real QR/deeplink flows require fixtures).
  • No automated test commands were executed locally in this change (no yarn test / CI run as part of this rollout).

Codex Task

Summary by CodeRabbit

Release Notes

  • New Features
    • Added a document selection screen in the proof verification flow for users to choose their ID document before proceeding.
    • Introduced a new "Proof Settings" option to customize document selection behavior with toggles to always skip the selection screen or skip when only one document is available.
    • Enabled automatic document selection when configured to skip the selection screen, streamlining the proof process for returning users.

✏️ Tip: You can customize this high-level summary in your review settings.

@transphorm transphorm marked this pull request as draft January 7, 2026 19:39
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 7, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (3)
  • main
  • dev
  • staging

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

This PR introduces a new document-selection screen (DocumentSelectorForProving) inserted before the Prove verification flow. It includes a new settings screen to configure auto-skip behavior, updates multiple navigation paths to route through the selector, adds corresponding store flags, and provides comprehensive test coverage.

Changes

Cohort / File(s) Summary
Navigation Infrastructure
app/src/navigation/index.tsx, app/src/navigation/account.ts, app/src/navigation/verification.ts
Updated type signatures (RootStackParamList) and navigation registrations to include DocumentSelectorForProving and ProofSettings routes; verification tree now includes DocumentSelectorForProving screen with black header styling.
Navigation Redirects
app/src/navigation/deeplinks.ts
Replaced target screen from Prove to DocumentSelectorForProving in two deeplink navigation creations; parent screen parameters preserved.
Hook & Component Redirects
app/src/components/navbar/HomeNavBar.tsx, app/src/hooks/useEarnPointsFlow.ts, app/src/screens/verification/QRCodeViewFinderScreen.tsx
Updated post-flow navigation targets to route to DocumentSelectorForProving instead of Prove; no logic changes.
Document Selector Screen
app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
New complex screen component with document fetching, auto-selection logic based on validity/expiry, configurable skip behavior via settings store, error handling with retry, and AbortController for request cancellation.
Proof Settings Screen
app/src/screens/account/settings/ProofSettingsScreen.tsx
New settings screen with two toggles: "Always skip document selection" and "Skip when only one document" (disabled when first is enabled); displays informational message when skipping is active.
Settings Menu
app/src/screens/account/settings/SettingsScreen.tsx
Added Settings2 icon import and new "Proof settings" route entry linking to ProofSettingsScreen; exposed in both web and non-web routes.
Persisted Settings
app/src/stores/settingStore.ts
Added two new persisted state fields (skipDocumentSelector: false, skipDocumentSelectorIfSingle: true) and corresponding setter methods to PersistedSettingsState interface.
Mock & Test Updates
app/tests/__setup__/mocks/navigation.js, app/tests/src/hooks/useEarnPointsFlow.test.ts, app/tests/src/navigation.test.tsx, app/tests/src/navigation/deeplinks.test.ts
Navigation mock updated to execute focus effects once per mount (preventing re-render loops); test expectations updated to expect DocumentSelectorForProving instead of Prove; navigation screen registry updated to include new routes.
Comprehensive Test Suite
app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
Extensive test coverage for document loading, auto-selection logic, skip settings flows (single/multi-document cases), continue button state, error handling with retry, and empty/error state rendering.

Sequence Diagram

sequenceDiagram
    actor User
    participant DSS as DocumentSelectorForProving<br/>Screen
    participant Store as Settings Store
    participant Nav as Navigation
    participant PS as Prove Screen
    participant OB as Onboarding

    User->>DSS: Mount DocumentSelectorForProvingScreen
    activate DSS
    DSS->>Store: Check skipDocumentSelector & skipDocumentSelectorIfSingle
    DSS->>DSS: Fetch documents & catalog
    
    alt Auto-Skip Enabled (skipDocumentSelector = true)
        DSS->>DSS: pickInitialDocument() → auto-select valid doc
        Note over DSS: Skip UI rendering, show "Preparing proof..."
        DSS->>Nav: navigate('Prove', { selectedDocument })
        Nav->>PS: Load Prove Screen
    else Single Doc Exists & skipDocumentSelectorIfSingle = true
        DSS->>DSS: Auto-select single valid document
        DSS->>Nav: navigate('Prove', { selectedDocument })
        Nav->>PS: Load Prove Screen
    else No Valid Documents
        DSS->>Nav: navigate('DocumentDataNotFound')
        Nav->>OB: Load Onboarding
    else Manual Selection Path
        DSS->>User: Display document list
        User->>DSS: Select document
        activate DSS
        DSS->>DSS: handleSelect(document)
        deactivate DSS
        User->>DSS: Press Continue button
        activate DSS
        DSS->>DSS: Validate selection
        DSS->>Nav: navigate('Prove', { selectedDocument })
        Nav->>PS: Load Prove Screen
        deactivate DSS
    end
    deactivate DSS
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • shazarre
  • aaronmgdr

Poem

🧭 A selector screen appears, guiding docs with care,
Skip or choose—the settings declare,
Auto-flows where single trails hide,
Proof awaits on the other side! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding a new DocumentSelectorForProving screen and updating proof flows to route through it.
Description check ✅ Passed The description follows the template with clear Motivation, Description, and Testing sections that comprehensively explain the changes, implementation details, and test coverage.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@transphorm transphorm marked this pull request as ready for review January 7, 2026 22:32
@chatgpt-codex-connector
Copy link

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@transphorm
Copy link
Member Author

@coderabbitai full review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 7, 2026

✅ Actions performed

Full review triggered.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @app/src/screens/verification/DocumentSelectorForProvingScreen.tsx:
- Around line 155-162: The code can return catalog.selectedDocumentId when
selectedMeta exists but selectedData is undefined, which may select a document
whose data hasn't loaded; update the logic in DocumentSelectorForProvingScreen
to only return catalog.selectedDocumentId if selectedData is present and
determineDocumentState(selectedMeta, selectedData.data) is not a disabled state
(i.e., require both selectedMeta and selectedData before returning), or if
metadata-only selection is truly intended, add an explicit comment near the
selectedMeta branch documenting that metadata suffices and why; reference the
symbols selectedMeta, selectedData, catalog.selectedDocumentId,
determineDocumentState, and isDisabledState when making the change.
🧹 Nitpick comments (1)
app/tests/src/hooks/useEarnPointsFlow.test.ts (1)

228-272: Test expectation updated correctly, but test description is outdated.

The test now expects navigation to DocumentSelectorForProving, which is correct. However, the test description at line 228 still says "should navigate to Prove screen" - consider updating it to "should navigate to DocumentSelectorForProving screen" for clarity.

📝 Update test description
-    it('should navigate to Prove screen when points disclosure modal button is pressed', async () => {
+    it('should navigate to DocumentSelectorForProving screen when points disclosure modal button is pressed', async () => {
       mockHasUserAnIdentityDocumentRegistered.mockResolvedValue(true);
       mockHasUserDoneThePointsDisclosure.mockResolvedValue(false);
       mockPointsSelfApp.mockResolvedValue(mockSelfApp as any);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4ad10e6 and 87e27dd.

📒 Files selected for processing (16)
  • app/src/components/navbar/HomeNavBar.tsx
  • app/src/hooks/useEarnPointsFlow.ts
  • app/src/navigation/account.ts
  • app/src/navigation/deeplinks.ts
  • app/src/navigation/index.tsx
  • app/src/navigation/verification.ts
  • app/src/screens/account/settings/ProofSettingsScreen.tsx
  • app/src/screens/account/settings/SettingsScreen.tsx
  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
  • app/src/stores/settingStore.ts
  • app/tests/__setup__/mocks/navigation.js
  • app/tests/src/hooks/useEarnPointsFlow.test.ts
  • app/tests/src/navigation.test.tsx
  • app/tests/src/navigation/deeplinks.test.ts
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
🧰 Additional context used
📓 Path-based instructions (27)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{js,jsx,ts,tsx}: NEVER log sensitive data including PII (names, DOB, passport numbers, addresses), credentials, tokens, API keys, private keys, or session identifiers.
ALWAYS redact/mask sensitive fields in logs using consistent patterns (e.g., ***-***-1234 for passport numbers, J*** D*** for names).

Files:

  • app/src/components/navbar/HomeNavBar.tsx
  • app/tests/src/navigation.test.tsx
  • app/src/hooks/useEarnPointsFlow.ts
  • app/tests/src/hooks/useEarnPointsFlow.test.ts
  • app/tests/__setup__/mocks/navigation.js
  • app/src/screens/account/settings/SettingsScreen.tsx
  • app/src/stores/settingStore.ts
  • app/src/screens/account/settings/ProofSettingsScreen.tsx
  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/src/navigation/verification.ts
  • app/tests/src/navigation/deeplinks.test.ts
  • app/src/navigation/account.ts
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
  • app/src/navigation/deeplinks.ts
  • app/src/navigation/index.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,js,jsx}: Use React Navigation with createStaticNavigation for type-safe navigation in React Native applications.
Implement platform-specific handling with Platform.OS === 'ios' ? 'iOS' : 'Android' checks before platform-specific code in React Native.
Initialize native modules with initializeNativeModules() before any native operations in React Native.
Implement lazy loading for screens using React.lazy() in React Native applications.
Implement custom modal system with useModal hook and callback registry in React Native.
Integrate haptic feedback using useHapticNavigation hook in React Native navigation.
Use platform-specific initial routes: web uses 'Home', mobile uses 'Splash' in React Navigation.
Use Zustand for global state management in React Native applications.
Use custom hooks for complex state (useModal, useHapticNavigation) instead of inline logic.
Use AsyncStorage for simple data, SQLite for complex data, and Keychain for sensitive data in React Native.
Use @/ alias for src imports and @tests/ alias for test imports in TypeScript/JavaScript files.
Use conditional rendering with Platform.OS for platform-specific code in React Native.
Use Tamagui for UI components in React Native applications.
Do not log sensitive data in production, including identity verification and passport information.
Use Keychain for secure storage of sensitive data in React Native.
Implement proper cleanup of sensitive data after use.
Implement certificate validation for passport data verification.
Always use try-catch for async operations in React Native and TypeScript code.
Implement graceful degradation when native modules fail in React Native.
Provide user-friendly error messages in UI and error handlers.
Lazy load screens and components to optimize bundle size in React Native.
Prevent memory leaks in native modules in React Native.

Files:

  • app/src/components/navbar/HomeNavBar.tsx
  • app/tests/src/navigation.test.tsx
  • app/src/hooks/useEarnPointsFlow.ts
  • app/tests/src/hooks/useEarnPointsFlow.test.ts
  • app/tests/__setup__/mocks/navigation.js
  • app/src/screens/account/settings/SettingsScreen.tsx
  • app/src/stores/settingStore.ts
  • app/src/screens/account/settings/ProofSettingsScreen.tsx
  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/src/navigation/verification.ts
  • app/tests/src/navigation/deeplinks.test.ts
  • app/src/navigation/account.ts
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
  • app/src/navigation/deeplinks.ts
  • app/src/navigation/index.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursorrules)

Implement comprehensive error boundaries in React components.

Files:

  • app/src/components/navbar/HomeNavBar.tsx
  • app/tests/src/navigation.test.tsx
  • app/src/screens/account/settings/SettingsScreen.tsx
  • app/src/screens/account/settings/ProofSettingsScreen.tsx
  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
  • app/src/navigation/index.tsx
**/*.{tsx,jsx,ts,js}

📄 CodeRabbit inference engine (.cursorrules)

Implement proper cleanup in useEffect and component unmount hooks in React.

Files:

  • app/src/components/navbar/HomeNavBar.tsx
  • app/tests/src/navigation.test.tsx
  • app/src/hooks/useEarnPointsFlow.ts
  • app/tests/src/hooks/useEarnPointsFlow.test.ts
  • app/tests/__setup__/mocks/navigation.js
  • app/src/screens/account/settings/SettingsScreen.tsx
  • app/src/stores/settingStore.ts
  • app/src/screens/account/settings/ProofSettingsScreen.tsx
  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/src/navigation/verification.ts
  • app/tests/src/navigation/deeplinks.test.ts
  • app/src/navigation/account.ts
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
  • app/src/navigation/deeplinks.ts
  • app/src/navigation/index.tsx
**/{mobile,client,app,time,verification}/**/*.{ts,tsx,js,swift,kt}

📄 CodeRabbit inference engine (.cursor/rules/compliance-verification.mdc)

Use server-signed time tokens or chain block timestamps for trusted time in mobile clients, do not trust device wall-clock alone

Files:

  • app/src/components/navbar/HomeNavBar.tsx
  • app/tests/src/navigation.test.tsx
  • app/src/hooks/useEarnPointsFlow.ts
  • app/tests/src/hooks/useEarnPointsFlow.test.ts
  • app/tests/__setup__/mocks/navigation.js
  • app/src/screens/account/settings/SettingsScreen.tsx
  • app/src/stores/settingStore.ts
  • app/src/screens/account/settings/ProofSettingsScreen.tsx
  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/src/navigation/verification.ts
  • app/tests/src/navigation/deeplinks.test.ts
  • app/src/navigation/account.ts
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
  • app/src/navigation/deeplinks.ts
  • app/src/navigation/index.tsx
**/{mobile,client,app,proof,zk}/**/*.{ts,tsx,js,swift,kt}

📄 CodeRabbit inference engine (.cursor/rules/compliance-verification.mdc)

**/{mobile,client,app,proof,zk}/**/*.{ts,tsx,js,swift,kt}: Include trusted time anchor in proof generation and verify time anchor authenticity before proof generation in mobile implementations
Achieve proof generation in <60 seconds on mid-tier mobile devices

Files:

  • app/src/components/navbar/HomeNavBar.tsx
  • app/tests/src/navigation.test.tsx
  • app/src/hooks/useEarnPointsFlow.ts
  • app/tests/src/hooks/useEarnPointsFlow.test.ts
  • app/tests/__setup__/mocks/navigation.js
  • app/src/screens/account/settings/SettingsScreen.tsx
  • app/src/stores/settingStore.ts
  • app/src/screens/account/settings/ProofSettingsScreen.tsx
  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/src/navigation/verification.ts
  • app/tests/src/navigation/deeplinks.test.ts
  • app/src/navigation/account.ts
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
  • app/src/navigation/deeplinks.ts
  • app/src/navigation/index.tsx
app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (app/AGENTS.md)

Ensure yarn types passes (TypeScript validation) before creating a PR

Files:

  • app/src/components/navbar/HomeNavBar.tsx
  • app/tests/src/navigation.test.tsx
  • app/src/hooks/useEarnPointsFlow.ts
  • app/tests/src/hooks/useEarnPointsFlow.test.ts
  • app/src/screens/account/settings/SettingsScreen.tsx
  • app/src/stores/settingStore.ts
  • app/src/screens/account/settings/ProofSettingsScreen.tsx
  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/src/navigation/verification.ts
  • app/tests/src/navigation/deeplinks.test.ts
  • app/src/navigation/account.ts
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
  • app/src/navigation/deeplinks.ts
  • app/src/navigation/index.tsx
app/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (app/AGENTS.md)

app/**/*.{ts,tsx,js,jsx}: Ensure web build succeeds with yarn web before creating a PR
Do not include sensitive data in logs - avoid logging PII, credentials, and tokens
Use react-native-dotenv for environment configuration via @env import
Confirm no sensitive data exposed before PR merge

Files:

  • app/src/components/navbar/HomeNavBar.tsx
  • app/tests/src/navigation.test.tsx
  • app/src/hooks/useEarnPointsFlow.ts
  • app/tests/src/hooks/useEarnPointsFlow.test.ts
  • app/tests/__setup__/mocks/navigation.js
  • app/src/screens/account/settings/SettingsScreen.tsx
  • app/src/stores/settingStore.ts
  • app/src/screens/account/settings/ProofSettingsScreen.tsx
  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/src/navigation/verification.ts
  • app/tests/src/navigation/deeplinks.test.ts
  • app/src/navigation/account.ts
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
  • app/src/navigation/deeplinks.ts
  • app/src/navigation/index.tsx
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/components/navbar/HomeNavBar.tsx
  • app/src/hooks/useEarnPointsFlow.ts
  • app/src/screens/account/settings/SettingsScreen.tsx
  • app/src/stores/settingStore.ts
  • app/src/screens/account/settings/ProofSettingsScreen.tsx
  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/src/navigation/verification.ts
  • app/src/navigation/account.ts
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
  • app/src/navigation/deeplinks.ts
  • app/src/navigation/index.tsx
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.test.{ts,tsx,js,jsx}: Use renderHook for testing custom React hooks instead of rendering components.
Mock console.error in tests to avoid test output clutter while testing error scenarios.
Test error boundaries and recovery mechanisms in React components.
Mock SQLite operations with executeSql method in database tests using utilities from tests/__setup__/databaseMocks.ts.

**/*.test.{ts,tsx,js,jsx}: Never use require('react-native') in test files; use ES6 import statements instead to avoid nested require() calls that cause out-of-memory errors in CI/CD pipelines
Never use require('react') in test files; use ES6 import React from 'react' instead to avoid nested require() calls that cause out-of-memory errors

Files:

  • app/tests/src/navigation.test.tsx
  • app/tests/src/hooks/useEarnPointsFlow.test.ts
  • app/tests/src/navigation/deeplinks.test.ts
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
{app,packages/mobile-sdk-alpha}/**/*.{test,spec}.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Never create nested require('react-native') calls in tests as this causes out-of-memory errors in CI/CD pipelines; use ES6 import statements instead and avoid dynamic require() calls in beforeEach/afterEach hooks

Files:

  • app/tests/src/navigation.test.tsx
  • app/tests/src/hooks/useEarnPointsFlow.test.ts
  • app/tests/src/navigation/deeplinks.test.ts
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
app/**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (app/AGENTS.md)

app/**/*.test.{ts,tsx,js,jsx}: Ensure yarn test passes (unit tests) before creating a PR
Avoid nested require('react') or require('react-native') calls in test files - use ES6 import statements instead
Put all imports at the top of test files - avoid dynamic imports in hooks
Never use require() calls in beforeEach/afterEach hooks in test files
Verify no memory leaks introduced, including test memory patterns
Use ES6 import statements exclusively - never use require('react') or require('react-native') in test files

Files:

  • app/tests/src/navigation.test.tsx
  • app/tests/src/hooks/useEarnPointsFlow.test.ts
  • app/tests/src/navigation/deeplinks.test.ts
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
app/tests/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (app/AGENTS.md)

Do not create nested require('react-native') calls in tests - causes OOM in CI

Files:

  • app/tests/src/navigation.test.tsx
  • app/tests/src/hooks/useEarnPointsFlow.test.ts
  • app/tests/__setup__/mocks/navigation.js
  • app/tests/src/navigation/deeplinks.test.ts
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
**/*.{test,spec}.{ts,js,tsx,jsx}

⚙️ CodeRabbit configuration file

**/*.{test,spec}.{ts,js,tsx,jsx}: Review test files for:

  • Test coverage completeness
  • Test case quality and edge cases
  • Mock usage appropriateness
  • Test readability and maintainability

Files:

  • app/tests/src/navigation.test.tsx
  • app/tests/src/hooks/useEarnPointsFlow.test.ts
  • app/tests/src/navigation/deeplinks.test.ts
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
**/{compliance,ofac,verification,identity}/**/*.{ts,tsx,js,py}

📄 CodeRabbit inference engine (.cursor/rules/compliance-verification.mdc)

**/{compliance,ofac,verification,identity}/**/*.{ts,tsx,js,py}: Implement three-tier OFAC verification system: Passport Number Check (direct passport validation), Name + DOB Check (full name with exact date of birth), and Name + Year Check (name with year of birth, defaulting to Jan-01)
Apply Jaro–Winkler fuzzy matching algorithm with ≥0.92 threshold for OFAC name verification
Validate passport numbers by removing whitespace/punctuation and performing country-specific format validation
Protect all PII by committing via domain-separated hashes using Poseidon hash function with 'ofac-v1' domain separator
Implement per-issuer salt for additional privacy in OFAC hash commitments, with unique salt per issuing country

Files:

  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
**/{compliance,ofac,verification,identity,utils}/**/*.{ts,tsx,js,py}

📄 CodeRabbit inference engine (.cursor/rules/compliance-verification.mdc)

Normalize names using case-folding, Unicode NFKC normalization, and diacritics removal for OFAC matching

Files:

  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
**/{compliance,ofac,verification,identity,age}/**/*.{ts,tsx,js,py}

📄 CodeRabbit inference engine (.cursor/rules/compliance-verification.mdc)

Use ISO 8601 format (YYYY-MM-DD) for all date inputs in compliance verification

Files:

  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
**/{age,verification,identity,compliance}/**/*.{ts,tsx,js,py}

📄 CodeRabbit inference engine (.cursor/rules/compliance-verification.mdc)

Implement age verification with day-level precision for 'olderThan' checks accepting ISO 8601 date inputs

Files:

  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
**/{circuits,age,verification,zk,proof}/**/*.{circom,ts,tsx,js,py}

📄 CodeRabbit inference engine (.cursor/rules/compliance-verification.mdc)

Implement zero-knowledge proof of age without disclosing actual date of birth

Files:

  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
**/{compliance,country,verification,identity}/**/*.{ts,tsx,js,py}

📄 CodeRabbit inference engine (.cursor/rules/compliance-verification.mdc)

**/{compliance,country,verification,identity}/**/*.{ts,tsx,js,py}: Implement forbidden country validation using Bloom filter with false positive rate ≤1e-6
Validate country codes in ISO 3166-1 alpha-3 format for forbidden country checks

Files:

  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
**/{circuits,country,verification,zk,proof}/**/*.{circom,ts,tsx,js,py}

📄 CodeRabbit inference engine (.cursor/rules/compliance-verification.mdc)

Implement zero-knowledge proof of country non-inclusion without revealing actual country code

Files:

  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
**/{compliance,country,verification}/**/*.{ts,tsx,js,py}

📄 CodeRabbit inference engine (.cursor/rules/compliance-verification.mdc)

Implement graceful degradation for country validation when filter is unavailable

Files:

  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
**/{compliance,verification,identity,age,country}/**/*.{ts,tsx,js,py}

📄 CodeRabbit inference engine (.cursor/rules/compliance-verification.mdc)

**/{compliance,verification,identity,age,country}/**/*.{ts,tsx,js,py}: Use UTC timestamps only for all compliance verification operations
Allow ±5 minutes clock drift tolerance in timestamp validation for compliance checks

Files:

  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
**/{compliance,verification,proof}/**/*.{ts,tsx,js,py}

📄 CodeRabbit inference engine (.cursor/rules/compliance-verification.mdc)

Enforce 24-hour verification window with drift adjustment for compliance proof validity

Files:

  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
**/{compliance,verification,proof,zk,identity,age,country}/**/*.{ts,tsx,js,py}

📄 CodeRabbit inference engine (.cursor/rules/compliance-verification.mdc)

Maintain peak memory usage below 300MB for compliance verification operations

Files:

  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
**/{compliance,verification,service,api}/**/*.{ts,tsx,js,py}

📄 CodeRabbit inference engine (.cursor/rules/compliance-verification.mdc)

**/{compliance,verification,service,api}/**/*.{ts,tsx,js,py}: Make all network calls idempotent with exponential backoff retry logic
Implement exponential backoff with jitter for compliance verification retry logic

Files:

  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
**/{compliance,audit,log,verification}/**/*.{ts,tsx,js,py}

📄 CodeRabbit inference engine (.cursor/rules/compliance-verification.mdc)

Maintain privacy-preserving audit logs for compliance verification operations

Files:

  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
🧠 Learnings (40)
📓 Common learnings
Learnt from: seshanthS
Repo: selfxyz/self PR: 1497
File: app/src/screens/verification/ProveScreen.tsx:125-161
Timestamp: 2025-12-13T18:00:46.963Z
Learning: In app/src/screens/verification/ProveScreen.tsx: The document expiration check using checkDocumentExpiration() is UX-only to prevent wasted gas and provide better user experience. The authoritative expiration validation is enforced in the circuits and smart contracts using trusted time sources (block timestamps), not device clock.
📚 Learning: 2025-12-25T19:19:35.354Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-12-25T19:19:35.354Z
Learning: Applies to packages/mobile-sdk-alpha/**/*.{ts,tsx} : Ensure no breaking changes to public API or document them properly

Applied to files:

  • app/src/components/navbar/HomeNavBar.tsx
  • app/tests/src/navigation.test.tsx
  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/tests/src/navigation/deeplinks.test.ts
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
  • app/src/navigation/deeplinks.ts
📚 Learning: 2025-11-25T14:06:55.970Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T14:06:55.970Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use platform-specific initial routes: web uses 'Home', mobile uses 'Splash' in React Navigation.

Applied to files:

  • app/src/components/navbar/HomeNavBar.tsx
  • app/tests/src/navigation/deeplinks.test.ts
  • app/src/navigation/index.tsx
📚 Learning: 2025-08-26T14:49:11.190Z
Learnt from: shazarre
Repo: selfxyz/self PR: 936
File: app/src/screens/passport/PassportNFCScanScreen.tsx:28-31
Timestamp: 2025-08-26T14:49:11.190Z
Learning: The main App.tsx file is located at app/App.tsx (not in app/src), and it properly wraps the entire app with SelfClientProvider at the top of the provider hierarchy, enabling useSelfClient() hook usage throughout all navigation screens.

Applied to files:

  • app/src/components/navbar/HomeNavBar.tsx
  • app/src/screens/account/settings/SettingsScreen.tsx
  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/src/navigation/deeplinks.ts
📚 Learning: 2025-12-25T19:19:04.954Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: app/AGENTS.md:0-0
Timestamp: 2025-12-25T19:19:04.954Z
Learning: Document complex native module changes in PRs

Applied to files:

  • app/src/components/navbar/HomeNavBar.tsx
  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/src/navigation/deeplinks.ts
📚 Learning: 2025-08-26T14:41:41.821Z
Learnt from: shazarre
Repo: selfxyz/self PR: 936
File: app/src/screens/aesop/PassportOnboardingScreen.tsx:0-0
Timestamp: 2025-08-26T14:41:41.821Z
Learning: When verifying provider hierarchies in React Native apps, always check the main App.tsx file at the app root, not just navigation/index.tsx and layout files, as providers are often configured at the top-level App component.

Applied to files:

  • app/src/components/navbar/HomeNavBar.tsx
  • app/src/screens/account/settings/SettingsScreen.tsx
  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
📚 Learning: 2025-09-10T14:47:40.945Z
Learnt from: shazarre
Repo: selfxyz/self PR: 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/components/navbar/HomeNavBar.tsx
  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
📚 Learning: 2025-12-13T18:00:46.963Z
Learnt from: seshanthS
Repo: selfxyz/self PR: 1497
File: app/src/screens/verification/ProveScreen.tsx:125-161
Timestamp: 2025-12-13T18:00:46.963Z
Learning: In app/src/screens/verification/ProveScreen.tsx: The document expiration check using checkDocumentExpiration() is UX-only to prevent wasted gas and provide better user experience. The authoritative expiration validation is enforced in the circuits and smart contracts using trusted time sources (block timestamps), not device clock.

Applied to files:

  • app/src/components/navbar/HomeNavBar.tsx
  • app/src/screens/account/settings/ProofSettingsScreen.tsx
  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/src/navigation/verification.ts
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
  • app/src/navigation/index.tsx
📚 Learning: 2025-11-25T14:06:55.970Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T14:06:55.970Z
Learning: Organize screens by feature modules (passport, home, settings, etc.) with navigation defined in separate files.

Applied to files:

  • app/tests/src/navigation.test.tsx
  • app/src/navigation/account.ts
📚 Learning: 2025-11-25T14:06:55.970Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T14:06:55.970Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use React Navigation with `createStaticNavigation` for type-safe navigation in React Native applications.

Applied to files:

  • app/tests/src/navigation.test.tsx
  • app/src/screens/account/settings/SettingsScreen.tsx
📚 Learning: 2025-12-25T19:19:35.354Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-12-25T19:19:35.354Z
Learning: Applies to packages/mobile-sdk-alpha/**/*.test.{ts,tsx} : Prefer top-level imports over nested requires in test files

Applied to files:

  • app/tests/src/navigation.test.tsx
  • app/tests/src/navigation/deeplinks.test.ts
📚 Learning: 2025-12-25T19:19:04.954Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: app/AGENTS.md:0-0
Timestamp: 2025-12-25T19:19:04.954Z
Learning: Applies to app/**/*.test.{ts,tsx,js,jsx} : Verify no memory leaks introduced, including test memory patterns

Applied to files:

  • app/tests/src/hooks/useEarnPointsFlow.test.ts
  • app/tests/src/navigation/deeplinks.test.ts
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
📚 Learning: 2025-12-25T19:18:22.033Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursor/rules/test-memory-optimization.mdc:0-0
Timestamp: 2025-12-25T19:18:22.033Z
Learning: Applies to **/tests/setup.ts : Use `vi.mock()` instead of `require()` calls in Vitest setup files; ensure React Native mocks are established once at setup time, not during test execution

Applied to files:

  • app/tests/__setup__/mocks/navigation.js
📚 Learning: 2025-12-25T19:18:22.033Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursor/rules/test-memory-optimization.mdc:0-0
Timestamp: 2025-12-25T19:18:22.033Z
Learning: Applies to **/jest.setup.{js,cjs} : Only use `require()` calls in Jest setup files (jest.setup.js) for one-time module mocking and initialization; never create nested require() calls within test execution contexts

Applied to files:

  • app/tests/__setup__/mocks/navigation.js
📚 Learning: 2025-12-25T19:19:35.354Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-12-25T19:19:35.354Z
Learning: Applies to packages/mobile-sdk-alpha/**/*.test.{ts,tsx} : Avoid mocking the entire package in Jest setup or replacing real functions with mock implementations

Applied to files:

  • app/tests/__setup__/mocks/navigation.js
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
📚 Learning: 2025-12-25T19:19:35.354Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-12-25T19:19:35.354Z
Learning: Applies to packages/mobile-sdk-alpha/**/*.test.{ts,tsx} : React Native is mocked in `tests/setup.ts` using `vi.mock()` - use imports in test files instead of require()

Applied to files:

  • app/tests/__setup__/mocks/navigation.js
📚 Learning: 2025-12-25T19:18:22.033Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursor/rules/test-memory-optimization.mdc:0-0
Timestamp: 2025-12-25T19:18:22.033Z
Learning: Use setup file mocks for React Native (jest.setup.js for Jest or tests/setup.ts for Vitest) which run once during test initialization, allowing test files to safely import mocked React Native modules without causing nested require() issues

Applied to files:

  • app/tests/__setup__/mocks/navigation.js
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
📚 Learning: 2025-11-25T14:06:55.970Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T14:06:55.970Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Implement custom modal system with `useModal` hook and callback registry in React Native.

Applied to files:

  • app/tests/__setup__/mocks/navigation.js
  • app/src/screens/account/settings/SettingsScreen.tsx
  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
📚 Learning: 2025-11-25T14:06:55.970Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T14:06:55.970Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use Tamagui for UI components in React Native applications.

Applied to files:

  • app/src/screens/account/settings/SettingsScreen.tsx
  • app/src/screens/account/settings/ProofSettingsScreen.tsx
📚 Learning: 2025-11-25T14:06:55.970Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T14:06:55.970Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Integrate haptic feedback using `useHapticNavigation` hook in React Native navigation.

Applied to files:

  • app/src/screens/account/settings/SettingsScreen.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
📚 Learning: 2025-08-23T02:02:02.556Z
Learnt from: transphorm
Repo: selfxyz/self PR: 942
File: app/vite.config.ts:170-0
Timestamp: 2025-08-23T02:02:02.556Z
Learning: In the selfxyz/self React Native app, devTools from '@/navigation/devTools' are intentionally shipped to production builds for testing purposes, not excluded as is typical in most applications.

Applied to files:

  • app/src/screens/account/settings/SettingsScreen.tsx
  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
📚 Learning: 2025-11-25T14:06:55.970Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T14:06:55.970Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use Zustand for global state management in React Native applications.

Applied to files:

  • app/src/screens/account/settings/SettingsScreen.tsx
📚 Learning: 2025-11-25T14:06:55.970Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T14:06:55.970Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use custom hooks for complex state (`useModal`, `useHapticNavigation`) instead of inline logic.

Applied to files:

  • app/src/screens/account/settings/SettingsScreen.tsx
  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
📚 Learning: 2025-08-26T14:49:11.190Z
Learnt from: shazarre
Repo: selfxyz/self PR: 936
File: app/src/screens/passport/PassportNFCScanScreen.tsx:28-31
Timestamp: 2025-08-26T14:49:11.190Z
Learning: SelfClientProvider is wrapped in app/App.tsx, providing context for useSelfClient() hook usage throughout the React Native app navigation stacks.

Applied to files:

  • app/src/screens/account/settings/SettingsScreen.tsx
  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
📚 Learning: 2025-11-25T14:07:28.188Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursor/rules/compliance-verification.mdc:0-0
Timestamp: 2025-11-25T14:07:28.188Z
Learning: Applies to **/{mobile,client,app,proof,zk}/**/*.{ts,tsx,js,swift,kt} : Include trusted time anchor in proof generation and verify time anchor authenticity before proof generation in mobile implementations

Applied to files:

  • app/src/screens/account/settings/ProofSettingsScreen.tsx
  • app/src/navigation/verification.ts
  • app/src/navigation/account.ts
📚 Learning: 2025-11-25T14:06:55.970Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T14:06:55.970Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Implement lazy loading for screens using `React.lazy()` in React Native applications.

Applied to files:

  • app/src/screens/account/settings/ProofSettingsScreen.tsx
  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
📚 Learning: 2025-11-25T14:06:55.970Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T14:06:55.970Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Implement certificate validation for passport data verification.

Applied to files:

  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
📚 Learning: 2025-10-23T12:08:55.529Z
Learnt from: shazarre
Repo: selfxyz/self PR: 1236
File: packages/mobile-sdk-alpha/src/flows/onboarding/document-nfc-screen.tsx:356-378
Timestamp: 2025-10-23T12:08:55.529Z
Learning: In packages/mobile-sdk-alpha/src/flows/onboarding/document-nfc-screen.tsx, the NFC native events emitted via NativeEventEmitter are generic status strings (e.g., "PACE succeeded", "BAC failed", "Reading DG1 succeeded") and do not contain sensitive MRZ data or passport numbers, so they do not require sanitization before logging.

Applied to files:

  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
📚 Learning: 2025-11-25T14:06:55.970Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T14:06:55.970Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Lazy load screens and components to optimize bundle size in React Native.

Applied to files:

  • app/src/screens/verification/DocumentSelectorForProvingScreen.tsx
📚 Learning: 2025-12-25T19:19:35.354Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-12-25T19:19:35.354Z
Learning: Applies to packages/mobile-sdk-alpha/**/*.test.{ts,tsx} : Verify `extractMRZInfo()` using published sample MRZ strings (e.g., ICAO examples)

Applied to files:

  • app/src/navigation/verification.ts
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
📚 Learning: 2025-11-25T14:07:28.188Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursor/rules/compliance-verification.mdc:0-0
Timestamp: 2025-11-25T14:07:28.188Z
Learning: Applies to **/{mobile,client,app,proof,zk}/**/*.{ts,tsx,js,swift,kt} : Achieve proof generation in <60 seconds on mid-tier mobile devices

Applied to files:

  • app/src/navigation/verification.ts
📚 Learning: 2025-12-25T19:19:35.354Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-12-25T19:19:35.354Z
Learning: Applies to packages/mobile-sdk-alpha/**/*.test.{ts,tsx} : Use real imports from `selfxyz/mobile-sdk-alpha` in tests instead of mocking the entire package

Applied to files:

  • app/tests/src/navigation/deeplinks.test.ts
  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
📚 Learning: 2025-11-25T14:08:34.041Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: noir/AGENTS.md:0-0
Timestamp: 2025-11-25T14:08:34.041Z
Learning: Applies to noir/**/*.nr : Proof generation must still work and verification must pass for all test cases after changes

Applied to files:

  • app/tests/src/navigation/deeplinks.test.ts
📚 Learning: 2025-12-25T19:19:35.354Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-12-25T19:19:35.354Z
Learning: Applies to packages/mobile-sdk-alpha/**/*.test.{ts,tsx} : Use ES6 `import` statements instead of `require()` when possible

Applied to files:

  • app/tests/src/navigation/deeplinks.test.ts
📚 Learning: 2025-12-25T19:19:35.354Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-12-25T19:19:35.354Z
Learning: Applies to packages/mobile-sdk-alpha/**/*.test.{ts,tsx} : Test `isPassportDataValid()` with realistic, synthetic passport data (never use real user data)

Applied to files:

  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
📚 Learning: 2025-12-25T19:19:04.954Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: app/AGENTS.md:0-0
Timestamp: 2025-12-25T19:19:04.954Z
Learning: Applies to app/**/*.test.{ts,tsx,js,jsx} : Ensure `yarn test` passes (unit tests) before creating a PR

Applied to files:

  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
📚 Learning: 2025-12-25T19:19:35.354Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-12-25T19:19:35.354Z
Learning: Applies to packages/mobile-sdk-alpha/**/*.test.{ts,tsx} : Write integration tests that exercise real validation logic from the SDK

Applied to files:

  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
📚 Learning: 2025-12-25T19:19:35.354Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-12-25T19:19:35.354Z
Learning: Applies to packages/mobile-sdk-alpha/**/*.test.{ts,tsx} : Test both React Native and Web environments when adding platform-specific code

Applied to files:

  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
📚 Learning: 2025-11-25T14:06:55.970Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T14:06:55.970Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Test error boundaries and recovery mechanisms in React components.

Applied to files:

  • app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx
📚 Learning: 2025-07-16T02:20:44.173Z
Learnt from: transphorm
Repo: selfxyz/self PR: 636
File: app/src/components/native/QRCodeScanner.tsx:135-142
Timestamp: 2025-07-16T02:20:44.173Z
Learning: In app/src/components/native/QRCodeScanner.tsx, the Android camera dimension multipliers (screenWidth * 3 and screenHeight * 2) are intentionally set to these values and should not be changed. These multipliers are correct and any visual issues with black areas in the camera preview are caused by other factors, not the dimension calculations.

Applied to files:

  • app/src/screens/verification/QRCodeViewFinderScreen.tsx
🧬 Code graph analysis (2)
app/src/navigation/account.ts (2)
app/src/screens/account/settings/ProofSettingsScreen.tsx (1)
  • ProofSettingsScreen (130-130)
packages/mobile-sdk-alpha/src/constants/colors.ts (2)
  • white (59-59)
  • black (8-8)
app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx (3)
packages/mobile-sdk-demo/src/navigation/NavigationProvider.tsx (1)
  • useNavigation (110-116)
app/src/providers/passportDataProvider.tsx (1)
  • usePassport (861-863)
app/src/stores/settingStore.ts (1)
  • useSettingStore (58-168)
🔇 Additional comments (19)
app/tests/__setup__/mocks/navigation.js (1)

12-28: LGTM - Good improvement to prevent infinite render loops!

The WeakSet-based approach correctly tracks callback instances and prevents duplicate invocations. This simulates real focus effect behavior while avoiding test instability from state updates triggering re-renders.

app/tests/src/navigation/deeplinks.test.ts (2)

72-97: Test expectations correctly updated for selfApp parameter flow.

The test now expects navigation to DocumentSelectorForProving instead of Prove, matching the new routing behavior.


99-123: Test expectations correctly updated for sessionId parameter flow.

Consistent with the selfApp flow, this test now expects navigation to DocumentSelectorForProving.

app/tests/src/navigation.test.tsx (1)

32-93: LGTM - Navigation screen registry correctly updated.

The test now includes the two new screens (DocumentSelectorForProving and ProofSettings) in the expected list, maintaining alphabetical order. This ensures the navigation configuration matches expectations.

app/src/hooks/useEarnPointsFlow.ts (1)

37-45: Navigation routing is correctly implemented across all entry points.

Verified that all entry points to the proving flow route through DocumentSelectorForProving:

  • Points flow (useEarnPointsFlow) → DocumentSelectorForProving
  • QR scan (QRCodeViewFinderScreen) → DocumentSelectorForProving
  • Deeplinks → DocumentSelectorForProving
  • Home navbar → DocumentSelectorForProving

The only direct navigate('Prove') call is from within DocumentSelectorForProvingScreen itself after document selection, which is the correct pattern. Navigation architecture is consistent across all entry points.

app/src/components/navbar/HomeNavBar.tsx (1)

59-59: LGTM! Navigation update is correct.

The change correctly routes the token consumption flow through the new DocumentSelectorForProving screen, aligning with the PR's objective to ensure document selection before proving.

app/src/navigation/deeplinks.ts (1)

129-132: LGTM! Deeplink routing correctly updated.

Both deeplink navigation paths now properly route through DocumentSelectorForProving, ensuring users select a valid document before entering the proof flow. The parentScreen parameter is preserved correctly in both cases.

Also applies to: 149-152

app/src/screens/verification/QRCodeViewFinderScreen.tsx (1)

51-53: LGTM! QR scan flow correctly updated.

The variable rename from navigateToProve to navigateToDocumentSelector is consistent throughout the file. All call sites and the useCallback dependency array have been properly updated to reflect the new navigation target.

Also applies to: 96-96, 120-120, 134-140

app/src/navigation/account.ts (1)

19-19: LGTM! ProofSettings screen properly registered.

The new ProofSettings screen is correctly registered in the account navigation stack with appropriate header styling that matches the existing pattern used by other settings screens in this file.

Also applies to: 69-80

app/src/screens/account/settings/SettingsScreen.tsx (1)

15-15: LGTM! Proof settings menu item properly added.

The new "Proof settings" menu item is correctly added to both web and non-web route configurations following the existing pattern. The Settings2 icon import and type assertion are consistent with the FileText icon usage elsewhere in the file.

Also applies to: 81-81, 92-92

app/src/navigation/index.tsx (1)

76-77: LGTM! Navigation types properly extended.

The new DocumentSelectorForProving and ProofSettings routes are correctly added to the RootStackParamList with undefined params, following the existing pattern for screens that don't require navigation parameters.

Also applies to: 146-154

app/src/screens/account/settings/ProofSettingsScreen.tsx (1)

20-85: Clean settings screen implementation.

The component properly manages the toggle states with clear UX feedback when skipDocumentSelector is enabled (disabling the second toggle and showing explanatory text). TestIDs are present for testing. The use of Tamagui components aligns with coding guidelines.

app/src/navigation/verification.ts (1)

24-36: Navigation configuration looks good.

The gestureEnabled: false setting appropriately prevents accidental swipe-back during the proof flow. Header styling is consistent with the adjacent Prove screen.

app/src/stores/settingStore.ts (1)

142-148: Store additions are straightforward.

The new skipDocumentSelector and skipDocumentSelectorIfSingle settings are simple boolean flags with sensible defaults. They're correctly integrated into the persisted state and contain no sensitive data.

app/src/screens/verification/DocumentSelectorForProvingScreen.tsx (2)

176-224: Solid async handling with proper cleanup.

The AbortController pattern is correctly implemented:

  • Cancels in-flight requests on re-invocation
  • Checks signal.aborted before state updates
  • Cleanup on unmount via useEffect return

This prevents race conditions and memory leaks from stale async operations.


252-292: Auto-redirect logic is well-guarded.

The hasAttemptedSkipRef ref prevents infinite redirect loops, and the effect properly:

  • Guards against loading/error states
  • Handles the no-documents case by redirecting to onboarding
  • Catches auto-select errors and resets the flag for retry
app/tests/src/screens/verification/DocumentSelectorForProvingScreen.test.tsx (3)

97-130: Good test setup with stable mock objects.

The stable mock objects pattern prevents infinite re-renders during tests, which is a common pitfall when testing React components with hooks. The separation of mock functions from stable context objects allows for proper jest.clearAllMocks() behavior.


463-474: Console mocking properly implemented.

Error and warning scenarios correctly mock console.warn/console.error and restore them after each test, following the guideline to mock console.error to avoid test output clutter while testing error scenarios.

Also applies to: 497-518, 537-563


565-763: Comprehensive skip settings test coverage.

The skip settings describe block covers all important scenarios:

  • Redirect when no valid documents
  • Skip with skipDocumentSelector: true
  • Skip with single document and skipDocumentSelectorIfSingle: true
  • No skip with multiple documents
  • "Preparing proof..." UI state
  • Graceful error handling during auto-select

This provides good confidence in the auto-redirect logic.

Comment on lines +155 to +162
if (selectedMeta && selectedData) {
const state = determineDocumentState(selectedMeta, selectedData.data);
if (!isDisabledState(state)) {
return catalog.selectedDocumentId;
}
} else if (selectedMeta) {
return catalog.selectedDocumentId;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Potential edge case: returning document ID without data.

When selectedMeta exists but selectedData is undefined (line 160-162), the function returns the catalog.selectedDocumentId. This could result in selecting a document whose data hasn't loaded yet, potentially causing issues downstream if the document data is required for validation.

Suggested fix
-        } else if (selectedMeta) {
-          return catalog.selectedDocumentId;
-        }
+        // Only return if metadata exists but we couldn't determine state
+        // (data may still be loading - fall through to find first valid)

Alternatively, if this is intentional behavior (e.g., metadata alone is sufficient), consider adding a comment explaining why.

🤖 Prompt for AI Agents
In @app/src/screens/verification/DocumentSelectorForProvingScreen.tsx around
lines 155 - 162, The code can return catalog.selectedDocumentId when
selectedMeta exists but selectedData is undefined, which may select a document
whose data hasn't loaded; update the logic in DocumentSelectorForProvingScreen
to only return catalog.selectedDocumentId if selectedData is present and
determineDocumentState(selectedMeta, selectedData.data) is not a disabled state
(i.e., require both selectedMeta and selectedData before returning), or if
metadata-only selection is truly intended, add an explicit comment near the
selectedMeta branch documenting that metadata suffices and why; reference the
symbols selectedMeta, selectedData, catalog.selectedDocumentId,
determineDocumentState, and isDisabledState when making the change.

@transphorm transphorm merged commit d28cf5a into justin/self-1754-proving-screen-selective-disclosure Jan 8, 2026
6 checks passed
@transphorm transphorm deleted the codex/create-documentselectorforprovingscreen branch January 8, 2026 02:33
transphorm added a commit that referenced this pull request Jan 9, 2026
* add document selector test screen

* clean up mock docs

* update selection options

* Add DocumentSelectorForProving screen and route proof flows through it (#1555)

* Add document selector to proving flow

* fix formatting

* improvements

* redirect user to document not found screen when no documents

* option flow tweaks and tests

* wip tweaks

* fix scrollview bottom padding (#1556)

* tighten up selection text

* create inerstitial

* save wip

* remove not accepted state

* save wip design

* formatting

* update design

* update layout

* Update proving flow tests (#1559)

* Refactor ProveScreen to ProofRequestCard layout and preserve scroll position (#1560)

* Refactor prove screen layout

* fix: amount of hooks rendered needs to be the same for all variants

* long URL ellipsis

* keep titles consistent

* lint

---------

Co-authored-by: Leszek Stachowski <[email protected]>

* wip fix tests

* fix tests

* formatting

* agent feedback

* fix tests

* save wip

* remove text

* fix types

* save working header update

* no transition

* cache document load for proving flow

* save fixes

* small fixes

* match disclosure text

* design updates

* fix approve flow

* fix document type flash

* add min height so text doesn't jump

* update lock

* formatting

* save refactor wip

* don't enable euclid yet

* fix tests

* fix staleness check

* fix select box description

* remove id selector screen

* vertically center

* button updates

* Remove proving document cache (#1567)

* formatting

---------

Co-authored-by: Leszek Stachowski <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants