Skip to content

refactor(onboarding): retire /onboarding/* into /setup/* via config redirects (chat#1889 item 1, part 1) - #1887

Merged
sweetmantech merged 4 commits into
mainfrom
feat/converge-onboarding-surfaces
Jul 27, 2026
Merged

refactor(onboarding): retire /onboarding/* into /setup/* via config redirects (chat#1889 item 1, part 1)#1887
sweetmantech merged 4 commits into
mainfrom
feat/converge-onboarding-surfaces

Conversation

@sweetmantech

@sweetmantech sweetmantech commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

What

Today direct-chat signups render the unified OnboardingSequence (via HomePageuseOnboardingGate), while marketing-funnel signups deep-link to the standalone /onboarding/first-task mount — a second, divergent onboarding surface.

This ships the minimal user-testable first slice of convergence: the funnel entry now routes through the same surface.

Change

  • app/onboarding/first-task/page.tsx — replace the standalone <FirstTaskStep /> mount with redirect("/").

The home gate renders OnboardingSequence at the account's derived step (getOnboardingStep — first unmet checkpoint), so the funnel CTA always lands at the right step instead of a hard-coded first-task, and both entry paths converge on one experience.

Why a redirect (not re-mounting the sequence here)

OnboardingSequence needs the full gate wiring (checkpoints, session skip flags, resume) that HomePage already owns. Redirecting to / reuses that single source of truth (DRY) rather than duplicating the gate on this route.

Deferred follow-up (out of scope here)

  • Fully retire the interim standalone /onboarding/* mounts (/onboarding/first-task once nothing links to it, plus /onboarding/roster).
  • Repoint any external/marketing deep-links straight at /.

Kept as a redirect for now so any live funnel link keeps working through the cutover.

Verification

  • pnpm exec tsc --noEmit — clean for the changed page.
  • pnpm exec eslint app/onboarding/first-task/page.tsx — clean.
  • Behavior: visiting /onboarding/first-task now server-redirects to /, where an incomplete account resumes OnboardingSequence at its derived step (existing HomePage behavior, covered by components/Home/__tests__/HomePage.onboarding.test.tsx).

Targets main. Part of chat#1885 (converge the two onboarding surfaces).

🤖 Generated with Claude Code


Summary by cubic

Converges funnel and email entry on the canonical setup flow. /onboarding/first-task now 308-redirects to /setup/tasks and /onboarding/roster to /setup/artists; updates the catalog report CTA to /setup/tasks. Aligns with chat#1889 and progresses chat#1885.

  • Refactors
    • Move redirects to 308 edge rules in next.config.mjs and delete the /onboarding/* page stubs.
    • Add tests for redirect rules and for CatalogReportCta linking to /setup/tasks.

Written for commit df30211. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features
    • Updated onboarding navigation so the “first task” step now routes users to the canonical task setup flow.
    • Roster onboarding behavior was updated by removing the prior social step flow from the roster page.
    • Updated catalog report calls to action to direct users to the current task setup experience.
  • Documentation
    • Refreshed in-code documentation/comments to match the current onboarding routing and mounting flow.

…quence

The funnel-entry deep-link (/onboarding/first-task) rendered a standalone
FirstTaskStep mount — a surface distinct from the unified OnboardingSequence
that direct-chat signups see. Redirect it to the home gate, which renders
OnboardingSequence at the account's derived step, so both entry paths converge
on one onboarding experience and the funnel CTA always lands at the correct
step rather than a hard-coded one.

Deferred (noted in PR): fully retire the interim standalone /onboarding/*
mounts and repoint external deep-links.

Refs chat#1885.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cursor

cursor Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@vercel

vercel Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated (UTC)
chat Ready Ready Preview Jul 27, 2026 4:37pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f0b602cf-2dcc-40f6-a07c-c68fc1f0d013

📥 Commits

Reviewing files that changed from the base of the PR and between 3d26e22 and df30211.

⛔ Files ignored due to path filters (2)
  • __tests__/nextConfigRedirects.test.ts is excluded by !**/*.test.* and included by none
  • next.config.mjs is excluded by none and included by none
📒 Files selected for processing (5)
  • app/onboarding/first-task/page.tsx
  • app/onboarding/roster/page.tsx
  • app/setup/tasks/page.tsx
  • components/Catalog/report/CatalogReportCta.tsx
  • components/Onboarding/RosterSocialsFlow.tsx
💤 Files with no reviewable changes (2)
  • app/onboarding/roster/page.tsx
  • app/onboarding/first-task/page.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/Catalog/report/CatalogReportCta.tsx

📝 Walkthrough

Walkthrough

Legacy onboarding entrypoints are adjusted toward the canonical setup flow. The catalog report CTA now links to /setup/tasks, and documentation is updated for the task page and roster socials mounting paths.

Changes

Onboarding route migration

Layer / File(s) Summary
Canonical task route wiring
components/Catalog/report/CatalogReportCta.tsx, app/setup/tasks/page.tsx
The catalog CTA now targets /setup/tasks; related module and page descriptions reference the canonical task setup flow.
Onboarding mount documentation
components/Onboarding/RosterSocialsFlow.tsx
Documentation now describes the current roster socials container and sibling onboarding-sequence router mounting behavior.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

Possibly related PRs

  • recoupable/chat#1870 — Directly relates to roster onboarding wiring involving RosterSocialsFlow.
  • recoupable/chat#1888 — Introduced the /setup/* flow and related RosterSocialsFlow behavior referenced by this change.

Poem

