Problem
requiredKycSteps(userData) in src/subdomains/generic/kyc/enums/kyc.enum.ts:51 returns KycStepName.FINANCIAL_DATA unconditionally for every user. Three call sites (kyc.service.ts:389, kyc.service.ts:1186, kyc.service.ts:1325 plus the UI mapper at kyc-info.mapper.ts:43) therefore always count it as a required step.
For users of the RealUnit wallet (detected today via wallet.name === 'RealUnit' — see the constant REALUNIT_WALLET_NAME in src/subdomains/supporting/notification/realunit-mail-rules.ts:3) the agreed product behaviour is that the 10 Financial-Data questions fire only when the user actually attempts to sell, not on first buy. The current implementation surfaces them on every onboarding regardless of action.
User impact
Every new RealUnit user is forced through the 10-question Financial-Data step before they can complete a first buy, even though the data is only relevant on the sell side. Friction is concentrated on the highest-volume flow.
Suggested fix shape
requiredKycSteps(userData) to gate FINANCIAL_DATA on a condition equivalent to:
- not on a RealUnit wallet (status quo for all other wallets), or
- already past first sell (
userData.sellVolume > 0 — column at user-data.entity.ts:337).
Two implementation options:
- Keep the signature pure —
requiredKycSteps(userData) looks at userData.wallet.name + userData.sellVolume. Fully derivable from existing entity state. No new column, no call-site changes.
- Extend the signature with an action context —
requiredKycSteps(userData, action?: 'buy' | 'sell'). Sell endpoints opt in to require Financial-Data, buy endpoints don't. More flexible but propagates to every caller.
Option 1 is preferable because it keeps the API as the single decision authority (realunit-app/CONTRIBUTING.md:23–67) — clients never need to send action context for a question that the backend can answer from the user's own history.
Pair-PR
App-side is a no-op: the realunit-app already renders KycStepDto.isRequired (Wave 2 / app#494). Removing FINANCIAL_DATA from the required list on the API automatically removes it from the client's kycSteps.filter(s => s.isRequired) iteration.
Source
Surfaced in DFXswiss/realunit-app#611 (item 1) from an Android internal-test session 2026-05-28.
Problem
requiredKycSteps(userData)insrc/subdomains/generic/kyc/enums/kyc.enum.ts:51returnsKycStepName.FINANCIAL_DATAunconditionally for every user. Three call sites (kyc.service.ts:389,kyc.service.ts:1186,kyc.service.ts:1325plus the UI mapper atkyc-info.mapper.ts:43) therefore always count it as a required step.For users of the RealUnit wallet (detected today via
wallet.name === 'RealUnit'— see the constantREALUNIT_WALLET_NAMEinsrc/subdomains/supporting/notification/realunit-mail-rules.ts:3) the agreed product behaviour is that the 10 Financial-Data questions fire only when the user actually attempts to sell, not on first buy. The current implementation surfaces them on every onboarding regardless of action.User impact
Every new RealUnit user is forced through the 10-question Financial-Data step before they can complete a first buy, even though the data is only relevant on the sell side. Friction is concentrated on the highest-volume flow.
Suggested fix shape
requiredKycSteps(userData)to gateFINANCIAL_DATAon a condition equivalent to:userData.sellVolume > 0— column atuser-data.entity.ts:337).Two implementation options:
requiredKycSteps(userData)looks atuserData.wallet.name+userData.sellVolume. Fully derivable from existing entity state. No new column, no call-site changes.requiredKycSteps(userData, action?: 'buy' | 'sell'). Sell endpoints opt in to require Financial-Data, buy endpoints don't. More flexible but propagates to every caller.Option 1 is preferable because it keeps the API as the single decision authority (
realunit-app/CONTRIBUTING.md:23–67) — clients never need to send action context for a question that the backend can answer from the user's own history.Pair-PR
App-side is a no-op: the realunit-app already renders
KycStepDto.isRequired(Wave 2 /app#494). RemovingFINANCIAL_DATAfrom the required list on the API automatically removes it from the client'skycSteps.filter(s => s.isRequired)iteration.Source
Surfaced in
DFXswiss/realunit-app#611(item 1) from an Android internal-test session 2026-05-28.