Show Bridge EEA uplift remediation CTA#2080
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds EEA uplift handling by tagging remediation actions with ChangesEEA Uplift Remediation Support + UI wiring
🎯 3 (Moderate) | ⏱️ ~20 minutes
Suggested reviewers:
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/hooks/useMultiPhaseKycFlow.ts (1)
252-252: 💤 Low valueVerify dependency array for handleSdkComplete.
The dependency array includes
handleActionFlowCompletewhich itself depends onfetchUser,handleSelfHealResubmit,lastSelfHealQuestionnaireCluster, andstartTracking. React 19 should handle this correctly, but verify that the closure captures the latest values. If stale closures become an issue, consider adding those dependencies directly or using refs for stable function identity.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/hooks/useMultiPhaseKycFlow.ts` at line 252, The dependency array for the effect using originalHandleSdkComplete currently includes handleActionFlowComplete, but since handleActionFlowComplete closes over fetchUser, handleSelfHealResubmit, lastSelfHealQuestionnaireCluster, and startTracking you should ensure the effect sees up-to-date values: either expand the dependency array to include those underlying symbols (fetchUser, handleSelfHealResubmit, lastSelfHealQuestionnaireCluster, startTracking) along with originalHandleSdkComplete, isActionFlow, and regionIntent, or make handleActionFlowComplete stable (e.g., wrap it in useCallback or store it in a ref) so the effect's dependency can safely reference the stable function identity used by handleSdkComplete.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/hooks/useMultiPhaseKycFlow.ts`:
- Around line 219-235: The polling loop calls fetchUser() without handling
rejections; wrap the await fetchUser() inside a try-catch in
useMultiPhaseKycFlow so network or parsing errors don't throw the whole flow. On
catch, log the error (or report via existing logger), increment a local retry
counter or let the loop continue after awaiting
BRIDGE_ACTION_AUTO_CONTINUE_INTERVAL_MS, and if retries exceed a small threshold
(or elapsed >= BRIDGE_ACTION_AUTO_CONTINUE_TIMEOUT_MS) fall through to the same
"preparing" behavior used elsewhere (e.g., clear modal via
setForceShowModal(false) or break so getBridgeNextQuestionnaireClusterFromUser
and handleSelfHealResubmit logic can proceed safely). Ensure you reference the
existing symbols fetchUser, getBridgeNextQuestionnaireClusterFromUser,
handleSelfHealResubmit, setForceShowModal,
BRIDGE_ACTION_AUTO_CONTINUE_INTERVAL_MS and
BRIDGE_ACTION_AUTO_CONTINUE_TIMEOUT_MS when applying the change.
- Around line 209-240: handleActionFlowComplete currently breaks to the
'preparing' phase silently when handleSelfHealResubmit('BRIDGE') returns false
and also breaks immediately when seeing nextCluster === 'eea_tin_reupload' while
auto-continue is blocked; update handleActionFlowComplete to (1) surface
failures from handleSelfHealResubmit by either setting an error state (e.g.,
setSelfHealError or reuse existing modal state) or at minimum logging the
returned failure so the UI can inform the user before proceeding to
setModalPhase('preparing')/setForceShowModal(true), and (2) when nextCluster ===
'eea_tin_reupload' but canAutoContinueTin is false, await one
BRIDGE_ACTION_AUTO_CONTINUE_INTERVAL_MS (use
wait(BRIDGE_ACTION_AUTO_CONTINUE_INTERVAL_MS)) before breaking to allow API
metadata to settle. Ensure references to handleSelfHealResubmit,
handleActionFlowComplete, setModalPhase, setForceShowModal, startTracking and
the polling logic remain consistent.
---
Nitpick comments:
In `@src/hooks/useMultiPhaseKycFlow.ts`:
- Line 252: The dependency array for the effect using originalHandleSdkComplete
currently includes handleActionFlowComplete, but since handleActionFlowComplete
closes over fetchUser, handleSelfHealResubmit, lastSelfHealQuestionnaireCluster,
and startTracking you should ensure the effect sees up-to-date values: either
expand the dependency array to include those underlying symbols (fetchUser,
handleSelfHealResubmit, lastSelfHealQuestionnaireCluster, startTracking) along
with originalHandleSdkComplete, isActionFlow, and regionIntent, or make
handleActionFlowComplete stable (e.g., wrap it in useCallback or store it in a
ref) so the effect's dependency can safely reference the stable function
identity used by handleSdkComplete.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: a2a0b488-fb01-4ec7-8169-9dce8f44c837
📒 Files selected for processing (8)
src/app/actions/sumsub.tssrc/components/Kyc/KycVerificationInProgressModal.tsxsrc/hooks/__tests__/useMultiPhaseKycFlow.test.tssrc/hooks/__tests__/useProviderRejectionStatus.test.tssrc/hooks/useMultiPhaseKycFlow.tssrc/hooks/useProviderRejectionStatus.tssrc/hooks/useSumsubKycFlow.tssrc/interfaces/interfaces.ts
|
@coderabbitai review in depth. Evaluate:
Also, write a very concise testing guide for QA |
|
Tip For best results, initiate chat on the files or code changes.
Risk of New Bugs / Breaking Existing Functionality🔴 High: Double
|
| Path | Impact |
|---|---|
| Happy path (EEA uplift → TIN reupload detected on first poll) | +1 fetchUser call (~200–500ms added latency), acceptable |
| Worst case (no cluster returned for 20s) | 11 fetchUser calls over 20 seconds while user sees "Checking your details…" |
| Self-heal action complete (any case) | 2 concurrent fetchUser calls fired simultaneously |
| All other paths | No change from pre-PR behavior |
The 20-second timeout with a non-dismissible "Checking your details..." modal (no CTA, no close button) is the biggest UX risk. If the API is slow or the cluster never arrives, the user is stuck for 20 seconds with no feedback or escape. Consider adding a fallback CTA ("Skip for now") after a shorter interval, similar to the preparingTimedOut pattern already in the codebase.
Code Quality & DRY
1. Duplicated questionnaireCluster literal union
The same string literal union is defined separately in two files:
src/hooks/useProviderRejectionStatus.ts→ProviderRemediationAction.questionnaireClustersrc/app/actions/sumsub.ts→SelfHealResubmissionResponse.questionnaireCluster
Adding a new cluster (e.g. 'source_of_address') requires updating both. Extract to a shared type:
// src/interfaces/interfaces.ts or a shared types file
export type BridgeQuestionnaireCluster =
| 'source_of_funds'
| 'tax_id'
| 'address'
| 'birth_details'
| 'eea_uplift'
| 'eea_tin_reupload'2. Duplicated bridge remediation lookup logic
getBridgeRemediationFromUser in useMultiPhaseKycFlow.ts and getBridgeRemediation in useProviderRejectionStatus.ts both implement the same priority logic (verification metadata wins over rail metadata). The multi-phase version additionally lacks the status validation that the rejection status version performs:
// In getBridgeRemediation (useProviderRejectionStatus.ts) — validated ✓
if (candidate.status !== 'APPROVED' && candidate.status !== 'AWAITING_INPUT' && ...)
// In getBridgeRemediationFromUser (useMultiPhaseKycFlow.ts) — not validated ✗
return isRecord(verificationRemediation) ? verificationRemediation : ...This means getBridgeNextQuestionnaireClusterFromUser could theoretically return a cluster for an APPROVED remediation. Consider exporting a shared lookup helper.
3. Inconsistent eea_* check pattern
eea_tin_reupload has a named helper isEeaTinReuploadAction(), but eea_uplift is always checked inline:
// inconsistent
if (action?.questionnaireCluster === 'eea_uplift') return 'Provide required details' // inline
if (isEeaTinReuploadAction(action)) return 'Re-upload TIN' // helperAdd isEeaUpliftAction() for symmetry.
4. Double-numbered step comment
In useBridgeTransferReadiness.ts, both "needs_enrollment" and "ready" are labeled // 5. in the gate priority comment block. This is cosmetic but should be // 5. and // 6. respectively.
QA Testing Guide
Prerequisites
- A Bridge-approved user account with
AWAITING_INPUTremediation metadata carryingquestionnaireCluster: 'eea_uplift' - A staging environment where the API returns EEA uplift metadata
Test Matrix
| # | Scenario | Expected Result |
|---|---|---|
| 1 | Affected Bridge-approved user opens Add Money or Withdraw | InitiateKycModal appears with title "We need more details" (or custom providerTitle) and CTA "Provide required details" |
| 2 | User clicks "Provide required details" | Sumsub SDK opens (applicant action flow); isActionFlow = true |
| 3 | User completes Sumsub action | "Checking your details…" modal appears; no close button visible |
| 4 | API returns eea_tin_reupload as next cluster within 20s |
Sumsub SDK re-opens automatically with TIN reupload action; "Checking" modal disappears |
| 5 | User completes TIN reupload | "Checking your details…" reappears; API returns no more clusters; transitions to "Setting up your account" (preparing) → "All set!" |
| 6 | API never returns eea_tin_reupload within 20s |
After 20s, modal transitions from "Checking" to "Setting up your account" and startTracking begins |
| 7 | Affected user who has already done TIN reupload (second time) | canAutoContinueTin = false; loop exits on finding eea_tin_reupload; goes directly to preparing/tracking |
| 8 | User with blocked remediation (TERMINAL) | InitiateKycModal shows "Payment setup issue" with "Contact support" CTA; no Sumsub action offered |
| 9 | User with AWAITING_PROVIDER remediation |
Modal shows "Document review in progress" with "Got it" CTA |
| 10 | Non-EEA Bridge user with standard BRIDGE_CUSTOMER_FIELDS rejection |
Existing "Provide details" label and copy unchanged; no regression |
| 11 | Countries list page (AddWithdrawCountriesList) |
providerTitle and providerActionLabel props correctly propagate to InitiateKycModal from getGateProviderTitle/getGateActionLabel |
| 12 | User navigates away during "Checking your details…" | No JS errors; background polling stops cleanly (note: currently no abort mechanism — may still fire network calls) |
|
@coderabbitai re-review in depth. Evaluate:
Also, write a very concise testing guide for QA |
|
Tip For best results, initiate chat on the files or code changes.
Bugs Fixed Since the Previous Review ✅
🔴 High:
|
| # | Scenario | Expected |
|---|---|---|
| 1 | Approved Bridge user with AWAITING_INPUT + questionnaireCluster: eea_uplift opens Add Money / Withdraw |
InitiateKycModal shows title "We need more details", CTA "Provide required details" |
| 2 | User taps "Provide required details" | Sumsub SDK opens; isActionFlow = true |
| 3 | User completes Sumsub action flow | "Checking your details..." modal appears; no close button or CTA visible |
| 4 | API returns eea_tin_reupload as next cluster within 20 s |
Sumsub SDK re-opens automatically with TIN reupload; checking modal disappears |
| 5 | User completes TIN reupload | "Checking your details..." reappears → "Setting up your account" → "All set!" |
| 6 | API never returns eea_tin_reupload within 20 s |
After 20 s, transitions to "Setting up your account" and startTracking begins |
| 7 | User who has already done TIN reupload (second session) | canAutoContinueTin = false; loop detects eea_tin_reupload cluster but skips auto-continue; goes to preparing/tracking |
| 8 | User navigates away during "Checking your details..." | No JS errors in console; background polling eventually stops (note: network calls may still fire until timeout) |
| 9 | TERMINAL remediation status |
"Payment setup issue" title, "Contact support" CTA; no Sumsub action |
| 10 | AWAITING_PROVIDER status |
"Document review in progress" / "Got it" CTA |
| 11 | Standard Bridge BRIDGE_CUSTOMER_FIELDS rejection (no EEA cluster) |
Existing "Provide details" label; no regression |
| 12 | AddWithdrawCountriesList, add-money page, withdraw page, BankFlowManager |
providerTitle and providerActionLabel all propagate correctly to InitiateKycModal |
|
@coderabbitai re-review in depth. Evaluate:
Also, write a very concise testing guide for QA |
|
Tip For best results, initiate chat on the files or code changes.
Issues Fixed Since the Previous Review ✅
The high- and medium-severity bugs from the last two reviews are all resolved. The remaining items are code-quality / DRY only. Remaining Issues🟡 Low: Duplicated
|
| # | Scenario | Expected |
|---|---|---|
| 1 | Approved Bridge user with AWAITING_INPUT + questionnaireCluster: eea_uplift opens Add Money / Withdraw |
InitiateKycModal shows title "We need more details", CTA "Provide required details" |
| 2 | User taps CTA | Sumsub SDK opens; isActionFlow = true |
| 3 | User completes Sumsub action | "Checking your details..." appears; no close button or CTA visible |
| 4 | API returns eea_tin_reupload within 20 s |
Sumsub re-opens automatically for TIN reupload; checking modal disappears |
| 5 | User completes TIN reupload | "Checking…" → "Setting up your account" → "All set!" |
| 6 | API never returns eea_tin_reupload within 20 s |
After 20 s → "Setting up your account"; startTracking begins |
| 7 | Second session — TIN already submitted (canAutoContinueTin = false) |
Loop detects eea_tin_reupload cluster, skips auto-continue, goes to preparing |
| 8 | User navigates away during "Checking…" | No JS errors; network calls eventually stop after timeout |
| 9 | TERMINAL remediation |
"Payment setup issue" + "Contact support" CTA |
| 10 | AWAITING_PROVIDER remediation |
"Document review in progress" + "Got it" CTA |
| 11 | Non-EEA Bridge BRIDGE_CUSTOMER_FIELDS rejection |
Existing "Provide details" label; no regression |
| 12 | All four entry-points (AddWithdrawCountriesList, add-money page, withdraw page, BankFlowManager) |
providerTitle + providerActionLabel propagate correctly to InitiateKycModal |
1ccf830
into
feat/bridge-rfi-remediation-ui-clean
Summary
Risks
QA Guidelines