Skip to content

Commit 6c154c1

Browse files
octoberclubclaude
authored andcommitted
Exclude students with no attendance in the past year from chaser email
Narrows the chaser target to members who attended between 3 months and 1 year ago, filtering out long-inactive students who are unlikely to re-engage. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent f2ffaa1 commit 6c154c1

2 files changed

Lines changed: 44 additions & 2 deletions

File tree

app/services/three_month_email_service.rb

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,29 @@
22

33
class ThreeMonthEmailService
44
def self.send_chaser
5-
cutoff = 3.months.ago.beginning_of_day
5+
three_month_cutoff = 3.months.ago.beginning_of_day
6+
one_year_cutoff = 1.year.ago.beginning_of_day
7+
68
recent_attendee_ids = WorkshopInvitation.to_students
79
.attended
810
.joins(:workshop)
9-
.where('workshops.date_and_time >= ?', cutoff)
11+
.where('workshops.date_and_time >= ?', three_month_cutoff)
1012
.select(:member_id)
1113

14+
past_year_attendee_ids = WorkshopInvitation.to_students
15+
.attended
16+
.joins(:workshop)
17+
.where('workshops.date_and_time >= ?', one_year_cutoff)
18+
.select(:member_id)
19+
1220
members = Member.not_banned
1321
.accepted_toc
1422
.joins(:groups)
1523
.merge(Group.students)
1624
.left_joins(:member_email_deliveries)
1725
.where(member_email_deliveries: { id: nil })
1826
.where.not(id: recent_attendee_ids)
27+
.where(id: past_year_attendee_ids)
1928
.distinct
2029
return if members.empty?
2130

spec/services/three_month_email_service_spec.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@
99
let!(:eligible_student) do
1010
member = Fabricate(:member)
1111
Fabricate(:subscription, member: member, group: students_group)
12+
Fabricate(
13+
:workshop_invitation,
14+
member: member,
15+
workshop: Fabricate(:workshop, chapter: chapter, date_and_time: 6.months.ago),
16+
role: "Student",
17+
attended: true
18+
)
1219
member
1320
end
1421

@@ -63,6 +70,19 @@
6370
member
6471
end
6572

73+
let!(:student_with_very_old_attendance) do
74+
member = Fabricate(:member)
75+
Fabricate(:subscription, member: member, group: students_group)
76+
Fabricate(
77+
:workshop_invitation,
78+
member: member,
79+
workshop: Fabricate(:workshop, chapter: chapter, date_and_time: 14.months.ago),
80+
role: "Student",
81+
attended: true
82+
)
83+
member
84+
end
85+
6686
it "emails only students who have not attended in the last 3 months and were not emailed before" do
6787
expect { perform_enqueued_jobs { call } }.to change(MemberEmailDelivery, :count).by(2)
6888

@@ -94,6 +114,12 @@
94114
expect(MemberEmailDelivery.where(member: student_without_toc)).to be_empty
95115
end
96116

117+
it "does not email students who have not attended in the past year" do
118+
perform_enqueued_jobs { call }
119+
120+
expect(MemberEmailDelivery.where(member: student_with_very_old_attendance)).to be_empty
121+
end
122+
97123
it "sends only one chaser for a member with multiple student subscriptions" do
98124
member = Fabricate(:member)
99125
other_chapter = Fabricate(:chapter)
@@ -151,6 +177,13 @@
151177
it "emails a student member who has recent attendance only as a coach" do
152178
member = Fabricate(:member)
153179
Fabricate(:subscription, member: member, group: students_group)
180+
Fabricate(
181+
:workshop_invitation,
182+
member: member,
183+
workshop: Fabricate(:workshop, chapter: chapter, date_and_time: 6.months.ago),
184+
role: "Student",
185+
attended: true
186+
)
154187
Fabricate(
155188
:workshop_invitation,
156189
member: member,

0 commit comments

Comments
 (0)