Files
self/docs/development-patterns.md
Justin Hernandez bd8d425cc7 SELF-763: remove aesop features for now (#1132)
* clean onboarding camera screens

* remove remaining aesop artifacts. fix tests
2025-09-28 07:55:11 -07:00

205 lines
5.6 KiB
Markdown

# Self App Development Patterns
## React Native Architecture
### Navigation System
The app uses `@react-navigation/native` with `createStaticNavigation` for type-safe navigation. Screens are organized by feature modules and use platform-specific initial routes.
```typescript
// Navigation setup pattern
export const navigationScreens = {
...systemScreens,
...passportScreens,
...homeScreens,
...proveScreens,
...settingsScreens,
...recoveryScreens,
...devScreens,
};
// Platform-specific initial routes
initialRouteName: Platform.OS === 'web' ? 'Home' : 'Splash'
```
### Modal System
Custom modal system using `useModal` hook with callback registry for handling button presses and dismissals.
```typescript
const { showModal, dismissModal, visible } = useModal({
titleText: 'Modal Title',
bodyText: 'Modal content',
buttonText: 'Action',
onButtonPress: async () => {
// Handle button press
},
onModalDismiss: () => {
// Handle modal dismiss
},
});
```
### Platform-Specific Handling
Always check platform before implementing platform-specific code:
```typescript
if (Platform.OS === 'ios') {
// iOS-specific implementation
} else {
// Android-specific implementation
}
```
### Native Module Initialization
Critical for NFC and other native functionality:
```typescript
// Initialize native modules before any native operations
const modulesReady = await initializeNativeModules();
if (!modulesReady) {
console.warn('Native modules not ready, proceeding with limited functionality');
}
```
## State Management
### Hook-Based State
- Custom hooks for complex state management (`useModal`, `useHapticNavigation`)
- Zustand for global state management
- React Navigation state for screen-specific data
### Data Persistence
- **AsyncStorage**: Simple key-value storage
- **SQLite**: Complex data (proof history)
- **Keychain**: Sensitive data (biometrics, encryption keys)
## Testing Conventions
### Jest Configuration
- Comprehensive mocks in `jest.setup.js` for all native modules
- Module mapping for clean imports
- Test-specific TypeScript configuration
### Mock Patterns
All React Native native modules are mocked with realistic return values:
```javascript
jest.mock('react-native-keychain', () => ({
SECURITY_LEVEL_ANY: 'MOCK_SECURITY_LEVEL_ANY',
setGenericPassword: jest.fn(),
getGenericPassword: jest.fn(),
resetGenericPassword: jest.fn(),
ACCESSIBLE: {
WHEN_UNLOCKED: 'AccessibleWhenUnlocked',
// ... other constants
},
}));
```
### Testing Patterns
- Use `renderHook` for custom hook testing
- Mock console.error to avoid test output clutter
- Test error boundaries and recovery mechanisms
- E2E testing with Maestro for platform-specific flows
## NFC Implementation
### Cross-Platform Architecture
- **iOS**: Custom PassportReader Swift module
- **Android**: Custom RNPassportReaderModule Kotlin implementation
- Unified JavaScript interface with platform detection
### Authentication Methods
- **MRZ Key**: Derived from passport number, DOB, and expiry date
- **CAN (Card Access Number)**: 6-digit number for PACE authentication
- **PACE**: Password Authenticated Connection Establishment
- **BAC Fallback**: Basic Access Control when PACE fails
### Error Handling
- Multiple BAC attempts with delays
- Graceful degradation from PACE to BAC
- Real-time status updates and haptic feedback
- Comprehensive error boundaries
### JavaScript Interface
```typescript
export const scan = async (inputs: Inputs) => {
return Platform.OS === 'android'
? await scanAndroid(inputs)
: await scanIOS(inputs);
};
```
## Code Organization
### File Structure
```
src/
├── components/ # Reusable UI components
├── screens/ # Screen components by feature
├── navigation/ # Navigation configuration
├── hooks/ # Custom React hooks
├── utils/ # Shared utilities
├── types/ # TypeScript type definitions
├── stores/ # State management
└── providers/ # Context providers
```
### Import Patterns
- Use `@/` alias for src imports: `import { Component } from '@/components'`
- Use `@tests/` alias for test imports: `import { mockData } from '@tests/utils'`
- Platform-specific imports with conditional rendering
## Build & Deployment
### Scripts
- `yarn ios` / `yarn android` for platform-specific builds
- `yarn test` for Jest testing
- `yarn test:e2e:ios` / `yarn test:e2e:android` for E2E
- Fastlane for deployment automation
### Dependencies
- Yarn workspaces for monorepo management
- Platform-specific native modules
- Tamagui for UI components
- React Navigation for routing
## Security & Privacy
### Data Protection
- Sensitive data not logged in production
- Secure storage with Keychain
- Proper cleanup of sensitive data
- Certificate validation for passport data
### Privacy Features
- Zero-knowledge proof generation
- Selective attribute revelation
- Privacy-preserving age verification
- Identity commitment privacy
## Common Patterns
### Error Handling
```typescript
try {
const result = await riskyOperation();
return result;
} catch (error) {
console.error('Operation failed:', error);
// Graceful degradation
return fallbackValue;
}
```
### Performance Optimization
- Lazy load screens and components
- Bundle size optimization with tree shaking
- Memory leak prevention in native modules
- Proper cleanup in useEffect and component unmount
### Platform Differences
- Always check Platform.OS before platform-specific code
- Different implementations for iOS/Android when needed
- Platform-specific testing strategies
- Conditional rendering for platform differences