critical priority medium complexity backend pending backend specialist Tier 1

Acceptance Criteria

A mapGoTrueError(Object error) function or GoTrueErrorMapper class is defined in lib/features/auth/data/gotrue_error_mapper.dart
AuthException with error code 'invalid_credentials' or message containing 'Invalid login credentials' maps to InvalidCredentialsException
AuthException with error code 'email_not_confirmed' maps to InvalidCredentialsException (user-facing: treat as invalid to avoid account enumeration)
SocketException, TimeoutException, and ClientException with no response map to NetworkFailureException(isTimeout: ...)
AuthException with HTTP status 429 maps to RateLimitException with retryAfterSeconds extracted from response headers if available
AuthException with HTTP status 500–599 maps to ServerErrorException with the status code
Any unrecognized exception type falls back to ServerErrorException(statusCode: 0) — no raw exceptions leak to callers
Mapper is a pure function (or stateless class) with no side effects
All mapping branches are covered by unit tests
No UI or BLoC imports in this file

Technical Requirements

frameworks
Flutter
Dart
Supabase Flutter SDK
apis
Supabase GoTrue Auth API
data models
AuthException (GoTrue)
InvalidCredentialsException
NetworkFailureException
RateLimitException
ServerErrorException
performance requirements
Mapper must be synchronous — no async operations
Must not perform any network calls or I/O
security requirements
Must NOT propagate raw GoTrue error messages to domain exceptions to prevent information leakage
Email enumeration: treat 'email not found' and 'wrong password' identically as InvalidCredentialsException

Execution Context

Execution Tier
Tier 1

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.

Component
Authentication Service
service medium
Epic Risks (2)
high impact medium prob integration

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.

medium impact medium prob technical

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.