From 39ad9c51e1c19cabdb59aab85279d3f7caa5c67b Mon Sep 17 00:00:00 2001 From: Jamie Benstead Date: Thu, 25 Jun 2026 14:51:00 +0100 Subject: [PATCH 1/5] Add extra required data to the track_event call when creating a school --- app/controllers/api/schools_controller.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/schools_controller.rb b/app/controllers/api/schools_controller.rb index 9bc829bb8..f4029f4ff 100644 --- a/app/controllers/api/schools_controller.rb +++ b/app/controllers/api/schools_controller.rb @@ -20,7 +20,12 @@ def create if result.success? @school = result[:school] - track_event('School - Created', school_id: @school.id) + track_event( + 'School - Created', + school_id: @school.id, + first_landing_page: params[:first_landing_page], + marketing_parameters: marketing_parameters + ) render :show, formats: [:json], status: :created else render json: { @@ -77,6 +82,10 @@ def import private + def marketing_parameters + params[:marketing_parameters]&.permit!&.to_h + end + def create_params params.expect( school: %i[name From 75897cdc3dc5f82ed0449bf16ded2afff1a811fc Mon Sep 17 00:00:00 2001 From: Jamie Benstead Date: Tue, 30 Jun 2026 11:21:22 +0100 Subject: [PATCH 2/5] Flattern school created marketing event properties --- app/controllers/api/schools_controller.rb | 6 ++--- .../features/school/creating_a_school_spec.rb | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/schools_controller.rb b/app/controllers/api/schools_controller.rb index f4029f4ff..aa77964b8 100644 --- a/app/controllers/api/schools_controller.rb +++ b/app/controllers/api/schools_controller.rb @@ -22,9 +22,9 @@ def create @school = result[:school] track_event( 'School - Created', + **marketing_parameters, school_id: @school.id, - first_landing_page: params[:first_landing_page], - marketing_parameters: marketing_parameters + first_landing_page: params[:first_landing_page] ) render :show, formats: [:json], status: :created else @@ -83,7 +83,7 @@ def import private def marketing_parameters - params[:marketing_parameters]&.permit!&.to_h + params[:marketing_parameters]&.permit!&.to_h || {} end def create_params diff --git a/spec/features/school/creating_a_school_spec.rb b/spec/features/school/creating_a_school_spec.rb index f288d719a..4535b019c 100644 --- a/spec/features/school/creating_a_school_spec.rb +++ b/spec/features/school/creating_a_school_spec.rb @@ -67,4 +67,27 @@ time: be_within(1.second).of(Time.current) ) end + + it 'records marketing parameters as top-level event properties' do + post( + '/api/schools', + headers:, + params: params.merge( + first_landing_page: '/signup', + marketing_parameters: { + utm_source: 'newsletter', + utm_campaign: 'back-to-school' + } + ) + ) + + properties = Event.last.properties + expect(properties).to include( + 'school_id' => School.last.id, + 'first_landing_page' => '/signup', + 'utm_source' => 'newsletter', + 'utm_campaign' => 'back-to-school' + ) + expect(properties).not_to have_key('marketing_parameters') + end end From 390cb3a29c4ef1e10027002f27cf24c26e4ab59e Mon Sep 17 00:00:00 2001 From: Jamie Benstead Date: Tue, 30 Jun 2026 11:22:59 +0100 Subject: [PATCH 3/5] Remove redundant safety --- app/controllers/api/schools_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/schools_controller.rb b/app/controllers/api/schools_controller.rb index aa77964b8..c88d73db3 100644 --- a/app/controllers/api/schools_controller.rb +++ b/app/controllers/api/schools_controller.rb @@ -83,7 +83,7 @@ def import private def marketing_parameters - params[:marketing_parameters]&.permit!&.to_h || {} + params[:marketing_parameters]&.permit!.to_h end def create_params From 6366cc3124473179a2f55ef4e3131aa10b3c4e03 Mon Sep 17 00:00:00 2001 From: Jamie Benstead Date: Tue, 30 Jun 2026 11:37:55 +0100 Subject: [PATCH 4/5] Add marketing param keys and safety check --- app/controllers/api/schools_controller.rb | 15 ++++++++++++++- spec/features/school/creating_a_school_spec.rb | 15 ++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/schools_controller.rb b/app/controllers/api/schools_controller.rb index c88d73db3..9d5729548 100644 --- a/app/controllers/api/schools_controller.rb +++ b/app/controllers/api/schools_controller.rb @@ -2,6 +2,16 @@ module Api class SchoolsController < ApiController + MARKETING_PARAMETER_KEYS = %i[ + utm_source + utm_medium + utm_campaign + utm_term + utm_content + gclid + fbclid + ].freeze + before_action :authorize_user load_and_authorize_resource skip_load_and_authorize_resource only: :import @@ -83,7 +93,10 @@ def import private def marketing_parameters - params[:marketing_parameters]&.permit!.to_h + marketing_params = params[:marketing_parameters] + return {} unless marketing_params.is_a?(ActionController::Parameters) + + marketing_params.permit(*MARKETING_PARAMETER_KEYS).to_h end def create_params diff --git a/spec/features/school/creating_a_school_spec.rb b/spec/features/school/creating_a_school_spec.rb index 4535b019c..90d15f3a2 100644 --- a/spec/features/school/creating_a_school_spec.rb +++ b/spec/features/school/creating_a_school_spec.rb @@ -76,7 +76,8 @@ first_landing_page: '/signup', marketing_parameters: { utm_source: 'newsletter', - utm_campaign: 'back-to-school' + utm_campaign: 'back-to-school', + unexpected_email: 'person@example.com' } ) ) @@ -89,5 +90,17 @@ 'utm_campaign' => 'back-to-school' ) expect(properties).not_to have_key('marketing_parameters') + expect(properties).not_to have_key('unexpected_email') + end + + it 'ignores malformed marketing parameters' do + post( + '/api/schools', + headers:, + params: params.merge(marketing_parameters: 'newsletter') + ) + + expect(response).to have_http_status(:created) + expect(Event.last.properties).to eq('school_id' => School.last.id) end end From 3ba41ff758b0f7e1bafb64bed4b8c622e5e2fab2 Mon Sep 17 00:00:00 2001 From: Jamie Benstead Date: Tue, 30 Jun 2026 11:44:09 +0100 Subject: [PATCH 5/5] Safely flatten school created marketing properties --- app/controllers/api/schools_controller.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/schools_controller.rb b/app/controllers/api/schools_controller.rb index 9d5729548..f4d9956c9 100644 --- a/app/controllers/api/schools_controller.rb +++ b/app/controllers/api/schools_controller.rb @@ -32,9 +32,10 @@ def create @school = result[:school] track_event( 'School - Created', - **marketing_parameters, - school_id: @school.id, - first_landing_page: params[:first_landing_page] + marketing_parameters.merge( + school_id: @school.id, + first_landing_page: params[:first_landing_page] + ) ) render :show, formats: [:json], status: :created else