fix(kyc): filter country pickers by allow-flag, harden load states#519
Merged
Conversation
Contributor
Author
Review-Notiz (Draft-Stand)Verdict: Logisch sauber, gute Test-Coverage, ready-for-review sobald rebased. Was ich gegen
|
This was referenced May 22, 2026
This was referenced May 22, 2026
The shared CountryField (used by 4 KYC/onboarding screens) showed the same unfiltered country list for both nationality and residence pickers, auto-selected Switzerland, and collapsed to an empty or non-FormField widget while loading or on error — letting Form.validate() pass with no selection and crashing the KYC submit on a null country. - Country now carries nationalityAllowed/locationAllowed; CountryField takes a required `purpose` and filters the list accordingly - loading and error states render a present, invalid FormField so the surrounding form can never validate without a selection; the error state shows a localized message and a retry instead of the raw exception - drop the silent Switzerland auto-select; country selection is now explicit and validated - localize the nationality-failure SnackBar
A backend audit of DFXswiss/api showed the allow-flags this branch originally filtered by are wrong: the CountryDto `locationAllowed` field is `ipEnable` (it gates the request IP's country, not a user-entered country), and `nationalityAllowed` maps to the entity column `nationalityStepEnable`, which the backend reads nowhere. - the residence/address picker now filters by `kycAllowed` (= `dfxEnable`), the flag the backend actually enforces on the address country (HTTP 400 on submit otherwise) - the nationality picker no longer filters: nationality is a fact, and the backend routes a disallowed nationality to manual review rather than rejecting it, so hiding countries would be wrong - Country drops nationalityAllowed/locationAllowed, carries kycAllowed
0e208a4 to
82154ae
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The shared
CountryFieldwidget (used by 4 KYC/onboarding screens — nationality, registration personal step, registration address step, settings address) had three correctness gaps, all fixed here:kycAllowed. The nationality pickers intentionally do not filter — see below.ConnectionState.waitingrenderedSizedBox.shrink()andhasErrorrendered a bareTextwith the raw exception. With noFormFieldin the tree,Form.validate()returnedtruewith no selection and the submit crashed oncountry!. Both states now render a present, invalidFormField; the error state shows a localized message and a retry._preloadCountryauto-selected the first country, which made the validator dead code and silently registered users as Swiss nationals. Removed — selection is now explicit and validated.Also: the non-localized
'Set Nationality failed: …'SnackBar is now localized.Flag semantics (resolved against the backend)
A deep audit of
DFXswiss/apiresolved which flag actually gates which field — the DTO flag names are misleading:kycAllowed(DTO alias of the backend'sdfxEnable). A non-allowed address country is rejected with HTTP 400 on submit, so client-side filtering is correct and useful here.CountryDtofield correctly represents the nationality gate:nationalityAllowedmaps tonationalityStepEnable, which the backend reads nowhere; the real gate isnationalityEnable, which is not exposed. And a disallowed nationality is routed to manual review, not rejected — nationality is a fact, so the picker must offer every country. See CountryDto: nationalityAllowed maps to an unused column; no DTO field exposes the real nationality gate DFXswiss/api#3755.locationAllowedwas the original (wrong) choice for residence — it maps toipEnableand gates the request IP's country, not a user-entered field.Out of scope
The KYC flow can collect nationality twice (standalone
nationalityDatastep + the registration step). The root cause is on the backend — tracked in DFXswiss/api#3754. Not touched here.Test plan
flutter analyze— cleanflutter test— all tests pass;test/widgets/form/country_field_test.dartcovers residence filtering bykycAllowed, the nationality picker showing all countries, loading/error invalidity, retry recovery, and no auto-selectkycAllowedcountries, nationality picker shows all, both block submit until a country is picked, and recover from a failed country load via retry