Repository navigation
Onboarding: capture user intent with a short survey #2
Description
Summary
Right after signup, ask a short intent survey so we know who the user is and what they came to do. Today we only know GitHub identity + Discord “new user” ping. That is not enough to prioritize the roadmap, write use-case landing pages, or tailor onboarding.
This is not a blocker for installing the GitHub App. It is a 20-second, skippable step that captures signal we currently throw away.
Current onboarding (as implemented)
There is no product onboarding flow. Activation is implicit:
- GitHub OAuth (
auth.ts).events.createUsersends a welcome email (lib/email/send-welcome-email.ts) and a Discord notify (lib/notify-new-user-discord.ts). - Logged-in
/redirects to/dashboard(app/page.tsx). - Dashboard empty states (
components/home/dashboard-view.tsx):- No GitHub App → “Connect your GitHub repositories” /
+ ADD PROJECT→/api/github/install - App installed, no repos → “No repositories yet”
- No GitHub App → “Connect your GitHub repositories” /
- Per-repo configure (
app/dashboard/[owner]/[repo]/configure/page.tsx): authorized domains → embed snippet → PR email toggle → custom agent instructions.
User in prisma/schema.prisma has identity + billing + githubAppInstalled only. No persona, use-case, or onboarding-complete flag.
The welcome email already assumes “your first project is connected” and jumps to “paste the snippet” — which is often false (they have not installed the App yet). Survey + sequenced onboarding would also let us fix that copy later.
Problem
- We cannot tell agencies vs freelancers vs people putting this on their own SaaS.
- We cannot measure “signed up but never installed the App” vs “installed but never embedded”.
- Use-case landing pages (separate issue) need real intent data, not guesses.
- Custom agent instructions and domain setup are the hard parts; a one-line “what are you using this for?” lets us later show the right example snippet / copy.
Proposed design
When
Show once, after first successful GitHub login, before or as a sheet on the dashboard — not before OAuth (we need a user row). Do not delay GitHub App install; the survey should sit beside the existing “+ ADD PROJECT” empty state, or as a dismissible modal on first dashboard view.
Skip if User.onboardingCompletedAt is set (including skip).
Questions (keep to 3, all optional except we strongly want Q1)
1. I am… (single choice, required-to-continue or skip)
- Freelance developer
- Agency / studio
- In-house (my company’s product)
- Other
2. I want to collect feedback on… (single choice)
- Client websites I maintain
- My own marketing / docs / app
- Internal tools
- Not sure yet
3. How did you hear about us? (optional, short text or a small set: Twitter/X, GitHub, friend, search, other)
No NPS, no company-size, no “how many clients”. Resist the urge. Completion rate dies after 3.
Storage
On User:
role String? // freelance | agency | in_house | other
intent String? // client_sites | own_product | internal | unsure
referralSource String?
onboardingCompletedAt DateTime?Do not invent a separate survey table for v1.
Also send a Discord line (same channel as notifyNewUserDiscord) when they submit, so you see personas in real time without a dashboard. Do not put PII beyond what we already log (email is already there).
Product use of the answers (assumptions)
- Copy / empty states: freelancer → “paste this on the client site”; agency → “one widget per client repo”; in-house → “put it on staging first”.
- Landing pages: if
/for/agenciesexists later, we can confirm which pages convert to which persona. - Roadmap: if 70% are agencies, path allowlists + widget theme jump the queue; if in-house SaaS, element picker + iterate-on-PR matter more.
- Not for pricing discrimination. Same Free/Pro for everyone.
Assumptions
- Survey is first-party (our DB), not Typeform/Tally. One less vendor; answers stay next to
User. - We will not auto-provision different product SKUs from the answers.
- Skipping is a first-class outcome (
onboardingCompletedAtstill set) so we do not nag every dashboard load. - German/EU users: keep this as product analytics on our Postgres, not a US-only SaaS survey tool, until we have a DPA story. Store enums, not free-text life stories. Q3 free text: cap 200 chars, no emails.
Acceptance criteria
- First dashboard visit for a new user shows the survey (or a compact card); existing users are unaffected (
onboardingCompletedAtbackfill asnow()for current users so they are not ambushed). - Skip and Submit both persist
onboardingCompletedAtand never show again. - Answers visible on Account (read-only) or an internal admin query — at least queryable in Prisma.
- Discord (or existing new-user hook) includes role + intent when present.
- Does not block GitHub App install or repo configure.
- Welcome email unchanged in this issue (follow-up: make welcome match persona).
Out of scope
- Multi-step product tour / coach marks on configure.
- In-widget “client vs visitor” survey.
- HubSpot/CRM sync.
Implementation notes
components/home/dashboard-view.tsx+app/dashboard/page.tsx(pass aneedsOnboardingflag).prisma/schema.prismaUserfields + migration.- Small
POST /api/onboardingor a server action; CSRF via session cookie. - Backfill:
UPDATE "User" SET "onboardingCompletedAt" = "createdAt"equivalent so current accounts are grandfathered.
See also
- Use-case landing pages (persona copy should match these enums)
- Quota warning emails (persona can later change tone, not v1)
Activity
ezzcodeezzlife commentedon Aug 18, 2026
Related: use-case landings #4 (same persona enums), quota emails #7