Skip to content

Remove referrals feature, keep freebuff creator attribution#519

Merged
jahooma merged 7 commits intomainfrom
jahooma/remove-referrals
Apr 20, 2026
Merged

Remove referrals feature, keep freebuff creator attribution#519
jahooma merged 7 commits intomainfrom
jahooma/remove-referrals

Conversation

@jahooma
Copy link
Copy Markdown
Contributor

@jahooma jahooma commented Apr 19, 2026

Summary

Removes the referrals feature while preserving historical data, restores simplified creator/referrer landing pages, and wires freebuff creator attribution through OAuth.

Removed:

  • CLI /refer-friends command, referral banner, and related UI/tests
  • Web referral promotion UI (onboarding flow referrer step, homepage promo, navbar link, affiliates page, API redemption, server helpers, redirect component)
  • Shared referral limits, util helpers, and analytics events

Kept / Simplified:

  • DB schema and legacy referral bonus grants intact
  • Profile "Referrals" section now read-only
  • Codebuff /[sponsee]/referrals/[code] landing pages restored but credit-free — just shows "{Name} invited you to Codebuff!" with install instructions
  • Freebuff /onboard preserves ?referrer= and shows "{Name} invited you to try Freebuff!" for logged-in users
  • ?referrer= now persists through OAuth via localStorage.freebuff_referrer, set in SignInButton and LoginCard before signIn; ReferrerTracker mounted in the root layout fires the FREEBUFF_REFERRER_ATTRIBUTED PostHog event on any post-OAuth landing page

Test plan

  • Visit /get-started?referrer=Bob, sign in, confirm PostHog receives freebuff.referrer_attributed with referrer=Bob and $set_once.freebuff_referrer=Bob
  • Visit /login?referrer=Bob directly (no get-started), sign in, confirm attribution still fires
  • Visit a codebuff referral link like /somehandle, confirm redirect to /referrals/<code>?referrer=somehandle and landing page shows referrer name + install CTA
  • Confirm profile Referrals section shows past referred users as read-only list

🤖 Generated with Claude Code

Strip the /refer-friends CLI command, web referral pages, affiliate
sponsee routes, and one-time referral redemption API. Simplify the
profile referrals section to a read-only list of who you referred.
Keep DB schema, legacy monthly bonus grants, and the GrantType enum
so historical referrals continue to pay out.

Restore creator attribution for freebuff only: /get-started already
accepts ?referrer=<name> and persists it; /onboard fires a
FREEBUFF_REFERRER_ATTRIBUTED PostHog event with \$set_once on first
visit post-login. /onboard now redirects logged-out visitors to
/get-started (or /login when an auth_code is present) and greets
logged-in users with an optional "{Name} invited you to try Freebuff!"
header. Fixes a pre-existing bug where auth_code was dropped when
/onboard redirected unauthenticated users.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 19, 2026

Greptile Summary

This PR removes the Codebuff referral program (CLI /refer-friends command, web referral/affiliate/sponsee pages, and one-time referral redemption API) while preserving all historical referral data in the DB and keeping legacy monthly bonuses paying out. It also adds a lightweight freebuff creator attribution flow: /get-started?referrer=<name> stores the name to localStorage, and /onboard fires a FREEBUFF_REFERRER_ATTRIBUTED PostHog event (with $set_once) on first post-login visit. The profile Referrals tab becomes a read-only list.

Key changes:

  • Deleted: cli/src/commands/referral.ts, web/src/app/affiliates/, web/src/app/referrals/[code]/, web/src/app/[sponsee]/, web/src/app/api/referrals/helpers.ts, web/src/components/onboard/onboarding-flow.tsx, web/src/components/onboard/onboard-client-wrapper.tsx, web/src/lib/server/referral.ts, common/src/util/referral.ts
  • Simplified: GET /api/referrals no longer fetches referral_code/referral_limit; /api/v1/me drops the derived referral_link field and referral_code from valid fields; UserProfile type drops referral_code
  • Added: freebuff/web/src/components/referrer-tracker.tsx — client component that reads freebuff_referrer from localStorage, fires PostHog event, and removes the key; freebuff /onboard now redirects unauthenticated users with auth_code to /login (fixes a prior bug that dropped auth_code)
  • Minor: normalizeReferrer is duplicated in both freebuff/web/src/app/onboard/page.tsx and get-started/page.tsx; ReferrerTracker fires on all StatusCard branches (including error pages), not only the success path

Confidence Score: 4/5

Safe to merge; the referral cleanup is complete and the creator attribution flow is logically sound, with one P2 concern around ReferrerTracker firing on error pages.

Large deletion PR (3800+ lines removed) with focused new additions for freebuff creator attribution. The deletion is clean with no dangling references. The new ReferrerTracker uses $set_once which makes premature firing on error pages a non-issue for PostHog data quality. The redirect logic fix for auth_code preservation is correct. One P2 issue (ReferrerTracker on error branches) and one style issue (duplicated normalizeReferrer) remain.

freebuff/web/src/app/onboard/page.tsx — ReferrerTracker placement in all StatusCard branches; freebuff/web/src/app/get-started/get-started-client.tsx — paired normalizeReferrer duplication

Important Files Changed

