# Build an Onboarding Flow in a Next.js App with Your Team

Yes. Your product team can watch an agent build a three-step signup flow in Next.js and correct the copy before the pull request.

[Run this on Rush](https://cloud.getrush.ai/run/build-onboarding-flow/nextjs/), in a Project that has your repository.

## What the agent does

The agent reads the signup path that already lands a new user on an empty dashboard. In nextjs/saas-starter, package.json pins next to 15.6.0-canary.59, react 19.1.0, drizzle-orm ^0.43.1, stripe ^18.1.0 and typescript ^5.8.3. Scripts are dev, build, start and the db:* scripts. There is no lint script and no test script, and there is no .github workflow. pnpm-lock.yaml is the lockfile. lib/db/drizzle.ts throws if POSTGRES_URL is unset. lib/db/schema.ts defines users (email, passwordHash, an optional name varchar of 100, role), teams (name, Stripe customer and subscription ids), teamMembers, activityLogs and invitations. ActivityType includes SIGN_UP, CREATE_TEAM, INVITE_TEAM_MEMBER and ACCEPT_INVITATION.

signUp in app/(login)/actions.ts validates email, a password of at least 8 characters, and an optional inviteId with Zod. With no invitation it inserts a team named from the email, a team member with role owner, writes the activity rows, sets the session and redirect('/dashboard'). With redirect=checkout it goes to Stripe instead. The dashboard page already renders a team member list and calls inviteTeamMember, whose schema lives further down in the same actions file. There is no projects table. A three-step flow of profile, first project and invite has to use these tables: profile fills users.name, which signup never asks for; the project step renames the team signUp just created, rather than inserting a second team; the invite step calls the existing inviteTeamMember path so invitations stay the source of a pending invite.

Each step is skippable, and skipping still ends on /dashboard. The agent adds the routes under the login group, redirects signUp there instead of straight to the dashboard, and leaves the checkout redirect alone so a priced signup does not detour through onboarding. Copy for the three steps is plain and short, because the product team is about to rewrite it. The sandbox browser, against next dev --turbopack, captures profile, the team name step and the invite step, and those shots are posted on the run before any pull request is opened.

The team edits in follow-ups: a different heading, a step removed, an invite field that should say email and role the way the dashboard radio group already does. The agent applies that to the same pages and recaptures them. It does not add a test framework the repository does not have. It runs pnpm build so the server actions still typecheck, with POSTGRES_URL set to a database it started in the sandbox, because drizzle.ts will not load without it. The pull request says what was skippable and that checkout still bypasses the flow.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "codex",
  "input": "Add a three-step onboarding flow after sign-up: profile, first project and invite a teammate, each skippable. Read app/(login)/actions.ts first. signUp already creates a team named from the email and redirects to /dashboard, or to Stripe when redirect is checkout. Profile should set users.name. The project step should rename that team, not insert another one. Invite should use inviteTeamMember and the invitations table. Do not change the checkout redirect. Screenshot each step in the browser and post them, then apply the follow-ups you get before opening the pull request. Run pnpm build with POSTGRES_URL set. Do not add a test runner.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

What comes back is a pull request that adds the three step routes, points signUp at the first step, and leaves createCheckoutSession on the checkout redirect. The description includes the three screenshots, the field each step writes (users.name, teams.name, invitations) and the sentence that each step can be skipped. Build output from pnpm build is in the transcript. Screenshot files on the session are artifacts with a one-hour download URL.

A reviewer signs up once in their head against the diff: a brand-new email creates one team, not two; a pending invitation still joins that team and does not show onboarding as an owner; checkout never renders the steps. They read the copy the follow-ups settled, not the first draft. They confirm no test script was added to package.json.

The copy edits happen on the open run, before the pull request. After a turn, the sandbox parks and POST /o/{org}/sessions/{id}/messages wakes it. During the turn that POST is 409 TURN_ACTIVE, and the console queues the message. The org can read the stream. The starter or an org admin is who sends the new heading.

## Run it on every product brief

When a brief describes a signup change, start this session with the repository in resources. One run holds the Next dev server and the browser. Teammates watch the three screenshots and send the replacement copy as follow-ups. A browser lease lasts five minutes and is exclusive.

The API key's webhook fires on run.completed, run.failed or run.cancelled at the end of each turn, so the channel sees the screenshot turn and the later copy turn separately. result is included up to 16 KiB. Parked sandboxes remain for 7 idle days. Starting past max_concurrent, 4 by default, returns 429.

## Why run it on Rush?

Onboarding copy is rewritten more often than it is designed, and the current code sends every new user to /dashboard with a team name they did not choose. A laptop branch hides that from the person who owns the words until a preview deploy exists. The sandbox renders the three steps, posts the pictures, and waits, so the correction is a follow-up rather than a meeting.

The pull request records the settled copy and the schema it uses. The transcript records the build and each follow-up. The checkout path is untouched unless a follow-up asks for it. Other briefs run in other sandboxes and open other pull requests.

## Frequently asked questions

### Signup already creates a team. Does onboarding create a second one?

No. signUp inserts the team and the owner membership before the redirect. The project step updates teams.name on that row. A second insert would show two teams for one new account, and the prompt forbids it. An invited user, who takes the inviteId branch and never creates a team, should skip the project step.

### What happens to someone who chose a pricing plan?

signUp returns createCheckoutSession when the form's redirect field is checkout. That branch stays. Onboarding runs only for the redirect to the dashboard. A follow-up can ask for the steps after checkout, but the first pull request does not put them in front of Stripe.

### The app has no tests. What is the check?

pnpm build, with POSTGRES_URL set so lib/db/drizzle.ts can load, plus the screenshots of the three steps. There is no lint or test script in package.json, and the prompt says not to add a runner. Type errors in the server actions fail the build, and that output is in the transcript.

### Can marketing change the headings without a new run?

Yes, while the sandbox is parked, for 7 idle days. They send a follow-up with the new sentences. The agent edits the steps, recaptures them and then opens the pull request. After the run is finished for good, a new session is a new POST.
