Analytics Consolidation: Unifying Event Tracking Across Two Portals at GAF Energy
The Stakes
GAF Energy had two customer-facing portals: a Partner Portal used by roofing partners to manage leads and proposals, and a Homeowner Portal where homeowners tracked their system's energy production and consumption and received important notifications. Both portals had some level of Google Analytics tracking, but beyond that, the analytics tooling was fragmented and largely unreliable. Amplitude had been integrated into the Partner Portal at some point, but only one or two out of roughly five tracked events were firing correctly, and the data it captured was not informing any decisions. A Mixpanel account existed but had never been fully integrated into either portal. HotJar was capturing session replays, but without meaningful anomaly detection it was an expensive tool that saw almost no regular use. Four analytics tools, two portals, and no reliable data coming out of any of it.
Feature adoption, user flows, drop-off points, and engagement patterns were all based on anecdotal feedback rather than instrumented evidence. There were no guardrails around what data was being collected, and PII was flowing into analytics databases that were accessible to groups who should not have had access to it.
My Role
I was the Technical Product Manager responsible for scoping the consolidation, defining the event taxonomy, coordinating with engineering on implementation, and managing the rollout across both portals. This project required working closely with the frontend teams who owned each portal, the data team that consumed the analytics output, and the engineering leads who needed to adopt the new instrumentation patterns going forward.
Beyond the technical coordination, the harder parts of this project were in the implementation itself. With four analytics platforms in place, cleanup required carefully removing each one without breaking existing functionality, and where dashboards depended on existing data, I needed to ensure we replaced the data sources so those dashboards stayed functional. But the most difficult challenge was making sure we were not just implementing analytics but building a system that would scale and that teams would actually use after the project ended. I know from experience that if instrumentation is not built into the normal muscle of feature development and scoping, it falls behind quickly. You take one big pass through the data, but then as new features ship and nothing new is instrumented, analytics become stale. The real work was designing a system that made ongoing instrumentation intuitive enough that teams would sustain it long after I moved on. I also had to make the case that reliable analytics was a prerequisite for every other product decision we wanted to make, not a nice-to-have we could keep deferring.
The Real Problem
The surface problem was tool sprawl: too many analytics platforms, none of them working properly. But underneath that, there had never been a clear definition of what actually needed to be measured, how events should be structured, or who was responsible for data quality.
When I audited the existing setup, I found roughly 5 to 10 events being tracked across both portals, several of which were duplicates caused by misspellings of button click names and a lack of cohesive event identification. Frontend and backend teams had no shared conventions for event naming, field structure, or granularity. Documentation that did exist was outdated, which made things worse: some developers believed they had accurate event documentation, others knew it was stale, and some did not know it existed at all. The Amplitude integration in the Partner Portal had been set up during an earlier sprint and then left untouched. Mixpanel had been explored as a potential replacement but was never committed to. Without any deliberate decision to sunset tools, everything just kept running in parallel.
Midway through the project, we uncovered another significant issue. Amplitude was not consistently receiving a unique user identifier on login, so it was assigning its own session-based IDs. Every time a user started a new session, Amplitude recorded them as a new unique user. This meant our monthly unique count was roughly double our actual user base. Once we turned off Amplitude's automatic ID assignment and ensured we were passing the authenticated user ID on every login, our monthly uniques dropped by half. Since Amplitude's pricing tiers are based on tracked users, this correction alone moved us down an entire subscription tier and reduced our costs significantly.
There was also no error logging or monitoring on analytics events. We had no way to know if an event stopped firing or if volume changed unexpectedly. As part of this project, we set up monitoring so that if any event saw a daily change of 20% or more, an alert was sent to our Analytics Slack channel. For critical events like login failures and proposal downloads, we also configured alerts to the DevOps channel to ensure high visibility on the systems that mattered most.
The PII issue was the most urgent finding. Analytics events were passing user-identifiable information into databases that broader teams had access to, creating a compliance and trust risk that needed to be addressed immediately regardless of the broader consolidation effort.
Approach
The first decision was which platform to consolidate onto. The evaluation came down to Amplitude versus a fully configured Google Analytics 4 setup. Amplitude won for several reasons: it was already partially in place, its event-based model aligned better with the kinds of product questions we needed to answer, its cohort and funnel analysis tools were stronger for a product team our size, and the cost was manageable for our usage volume.
With the platform decided, the project broke into four workstreams.
Event taxonomy and schema design
I met with the product team and engineering leads to define every key event we needed to track across both portals. One of the first things I asked each person was to identify their top five absolutely critical events. Whenever I am on a project with a large scope, I prioritize understanding the 80/20: if we can only deliver one thing, which one has the most impact? This came in handy here because it meant that if we lost resources midway through the project, we already knew what to prioritize. For each event, we documented the trigger condition, the expected payload fields, the data types, and the downstream questions the event was meant to answer.
We categorized events into three types: system events, user events, and process events. System events covered code-level tracking such as function performance, backend response times, and tracing. User events captured user actions like button clicks and page views. Process events tracked multi-step workflows, for example, a roofer uploading photos that were then saved into Salesforce with a confirmation displayed back in the portal. Each event type had a boilerplate metadata template with standard fields: system events included the service name and other infrastructure-level data, user events included the user's company, name, and location. These templates meant that when a developer or product manager defined a new event, they only had to focus on what was unique to that event rather than re-specifying common fields every time. This decreased overhead significantly and made development faster.
The goal was a single shared taxonomy that both portals followed, so that cross-portal analysis (for example, tracking how a roofer's engagement in the Partner Portal correlated with homeowner activity in the Homeowner Portal) was possible from day one.
Event schema validation
Defining a taxonomy only works if it is enforced. We implemented event schema validation on a pub/sub architecture: both the frontend and backend sent events to a shared pub/sub event topic, where each event was validated against its registered schema before being ingested into the pipeline. If an event was missing required fields, had incorrect data types, or included fields outside the schema, it would be flagged and rejected. This also meant that if someone on another team inadvertently broke an event you depended on, the validation layer caught it. This was the mechanism that turned our analytics from data we hoped was right into data we could trust.
PII remediation
We audited every event payload and data flow to identify where PII was being passed into analytics databases. All PII fields were tagged with a PII type, and each type was associated with a set of rules defined in the event schema. These rules controlled which fields could be validated and ingested into which databases, ensuring that sensitive data was routed appropriately rather than flowing freely into broadly accessible stores. This ran in parallel with the broader consolidation work because the compliance risk could not wait for the full project to complete.
Tool sunset and developer patterns
We formally sunset Mixpanel and HotJar, removing their scripts from both portals and decommissioning the accounts. For the engineering teams, I documented the new instrumentation patterns: how to add a new event, how to validate it against the schema, how to test it locally, and how to verify it was flowing correctly in production. The goal was to make the right way to instrument events also the easiest way, so that the patterns would stick after the project ended.
Results
| Metric | Before | After |
|---|---|---|
| Analytics tools in use | 4 (GA, Amplitude, Mixpanel, HotJar) | 1 (Amplitude) |
| Tracked key events | ~5-10 (partially duplicated, misconfigured) | ~120 validated events with monitoring |
| Event schema validation | None | 100% of events validated via pub/sub |
| Event monitoring | None | Automated alerts on 20%+ daily change for critical events |
| PII in analytics databases | Present and uncontrolled | Tagged, governed by PII-type rules in event schema |
| Cross-portal analysis capability | Not possible | Unified taxonomy in place |
| Developer instrumentation documentation | Outdated and inconsistent | Full event catalog, templates, and patterns |
| Amplitude subscription cost | Higher tier (inflated unique count) | Reduced by one full tier after correcting user ID assignment |
The most important outcome was not any single metric but the fact that the product team could now make decisions grounded in real data. Before this project, every product discussion about user behavior was based on what account managers heard from roofers or what engineers noticed anecdotally. After, we had actual funnel data, adoption metrics, and engagement patterns. Feature prioritization conversations changed because we could point to what users were actually doing rather than what we assumed they were doing.
To make sure the data was actually used, I set up a product dashboard highlighting critical metrics and created individual dashboards for each major product team with their key events. I ran video training sessions for product managers, held one-on-one walkthroughs, and offered office hours to ensure they knew how to use the data and would incorporate analytics into their product briefs going forward. On the developer side, we included full documentation so that when a product manager asked their team to track something new, engineers had a clear and easy path to implement it.
The developer patterns proved durable. When new features were built in the months that followed, the engineering teams instrumented events using the documented patterns without needing to be reminded. That was the signal that the work had stuck.
What I'd Do Differently
I would have pushed harder to implement automated alerting on schema violations from the start. We had validation in place, but the feedback loop for developers was manual: they had to check whether their events passed validation rather than being notified automatically when something broke. Adding automated alerts in CI or in the pipeline itself would have caught issues faster and reinforced the patterns more effectively.
I also would have formalized the event taxonomy governance process earlier. We built the initial taxonomy as a focused effort, but as new features shipped, keeping it current required ongoing attention. A lightweight process like a standing agenda item in sprint planning, ensuring new events were properly defined and documented before the code was written, would have prevented the taxonomy from drifting. The training and dashboards helped product managers engage with the data, but pairing that with a more structured intake process for new events would have made the system even more self-sustaining.
So What
This project taught me that data infrastructure is platform work. The same principles that apply to API governance apply to analytics governance: define contracts, validate them, document the patterns, and make compliance easier than non-compliance. The event taxonomy we built here directly informed the event schema validation work I later did at the API gateway level during the API standardization project. The pattern repeated because it works: when you treat data quality as a platform concern rather than an afterthought, everything downstream gets better.