Skip to content

Ritam/unified tracking#1132

Open
ritamzico wants to merge 18 commits into
mainfrom
ritam/unified-tracking
Open

Ritam/unified tracking#1132
ritamzico wants to merge 18 commits into
mainfrom
ritam/unified-tracking

Conversation

@ritamzico
Copy link
Copy Markdown
Contributor

@ritamzico ritamzico commented Apr 13, 2026

Problem

Two problems with old tracking:

  1. Fragmented models. Click events, banner views, and
    class views each had their own model (ClickEvent,
    BannerViewCount, ClassViewCount) with incompatible
    schemas. Adding a new event type meant a new model, new
    resolver, new migration. No shared query surface across
    event types.

  2. No frontend batching. Every tracking call fired its
    own network request immediately. High-traffic pages (catalog
    search, class view) hammered the backend with individual
    mutations.

Solution

Single TrackingEvent model with open string enums
(eventType, targetType) and a flexible metadata: JSON
field. Any team can add new event types without schema
changes.

Frontend useTracking hook queues events client-side and
flushes in one trackEvents mutation — either every 5
seconds or when 50 events accumulate, whichever comes first.
Server enriches each event with sessionId, ipHash,
userAgent, and referrer so clients send only what they
know.

What changed

Backend

  • New TrackingEvent Mongoose model with indexes on
    [eventType, targetType, timestamp], [targetId, timestamp], [sessionId, timestamp], and [userId, timestamp]
  • trackEvents GraphQL mutation — accepts up to 50 events
    per call, buffers to Redis, flushed to MongoDB every 5
    minutes
  • trackingEventsTimeSeries staff-only query for analytics
  • Dual-emit on all server-side redirect routes
    (/banner/click/:id, /go/*path, /message/click/:id) —
    old counters preserved, new model always written

Frontend

  • useTracking hook with client-side batching
    (trackClick, trackView, trackDismiss, trackSearch,
    trackSearchClick)
  • Search tracking added to CourseSearch — debounced 1s,
    captures query + result count + which result was clicked
  • Banner view/dismiss and class view now emit to
    TrackingEvent alongside existing tracking
  • Staff analytics (OutreachAnalytics) reads from
    TrackingEvent via trackingEventsTimeSeries

Migration

  • apps/backend/src/scripts/migrate-click-events.ts
    backfills all historical ClickEvent records into
    TrackingEvent. Safe to re-run (ignores duplicate key
    errors)

What's preserved

Old clickCount/viewCount/dismissCount counters on
banners, redirects, and targeted messages are untouched. Old
ClickEvent writes still happen when clickEventLogging
is enabled on a resource. No data is deleted.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b066c49899

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/backend/src/scripts/migrate-click-events.ts
Comment thread apps/backend/src/modules/tracking/controller.ts Outdated
Comment thread apps/backend/src/modules/tracking/controller.ts Outdated
@ritamzico
Copy link
Copy Markdown
Contributor Author

I will create another PR after getting rid of the ClickEvent model and other such tracking infrastructure. The migration needs to be run on production first before doing that, so that steps needs to be separate.

@ritamzico ritamzico requested review from ARtheboss and PineND April 13, 2026 21:00
Comment thread apps/frontend/src/hooks/api/tracking/useTracking.ts Outdated
Comment thread apps/backend/src/modules/tracking/controller.ts Outdated
Comment thread apps/backend/src/modules/tracking/jobs/flush-tracking-events.ts Outdated
Comment thread apps/backend/src/modules/tracking/jobs/flush-tracking-events.ts
Comment thread apps/frontend/src/components/RootWrapper/index.tsx
Comment thread apps/frontend/src/hooks/api/tracking/useTracking.ts Outdated
Comment thread apps/backend/src/modules/tracking/resolver.ts
@LehuyH
Copy link
Copy Markdown

LehuyH commented Apr 28, 2026

LGTM!

@ritamzico
Copy link
Copy Markdown
Contributor Author

@PineND lmk if it looks good now

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.

3 participants