Files
Kordant/tasks/shieldai-unified-restructure/36-android-auth-onboarding.md
2026-05-25 12:23:23 -04:00

123 lines
6.3 KiB
Markdown

# 36. Android App — Authentication, Onboarding, and Account Setup
meta:
id: shieldai-unified-restructure-36
feature: shieldai-unified-restructure
priority: P1
depends_on: [shieldai-unified-restructure-34, shieldai-unified-restructure-35]
tags: [android, jetpack-compose, auth, onboarding, mobile]
objective:
- Build the authentication and onboarding flow for the Android app: login, signup, password reset, and a multi-step onboarding experience. Use native Android authentication where possible (Google Sign-In, Credential Manager) and maintain visual consistency with the web app.
deliverables:
- `android/app/src/main/java/com/shieldai/android/ui/screens/auth/` — Auth screens:
- `AuthScreen.kt` — Auth container with login/signup toggle
- `LoginScreen.kt` — Email + password login form
- `SignupScreen.kt` — Account creation form
- `ForgotPasswordScreen.kt` — Password reset request
- `ResetPasswordScreen.kt` — Password reset confirmation
- `android/app/src/main/java/com/shieldai/android/ui/screens/onboarding/` — Onboarding:
- `OnboardingScreen.kt` — Horizontal pager with 4 steps
- `PlanSelectionStep.kt` — Tier cards (Basic, Plus, Premium)
- `WatchlistSetupStep.kt` — Add first email/phone
- `FamilyInviteStep.kt` — Invite family members
- `CompleteStep.kt` — Success animation and "Get Started"
- `android/app/src/main/java/com/shieldai/android/ui/screens/auth/BiometricAuthScreen.kt` — Biometric prompt:
- Uses `BiometricPrompt` from `androidx.biometric:biometric`
- Face/fingerprint authentication
- Fallback to device credential
- `android/app/src/main/java/com/shieldai/android/viewmodel/AuthViewModel.kt` — Auth logic:
- `login(email, password)` → calls API (task 37)
- `signup(name, email, password)` → calls API
- `resetPassword(email)` → calls API
- `signInWithGoogle()` → Google Sign-In
- `enableBiometricAuth()` → stores credential in EncryptedSharedPreferences
- `logout()` → clears tokens and state
- `android/app/src/main/java/com/shieldai/android/data/repository/AuthRepository.kt` — Data layer:
- Token storage in `EncryptedSharedPreferences`
- API calls via repository pattern
steps:
1. Create auth and onboarding screen directories.
2. **AuthScreen**:
- `Column` with ShieldAI logo and tagline
- `TabRow` or custom toggle for Login/Signup
- `ShieldCard` containing the form
3. **LoginScreen**:
- `ShieldTextField` for email and password
- "Remember me" `Switch`
- "Forgot password?" `TextButton`
- "Sign In" `ShieldButton`
- Google Sign-In button (Material `Button` with Google icon)
- On success: store JWT in `EncryptedSharedPreferences`, navigate to main app
4. **SignupScreen**:
- Additional fields: name, confirm password
- Password strength indicator using `ShieldProgressBar`
- Terms `Checkbox` (required)
- "Create Account" `ShieldButton`
5. **ForgotPasswordScreen**:
- Email `ShieldTextField` + submit
- Success state with instructions
6. **OnboardingScreen**:
- `HorizontalPager` from `androidx.compose.foundation:pager`
- 4 pages with `PageIndicator` dots at bottom
- Step 1: Plan cards with feature comparison
- Step 2: Input for email/phone with "Add" button
- Step 3: Email inputs for family invites with "Skip" button
- Step 4: Success animation using `Lottie` or Compose animation
- "Get Started" button navigates to Dashboard
7. **BiometricAuthScreen**:
- `BiometricPrompt` setup with `BiometricManager`
- `setDeviceCredentialAllowed(true)` for fallback
- On success: store "useBiometric" flag and credential in `EncryptedSharedPreferences`
- Show prompt on app launch if enabled
8. **AuthViewModel**:
- `ViewModel` with `StateFlow` for UI state (`Loading`, `Success`, `Error`)
- `login()`, `signup()`, etc. methods
- `signInWithGoogle()` using `com.google.android.gms:play-services-auth`
- Token management: save to `EncryptedSharedPreferences`, include in API calls
9. **AuthRepository**:
- Interface + implementation
- `login(email, password)` returns `Result<AuthToken>`
- `saveToken(token)`, `getToken()`, `clearToken()`
10. Wire auth state to navigation:
- `MainActivity` observes auth state
- Unauthenticated → show LoginScreen
- Authenticated but new → show OnboardingScreen
- Authenticated → show Dashboard
steps:
- Unit: AuthViewModel emits correct states for login/signup
- Unit: Password strength calculator returns correct level
- Unit: Onboarding pager advances and collects data
- Integration: Google Sign-In button triggers auth flow
- E2E: Complete login → onboarding → main app flow
acceptance_criteria:
- [ ] Login screen accepts email/password and authenticates via API
- [ ] Signup screen validates inputs and creates account via API
- [ ] Password reset flow sends request to API and shows success state
- [ ] Onboarding has 4 steps with pager indicator and swipe navigation
- [ ] Google Sign-In button works and authenticates user
- [ ] Biometric auth (face/fingerprint) can be enabled after first login
- [ ] Tokens are stored securely in EncryptedSharedPreferences
- [ ] Logout clears all auth state and returns to login screen
- [ ] Auth flow matches web app visual style
validation:
- Run app on emulator, complete login with test credentials
- Verify JWT stored in EncryptedSharedPreferences (use Android Studio Database Inspector or log)
- Test Google Sign-In flow (emulator supports mock Google account)
- Complete onboarding and verify data sent to API
- Test biometric prompt on device (emulator can simulate with Extended Controls)
- Run `./gradlew test` for unit tests
notes:
- Credential Manager (`androidx.credentials:credentials`) is the modern replacement for Google Sign-In. Use it if targeting API 34+; otherwise, use `play-services-auth`.
- `EncryptedSharedPreferences` from `androidx.security:security-crypto` is the standard for secure token storage.
- The onboarding data should be collected in a ViewModel state and submitted to the API at the final step.
- For the success animation in onboarding, consider using Lottie (`com.airbnb.android:lottie-compose`) with a checkmark animation.
- The `BiometricPrompt` should be shown as a system dialog, not a custom screen. The `BiometricAuthScreen.kt` is just a wrapper/helper.
- Handle configuration changes (rotation) correctly: ViewModel survives, but UI state should be restored.