Old paths fade,
Setup routes lead the way,
Roster notes find their place,
Tasks begin in a cleaner space.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Solid & Clean Code ✅ Passed Small, single-purpose redirect refactor; components and config stay simple, focused, and DRY with no added architectural complexity.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/converge-onboarding-surfaces

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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cb7472c12c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread app/onboarding/first-task/page.tsx Outdated
*/
const FirstTaskOnboardingPage = () => <FirstTaskStep />;
const FirstTaskOnboardingPage = () => {
redirect("/");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve the first-task scheduling flow

For users coming from the catalog report CTA, CatalogReportCta still links to /onboarding/first-task, but this redirect sends them to /, where the task step is only the generic OnboardingStepCard linking to /tasks rather than FirstTaskStep with the pre-run report and Monday scheduling confirmation. In the funnel case where the derived onboarding step is task, this removes the promised one-click weekly-report setup path and drops users into the generic app instead of running/scheduling the first report.

Useful? React with 👍 / 👎.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No issues found across 1 file

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Auto-approved: Replaces a standalone onboarding step with a redirect to the shared home gate, converging funnel entry onto existing logic. The change is bounded, clearly beneficial, and the redirect preserves backward compatibility and is trivially verifiable.

Re-trigger cubic

sweetmantech and others added 2 commits July 26, 2026 23:18
chat#1887 previously redirected /onboarding/first-task to `/`. That route's
only internal referrer is the catalog report's primary CTA, which is where
both the marketing valuation funnel and the valuation email land — so the
redirect sent converting users to the home surface instead of the step,
where they hit the placeholder onboarding cards.

Repoint at the canonical `/setup/*` sequence instead (chat#1889):
- /onboarding/first-task -> /setup/tasks
- /onboarding/roster     -> /setup/artists
- CatalogReportCta href  -> /setup/tasks

The `/onboarding/*` mounts stay as redirects rather than being deleted so any
pasted or indexed link still resolves; deletion is a follow-up once logs show
no traffic.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@sweetmantech sweetmantech changed the title feat(onboarding): converge funnel entry onto the unified OnboardingSequence fix(onboarding): repoint funnel entry at /setup/tasks, not home (chat#1889 item 1, part 1) Jul 27, 2026
@sweetmantech

Copy link
Copy Markdown
Collaborator Author

Re-scoped 2026-07-26

The prior diff redirected /onboarding/first-task/. That is the wrong target under the 2026-07-23 decision that /setup/* is the canonical onboarding sequence, and it was an active regression risk: this route's only internal referrer is components/Catalog/report/CatalogReportCta.tsx L23 — the primary CTA on the catalog report, which is the landing page for both the marketing valuation funnel and the valuation email. Merging as-is would have sent converting users to the home surface, which still renders the placeholder onboarding step cards.

What changed

File Before After
app/onboarding/first-task/page.tsx redirect("/") redirect("/setup/tasks")
app/onboarding/roster/page.tsx rendered a 2nd RosterSocialsFlow redirect("/setup/artists")
components/Catalog/report/CatalogReportCta.tsx href="/onboarding/first-task" href="/setup/tasks"

The /onboarding/* mounts stay as redirects rather than deletions — no already-sent email deep-links there (welcome used /setup, valuation used /catalogs/{id}), but redirects are cheap insurance against pasted or indexed links. Deletion is a follow-up once logs show no traffic.

Verification

TDD, red → green on a new regression guard:

# RED (href still /onboarding/first-task)
AssertionError: expected '/onboarding/first-task' to be '/setup/tasks'
  components/Catalog/report/__tests__/CatalogReportCta.test.tsx:28:38
  Test Files  1 failed (1)

# GREEN (href /setup/tasks)
✓ components/Catalog/report/__tests__/CatalogReportCta.test.tsx (1 test) 176ms
  Test Files  1 passed (1)

pnpm exec tsc --noEmit reports no errors in the touched files. Preview click-through pending.

Tracked in chat#1889 (matrix row 1).

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

0 issues found across 4 files (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Auto-approved: Consolidates two onboarding surfaces into one by replacing standalone mounts with redirects to canonical setup routes, and updates the CTA link. Bounded refactor with no new behavior; backward-compatible via redirects.

Re-trigger cubic

@sweetmantech

Copy link
Copy Markdown
Collaborator Author

Preview verification — 2026-07-27

Preview: https://chat-hhy9sxnkd-recoup.vercel.app
Built from: 3d26e22d4233b0deb9b0fb2ecf8bcafa8c9f2294 (PR head — confirmed via sha-filtered deployment 5617142700, status success)
Account: brand-new signup, zero artists / zero catalogs / no valuation — i.e. the cold-start cohort described in chat#1889, tested in a fresh isolated browser context so first-run state is real.

Results

# Path Documented Actual Result
1 /onboarding/first-task (logged out) /setup/tasks landed /setup/tasks, rendered "Your first weekly report" + Privy login modal
2 /onboarding/roster (logged out) /setup/artists landed /setup/artists, rendered "Confirm your roster" + Privy login modal
3 /onboarding/first-task (authed) /setup/tasks landed /setup/tasks, rendered "Select an artist to generate your first report."
4 /onboarding/roster (authed) /setup/artists landed /setup/artists, rendered "No artists on your roster yet."
5 Redirect payload, both routes 307 to the setup route NEXT_REDIRECT;replace;/setup/tasks;307; and NEXT_REDIRECT;replace;/setup/artists;307;
6 CatalogReportCta href → /setup/tasks CTA routes to /setup/tasks not exercisable on this account — see below ⚠️ not verified live

The blocker note on chat#1889 is satisfied for rows 1–5: neither retired route lands on home, and neither renders the placeholder step cards. Both resolve to the canonical /setup/* pages.

/onboarding/first-task lands on /setup/tasks

/onboarding/roster lands on /setup/artists

Row 6 — why the CTA could not be verified live

CatalogReportCta only renders on a catalog report that has a valuation. On a cold-start account there is no path to one:

  • /catalogs"No catalogs found."
  • /catalogs/{unknown-id}"No valuation found for this catalog" (the page is account-scoped, so another account's catalog can't stand in)
  • /setup/catalog → redirects to /catalogs, which is empty

I also scanned all 36 chunks loaded on the catalog report route for /setup/tasks, /onboarding/first-task, and the CTA copy — none are present, so the component ships in a chunk that only loads once a valuation renders. That is not evidence either way; it just means the bundle can't stand in for the live check.

The href change is covered by the new unit test in this PR (components/Catalog/report/__tests__/CatalogReportCta.test.tsx). To close row 6 live, someone needs an account that arrived through the valuation funnel — I did not run the marketing funnel because it creates an Attio lead and sends real email.

Finding — the redirects are client-side, not HTTP

Both retired routes return HTTP 200, not 307:

$ curl -sI https://chat-hhy9sxnkd-recoup.vercel.app/onboarding/first-task
HTTP/2 200
x-matched-path: /onboarding/first-task
x-nextjs-prerender: 1

Next prerendered both pages, so the redirect() ships inside the RSC flight payload and executes on hydration rather than as a server redirect. It works correctly in a real browser (rows 1–4 above), so this does not block the merge. But it means a non-JS client — curl, a crawler, a link previewer — sees the old URL return 200 with an empty shell. Given the PR's stated intent is that "any pasted/indexed link still resolves," worth a follow-up: export const dynamic = "force-dynamic" on both pages, or a redirects() entry in next.config, would make it a real 307.

Pre-existing issues observed (not caused by this PR, already tracked)

  • /setup/artists shows "Step 1 of 2" — the disagreeing progress counter that #1891 fixes.
  • Copy reads "We set these artists up from your valuation" on an account with no valuation, and "This is my artist — continue" is disabled with an empty roster — the cold-start dead end #1892 addresses.

…te the page stubs

The interim /onboarding/first-task and /onboarding/roster mounts were
scaffolding from chat#1880 so each step was user-testable before the
sequence container existed. Replace the redirect() page components with
308s in next.config.mjs and delete the files.

Two reasons over redirect() pages:

- Next prerenders a page whose body is just redirect(), so the old URL
  answers HTTP 200 with the redirect in its RSC payload and only moves
  once React hydrates. A crawler, link previewer or curl sees a 200 and
  an empty shell. Config redirects are real 308s at the edge, checked
  before the filesystem.
- No page files left behind carrying a 'delete once logs show no
  traffic' marker. chat#1889 exists because interim surfaces accumulated
  and were never retired; this does not add two more.

After this PR nothing internal references /onboarding/* — the only
referrer was CatalogReportCta, repointed here at /setup/tasks.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@sweetmantech

Copy link
Copy Markdown
Collaborator Author

Reworked: config redirects instead of redirect() page stubs — re-verified 2026-07-27

Replaces the two redirect() page components with 308s in next.config.mjs and deletes app/onboarding/first-task/page.tsx and app/onboarding/roster/page.tsx. The CatalogReportCta href fix and its test are unchanged.

Why

1. The page stubs weren't actually redirecting for non-JS clients. My verification of the previous revision found both routes answering HTTP 200, not 307 — Next prerendered them, so the redirect shipped inside the RSC flight payload and only fired on hydration. A crawler, link previewer, or curl got a 200 and a 43KB empty shell. That defeats the stated purpose of keeping the old URL alive for "any pasted/indexed link."

2. The stated rationale no longer held. After grepping chat, api, marketing and docs: the only internal referrer to either route was CatalogReportCta, which this PR repoints. No email links to /onboarding/* — the welcome and valuation emails link to /setup/*, /catalogs/{id} and /chat/{id}, so the funnel reaches the CTA, never the route. Both routes are 6 days old (#1880, 2026-07-21) and were explicitly interim scaffolding, per their own original comment: "so the step is user-testable before the OnboardingSequence container exists."

3. "Delete once logs show no traffic" is the pattern #1889 exists to end. That issue's route audit found 4 entry paths on 3 parallel implementations precisely because interim surfaces accumulated and were never retired. Leaving two more files marked delete-later repeats it. Config redirects keep the link safety with nothing left in app/ to forget.

Redirects are checked before the filesystem (docs), so deleting the pages is safe. permanent: true → 308, which preserves method and tells crawlers to drop the old URL.

Verification — preview https://chat-9o5pms78a-recoup.vercel.app

Built from df302111 (confirmed via sha-filtered deployment 5626220974, status success).

# Check Before (page stubs) After (config redirects) Result
1 GET /onboarding/first-task HTTP 200, x-nextjs-prerender: 1 HTTP 308, location: /setup/tasks ✅ fixed
2 GET /onboarding/roster HTTP 200, x-nextjs-prerender: 1 HTTP 308, location: /setup/artists ✅ fixed
3 Query passthrough dropped (destination was hardcoded) ?utm_source=email&x=1location: /setup/tasks?utm_source=email&x=1 ✅ improved
4 Redirect chain n/a 1 hop, final 200 at /setup/tasks and /setup/artists
5 Browser navigation landed correctly landed /setup/tasks?utm_source=valuation_email and /setup/artists
6 Response body 43,295-byte HTML shell Redirecting...
7 Destinations render directly 200 200

Row 3 is a real gain, not just cleanup: the old redirect("/setup/tasks") discarded query strings, so any utm_* on a funnel or email link was lost at the hop. Config redirects pass them through.

Local gates

  • Full suite: 68 files / 257 tests pass, including 3 new TDD units in __tests__/nextConfigRedirects.test.ts (confirmed RED — expected 'undefined' to be 'function' — before the config existed).
  • tsc --noEmit: 8 errors, all pre-existing in SpotifyDeepResearchResult.tsx and extractSendEmailResults.test.ts, none in changed files.
  • pnpm build can't run locally (no .env, only .env.example), so the Vercel preview build is the gate — it's green.

Note on the earlier approval

This PR is carrying an approval that predates both the re-scope and this rework. Worth another look before merge.

@sweetmantech sweetmantech changed the title fix(onboarding): repoint funnel entry at /setup/tasks, not home (chat#1889 item 1, part 1) refactor(onboarding): retire /onboarding/* into /setup/* via config redirects (chat#1889 item 1, part 1) Jul 27, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

0 issues found across 7 files (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Auto-approved: Removes standalone onboarding pages and replaces with 308 redirects to canonical /setup/* routes; updates link in CatalogReportCta. Bounded cleanup that preserves behavior and simplifies codebase.

Re-trigger cubic

@sweetmantech

Copy link
Copy Markdown
Collaborator Author

Full verification on the current build — 2026-07-27

Supersedes the screenshots in my first comment, which were captured on chat-hhy9sxnkd (the redirect()-page revision) and no longer reflect this code.

Preview: https://chat-9o5pms78a-recoup.vercel.app
Built from: df302111 — confirmed via sha-filtered deployment 5626220974, state success
Account: brand-new signup (+july2720260944), zero artists / zero catalogs / no valuation — the cold-start cohort from #1889. Fresh isolated browser context, signed in on this origin.

Protocol level

# Check Expected Actual Result
1 GET /onboarding/first-task 308 → /setup/tasks HTTP/2 308, location: /setup/tasks
2 GET /onboarding/roster 308 → /setup/artists HTTP/2 308, location: /setup/artists
3 Query passthrough params preserved ?utm_source=email&x=1location: /setup/tasks?utm_source=email&x=1
4 Redirect chain 1 hop, no loop hops:1/setup/tasks and /setup/artists, both 200
5 Response body not a page shell Redirecting... (was 43,295 bytes)
6 Destinations direct 200 /setup/tasks 200, /setup/artists 200

Negative probes — the directory is genuinely gone

# Path Expected Actual Result
7 /onboarding 404 — no stray catch-all HTTP 404, 0 redirects
8 /onboarding/unknown-step 404 — rules are exact-match HTTP 404, 0 redirects
9 /onboarding/first-task/extra 404 — no over-broad prefix match HTTP 404, 0 redirects

Rows 7–9 confirm the two rules match exactly what they should and nothing more, and that no app/onboarding/** route remains to shadow them.

Browser — logged out

# Entered location.href after load Rendered Result
10 /onboarding/first-task?utm_source=valuation_email /setup/tasks?utm_source=valuation_email h1 "Your first weekly report"
11 /onboarding/roster /setup/artists h1 "Confirm your roster"

logged out — first-task lands on /setup/tasks with utm preserved

logged out — roster lands on /setup/artists

Browser — authenticated

Signed in on this deployment via Privy email OTP, then re-ran both entries.

# Entered location.href after load Rendered Result
12 /onboarding/first-task?utm_source=valuation_email /setup/tasks?utm_source=valuation_email "Select an artist to generate your first report."
13 /onboarding/roster /setup/artists "No artists on your roster yet. Add your first artist below."

authenticated — first-task lands on /setup/tasks, utm preserved

authenticated — roster lands on /setup/artists

Neither entry reaches / in either auth state, which is what the #1889 blocker note required.

Still not verified

CatalogReportCta rendered click. The CTA only renders on a catalog report that has a valuation, and a cold-start account has no route to one: /catalogs is empty, /catalogs/{id} is account-scoped ("No valuation found for this catalog"), and /setup/catalog redirects back to the empty list. Covered by components/Catalog/report/__tests__/CatalogReportCta.test.tsx, but not exercised live. Closing it needs an account that came through the valuation funnel — I did not run the funnel because it creates an Attio lead and sends real email.

Local gates

  • Full suite 68 files / 257 tests pass, including 3 new units in __tests__/nextConfigRedirects.test.ts — confirmed RED (expected 'undefined' to be 'function') before the config existed.
  • tsc --noEmit: 8 errors, all pre-existing in SpotifyDeepResearchResult.tsx and extractSendEmailResults.test.ts; none in changed files.
  • pnpm build cannot run locally (no .env, only .env.example), so the Vercel preview build is the gate — green.

Pre-existing, not caused by this PR

Visible in rows 11 and 13: /setup/artists reads "Step 1 of 2" (the disagreeing progress model, #1891) and says "We set these artists up from your valuation" to an account with no valuation, with continue disabled on an empty roster (#1892).

@sweetmantech

Copy link
Copy Markdown
Collaborator Author

Onboarded-account regression pass — 2026-07-27

Follow-up to the cold-start verification above. Question being answered: does a fully onboarded account get pulled into /setup by this PR? Short answer: no, and it structurally cannot.

Preview: https://chat-9o5pms78a-recoup.vercel.app (df302111)
Account: existing, fully onboarded — multi-artist roster (Ana Bárbara, Charlie Zaa, Apache, Adri Torron, Collie… ), socials matched per artist, scheduled tasks running and completing.

Why it can't happen

This PR's whole diff is 8 files: next.config.mjs, the two deleted stubs, CatalogReportCta + its test, the new config test, and two doc comments. It touches neither app/page.tsx nor useOnboardingState/deriveOnboardingState — there is no code path by which #1887 routes anyone from home into /setup.

Results

# Entered location.href after load Rendered Result
1 / / — no redirect "Ask me about Ana Bárbara", YOUR LABEL AT WORK with 5 completed scheduled runs ✅ home is untouched
2 / (hard reload) / — no redirect same ✅ not a client-nav artifact
3 /onboarding/first-task /setup/tasks "This week's catalog report for Ana Bárbara" ✅ redirect fires, lands on a real populated step
4 /onboarding/roster /setup/artists full roster, each with "N social profiles matched"
5 /setup /setup/artists — "Step 1 of 2" pre-existing wart, see below ⚠️ not caused by this PR

onboarded account on home — no /setup redirect

onboarded account, /onboarding/first-task lands on a populated /setup/tasks

Row 3–4: the redirect is auth-blind, and that's the correct tradeoff

A next.config redirect cannot read session state, so /onboarding/*/setup/* fires for onboarded and cold-start accounts alike. That is fine here because /onboarding/* is a retired URL nobody navigates to organically — and the destination degrades well: row 3 shows an onboarded account landing on a /setup/tasks populated with their real artist, not an empty or broken step.

If we ever want onboarded users routed differently, that belongs in PR B's home convergence (#1890), which is auth-aware via useOnboardingState. It does not belong in a config redirect.

Row 5: pre-existing, and worse than it looks with a real roster

/setup sends a fully onboarded account with a multi-artist roster back to "Step 1 of 2 — Confirm your roster." Confirmed not caused by this PR — app/setup/page.tsx is byte-identical to origin/main:

export default function SetupPage() {
  redirect("/setup/artists");   // unchanged on main
}

onboarded account at /setup dumped back to step 1 with a full roster

This is exactly the item #1890 carries — "make /setup open at the derived step instead of hard-redirecting to /setup/artists — today a user who already confirmed their roster is sent back to step 1." Worth noting the real-roster case makes it sharper than the cold-start case did: the welcome email's "Confirm your roster" CTA points at /setup, so any returning onboarded user who clicks it gets told to redo step 1. Reinforces PR B as the keystone.

Correction to the screenshots in my previous comment

The two images showing a Privy login popup are the logged-out captures (01, 02) — deliberate, and labeled as such under "Browser — logged out". The authenticated pair (03, 04) has no modal and shows "Select an artist to generate your first report." / "No artists on your roster yet.", the latter rendering only once the roster query resolves for a signed-in account. The numbering made that easy to miss; the images in this comment are prefixed A/B/C and are all authenticated.

@sweetmantech
sweetmantech merged commit 7168ac6 into main Jul 27, 2026
4 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