Skip to content

feat(role-manager): wire all analytics trackers and add network_id to action events - #137

Merged
pasevin merged 2 commits into
mainfrom
feat/analytics-wire-events
Aug 25, 2026
Merged

feat(role-manager): wire all analytics trackers and add network_id to action events#137
pasevin merged 2 commits into
mainfrom
feat/analytics-wire-events

Conversation

@pasevin

@pasevin pasevin commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

Summary

Marketing/analytics only see page_view in GA4 because 12 of the 16 trackers in useRoleManagerAnalytics were never called, and the action events that did fire carried only ecosystem. This PR wires every tracker at its natural call site and attaches network_id + ecosystem to every action event so Stellar (and per-network) adoption can be queried in Athena/Metabase.

Scope: apps/role-manager only.

Changes

  • useRoleManagerAnalytics — trackers now take an AnalyticsNetworkContext ({ networkId, ecosystem }), built via getAnalyticsNetworkContext(runtime) (runtime.networkConfig.id / .ecosystem, "unknown" fallback). Every action event emits network_id and ecosystem. Existing GA param names are unchanged.
  • Tx actions fire on mutation success (same pattern as useCancelAdminTransferDialog): useAssignRoleDialog, useRevokeRoleDialog, useManageRolesDialog, useRenounceDialog, useOwnershipTransferDialog, useAcceptOwnershipDialog, useAdminTransferDialog, useAcceptAdminTransferDialog.
  • contract_selecteduseContractSelection tracks user-driven selections (contract picker and select-by-id after adding a contract). Auto-selecting the first contract on load is not tracked.
  • wallet_connected / wallet_disconnected — new WalletConnectionTracker (mounted in App.tsx) reports connect/disconnect transitions with the connector name (MetaMask, Freighter, …).
  • snapshot_exporteduseDashboardData passes onSuccess to useExportSnapshot (format: "json").
  • filter_applied — new useFilterAnalytics(page) hook used on Role Changes and Authorized Accounts; one event per changed filter field.
  • Docsapps/role-manager/README.md gets an Analytics section with the table below.
  • Tests — hook tests rewritten for the new signatures; new suites for useFilterAnalytics and WalletConnectionTracker; tracker assertions added to the assign/revoke/manage/renounce/ownership/accept-ownership/contract-selection/dashboard tests.

Privacy

  • Wallet/account addresses are never sent (the tracker test asserts this).
  • contract_address is sent on contract_selected only.
  • Free-form filter input (searchQuery, date bounds) is reported as set / cleared — a search string may be an address. Enumerated filters report the selected option.

Event → params

Event Params Fired from
page_view page_title, page_path (shared useAnalytics) TrackedRoute on every route render
contract_selected contract_address, network_id, ecosystem useContractSelection — user picks a contract / selects by id
wallet_connected wallet_type, network_id, ecosystem WalletConnectionTracker on connect
wallet_disconnected network_id, ecosystem WalletConnectionTracker on disconnect
role_granted role_name, network_id, ecosystem useAssignRoleDialog, useManageRolesDialog on tx success
role_revoked role_name, network_id, ecosystem useRevokeRoleDialog, useManageRolesDialog on tx success
role_renounced role_name, network_id, ecosystem useRenounceDialog (type role) on tx success
ownership_transfer_initiated network_id, ecosystem useOwnershipTransferDialog on tx success
ownership_accepted network_id, ecosystem useAcceptOwnershipDialog on tx success
ownership_renounced network_id, ecosystem useRenounceDialog (type ownership) on tx success
admin_transfer_initiated network_id, ecosystem useAdminTransferDialog on tx success
admin_transfer_accepted network_id, ecosystem useAcceptAdminTransferDialog on tx success
admin_transfer_cancelled network_id, ecosystem useCancelAdminTransferDialog on tx success
admin_delay_change_scheduled network_id, ecosystem useChangeAdminDelayDialog on tx success
admin_delay_change_rolled_back network_id, ecosystem useRollbackAdminDelayDialog on tx success
snapshot_exported format (json), network_id, ecosystem useDashboardData when the download succeeds
filter_applied page, filter_type, filter_value, network_id, ecosystem useFilterAnalytics on Role Changes / Authorized Accounts

