fix: add missing PostHog events#7722
Conversation
…egrations PostHog `organization_created` event was not firing during user signup flow, and `integration_connected` was missing from OAuth callbacks (Notion, Airtable, Slack). Also fixes survey_response_received sampling which was broken by stale cache — extracted to lib with milestone-based firing (1, 10, 50, 100, 500+). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…s OAuth Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
WalkthroughThis pull request introduces PostHog analytics tracking across multiple integration and survey response flows. A new PostHog module is added with functions to determine milestone-based survey response capture (1st, 10th, 50th, 100th, and every 500th response) and to emit survey response events with metadata. PostHog event tracking is integrated into three integration callback handlers for Airtable, Notion, and Slack to log successful connections. A new tracking call is added to organization creation. The survey response tracking in the pipeline route is refactored to use the new helper function and remove response count caching. Comprehensive tests are included for the new survey response tracking logic. 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/web/app/api/`(internal)/pipeline/route.ts:
- Around line 303-313: The milestone count is being recomputed after
Promise.allSettled so it can be stale; instead obtain the exact response ordinal
during the response-creation DB transaction and pass that through to
captureSurveyResponsePostHogEvent (or implement an idempotent milestone-claim in
the same transaction). Concretely: modify the response creation flow to return
the created response's ordinal/id from the transaction, thread that value out of
the function that calls getResponseCountBySurveyId, and replace the call to
getResponseCountBySurveyId with the transaction-returned ordinal when invoking
captureSurveyResponsePostHogEvent (or call an idempotent claim function inside
the creation transaction to mark milestones).
In `@apps/web/app/api/v1/integrations/airtable/callback/route.ts`:
- Around line 92-96: The analytics lookup getOrganizationIdFromEnvironmentId is
on the critical path and can turn a successful Airtable connect into a 500 if it
fails; wrap the analytics side-effect so failures don't affect the response:
call getOrganizationIdFromEnvironmentId and capturePostHogEvent inside a
try/catch (or otherwise swallow/log errors) using authentication.user.id and the
integration metadata, and ensure any thrown error is logged but not rethrown so
the redirect still occurs; apply the same guard pattern to the matching Slack
and Notion callback handlers (i.e., protect their capturePostHogEvent calls
similarly).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: e25ef5c4-628d-4bcf-b797-03ef947c2bab
📒 Files selected for processing (7)
apps/web/app/api/(internal)/pipeline/lib/posthog.test.tsapps/web/app/api/(internal)/pipeline/lib/posthog.tsapps/web/app/api/(internal)/pipeline/route.tsapps/web/app/api/v1/integrations/airtable/callback/route.tsapps/web/app/api/v1/integrations/notion/callback/route.tsapps/web/app/api/v1/integrations/slack/callback/route.tsapps/web/modules/auth/signup/actions.ts
|



What does this PR do?
Adds missing PostHog events that were not firing in several flows:
organization_creatednot firing during signup —handleOrganizationCreationin signup flow creates org but never captured the PostHog event. Only the/setup/organization/createaction had it.integration_connectednot firing on OAuth connect — Notion, Airtable, and Slack OAuth callbacks callcreateOrUpdateIntegrationservice directly, bypassing theserver action that has the PostHog capture.
survey_response_receivedfiring inconsistently — Old logic used 60s cached response count +count === 1 || count % 100 === 0. Stale cache caused duplicatefires for early responses, then silence until 100th. Replaced with milestone-based sampling (1, 10, 50, 100, 500, 1000, ...) and extracted to testable lib.
Also removed debug
console.logs from integrations action.How should this be tested?
organization_createdevent appears in PostHog withorganization_idandis_first_orgpropertiesintegration_connectedevent appears in PostHog with correctintegration_typeandorganization_idsurvey_response_receivedfires at counts 1, 10, 50, 100, 500 and does NOT fire for counts 2-9, 11-49,etc.
npx vitest run apps/web/app/api/\(internal\)/pipeline/lib/posthog.test.ts— 10 tests covering milestone logicChecklist
Required
pnpm buildconsole.logsgit pull origin mainAppreciated