Update test structure for new role - #5
Conversation
There was a problem hiding this comment.
Pull request overview
Reworks the exercise around onboarding Meridian Live into the existing dbt platform.
Changes:
- Adds Meridian source fixtures, FX rates, and ingestion support.
- Adds the existing TTG staging, intermediate, and mart baseline.
- Documents the revised architecture-focused exercise.
Reviewed changes
Copilot reviewed 26 out of 31 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
README.md |
Defines the Meridian onboarding exercise. |
scripts/load_initial_source_data.py |
Loads Meridian source tables. |
scripts/ingest.py |
Ingests incremental Meridian data. |
dbt/seeds/fx_rates.csv |
Provides currency conversion rates. |
dbt/seeds/.gitkeep |
Seed-directory placeholder. |
dbt/models/sources.yml |
Declares TTG and Meridian sources. |
dbt/models/staging/stg_accounts.sql |
Adds account staging baseline. |
dbt/models/staging/stg_events.sql |
Adds event staging baseline. |
dbt/models/staging/stg_showtimes.sql |
Adds showtime staging baseline. |
dbt/models/staging/stg_orders.sql |
Adds order staging baseline. |
dbt/models/staging/stg_transactions.sql |
Adds transaction staging baseline. |
dbt/models/staging/stg_pages.sql |
Adds normalized page staging. |
dbt/models/staging/stg_identity_merges.sql |
Adds identity-merge staging. |
dbt/models/staging/.gitkeep |
Directory placeholder. |
dbt/models/staging/.gitkeep_meridian |
Meridian work placeholder. |
dbt/models/intermediate/int_pages_identity_resolved.sql |
Adds TTG identity resolution. |
dbt/models/intermediate/.gitkeep_meridian |
Meridian work placeholder. |
dbt/models/mart/dim_customers.sql |
Adds customer dimension baseline. |
dbt/models/mart/dim_events.sql |
Adds event dimension baseline. |
dbt/models/mart/fct_transactions.sql |
Adds certified transaction fact baseline. |
dbt/models/mart/.gitkeep_meridian |
Meridian work placeholder. |
data/initial/meridian_customers.csv |
Supplies customer fixtures. |
data/initial/meridian_venues.csv |
Supplies venue fixtures. |
data/initial/meridian_events.csv |
Supplies event fixtures. |
data/initial/meridian_performances.csv |
Supplies performance fixtures. |
data/initial/meridian_orders.csv |
Supplies order fixtures. |
data/initial/meridian_order_items.csv |
Supplies line-item fixtures. |
data/initial/meridian_web_sessions.csv |
Supplies web-session fixtures. |
data/incremental/meridian_orders/batch_001.csv |
Adds incremental orders. |
data/incremental/meridian_order_items/batch_001.csv |
Adds incremental line items. |
data/incremental/meridian_web_sessions/batch_001.csv |
Adds incremental sessions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Three brands land page tracking in their own wl_<brand> schemas, plus one pre-standard source that keeps its bespoke model. stg_pages unions them by hand today, so onboarding a brand costs a pull request. bin/add-partner creates a new brand schema in the warehouse mid-session, which is how the candidate's solution gets tested.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 40 out of 44 changed files in this pull request and generated no new comments.
Suppressed comments (2)
scripts/whitelabel_sources.py:33
create_relationis relation-scoped by name, but it drops the entire schema. Loading two CSVs for one brand—or runningbin/add-partner sandboxagainst the includedwl_sandbox.sessionsfixture—deletes the brand's other relations. Recreate only the requested table so unrelated warehouse data survives.
README.md:20- This sentence says the listed certified models need not change immediately after proposing that candidates extend those same models. That gives conflicting acceptance criteria for whether Meridian must appear in the existing marts; state explicitly that candidates may change the relevant marts while preserving their contracts.
- **Challenge 1 builds:** the staging → intermediate → mart path for Meridian's raw tables, converging into the existing marts (extending `fct_transactions`/`dim_customers`/`dim_events`, adding new models, or some combination — your call, but be explicit about why) so Meridian's activity shows up alongside TodayTix's in a way stakeholders and downstream consumers can trust. Nothing in the list above needs to change for this.
The intermediate and mart models were a template: they told the candidate what to build and left them filling in blanks. Same for the whitelabel base models and their source declarations — the union was already designed. Only the staging models over raw remain. The brand schemas load into the warehouse undeclared and unread, and what sits above staging is the candidate's design.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 32 out of 36 changed files in this pull request and generated no new comments.
Suppressed comments (2)
scripts/whitelabel_sources.py:33
create_relationdrops the entire schema for every CSV. Consequently, ifdata/whitelabel/ever contains two relations for one brand (the module explicitly supports<schema>__<table>.csvfiles), loading the second file deletes the first relation. Recreate only the target table while preserving other relations in the schema.
dbt/models/sources.yml:14- This says the TodayTix sources are already modeled through intermediate and mart, but this PR intentionally leaves those layers empty and README.md:19-20 states that only staging exists. Update the comment so candidates are not given contradictory project-state guidance.
# ---- Existing TodayTix (TTG) platform — already modeled in staging/intermediate/mart ----
The grain bullet named TTG's transaction grain and Meridian's order grain without saying how the two relate, which read as if a Meridian order were a TTG transaction. It now describes both shapes — TTG splitting checkout from payment, Meridian carrying the money on the order row with line items underneath — and points at the tables to compare. Choosing which challenge to run is the candidate's call, not the interviewer's.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 32 out of 36 changed files in this pull request and generated no new comments.
Suppressed comments (3)
scripts/whitelabel_sources.py:33
- This helper drops the entire brand schema when recreating one relation. Because
load_dirsupports one CSV per relation, adding a second CSV for the same brand will cause the later file to erase the relation loaded from the earlier file;add-partnercan likewise delete unrelated relations already present in that brand schema. Create the schema if needed and replace only the target table.
data/initial/meridian_performances.csv:8 mp_7andmp_8are performances of the same Bath event one week apart in February 2025, when the UK was UTC+0 throughout. Giving onlymp_7a +60-minute offset makes its normalized instant one hour early and introduces a DST change that did not occur.
mp_7,me_comedy_night,2025-02-01 20:30:00,60,2025-02-01 19:45:00
dbt/models/sources.yml:14
- This says the existing platform is already modeled through intermediate and mart layers, but this PR intentionally leaves both layers empty and the README states that only staging is built. The source documentation should not tell candidates that those higher layers already exist.
# ---- Existing TodayTix (TTG) platform — already modeled in staging/intermediate/mart ----
create_relation dropped the whole brand schema before recreating the target table, so loading a second relation for a brand — or rerunning add-partner against a brand that already has one — silently removed the sibling. It now creates the schema if absent and replaces only the named table; init.sh still drops the brand schemas wholesale between runs. Also corrects mp_7's UTC offset: the Bath venue was on GMT that February, and the same event a week later already carried 0. And the raw sources header no longer claims TodayTix is modeled through intermediate and mart, which the project deliberately leaves empty.
The exercise now carries two challenges, and which one a candidate runs is theirs to pick — the interviewer hands over a project, not a task. The project ships with a staging layer over
rawand nothing above it — no intermediate models, no marts, no whitelabel models. What the platform should expose, at what grain, under what names, is the candidate's call.Challenge 1 — onboard Meridian Live. A MARI portfolio ticketing company lands in
rawwith multi-currency formatted amounts, order-level grain against TodayTix's payment-level grain, naive local timestamps plus an offset, and no identity merge log. Modeling judgment against messy source data. The grain bullet describes both shapes rather than naming them — TodayTix splitting checkout from payment, Meridian carrying the money on the order row with line items underneath — because naming them alone read as if a Meridian order simply were a transaction.Challenge 2 — whitelabel storefronts that onboard themselves. Brands write page tracking into their own
wl_<brand>schemas in the warehouse. They aren't declared insources.ymland nothing reads them. The candidate builds the page-load path — and the question is whether they build the version that costs a pull request per brand launch or the version that doesn't. This is the exercise version ofpage_loads_pxt_schemas/page_loads_pxt_legin analytics-models.The sources are built so that "add a name to a list" can't pass:
wl_arcadia.pageswl_northgate.pagesshowtime_idandutm_*don't exist on the tablewl_lumen.pageswl_sandbox.sessionspagesrelation — discovery has to filter on relation name toopartner_orpheum.page_viewsA brand missing columns and a brand with extra columns break
select *in both directions, so each leg has to be rendered from the brand's actual column set.How it's graded live.
bin/add-partner <brand>creates a newwl_*schema directly in the warehouse — nothing lands in the repo. The interviewer runs it mid-session against the candidate's untouched working tree, thenbin/dbt build.Verified.
./scripts/init.shbuilds the 7 staging models clean and loads all five brand schemas unread. With a reference solution applied:bin/add-partner zephyr(reduced columns) andbin/add-partner halloway --fullboth appear after a plainbin/dbt build, with absent columns null-filled rather than erroring;bin/add-partner zephyr --dropremoves it again;wl_sandboxstays out../scripts/reset.shdrops brands added mid-session, so the exercise resets between candidates.Loader fix. Recreating one relation dropped the whole brand schema, so a brand with two relations lost the first one and rerunning
add-partnercould wipe siblings. It now creates the schema if absent and replaces only the named table — confirmed by adding a table towl_arcadia, rerunningbin/add-partner arcadia, and seeing both relations with their rows intact.mp_7also carried a +60 offset for a Bath venue in February, when the UK was on GMT and the same event a week later already read 0.Rejected alternative. A manifest file of brand slugs in the repo would have been simpler to build and to grade, but it leaves the pull request in place — which is the whole problem the candidate is meant to see.
Rubric and reference solution live in the private ttg repo at
_private/drafts/tt-data-exercise-challenge-2-rubric.md, not in this one.🤖 This was posted by Claude