Skip to content

Commit f19575c

Browse files
committed
Track project workflow analytics events
1 parent 97f9dc1 commit f19575c

19 files changed

Lines changed: 289 additions & 4 deletions

app/controllers/api/feedback_controller.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ def create
2424

2525
if result.success?
2626
@feedback = result[:feedback]
27+
track_project_event('Project - Feedback given', project)
2728
render :show, formats: [:json], status: :created
2829
else
2930
render json: { error: result[:error] }, status: :unprocessable_content

app/controllers/api/lessons/batch_controller.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ def create_batch
1818
lessons_params: batch_lessons_params
1919
)
2020
@user = current_user
21+
@results.select(&:success?).each { |result| track_project_event('Project - Created', result[:lesson].project) }
2122
render :create_batch, formats: [:json], status: :created
2223
end
2324

app/controllers/api/lessons_controller.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def show
3333
def create
3434
result = Lesson::Create.call(lesson_params: create_params)
3535
if result.success?
36+
track_project_event('Project - Created', result[:lesson].project)
3637
@lesson_with_user = result[:lesson].with_user
3738
render :show, formats: [:json], status: :created
3839
else
@@ -54,9 +55,11 @@ def create_copy
5455
def update
5556
# TODO: Consider removing user_id from the lesson_params for update so users can update other users' lessons without changing ownership
5657
# OR consider dropping user_id on lessons and using teacher id/ids on the class instead
58+
previous_visibility = @lesson.visibility
5759
result = Lesson::Update.call(lesson: @lesson, lesson_params: update_params)
5860

5961
if result.success?
62+
track_project_event('Project - Made visible', result[:lesson].project) if previous_visibility != 'students' && result[:lesson].visibility == 'students'
6063
@lesson_with_user = result[:lesson].with_user
6164
render :show, formats: [:json], status: :ok
6265
else

app/controllers/api/projects/remixes_controller.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def create
3636

3737
if result.success?
3838
@project = result[:project]
39+
track_project_event('Project - Saved', @project)
3940
render '/api/projects/show', formats: [:json]
4041
else
4142
render json: { error: result[:error] }, status: :bad_request

app/controllers/api/projects_controller.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ def index
1717
end
1818

1919
def show
20+
track_project_event('Project - Opened', @project) if current_user.present?
21+
2022
if !@project.school_id.nil? && @project.lesson_id.nil?
2123
project_with_user = @project.with_student(current_user)
2224
@user = project_with_user[1]
@@ -31,6 +33,7 @@ def create
3133

3234
if result.success?
3335
@project = result[:project]
36+
track_project_event('Project - Created', @project)
3437
render :show, formats: [:json], status: :created
3538
else
3639
render json: { error: result[:error] }, status: :unprocessable_content
@@ -41,6 +44,7 @@ def update
4144
result = Project::Update.call(project: @project, update_hash: project_params, current_user:)
4245

4346
if result.success?
47+
track_project_event('Project - Saved', @project)
4448
render :show, formats: [:json]
4549
else
4650
render json: { error: result[:error] }, status: :unprocessable_content

app/controllers/api/school_projects_controller.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ def unsubmit
2323

2424
def submit
2525
authorize! :submit, school_project
26+
previous_status = school_project.status
2627
result = SchoolProject::SetStatus.call(school_project:, status: :submitted, user_id: current_user.id)
2728
if result.success?
2829
@school_project = result[:school_project]
30+
track_project_event('Project - Submitted for review', @school_project.project) if previous_status != 'submitted'
2931
render :show_status, formats: [:json], status: :ok
3032
else
3133
render json: { error: result[:error] }, status: :unprocessable_content
@@ -45,9 +47,11 @@ def return
4547

4648
def complete
4749
authorize! :complete, school_project
50+
previous_status = school_project.status
4851
result = SchoolProject::SetStatus.call(school_project:, status: :complete, user_id: current_user.id)
4952
if result.success?
5053
@school_project = result[:school_project]
54+
track_project_event('Project - Marked as completed', @school_project.project) if previous_status != 'complete'
5155
render :show_status, formats: [:json], status: :ok
5256
else
5357
render json: { error: result[:error] }, status: :unprocessable_content