Filename Overview
freebuff/web/src/app/onboard/page.tsx Updated to redirect unauthenticated users to /login (with auth_code) or /get-started, and to show "{Name} invited you!" greeting; ReferrerTracker is placed in all StatusCard branches including error pages, which causes premature localStorage clearance on auth failures.
freebuff/web/src/components/referrer-tracker.tsx New client component that reads freebuff_referrer from localStorage, fires FREEBUFF_REFERRER_ATTRIBUTED PostHog event with $set_once, and clears the key; fires on all onboard StatusCard branches, not just success.
web/src/app/api/referrals/route.ts POST handler (referral redemption) removed cleanly; GET handler simplified to no longer fetch user row for referral_code/referral_limit; ReferralData type updated correctly.
web/src/app/api/v1/me/_get.ts Removed derived referral_link field and related plumbing; VALID_USER_INFO_FIELDS is now the single source of truth for field validation; logic simplified correctly.
web/src/app/profile/components/referrals-section.tsx Converted from interactive referral-sharing UI to read-only list; referral link copy button, limit display, and refetchInterval all removed cleanly.
web/src/app/api/referrals/helpers.ts Entire referral redemption helper (redeemReferralCode) deleted; no remaining references in the codebase.
cli/src/commands/referral.ts CLI /refer-friends command deleted entirely along with its tests and registry entry.
web/src/components/onboard/onboarding-flow.tsx Entire onboarding flow component (referral-triggered) deleted; web/src/components/onboard/onboard-client-wrapper.tsx also deleted.

Sequence Diagram

sequenceDiagram
    participant U as User Browser
    participant GS as GetStarted Page
    participant LS as localStorage
    participant Login as Login Page
    participant Onboard as Onboard Page
    participant RT as ReferrerTracker
    participant PH as PostHog

    U->>GS: Visit /get-started with referrer param
    GS->>LS: setItem freebuff_referrer
    Note over GS: posthog FREEBUFF_GET_STARTED_VIEWED

    U->>U: Install CLI, run freebuff
    U->>Onboard: CLI opens onboard with auth code (not logged in)
    Onboard-->>Login: redirect to login preserving auth code and referrer

    U->>Login: Sign in via OAuth
    Login-->>Onboard: OAuth callback back to onboard

    Onboard->>Onboard: Validate auth code, create CLI session
    Onboard->>RT: Render ReferrerTracker component
    RT->>LS: getItem freebuff_referrer
    RT->>PH: capture FREEBUFF_REFERRER_ATTRIBUTED with set_once
    RT->>LS: removeItem freebuff_referrer
    Onboard-->>U: Show Login successful
Loading

Comments Outside Diff (1)

  1. freebuff/web/src/app/onboard/page.tsx, line 51-55 (link)

    P2 ReferrerTracker fires and clears localStorage on error pages

    ReferrerTracker is placed inside StatusCard, which is used for every branch of the onboard flow — including error states ("Invalid auth code", "Auth code expired", "Unable to complete login"). This means if a user visits /onboard with an invalid/expired auth code while freebuff_referrer is set in localStorage, the attribution event fires and the key is removed. When they retry with a new auth code, the event won't fire again.

    The PostHog $set_once ensures the attribution IS correctly recorded on the first fire, so the data isn't actually lost. But if the event fires on an error page (before a successful login), the freebuff_referrer localStorage key is removed, and the success page won't fire the event again. This is a subtle UX inconsistency: the event label implies "first post-login visit" but actually fires on any /onboard visit (including failures).

    Consider rendering ReferrerTracker only on the success path (the !authCode greeting page or the success case) to align with the intended "post-login" attribution semantics, or simply move <ReferrerTracker /> out of StatusCard and render it only in the !authCode and success branches.

Reviews (1): Last reviewed commit: "Remove referrals feature while preservin..." | Re-trigger Greptile

Comment on lines +27 to 32
if (!raw) return null
const trimmed = raw.trim().slice(0, 50)
return trimmed || null
}

interface PageProps {
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.

P2 normalizeReferrer duplicated across two files

The normalizeReferrer function is identical in both freebuff/web/src/app/onboard/page.tsx and freebuff/web/src/app/get-started/page.tsx. These should be extracted to a shared utility (e.g. freebuff/web/src/lib/referrer.ts) to avoid drift if the logic ever changes.

// freebuff/web/src/lib/referrer.ts
export function normalizeReferrer(raw: string | undefined): string | null {
  if (!raw) return null
  const trimmed = raw.trim().slice(0, 50)
  return trimmed || null
}

jahooma and others added 6 commits April 19, 2026 17:42
Brings back the codebuff referral landing routes (/[sponsee], /referrals/[code],
/api/referrals/[code]) without free-credit mentions, and ensures freebuff persists
?referrer= through OAuth by saving to localStorage in all sign-in entrypoints and
mounting ReferrerTracker in the root layout.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Saves the referrer display name to localStorage on /referrals/[code] and swaps
the /onboard welcome/success title to "{Name} invited you to Codebuff!" when
it's present, mirroring the freebuff attribution pattern.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds a ReferrerTracker to the codebuff root layout so any signed-in user who
passed through /referrals/<code> gets attributed via PostHog (with \$set_once)
on whatever page they eventually land on. Split the localStorage key so the
tracker and the /onboard welcome card don't race to clear each other.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Consolidate to a single `codebuff_referrer` localStorage key. WelcomeCard
  now both fires the PostHog attribution event (post-auth) and renders the
  personalized title, removing the tracker/welcome-card race.
- Delete ReferrerTracker and its mount in the root layout.
- Replace HTTP self-fetch in /referrals/[code] with a direct DB query and
  delete the now-unused /api/referrals/[code] route.
- Inline the trivial renderSuccessPage/renderErrorCard wrappers in the
  onboard page.
- Hide the Referrals profile tab when the user has no referral history.
- Strip leftover console.log debug statements from SignInButton.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@jahooma jahooma merged commit 4e3eb3e into main Apr 20, 2026
10 of 11 checks passed
@jahooma jahooma deleted the jahooma/remove-referrals branch April 20, 2026 04:34
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