Deuex · Client · 2022—25

Uber Databook

Internal Data Insights Platform

React TypeScript GraphQL Apollo Playwright

Databook is the internal data catalog and insights platform Uber's engineering org uses to discover, trust, and query internal datasets. As frontend and UI/UX owner across a three-year engagement, I shipped features spanning an analytics platform migration, cache reliability, and self-serve schema tooling for a platform 1,000+ engineers use daily.

Zero
Reporting continuity gaps through the GA4 cutover
1,000+
Engineers using Databook daily
01 Analytics

Migrating tracking from Universal Analytics to GA4

When Google mandated the shift from Universal Analytics to GA4, I led the migration for Databook end to end. The two platforms don't share a data model — UA tracked interactions through a flat category/action/label structure, while GA4 is built entirely around events and parameters — so existing tracking couldn't be ported over as-is. I went through the tracking event by event, deciding how each UA hit should be represented in GA4's event/parameter structure, and rebuilt it accordingly.

Universal Analytics (before)
User taps "Add to cart"
tracked as a flat hit
category: 'Ecommerce' · action: 'Add to Cart'
segmented later using UA Views
No native event/parameter model
GA4 (after)
User taps "Add to cart"
tracked as a structured event
event: 'add_to_cart' · params: { item_id }
segmented using GA4 Data Filters
Structured, queryable event model

The harder problem was structural, not mechanical: GA4 doesn't have "views," which is how UA had handled filtering and segmenting data for different teams. I worked out how to replicate that functionality using GA4's data filters, and made sure the migration didn't break continuity with the historical data teams already relied on for reporting.

Alongside the migration itself, I wrote the reference documentation the team uses to understand the new setup — the full event mapping, the views-to-filters approach, and the reasoning behind each decision, including how to set up the GA4 equivalent of views. It's still the doc people go to when they need to work with the new tracking.

02 Reliability

Fixing a stale-data bug at its root

Rows kept reverting to stale values after a save. Chasing it past the network and the resolvers, I traced it to Apollo's cache identity: dynamically generated row IDs meant every backend update looked like a brand-new object to the client cache. Switching to a static, content-derived ID let Apollo match and merge updates against the existing entity instead of shadowing it.

Dynamic ID (the bug)
Backend sends an update
record gets a new dynamic ID
tag:row12:x7f2q9 → tag:row12:m8k1p3
Apollo cache treats it as a new object
UI keeps showing stale data
Static ID (the fix)
Backend sends an update
record keeps its stable ID
tag:row12:INV-2049 → tag:row12:INV-2049
Apollo cache matches the existing entity
UI updates correctly
03 Tooling

A schema builder that speaks the data model

Adding a governed field to a dataset meant filing a ticket and waiting. I built a self-serve field composer that lets owners construct nested types — arrays, structs, and primitives — with a live type preview, so a request that took days now takes a minute.

Add Field
user_attributes
Type Preview: Array<Struct<string, string>>
Field type
Array
Value type · Array element
Struct
Key · Struct
string fixed
Value type · Struct
string
string
int
boolean
struct
array
Cancel
Add Field
Additional contributions
  • Worked across three teams over the engagement, but spent most of the time on Databook.
  • Largely focused on adding new frontend functionality and owning entire new pages or features end to end — including the personalised chats section on datasets, the Schema Builder, and the Ownership Hierarchy page, among others.
  • Reduced landing-page load time from ~12s to 3s through query optimisation and more efficient data handling.