app/controllers/api/scratch/projects_controller.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ def create
2727
scratch_component.content = scratch_content_params
2828
existing_remix.save!
2929
move_assets_uploaded_by_current_user_before_remix(original_project:, remix_project: existing_remix)
30+
track_project_event('Project - Saved', existing_remix)
3031

3132
return render json: { status: 'ok', 'content-name': existing_remix.identifier }, status: :ok
3233
end
@@ -42,6 +43,7 @@ def create
4243

4344
if result.success?
4445
move_assets_uploaded_by_current_user_before_remix(original_project:, remix_project: result[:project])
46+
track_project_event('Project - Saved', result[:project])
4547
render json: { status: 'ok', 'content-name': result[:project].identifier }, status: :ok
4648
else
4749
render json: { error: result[:error] }, status: :bad_request
@@ -51,6 +53,7 @@ def create
5153
def update
5254
@project.scratch_component&.content = scratch_content_params
5355
@project.save!
56+
track_project_event('Project - Saved', @project)
5457
render json: { status: 'ok' }, status: :ok
5558
end
5659

spec/features/feedback/creating_feedback_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,24 @@
4646
it 'adds the feedback to the school project' do
4747
expect(student_project.school_project.feedback.count).to eq(1)
4848
end
49+
50+
it 'records a project feedback given event' do
51+
event = Event.last
52+
53+
expect(event).to have_attributes(
54+
name: 'Project - Feedback given',
55+
user_id: teacher.id,
56+
properties: {
57+
'school_id' => school.id,
58+
'class_id' => school_class.id,
59+
'lesson_id' => lesson.id,
60+
'project_type' => Project::Types::PYTHON,
61+
'user_role' => 'educator',
62+
'student_id' => student.id
63+
},
64+
time: be_within(1.second).of(Time.current)
65+
)
66+
end
4967
end
5068

5169
context 'when leaving feedback on a project that is not student work' do

spec/features/lesson/creating_a_batch_of_lessons_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,24 @@
127127
expect(response).to have_http_status(:created)
128128
end
129129

130+
it 'records project created events for each created lesson project' do
131+
events = Event.where(name: 'Project - Created')
132+
133+
expect(events.count).to eq(2)
134+
expect(events.map(&:user_id)).to all(eq(teacher.id))
135+
expect(events.map(&:properties)).to match_array(
136+
Lesson.order(:created_at).map do |lesson|
137+
{
138+
'school_id' => school.id,
139+
'class_id' => school_class.id,
140+
'lesson_id' => lesson.id,
141+
'project_type' => Project::Types::CODE_EDITOR_SCRATCH,
142+
'user_role' => 'educator'
143+
}
144+
end
145+
)
146+
end
147+
130148
context 'when school_class_id does not correspond to school_id' do
131149
let(:lesson_projects) { lesson_project_params.map { |entry| entry.merge(school_id: SecureRandom.uuid) } }
132150

spec/features/lesson/creating_a_lesson_spec.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,25 @@
148148
expect(response).to have_http_status(:created)
149149
end
150150

151+
it 'records a project created event' do
152+
authenticated_in_hydra_as(teacher)
153+
154+
post('/api/lessons', headers:, params:)
155+
156+
expect(Event.last).to have_attributes(
157+
name: 'Project - Created',
158+
user_id: teacher.id,
159+
properties: {
160+
'school_id' => school.id,
161+
'class_id' => school_class.id,
162+
'lesson_id' => Lesson.last.id,
163+
'project_type' => Project::Types::PYTHON,
164+
'user_role' => 'educator'
165+
},
166+
time: be_within(1.second).of(Time.current)
167+
)
168+
end
169+
151170
it 'responds 422 Unprocessable if school_id is missing' do
152171
new_params = { lesson: params[:lesson].without(:school_id) }
153172

0 commit comments

Comments
 (0)