filter_applied: page ∈ {Role Changes, Authorized Accounts}; filter_type is the filter-state key (actionFilter, statusFilter, roleFilter, searchQuery, timestampFrom, timestampTo); filter_value is the option for enumerated filters, set/cleared for free-form ones.

Not wired (intentionally)

  • Address Book network multi-select filter: cross-network page with no active runtime, so network_id would always be unknown; left out to keep filter_applied meaningful. Easy to add if wanted.
  • Auto-selection of the first contract on page load is not reported as contract_selected (it is not a user action). page_view still covers the session.

Verification

  • pnpm typecheck, pnpm lint — clean
  • pnpm test — 55 files / 1221 tests passing

… action events

Only page_view and three admin events were reaching GA4; the remaining
trackers were defined but never called, and no action event carried the
network. This wires every tracker at its natural call site and attaches
network_id + ecosystem to all action events so adoption can be broken down
per network.

- useRoleManagerAnalytics: trackers take an AnalyticsNetworkContext
  (network_id, ecosystem) built via getAnalyticsNetworkContext(runtime)
- role_granted/revoked/renounced, ownership_* and admin_* fire on
  mutation success in the dialog hooks
- contract_selected fires on user-driven selection in useContractSelection
- wallet_connected/disconnected via new WalletConnectionTracker
  (connector name only, never addresses)
- snapshot_exported on successful export in useDashboardData
- filter_applied via new useFilterAnalytics on Role Changes and
  Authorized Accounts (free-form values reported as set/cleared)
- tests for the hook, filter analytics, wallet tracker and call sites
- README: event -> params table

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR completes Role Manager’s GA4 instrumentation by wiring previously-unused analytics trackers at their natural call sites and standardizing action events to always include network_id and ecosystem, enabling per-network adoption analysis downstream (Athena/Metabase). It also adds tracking for wallet connect/disconnect, filter usage, contract selection, and snapshot exports, with updated docs and tests under apps/role-manager.

Changes:

  • Extend useRoleManagerAnalytics to use an AnalyticsNetworkContext and attach network_id + ecosystem to all action events via getAnalyticsNetworkContext(runtime).
  • Add new trackers/hooks for filter usage (useFilterAnalytics) and wallet connect/disconnect (WalletConnectionTracker), and wire action trackers into relevant dialogs and flows.
  • Update README analytics documentation and expand/adjust test suites to validate new signatures and privacy constraints.

Reviewed changes

