From d1a6313ad65c9a62fde26dc277dc6b8c81e2e9e3 Mon Sep 17 00:00:00 2001 From: EmilyYoung26 Date: Mon, 13 Apr 2026 16:11:59 +0100 Subject: [PATCH 1/6] Created fact_bookings sql and yml files. Added a singular test too make sure the attendance flags work. --- models/marts/fact_bookings.sql | 32 ++++++++ models/marts/fact_bookings.yml | 78 +++++++++++++++++++ .../fact_bookings_status_flags_consistent.sql | 9 +++ 3 files changed, 119 insertions(+) create mode 100644 models/marts/fact_bookings.sql create mode 100644 models/marts/fact_bookings.yml create mode 100644 tests/singular_tests/fact_bookings_status_flags_consistent.sql diff --git a/models/marts/fact_bookings.sql b/models/marts/fact_bookings.sql new file mode 100644 index 0000000..126a595 --- /dev/null +++ b/models/marts/fact_bookings.sql @@ -0,0 +1,32 @@ +with bookings as ( + + select * + from {{ ref('stg_bookings') }} + +), + +final as ( + + select + booking_id, + member_id, + class_id, + + booking_timestamp, + date(booking_timestamp) as booking_date, + + attendance_status, + + case when attendance_status = 'attended' then true else false end as is_attended, + case when attendance_status = 'cancelled' then true else false end as is_cancelled, + case when attendance_status = 'no_show' then true else false end as is_no_show, + + check_in_timestamp, + cancellation_timestamp + + from bookings + +) + +select * +from final \ No newline at end of file diff --git a/models/marts/fact_bookings.yml b/models/marts/fact_bookings.yml new file mode 100644 index 0000000..ed8927f --- /dev/null +++ b/models/marts/fact_bookings.yml @@ -0,0 +1,78 @@ +version: 2 + +models: + - name: fact_bookings + description: Final fact table for class bookings with one row per booking. + + columns: + - name: booking_id + description: Unique identifier for each booking. + tests: + - not_null + - unique + + - name: member_id + description: Identifier for the member who made the booking. + tests: + - not_null + - relationships: + arguments: + to: ref('dim_members') + field: member_id + + - name: class_id + description: Identifier for the class that was booked. + tests: + - not_null + + - name: booking_timestamp + description: Timestamp of when the booking was made. + tests: + - not_null + + - name: booking_date + description: Date when the booking was made. + tests: + - not_null + + - name: attendance_status + description: Cleaned attendance status for the booking. + tests: + - not_null + - accepted_values: + arguments: + values: ['attended', 'cancelled', 'no_show'] + + - name: is_attended + description: Flag indicating whether the booking was attended. + tests: + - not_null + - accepted_values: + arguments: + values: [true, false] + quote: false + + - name: is_cancelled + description: Flag indicating whether the booking was cancelled. + tests: + - not_null + - accepted_values: + arguments: + values: [true, false] + quote: false + + - name: is_no_show + description: Flag indicating whether the booking was a no-show. + tests: + - not_null + - accepted_values: + arguments: + values: [true, false] + quote: false + + - name: check_in_timestamp + description: Timestamp when the member checked in, if they attended. + + - name: cancellation_timestamp + description: Timestamp when the booking was cancelled, if cancelled. + diff --git a/tests/singular_tests/fact_bookings_status_flags_consistent.sql b/tests/singular_tests/fact_bookings_status_flags_consistent.sql new file mode 100644 index 0000000..370da4c --- /dev/null +++ b/tests/singular_tests/fact_bookings_status_flags_consistent.sql @@ -0,0 +1,9 @@ +select * +from {{ ref('fact_bookings') }} +where + (attendance_status = 'attended' and (is_attended = false or is_cancelled = true or is_no_show = true)) + or + (attendance_status = 'cancelled' and (is_attended = true or is_cancelled = false or is_no_show = true)) + or + (attendance_status = 'no_show' and (is_attended = true or is_cancelled = true or is_no_show = false)) + From ac580edf7ad4e31c00508162e3cf96e083a05c05 Mon Sep 17 00:00:00 2001 From: EmilyYoung26 Date: Wed, 15 Apr 2026 15:16:48 +0100 Subject: [PATCH 2/6] Updated sql file to remove select * from CTE and added a unit test for attendance flags. --- models/marts/fact_bookings.sql | 9 ++++++++- models/marts/fact_bookings.yml | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/models/marts/fact_bookings.sql b/models/marts/fact_bookings.sql index 126a595..fe83b21 100644 --- a/models/marts/fact_bookings.sql +++ b/models/marts/fact_bookings.sql @@ -1,6 +1,13 @@ with bookings as ( - select * + select + booking_id, + member_id, + class_id, + booking_timestamp, + attendance_status, + check_in_timestamp, + cancellation_timestamp from {{ ref('stg_bookings') }} ), diff --git a/models/marts/fact_bookings.yml b/models/marts/fact_bookings.yml index ed8927f..b03c33c 100644 --- a/models/marts/fact_bookings.yml +++ b/models/marts/fact_bookings.yml @@ -76,3 +76,20 @@ models: - name: cancellation_timestamp description: Timestamp when the booking was cancelled, if cancelled. +unit_tests: + - name: test_fact_bookings_attendance_flags + description: Test that the attendance_status is consistent with the attendance flags. + model: fact_bookings + + given: + - input: ref('stg_bookings') + rows: + - {booking_id: 1, member_id: 101, class_id: 1001, booking_timestamp: '2025-01-10 09:00:00', attendance_status: 'attended', check_in_timestamp: '2025-01-10 09:55:00', cancellation_timestamp: null} + - {booking_id: 2, member_id: 102, class_id: 1002, booking_timestamp: '2025-01-11 10:00:00', attendance_status: 'cancelled', check_in_timestamp: null, cancellation_timestamp: '2025-01-10 15:00:00'} + - {booking_id: 3, member_id: 103, class_id: 1003, booking_timestamp: '2025-01-12 11:00:00', attendance_status: 'no_show', check_in_timestamp: null, cancellation_timestamp: null} + + expect: + rows: + - {booking_id: 1, member_id: 101, class_id: 1001, booking_timestamp: '2025-01-10 09:00:00', booking_date: '2025-01-10', attendance_status: 'attended', is_attended: true, is_cancelled: false, is_no_show: false, check_in_timestamp: '2025-01-10 09:55:00', cancellation_timestamp: null} + - {booking_id: 2, member_id: 102, class_id: 1002, booking_timestamp: '2025-01-11 10:00:00', booking_date: '2025-01-11', attendance_status: 'cancelled', is_attended: false, is_cancelled: true, is_no_show: false, check_in_timestamp: null, cancellation_timestamp: '2025-01-10 15:00:00'} + - {booking_id: 3, member_id: 103, class_id: 1003, booking_timestamp: '2025-01-12 11:00:00', booking_date: '2025-01-12', attendance_status: 'no_show', is_attended: false, is_cancelled: false, is_no_show: true, check_in_timestamp: null, cancellation_timestamp: null} From a6e31880b0ca858d9af353e294a8ba12e9a804df Mon Sep 17 00:00:00 2001 From: EmilyYoung26 Date: Wed, 15 Apr 2026 15:40:20 +0100 Subject: [PATCH 3/6] Added null test case to unit test. --- models/marts/fact_bookings.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/models/marts/fact_bookings.yml b/models/marts/fact_bookings.yml index b03c33c..d4f300d 100644 --- a/models/marts/fact_bookings.yml +++ b/models/marts/fact_bookings.yml @@ -87,9 +87,12 @@ unit_tests: - {booking_id: 1, member_id: 101, class_id: 1001, booking_timestamp: '2025-01-10 09:00:00', attendance_status: 'attended', check_in_timestamp: '2025-01-10 09:55:00', cancellation_timestamp: null} - {booking_id: 2, member_id: 102, class_id: 1002, booking_timestamp: '2025-01-11 10:00:00', attendance_status: 'cancelled', check_in_timestamp: null, cancellation_timestamp: '2025-01-10 15:00:00'} - {booking_id: 3, member_id: 103, class_id: 1003, booking_timestamp: '2025-01-12 11:00:00', attendance_status: 'no_show', check_in_timestamp: null, cancellation_timestamp: null} + - {booking_id 4, member_id: 104, class_id: 1004, booking_timestamp: '2025-01-13 12:00:00', attendance_status: null, check_in_timestamp:null, cancellation_timestamp: null} expect: rows: - {booking_id: 1, member_id: 101, class_id: 1001, booking_timestamp: '2025-01-10 09:00:00', booking_date: '2025-01-10', attendance_status: 'attended', is_attended: true, is_cancelled: false, is_no_show: false, check_in_timestamp: '2025-01-10 09:55:00', cancellation_timestamp: null} - {booking_id: 2, member_id: 102, class_id: 1002, booking_timestamp: '2025-01-11 10:00:00', booking_date: '2025-01-11', attendance_status: 'cancelled', is_attended: false, is_cancelled: true, is_no_show: false, check_in_timestamp: null, cancellation_timestamp: '2025-01-10 15:00:00'} - {booking_id: 3, member_id: 103, class_id: 1003, booking_timestamp: '2025-01-12 11:00:00', booking_date: '2025-01-12', attendance_status: 'no_show', is_attended: false, is_cancelled: false, is_no_show: true, check_in_timestamp: null, cancellation_timestamp: null} + - {booking_id: 4, member_id: 104, class_id: 1004, booking_timestamp: '2025-01-13 12:00:00', booking_date: '2025-01-13', attendance_status: null, is_attended: false, is_no_show: false, check_in_timestamp: null, cancellation_timestamp: null} + \ No newline at end of file From 2fcd287daa4f15c0c0d0394f9f4f3e65201a476d Mon Sep 17 00:00:00 2001 From: EmilyYoung26 Date: Wed, 15 Apr 2026 15:44:36 +0100 Subject: [PATCH 4/6] Added null test case to unit test. --- models/marts/fact_bookings.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/models/marts/fact_bookings.yml b/models/marts/fact_bookings.yml index d4f300d..8e20012 100644 --- a/models/marts/fact_bookings.yml +++ b/models/marts/fact_bookings.yml @@ -87,7 +87,7 @@ unit_tests: - {booking_id: 1, member_id: 101, class_id: 1001, booking_timestamp: '2025-01-10 09:00:00', attendance_status: 'attended', check_in_timestamp: '2025-01-10 09:55:00', cancellation_timestamp: null} - {booking_id: 2, member_id: 102, class_id: 1002, booking_timestamp: '2025-01-11 10:00:00', attendance_status: 'cancelled', check_in_timestamp: null, cancellation_timestamp: '2025-01-10 15:00:00'} - {booking_id: 3, member_id: 103, class_id: 1003, booking_timestamp: '2025-01-12 11:00:00', attendance_status: 'no_show', check_in_timestamp: null, cancellation_timestamp: null} - - {booking_id 4, member_id: 104, class_id: 1004, booking_timestamp: '2025-01-13 12:00:00', attendance_status: null, check_in_timestamp:null, cancellation_timestamp: null} + - {booking_id: 4, member_id: 104, class_id: 1004, booking_timestamp: '2025-01-13 12:00:00', attendance_status: null, check_in_timestamp:null, cancellation_timestamp: null} expect: rows: @@ -95,4 +95,3 @@ unit_tests: - {booking_id: 2, member_id: 102, class_id: 1002, booking_timestamp: '2025-01-11 10:00:00', booking_date: '2025-01-11', attendance_status: 'cancelled', is_attended: false, is_cancelled: true, is_no_show: false, check_in_timestamp: null, cancellation_timestamp: '2025-01-10 15:00:00'} - {booking_id: 3, member_id: 103, class_id: 1003, booking_timestamp: '2025-01-12 11:00:00', booking_date: '2025-01-12', attendance_status: 'no_show', is_attended: false, is_cancelled: false, is_no_show: true, check_in_timestamp: null, cancellation_timestamp: null} - {booking_id: 4, member_id: 104, class_id: 1004, booking_timestamp: '2025-01-13 12:00:00', booking_date: '2025-01-13', attendance_status: null, is_attended: false, is_no_show: false, check_in_timestamp: null, cancellation_timestamp: null} - \ No newline at end of file From 4c7da121a7ef369759078dbbcc594b36997d6baa Mon Sep 17 00:00:00 2001 From: EmilyYoung26 Date: Wed, 15 Apr 2026 15:49:17 +0100 Subject: [PATCH 5/6] Added null test case to unit test. --- models/marts/fact_bookings.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/marts/fact_bookings.yml b/models/marts/fact_bookings.yml index 8e20012..bc485db 100644 --- a/models/marts/fact_bookings.yml +++ b/models/marts/fact_bookings.yml @@ -87,7 +87,7 @@ unit_tests: - {booking_id: 1, member_id: 101, class_id: 1001, booking_timestamp: '2025-01-10 09:00:00', attendance_status: 'attended', check_in_timestamp: '2025-01-10 09:55:00', cancellation_timestamp: null} - {booking_id: 2, member_id: 102, class_id: 1002, booking_timestamp: '2025-01-11 10:00:00', attendance_status: 'cancelled', check_in_timestamp: null, cancellation_timestamp: '2025-01-10 15:00:00'} - {booking_id: 3, member_id: 103, class_id: 1003, booking_timestamp: '2025-01-12 11:00:00', attendance_status: 'no_show', check_in_timestamp: null, cancellation_timestamp: null} - - {booking_id: 4, member_id: 104, class_id: 1004, booking_timestamp: '2025-01-13 12:00:00', attendance_status: null, check_in_timestamp:null, cancellation_timestamp: null} + - {booking_id: 4, member_id: 104, class_id: 1004, booking_timestamp: '2025-01-13 12:00:00', attendance_status: null, check_in_timestamp: null, cancellation_timestamp: null} expect: rows: From 7dc2e364c34b0399bdb3b15d94c1545ba533c017 Mon Sep 17 00:00:00 2001 From: EmilyYoung26 Date: Wed, 15 Apr 2026 15:57:54 +0100 Subject: [PATCH 6/6] Corrected unit testing to include a null test. --- models/marts/fact_bookings.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/models/marts/fact_bookings.yml b/models/marts/fact_bookings.yml index bc485db..3899938 100644 --- a/models/marts/fact_bookings.yml +++ b/models/marts/fact_bookings.yml @@ -84,14 +84,14 @@ unit_tests: given: - input: ref('stg_bookings') rows: - - {booking_id: 1, member_id: 101, class_id: 1001, booking_timestamp: '2025-01-10 09:00:00', attendance_status: 'attended', check_in_timestamp: '2025-01-10 09:55:00', cancellation_timestamp: null} - - {booking_id: 2, member_id: 102, class_id: 1002, booking_timestamp: '2025-01-11 10:00:00', attendance_status: 'cancelled', check_in_timestamp: null, cancellation_timestamp: '2025-01-10 15:00:00'} - - {booking_id: 3, member_id: 103, class_id: 1003, booking_timestamp: '2025-01-12 11:00:00', attendance_status: 'no_show', check_in_timestamp: null, cancellation_timestamp: null} - - {booking_id: 4, member_id: 104, class_id: 1004, booking_timestamp: '2025-01-13 12:00:00', attendance_status: null, check_in_timestamp: null, cancellation_timestamp: null} + - {booking_id: 1, member_id: 101, class_id: 1001, booking_timestamp: "timestamp('2025-01-10 09:00:00')", attendance_status: 'attended', check_in_timestamp: "timestamp('2025-01-10 09:55:00')", cancellation_timestamp: null} + - {booking_id: 2, member_id: 102, class_id: 1002, booking_timestamp: "timestamp('2025-01-11 10:00:00')", attendance_status: 'cancelled', check_in_timestamp: null, cancellation_timestamp: "timestamp('2025-01-10 15:00:00')"} + - {booking_id: 3, member_id: 103, class_id: 1003, booking_timestamp: "timestamp('2025-01-12 11:00:00')", attendance_status: 'no_show', check_in_timestamp: null, cancellation_timestamp: null} + - {booking_id: 4, member_id: 104, class_id: 1004, booking_timestamp: "timestamp('2025-01-13 12:00:00')", attendance_status: null, check_in_timestamp: null, cancellation_timestamp: null} expect: rows: - - {booking_id: 1, member_id: 101, class_id: 1001, booking_timestamp: '2025-01-10 09:00:00', booking_date: '2025-01-10', attendance_status: 'attended', is_attended: true, is_cancelled: false, is_no_show: false, check_in_timestamp: '2025-01-10 09:55:00', cancellation_timestamp: null} - - {booking_id: 2, member_id: 102, class_id: 1002, booking_timestamp: '2025-01-11 10:00:00', booking_date: '2025-01-11', attendance_status: 'cancelled', is_attended: false, is_cancelled: true, is_no_show: false, check_in_timestamp: null, cancellation_timestamp: '2025-01-10 15:00:00'} - - {booking_id: 3, member_id: 103, class_id: 1003, booking_timestamp: '2025-01-12 11:00:00', booking_date: '2025-01-12', attendance_status: 'no_show', is_attended: false, is_cancelled: false, is_no_show: true, check_in_timestamp: null, cancellation_timestamp: null} - - {booking_id: 4, member_id: 104, class_id: 1004, booking_timestamp: '2025-01-13 12:00:00', booking_date: '2025-01-13', attendance_status: null, is_attended: false, is_no_show: false, check_in_timestamp: null, cancellation_timestamp: null} + - {booking_id: 1, member_id: 101, class_id: 1001, booking_timestamp: "timestamp('2025-01-10 09:00:00')", booking_date: "date('2025-01-10')", attendance_status: 'attended', is_attended: true, is_cancelled: false, is_no_show: false, check_in_timestamp: "timestamp('2025-01-10 09:55:00')", cancellation_timestamp: null} + - {booking_id: 2, member_id: 102, class_id: 1002, booking_timestamp: "timestamp('2025-01-11 10:00:00')", booking_date: "date('2025-01-11')", attendance_status: 'cancelled', is_attended: false, is_cancelled: true, is_no_show: false, check_in_timestamp: null, cancellation_timestamp: "timestamp('2025-01-10 15:00:00')"} + - {booking_id: 3, member_id: 103, class_id: 1003, booking_timestamp: "timestamp('2025-01-12 11:00:00')", booking_date: "date('2025-01-12')", attendance_status: 'no_show', is_attended: false, is_cancelled: false, is_no_show: true, check_in_timestamp: null, cancellation_timestamp: null} + - {booking_id: 4, member_id: 104, class_id: 1004, booking_timestamp: "timestamp('2025-01-13 12:00:00')", booking_date: "date('2025-01-13')", attendance_status: null, is_attended: false, is_cancelled: false, is_no_show: false, check_in_timestamp: null, cancellation_timestamp: null}