Skip to content

feat(analytics): emit group_id on every event (RQ-4675) [Interceptor 3.1]#85

Draft
wrongsahil wants to merge 2 commits into
feat/rq-3644-usage-reportsfrom
feat/rq-4675-group-id
Draft

feat(analytics): emit group_id on every event (RQ-4675) [Interceptor 3.1]#85
wrongsahil wants to merge 2 commits into
feat/rq-3644-usage-reportsfrom
feat/rq-4675-group-id

Conversation

@wrongsahil

Copy link
Copy Markdown
Member

[Interceptor 3.1] Plumb BrowserStack group_id onto every event — RQ-4675

First stacked PR on the Task-3 base (#84). Targets feat/rq-3644-usage-reports.

What

Stamp the signed-in user's BrowserStack group_id onto every analytics event so BrowserStack Usage Reports can attribute Interceptor usage per group.

Why this source

group_id is a property of the user, not the workspace (the workspace's browserstackDetails.groupId was the wrong semantic). It's sourced from the user's BS-linked billing team browserstackGroupId, which requestly-cloud maps 1:1 to a BS group (getBillingTeamIdFromGroupIdbrowserstack-<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.tspickUserBrowserstackGroupId (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; null when none.
  • hooks/useBrowserstackGroupId.ts — keeps window.currentlyActiveBrowserstackGroupId in sync (mirrors the existing window.currentlyActiveWorkspace* globals the non-hook trackEvent reads); mounted in AppLayout.
  • modules/analytics/index.jstrackEvent enrichment stamps newParams.group_id. sub_group_id intentionally 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

  • Field name 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.
  • null for users with no BS-linked billing team (email/Firebase-only) — matches the canonical /me behavior.

Verification

⚠️ This checkout has no node_modules installed (bare source), so tsc/vitest were not run locally — CI is the automated gate. Statically reviewed: import paths (aliases resolve via baseUrl: ./src), types (BillingTeamRoles enum in tests, Record membership check, string | null return), and the Window augmentation. End-to-end EDS→BigQuery verification (the _qa rig) depends on the sink confirmation in 3.6 (RQ-4680).

🤖 Generated with Claude Code

wrongsahil and others added 2 commits July 17, 2026 17:49
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>
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.

1 participant