Skip to content

feat(web): skip customer-source survey for SSO and invite joins - #4924

Merged
RSO merged 1 commit into
mainfrom
subdued-promise
Jul 31, 2026
Merged

feat(web): skip customer-source survey for SSO and invite joins#4924
RSO merged 1 commit into
mainfrom
subdued-promise

Conversation

@RSO

@RSO RSO commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

When a user joins an organization through SSO or an invitation, we should not ask them how they heard about Kilo.

The CustomerSourceSurvey floating card renders only when customer_source === null (null = never asked, '' = dismissed, string = answered). Rather than gating in the frontend — which doesn't know how a user joined — this marks the survey as dismissed at the two server-side join points.

Changes

  • apps/web/src/lib/organizations/organizations.ts: added skipCustomerSourceSurveyForOrgJoin(userId, txn?), which sets customer_source = '' only WHERE customer_source IS NULL (never overwrites an existing answer; accepts an optional transaction). Called inside acceptOrganizationInvite's transaction right after the new membership is inserted.
  • apps/web/src/lib/user/sso.ts: calls the helper inside the if (added) block, so it fires only when the SSO user actually joins the org (not on every re-login).

Tests

  • sso.test.ts: helper added to the module mock; asserts it's called when the user joins via SSO and not called for an existing member.
  • organizations.test.ts: asserts accepting an invite sets customer_source to '', and that an existing answer ('GitHub') is preserved.

Notes / assumptions

  • Targets only the actual "join" events (membership inserted / SSO auto-provision). Re-logins and already-a-member accept flows are not re-marked; pre-existing members with a null source are not retroactively marked.
  • The IS NULL guard makes both call sites idempotent and safe against overwriting real answers.

Validation

  • pnpm --filter web run typecheck (exit 0), lint (0 warnings/errors), targeted jest suites pass.

@kilo-code-bot

kilo-code-bot Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

Incremental review of the new isNewUser option on addSsoUserToOrganization (disabling the personal account for SSO-provisioned brand-new accounts) plus its tests found no defects; the flag source (res.isNew from createOrUpdateUser) and the in-transaction update correctly mirror the existing invite behavior.

Files Reviewed (4 files)
  • apps/web/src/lib/organizations/organizations.ts
  • apps/web/src/lib/organizations/organizations.test.ts
  • apps/web/src/lib/user/sso.ts
  • apps/web/src/lib/user/sso.test.ts
Verification notes
  • createOrUpdateUser returns isNew: true only when a new row is inserted (apps/web/src/lib/user/index.ts:746); existing-user and auto-linked WorkOS paths return isNew: false, so pre-existing accounts keep their personal_account_disabled value.
  • The personal_account_disabled update is guarded by added && options?.isNewUser and runs on the same tx as the membership insert, so it commits/rolls back atomically and does not fire on re-logins.
  • addSsoUserToOrganization has exactly one production caller (apps/web/src/lib/user/sso.ts:85); the new parameter is optional, so no other call sites break.
  • Semantics match acceptOrganizationInvite (organizations.ts:854-861), which disables the personal account only when the account postdates the invite.
  • getProfileRedirectPath reads personal_account_disabled from a freshly loaded user in later requests, so the mid-flow update is not observed stale.
  • New tests use already-imported db, eq, and kilocode_users; no missing imports.
  • No subscriptions, timers, listeners, or retained references added (no memory-leak risk).
  • Markdown/landing-page custom rules were not applicable: this diff changes no .md or page files.
Previous Review Summary (commit ad3b224)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit ad3b224)

Status: No Issues Found | Recommendation: Merge

Executive Summary

Reviewed the new skipCustomerSourceSurveyForOrgJoin helper and its two call sites (invite acceptance inside the existing transaction, SSO auto-provision inside the if (added) branch) plus the accompanying tests; the customer_source IS NULL guard, ''-means-dismissed semantics, and optional-transaction pattern all match existing usage in apps/web/src/routers/user-router.ts and shouldShowCustomerSourceSurvey, so confidence is high.

Files Reviewed (4 files)
  • apps/web/src/lib/organizations/organizations.ts
  • apps/web/src/lib/organizations/organizations.test.ts
  • apps/web/src/lib/user/sso.ts
  • apps/web/src/lib/user/sso.test.ts
Verification notes
  • isNull/and are already imported in organizations.ts; no missing imports.
  • customer_source is a nullable text() column with no non-empty check constraint, so writing '' is valid.
  • The invite-flow call sits after the membership insert and uses the surrounding tx, so it rolls back with the rest of the accept flow.
  • The SSO call is guarded by added, so re-logins do not re-mark the survey, matching the PR intent.
  • No new subscriptions, timers, listeners, or retained references were introduced (no memory-leak risk).
  • Markdown/landing-page custom rules were not applicable: this PR changes no .md or page files.

Reviewed by claude-opus-5 · Input: 46 · Output: 7.7K · Cached: 1.1M

Review guidance: REVIEW.md from base branch main

Users who join an organization through SSO or an invitation should not be asked how they heard about Kilo. Mark the customer-source survey as dismissed (customer_source = '') at both join points, only when it is still unset (IS NULL) so an existing answer is never overwritten.
@RSO
RSO force-pushed the subdued-promise branch from ad3b224 to 4baa5e1 Compare July 31, 2026 12:43
@RSO
RSO enabled auto-merge (squash) July 31, 2026 12:46
@RSO
RSO merged commit 4316218 into main Jul 31, 2026
16 checks passed
@RSO
RSO deleted the subdued-promise branch July 31, 2026 12:54
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.

2 participants