fix: thread crossRegion flag for cross-region KYC#1874
fix: thread crossRegion flag for cross-region KYC#1874kushagrasarathe wants to merge 4 commits intomainfrom
Conversation
pairs with backend fix that moves rail enrollment to webhook time. cross-region moveToLevel now requires explicit crossRegion=true flag. only set when user clicks "Verify now" on a different region — automatic calls (fetchCurrentStatus, polling) never set it.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughThreads a new optional Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/components/Profile/views/RegionsVerification.view.tsx`:
- Around line 103-107: The code computes isCrossRegion and always passes it into
flow.handleInitiateKyc, which sends crossRegion: false when not cross-region;
change the call site so crossRegion is only included when true: compute
isCrossRegion (using selectedRegion and sumsubVerificationRegionIntent) then
call flow.handleInitiateKyc(intent, undefined) for non-cross-region flows and
call flow.handleInitiateKyc(intent, undefined, true) only when isCrossRegion is
true; update the block around isCrossRegion, setSelectedRegion, and the
flow.handleInitiateKyc call accordingly.
🪄 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: d4ff7b36-fb9d-4b2a-8286-d11776d6bfd5
📒 Files selected for processing (4)
src/app/actions/sumsub.tssrc/components/Profile/views/RegionsVerification.view.tsxsrc/hooks/useMultiPhaseKycFlow.tssrc/hooks/useSumsubKycFlow.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. 🧩 Analysis chain🏁 Script executed: Length of output: 33455 🏁 Script executed: Length of output: 6423 🏁 Script executed: Length of output: 22586
Overall AssessmentThe change is minimal, well-scoped, and low-risk. The flag is correctly threaded through the entire chain ( 🐛 Risk of Bugs / Breaking Existing Functionality
|
| Caller | crossRegion in JSON |
|---|---|
| Automatic (fetchCurrentStatus, polling, refreshToken) | absent |
Same-region explicit click from RegionsVerification |
false |
Cross-region explicit click from RegionsVerification |
true |
| All other consumers (SumsubKycFlow, KycStatusDrawer, MantecaFlowManager, etc.) | absent |
If the backend guards with if (crossRegion) (truthy check), this is a non-issue. But if it ever checks crossRegion === false for any separate branch, it could behave differently for same-region clicks vs all other callers. The safest fix is to pass undefined instead of false at the call site:
// RegionsVerification.view.tsx
await flow.handleInitiateKyc(intent, undefined, isCrossRegion || undefined)This ensures the JSON field is only ever present when true, making the contract consistent with every other caller.
✅ All other callers are safe — no updates needed
Confirmed: SumsubKycFlow, KycStatusDrawer, MantecaFlowManager, BankFlowManager, AddWithdrawCountriesList, MantecaAddMoney, withdraw/manteca/page.tsx, and add-money/[country]/bank/page.tsx all call handleInitiateKyc without the third argument. Since crossRegion is optional and defaults to undefined, these are completely unaffected.
✅ No risk from dependency arrays
crossRegion is always a function parameter, never a closed-over variable. All useCallback dep arrays in useSumsubKycFlow, useMultiPhaseKycFlow, and RegionsVerification are correct. The newly added sumsubVerificationRegionIntent dep to handleStartKyc's useCallback was correctly identified and added.
✅ No risk from automatic calls
fetchCurrentStatus, the 5-second polling interval, and refreshToken in useSumsubKycFlow all call initiateSumsubKyc without crossRegion, so they will never trigger moveToLevel on the backend. This is the core invariant of the PR and it holds.
⚡ Performance Impact & Latency
Negligible. The changes introduce:
- One extra optional boolean field in the POST body
- No new
useState,useEffect,useRef, or extra renders - No change to request frequency (polling, WebSocket, mount-time fetch all unchanged)
🧹 Code Quality & DRY
- Clean pass-through: the flag propagates through 4 layers without any logic duplication — detection is correctly placed only at the view layer (
RegionsVerification), which is the sole place that has context about user intent vs existing state. - Body type widening (
Record<string, string | boolean | undefined>) insumsub.tsis correct and minimal. isCrossRegionlogic (!!sumsubVerificationRegionIntent && !!intent && intent !== sumsubVerificationRegionIntent) is readable, handles all edge cases (first-time KYC, same-region, cross-region), and is correctly guarded by double negation.- Minor: the
bodyobject insumsub.tscould optionally filter outundefinedentries before stringifying to be explicit, butJSON.stringifyalready handles this — not a real issue.
🧪 QA Testing Guide
| Scenario | Expected behaviour |
|---|---|
| First-time KYC — no existing verification, click "Verify now" for any region | crossRegion absent from request; normal KYC flow, no side effects |
| Cross-region — already APPROVED for EUROPE, click "Verify now" for US | crossRegion: true sent; backend triggers moveToLevel; new region unlocked on approval |
| Same-region resubmit — ACTION_REQUIRED for EUROPE, click "Retry" | crossRegion absent (after fix) or false (current); no moveToLevel triggered |
Page load / navigation — navigate to /profile/regions while approved |
Mount-time fetchCurrentStatus fires without crossRegion; status read-only, no rail enrollment side effects |
| Token refresh — leave Sumsub SDK idle until token expires | Refresh call has no crossRegion; no moveToLevel triggered |
| Polling — verification progress modal open, websocket delayed | Polling calls have no crossRegion; status updates correctly without backend side effects |
| Other entry points (add-money bank flow, withdraw Manteca, claim link flow) | None of these pass crossRegion; existing behaviour fully preserved |
TL;DR: One actionable fix — pass isCrossRegion || undefined instead of isCrossRegion at the call site in RegionsVerification.handleStartKyc to avoid sending "crossRegion": false" to the backend for same-region clicks. Everything else is solid.
🧠 Learnings used
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 852
File: src/hooks/useTransactionHistory.ts:177-239
Timestamp: 2025-05-14T21:16:06.369Z
Learning: When reviewing code, pay attention to and resolve CodeRabbit comments as they can contain useful refactoring suggestions and insights.
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 594
File: src/components/Request/Pay/Views/Initial.view.tsx:188-213
Timestamp: 2024-12-31T15:08:15.640Z
Learning: Always resolve coderabbit comments when reviewing code, since they can contain useful suggestions.
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 0
File: :0-0
Timestamp: 2026-03-04T18:32:51.654Z
Learning: In peanutprotocol/peanut-ui, Bridge-specific add-money and withdraw flows (`src/app/(mobile-ui)/add-money/[country]/bank/page.tsx`, `src/components/AddWithdraw/AddWithdrawCountriesList.tsx`, `src/components/Claim/Link/views/BankFlowManager.view.tsx`) have been migrated (PR `#1713`) to use the unified `isUserKycApproved` from `useKycStatus()` hook instead of per-component `liveKycStatus` + WebSocket state. The migration is complete; no more direct `bridgeKycStatus === 'approved'` checks in those files.
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 1654
File: src/components/Card/CardGeoScreen.tsx:41-45
Timestamp: 2026-02-02T06:03:48.192Z
Learning: In peanutprotocol/peanut-ui, KYC 2.0 uses the unified entry route '/profile/identity-verification'. Components (e.g., src/components/Card/CardGeoScreen.tsx) should avoid region-specific paths like '/profile/identity-verification/europe/bridge' and navigate to the unified route instead.
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 1693
File: src/app/(mobile-ui)/add-money/[country]/bank/page.tsx:206-207
Timestamp: 2026-03-04T18:35:17.673Z
Learning: In Bridge-specific add-money and withdraw flows (e.g., src/app/(mobile-ui)/add-money/[country]/bank/page.tsx), liveKycStatus from WebSocket tracks real-time bridge KYC status changes, and bridgeKycStatus is the persisted status. These flows use direct bridgeKycStatus === 'approved' checks instead of the unified isUserKycVerified helper. Migrating to the unified verifier requires careful testing of WebSocket-based real-time status tracking and is deferred to follow-up work.
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 1683
File: src/components/Kyc/SumsubKycFlow.tsx:218-230
Timestamp: 2026-02-23T16:00:24.665Z
Learning: In src/components/Kyc/SumsubKycFlow.tsx, the ToS confirmation flow in handleTosIframeClose intentionally continues to fetchUser() even when confirmBridgeTos() fails after retry. The phase-transition effect (which monitors rail status via useRailStatusTracking) serves as the actual validation mechanism, making the flow resilient to transient confirmation API failures while still ensuring correct state progression.
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 1690
File: src/hooks/useMultiPhaseKycFlow.ts:84-89
Timestamp: 2026-02-25T11:02:11.410Z
Learning: In src/hooks/useMultiPhaseKycFlow.ts, the bridge_tos phase does not require rail status tracking because handleTosIframeClose optimistically calls completeFlow() immediately after confirmBridgeTos() succeeds. The flow bypasses the phase-transition effect entirely for the happy path, completing the flow after fetchUser() without waiting for WebSocket rail status updates.
REVERIFYING is treated as approved for all access checks — user retains existing provider access while re-verifying for a new region. added to APPROVED_STATUSES set (single source of truth) so all downstream readers (useKycStatus, useQrKycGate, useIdentityVerification, KycStatusItem, etc.) automatically handle it correctly.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/constants/kyc.consts.ts`:
- Around line 13-15: APPROVED_STATUSES currently includes 'REVERIFYING', which
causes getKycStatusCategory() to classify re-verifying users as 'completed' and
breaks the cross-region flow; remove 'REVERIFYING' from the APPROVED_STATUSES
set in src/constants/kyc.consts.ts and instead update getKycStatusCategory() to
treat 'REVERIFYING' as 'processing' so UI components (KycStatusDrawer,
KycCompleted) render the processing state while keeping access-check helpers
(isKycStatusApproved, isUserKycVerified) unchanged if they must still treat
REVERIFYING as approved for access; ensure regionIntent is not cleared for
REVERIFYING users so initiateSumsubKyc() can run.
🪄 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: a4b08a0a-33a1-45f4-bad2-8a9a4b7662f4
📒 Files selected for processing (2)
src/app/actions/types/sumsub.types.tssrc/constants/kyc.consts.ts
✅ Files skipped from review due to trivial changes (1)
- src/app/actions/types/sumsub.types.ts
| // REVERIFYING = user is approved but re-verifying for a new region (cross-region KYC). | ||
| // treated as approved for access checks — user retains existing provider access. | ||
| const APPROVED_STATUSES: ReadonlySet<string> = new Set(['approved', 'ACTIVE', 'APPROVED', 'REVERIFYING']) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check all usages of getKycStatusCategory to assess impact of REVERIFYING returning 'completed'
echo "=== getKycStatusCategory usages ==="
rg -n -C3 'getKycStatusCategory'
echo ""
echo "=== isKycStatusApproved usages ==="
rg -n -C3 'isKycStatusApproved'
echo ""
echo "=== isUserKycVerified usages ==="
rg -n -C3 'isUserKycVerified'Repository: peanutprotocol/peanut-ui
Length of output: 17219
🏁 Script executed:
# Check the current implementation of getKycStatusCategory and surrounding constants
cat -n src/constants/kyc.consts.ts | head -90Repository: peanutprotocol/peanut-ui
Length of output: 4364
🏁 Script executed:
# Check KycStatusDrawer.tsx around the lines mentioned in the review (39-60, 131-137)
cat -n src/components/Kyc/KycStatusDrawer.tsx | head -150Repository: peanutprotocol/peanut-ui
Length of output: 7521
🏁 Script executed:
# Check if REVERIFYING is already handled specially anywhere
rg -n 'REVERIFYING' --type ts --type tsxRepository: peanutprotocol/peanut-ui
Length of output: 95
🏁 Script executed:
# Search for REVERIFYING references without type filter
rg -n 'REVERIFYING'Repository: peanutprotocol/peanut-ui
Length of output: 384
🏁 Script executed:
# Check if there's any conditional handling for REVERIFYING in the codebase
rg -n -B2 -A2 "statusCategory.*completed"Repository: peanutprotocol/peanut-ui
Length of output: 526
REVERIFYING in APPROVED_STATUSES breaks cross-region KYC flows.
Adding REVERIFYING to APPROVED_STATUSES causes getKycStatusCategory() to return 'completed' for users actively re-verifying for a new region. This creates two problems:
-
KycStatusDrawer prevents KYC initialization: Line 60 sets
regionIntent = undefinedwhenstatusCategory === 'completed', blockinginitiateSumsubKyc()from being called for REVERIFYING users who need to complete cross-region verification. -
Wrong UI shown to users: REVERIFYING users see the
KycCompletedcomponent (lines 131–139), displaying "verification complete" while they're still actively verifying.
Consider separating access-check logic from UI categorization:
Suggested fix: Handle REVERIFYING as 'processing' in getKycStatusCategory
export const getKycStatusCategory = (status: string): KycStatusCategory => {
+ // REVERIFYING users are approved but actively re-verifying for a new region
+ if (status === 'REVERIFYING') return 'processing'
if (APPROVED_STATUSES.has(status)) return 'completed'
if (FAILED_STATUSES.has(status)) return 'failed'
if (ACTION_REQUIRED_STATUSES.has(status)) return 'action_required'
return 'processing'
}This allows access checks (isKycStatusApproved, isUserKycVerified) to return true for REVERIFYING users while showing appropriate processing UI for the cross-region flow.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/constants/kyc.consts.ts` around lines 13 - 15, APPROVED_STATUSES
currently includes 'REVERIFYING', which causes getKycStatusCategory() to
classify re-verifying users as 'completed' and breaks the cross-region flow;
remove 'REVERIFYING' from the APPROVED_STATUSES set in
src/constants/kyc.consts.ts and instead update getKycStatusCategory() to treat
'REVERIFYING' as 'processing' so UI components (KycStatusDrawer, KycCompleted)
render the processing state while keeping access-check helpers
(isKycStatusApproved, isUserKycVerified) unchanged if they must still treat
REVERIFYING as approved for access; ensure regionIntent is not cleared for
REVERIFYING users so initiateSumsubKyc() can run.
|
@coderabbitai re-review in depth, more changes are made since last review Evaluate:
Also, write a very concise testing guide for QA |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 37662
Overall AssessmentThe PR is in good shape. The previously flagged 🐛 Risk of New Bugs / Breaking Existing Functionality✅
|
| Helper | With REVERIFYING |
Correct? |
|---|---|---|
isKycStatusApproved |
true |
✅ user retains access |
isUserKycVerified |
true |
✅ |
getKycStatusCategory |
'completed' |
✅ intentional (access preserved) |
isSumsubStatusInProgress |
false |
✅ not gated |
FAILED_STATUSES, PENDING_STATUSES, ACTION_REQUIRED_STATUSES are all unaffected. ✅
✅ getModalVariant handles REVERIFYING correctly
- Same region +
REVERIFYING: hitsdefault→'start'modal — lets user re-initiate. Intentional. - Different region +
REVERIFYING:clickedRegionIntent !== existingRegionIntentguard →'start'modal. ✅
✅ All other callers remain unaffected
Confirmed: all other call sites (SumsubKycFlow, KycStatusDrawer, MantecaFlowManager, BankFlowManager, AddWithdrawCountriesList, add-money/withdraw pages) omit the third arg. No changes needed there. ✅
✅ useCallback dependency arrays — correct
handleStartKyc: now includessumsubVerificationRegionIntent. ✅handleInitiateKycin both hooks:crossRegionis a parameter, never closed over. No dep array changes needed. ✅
⚡ Performance Impact & Latency
No change. No new state, hooks, effects, or render cycles. The only addition is an optional boolean in one POST body. ✅
🧹 Code Quality & DRY
- Single source of truth for the new status (
APPROVED_STATUSESinkyc.consts.ts). - Detection logic for cross-region remains correctly localized to the view layer.
? true : undefinedis idiomatic and correct.- Type widening (
string | boolean | undefined) in the server action body is minimal and correct.
🧪 Concise QA Testing Guide
| Scenario | What to verify |
|---|---|
| First-time KYC — no existing verification | crossRegion absent from POST body; normal flow, no side effects |
| Cross-region — APPROVED for EUROPE, click US | crossRegion: true in POST body; moveToLevel fires; new region unlocked after approval |
| Same-region resubmit — ACTION_REQUIRED for EUROPE, click Retry | crossRegion absent from POST body; no moveToLevel |
| REVERIFYING status — backend returns REVERIFYING on cross-region initiation | SDK opens; user completes flow; eventually transitions to APPROVED; progress modal stays open |
Page load/navigation — visit /profile/regions while APPROVED |
Mount-time fetchCurrentStatus fires without crossRegion; no backend side effects |
| Token refresh — leave SDK open until token expires | Refresh call has no crossRegion; flow continues normally |
| Polling — progress modal open, WebSocket delayed | Polling calls have no crossRegion; status updates correctly |
| Other entry points (add-money, withdraw, claim link) | No crossRegion sent; existing behaviour unchanged |
TL;DR: Two minor edge cases to verify against the backend contract — (1) whether REVERIFYING can arrive via WebSocket during SDK completion phase (if yes, add it to the exclusion list in the status-transition effect), and (2) whether REVERIFYING can come token-less (if yes, add a fast-exit branch alongside APPROVED). Everything else is correct and ready.
🧠 Learnings used
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 0
File: :0-0
Timestamp: 2026-03-04T18:32:51.654Z
Learning: In peanutprotocol/peanut-ui, Bridge-specific add-money and withdraw flows (`src/app/(mobile-ui)/add-money/[country]/bank/page.tsx`, `src/components/AddWithdraw/AddWithdrawCountriesList.tsx`, `src/components/Claim/Link/views/BankFlowManager.view.tsx`) have been migrated (PR `#1713`) to use the unified `isUserKycApproved` from `useKycStatus()` hook instead of per-component `liveKycStatus` + WebSocket state. The migration is complete; no more direct `bridgeKycStatus === 'approved'` checks in those files.
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 1683
File: src/components/Kyc/SumsubKycFlow.tsx:218-230
Timestamp: 2026-02-23T16:00:24.665Z
Learning: In src/components/Kyc/SumsubKycFlow.tsx, the ToS confirmation flow in handleTosIframeClose intentionally continues to fetchUser() even when confirmBridgeTos() fails after retry. The phase-transition effect (which monitors rail status via useRailStatusTracking) serves as the actual validation mechanism, making the flow resilient to transient confirmation API failures while still ensuring correct state progression.
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 1693
File: src/app/(mobile-ui)/add-money/[country]/bank/page.tsx:206-207
Timestamp: 2026-03-04T18:35:17.673Z
Learning: In Bridge-specific add-money and withdraw flows (e.g., src/app/(mobile-ui)/add-money/[country]/bank/page.tsx), liveKycStatus from WebSocket tracks real-time bridge KYC status changes, and bridgeKycStatus is the persisted status. These flows use direct bridgeKycStatus === 'approved' checks instead of the unified isUserKycVerified helper. Migrating to the unified verifier requires careful testing of WebSocket-based real-time status tracking and is deferred to follow-up work.
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 1690
File: src/hooks/useMultiPhaseKycFlow.ts:84-89
Timestamp: 2026-02-25T11:02:11.410Z
Learning: In src/hooks/useMultiPhaseKycFlow.ts, the bridge_tos phase does not require rail status tracking because handleTosIframeClose optimistically calls completeFlow() immediately after confirmBridgeTos() succeeds. The flow bypasses the phase-transition effect entirely for the happy path, completing the flow after fetchUser() without waiting for WebSocket rail status updates.
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 1654
File: src/components/Card/CardGeoScreen.tsx:41-45
Timestamp: 2026-02-02T06:03:48.192Z
Learning: In peanutprotocol/peanut-ui, KYC 2.0 uses the unified entry route '/profile/identity-verification'. Components (e.g., src/components/Card/CardGeoScreen.tsx) should avoid region-specific paths like '/profile/identity-verification/europe/bridge' and navigate to the unified route instead.
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 1078
File: src/hooks/useKycFlow.ts:129-141
Timestamp: 2025-08-11T10:35:02.715Z
Learning: In the KYC flow implementation in `src/hooks/useKycFlow.ts`, when Terms of Service (ToS) is accepted, there will always be a KYC link available in the `apiResponse`. The system ensures this invariant, so defensive checks for missing KYC links after ToS acceptance are unnecessary.
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 852
File: src/hooks/useTransactionHistory.ts:177-239
Timestamp: 2025-05-14T21:16:06.369Z
Learning: When reviewing code, pay attention to and resolve CodeRabbit comments as they can contain useful refactoring suggestions and insights.
Learnt from: Hugo0
Repo: peanutprotocol/peanut-ui PR: 594
File: src/components/Request/Pay/Views/Initial.view.tsx:188-213
Timestamp: 2024-12-31T15:08:15.640Z
Learning: Always resolve coderabbit comments when reviewing code, since they can contain useful suggestions.
Learnt from: kushagrasarathe
Repo: peanutprotocol/peanut-ui PR: 1693
File: src/constants/kyc.consts.ts:49-50
Timestamp: 2026-03-02T18:08:32.294Z
Learning: In src/constants/kyc.consts.ts, bridgeKycStatus is a field specific to the Bridge provider and always contains lowercase 'approved' when KYC is approved. Direct string comparison (bridgeKycStatus === 'approved') is correct and preferred over using isKycStatusApproved, since the field will never contain Manteca ('ACTIVE') or Sumsub ('APPROVED') statuses. The provider-specific field name indicates it only holds Bridge-formatted values.
…less handling 1. add REVERIFYING to exclusion list in status-transition effect so it doesn't close the progress modal if received via websocket during SDK completion 2. handle REVERIFYING + no token same as APPROVED — call onKycSuccess instead of showing misleading "Could not initiate verification" error
context
pairs with backend PR peanutprotocol/peanut-api-ts#643. must be deployed together.
changes
1. crossRegion flag threading
threads
crossRegionboolean through the KYC initiation chain:initiateSumsubKycserver action → backendPOST /users/identityuseSumsubKycFlow.handleInitiateKyc→ acceptscrossRegionparamuseMultiPhaseKycFlow.handleInitiateKyc→ passes throughRegionsVerification.handleStartKyc→ detects cross-region (clicked intent differs from existing) and passescrossRegion: true(omitted when same-region)automatic calls (fetchCurrentStatus, polling, component mounts) never set this flag, so they can't trigger moveToLevel or stale rail enrollment on the backend.
2. REVERIFYING status support
REVERIFYINGtoSumsubKycStatustype unionREVERIFYINGtoAPPROVED_STATUSESset inkyc.consts.ts(single source of truth)isKycStatusApproved,getKycStatusCategory,useKycStatus,useQrKycGate,useIdentityVerification,KycStatusItem, etc.test plan