Skip to content

chore: retire utm badge forwarding + dead acquisition-destination pipeline (TASK-21226) — HOLD until 2026-09-07 - #2881

Draft
kushagrasarathe wants to merge 1 commit into
devfrom
chore/offramp-utm-cleanup
Draft

chore: retire utm badge forwarding + dead acquisition-destination pipeline (TASK-21226) — HOLD until 2026-09-07#2881
kushagrasarathe wants to merge 1 commit into
devfrom
chore/offramp-utm-cleanup

Conversation

@kushagrasarathe

Copy link
Copy Markdown
Contributor

Warning

DO NOT MERGE before the offramp.xyz campaign links are confirmed dead — 2026-09-07 floor. Merging earlier stops ?utm_campaign=offramp from queueing the badge claim. Pairs with peanut-api-ts#1463 (either merge order is safe).

Summary

FE half of the offramp wind-down cleanup (TASK-21226):

  • utm_campaign is analytics-only now — badge-campaign-context stops source-qualifying it into utm: badge identities. A utm-only /invite link is a dead bare link.
  • Deletes the acquisition-destination pipeline, which collapsed to a constant /home after TASK-20535 removed the migration surface: acquisition-navigation.ts, registration-acquisition.ts (a guaranteed no-op), the acquisition claim projection + destinationForConfirmedBadgeCampaignAcquisition in badge-campaigns, destinationForInviteAcquisition, and the InvitesPage destination ladder.
  • LegacyInviteAcquisition shrinks to { campaignTag }; old backends still echoing fallback/destination are tolerated (fields ignored).
  • The 68-char deferred-payload identity bound stays, so utm:-prefixed identities queued before this deploy still settle (they resolve unknown at the backend and are dropped gracefully).

Task

TASK-21226 (parent: TASK-21539 Offramp wind-down)

Risks / breaking changes

  • After merge, ?utm_campaign=<x>-only links never queue a badge claim — intended; every live campaign uses badge_campaign/campaign or invite codes.
  • In-flight deferred install payloads carrying a bare utm_campaign lose their (already-unknown) badge intent. Cohort is pre-Sep-7 installs that never opened the app; the claim would resolve unknown anyway once api#1463 lands.
  • Screenshots: N/A (no visible change — routing/service cleanup only).

QA

  • npm test (4520 passed), npm run typecheck, npm run build — all green locally.

🤖 Generated with Claude Code

…on pipeline (TASK-21226)

utm_campaign is analytics-only now — it never becomes a badge identity.
The acquisition-destination machinery collapsed to a constant /home
after TASK-20535 removed the offramp migration surface, so this deletes
it: acquisition-navigation, registration-acquisition, the destination
reads in badge-campaigns/invite-acquisition, and the InvitesPage ladder.

DO NOT MERGE before the offramp.xyz links are confirmed dead
(2026-09-07 floor). Pairs with peanut-api-ts#1463.
@notion-workspace

Copy link
Copy Markdown

@vercel

vercel Bot commented Aug 31, 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 Aug 31, 2026 5:45am

Request Review

@coderabbitai

coderabbitai Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

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

@github-actions

Copy link
Copy Markdown
Contributor

Code-analysis diff

Painscore total: 7211.27 → 7204.32 (-6.95)
Findings: -2 net (+31 new, -33 resolved)

