Implement GoTrue error code mapper
epic-email-password-login-auth-logic-task-002 — Implement a mapping function that translates GoTrue/Supabase Auth error codes and messages into typed domain exceptions. Must distinguish: invalid credentials (wrong password/email), network failures (timeout, no connectivity), rate limiting (429 responses), and server errors (5xx). This mapping is the core of plain-language error feedback.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 1 - 540 tasks
Can start after Tier 0 completes
Implementation Notes
Inspect supabase_flutter's AuthException class: it exposes `statusCode` (String?) and `message` (String). GoTrue error codes are documented at gotrue-js; common ones: 'invalid_credentials', 'email_not_confirmed', 'user_not_found'. Treat 'user_not_found' identically to 'invalid_credentials' to prevent account enumeration attacks — this is a security requirement aligned with WCAG 2.2 and general auth best practice. For the SocketException catch, check dart:io imports are only in the data layer.
The mapper is intentionally isolated so it can be unit-tested without a Supabase instance. Use a switch expression (Dart 3) on exception type + status code for clean exhaustive handling. Document each mapping rule with a comment referencing the GoTrue error code.
Testing Requirements
Unit tests in test/features/auth/data/gotrue_error_mapper_test.dart. Parameterized tests covering: (1) AuthException with each known invalid-credentials error code. (2) AuthException with each known email-not-confirmed code. (3) SocketException → NetworkFailureException with isTimeout: false.
(4) TimeoutException → NetworkFailureException with isTimeout: true. (5) AuthException with statusCode 429 → RateLimitException. (6) AuthException with statusCode 500 → ServerErrorException. (7) Unknown exception type → ServerErrorException fallback.
Use dart:io stubs, no Flutter widget test runner needed. 100% branch coverage required.
Supabase GoTrue returns HTTP error codes and string messages that may change between SDK versions. Incorrect or incomplete mapping could cause the wrong user-facing message to be shown (e.g., showing a generic error instead of a specific credential error), violating the plain-language feedback acceptance criteria and potentially exposing security-sensitive information.
Mitigation & Contingency
Mitigation: Pin the supabase_flutter SDK to a specific minor version in pubspec.yaml. Write integration tests that mock the Supabase HTTP layer and assert each error code maps to the correct domain exception. Document the mapping table as a constant in AuthService.
Contingency: If an unrecognized error code is received at runtime, catch it as an UnknownAuthException and display a generic safe message. Alert via crash reporting for triage and SDK update.
If the user taps the sign-in button multiple times rapidly, concurrent authentication requests could result in race conditions: duplicate network calls, out-of-order state emissions, or multiple session tokens being written to secure storage.
Mitigation & Contingency
Mitigation: Use bloc concurrency transformer (droppable or restartable) to ensure only one authentication event is processed at a time. The BLoC should guard against submission while in LoginLoading state.
Contingency: Add a UI-level disable on the submit button when loading state is active as a secondary guard independent of BLoC concurrency control.