- OTP Generation:
/auth/otp/generate - OTP Verification:
/auth/otp/verify
-
LoginScreen
- Handles phone number input (10 digits)
- Formats number with +91 prefix
- Uses loading states during API calls
- Proper error handling with user-friendly messages
-
OTPScreen
- 6-digit OTP verification
- 60-second resend timer
- Handles loading states
- Error handling for invalid OTPs
- Navigation logic based on onboarding status
- API calls wrapped in try/catch blocks
- Specific error messages for different failure cases
- Loading states properly managed in try/catch/finally blocks
- User-friendly error messages displayed via Alert
All API service methods follow this error handling pattern:
try {
const response = await apiClient.request(...);
return response.data;
} catch (error) {
console.error('Operation name error:', error);
throw error; // Re-throw for component layer handling
}Benefits:
- Consistent error logging across all API calls
- Error details preserved for UI layer handling
- Clear error context in logs for debugging
Components should handle API errors by:
- Using try/catch blocks around API calls
- Dispatching error state to Redux if needed
- Showing user-friendly error messages via Alert
- Setting loading states appropriately
Example:
try {
dispatch(setLoading(true));
await api.someOperation();
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Operation failed';
dispatch(setError(errorMessage));
Alert.alert('Error', errorMessage);
} finally {
dispatch(setLoading(false));
}- Login → OTP Screen
- After OTP verification:
- If onboarding complete → Home
- If onboarding incomplete → Age Screen
- Fallback to Age Screen if status check fails
-
Authentication Flow:
- 'Login' - Phone number input
- 'OTP' - OTP verification
-
Onboarding Flow:
- 'OnboardingAge' - Age verification
- 'OnboardingProfile' - User profile
- 'OnboardingPurpose' - User goals
- 'OnboardingIncome' - Income range
- 'OnboardingSpending' - Spending habits
- 'OnboardingSavings' - Savings goals
- 'OnboardingKyc' - KYC information
- 'OnboardingKycDocument' - Document upload
- 'OnboardingKycStatus' - KYC status
-
Main App:
- 'Home' - Main dashboard
- All routes defined in
navigation/types.ts - Type-safe navigation using
RootStackParamList - Screen props typed with
RootStackScreenProps
-
Components
- Balance Card
- Shows current wallet balance
- Quick action buttons
- Recent Transactions
- List of latest transactions
- Transaction type indicators
- Quick Actions
- Send Money
- Request Money
- Scan QR
- View History
- Balance Card
-
API Integration
- GET /api/wallet/balance for wallet info
- Transaction history endpoint for recent activities
- User profile data for personalization
-
Redux Integration
- Wallet slice for balance management
- Transaction slice for history
- Loading states management
-
Navigation
- Tab navigation root
- Stack navigation for action flows
- Modal screens for quick actions
-
Error Handling
- Balance fetch retry mechanism
- Transaction list error states
- Offline mode indicators
- Refresh functionality
The backend validation middleware expects request data in this format:
{
body: {
// request data here
}
}The middleware automatically wraps the request data in a body object, so the frontend should send data directly:
✅ Correct way:
// Frontend API call
apiClient.post('/onboarding/age', { age: 21 });
// Backend receives:
{
body: {
age: 21
}
}❌ Wrong way:
// Frontend API call
apiClient.post('/onboarding/age', { body: { age: 21 } });
// Backend receives:
{
body: {
body: {
age: 21 // Extra nesting causes validation error!
}
}
}Examples of correct API calls:
- Profile Update:
apiClient.post('/onboarding/profile', {
firstName: string,
lastName: string,
email: string,
panNumber: string // Format: ABCDE1234F
});- Age Update:
apiClient.post('/onboarding/age', {
age: number // between 18 and 60
});- Primary Goal:
apiClient.post('/onboarding/primary-goal', {
primaryGoal: UserGoal // enum value
});- Income Range:
apiClient.post('/onboarding/income-range', {
incomeRange: IncomeRange // enum value
});- Spending Habits:
apiClient.post('/onboarding/spending-habits', {
spendingHabit: SpendingHabit, // enum value
targetSpendingPercentage: number // 0-100
});-
Store Configuration (
src/store/store.ts):- Configures Redux store with reducers
- Exports typed hooks: useAppDispatch, useAppSelector
- Exports RootState and AppDispatch types
-
Auth Slice (
src/store/slices/authSlice.ts):- Manages authentication state
- Actions: setCredentials, setLoading, setError, logout
- Stores user data and token
-
Onboarding Slice (
src/store/slices/onboardingSlice.ts):- Manages onboarding flow state
- Tracks completion of onboarding steps
-
Usage in Components:
- Import hooks from store:
import { useAppDispatch, useAppSelector, RootState } from '../../store/store' - Import actions from slices:
import { setCredentials, setLoading } from '../../store/slices/authSlice' - Type state in selectors:
useAppSelector((state: RootState) => state.auth)
- Import hooks from store: