feat(realunit): pre-fill registration form from existing KYC data#3780
Closed
TaprootFreak wants to merge 1 commit into
Closed
feat(realunit): pre-fill registration form from existing KYC data#3780TaprootFreak wants to merge 1 commit into
TaprootFreak wants to merge 1 commit into
Conversation
Users with completed DFX KYC who initiate a RealUnit purchase get sent through the Aktionariat registration flow, where the form controllers currently start empty. They must retype data the backend already holds, and `completeRegistration`'s `isPersonalDataMatching` rejects any deviation byte-for-byte — turning a one-tap signing step into a guessing game. Make `GET /v1/realunit/wallet/status` fall back to the underlying `user_data` record when no `RealUnitRegistration` KycStep exists yet. The app already consumes `RealUnitWalletStatusDto.userData` for the merge-existing-registration path; this extends the same shape to first-time registrations so the form can pre-fill with values that will pass server-side validation verbatim. Controller loads the country / nationality / language relations needed by the new mapper. Mapper degrades gracefully: no firstname/surname → `userData: undefined` (back to manual entry, same as before this PR).
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
GET /v1/realunit/wallet/statusnow returnsuserDataderived from the user's existing DFX KYC record when noRealUnitRegistrationKycStep has been created yet. The app uses this as the source of truth for pre-filling the Aktionariat registration form, replacing the current empty-controllers experience.Why
Today every user reaching the RealUnit buy screen with completed DFX KYC gets routed through the registration wizard with empty fields — name, birthday, phone, nationality, full address — even though the API has all of those values verified. Worse,
completeRegistrationcallsisPersonalDataMatching(transliterated equality on every personal-data field), so any guess-and-type discrepancy hard-fails the registration request. The user is forced to reproduce their KYC submission byte-for-byte from memory.Verified against PRD for userData 290795 (Cyrill, KYC 50, three wallets): all fields the form collects (firstname, surname, phone, birthday, nationality, street + houseNumber, location, zip, country) are populated on
user_databut unreachable from any user-facing endpoint. This PR is the smallest backend change that unblocks the matching app-side pre-fill PR.What changed
realunit.service.tsgetAddressWalletStatusnow falls back totoUserDataDtoFromUserData(userData)when the step-based mapper returns nothingtoUserDataDtoFromUserData(userData)maps:mail/firstname/surname/phone/birthday → email/name/phoneNumber/birthdaynationality.symbol / language.symbol → nationality / lang(lang falls back toENif not in the supported set)street + houseNumber → addressStreet(concatenated to match the Aktionariat single-line format)zip/location/country.symbol → addressPostalCode/addressCity/addressCountrytin (JSON) → countryAndTINscountry.symbol === 'CH' → swissTaxResidence(defensive default; user can override before signing)kycData: KycPersonalDatafor any subsequent submission round-triprealunit.controller.tsgetWalletStatusloadscountry,nationality,organizationCountry,languagealongside the existingkycStepsrelation — needed by the new mapper, no behavioural change for callers that don't depend on these fieldsOut of scope
The deeper redesign — driving every onboarding step purely from API-shaped definitions ("show" / "skip" per step, schema-driven forms) — is being scoped separately. This PR is the minimum that converts the current re-typing trap into a one-tap confirmation flow for KYC-completed users.
API as Decision Authority
Consistent with the rule: the server alone decides whether to expose pre-fill data and which fields to send; the app renders what arrives. No new client-side gating logic introduced.
Tests
realunit.service.spec.tsgains a `getAddressWalletStatus (user_data fallback)` block:`npm test -- --testPathPattern=realunit.service` → 18 / 18 passing (14 baseline + 4 new).
Local verification
Pair-PR
App-side consumer PR follows on DFXswiss/realunit-app — calls `getWalletStatus()` in the registration page's `initState()` and initializes the form controllers from `userData`.