Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement EventTracker abstraction and Amplitude implementation #3650

Merged
merged 14 commits into from
Jan 22, 2025

Conversation

spalmurray-codecov
Copy link
Contributor

@spalmurray-codecov spalmurray-codecov commented Jan 10, 2025

Implements a new EventTracker abstraction and an Amplitude specific implementation of it. This provides a generic even tracking interface so we can swap out or change the implementation without major refactoring. This PR also adds some example 'Button Clicked' events that we're interested in tracking for our onboarding funnel.

Depends on codecov/codecov-api#1095
Depends on AMPLITUDE_API_KEY env var getting set (done)

Closes codecov/engineering-team#3178

@codecov-staging
Copy link

codecov-staging bot commented Jan 10, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

✅ All tests successful. No failed tests found.

@@           Coverage Diff           @@
##             main    #3650   +/-   ##
=======================================
  Coverage   98.80%   98.81%           
=======================================
  Files         820      825    +5     
  Lines       14784    14876   +92     
  Branches     4214     4234   +20     
=======================================
+ Hits        14608    14700   +92     
  Misses        167      167           
  Partials        9        9           
Files with missing lines Coverage Δ
src/layouts/BaseLayout/BaseLayout.tsx 100.00% <100.00%> (ø)
...ts/Header/components/UserDropdown/UserDropdown.tsx 100.00% <100.00%> (ø)
...rBanners/GithubConfigBanner/GithubConfigBanner.jsx 100.00% <100.00%> (ø)
src/services/events/__mocks__/events.ts 100.00% <100.00%> (ø)
src/services/events/amplitude/amplitude.ts 100.00% <100.00%> (ø)
src/services/events/events.ts 100.00% <100.00%> (ø)
src/services/events/hooks.tsx 100.00% <100.00%> (ø)
src/services/events/types.ts 100.00% <100.00%> (ø)
src/services/user/useOwner.ts 100.00% <100.00%> (ø)
src/services/user/useUser.ts 100.00% <100.00%> (ø)
... and 5 more
Components Coverage Δ
Assets 100.00% <ø> (ø)
Layouts 99.71% <100.00%> (+<0.01%) ⬆️
Pages 98.43% <100.00%> (+<0.01%) ⬆️
Services 99.30% <100.00%> (+0.01%) ⬆️
Shared 99.37% <100.00%> (+<0.01%) ⬆️
UI 99.14% <100.00%> (+<0.01%) ⬆️

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 02d5b6b...16a63d2. Read the comment docs.

@codecov-qa
Copy link

codecov-qa bot commented Jan 10, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.81%. Comparing base (02d5b6b) to head (16a63d2).
Report is 2 commits behind head on main.

✅ All tests successful. No failed tests found.

@@           Coverage Diff           @@
##             main    #3650   +/-   ##
=======================================
  Coverage   98.80%   98.81%           
=======================================
  Files         820      825    +5     
  Lines       14784    14876   +92     
  Branches     4214     4234   +20     
=======================================
+ Hits        14608    14700   +92     
  Misses        167      167           
  Partials        9        9           
Files with missing lines Coverage Δ
src/layouts/BaseLayout/BaseLayout.tsx 100.00% <100.00%> (ø)
...ts/Header/components/UserDropdown/UserDropdown.tsx 100.00% <100.00%> (ø)
...rBanners/GithubConfigBanner/GithubConfigBanner.jsx 100.00% <100.00%> (ø)
src/services/events/__mocks__/events.ts 100.00% <100.00%> (ø)
src/services/events/amplitude/amplitude.ts 100.00% <100.00%> (ø)
src/services/events/events.ts 100.00% <100.00%> (ø)
src/services/events/hooks.tsx 100.00% <100.00%> (ø)
src/services/events/types.ts 100.00% <100.00%> (ø)
src/services/user/useOwner.ts 100.00% <100.00%> (ø)
src/services/user/useUser.ts 100.00% <100.00%> (ø)
... and 5 more
Components Coverage Δ
Assets 100.00% <ø> (ø)
Layouts 99.71% <100.00%> (+<0.01%) ⬆️
Pages 98.43% <100.00%> (+<0.01%) ⬆️
Services 99.30% <100.00%> (+0.01%) ⬆️
Shared 99.37% <100.00%> (+<0.01%) ⬆️
UI 99.14% <100.00%> (+<0.01%) ⬆️

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 02d5b6b...16a63d2. Read the comment docs.

Copy link

codecov-public-qa bot commented Jan 10, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.92%. Comparing base (c9c56e6) to head (093c894).

✅ All tests successful. No failed tests found.

@@           Coverage Diff           @@
##             main    #3650   +/-   ##
=======================================
  Coverage   98.91%   98.92%           