🆕 New findings (31)

  • critical complexity — src/components/Invites/InvitesPage.tsx — CC 84, MI 55.47, SLOC 210
  • critical complexity — src/services/badge-campaigns.ts — CC 83, MI 60.33, SLOC 221
  • high hotspot — src/hooks/useZeroDev.ts — 49 commits, +592/-365 lines since 6 months ago
  • high complexity — src/components/Invites/badge-campaign-context.ts — CC 47, MI 63.42, SLOC 162
  • high hotspot — src/components/Invites/InvitesPage.tsx — 37 commits, +572/-379 lines since 6 months ago
  • medium high-mdd — src/components/Invites/InvitesPage.tsx:37 — InvitePageContent: MDD 107.2 (uses across many lines from declarations)
  • medium high-mdd — src/hooks/useZeroDev.ts:64 — useZeroDev: MDD 70.7 (uses across many lines from declarations)
  • medium high-dlt — src/hooks/useZeroDev.ts:64 — useZeroDev: DLT 68 (calls 68 distinct functions — high context load)
  • medium high-dlt — src/components/Invites/InvitesPage.tsx:37 — InvitePageContent: DLT 47 (calls 47 distinct functions — high context load)
  • medium high-dlt — src/hooks/useZeroDev.ts:76 — handleRegister: DLT 41 (calls 41 distinct functions — high context load)
  • medium high-mdd — src/hooks/useZeroDev.ts:76 — handleRegister: MDD 31.8 (uses across many lines from declarations)
  • medium high-mdd — src/hooks/useZeroDev.ts:330 — : MDD 28.2 (uses across many lines from declarations)
  • medium method-complexity — src/components/Invites/InvitesPage.tsx:37 — InvitePageContent CC 22 SLOC 96
  • medium method-complexity — src/services/badge-campaigns.ts:134 — parseBackendBadgeCampaignClaim CC 15 SLOC 16
  • low high-dlt — src/hooks/useZeroDev.ts:330 — : DLT 19 (calls 19 distinct functions — high context load)
  • low high-mdd — src/components/Invites/InvitesPage.tsx:142 — : MDD 17.7 (uses across many lines from declarations)
  • low high-dlt — src/hooks/useZeroDev.ts:267 — handleLogin: DLT 18 (calls 18 distinct functions — high context load)
  • low structural-dup — components/Invites/InvitesPage.test.tsx:170 — 17 duplicate lines / 61 tokens with components/Invites/InvitesPage.test.tsx:380
  • low structural-dup — components/Invites/InvitesPage.test.tsx:453 — 17 duplicate lines / 74 tokens with components/Invites/InvitesPage.test.tsx:585
  • low structural-dup — components/Invites/InvitesPage.test.tsx:168 — 16 duplicate lines / 60 tokens with components/Invites/InvitesPage.test.tsx:199

…and 11 more.

✅ Resolved (33)

  • src/services/badge-campaigns.ts — CC 91, MI 60.16, SLOC 240
  • src/components/Invites/InvitesPage.tsx — CC 87, MI 55.1, SLOC 214
  • src/components/Invites/badge-campaign-context.ts — CC 48, MI 63.25, SLOC 171
  • src/hooks/useZeroDev.ts — 48 commits, +587/-358 lines since 6 months ago
  • src/app/shhhhh/ShhhhhLandingPage.tsx — 37 commits, +1164/-505 lines since 6 months ago
  • src/components/Invites/InvitesPage.tsx:39 — InvitePageContent: MDD 109.8 (uses across many lines from declarations)
  • src/hooks/useZeroDev.ts:65 — useZeroDev: MDD 70.0 (uses across many lines from declarations)
  • src/hooks/useZeroDev.ts:65 — useZeroDev: DLT 69 (calls 69 distinct functions — high context load)
  • src/components/Invites/InvitesPage.tsx:39 — InvitePageContent: DLT 49 (calls 49 distinct functions — high context load)
  • src/hooks/useZeroDev.ts:77 — handleRegister: DLT 42 (calls 42 distinct functions — high context load)
  • src/hooks/useZeroDev.ts:77 — handleRegister: MDD 31.2 (uses across many lines from declarations)
  • src/hooks/useZeroDev.ts:332 — : MDD 28.2 (uses across many lines from declarations)
  • src/components/Invites/InvitesPage.tsx:39 — InvitePageContent CC 22 SLOC 96
  • src/services/badge-campaigns.ts:135 — parseBackendBadgeCampaignClaim CC 17 SLOC 19
  • src/components/Invites/InvitesPage.tsx:144 — : MDD 18.9 (uses across many lines from declarations)
  • src/hooks/useZeroDev.ts:332 — : DLT 19 (calls 19 distinct functions — high context load)
  • src/hooks/useZeroDev.ts:269 — handleLogin: DLT 18 (calls 18 distinct functions — high context load)
  • components/Invites/InvitesPage.test.tsx:168 — 17 duplicate lines / 61 tokens with components/Invites/InvitesPage.test.tsx:391
  • components/Invites/InvitesPage.test.tsx:464 — 17 duplicate lines / 74 tokens with components/Invites/InvitesPage.test.tsx:604
  • components/Invites/InvitesPage.test.tsx:166 — 16 duplicate lines / 60 tokens with components/Invites/InvitesPage.test.tsx:197

