Skip to content

TASK-23054: Home onboarding is one checklist until the first spend - #3474

Merged
Hugo0 merged 10 commits into
devfrom
task-23054-activation-add-money
Sep 25, 2026
Merged

Hugo0 merged 10 commits into
devfrom
task-23054-activation-add-money

Conversation

@Hugo0

@Hugo0 Hugo0 commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

TASK-23054. Hugo approved option A from the onboarding review (2026-09-25): one checklist on Home until the first spend, then the carousel. This replaces the narrower "any balance ticks Add money" fix.

What changes

Home shows one CTA class at a time. Until every checklist row is done, the slot shows the getting-started checklist. After that, it shows the carousel. The large deposit, card ("Spend anywhere Visa is accepted" / "Maybe later") and outbound ("Spend with Peanut" / "Start Spending") cards are gone. A due verification task card (#3467's PendingVerificationTasks arbiter) still replaces both. This PR extends that arbiter and adds no second one.

The checklist (GettingStartedChecklist, rules in src/utils/activation-step.utils.ts):

Row Done when Tap
Create account always —
Verify identity identity status verified. While processing, the subtitle says "In review" and a status chip shows ID check screen (/profile/accounts)
Add money any money received (API milestone funded/activated) or any money held: wallet USDC, card collateral, or a collateral top-up in transit. $0.17 by crypto counts Add drawer. It can be tapped before verification
Make the first payment API isActivated (card spend or QR pay, Lexicon v2) card + QR → FirstPaymentChooser (card / QR). Card only → /card. QR only → QR scanner
  • Which payment row shows depends on one selector: selectFirstPaymentRoute({ canSpendViaCard, canPayQr }) returns card_qr, card, qr, none or pending.
    • QR counts when the user can pay one now, or will once verified: a Manteca pay op that is not blocked, or, with no such rail yet, a residence in AR or BR (canReachQrPay). So a new card-eligible user in Brazil sees both options before verifying.
    • The copy follows the route: "Pay a QR or get the card", "Get the Peanut Card", "Pay a QR code".
    • With none (no card, no QR), the payment row is not shown. The list ends at Add money, and Home hands over to the carousel once all three rows are done.
    • pending means card eligibility is unknown (loading, or a failed request). The row keeps its place with a pulse placeholder, no tap and no outline, and the list cannot complete.
    • Sends never complete the checklist.
  • The next row is outlined in pink: the first open row that has something to do. A row that is in review is skipped. Every open row can still be tapped.
  • Progress starts at 25%, because Create account is always done.
  • Every row is one height: a title plus one subtitle line, in every state. Done rows keep a subtitle ("Username ready", "ID verified", "Money received"). Done and in-review rows use icon status chips; the status word is on the subtitle line. The copy is sized to fit 320px. Headless Playwright checked 7 states at 320, 375 and 430 px in all four locales (84 renders): rows are 75–76 px (the top row carries the group's top border), and no text is cut. A Jest test checks the structure: one title line and one truncating subtitle line per row, in every state.
  • An ID check in review no longer leaves Home empty.
  • Region-restricted and provider-rejection cards still replace the checklist. Their rules are unchanged, now keyed on "identity verified" instead of the old step names.
  • A rejection also wins over the carousel. The rejection logic now lives in useProviderRejection, so HomePage and ActivationCTAs read one answer. A verified, funded user with no card and no QR and a blocked bank rail keeps the rejection card.
  • The list does not complete while card eligibility is loading. With no QR rail, the route stays unsettled until card info answers. A failed request settles as no card. Without this, Home would flash the carousel and then swap back.

The activation definition is unchanged. API isActivated (card spend or Manteca QR pay) still drives the Lexicon metric and Rewards gating: showRewards, invite and bug-bounty slides, and the receipt referral. No API PR is needed.

PostHog:

  • activation_step_viewed now reports verify / add_money / first_payment, once per step per session. The old values were verify / deposit / card / outbound, on every Home visit.
  • home_checklist_viewed now sends first_payment_route instead of third_item. Dashboards that read the old values need an update.

Carousel (Konrad's QR banner rule, src/utils/home-carousel.utils.ts):

Also:

  • Copy in en, es-419, es-AR (voseo) and pt-BR, one line each (pt-BR row 4 title is "Primeiro pagamento" so it fits). Removed the unused home.activation.steps.*, spendWithPeanut, getCard*, firstPaymentNote and addMoneyRoutesKyc keys. The full old/new string table for Hugo's copy review is in the review page (section 2b).
  • Icons come from CONCEPT_ICONS. The hand-rolled arrow-up exemption is removed.
  • /dev/home-ctas, the dev surfaces and /dev/journey are updated.
  • 13 dev fixtures: home-new-user, home-verify-processing, home-verified-unfunded(-no-card), home-verified-crypto-dust, home-money-before-verify, home-collateral-only, home-funded (card + QR), home-funded-qr, home-funded-no-spend-path, home-provider-rejection, home-region-restricted, home-activated. A fixture can now declare its wallet balance (the demo overlay, set per tab and not persisted).
  • The Home entry in the wordiness baseline drops from 485 to 404.

Screens (375×667, local dev with the fixtures above)

State Checklist Tap / surface
New user in Brazil, $0, card offered Create ✓ · Verify · Add money · First payment "Pay a QR or get the card" — 25% Verify → ID check
ID check in review Verify "In review" · Add money — 25% Add drawer
Verified, $0 Verify ✓ "ID verified" · Add money — 50% Add drawer
Verified, $0.17 by crypto (ledger not booked) Add money ✓ "Money received" · First payment "Get the Peanut Card" — 75% /card
Money in before the ID check Add money ✓ · Verify — 50% ID check
Card holder, $0 wallet, $25 collateral Add money ✓ — 75% /card
Funded, card + Pix QR First payment "Pay a QR or get the card" — 75% chooser
Funded, Pix QR only First payment "Pay a QR code" — 75% QR scanner
No card, no QR, verified, $0 3 rows · Add money — 67% Add drawer
No card, no QR, verified, funded done carousel
Bank partner declined rejection card (also wins over the carousel) support / heal
Region restricted region card (unchanged) send or request
Activated done carousel

The Screen Library captures every fixture on this PR. The mono review page local/scratch/home-viz/onboarding.html has all 13 captures at full size, a contact sheet (checklist-sheet.jpg), the before states, and the copy table.

Tests

  • activation-step.utils.test.ts covers each state: new user, in review, needs action, verified $0, $0.17 crypto, collateral only, bank top-up spent, money before verify, activated. It also covers what completes the checklist for each route, the route selector for all four cases, and hasQrPayRail, whose cases moved from the ActivationCTAs suite.
  • home-carousel.utils.test.ts: a closed card stays closed, app-install comes back after 7 days, the legacy shape, an unreadable date, and the QR slide gate (no rail, already paid, loading).
  • HomePage.test.tsx checks that the two never show together: checklist or carousel, and a due task card replaces the checklist.
  • useActivationStatus tests the wiring. GettingStartedChecklist tests rows, the outline, the in-review state, percentages, every route's copy and tap, the pending row, three rows for none, and one title plus one subtitle line per row in every state. ActivationCTAs keeps its override suites and adds a test that activation_step_viewed fires once per step.
  • Local: prettier clean, tsc clean, full Jest green, node --test scripts/screens/*.test.mjs green.
  • Canonical funnel doc updated in mono f776b2be (product/activation-funnel.md).

Notes for review

  • A card holder who has not spent sees "Get the Peanut Card". Their tap goes to /card, where they can use the card. The copy could say "Pay with the Peanut Card" for holders. Left as specified.
  • The demo user (no milestone in demo data) now sees the checklist at "Make the first payment", not the card step.

Home told users holding money to add money. The step read only the API
milestone, which needs a posted ledger credit, and ignored card collateral;
the wallet balance counted only for the card upgrade. One rule now decides
funded for the step and the checklist: milestone funded, or any wallet USDC
or card collateral. The activation_step_viewed event follows the same step.
Hugo approved option A: new users saw a checklist, then a large card step,
then a spend card, with rules that disagreed about money ($0.17 by crypto
stayed on Add money). Home now shows one checklist — Create account, Verify
identity, Add money, Make the first payment — and the carousel only after it.
Add money is done on any money received or held (wallet or card collateral).
The payment row exists only for users who can make an activating spend and
completes on the API activation, so Lexicon v2 and Rewards gating are unchanged.
A closed carousel card stays closed (app install excepted), and Pay with QR
needs a QR rail.
…add-money

# Conflicts:
#	src/features/home/HomePage.tsx
…ure opens the chooser

The first-payment row no longer draws a hand-rolled arrow, so its icon
exemption goes.
@notion-workspace

Copy link
Copy Markdown

@Hugo0

Hugo0 commented Sep 25, 2026

Copy link
Copy Markdown
Contributor Author

/chip review

@vercel

vercel Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
peanut-wallet Ready Ready Preview Sep 25, 2026 2:47pm UTC

Request Review

@coderabbitai

coderabbitai Bot commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository: peanutprotocol/peanut-ui/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: ab969ee4-56e9-4120-affb-2bb273a385d2

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions

github-actions Bot commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Code-analysis diff

Painscore total: 8912.33 → 8935.2 (+22.87)
Findings: +12 net (+50 new, -38 resolved)

🆕 New findings (50)

  • critical complexity — src/dev/surfaces/registry.tsx — CC 98, MI 67.91, SLOC 503
  • critical complexity — src/hooks/useHomeCarouselCTAs.tsx — CC 56, MI 59.06, SLOC 268
  • critical complexity — src/dev/fixtures/registry.ts — CC 9, MI 23.67, SLOC 1437
  • critical complexity — src/app/(mobile-ui)/dev/journey/journeyData.ts — CC 1, MI 27.45, SLOC 221
  • high hotspot — src/components/Home/ActivationCTAs.tsx — 71 commits, +1048/-816 lines since 6 months ago
  • high hotspot — src/dev/fixtures/registry.ts — 66 commits, +2051/-374 lines since 6 months ago
  • high hotspot — src/hooks/useHomeCarouselCTAs.tsx — 51 commits, +552/-426 lines since 6 months ago
  • high complexity — src/components/Home/ActivationCTAs.tsx — CC 37, MI 49.99, SLOC 161
  • high complexity — src/components/Home/GettingStartedChecklist.tsx — CC 33, MI 59.39, SLOC 143
  • high complexity — src/utils/activation-step.utils.ts — CC 33, MI 63.31, SLOC 69
  • high complexity — src/hooks/useProviderRejection.ts — CC 30, MI 62.62, SLOC 96
  • medium high-mdd — src/hooks/useHomeCarouselCTAs.tsx:57 — useHomeCarouselCTAs: MDD 138.5 (uses across many lines from declarations)
  • medium high-mdd — src/hooks/useHomeCarouselCTAs.tsx:113 — : MDD 96.3 (uses across many lines from declarations)
  • medium high-mdd — src/components/Home/ActivationCTAs.tsx:45 — ActivationCTAs: MDD 81.1 (uses across many lines from declarations)
  • medium high-dlt — src/hooks/useHomeCarouselCTAs.tsx:57 — useHomeCarouselCTAs: DLT 50 (calls 50 distinct functions — high context load)
  • medium high-mdd — src/components/Home/GettingStartedChecklist.tsx:74 — GettingStartedChecklist: MDD 45.0 (uses across many lines from declarations)
  • medium high-mdd — src/components/Home/GettingStartedChecklist.tsx:85 — : MDD 30.2 (uses across many lines from declarations)
  • medium high-mdd — src/components/Home/FirstPaymentChooser.tsx:18 — FirstPaymentChooser: MDD 28.1 (uses across many lines from declarations)
  • medium method-complexity — src/hooks/useHomeCarouselCTAs.tsx:113 — CC 27 SLOC 129
  • medium complexity — src/utils/demo-balance.ts — CC 27, MI 66.58, SLOC 87

…and 30 more.

✅ Resolved (38)

  • src/dev/surfaces/registry.tsx — CC 98, MI 68.04, SLOC 497
  • src/components/Home/ActivationCTAs.tsx — CC 97, MI 55.25, SLOC 328
  • src/hooks/useHomeCarouselCTAs.tsx — CC 62, MI 58.46, SLOC 285
  • src/dev/fixtures/registry.ts — CC 9, MI 26.19, SLOC 1175
  • src/app/(mobile-ui)/dev/journey/journeyData.ts — CC 1, MI 25.34, SLOC 263
  • src/components/Home/ActivationCTAs.tsx — 67 commits, +1001/-471 lines since 6 months ago
  • src/dev/fixtures/registry.ts — 63 commits, +1754/-372 lines since 6 months ago
  • src/hooks/useHomeCarouselCTAs.tsx — 50 commits, +544/-389 lines since 6 months ago
  • src/components/Home/ActivationCTAs.tsx:54 — ActivationCTAs: MDD 151.6 (uses across many lines from declarations)
  • src/hooks/useHomeCarouselCTAs.tsx:84 — useHomeCarouselCTAs: MDD 138.5 (uses across many lines from declarations)
  • src/hooks/useHomeCarouselCTAs.tsx:140 — : MDD 95.4 (uses across many lines from declarations)
  • src/hooks/useHomeCarouselCTAs.tsx:84 — useHomeCarouselCTAs: DLT 48 (calls 48 distinct functions — high context load)
  • src/components/Home/GettingStartedChecklist.tsx:52 — GettingStartedChecklist: MDD 41.4 (uses across many lines from declarations)
  • src/components/Home/ActivationCTAs.tsx:54 — ActivationCTAs: DLT 37 (calls 37 distinct functions — high context load)
  • src/components/Home/GettingStartedChecklist.tsx:72 — : MDD 31.0 (uses across many lines from declarations)
  • src/components/Home/GettingStartedChecklist.tsx — CC 29, MI 59.32, SLOC 112
  • src/hooks/useHomeCarouselCTAs.tsx:140 — CC 28 SLOC 125
  • src/hooks/useActivationStatus.ts:53 — useActivationStatus: MDD 26.1 (uses across many lines from declarations)
  • src/utils/demo-balance.ts — CC 24, MI 66.26, SLOC 78
  • src/hooks/useActivationStatus.ts — CC 23, MI 54.44, SLOC 76

…and 18 more.

📈 Painscore deltas (top movers)

File Before After Δ
src/utils/activation-step.utils.ts 0.0 6.2 +6.2
src/hooks/useProviderRejection.ts 0.0 5.7 +5.7
src/components/Home/FirstPaymentChooser.tsx 0.0 4.2 +4.2
src/utils/home-carousel.utils.ts 0.0 4.0 +4.0
src/features/home/HomePage.tsx 6.5 8.5 +2.0
src/dev/fixtures/registry.ts 12.7 13.3 +0.7
src/hooks/useActivationStatus.ts 8.5 9.0 +0.5
src/components/Home/ActivationCTAs.tsx 16.5 14.6 -1.9

@github-actions

github-actions Bot commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

🧪 UI test report — ✅ all green

Suites

  • ✅ unit: 10208 ran, 0 failed, 0 skipped, 3.3m

📊 Coverage (unit)

metric %
statements 82.2%
branches 72.0%
functions 76.6%
lines 83.5%
⏱ 10 slowest test cases
time test
🐢 9.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › Network failure keeps loading while retries remain, then shows the generic error
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › MANTECA_SOURCE_OVER_MONTHLY_CAP fails fast with copy that names the real cause
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › routes the KYC rejection on its wire code, and does not retry it
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › MANTECA_MERCHANT_RECENT_REFUND fails fast with copy that names the real cause
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › User KYC not approved fails fast with copy that names the real cause
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › a refused idempotency key tells the user to scan again, not to contact support
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › MANTECA_MERCHANT_VOLUME_NEAR_CAP fails fast with copy that names the real cause
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › MANTECA_USER_NOT_PROVISIONED fails fast with copy that names the real cause
3.3s src/components/Card/share-asset/__tests__/shareAssetLayout.test.ts › never places two stickers in heavy overlap (broad seed sweep)
3.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › Going offline blames the connection, and reconnecting clears it for the recovered scan
📍 Inline annotations are in the **Unit test report** check above. Coverage artifact: `coverage-unit`. Generated by `.github/workflows/tests.yml`.

@chip-peanut-bot chip-peanut-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chip review — no blocking findings — this is not an approval

The review found two Home handoff defects, a PR-caused screen-test failure, and stale canonical funnel documentation.

Findings

  • MAJOR · src/hooks/useActivationStatus.ts:55 · Do not treat an unresolved card path as no spend path
    For a verified, funded, not-yet-activated account with no QR rail, useCardInfo initially has no data, so canSpendPathViaCard is false and this selector returns none. resolveOnboarding then marks the three-row list completed and Home shows the carousel; when card info loads and permits a card, Home swaps back to the first-payment checklist. If the card-info request fails, the payment row never appears. Keep card eligibility unknown until the query resolves and avoid completing onboarding from that unknown state; cover this loading/error transition in Home tests.

  • MAJOR · src/features/home/HomePage.tsx:71 · Preserve provider-rejection override after three-row completion
    A verified account that has received crypto, has no card or QR spend path, and has a blocked bank rail is marked onboarding-complete once Add money is done. This branch renders the carousel and never mounts ActivationCTAs, where the provider-rejection card and its support/retry action are selected. The old funded outbound path showed that rejection. Evaluate the rejection override before handing this cohort to the carousel, or move the override into the Home arbiter; add a funded-and-rejected case.

  • MAJOR · src/i18n/app/messages/es-419.json:106 · Repair the capture-copy lookup after deleting the outbound CTA key
    The screen-tests check fails at this head: capture-copy.mjs still maps Start Spending to home.activation.steps.outbound.cta, which this deletion removes. In es-419 the lookup now returns the English fallback instead of Empezar a gastar (the same stale path affects the other locales). Update the capture-copy mapping and its expected checkpoint to a live string, or remove the obsolete checkpoint, so pnpm screens:test passes.

  • MINOR · src/features/home/HomePage.tsx:28 · Update the canonical activation-funnel description
    This new Home rule keeps the checklist through first spend and removes the standalone post-funding card/outbound cards. The canonical mono product/activation-funnel.md still says the checklist is pre-funding only and a funded account sees a separate spend card. Coordinate that source-of-truth update so future implementation and analytics work do not follow the superseded flow.

Checked clean

  • Confirmed exact head and merge-base diff; the supplied base SHA is newer than the merge base, so unrelated withdraw changes were excluded.
  • Read the trusted PR description, Home/activation/card access/verification/carousel paths, relevant tests, and the canonical funnel context.
  • The screen-tests failure is the deleted outbound CTA translation path; typecheck, lint, format and wordiness checks were green when inspected.
  • No earlier review findings were supplied; issue and review comments were not read.

Security review: did not run — this change has no security, privacy or money surface, so it was not asked. This review is one reviewer short.

Third opinion: did not run — claude-api_error. This review is one reviewer short.

Exact head: 2f0d93c53a3f · Context: repo, product, lexicon · Took 10m

Comment thread src/hooks/useActivationStatus.ts Outdated
Comment thread src/features/home/HomePage.tsx Outdated
Comment thread src/i18n/app/messages/es-419.json
Comment thread src/features/home/HomePage.tsx
The surface capture now opens the chooser from the checklist row by test id,
so the translated button label it keyed on no longer exists.

@chip-peanut-bot chip-peanut-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chip review — no blocking findings — this is not an approval

The capture-copy failure is fixed. Two Home handoff defects and the canonical funnel documentation drift remain.

Findings

  • MAJOR · src/hooks/useActivationStatus.ts:55 · Do not treat an unresolved card path as no spend path
    For a verified, funded, not-yet-activated account with no QR rail, useCardInfo initially has no data, so canSpendPathViaCard is false and this selector returns none. resolveOnboarding marks the three-row list completed and Home shows the carousel; when card info loads and permits a card, Home swaps back to the first-payment checklist. If the card-info request fails, that payment row never appears. Keep card eligibility unknown until the query resolves and avoid completing onboarding from that unknown state; cover the loading/error transition in Home tests.

  • MAJOR · src/features/home/HomePage.tsx:71 · Preserve provider-rejection override after three-row completion
    A verified account that has received crypto, has no card or QR spend path, and has a blocked bank rail is marked onboarding-complete once Add money is done. This branch renders the carousel and never mounts ActivationCTAs, where the provider-rejection card and its support/retry action are selected. The old funded outbound path showed that rejection. Evaluate the rejection override before handing this cohort to the carousel, or move the override into the Home arbiter; add a funded-and-rejected case.

  • MINOR · src/features/home/HomePage.tsx:28 · Update the canonical activation-funnel description
    This new Home rule keeps the checklist through first spend and removes the standalone post-funding card/outbound cards. The canonical mono product/activation-funnel.md still says the checklist is pre-funding only and a funded account sees a separate spend card. Coordinate that source-of-truth update so future implementation and analytics work do not follow the superseded flow.

Checked clean

  • Confirmed the exact new head, trusted PR metadata and merge-base diff; only capture-copy mapping and test changed since the prior review.
  • P1 and P2 remain reachable in the current Home, card-access, and rejection paths; their diff anchors remain valid.
  • P3 is fixed: the removed outbound copy lookup and its stale expected checkpoint are gone; node --test scripts/screens/capture-copy.test.mjs passed (3 tests).
  • P4 remains unaddressed by this PR head. Exact-head CI checks had not yet registered when inspected.
  • No issue or review comments were read.

Security review: did not run — this change has no security, privacy or money surface, so it was not asked. This review is one reviewer short.

Third opinion: did not run — it reads only the first review of a pull request; the first reviewer checks later rounds. This review is one reviewer short.

Exact head: a71c3ee2e994 · Context: repo, product, lexicon · Took 6m

Comment thread src/hooks/useActivationStatus.ts Outdated
Comment thread src/features/home/HomePage.tsx Outdated
Comment thread src/features/home/HomePage.tsx
…ected rail outranks the carousel

Chip review: a user with no QR rail read as 'no spend path' while card info
was loading, so Home flashed the carousel and then swapped back. And a
funded, verified user with no card or QR and a blocked bank rail lost the
rejection card to the carousel. The rejection logic moves into
useProviderRejection so HomePage and ActivationCTAs read one answer.

@chip-peanut-bot chip-peanut-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chip review — no blocking findings — this is not an approval

The provider-rejection handoff and capture-copy failure are fixed. Card-route uncertainty and canonical funnel documentation drift remain.

Findings

  • MAJOR · src/hooks/useActivationStatus.ts:68 · Keep an unknown or failed card route distinct from no card route
    For a verified, funded account with no QR rail and an uncached card-info request, this computes route none while the query loads. resolveOnboarding keeps Home on the checklist, but GettingStartedChecklist renders only the three completed rows, showing 100% progress and no action; an eligible response then drops it to 75% and adds the card row. If the request fails, isLoading becomes false with cardInfo still absent, so this marks the route settled and switches to the carousel even though card eligibility is unknown. Represent pending/error separately, with a loading or retry affordance, and complete the three-row list only after a confirmed no-card result.

  • MINOR · src/features/home/HomePage.tsx:29 · Update the canonical activation-funnel description
    This new Home rule keeps the checklist through first spend and removes the standalone post-funding card/outbound cards. The canonical mono product/activation-funnel.md still says the checklist is pre-funding only and a funded account sees a separate spend card. Coordinate that source-of-truth update so future implementation and analytics work do not follow the superseded flow.

Checked clean

  • Confirmed the exact new head, trusted PR metadata, and merge-base diff; reviewed all nine files changed since the prior head.
  • P1/P5: the premature carousel during card-info loading is fixed, but the 100%-with-no-action loading state and failed-query handoff remain; P5 is a duplicate of P1.
  • P2/P6: Home now evaluates the shared provider-rejection predicate before carousel handoff, and ActivationCTAs renders the rejection for a funded three-row account; fixed.
  • P3: the obsolete capture-copy lookup is absent; focused capture-copy tests passed and exact-head screen-tests CI succeeded.
  • P4/P7: this PR head does not update the previously verified canonical funnel description; P7 is a duplicate of P4.
  • Exact-head eslint succeeded; unit and typecheck were still running when inspected. No issue or review comments were read.

Security review: did not run — this change has no security, privacy or money surface, so it was not asked. This review is one reviewer short.

Third opinion: did not run — it reads only the first review of a pull request; the first reviewer checks later rounds. This review is one reviewer short.

Exact head: d17d4ab17333 · Context: repo, product, lexicon · Took 6m

Comment thread src/hooks/useActivationStatus.ts Outdated
Comment thread src/features/home/HomePage.tsx
@github-actions

github-actions Bot commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

English · Español · Español (Argentina) · Português (Brasil)

Open screen library dashboard

After merge: f2cf582 → 3198989. Incomplete capture; unavailable states are listed in the report.

@github-actions

Copy link
Copy Markdown
Contributor

🖼 Visual diff — 12 screens moved

21 of 166 shots changed · 145 identical · baseline e266fa2 → head d17d4ab

worst % screen widths
19.22% avatar-picker 320, 430
13.09% card-access 320, 430
13.09% home-avatar 320, 430
13.09% home 320, 430
12.18% empty-home 320, 430
11.01% early-user 430
3.15% home-add-drawer 320, 430
3.15% home-send-drawer 320, 430
3.00% home-request-drawer 430
1.52% guest-invite 320, 430
0.92% reconsent 320, 430
0.30% empty-history 320
new screens (13)
  • home-activated
  • home-collateral-only
  • home-funded
  • home-funded-no-spend-path
  • home-funded-qr
  • home-money-before-verify
  • home-new-user
  • home-provider-rejection
  • home-region-restricted
  • home-verified-crypto-dust
  • home-verified-unfunded
  • home-verified-unfunded-no-card
  • home-verify-processing

job summary · before/after/diff images — artifact

Fixture screenshots, no backend. Advisory — this check never blocks a merge. Posted from the default branch by ds-shots-comment.yml; the report it renders is untrusted data.

…known card eligibility

Hugo: every checklist row is title plus one subtitle line in every state,
sized to fit 320px in all four locales (done and in-review status moves to
icon chips; the words sit on the subtitle line). Make the first payment
offers QR or card to anyone who can reach either, including a new user in a
QR country before verifying. Chip: loading or failed card info is not 'no
card' — the payment row holds its place and the list cannot complete.
…add-money

# Conflicts:
#	src/app/(mobile-ui)/dev/journey/journeyData.ts
#	src/components/Home/ActivationCTAs.tsx
@Hugo0
Hugo0 merged commit 3198989 into dev Sep 25, 2026
36 of 47 checks passed
@chip-peanut-bot

Copy link
Copy Markdown
Contributor

This pull request was already closed when the review finished, so these findings are follow-up work rather than a gate.

Chip review — no blocking findings — this is not an approval

The prior findings are fixed at this head. Two new issues remain: a known QR route is hidden when card lookup fails, and route analytics can be frozen at pending.

Findings

  • MAJOR · src/utils/activation-step.utils.ts:113 · Keep an available QR payment actionable when card lookup fails
    For a funded, verified user with an enabled Manteca QR pay rail, if GET /card fails after its retry, useCardInfo leaves cardInfo undefined. This selector returns pending even though canPayQr is true, and GettingStartedChecklist renders an untappable skeleton for the only remaining payment row indefinitely. The QR scanner is already a valid activation path; expose that action while card eligibility is unknown (or otherwise provide an actionable QR fallback), while preserving pending for the no-QR case.

  • MINOR · src/components/Home/GettingStartedChecklist.tsx:174 · Wait for a settled route before recording checklist route analytics
    On a fresh Home visit, /users/me can render the checklist before GET /card returns, so firstPaymentRoute is pending. This effect records home_checklist_viewed with pending and sets viewedRef, then never reports card, card_qr, qr, or none when the route settles. The new first_payment_route breakdown therefore measures request timing rather than the user route. Defer the one-shot event until the route is not pending; the activation_step_viewed effect should likewise avoid counting an untappable pending payment row as a viewed step.

Inline anchors unavailable for 2 finding(s); the findings remain in this summary.

Checked clean

  • Prior P1/P5/P8: unknown or failed card lookup now stays pending rather than completing as no route.
  • Prior P2/P6: HomePage and ActivationCTAs share the provider-rejection override; a rejected rail still outranks the carousel.
  • Prior P3: deleted Start Spending capture lookup is absent; current capture-copy mappings resolve live locale keys.
  • Prior P4/P7/P9: mono commit f776b2be updates product/activation-funnel.md and is an ancestor of origin/main.
  • PR diff against exact dev base, card/QR selectors, checklist actions, carousel gates, and merge-resolved routes reviewed.
  • Completed head checks including unit, eslint, typecheck, screen tests, and native export succeeded; capture and visual jobs were still in progress at review time.

Security review: did not run — this change has no security, privacy or money surface, so it was not asked. This review is one reviewer short.

Third opinion: did not run — it reads only the first review of a pull request; the first reviewer checks later rounds. This review is one reviewer short.

Exact head: 102d163bb755 · Context: repo, product · Took 10m

This branch was successfully deployed

1 active deployment
Preview — 102d163b Deployed Sep 25, 2026 by vercel[bot]
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