Copilot reviewed 35 out of 35 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
apps/role-manager/src/pages/RoleChanges.tsx Wrap filter updates to emit filter_applied events for Role Changes page.
apps/role-manager/src/pages/AuthorizedAccounts.tsx Emit filter_applied analytics on filter changes for Authorized Accounts page.
apps/role-manager/src/hooks/useRollbackAdminDelayDialog.ts Add network context to admin_delay_change_rolled_back tracking on success.
apps/role-manager/src/hooks/useRoleManagerAnalytics.ts Introduce network context + helpers; update trackers to include network_id/ecosystem.
apps/role-manager/src/hooks/useRevokeRoleDialog.ts Track role_revoked on successful revoke mutation with network context.
apps/role-manager/src/hooks/useRenounceDialog.ts Track ownership_renounced / role_renounced on success with network context.
apps/role-manager/src/hooks/useOwnershipTransferDialog.ts Track ownership_transfer_initiated on tx success with network context.
apps/role-manager/src/hooks/useManageRolesDialog.ts Track grant/revoke events for submitted role changes on multi-mutation success.
apps/role-manager/src/hooks/useFilterAnalytics.ts New hook to diff filter states and emit privacy-safe filter_applied events.
apps/role-manager/src/hooks/useDashboardData.ts Track snapshot_exported on successful snapshot download with network context.
apps/role-manager/src/hooks/useContractSelection.ts Track user-driven contract_selected events with network + ecosystem resolution.
apps/role-manager/src/hooks/useChangeAdminDelayDialog.ts Track admin_delay_change_scheduled on success with network context.
apps/role-manager/src/hooks/useCancelAdminTransferDialog.ts Track admin_transfer_cancelled on success with network context.
apps/role-manager/src/hooks/useAssignRoleDialog.ts Track role_granted on success with submitted role name and network context.
apps/role-manager/src/hooks/useAdminTransferDialog.ts Track admin_transfer_initiated on tx success with network context.
apps/role-manager/src/hooks/useAcceptOwnershipDialog.ts Track ownership_accepted on tx success with network context.
apps/role-manager/src/hooks/useAcceptAdminTransferDialog.ts Track admin_transfer_accepted on tx success with network context.
apps/role-manager/src/hooks/index.ts Export new analytics helpers/types and useFilterAnalytics.
apps/role-manager/src/hooks/tests/useSelectedContract.test.tsx Stub analytics hook to satisfy provider requirements in contract selection tests.
apps/role-manager/src/hooks/tests/useRoleManagerAnalytics.test.tsx Update analytics hook tests for network context + GA param correctness.
apps/role-manager/src/hooks/tests/useRevokeRoleDialog.test.tsx Assert revoke success emits role revoke tracking with network context.
apps/role-manager/src/hooks/tests/useRenounceDialog.test.tsx Add analytics assertions for renounce flows and unknown-network fallback.
apps/role-manager/src/hooks/tests/useOwnershipTransferDialog.test.tsx Assert ownership transfer tracking fires with runtime network context.
apps/role-manager/src/hooks/tests/useManageRolesDialog.test.tsx Assert manage roles grant/revoke analytics fire with network context.
apps/role-manager/src/hooks/tests/useFilterAnalytics.test.tsx New tests for filter diffing + privacy-safe reporting and network dims.
apps/role-manager/src/hooks/tests/useDashboardData.test.tsx Assert snapshot_exported tracking fires only on export success callback.
apps/role-manager/src/hooks/tests/useContractSelection.test.ts Add analytics assertions for user-driven contract selections and non-tracked auto-select.
apps/role-manager/src/hooks/tests/useAssignRoleDialog.test.tsx Assert grant success emits role_granted analytics with network context.
apps/role-manager/src/hooks/tests/useAcceptOwnershipDialog.test.tsx Assert accept ownership success emits ownership_accepted analytics.
apps/role-manager/src/context/tests/ContractContext.test.tsx Stub analytics hook for contract context test environment.
apps/role-manager/src/components/Analytics/WalletConnectionTracker.tsx New component to track wallet connect/disconnect transitions with connector name.
apps/role-manager/src/components/Analytics/index.ts Export WalletConnectionTracker from analytics barrel.
apps/role-manager/src/components/Analytics/tests/WalletConnectionTracker.test.tsx New tests for wallet connect/disconnect events and address privacy.
apps/role-manager/src/App.tsx Mount WalletConnectionTracker within providers so it can read wallet/runtime context.
apps/role-manager/README.md Document analytics events, params, privacy constraints, and call sites.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread apps/role-manager/src/pages/AuthorizedAccounts.tsx
Comment thread apps/role-manager/src/pages/RoleChanges.tsx Outdated
Comment thread apps/role-manager/src/components/Analytics/WalletConnectionTracker.tsx Outdated
@pasevin
pasevin marked this pull request as ready for review August 25, 2026 14:21
- useFilterAnalytics: diff against a ref of the last reported filter state
  instead of the render closure so rapid successive updates are tracked
  correctly; callers now pass only the next state
- WalletConnectionTracker: seed wasConnectedRef from the current status so
  an already-connected mount does not emit wallet_connected
- tests for rapid updates, external baseline re-sync, and connected mount
@pasevin
pasevin force-pushed the feat/analytics-wire-events branch from ee509d6 to 2a01ba6 Compare August 25, 2026 14:28
@pasevin
pasevin merged commit e07e0a0 into main Aug 25, 2026
11 checks passed
@pasevin
pasevin deleted the feat/analytics-wire-events branch August 25, 2026 14:31
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 25, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants