feat(analytics): emit group_id on every event (RQ-4675) [Interceptor 3.1]#85
Draft
wrongsahil wants to merge 2 commits into
Draft
feat(analytics): emit group_id on every event (RQ-4675) [Interceptor 3.1]#85wrongsahil wants to merge 2 commits into
wrongsahil wants to merge 2 commits into
Conversation
Stamp the signed-in user's BrowserStack group_id onto every analytics event so BrowserStack Usage Reports can attribute Interceptor usage per group. group_id is a property of the USER (not the workspace), sourced from the user's BS-linked billing team (browserstackGroupId), which maps 1:1 to a BS group via requestly-cloud (browserstack-<groupId>). - getUserBrowserstackGroupId / pickUserBrowserstackGroupId billing selectors: resolve the group id from the user's billing teams, preferring a team the user is a member of (over domain-matched teams). - useBrowserstackGroupId: keep window.currentlyActiveBrowserstackGroupId in sync (mirrors the existing window.currentlyActiveWorkspace* globals that the non-hook trackEvent choke-point reads), mounted in AppLayout. - trackEvent enrichment stamps newParams.group_id. sub_group_id is intentionally omitted (no sub-group source in Interceptor today). - Unit tests for the pure resolver. Field name group_id (snake_case) matches the BigQuery sink and the API Client envelope. null when the user has no BS-linked billing team. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…t_details (RQ-4675) Per the patch model (requestly-cloud webapp overwrites modules/analytics/), group_id must flow the same way as browserstack_user_id: a top-level data.* field stamped in the EDS integration (webapp/eds.ts), not in event_details. - Drop the newParams.group_id stamp from this repo's analytics/index.js (it lives in the overwritten module and belongs in event_details, wrong). - Keep the billing selector + useBrowserstackGroupId hook: they expose the group id on window.currentlyActiveBrowserstackGroupId — the interceptor-side source the EDS overlay reads (analogous to the auth handler's browserstackId). The EDS-side stamp lands in requestly-cloud webapp/src/modules/analytics/ integrations/eds.ts (separate PR). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
[Interceptor 3.1] Plumb BrowserStack
group_idonto every event — RQ-4675First stacked PR on the Task-3 base (#84). Targets
feat/rq-3644-usage-reports.What
Stamp the signed-in user's BrowserStack
group_idonto every analytics event so BrowserStack Usage Reports can attribute Interceptor usage per group.Why this source
group_idis a property of the user, not the workspace (the workspace'sbrowserstackDetails.groupIdwas the wrong semantic). It's sourced from the user's BS-linked billing teambrowserstackGroupId, which requestly-cloud maps 1:1 to a BS group (getBillingTeamIdFromGroupId→browserstack-<groupId>; a synced user belongs to exactly one such team). Full rationale + evidence in the base PR's design doc.Changes
store/features/billing/selectors.ts—pickUserBrowserstackGroupId(pure) +getUserBrowserstackGroupId(selector): resolve the group id from the user's billing teams, preferring a team the user is an actual member of over domain-matched teams;nullwhen none.hooks/useBrowserstackGroupId.ts— keepswindow.currentlyActiveBrowserstackGroupIdin sync (mirrors the existingwindow.currentlyActiveWorkspace*globals the non-hooktrackEventreads); mounted inAppLayout.modules/analytics/index.js—trackEventenrichment stampsnewParams.group_id.sub_group_idintentionally omitted (no sub-group source in Interceptor; commented for future).selectors.test.ts— unit tests for the pure resolver (member-of preference, domain fallback, non-BS teams, null cases).Notes
group_id(snake_case) matches the BigQuery sink + API Client envelope, so the cross-product query is uniform. RQ stores the id as a string;JSON_VALUE($.group_id)stringifies uniformly.nullfor users with no BS-linked billing team (email/Firebase-only) — matches the canonical/mebehavior.Verification
node_modulesinstalled (bare source), sotsc/vitestwere not run locally — CI is the automated gate. Statically reviewed: import paths (aliases resolve viabaseUrl: ./src), types (BillingTeamRolesenum in tests,Recordmembership check,string | nullreturn), and theWindowaugmentation. End-to-end EDS→BigQuery verification (the_qarig) depends on the sink confirmation in 3.6 (RQ-4680).🤖 Generated with Claude Code