Provide reusable models, injectable service contracts, lifecycle-safe providers and explicit dummy implementations for login, signup and verification. Add focused error and async lifecycle tests. Related to #4 and #5.
sxchnge_auth
Shared Flutter authentication providers and service contracts for web and mobile. Private package, version 0.1.0; Flutter 3.47+ / Dart 3.13+.
Install and use
From frontend/app (or a sibling frontend/mobile app):
dependencies:
sxchnge_auth:
path: ../packages/sxchnge_auth
import 'package:sxchnge_auth/sxchnge_auth.dart';
final login = LoginProvider(const DummyLoginService());
login.addListener(() {
// Render login.state.status, result, or typed error in your own UI.
});
await login.login(
email: 'demo@example.com',
password: 'example-password',
locale: 'en',
);
login.dispose();
SignupProvider accepts a SignupService and exposes signup(name:, email:, password:, locale:). Both providers extend ChangeNotifier and can be installed with ChangeNotifierProvider, ListenableBuilder, or another Flutter state binding. The package itself depends only on Flutter foundation; it contains no widgets, routes, localization, web-only code, network client, or storage.
Lifecycle and services
Providers expose immutable AuthState: idle, loading, success, or error. They trim email/name, preserve the password verbatim, pass the locale to services, suppress duplicate submissions while loading, and clear old errors before retrying. Reset invalidates older responses and allows a new request; disposal ignores all later completions. Reset does not cancel remote work. Do not treat a provider reset as undoing a production signup.
Services return AuthResult or throw AuthException with a typed AuthError. Unexpected exceptions are reduced to unexpected; raw errors and credentials are not retained in provider state. Credentials exist only as ephemeral request input. Localize error codes in each consuming application.
DummyLoginService and DummySignupService default to 600ms latency and simulated success. They do not validate credentials against an account registry, create accounts, issue tokens, open sessions, send requests, or persist data. Configure errors explicitly:
final service = DummyLoginService(
delay: Duration.zero,
failure: AuthError.invalidCredentials,
);
Supported failure codes: invalidCredentials, emailInUse, unavailable, and unexpected. Inject another implementation for deterministic retry scenarios or production integration. AuthResult.isSimulated distinguishes dummy responses; a successful operation alone must never be treated as an authorization decision. The package does not implement authenticated application/session state yet.
Sendico reuse
Adapted the ChangeNotifier lifecycle, service separation, locale-carrying request, and typed-outcome patterns from Sendico's pshared/lib/provider/account.dart, models/auth/login_outcome.dart, and service/authorization/client.dart. These were patterns rather than directly portable implementations: the originals depend on Sendico account/organization models, device IDs, static API services, token storage, and verification flows. Those dependencies are deliberately absent here. The B2B organization signup contract is not copied into the consumer product.
When a supported sxchnge BFF contract exists, implement transport DTOs and mappers behind the service interfaces, returning domain results. No dummy DTO/mapping layer is needed without serialized transport. Keep web cookie and mobile credential handling in production platform adapters, not the providers.
Validation
flutter analyze and flutter test from this directory; make test-frontend from the repository root also runs all consuming app and theme tests. Tests cover duplicate submission, request forwarding, typed/unexpected failures, retry, reset races, disposal, and both dummy implementations.
Email verification
VerificationService exposes send(email, locale) and confirm(token) as named-argument methods. Inject an implementation into VerificationProvider, shared by web and mobile. The provider exposes immutable VerificationState (idle/sending/sent/checking/verified/expired/invalid/error), suppresses concurrent duplicate operations, and ignores completions after reset or disposal. Typed VerificationException maps confirmation failures; unknown exceptions become internal errors without exposing exception text. Sending failures always become the general error state.
DummyVerificationService supports demo-valid, demo-expired, and demo-internal confirmation tokens; other tokens are invalid. Configure delay and sendFailure for tests. Results are explicitly simulated. It performs no network, storage, mail delivery, or account mutation. A production adapter must implement backend validation, delivery, rate limits, and safe token handling; this client provider is not an authorization boundary.