Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions app/tasks/maintenance/discard_stale_unconfirmed_accounts_task.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

class Maintenance::DiscardStaleUnconfirmedAccountsTask < MaintenanceTasks::Task
include SemanticLogger::Loggable

UNCONFIRMED_USER_RETENTION_DAYS = 30.days

def collection
User
Copy link
Member

@jenshenny jenshenny Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually could this happen?

  1. User creates account long ago that has gems
  2. User recently changes email within 30 days but never confirmed it
  3. We delete their account

.not_deleted
.where(email_confirmed: false)
.where(created_at: ...UNCONFIRMED_USER_RETENTION_DAYS.ago)
end

def process(user)
logger.tagged(user_id: user.id, email: user.email) do
user.transaction do
user.discard!
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# frozen_string_literal: true

require "test_helper"

class Maintenance::DiscardStaleUnconfirmedAccountsTaskTest < ActiveSupport::TestCase
test "#process discards stale unconfirmed users" do
stale_unconfirmed_user = create(:user, :unconfirmed, created_at: actionable_timestamp)

refute_predicate stale_unconfirmed_user, :discarded?

Maintenance::DiscardStaleUnconfirmedAccountsTask.process(stale_unconfirmed_user)

assert_predicate stale_unconfirmed_user, :discarded?
end

test "#collection returns discardable users" do
confirmed_user = create(:user, created_at: actionable_timestamp)
recent_unconfirmed_user = create(:user, :unconfirmed, created_at: 7.days.ago)
stale_unconfirmed_user = create(:user, :unconfirmed, created_at: actionable_timestamp)
discarded_user = create(:user, :unconfirmed, created_at: actionable_timestamp)
discarded_user.discard!

discardable_users = Maintenance::DiscardStaleUnconfirmedAccountsTask.collection

assert_includes discardable_users, stale_unconfirmed_user

assert_not_includes discardable_users, confirmed_user
assert_not_includes discardable_users, recent_unconfirmed_user
assert_not_includes discardable_users, discarded_user
end

def actionable_timestamp
Maintenance::DiscardStaleUnconfirmedAccountsTask::UNCONFIRMED_USER_RETENTION_DAYS.ago
end
end
Loading