From 23fadefff4d87f2a4f8c7a62d4ee332f9df3c1ba Mon Sep 17 00:00:00 2001 From: Quazi Date: Tue, 17 Feb 2026 12:13:26 -0500 Subject: [PATCH 01/13] Add page_engagement_views_report - Create reporting model joining afact_course_page_engagement with course content hierarchy and user data - Join dim_course_content for unit, subsection, and section titles and indexes - Join dim_user for user email and full name - Join int__combined__course_runs for course title - Add full documentation and tests to _reporting__models.yml - Replaces Superset virtual dataset with physical table --- .../models/reporting/_reporting__models.yml | 39 +++++++++++++ .../page_engagement_views_report.sql | 57 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 src/ol_dbt/models/reporting/page_engagement_views_report.sql diff --git a/src/ol_dbt/models/reporting/_reporting__models.yml b/src/ol_dbt/models/reporting/_reporting__models.yml index 4a89b1ba5..224e39d47 100644 --- a/src/ol_dbt/models/reporting/_reporting__models.yml +++ b/src/ol_dbt/models/reporting/_reporting__models.yml @@ -768,3 +768,42 @@ models: - dbt_expectations.expect_compound_columns_to_be_unique: column_list: ["user_email", "platform", "courserun_readable_id", "course_title", "section_title", "section_block_index"] + +- name: page_engagement_views_report + description: Page engagement report showing user activity at the unit, subsection, + and section level across course runs. Joins page engagement facts with course + content hierarchy and user information. + columns: + - name: user_email + description: string, email address of the user + tests: + - not_null + - name: full_name + description: string, full name of the user + - name: platform + description: string, name of the platform + tests: + - not_null + - name: courserun_readable_id + description: string, unique identifier for the course run formatted as course-v1:{org}+{course + code}+{run_tag} + tests: + - not_null + - name: num_of_views + description: int, number of times the user viewed this page unit + tests: + - not_null + - name: unit_title + description: string, title of the vertical (unit) block within the course + - name: subsection_title + description: string, title of the sequential (subsection) block within the course + - name: subsection_block_index + description: int, sequence number giving the order in which this subsection appears + within the section + - name: section_title + description: string, title of the chapter (section) block within the course + - name: section_block_index + description: int, sequence number giving the order in which this section appears + within the course + - name: course_title + description: string, title of the course run diff --git a/src/ol_dbt/models/reporting/page_engagement_views_report.sql b/src/ol_dbt/models/reporting/page_engagement_views_report.sql new file mode 100644 index 000000000..e3e549533 --- /dev/null +++ b/src/ol_dbt/models/reporting/page_engagement_views_report.sql @@ -0,0 +1,57 @@ +with page_engagement as ( + select * from {{ ref('afact_course_page_engagement') }} +) + +, dim_user as ( + select * from {{ ref('dim_user') }} +) + +, course_runs as ( + select + course_title + , courserun_readable_id + from {{ ref('int__combined__course_runs') }} + group by + course_title + , courserun_readable_id +) + +, unit_blocks as ( + select * from {{ ref('dim_course_content') }} + where block_category = 'vertical' + and is_latest = true +) + +, subsection_blocks as ( + select * from {{ ref('dim_course_content') }} + where is_latest = true +) + +, section_blocks as ( + select * from {{ ref('dim_course_content') }} + where is_latest = true +) + +select + dim_user.email as user_email + , dim_user.full_name + , page_engagement.platform + , page_engagement.courserun_readable_id + , page_engagement.num_of_views + , unit_blocks.block_title as unit_title + , subsection_blocks.block_title as subsection_title + , subsection_blocks.block_index as subsection_block_index + , section_blocks.block_title as section_title + , section_blocks.block_index as section_block_index + , course_runs.course_title +from page_engagement +inner join unit_blocks + on page_engagement.block_fk = unit_blocks.block_id +inner join subsection_blocks + on page_engagement.sequential_block_fk = subsection_blocks.block_id +inner join section_blocks + on page_engagement.chapter_block_fk = section_blocks.block_id +inner join dim_user + on page_engagement.openedx_user_id = dim_user.mitxonline_openedx_user_id +left join course_runs + on page_engagement.courserun_readable_id = course_runs.courserun_readable_id From 6e549db485f3c585fb663c999b3acdece8a4ec5f Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Fri, 20 Feb 2026 14:28:30 -0500 Subject: [PATCH 02/13] Fix page_engagement_views_report: platform joins, block_category filters, and uniqueness test (#1921) * Initial plan * Apply review feedback to page_engagement_views_report - Remove unnecessary GROUP BY from course_runs CTE - Add block_category filters to subsection_blocks (sequential) and section_blocks (chapter) CTEs - Fix dim_user join to use platform-conditional logic for all platforms - Add compound uniqueness test on [user_email, courserun_readable_id, unit_title] Co-authored-by: quazi-h <59845076+quazi-h@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: quazi-h <59845076+quazi-h@users.noreply.github.com> --- .../models/reporting/_reporting__models.yml | 3 +++ .../reporting/page_engagement_views_report.sql | 16 ++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/ol_dbt/models/reporting/_reporting__models.yml b/src/ol_dbt/models/reporting/_reporting__models.yml index 224e39d47..871344796 100644 --- a/src/ol_dbt/models/reporting/_reporting__models.yml +++ b/src/ol_dbt/models/reporting/_reporting__models.yml @@ -807,3 +807,6 @@ models: within the course - name: course_title description: string, title of the course run + tests: + - dbt_expectations.expect_compound_columns_to_be_unique: + column_list: ["user_email", "courserun_readable_id", "unit_title"] diff --git a/src/ol_dbt/models/reporting/page_engagement_views_report.sql b/src/ol_dbt/models/reporting/page_engagement_views_report.sql index e3e549533..c528831eb 100644 --- a/src/ol_dbt/models/reporting/page_engagement_views_report.sql +++ b/src/ol_dbt/models/reporting/page_engagement_views_report.sql @@ -11,9 +11,6 @@ with page_engagement as ( course_title , courserun_readable_id from {{ ref('int__combined__course_runs') }} - group by - course_title - , courserun_readable_id ) , unit_blocks as ( @@ -25,11 +22,13 @@ with page_engagement as ( , subsection_blocks as ( select * from {{ ref('dim_course_content') }} where is_latest = true + and block_category = 'sequential' ) , section_blocks as ( select * from {{ ref('dim_course_content') }} where is_latest = true + and block_category = 'chapter' ) select @@ -52,6 +51,15 @@ inner join subsection_blocks inner join section_blocks on page_engagement.chapter_block_fk = section_blocks.block_id inner join dim_user - on page_engagement.openedx_user_id = dim_user.mitxonline_openedx_user_id + on ( + (page_engagement.platform = 'mitxonline' + and page_engagement.openedx_user_id = dim_user.mitxonline_openedx_user_id) + or (page_engagement.platform = 'edxorg' + and page_engagement.openedx_user_id = dim_user.edxorg_openedx_user_id) + or (page_engagement.platform = 'mitxpro' + and page_engagement.openedx_user_id = dim_user.mitxpro_openedx_user_id) + or (page_engagement.platform = 'residential' + and page_engagement.openedx_user_id = dim_user.residential_openedx_user_id) + ) left join course_runs on page_engagement.courserun_readable_id = course_runs.courserun_readable_id From 5d2bf86ad97f1b98ac86c04e75d6afc4247d3940 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Fri, 20 Feb 2026 15:38:29 -0500 Subject: [PATCH 03/13] Initial plan (#1923) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> From 2fbc92b4d18b02828bb9f6b1e928ab5fbd79edd6 Mon Sep 17 00:00:00 2001 From: Quazi <59845076+quazi-h@users.noreply.github.com> Date: Fri, 27 Feb 2026 12:55:05 -0500 Subject: [PATCH 04/13] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/ol_dbt/models/reporting/_reporting__models.yml | 3 +++ src/ol_dbt/models/reporting/page_engagement_views_report.sql | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/ol_dbt/models/reporting/_reporting__models.yml b/src/ol_dbt/models/reporting/_reporting__models.yml index 871344796..84740e69c 100644 --- a/src/ol_dbt/models/reporting/_reporting__models.yml +++ b/src/ol_dbt/models/reporting/_reporting__models.yml @@ -810,3 +810,6 @@ models: tests: - dbt_expectations.expect_compound_columns_to_be_unique: column_list: ["user_email", "courserun_readable_id", "unit_title"] + tests: + - dbt_expectations.expect_compound_columns_to_be_unique: + column_list: ["user_email", "courserun_readable_id", "unit_title"] diff --git a/src/ol_dbt/models/reporting/page_engagement_views_report.sql b/src/ol_dbt/models/reporting/page_engagement_views_report.sql index c528831eb..6c319de3a 100644 --- a/src/ol_dbt/models/reporting/page_engagement_views_report.sql +++ b/src/ol_dbt/models/reporting/page_engagement_views_report.sql @@ -22,6 +22,7 @@ with page_engagement as ( , subsection_blocks as ( select * from {{ ref('dim_course_content') }} where is_latest = true + where is_latest = true and block_category = 'sequential' ) @@ -29,6 +30,7 @@ with page_engagement as ( select * from {{ ref('dim_course_content') }} where is_latest = true and block_category = 'chapter' + and block_category = 'chapter' ) select From 990d5f2351d971f95257ec9aa057945e2f36a386 Mon Sep 17 00:00:00 2001 From: Quazi <59845076+quazi-h@users.noreply.github.com> Date: Fri, 27 Feb 2026 13:48:29 -0500 Subject: [PATCH 05/13] Apply suggestions from code review Co-authored-by: Rachel Lougee --- .../models/reporting/page_engagement_views_report.sql | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/ol_dbt/models/reporting/page_engagement_views_report.sql b/src/ol_dbt/models/reporting/page_engagement_views_report.sql index 6c319de3a..e3bfd6a59 100644 --- a/src/ol_dbt/models/reporting/page_engagement_views_report.sql +++ b/src/ol_dbt/models/reporting/page_engagement_views_report.sql @@ -53,15 +53,6 @@ inner join subsection_blocks inner join section_blocks on page_engagement.chapter_block_fk = section_blocks.block_id inner join dim_user - on ( - (page_engagement.platform = 'mitxonline' - and page_engagement.openedx_user_id = dim_user.mitxonline_openedx_user_id) - or (page_engagement.platform = 'edxorg' - and page_engagement.openedx_user_id = dim_user.edxorg_openedx_user_id) - or (page_engagement.platform = 'mitxpro' - and page_engagement.openedx_user_id = dim_user.mitxpro_openedx_user_id) - or (page_engagement.platform = 'residential' - and page_engagement.openedx_user_id = dim_user.residential_openedx_user_id) - ) + on page_engagement.user_fk= dim_user.user_pk left join course_runs on page_engagement.courserun_readable_id = course_runs.courserun_readable_id From 4a596719840ed8e02144f69c8dcb8642a4784790 Mon Sep 17 00:00:00 2001 From: Quazi Date: Mon, 2 Mar 2026 13:23:23 -0500 Subject: [PATCH 06/13] Fix multiple issues in page_engagement_views_report SQL fixes: - Remove duplicate WHERE clauses in subsection_blocks and section_blocks CTEs - Add block_fk to SELECT for proper unique identification Documentation/Testing fixes: - Add block_fk column documentation to YAML - Change uniqueness test from unit_title to block_fk (prevents false failures) - Remove duplicate test definition Addresses Sentry feedback on uniqueness test bug --- src/ol_dbt/models/reporting/_reporting__models.yml | 10 ++++++---- .../models/reporting/page_engagement_views_report.sql | 3 +-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/ol_dbt/models/reporting/_reporting__models.yml b/src/ol_dbt/models/reporting/_reporting__models.yml index d9bb80472..7f006d1b9 100644 --- a/src/ol_dbt/models/reporting/_reporting__models.yml +++ b/src/ol_dbt/models/reporting/_reporting__models.yml @@ -789,6 +789,11 @@ models: code}+{run_tag} tests: - not_null + - name: block_fk + description: string, foreign key to dim_course_content for the vertical (unit) + block + tests: + - not_null - name: num_of_views description: int, number of times the user viewed this page unit tests: @@ -809,10 +814,7 @@ models: description: string, title of the course run tests: - dbt_expectations.expect_compound_columns_to_be_unique: - column_list: ["user_email", "courserun_readable_id", "unit_title"] - tests: - - dbt_expectations.expect_compound_columns_to_be_unique: - column_list: ["user_email", "courserun_readable_id", "unit_title"] + column_list: ["user_email", "courserun_readable_id", "block_fk"] - name: combined_video_engagements_counts_report description: Combined video engagement report across all platforms with video counts per chapter. Shows user video watching activity including total videos available diff --git a/src/ol_dbt/models/reporting/page_engagement_views_report.sql b/src/ol_dbt/models/reporting/page_engagement_views_report.sql index e3bfd6a59..adcd6dfed 100644 --- a/src/ol_dbt/models/reporting/page_engagement_views_report.sql +++ b/src/ol_dbt/models/reporting/page_engagement_views_report.sql @@ -22,7 +22,6 @@ with page_engagement as ( , subsection_blocks as ( select * from {{ ref('dim_course_content') }} where is_latest = true - where is_latest = true and block_category = 'sequential' ) @@ -30,7 +29,6 @@ with page_engagement as ( select * from {{ ref('dim_course_content') }} where is_latest = true and block_category = 'chapter' - and block_category = 'chapter' ) select @@ -38,6 +36,7 @@ select , dim_user.full_name , page_engagement.platform , page_engagement.courserun_readable_id + , page_engagement.block_fk , page_engagement.num_of_views , unit_blocks.block_title as unit_title , subsection_blocks.block_title as subsection_title From 3dec2dde43770369772fda3db9ebffdadb48c1e5 Mon Sep 17 00:00:00 2001 From: Quazi Date: Tue, 3 Mar 2026 16:13:44 -0500 Subject: [PATCH 07/13] Fix NULL user_fk handling in page_engagement_views_report - Change INNER JOIN to LEFT JOIN for dim_user - Prevents silent data loss when user_fk is NULL - Matches pattern used in problem_engagement_detail_report - Addresses Sentry bot feedback on data loss issue --- src/ol_dbt/models/reporting/page_engagement_views_report.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ol_dbt/models/reporting/page_engagement_views_report.sql b/src/ol_dbt/models/reporting/page_engagement_views_report.sql index adcd6dfed..9a585a8ad 100644 --- a/src/ol_dbt/models/reporting/page_engagement_views_report.sql +++ b/src/ol_dbt/models/reporting/page_engagement_views_report.sql @@ -51,7 +51,7 @@ inner join subsection_blocks on page_engagement.sequential_block_fk = subsection_blocks.block_id inner join section_blocks on page_engagement.chapter_block_fk = section_blocks.block_id -inner join dim_user +left join dim_user on page_engagement.user_fk= dim_user.user_pk left join course_runs on page_engagement.courserun_readable_id = course_runs.courserun_readable_id From 4052c5d70646599c51ad14a76e4629d4c77781f4 Mon Sep 17 00:00:00 2001 From: Quazi Date: Wed, 4 Mar 2026 13:20:26 -0500 Subject: [PATCH 08/13] Remove not_null test from user_email in page_engagement_views_report - Remove incompatible not_null test on user_email column - user_email can be NULL when user_fk is NULL (due to LEFT JOIN) - Updated description to clarify nullability - Addresses Sentry feedback on test failure with NULL user_fk --- src/ol_dbt/models/reporting/_reporting__models.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ol_dbt/models/reporting/_reporting__models.yml b/src/ol_dbt/models/reporting/_reporting__models.yml index 6a0f96b4b..37919ffb4 100644 --- a/src/ol_dbt/models/reporting/_reporting__models.yml +++ b/src/ol_dbt/models/reporting/_reporting__models.yml @@ -775,9 +775,7 @@ models: content hierarchy and user information. columns: - name: user_email - description: string, email address of the user - tests: - - not_null + description: string, email address of the user. May be null when user_fk is null. - name: full_name description: string, full name of the user - name: platform From c78f234a09ae2cd379e0fa5ec5a1940f9dbee6b9 Mon Sep 17 00:00:00 2001 From: Quazi Date: Wed, 4 Mar 2026 13:55:11 -0500 Subject: [PATCH 09/13] Change all content block joins to LEFT JOIN to prevent data loss - Change INNER JOIN to LEFT JOIN for unit_blocks, subsection_blocks, section_blocks - Prevents silent data loss when block foreign keys are NULL - afact_course_page_engagement can have NULL values for: - block_fk - sequential_block_fk - chapter_block_fk - Update column descriptions to clarify nullability - Addresses Sentry feedback on data loss from INNER JOINs --- .../models/reporting/_reporting__models.yml | 17 +++++++++++------ .../reporting/page_engagement_views_report.sql | 6 +++--- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/ol_dbt/models/reporting/_reporting__models.yml b/src/ol_dbt/models/reporting/_reporting__models.yml index 37919ffb4..9c4074ced 100644 --- a/src/ol_dbt/models/reporting/_reporting__models.yml +++ b/src/ol_dbt/models/reporting/_reporting__models.yml @@ -797,19 +797,24 @@ models: tests: - not_null - name: unit_title - description: string, title of the vertical (unit) block within the course + description: string, title of the vertical (unit) block within the course. May + be null if block_fk does not match dim_course_content. - name: subsection_title - description: string, title of the sequential (subsection) block within the course + description: string, title of the sequential (subsection) block within the course. + May be null if sequential_block_fk does not match or is null. - name: subsection_block_index description: int, sequence number giving the order in which this subsection appears - within the section + within the section. May be null if sequential_block_fk does not match or is + null. - name: section_title - description: string, title of the chapter (section) block within the course + description: string, title of the chapter (section) block within the course. May + be null if chapter_block_fk does not match or is null. - name: section_block_index description: int, sequence number giving the order in which this section appears - within the course + within the course. May be null if chapter_block_fk does not match or is null. - name: course_title - description: string, title of the course run + description: string, title of the course run. May be null if courserun_readable_id + does not match. tests: - dbt_expectations.expect_compound_columns_to_be_unique: column_list: ["user_email", "courserun_readable_id", "block_fk"] diff --git a/src/ol_dbt/models/reporting/page_engagement_views_report.sql b/src/ol_dbt/models/reporting/page_engagement_views_report.sql index 9a585a8ad..8d3979539 100644 --- a/src/ol_dbt/models/reporting/page_engagement_views_report.sql +++ b/src/ol_dbt/models/reporting/page_engagement_views_report.sql @@ -45,11 +45,11 @@ select , section_blocks.block_index as section_block_index , course_runs.course_title from page_engagement -inner join unit_blocks +left join unit_blocks on page_engagement.block_fk = unit_blocks.block_id -inner join subsection_blocks +left join subsection_blocks on page_engagement.sequential_block_fk = subsection_blocks.block_id -inner join section_blocks +left join section_blocks on page_engagement.chapter_block_fk = section_blocks.block_id left join dim_user on page_engagement.user_fk= dim_user.user_pk From 4fabe3e5ca165e07c066700e7213da6d7abf1c0f Mon Sep 17 00:00:00 2001 From: Quazi Date: Wed, 4 Mar 2026 13:59:01 -0500 Subject: [PATCH 10/13] Add GROUP BY to course_runs CTE to prevent data fan-out - Add GROUP BY course_title, courserun_readable_id - Prevents duplicate rows when int__combined__course_runs has duplicates - Avoids inflated row counts and uniqueness test failures - Addresses Sentry feedback on data fan-out issue --- src/ol_dbt/models/reporting/page_engagement_views_report.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ol_dbt/models/reporting/page_engagement_views_report.sql b/src/ol_dbt/models/reporting/page_engagement_views_report.sql index 8d3979539..339d19f06 100644 --- a/src/ol_dbt/models/reporting/page_engagement_views_report.sql +++ b/src/ol_dbt/models/reporting/page_engagement_views_report.sql @@ -11,6 +11,7 @@ with page_engagement as ( course_title , courserun_readable_id from {{ ref('int__combined__course_runs') }} + group by course_title, courserun_readable_id ) , unit_blocks as ( From 67ac0d4dad5314973198a7aa0c39f31b33a9090c Mon Sep 17 00:00:00 2001 From: Quazi Date: Wed, 4 Mar 2026 14:42:07 -0500 Subject: [PATCH 11/13] Add GROUP BY to prevent potential duplicate rows from block joins - Add GROUP BY on grain columns: user_email, full_name, platform, courserun_readable_id, block_fk - Wrap all non-grouped columns in MAX() aggregation - Defensive programming: prevents fan-out if dim_course_content has duplicate block_ids - Matches pattern used in problem_engagement_detail_report - Ensures uniqueness test on [user_email, courserun_readable_id, block_fk] passes Addresses Sentry feedback on potential duplicate rows --- .../page_engagement_views_report.sql | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/ol_dbt/models/reporting/page_engagement_views_report.sql b/src/ol_dbt/models/reporting/page_engagement_views_report.sql index 339d19f06..4c0bad03c 100644 --- a/src/ol_dbt/models/reporting/page_engagement_views_report.sql +++ b/src/ol_dbt/models/reporting/page_engagement_views_report.sql @@ -38,13 +38,13 @@ select , page_engagement.platform , page_engagement.courserun_readable_id , page_engagement.block_fk - , page_engagement.num_of_views - , unit_blocks.block_title as unit_title - , subsection_blocks.block_title as subsection_title - , subsection_blocks.block_index as subsection_block_index - , section_blocks.block_title as section_title - , section_blocks.block_index as section_block_index - , course_runs.course_title + , max(page_engagement.num_of_views) as num_of_views + , max(unit_blocks.block_title) as unit_title + , max(subsection_blocks.block_title) as subsection_title + , max(subsection_blocks.block_index) as subsection_block_index + , max(section_blocks.block_title) as section_title + , max(section_blocks.block_index) as section_block_index + , max(course_runs.course_title) as course_title from page_engagement left join unit_blocks on page_engagement.block_fk = unit_blocks.block_id @@ -56,3 +56,9 @@ left join dim_user on page_engagement.user_fk= dim_user.user_pk left join course_runs on page_engagement.courserun_readable_id = course_runs.courserun_readable_id +group by + dim_user.email + , dim_user.full_name + , page_engagement.platform + , page_engagement.courserun_readable_id + , page_engagement.block_fk From d413ea08ff4327832792ec0a01d93a3c463af746 Mon Sep 17 00:00:00 2001 From: Quazi Date: Wed, 4 Mar 2026 14:50:08 -0500 Subject: [PATCH 12/13] Add openedx_user_id to preserve grain and prevent data loss for NULL users CRITICAL FIX: Data loss for anonymous/unmatched users Issue: - When user_fk is NULL, LEFT JOIN to dim_user produces NULL for email and full_name - GROUP BY on (user_email, full_name, ...) collapses ALL NULL users into ONE row - MAX(num_of_views) only keeps highest view count, losing other users' data - Breaks the grain: multiple distinct users merged into single row Fix: - Add page_engagement.openedx_user_id to SELECT and GROUP BY - Each user (identified by openedx_user_id) now gets their own row - Even when email/full_name are NULL, users remain distinct - Update uniqueness test from [user_email, ...] to [openedx_user_id, ...] Changes: - SQL: Add openedx_user_id to SELECT (line 6) and GROUP BY (line 31) - YAML: Add openedx_user_id column documentation with not_null test - YAML: Update uniqueness test to use openedx_user_id instead of user_email Addresses Sentry feedback on data loss for NULL user scenarios --- src/ol_dbt/models/reporting/_reporting__models.yml | 6 +++++- .../models/reporting/page_engagement_views_report.sql | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ol_dbt/models/reporting/_reporting__models.yml b/src/ol_dbt/models/reporting/_reporting__models.yml index 9c4074ced..c74389efd 100644 --- a/src/ol_dbt/models/reporting/_reporting__models.yml +++ b/src/ol_dbt/models/reporting/_reporting__models.yml @@ -792,6 +792,10 @@ models: block tests: - not_null + - name: openedx_user_id + description: int, the user's numeric ID in the OpenedX platform + tests: + - not_null - name: num_of_views description: int, number of times the user viewed this page unit tests: @@ -817,7 +821,7 @@ models: does not match. tests: - dbt_expectations.expect_compound_columns_to_be_unique: - column_list: ["user_email", "courserun_readable_id", "block_fk"] + column_list: ["openedx_user_id", "courserun_readable_id", "block_fk"] - name: problem_engagement_detail_report description: Problem engagement detail report showing user performance at the problem diff --git a/src/ol_dbt/models/reporting/page_engagement_views_report.sql b/src/ol_dbt/models/reporting/page_engagement_views_report.sql index 4c0bad03c..8e50e0a14 100644 --- a/src/ol_dbt/models/reporting/page_engagement_views_report.sql +++ b/src/ol_dbt/models/reporting/page_engagement_views_report.sql @@ -38,6 +38,7 @@ select , page_engagement.platform , page_engagement.courserun_readable_id , page_engagement.block_fk + , page_engagement.openedx_user_id , max(page_engagement.num_of_views) as num_of_views , max(unit_blocks.block_title) as unit_title , max(subsection_blocks.block_title) as subsection_title @@ -62,3 +63,4 @@ group by , page_engagement.platform , page_engagement.courserun_readable_id , page_engagement.block_fk + , page_engagement.openedx_user_id From 37949ba663474af755ad5e3a668649768fd1f0bd Mon Sep 17 00:00:00 2001 From: Quazi Date: Wed, 4 Mar 2026 14:54:14 -0500 Subject: [PATCH 13/13] Add platform to uniqueness test to match actual grain Issue: - Model groups by: platform, openedx_user_id, courserun_readable_id, block_fk - Uniqueness test only checked: openedx_user_id, courserun_readable_id, block_fk - Missing platform causes test failure when same user+course+block on different platforms Fix: - Add platform to uniqueness test column list - Test now matches actual grain of the model Addresses Sentry feedback on uniqueness test mismatch --- src/ol_dbt/models/reporting/_reporting__models.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ol_dbt/models/reporting/_reporting__models.yml b/src/ol_dbt/models/reporting/_reporting__models.yml index c74389efd..fd4d848b2 100644 --- a/src/ol_dbt/models/reporting/_reporting__models.yml +++ b/src/ol_dbt/models/reporting/_reporting__models.yml @@ -821,7 +821,7 @@ models: does not match. tests: - dbt_expectations.expect_compound_columns_to_be_unique: - column_list: ["openedx_user_id", "courserun_readable_id", "block_fk"] + column_list: ["platform", "openedx_user_id", "courserun_readable_id", "block_fk"] - name: problem_engagement_detail_report description: Problem engagement detail report showing user performance at the problem