=======================================
  Files         817      822    +5     
  Lines       14716    14806   +90     
  Branches     4165     4184   +19     
=======================================
+ Hits        14557    14647   +90     
  Misses        152      152           
  Partials        7        7           
Files with missing lines Coverage Δ
src/layouts/BaseLayout/BaseLayout.tsx 100.00% <100.00%> (ø)
...ts/Header/components/UserDropdown/UserDropdown.tsx 100.00% <100.00%> (ø)
...rBanners/GithubConfigBanner/GithubConfigBanner.jsx 100.00% <100.00%> (ø)
src/services/events/__mocks__/events.ts 100.00% <100.00%> (ø)
src/services/events/amplitude/amplitude.ts 100.00% <100.00%> (ø)
src/services/events/events.ts 100.00% <100.00%> (ø)
src/services/events/hooks.tsx 100.00% <100.00%> (ø)
src/services/events/types.ts 100.00% <100.00%> (ø)
src/services/user/useOwner.ts 100.00% <100.00%> (ø)
src/services/user/useUser.ts 100.00% <100.00%> (ø)
... and 5 more
Components Coverage Δ
Assets 100.00% <ø> (ø)
Layouts 99.71% <100.00%> (+<0.01%) ⬆️
Pages 98.62% <100.00%> (+<0.01%) ⬆️
Services 99.30% <100.00%> (+0.01%) ⬆️
Shared 99.37% <100.00%> (+<0.01%) ⬆️
UI 99.14% <100.00%> (+<0.01%) ⬆️

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c9c56e6...093c894. Read the comment docs.

Copy link

codecov bot commented Jan 10, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.81%. Comparing base (02d5b6b) to head (16a63d2).
Report is 2 commits behind head on main.

✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3650   +/-   ##
=======================================
  Coverage   98.80%   98.81%           
=======================================
  Files         820      825    +5     
  Lines       14784    14876   +92     
  Branches     4206     4226   +20     
=======================================
+ Hits        14608    14700   +92     
  Misses        167      167           
  Partials        9        9           
Files with missing lines Coverage Δ
src/layouts/BaseLayout/BaseLayout.tsx 100.00% <100.00%> (ø)
...ts/Header/components/UserDropdown/UserDropdown.tsx 100.00% <100.00%> (ø)
...rBanners/GithubConfigBanner/GithubConfigBanner.jsx 100.00% <100.00%> (ø)
src/services/events/__mocks__/events.ts 100.00% <100.00%> (ø)
src/services/events/amplitude/amplitude.ts 100.00% <100.00%> (ø)
src/services/events/events.ts 100.00% <100.00%> (ø)
src/services/events/hooks.tsx 100.00% <100.00%> (ø)
src/services/events/types.ts 100.00% <100.00%> (ø)
src/services/user/useOwner.ts 100.00% <100.00%> (ø)
src/services/user/useUser.ts 100.00% <100.00%> (ø)
... and 5 more
Components Coverage Δ
Assets 100.00% <ø> (ø)
Layouts 99.71% <100.00%> (+<0.01%) ⬆️
Pages 98.43% <100.00%> (+<0.01%) ⬆️
Services 99.30% <100.00%> (+0.01%) ⬆️
Shared 99.37% <100.00%> (+<0.01%) ⬆️
UI 99.14% <100.00%> (+<0.01%) ⬆️

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 02d5b6b...16a63d2. Read the comment docs.


const AMPLITUDE_API_KEY = process.env.REACT_APP_AMPLITUDE_API_KEY

export interface EventTracker {
Copy link
Contributor

Choose a reason for hiding this comment

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

Using an abstract class instead of an interface is a little more explicit of this Class's purpose

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tried that initially, but went with interface because it handled method overloads a little more cleanly. I agree though - particularly if we go with the Event type instead of overloads

): void
}

class StubbedEventTracker implements EventTracker {
Copy link
Contributor

Choose a reason for hiding this comment

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

I love the idea of having a stubbed / generic event tracker instance; maybe we can throw some errors in the functions instead for some higher visibility

Additionally, pulling this out into a separate file would help reduce some cognitive load when parsing this file

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My current plan is for the StubbedEventTracker to be used in development/testing/staging environments, so I'm hesitant to make it noisy. We can chat more though

Agree on pulling out to its own file.

}

