SXCHNGE consumer app
Flutter web application using the local sxchnge_theme package.
Run
From this directory:
flutter pub get
flutter run -d chrome
Current scope
A responsive login/sign-up preview with a themed brand panel, email and password validation, password visibility controls, keyboard submission, and inline feedback. Sign-up additionally asks for a name and matching password confirmation. The 12-character sign-up minimum is a UI preview policy and must be aligned with the backend when authentication is integrated.
No authentication endpoint is configured. Submission validates locally and calls the shared dummy authentication services; it never creates an account, starts a session, sends credentials, or persists them. Passwords are cleared when switching modes. Password managers/autofill integration is deferred until real authentication exists. LoginProvider and SignupProvider own loading/results/errors; SxchngeApp accepts injected loginService and signupService implementations. Dummy completion is explicitly labeled and does not establish a real session.
The interface uses ColorScheme and TextTheme roles from sxchnge_theme; the desktop brand panel installs the package's dark theme locally. Entrance animation respects reduced-motion preferences. The public website remains separate in website/.
Validate
dart format --output=none --set-exit-if-changed lib test
flutter analyze
flutter test
flutter build web
From the repository root, make test-frontend runs both theme suites and the application tests. Tracker: tech/sxchnge#2, branch auth-2.
English and Russian
Localization follows Sendico's Flutter pattern: lib/l10n/en.arb is the template, ru.arb contains Russian translations, and flutter gen-l10n writes lib/generated/i18n/. Edit ARB files, not generated Dart files. Flutter's Material and Cupertino localizations are included through the generated delegates.
The language dropdown is available in both authentication modes. Startup reads sxchnge_last_locale using shared preferences; without a saved choice it uses the device language. Russian regional variants resolve to Russian and unsupported languages fall back to English. Preference writes are serialized, and storage failures leave the selected language usable for the current session with a localized notice. Only the language preference is stored; credentials remain transient.
Language switching preserves mode and input, translates existing validation errors, and updates the application title. Tracker: tech/sxchnge#3, branch localization-3.
Email verification
Successful signup opens /verification-sent and requests a verification email through the injected VerificationService. The screen shows sending, sent and resend errors. Reloading this route asks for the email again; the app does not persist it. A production signup endpoint should avoid sending a duplicate email if this separate send operation is retained.
Confirmation links use /#/verify-email?token=…. They display checking, verified, expired, invalid (including missing tokens), or internal error. Internal confirmation errors allow retry; invalid and expired links allow requesting a new email. The backend must validate tokens and enforce verification before enabling restricted operations.
The default service is a dummy: no email is sent or account verified. Preview tokens:
demo-valid: verifieddemo-expired: expireddemo-internal: internal error- Any other token or missing token: invalid
The sent screen includes a clearly labeled demo confirmation link. All states and actions support EN/RU and theme colors. Tracker: tech/sxchnge#5, branch verification-5.
Routing
lib/routing/router.dart owns the go_router route table, with route names in routes.dart. SxchngeApp creates one router for its lifetime, supplies it to MaterialApp.router, and disposes it on teardown. Locale changes preserve the router and current page state.
Use context.goNamed(AppRoutes.… ) for top-level navigation. Existing hash URLs remain compatible: /, /#/verification-sent, and /#/verify-email?token=…. Confirmation query changes re-run verification and discard stale async results. Unknown routes redirect to /.
The signup email travels as a transient route extra. The router's extra codec deliberately omits extras from serialized browser history, so a restored sent page asks for the email again. Do not add persistent route extras without explicitly updating that policy.
These are public routes: no session or KYC guard is added to the dummy authentication flow. Future protected pages should use centralized redirects driven by authoritative session state, with backend access enforcement. Tracker: tech/sxchnge#6, branch routing-6.
UX and analytics
The app accepts an optional analyticsService and defaults to the shared bounded
in-memory dummy analytics sink. Semantic service events correlate signup, delivery
and confirmation within this app instance. No analytics data leaves the device.
See the journey contract for the schema, metrics,
PostHog adapter boundary and measurement limitations. Demo outcomes are explicitly
simulated; recipient editing and internal-error recovery have dedicated controls.