Skip to content

feat: add customer source survey#1051

Open
evanjacobson wants to merge 15 commits intomainfrom
feature/customer-source-survey
Open

feat: add customer source survey#1051
evanjacobson wants to merge 15 commits intomainfrom
feature/customer-source-survey

Conversation

@evanjacobson
Copy link
Contributor

@evanjacobson evanjacobson commented Mar 12, 2026

Summary

Adds a one-time "Where did you hear about Kilo Code?" survey to the sign-in flow. Users see it once, right before they land on their destination.

This applies to every user that hasn't skipped or answered the survey before.

How it works

A new customer_source column on kilocode_users tracks whether the user has answered:

  • NULL → show the survey
  • Any value (including empty string for Skip) → don't show it

The survey page (/customer-source-survey) is a simple textarea with Submit and Skip. It slots into the existing sign-in redirect chain.

A maybeInterceptWithSurvey(user, destinationPath) helper centralizes the intercept logic. It's called from two places in the existing auth flow:

  • account-verification catches new users after Stytch verification
  • after-sign-in catches returning users who haven't answered yet

User flows

New user:         sign-in → verification → survey → /get-started
Returning user:   sign-in → survey → /profile (or callbackPath)
Already answered: sign-in → /profile (survey skipped)

Verification

  • Unit tests for the helper, account-verification redirects, and tRPC mutations (20 passing)
  • E2E tests for submit, skip, and already-answered bypass flows
  • pnpm run format and pnpm lint clean

Visual Changes

image

Reviewer Notes

  • Skip writes '' (empty string) with a WHERE customer_source IS NULL guard to prevent a race where Skip could overwrite a real answer.
  • The helper has a startsWith('/customer-source-survey') guard to prevent double-wrapping redirects.
  • Extension users (VS Code source param) also see the survey once before /sign-in-to-editor.

Route new users through a one-time survey page after account verification
and before /get-started. Existing users without a response are intercepted
on their next sign-in. Users can submit a free-text answer or skip.

- Add nullable `customer_source` column to kilocode_users
- Add `submitCustomerSource` tRPC mutation
- Create /customer-source-survey page with skip/submit form
- Update account-verification to redirect through survey
- Intercept existing users in after-sign-in route
- Add Jest tests for submitCustomerSource tRPC mutation (validation,
  persistence, overwrite, boundary lengths)
- Add Playwright e2e tests for survey page (render, submit, skip,
  callbackPath, already-answered redirect)
- Update auth.setup.ts to handle survey page in login flow
- Add survey page to visual regression screenshot list
- Add customer_source field to test user helper
- H1: reject whitespace-only input via .trim().min(1) on submitCustomerSource
- H2: persist skip as empty string sentinel via skipCustomerSource mutation
- H3: skip survey redirect when customer_source is already set
- Skip button uses mutation instead of direct navigation
- Add account-verification redirect unit tests (13 tests)
- Expand user-router tests for whitespace and skip semantics
- Rewrite E2E tests with fresh user isolation per test
Fixes typecheck errors in route.test.ts and token.test.ts caused by
the new required customer_source field on the user type.
… survey

Consolidate duplicated survey-intercept logic from account-verification
and after-sign-in into a single pure helper function. This collapses
12 lines of branching in account-verification to 2 lines and provides
a single point of change if survey conditions evolve.
@evanjacobson evanjacobson marked this pull request as ready for review March 12, 2026 13:56
@evanjacobson evanjacobson enabled auto-merge March 12, 2026 13:58
linkedin_url: text(),
github_url: text(),
openrouter_upstream_safety_identifier: text(),
customer_source: text(),
Copy link
Contributor

Choose a reason for hiding this comment

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

WARNING: Update the GDPR soft-delete flow for this new field

customer_source stores user-provided survey text on kilocode_users, but softDeleteUser does not clear it today. Merging the schema change without updating src/lib/user.ts and its soft-delete coverage leaves this new account-linked value behind after deletion.

@kilo-code-bot
Copy link
Contributor

kilo-code-bot bot commented Mar 12, 2026

Code Review Summary

Status: 5 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 5
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
packages/db/src/migrations/0049_customer_source_survey.sql 1 Migration takes an exclusive lock on kilocode_users
packages/db/src/schema.ts 195 GDPR soft-delete flow is not updated for customer_source
src/app/customer-source-survey/page.tsx 8 Signed-out visits to the survey page drop the forwarded callbackPath
src/components/CustomerSourceSurvey.tsx 43 Client-side length limit disagrees with the mutation contract
Other Observations (not in diff)

Issues found in unchanged code that cannot receive inline comments:

File Line Issue
tests/e2e/pages.visual.spec.ts N/A Visual test redirects past the survey page and captures /get-started instead

Fix these issues in Kilo Cloud

Files Reviewed (16 files)
  • packages/db/src/migrations/0049_customer_source_survey.sql - 1 issue
  • packages/db/src/schema.ts - 1 issue
  • src/app/account-verification/page.tsx - 0 issues
  • src/app/api/cloud-agent/sessions/prepare/route.test.ts - 0 issues
  • src/app/customer-source-survey/page.tsx - 1 issue
  • src/app/users/after-sign-in/route.tsx - 0 issues
  • src/components/CustomerSourceSurvey.tsx - 1 issue
  • src/lib/survey-redirect.ts - 0 issues
  • src/lib/token.test.ts - 0 issues
  • src/routers/user-router.test.ts - 0 issues
  • src/routers/user-router.ts - 0 issues
  • src/tests/account-verification-redirect.test.ts - 0 issues
  • src/tests/helpers/user.helper.ts - 0 issues
  • src/tests/survey-redirect.test.ts - 0 issues
  • tests/e2e/auth.setup.ts - 0 issues
  • tests/e2e/customer-source-survey.spec.ts - 0 issues

Reviewed by gpt-5.4-20260305 · 972,398 tokens

@evanjacobson evanjacobson requested a review from darkogj March 12, 2026 15:28
@evanjacobson evanjacobson marked this pull request as draft March 12, 2026 15:29
auto-merge was automatically disabled March 12, 2026 15:29

Pull request was converted to draft

@evanjacobson
Copy link
Contributor Author

Adding auto-focus and gdpr soft delete. Also evaluating if there's a better way to structure the data so it can be categorized with future surveys in mind also.

@evanjacobson evanjacobson marked this pull request as ready for review March 12, 2026 23:08
The auth setup skips the survey, so this entry just duplicates the
get-started screenshot. The survey UI is covered by its own spec.
@evanjacobson evanjacobson force-pushed the feature/customer-source-survey branch from 880ffb2 to 795324a Compare March 13, 2026 19:37
The server's Zod schema trims before enforcing max(1000), but the
Textarea's maxLength={1000} caps raw input. Trimming client-side
ensures the submitted value matches the server's contract.
@@ -0,0 +1 @@
ALTER TABLE "kilocode_users" ADD COLUMN "customer_source" text; No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

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

WARNING: This migration takes an exclusive lock on kilocode_users

ALTER TABLE ... ADD COLUMN still acquires an ACCESS EXCLUSIVE lock, even without a default. On a populated auth table this can briefly block sign-ins and writes, so this needs a quiet rollout window or a safer expand plan before it lands.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

reviewer — what's the usual process for this?

SurveyType, SurveyStatus, and SurveyPlatform were added but never
used — the implementation uses a simple text column instead.
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