Files
sxchnge/frontend/app/README.md

5.5 KiB

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.

Without backend configuration the app uses dummy services. The existing SXCHNGE_API_URL and SXCHNGE_CLIENT_ID select authenticated backend auth, identity, limits and wallet adapters. Wallet operations use Sendico through the BFF after the provider prerequisites and dedicated customer resource bindings are provisioned; they do not use demo balances in backend mode. LoginProvider, SignupProvider and shared wallet providers own loading/results/errors. SxchngeApp retains explicit service injection for tests and previews. See quotation/payment integration for setup, supported funding/destinations, authorization, reconciliation and rollout.

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/. Generated Dart files are ignored and untracked. Run flutter gen-l10n after a clean checkout and after editing ARB files; make test-frontend runs it before tests. 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: verified
  • demo-expired: expired
  • demo-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.