Guided setup without plan; embedded GitHub

Task 8461 · Done · Coder · created · updated

# Guided setup: no plan step, embedded GitHub connect (architecture child C4) This is part of the epic "Multi-Step Signup Flow With Stripe Billing". The full settled inputs are the PRD (Task 8416) and the Architecture (Task 8417); the relevant parts are embedded below. This task is architecture child **C4**. C0, which added `org_signups.plan_confirmed_at`, has merged. C1 sets that column at Sign up and runs in parallel with this task. ## Original requirement (verbatim) > When user logs in the onboarding wizard does not have a plan selection and goes straight to other things according to the plan selected. > > Embed GitHub connection to the Guided setup. PRD decision **D8 Plan step**: "Remove for all new signups". Guided setup never shows Choose plan for orgs created through the new signup. Existing orgs keep today's behaviour. ## PRD requirement R10 (verbatim) - **AC10.1** For an org created by the new signup, `/welcome` has no Choose-plan step, and its next steps follow the chosen plan (for example, the plan's node step). - **AC10.2** The Git/forge step in guided setup embeds the GitHub connection: a "Connect GitHub" button that runs the existing GitHub App install + user connect inside the wizard and returns to the same step marked done. It does not link away to `/profile?tab=git-accounts`. - **AC10.3** Existing orgs keep the current wizard behaviour. ## Approach (Architecture §5 C4, verbatim) - `apps/api/app/routes/org_setup.py:404-421`: omit `choose_plan` when `signup.plan_confirmed_at IS NOT NULL`. In `apps/web/src/lib/welcomeWizard.ts:131-138`, drop the plan step, and stop the node step waiting on the plan for those orgs. - `apps/api/app/routes/git_connect.py`: - `POST /start` accepts `return_to`, checks it against the allow-list `{"/welcome", "/profile"}`, and stores it in the flow cookie (`:232`). - `_profile_redirect` (`:165-174`) becomes `_return_redirect(return_to)`. - The GitHub App install hop (`:329,492-500`) and the Setup URL handler (`:503-524`) read `return_to` from a short-lived, path-scoped cookie set at `/start`. It has a 10-minute max age and the same allow-list. The cookie is used instead of GitHub echoing `state`. - The default stays `/profile`, which keeps today's behaviour. - `apps/web/src/components/onboarding/WelcomeWizard.tsx:180-187` passes `return_to:"/welcome"`. When the wizard comes back with `?git_connect=connected`, it refreshes the forge step. - **Risk: open redirect.** Use only the two-path allow-list. Never follow a free-form `return_to`. The embedded connect follows `docs/standards/ui-style-guide.md` and `docs/standards/ui-copy-standards.md`: - The button is labelled "Connect GitHub". - The step shows a done state with the connected account. - A failed or cancelled connect returns to `/welcome` with an inline, legible error, not a blank step. Credentials & reach: | Oracle(s) | Credential / environment | Status | |---|---|---| | Embedded Connect GitHub (AC10.2) in a real browser | a GitHub account able to sign in interactively | deferred: the operator said to proceed without an answer; covered by server tests that mock the OAuth hop | | Dev UI oracles AC10.x (log in as a newly approved user) | the signing-up user's own inbox | deferred: the dev walk-through is the operator's manual acceptance | | Server tests, `./dc check full` | nothing beyond the worktree | verified | Out of scope: - Do NOT touch signup routes or pages (C1/C3), or approval and billing (C2). - Do NOT add a migration. - Do NOT change the existing orgs' guided setup (AC10.3). - Do NOT touch the separate card-style onboarding guide (`apps/web/src/lib/onboarding.ts`) beyond what AC10.2 needs. Reusing `return_to` there is a deferred follow-up. - Do NOT accept a free-form redirect target. Done means: - **AC10.1:** an org with `plan_confirmed_at` set has no `choose_plan` step, and the wizard starts at a non-plan step. - `tests/test_org_setup*` gains a case: no `choose_plan` when it is set, still present when it is NULL. - The `welcomeWizard.ts` unit tests gain a case. - The dev check is deferred (inbox). - **AC10.2:** Connect GitHub in `/welcome` runs the install and connect, and returns to `/welcome` with the forge step checked. The URL never shows `/profile`. - `tests/test_git_connect*`: `return_to=/welcome` redirects back to `/welcome` through both the OAuth hop and the App-install Setup URL hop. An unlisted `return_to` falls back to `/profile`. - A `WelcomeWizard` unit test: `?git_connect=connected` marks the forge step done. - The real-browser GitHub check is deferred. - **AC10.3:** an existing self-service org with no plan chosen still sees Choose plan, and `/profile` connect still returns to `/profile`. - The test cases above. - **Gate:** `./dc check quick` locally and `./dc check full` in the merge lane are green.

Outcome

Confirmed-plan sign-ups skip Choose plan; Connect GitHub in /welcome returns there via allow-listed return_to (default /profile). Quick gate + changed-area tests green; review lanes pass; visual check done. PR #6461 queued. Follow-up draft #8473. Memory: used mem-22518.

Pull request

Artifacts

Activity

  • Draft
  • Ready
  • Runner started
  • Runner ended (done)