…and 13 more.

📈 Painscore deltas (top movers)

File Before After Δ
src/services/invite-acquisition.ts 4.4 3.7 -0.7
src/services/registration-acquisition.ts 2.7 0.0 -2.7
src/services/acquisition-navigation.ts 3.2 0.0 -3.2

@github-actions

Copy link
Copy Markdown
Contributor

🧪 UI test report — ✅ all green

Suites

  • unit: 4526 ran, 0 failed, 0 skipped, 1.6m

📊 Coverage (unit)

metric %
statements 72.5%
branches 58.1%
functions 63.5%
lines 73.4%
⏱ 10 slowest test cases
time test
4.1s src/components/Card/share-asset/__tests__/shareAssetLayout.test.ts › never places two stickers in heavy overlap (broad seed sweep)
1.7s src/components/Profile/views/__tests__/ResidenceChangeModal.test.tsx › prefers the server value over a stale device mirror
1.7s src/components/Profile/views/__tests__/ResidenceChangeModal.test.tsx › the change cooldown shows its date and blocks changing to another country, not re-saving
1.5s src/components/Setup/Views/__tests__/Residence.test.tsx › reveals the second selector via the multi-doc link
1.5s src/components/Profile/views/__tests__/ResidenceChangeModal.test.tsx › saves the declared residence, refetches, and closes
1.2s src/components/Profile/views/__tests__/ResidenceChangeModal.test.tsx › swaps from the server value with no device mirror at all
1.2s src/components/Profile/views/__tests__/ResidenceChangeModal.test.tsx › moving to a country in neither slot leaves the second document alone
1.2s src/components/Setup/Views/__tests__/Residence.test.tsx › returns to the selector from the heads-up
1.0s src/hooks/query/__tests__/user.test.tsx › does NOT clear a token that rotated mid-request (stale 401 racing a fresh login)
1.0s src/components/Profile/views/__tests__/ResidenceChangeModal.test.tsx › promoting the second document country swaps the pair instead of dropping one
📍 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

No actionable defects found for the planned post-2026-09-07 merge. The UTM retirement, mixed-version parsing, queued identity settlement, and /home navigation cleanup are consistent; keep the explicit merge hold.

Checked clean

  • Exact detached HEAD and merge base match the supplied SHAs; the review covered all 16 changed invite and badge files.
  • Correctness: traced URL parsing, deferred-install restore, logged-in auto-claim, registration acceptance, waitlist retry, and the Shhhhh continuation.
  • Security and adversarial paths: malformed or mixed-version acquisition payloads stay bounded to opaque badge claims and /home; the validated redirect still has priority.
  • Slop and architecture: the removed destination services have no production references, and the remaining acquisition paths preserve their tests.
  • CI at the exact head completed successfully, including format, lint, typecheck, unit, design-system, analysis, and preview checks.
  • The linked task and PR both require no merge before 2026-09-07; the Lexicon has no separate UTM or badge-campaign definition, so behavior was verified from the task and code.

Second opinion by moonshotai/kimi-k3: 0 finding(s), marked with the model name. It reads the diff only, so treat its findings as advice.

Exact head: 75f35ab071df · Context: repo, product, ops, notion

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.

2 participants