feat(#2075): migrate marts__combined_course_enrollment_detail to dimensional models#2314
Open
quazi-h wants to merge 6 commits into
Open
feat(#2075): migrate marts__combined_course_enrollment_detail to dimensional models#2314quazi-h wants to merge 6 commits into
quazi-h wants to merge 6 commits into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR migrates the marts__combined_course_enrollment_detail mart from a set of per-platform intermediate “combined” models to a dimensional-layer join strategy centered on tfact_enrollment, dim_course_run, dim_course, dim_user, and tfact_grade, while retaining intermediate ecommerce/certificate CTEs where dimensional equivalents don’t yet exist.
Changes:
- Replaces the prior 6-way per-platform
UNION ALLpattern with a single flattened query joining dimensional facts/dims byuser_fk+courserun_fk. - Reworks certificate and ecommerce order enrichment joins, including a supplemental MITxPro enrollment→order bridge CTE.
- Switches grade sourcing to
tfact_gradeusing the dimensional grain (user_fk,courserun_fk).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This was referenced Jul 8, 2026
blarghmatey
pushed a commit
that referenced
this pull request
Jul 16, 2026
- Add emeritus_enrollments/global_alumni_enrollments CTEs sourced from stg__emeritus__api__bigquery__user_enrollments / stg__global_alumni__api__bigquery__user_enrollments (the same staging models dim_user already uses for its emeritus_user_id/global_alumni_user_id columns), following the existing per-platform CTE pattern. - Add mitxpro_external_readable_id_lookup CTE (sourced from int__mitxpro__course_runs) to resolve these platforms' course run FK: Emeritus/Global Alumni don't own course run records, so their enrollments map onto existing MITxPro course runs via courserun_external_readable_id, mirroring the join logic previously used in int__combined__courserun_enrollments. - Extend user_lookup to select emeritus_user_id/global_alumni_user_id from dim_user (already present there) and thread through the user_fk coalesce chain. - Add dim_course_run_mitxpro CTE + join to resolve courserun_fk for these two platforms against MITxPro-platform dim_course_run rows. - enrollment_is_edx_enrolled is null for both (same treatment as program/bootcamps enrollments). Prerequisite for #2075/PR #2314 (migrate marts__combined_course_enrollment_detail to the dimensional layer): without this, sourcing that mart exclusively from tfact_enrollment would silently drop all Emeritus/Global Alumni enrollment rows. Closes #2405 Requires a --full-refresh of tfact_enrollment after deploy to backfill historical Emeritus/Global Alumni enrollment rows (incremental_strategy is delete+insert, so new CTEs alone only capture new activity going forward). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…nsional models - Add courserun_upgrade_deadline to dim_course_run (MITxOnline only; null for other platforms) - Add enrollment_is_edx_enrolled to tfact_enrollment (per-platform: true for edxorg/residential, from source field for mitxonline/mitxpro, null for program/bootcamps) - Rewrite marts__combined_course_enrollment_detail to source from dimensional layer: - tfact_enrollment + dim_course_run + dim_course + dim_user replace 6-way UNION ALL - Grade data from tfact_grade (joined on user_fk + courserun_fk) - Certificate join uses user_email (from dim_user) as cross-table key - edX.org MITxOnline certificate cross-lookup uses dim_user.user_mitxonline_username - Bootcamps order join changed from username-based to user_id-based - MITxPro order join bridged via supplemental ecommerce_order_id CTE - edX.org MicroMasters order join uses dim_user.micromasters_user_id - All 38 output columns preserved and verified via systematic diff Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ment_detail - course_readable_id: fall back to extract_course_readable_id(courserun_readable_id) instead of the raw courserun_readable_id (a course-run id, not a course id) when dim_course doesn't join, matching int__combined__course_runs' existing logic. - Add bootcamps_users CTE (joined on dim_user.bootcamps_application_user_id) since dim_user doesn't expose a bootcamps username attribute; restores user_username for Bootcamps enrollments (previously always NULL, a regression vs the prior mart). - user_username: add a Residential branch (dim_user.user_residential_username), previously NULL despite dim_user exposing this value (also a regression). - Certificate join: match on the platform-specific username (mitxonline/edxorg/ mitxpro/bootcamps) instead of dim_user.email, restoring the pre-migration int__combined__courserun_enrollments join semantics. dim_user.email is a deduped/canonicalized value and can silently miss platform-specific cert records. - micromasters_completed_orders: fix row_number() dedup partition to match the actual join key (courserun_edxorg_readable_id) instead of the MicroMasters-native courserun_readable_id, a different id namespace -- the mismatch could drop valid orders by assigning row_num=1 within the wrong partition. Verified with dbt compile (clean) and sqlfluff-lint/-fix (no changes needed). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The prior fix added a Residential branch to the user_username case expression referencing users.user_residential_username, but the users CTE never selected that column from dim_user, causing a COLUMN_NOT_FOUND compile failure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ate fan-out int__bootcamps__users joins profiles_legaladdress without dedup, so it can return multiple rows per user_id. Since only user_username is selected (invariant per user_id, sourced from the users table not legaladdress), switching to select distinct prevents duplicate rows downstream without needing a tie-breaker. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The combined_certificates join's platform-specific username CASE expression omitted the Residential platform, making courseruncertificate_* fields always NULL for Residential enrollments even when dim_user.user_residential_username is available and certificates exist. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…e_enrollment_detail mitxonline_certificates selected from int__mitxonline__courserun_certificates without filtering revoked certs. Since the edX.org cross-lookup coalesces mitxonline_certificates.courseruncertificate_* fields, a revoked cert could still populate URL/UUID/timestamps even when courseruncertificate_is_earned is false, and could fan out rows if multiple certificate records exist. Filter to non-revoked to match int__combined__courserun_certificates.
blarghmatey
force-pushed
the
copilot/2075-migrate-combined-course-enrollment-detail
branch
from
July 16, 2026 14:33
851f46f to
0340b5c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What are the relevant tickets?
Closes #2075 (mart migration — depends on prerequisite PR #2317)
Description (What does it do?)
Migrates
marts__combined_course_enrollment_detailfrom intermediate combined models (int__combined__courserun_enrollments,int__combined__course_runs,int__combined__users) to the dimensional layer.The 6-way per-platform UNION ALL is replaced by a single flat query joining dimensional models:
tfact_enrollment(filtered toenrollment_type = 'course') — enrollment base +enrollment_is_edx_enrolled(added in feat(#2075): add courserun_upgrade_deadline to dim_course_run and enrollment_is_edx_enrolled to tfact_enrollment #2317)dim_course_run(filtered tois_current = true) — course run attributes +courserun_upgrade_deadline(added in feat(#2075): add courserun_upgrade_deadline to dim_course_run and enrollment_is_edx_enrolled to tfact_enrollment #2317)dim_course—course_titleandcourse_readable_id(viadim_course_run.course_fk)dim_user— user demographics and all platform-specific user IDs/usernamestfact_grade— grade data joined onuser_fk + courserun_fkint__combined__courserun_certificates— certificate data (ecommerce order CTEs retained from int__ models)Notable join strategy decisions:
user_username(fromdim_user, or the dedupedbootcamps_usersCTE for Bootcamps) as the join key, restoring the pre-migrationint__combined__courserun_enrollmentssemantics.user_emailondim_useris a deduped/canonicalized value and can silently miss platform-specific certificate records, so it is only used as a secondary match for the edX.org MITxOnline certificate cross-lookup (alongsideuser_mitxonline_username).int__micromasters__usersCTE; now usesdim_user.user_mitxonline_usernamedirectly, eliminating that CTE.dim_user.micromasters_user_idreplacing themicromasters_usersCTE user_id lookup.user_username-based touser_id-based (dim_user.bootcamps_application_user_id = bootcamps_completed_orders.order_purchaser_user_id), since Bootcamps username is not indim_user.mitxpro_enrollment_ordersCTE sourcingecommerce_order_idfromint__mitxpro__courserunenrollments(not yet intfact_enrollment).tfact_gradejoined onuser_fk + courserun_fk— clean dimensional join, no per-platform grade CTEs needed.All 38 output columns preserved and verified via systematic diff against the original final SELECT.
How can this be tested?
Prerequisite: #2317 must be deployed first (with
--full-refreshon both dimensional models).Additional Context
Deployment order (no breaking change if followed):
dim_course_run --full-refreshandtfact_enrollment --full-refreshmarts__combined_course_enrollment_detailnormally (no full-refresh needed)Downstream consumers (dashboards, reports) using
courserun_upgrade_deadlineorcourserunenrollment_is_edx_enrolledwill see no regression as long as step 1 completes before step 3.