Merge pull request 'Set up RUB, USDT and USDC accounts automatically' (#73) from wallet-72 into main

This commit was merged in pull request #73.
This commit is contained in:
tech committed 2026-10-23 11:10:45 +00:00
commit 3b551f1565
21 files changed
+687 -62

No files matched your search

+45 -23
View File
@@ -302,32 +302,54 @@ that contradicts displayed balances or usage without explaining the fixtures.
- Keep unrelated accounts/history accessible during a pending operation. Do not
block the whole product behind an exchange spinner.
## Empty currency accounts (task #66)
## Automatic currency accounts (task #72)
The shared empty-account message used on Accounts and transfer screens explains
that no currency accounts have been set up and directs the customer to support
to request setup. English and Russian no longer suggest that refreshing creates
accounts or imply that automatic provisioning is underway. This follows the
existing support guidance for missing funding and payout setup. The application
has no configured support contact channel; the message therefore provides text
guidance without a nonfunctional contact button or invented contact details.
New customers receive RUB, USDT and USDC accounts through backend-owned setup
during signup. Existing customers receive missing defaults on their next wallet
load. The UI requires no account-creation form or support contact. During initial
loading it announces that the accounts are being prepared. Failure shows one
clear load error and a **Try again** action that reruns the same idempotent setup.
An unexpected empty snapshot has its own setup-failure fallback, rather than
being shown simultaneously with an error. A failed refresh retains existing
cards and the stale-data warning. Account-not-found copy requires loaded data.
UX review: the copy names the missing resource and the next step, retains the
existing wrapping text and accessible reading order, and does not alter loading,
error or populated-state behavior. Existing manual refresh remains available for
accounts provisioned externally. This copy-only change adds no controls or
journey outcomes and requires no new analytics events. Existing transaction
journey signals and their production measurement limitations below still apply;
support resolution and external account provisioning are not measured in-app.
The existing DTO → mapper → service → model → provider → UI boundaries remain
intact. Account creation belongs to the backend/provider, and widgets invoke the
existing provider refresh action. English and Russian use wrapping text and the
existing accessible button pattern; status text uses a live region. Dedicated
widget regressions cover loading, failure, retry and successful default accounts
on Accounts, Top up, Exchange and Payout at 320px with 1.6× text. Native device and
screen-reader QA remain a release check; tests do not claim physical-device QA.
Validation: `flutter gen-l10n`, `flutter analyze` in `frontend/app`,
`make test-frontend` (217 tests), and `git diff --check` passed. No Dart source
changed, so Dart formatting was not applicable. Existing responsive workspace
tests cover Russian at 320px with enlarged text; this copy-only change does not
add a dedicated empty-state rendering or native screen-reader test. No security
scan was requested. Delivery: [task #66](https://git.sendico.io/tech/sxchnge/issues/66),
branch `wallet-66`, [PR #68](https://git.sendico.io/tech/sxchnge/pulls/68).
Merge and deployment remain separate.
Measurement: `sxchnge_currency_accounts_setup_total{outcome="ready|failed"}` and
`sxchnge_currency_accounts_setup_duration_seconds` cover the server setup attempt.
`ready` is emitted only after all default bindings are confirmed, including
idempotent completion of provider wallet/route setup for newly bound ledgers.
Each signup/resend/wallet load is a separate attempt; a retry is not a new unique
customer conversion. The failure fraction uses all attempts as its denominator;
the histogram measures one attempt, not time across multiple browser sessions.
No customer, ledger, currency, balance, credentials or form input is a metric
label. These server metrics do not measure client abandonment or prove that a
balance card was viewed. Existing transaction journey outcomes below are reused;
no speculative button-click events are added.
Scope and rollout: [task #72](https://git.sendico.io/tech/sxchnge/issues/72), branch
`wallet-72`, [PR #73](https://git.sendico.io/tech/sxchnge/pulls/73). The provider
prerequisite and deployment order are documented in [payments](../payments.md).
Merge and deployment remain separate. Final validation is recorded in the task
and PR, including any transient failures and environmental blockers.
Final validation (2026-10-23): `flutter gen-l10n`, `flutter analyze` in
`frontend/app`, the changed-Dart formatting check, `make lint-backend`, and
`git diff --check` passed. `make test-frontend` passed all 242 tests on the current
app base, including the eight setup recovery scenarios. The full `make test`
passed with `TESTCONTAINERS_RYUK_DISABLED=true GOFLAGS='-p=2'`: earlier attempts
hit dependency DNS and Mongo/cleanup-helper startup timeouts. Disabling only the
failing helper retained every integration assertion, test timeout and race check;
each test's existing container cleanup still ran. No security scan was requested.
The live local provider catalog confirms RUB scale 2 and USDT/USDC scale 6.
Provider-side concurrency and frozen-binding checks passed against a disposable
Mongo replica set; see [Sendico PR #2970](https://git.sendico.io/tech/sendico/pulls/2970).
## Journey measurement plan