Implement Auth Repository Sign-In and Sign-Out
epic-email-password-login-foundation-task-008 — Add signInWithEmailAndPassword and signOut methods to AuthRepository. signIn calls the Supabase GoTrueClient, caches the returned session via the encrypted storage adapter, and returns a typed AuthResult. signOut calls Supabase, clears all cached tokens, and resets local state. Map Supabase error codes to domain-level AuthError types.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 3 - 413 tasks
Can start after Tier 2 completes
Implementation Notes
Define a private _mapSupabaseError(AuthException e) helper that switches on e.statusCode and e.message to return the correct AuthError. This keeps the sign-in method readable. For signOut, use a try/finally pattern: always execute storage.deleteToken() in the finally block so local state is cleared regardless of network outcome. Use Supabase's AuthException type specifically rather than catching dynamic/Object.
Coordinate with task-007 so the same encrypted storage adapter instance is injected via constructor — do not create a second instance. Consider adding a currentUser getter that reads from the in-memory Supabase session rather than re-reading storage on every call.
Testing Requirements
Unit tests must cover: successful sign-in maps to AuthResult.success and writes to storage; each mapped Supabase error code produces the correct AuthError variant; signOut deletes the stored token even when the Supabase call throws. Use mockito or mocktail to mock SupabaseClient and the encrypted storage adapter. Do not make real network calls. Verify that the password value is not accessible after the signIn call completes (scope check).
Target 100% branch coverage on both methods.
Supabase client initialization may fail silently in certain Flutter environments if environment variables are missing or the anon key is rotated, leading to runtime null-pointer errors throughout the auth layer.
Mitigation & Contingency
Mitigation: Add explicit assertion checks during app startup that verify the Supabase client is initialized before the router resolves. Document required --dart-define keys in the project README and add a CI step that validates their presence.
Contingency: Implement a fallback initialization error screen with a clear message and a retry button. Log initialization failures to crash reporting immediately.
The flutter_secure_storage package behaviour differs between iOS Keychain and Android Keystore implementations. On Android, biometric-enrolled devices may require additional authentication to read stored tokens, causing unexpected session read failures.
Mitigation & Contingency
Mitigation: Test the repository on Android devices with and without biometric enrollment early in development. Use accessibility options in flutter_secure_storage to configure whether biometric authentication is required for storage access.
Contingency: If biometric-gated storage causes regressions, fall back to a non-biometric storage option for session tokens (reserving biometric-gated storage for higher-sensitivity credentials only).