class StubbedEventTracker implements EventTracker {
identify(_userOwnerId: string | number, _username: string): void {}
Copy link
Contributor

Choose a reason for hiding this comment

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

Having this be a string | number seems a little smelly, is there a way around this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The goal here was to make the API as easy as possible to use. Give us the id in whatever type and we'll handle it. I will look around the codebase again though, I think it may be true that it's almost always a string or almost always a number. In that case we can get rid of the union type.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea. it's pretty much always a number, will update.


export interface EventTracker {
// Identifies the user this session belongs to.
identify(userOwnerId: number | string, username: string): void
Copy link
Contributor

Choose a reason for hiding this comment

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

Personally I really like having functions utilize an object syntax for input parameters for explicit defining instead of relying on proper placement from developers

so in this case we'd have identify({userOwnerId, username}: {userOwnerId: number | string, username: string})

which would prevent a situation where someone accidentally puts the username as the first param unknowingly (since it also accepts a string)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep that's fair.

// Adding event types this way provides type safety for event properties.
// E.g., every 'Button Clicked' event must have the buttonType property.
track(
eventType: 'Button Clicked',
Copy link
Contributor

Choose a reason for hiding this comment

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

Having a central const somewhere of "EventTypes" might help with readability

@@ -26,6 +31,11 @@ function InactiveRepo({
repo: repoName,
},
}}
onClick={() =>
eventTracker(provider, owner, repoName).track('Button Clicked', {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible to instantiate the event tracker somewhere as a singleton and then call track against that instance? Currently every time we want to call track we need to create a new instance of an AmplitudeEventTracker which seems a little expensive

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea I considered this. The con of doing a singleton is that we then need some system of keeping the provider/owner/repo the instance is storing up-to-date. This could simply be done by moving those three into the track() call. Would like to talk more on this for sure

@spalmurray-codecov spalmurray-codecov force-pushed the spalmurray/event-tracker-amplitude branch 2 times, most recently from 2ba5fd3 to 6e309e5 Compare January 13, 2025 21:34
@spalmurray-codecov spalmurray-codecov force-pushed the spalmurray/event-tracker-amplitude branch from 3069c0f to b0b22ee Compare January 15, 2025 18:14
@codecov-releaser
Copy link
Contributor

codecov-releaser commented Jan 16, 2025

✅ Deploy preview for gazebo ready!

Previews expire after 1 month automatically.

Storybook

Commit Created Cloud Enterprise
755f059 Thu, 16 Jan 2025 15:18:19 GMT Expired Expired
8485dde Thu, 16 Jan 2025 22:40:58 GMT Expired Expired
fd42c85 Fri, 17 Jan 2025 20:29:12 GMT Expired Expired
6144625 Fri, 17 Jan 2025 21:42:37 GMT Expired Expired
093c894 Mon, 20 Jan 2025 17:14:45 GMT Expired Expired
16a63d2 Tue, 21 Jan 2025 22:19:59 GMT Cloud Enterprise

Copy link

codecov bot commented Jan 16, 2025

Bundle Report

Changes will increase total bundle size by 267.24kB (2.2%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
gazebo-production-system 6.19MB 133.96kB (2.21%) ⬆️
gazebo-production-esm 6.24MB 133.28kB (2.18%) ⬆️

@spalmurray-codecov spalmurray-codecov marked this pull request as ready for review January 16, 2025 22:39
@spalmurray-codecov spalmurray-codecov force-pushed the spalmurray/event-tracker-amplitude branch 2 times, most recently from fd42c85 to 6144625 Compare January 17, 2025 21:36
@nicholas-codecov nicholas-codecov self-requested a review January 20, 2025 16:31
Copy link
Contributor

@nicholas-codecov nicholas-codecov left a comment

Choose a reason for hiding this comment

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

Two small tweaks

src/services/events/hooks.tsx Outdated Show resolved Hide resolved
src/services/events/hooks.tsx Outdated Show resolved Hide resolved
@spalmurray-codecov spalmurray-codecov force-pushed the spalmurray/event-tracker-amplitude branch from 6144625 to 093c894 Compare January 20, 2025 17:08
@codecov-staging
Copy link

codecov-staging bot commented Jan 20, 2025

Bundle Report

Changes will increase total bundle size by 267.15kB (2.2%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
gazebo-staging-system 6.18MB 133.92kB (2.21%) ⬆️
gazebo-staging-esm 6.23MB 133.23kB (2.18%) ⬆️

Copy link
Contributor

@ajay-sentry ajay-sentry left a comment

Choose a reason for hiding this comment

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

S U P E R S O L I D

send it

@spalmurray-codecov spalmurray-codecov force-pushed the spalmurray/event-tracker-amplitude branch from 093c894 to 16a63d2 Compare January 21, 2025 22:14
@spalmurray-codecov spalmurray-codecov added this pull request to the merge queue Jan 22, 2025
Merged via the queue into main with commit a5dcca4 Jan 22, 2025
62 checks passed
@spalmurray-codecov spalmurray-codecov deleted the spalmurray/event-tracker-amplitude branch January 22, 2025 15:40
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.

[Gazebo] Track onboarding events
4 participants