From 66f1879df41b280451f2f5eec23cdfd89c2a0f06 Mon Sep 17 00:00:00 2001 From: msukkari Date: Tue, 24 Feb 2026 14:13:30 -0800 Subject: [PATCH 1/7] feat: add wa_user_created PostHog event on successful sign-up Fire a `wa_user_created` telemetry event in the NextAuth `onCreateUser` handler so we can track successful sign-ups in PostHog, closing a gap in the visitor-to-sign-up conversion funnel. Co-Authored-By: Claude Opus 4.6 --- CHANGELOG.md | 1 + packages/web/src/lib/authUtils.ts | 6 +++++- packages/web/src/lib/posthogEvents.ts | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb05995bc..07462da69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added PostHog events for chat UI interactions (details card expand/collapse, copy answer, table of contents toggle) and repo tracking in `wa_chat_message_sent`. [#922](https://github.com/sourcebot-dev/sourcebot/pull/922) - Added Bitbucket Cloud OAuth identity provider support (`provider: "bitbucket-cloud"`) for SSO and account-linked permission syncing. [#924](https://github.com/sourcebot-dev/sourcebot/pull/924) - Added permission syncing support for Bitbucket Cloud. [#925](https://github.com/sourcebot-dev/sourcebot/pull/925) +- Added `wa_user_created` PostHog event fired on successful user sign-up. [#933](https://github.com/sourcebot-dev/sourcebot/pull/933) ### Changed - Hide version upgrade toast for askgithub deployment (`EXPERIMENT_ASK_GH_ENABLED`). [#931](https://github.com/sourcebot-dev/sourcebot/pull/931) diff --git a/packages/web/src/lib/authUtils.ts b/packages/web/src/lib/authUtils.ts index e11942a49..f250ad233 100644 --- a/packages/web/src/lib/authUtils.ts +++ b/packages/web/src/lib/authUtils.ts @@ -107,7 +107,7 @@ export const onCreateUser = async ({ user }: { user: AuthJsUser }) => { type: "org" } }); - } else if (!defaultOrg.memberApprovalRequired) { + } else if (!defaultOrg.memberApprovalRequired) { const hasAvailability = await orgHasAvailability(defaultOrg.domain); if (!hasAvailability) { logger.warn(`onCreateUser: org ${SINGLE_TENANT_ORG_ID} has reached max capacity. User ${user.id} was not added to the org.`); @@ -123,6 +123,10 @@ export const onCreateUser = async ({ user }: { user: AuthJsUser }) => { }); } + // Dynamic import to avoid circular dependency: + // authUtils -> posthog -> auth -> authUtils + const { captureEvent } = await import("@/lib/posthog"); + await captureEvent('wa_user_created', { userId: user.id }); }; diff --git a/packages/web/src/lib/posthogEvents.ts b/packages/web/src/lib/posthogEvents.ts index b2daa28dc..7750fd9a1 100644 --- a/packages/web/src/lib/posthogEvents.ts +++ b/packages/web/src/lib/posthogEvents.ts @@ -227,6 +227,9 @@ export type PosthogEventMap = { chatId: string, isExpanded: boolean, }, + wa_user_created: { + userId: string, + }, ////////////////////////////////////////////////////////////////// wa_demo_docs_link_pressed: {}, wa_demo_search_example_card_pressed: { From ac425074217589883b4e7a86316f48f6e0007844 Mon Sep 17 00:00:00 2001 From: msukkari Date: Tue, 24 Feb 2026 14:13:30 -0800 Subject: [PATCH 2/7] feat: add wa_user_created PostHog event on successful sign-up Fire a `wa_user_created` telemetry event in the NextAuth `onCreateUser` handler so we can track successful sign-ups in PostHog, closing a gap in the visitor-to-sign-up conversion funnel. Co-Authored-By: Claude Opus 4.6 --- packages/web/src/lib/posthog.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/web/src/lib/posthog.ts b/packages/web/src/lib/posthog.ts index 2e91f436f..6b4249eaf 100644 --- a/packages/web/src/lib/posthog.ts +++ b/packages/web/src/lib/posthog.ts @@ -1,5 +1,5 @@ import { PostHog } from 'posthog-node' -import { env, SOURCEBOT_VERSION } from '@sourcebot/shared' +import { createLogger, env, SOURCEBOT_VERSION } from '@sourcebot/shared' import { RequestCookies } from 'next/dist/compiled/@edge-runtime/cookies'; import * as Sentry from "@sentry/nextjs"; import { PosthogEvent, PosthogEventMap } from './posthogEvents'; @@ -7,6 +7,8 @@ import { cookies, headers } from 'next/headers'; import { auth } from '@/auth'; import { getVerifiedApiObject } from '@/withAuthV2'; +const logger = createLogger('posthog'); + /** * @note: This is a subset of the properties stored in the * ph_phc__posthog cookie. @@ -93,6 +95,8 @@ export async function captureEvent(event: E, properties: flushInterval: 0 }) + logger.debug(`Capturing event: ${event}`, { distinctId, host, ...properties }); + posthog.capture({ event, properties: { From dc55a274737d56713e4d75e7aa9014977e239e02 Mon Sep 17 00:00:00 2001 From: msukkari Date: Tue, 24 Feb 2026 15:14:57 -0800 Subject: [PATCH 3/7] feat(web): add PostHog events for user creation and Ask GitHub login wall - Add `wa_user_created` event fired on successful user sign-up - Add `wa_askgh_login_wall_prompted` event fired when an unauthenticated user attempts to ask a question on Ask GitHub and is shown the login modal - Add debug logging to server-side PostHog event capture Co-Authored-By: Claude Opus 4.6 --- .../[domain]/askgh/[owner]/[repo]/components/landingPage.tsx | 2 ++ packages/web/src/lib/posthogEvents.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/packages/web/src/app/[domain]/askgh/[owner]/[repo]/components/landingPage.tsx b/packages/web/src/app/[domain]/askgh/[owner]/[repo]/components/landingPage.tsx index 9e29dd46c..d54bb030c 100644 --- a/packages/web/src/app/[domain]/askgh/[owner]/[repo]/components/landingPage.tsx +++ b/packages/web/src/app/[domain]/askgh/[owner]/[repo]/components/landingPage.tsx @@ -14,6 +14,7 @@ import type { IdentityProviderMetadata } from "@/lib/identityProviders"; import { Descendant, Transforms } from "slate"; import { useSlate } from "slate-react"; import { useCallback, useEffect, useMemo, useState, useRef } from "react"; +import { captureEvent } from "@/hooks/useCaptureEvent"; const PENDING_MESSAGE_KEY = "askgh_pending_message"; @@ -55,6 +56,7 @@ export const LandingPage = ({ // Intercept submit to check auth status const handleSubmit = useCallback((children: Descendant[]) => { if (!isAuthenticated) { + captureEvent('wa_askgh_login_wall_prompted', {}); // Store message in sessionStorage to survive OAuth redirect sessionStorage.setItem(PENDING_MESSAGE_KEY, JSON.stringify(children)); setIsLoginModalOpen(true); diff --git a/packages/web/src/lib/posthogEvents.ts b/packages/web/src/lib/posthogEvents.ts index 7750fd9a1..285035ddd 100644 --- a/packages/web/src/lib/posthogEvents.ts +++ b/packages/web/src/lib/posthogEvents.ts @@ -231,6 +231,8 @@ export type PosthogEventMap = { userId: string, }, ////////////////////////////////////////////////////////////////// + wa_askgh_login_wall_prompted: {}, + ////////////////////////////////////////////////////////////////// wa_demo_docs_link_pressed: {}, wa_demo_search_example_card_pressed: { exampleTitle: string, From 064f9b111f764c8b6be42921e6784aab776e6ed7 Mon Sep 17 00:00:00 2001 From: msukkari Date: Tue, 24 Feb 2026 15:17:43 -0800 Subject: [PATCH 4/7] docs: update CHANGELOG with wa_askgh_login_wall_prompted event Co-Authored-By: Claude Opus 4.6 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07462da69..584f6aa3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added Bitbucket Cloud OAuth identity provider support (`provider: "bitbucket-cloud"`) for SSO and account-linked permission syncing. [#924](https://github.com/sourcebot-dev/sourcebot/pull/924) - Added permission syncing support for Bitbucket Cloud. [#925](https://github.com/sourcebot-dev/sourcebot/pull/925) - Added `wa_user_created` PostHog event fired on successful user sign-up. [#933](https://github.com/sourcebot-dev/sourcebot/pull/933) +- Added `wa_askgh_login_wall_prompted` PostHog event fired when an unauthenticated user attempts to ask a question on Ask GitHub. [#933](https://github.com/sourcebot-dev/sourcebot/pull/933) ### Changed - Hide version upgrade toast for askgithub deployment (`EXPERIMENT_ASK_GH_ENABLED`). [#931](https://github.com/sourcebot-dev/sourcebot/pull/931) From 532feb5972d93b5ca714c231cc89397a7a2b4dc8 Mon Sep 17 00:00:00 2001 From: msukkari Date: Tue, 24 Feb 2026 15:23:41 -0800 Subject: [PATCH 5/7] feat(web): add wa_askgh_repo_indexed PostHog event Fires when a repo completes indexing on Ask GitHub, capturing the repo name. Co-Authored-By: Claude Opus 4.6 --- .../askgh/[owner]/[repo]/components/repoIndexedGuard.tsx | 4 +++- packages/web/src/lib/posthogEvents.ts | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/web/src/app/[domain]/askgh/[owner]/[repo]/components/repoIndexedGuard.tsx b/packages/web/src/app/[domain]/askgh/[owner]/[repo]/components/repoIndexedGuard.tsx index 863f9b284..49fcf0acc 100644 --- a/packages/web/src/app/[domain]/askgh/[owner]/[repo]/components/repoIndexedGuard.tsx +++ b/packages/web/src/app/[domain]/askgh/[owner]/[repo]/components/repoIndexedGuard.tsx @@ -7,6 +7,7 @@ import { Loader2 } from "lucide-react"; import { usePrevious } from "@uidotdev/usehooks"; import { useEffect } from "react"; import { useBrowserNotification } from "@/hooks/useBrowserNotification"; +import { captureEvent } from "@/hooks/useCaptureEvent"; import { RepoInfo } from "../types"; const REINDEX_INTERVAL_MS = 2000; @@ -45,9 +46,10 @@ export function RepoIndexedGuard({ initialRepoInfo, children }: Props) { } }, [initialRepoInfo.isIndexed, requestPermission]); - // Show notification when indexing completes + // Show notification and fire event when indexing completes useEffect(() => { if (previousIsIndexed === false && repoInfo.isIndexed === true) { + captureEvent('wa_askgh_repo_indexed', { repoName: repoInfo.name }); const displayName = repoInfo.displayName ?? repoInfo.name; showNotification({ title: "Repository Ready", diff --git a/packages/web/src/lib/posthogEvents.ts b/packages/web/src/lib/posthogEvents.ts index 285035ddd..363ae1552 100644 --- a/packages/web/src/lib/posthogEvents.ts +++ b/packages/web/src/lib/posthogEvents.ts @@ -232,6 +232,9 @@ export type PosthogEventMap = { }, ////////////////////////////////////////////////////////////////// wa_askgh_login_wall_prompted: {}, + wa_askgh_repo_indexed: { + repoName: string, + }, ////////////////////////////////////////////////////////////////// wa_demo_docs_link_pressed: {}, wa_demo_search_example_card_pressed: { From 9ade8c36d26b74abb3e00de5b714ef3b39ffc666 Mon Sep 17 00:00:00 2001 From: msukkari Date: Tue, 24 Feb 2026 15:25:52 -0800 Subject: [PATCH 6/7] revert: remove wa_askgh_repo_indexed, use existing backend_repo_first_indexed backend_repo_first_indexed already fires server-side in repoIndexManager.ts when a repo is first indexed, which is more reliable than client-side tracking. Co-Authored-By: Claude Opus 4.6 --- .../askgh/[owner]/[repo]/components/repoIndexedGuard.tsx | 4 +--- packages/web/src/lib/posthogEvents.ts | 3 --- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/web/src/app/[domain]/askgh/[owner]/[repo]/components/repoIndexedGuard.tsx b/packages/web/src/app/[domain]/askgh/[owner]/[repo]/components/repoIndexedGuard.tsx index 49fcf0acc..863f9b284 100644 --- a/packages/web/src/app/[domain]/askgh/[owner]/[repo]/components/repoIndexedGuard.tsx +++ b/packages/web/src/app/[domain]/askgh/[owner]/[repo]/components/repoIndexedGuard.tsx @@ -7,7 +7,6 @@ import { Loader2 } from "lucide-react"; import { usePrevious } from "@uidotdev/usehooks"; import { useEffect } from "react"; import { useBrowserNotification } from "@/hooks/useBrowserNotification"; -import { captureEvent } from "@/hooks/useCaptureEvent"; import { RepoInfo } from "../types"; const REINDEX_INTERVAL_MS = 2000; @@ -46,10 +45,9 @@ export function RepoIndexedGuard({ initialRepoInfo, children }: Props) { } }, [initialRepoInfo.isIndexed, requestPermission]); - // Show notification and fire event when indexing completes + // Show notification when indexing completes useEffect(() => { if (previousIsIndexed === false && repoInfo.isIndexed === true) { - captureEvent('wa_askgh_repo_indexed', { repoName: repoInfo.name }); const displayName = repoInfo.displayName ?? repoInfo.name; showNotification({ title: "Repository Ready", diff --git a/packages/web/src/lib/posthogEvents.ts b/packages/web/src/lib/posthogEvents.ts index 363ae1552..285035ddd 100644 --- a/packages/web/src/lib/posthogEvents.ts +++ b/packages/web/src/lib/posthogEvents.ts @@ -232,9 +232,6 @@ export type PosthogEventMap = { }, ////////////////////////////////////////////////////////////////// wa_askgh_login_wall_prompted: {}, - wa_askgh_repo_indexed: { - repoName: string, - }, ////////////////////////////////////////////////////////////////// wa_demo_docs_link_pressed: {}, wa_demo_search_example_card_pressed: { From e5c6a06a6f9d643ab1a7d1178a5186f0508784b3 Mon Sep 17 00:00:00 2001 From: msukkari Date: Tue, 24 Feb 2026 15:48:53 -0800 Subject: [PATCH 7/7] chore: remove debug logging from posthog captureEvent Co-Authored-By: Claude Opus 4.6 --- packages/web/src/lib/posthog.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/web/src/lib/posthog.ts b/packages/web/src/lib/posthog.ts index 6b4249eaf..2e91f436f 100644 --- a/packages/web/src/lib/posthog.ts +++ b/packages/web/src/lib/posthog.ts @@ -1,5 +1,5 @@ import { PostHog } from 'posthog-node' -import { createLogger, env, SOURCEBOT_VERSION } from '@sourcebot/shared' +import { env, SOURCEBOT_VERSION } from '@sourcebot/shared' import { RequestCookies } from 'next/dist/compiled/@edge-runtime/cookies'; import * as Sentry from "@sentry/nextjs"; import { PosthogEvent, PosthogEventMap } from './posthogEvents'; @@ -7,8 +7,6 @@ import { cookies, headers } from 'next/headers'; import { auth } from '@/auth'; import { getVerifiedApiObject } from '@/withAuthV2'; -const logger = createLogger('posthog'); - /** * @note: This is a subset of the properties stored in the * ph_phc__posthog cookie. @@ -95,8 +93,6 @@ export async function captureEvent(event: E, properties: flushInterval: 0 }) - logger.debug(`Capturing event: ${event}`, { distinctId, host, ...properties }); - posthog.capture({ event, properties: {