From fae2c5b96e19e8724a6bacda04e35ba06c7a7d7b Mon Sep 17 00:00:00 2001 From: Ivan Vasilov Date: Thu, 2 Jul 2026 12:47:13 +0300 Subject: [PATCH] chore: Add org slug and project ref as tags to the Sentry data (#47442) ## Summary by CodeRabbit * **Bug Fixes** * Enhanced telemetry to include the active project reference and selected organization on events. * Cleared and re-applied project and organization tags when navigating to prevent stale tagging. * Only applies user identification when user account details are available. * **Tests** * Updated telemetry tests to cover the additional tagging behavior by extending Sentry mocks accordingly. --- apps/studio/lib/telemetry.test.tsx | 3 +++ apps/studio/lib/telemetry.tsx | 17 ++++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/apps/studio/lib/telemetry.test.tsx b/apps/studio/lib/telemetry.test.tsx index 5fba56af9bf..3537b94fab4 100644 --- a/apps/studio/lib/telemetry.test.tsx +++ b/apps/studio/lib/telemetry.test.tsx @@ -8,6 +8,7 @@ const mocks = vi.hoisted(() => ({ useUser: vi.fn(), useOrganizationsQuery: vi.fn(), setUser: vi.fn(), + setTag: vi.fn(), })) vi.mock('common', async (importOriginal) => { @@ -36,6 +37,7 @@ vi.mock('@/hooks/misc/useSelectedOrganization', () => ({ vi.mock('@sentry/nextjs', () => ({ setUser: (...args: unknown[]) => mocks.setUser(...args), + setTag: (...args: unknown[]) => mocks.setTag(...args), })) const USER_ID = 'user-abc-123' @@ -50,6 +52,7 @@ describe('Telemetry — posthog identify mirroring', () => { mocks.useUser.mockReset() mocks.useOrganizationsQuery.mockReset() mocks.setUser.mockReset() + mocks.setTag.mockReset() }) it('fires identify with both org_count and signup_timestamp when user and orgs are loaded', async () => { diff --git a/apps/studio/lib/telemetry.tsx b/apps/studio/lib/telemetry.tsx index ebad3e51def..cdf1a5b1c00 100644 --- a/apps/studio/lib/telemetry.tsx +++ b/apps/studio/lib/telemetry.tsx @@ -1,5 +1,5 @@ import * as Sentry from '@sentry/nextjs' -import { PageTelemetry, posthogClient, useUser } from 'common' +import { PageTelemetry, posthogClient, useParams, useUser } from 'common' import { useEffect, useRef } from 'react' import { useConsentToast } from 'ui-patterns/consent' @@ -19,6 +19,9 @@ export function Telemetry() { const user = useUser() + // Project ref from the URL params, mirroring the backend's `request.params.ref` + const { ref: projectRef } = useParams() + // Mirror the user's org-list length into a PostHog person property so feature // flags and analytics can segment by current org membership. signup_timestamp // is set on the same identify so flag audiences requiring both properties see @@ -50,12 +53,16 @@ export function Telemetry() { useEffect(() => { // don't set the sentry user id if the user hasn't logged in (so that Sentry errors show null user id instead of anonymous id) - if (!user?.id) { - return + if (user?.id) { + Sentry.setUser({ id: user.id }) } - Sentry.setUser({ id: user.id }) - }, [user?.id]) + // Tag Sentry events with the current project ref and customer org slug so backend/ + // frontend errors can be filtered by project / org. Passing a null value clears + // the tag, so stale values don't leak across navigation. + Sentry.setTag('project_ref', projectRef ?? null) + Sentry.setTag('org_slug', organization?.slug ?? null) + }, [user?.id, projectRef, organization?.slug]) return (