Skip to content

feat(kyc): provide-email sheet for the no-email verification dead-end#2342

Merged
Hugo0 merged 2 commits into
devfrom
feat/provide-email-action
Jul 3, 2026
Merged

feat(kyc): provide-email sheet for the no-email verification dead-end#2342
Hugo0 merged 2 commits into
devfrom
feat/provide-email-action

Conversation

@Hugo0

@Hugo0 Hugo0 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Companion to peanutprotocol/peanut-api-ts#1119. Users whose email was never captured dead-end on 'message support' — the only recovery for all 61 affected users (none have a Sumsub email either; verified against prod). The BE emits a provide-email NextAction for email-blocked rails; this PR renders it:

  • provide-email added to NextActionKind + capability gate (GateState variant, checked before restart-identity in the blocked branch).
  • New ProvideEmailStep (ActionModal + email field, BridgeTosStep shell): validates, POSTs update-user (first-time email set is allowed while KYC-locked), refetches capabilities. BE flips rails → PENDING and resubmits automatically.
  • Wired into both surfaces where the block manifests: home ActivationCTAs (detects reason.code === 'email_required', opens the sheet instead of the support drawer) and the bank add/withdraw gate (AddWithdrawCountriesList, mirrors accept-tos).

Risks / breaking changes

  • Deploy order: BE (feat: badges updates #1119) first. Until the BE emits the action, nothing changes here (gate branch never matches). If this FE lags the BE, blocked users see the generic state — same as today, no crash.
  • FE-only otherwise; no new deps.

QA

  • Unit: 1667 pass incl. 2 new gate tests (provide-email wins the blocked branch; plain blocked still dead-ends). Typecheck + build green.
  • Manual path once BE is live: user with email-blocked rail → home CTA or bank flow → email form → save → rail goes PENDING → normal in-progress UI.

Companion to peanut-api-ts#1119. Users whose email was never captured used
to dead-end on 'message support' (their only fix was a ticket); the BE now
emits a provide-email NextAction for those rails, and this renders it: an
email form (ActionModal, BridgeTosStep shell) wired into the two places the
block surfaces — the home activation CTA and the bank add/withdraw gate.
Saving posts update-user (first-time email set is allowed while KYC-locked)
and the BE flips the rails to PENDING and resubmits automatically.
@vercel

vercel Bot commented Jul 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
peanut-wallet Ready Ready Preview, Comment Jul 3, 2026 1:24am

Request Review

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 40 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 836d213e-806b-464a-8517-024e636209a7

📥 Commits

Reviewing files that changed from the base of the PR and between b655479 and 35700e9.

📒 Files selected for processing (6)
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx
  • src/components/Home/ActivationCTAs.tsx
  • src/components/Kyc/ProvideEmailStep.tsx
  • src/types/capabilities.ts
  • src/utils/capability-gate.test.ts
  • src/utils/capability-gate.ts

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Code-analysis diff

Painscore total: 5857.65 → 5867.21 (+9.56)
Findings: +4 net (+21 new, -17 resolved)

🆕 New findings (21)

  • critical complexity — src/components/AddWithdraw/AddWithdrawCountriesList.tsx — CC 122, MI 57.05, SLOC 347
  • critical complexity — src/utils/capability-gate.ts — CC 68, MI 63.85, SLOC 182
  • high complexity — src/components/Home/ActivationCTAs.tsx — CC 42, MI 59.12, SLOC 160
  • high hotspot — src/components/AddWithdraw/AddWithdrawCountriesList.tsx — 41 commits, +697/-480 lines since 6 months ago
  • medium high-mdd — src/components/AddWithdraw/AddWithdrawCountriesList.tsx:45 — AddWithdrawCountriesList: MDD 141.7 (uses across many lines from declarations)
  • medium high-dlt — src/components/AddWithdraw/AddWithdrawCountriesList.tsx:45 — AddWithdrawCountriesList: DLT 61 (calls 61 distinct functions — high context load)
  • medium high-mdd — src/components/Home/ActivationCTAs.tsx:77 — ActivationCTAs: MDD 45.1 (uses across many lines from declarations)
  • medium high-mdd — src/components/AddWithdraw/AddWithdrawCountriesList.tsx:447 — : MDD 28.5 (uses across many lines from declarations)
  • medium high-mdd — src/components/AddWithdraw/AddWithdrawCountriesList.tsx:438 — renderPaymentMethods: MDD 27.3 (uses across many lines from declarations)
  • medium method-complexity — src/components/AddWithdraw/AddWithdrawCountriesList.tsx:45 — CC 21 SLOC 118
  • medium method-complexity — src/components/AddWithdraw/AddWithdrawCountriesList.tsx:166 — CC 15 SLOC 53
  • medium complexity — src/components/Kyc/ProvideEmailStep.tsx — CC 11, MI 56.46, SLOC 58
  • medium react-effect-derives-state — src/components/AddWithdraw/AddWithdrawCountriesList.tsx:137 — small useEffect that only sets state from deps
  • medium react-effect-derives-state — src/components/Kyc/ProvideEmailStep.tsx:30 — small useEffect that only sets state from deps
  • low high-dlt — src/components/Home/ActivationCTAs.tsx:77 — ActivationCTAs: DLT 21 (calls 21 distinct functions — high context load)
  • low high-mdd — src/components/AddWithdraw/AddWithdrawCountriesList.tsx:166 — handleFormSubmit: MDD 18.6 (uses across many lines from declarations)
  • low high-mdd — src/utils/capability-gate.ts:187 — deriveGate: MDD 18.6 (uses across many lines from declarations)
  • low high-mdd — src/components/AddWithdraw/AddWithdrawCountriesList.tsx:256 — handleWithdrawMethodClick: MDD 14.7 (uses across many lines from declarations)
  • low high-mdd — src/components/Kyc/ProvideEmailStep.tsx:24 — ProvideEmailStep: MDD 11.3 (uses across many lines from declarations)
  • low missing-return-type — src/components/Home/ActivationCTAs.tsx:77 — ActivationCTAs: exported fn missing return type annotation

…and 1 more.

✅ Resolved (17)

  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx — CC 119, MI 56.62, SLOC 336
  • src/utils/capability-gate.ts — CC 62, MI 64.19, SLOC 167
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx — 40 commits, +688/-480 lines since 6 months ago
  • src/components/Home/ActivationCTAs.tsx — CC 34, MI 57.96, SLOC 130
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx:44 — AddWithdrawCountriesList: MDD 140.0 (uses across many lines from declarations)
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx:44 — AddWithdrawCountriesList: DLT 60 (calls 60 distinct functions — high context load)
  • src/components/Home/ActivationCTAs.tsx:76 — ActivationCTAs: MDD 40.9 (uses across many lines from declarations)
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx:438 — : MDD 28.5 (uses across many lines from declarations)
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx:429 — renderPaymentMethods: MDD 27.3 (uses across many lines from declarations)
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx:44 — CC 21 SLOC 114
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx:162 — CC 15 SLOC 53
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx:135 — small useEffect that only sets state from deps
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx:162 — handleFormSubmit: MDD 18.6 (uses across many lines from declarations)
  • src/components/Home/ActivationCTAs.tsx:76 — ActivationCTAs: DLT 17 (calls 17 distinct functions — high context load)
  • src/utils/capability-gate.ts:181 — deriveGate: MDD 16.2 (uses across many lines from declarations)
  • src/components/AddWithdraw/AddWithdrawCountriesList.tsx:252 — handleWithdrawMethodClick: MDD 14.7 (uses across many lines from declarations)
  • src/components/Home/ActivationCTAs.tsx:76 — ActivationCTAs: exported fn missing return type annotation

📈 Painscore deltas (top movers)

File Before After Δ
src/components/Kyc/ProvideEmailStep.tsx 0.0 8.4 +8.4
src/utils/capability-gate.ts 7.5 8.1 +0.5

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

🧪 UI test report — ✅ all green

Suites

  • unit: 1670 ran, 0 failed, 0 skipped, 25.9s

📊 Coverage (unit)

metric %
statements 55.1%
branches 38.5%
functions 43.1%
lines 55.0%
⏱ 10 slowest test cases
time test
3.6s src/components/Card/share-asset/__tests__/shareAssetLayout.test.ts › never places two stickers in heavy overlap (broad seed sweep)
0.5s src/components/Card/share-asset/__tests__/shareAssetLayout.test.ts › every sticker stays within canvas at any count
0.4s src/app/actions/__tests__/api-headers-extended.test.ts › should not include apiKey in updateUserById body
0.4s src/app/actions/__tests__/api-headers.test.ts › should include Content-Type in updateUserById
0.1s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › Perk claimed shows shake class + go home button
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle valid 9-digit US account
0.1s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › Perk claim in progress shows disabled button + progress
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle minimum length (6 digits) US account
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle too long for US account
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle valid ENS name
📍 Inline annotations are in the **Unit test report** check above. Coverage artifact: `coverage-unit`. Generated by `.github/workflows/tests.yml`.

…tract, shadowing, copy

getKycModalVariant maps provide-email to 'blocked' so unwired gate consumers
keep the contact-support floor instead of a bogus re-verify CTA; the gate and
ActivationCTAs both detect via the provide-email action kind (one contract,
no reason-code divergence) and prefer an email-blocked rail over an earlier
terminal one; the home CTA copy now says 'Add your email / Add email' instead
of promising support and opening a form; the sheet resets on reopen and
guards a not-yet-loaded userId.
@Hugo0

Hugo0 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Hugo0 Hugo0 marked this pull request as ready for review July 3, 2026 01:35
@Hugo0 Hugo0 merged commit 91d553c into dev Jul 3, 2026
18 of 20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant