Files
self/docs/development-patterns.md
Justin Hernandez 7dbd46f245 Add docstring reporting script and workflows (#1333)
* Trim docstring coverage snapshots

* format all the tings

* update lock

* Update docstring coverage snapshots (#1521)

* docstring fixes

* address agent feedback

* update lock files

* address agent feedback

* lock react-native-svg version to prevent pipeline failures

* update docstring logic

* remove docstring coverage from ci

* remove old report, fix cursorignroe rule
2025-12-25 11:17:42 -08:00

214 lines
6.4 KiB
Markdown

# Self App Development Patterns
## Docstring coverage workflow
- Run `yarn docstrings` to check documentation coverage for both the mobile app and SDK. This generates `docs/coverage/app.json` and `docs/coverage/sdk.json` so you can diff coverage changes in version control.
- Run `yarn docstrings:app` to check only the mobile app exports.
- Run `yarn docstrings:sdk` to focus on `@selfxyz/mobile-sdk-alpha` only.
- Add `--details` to any command when you want a full per-file JSON breakdown for ad-hoc analysis—the default snapshots include only top-level totals and a small sample of undocumented exports to keep the tracked files compact.
Run the docstring reports locally before committing to track coverage changes. The reports are advisory—use them to identify documentation gaps but they won't block builds.
## 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