DEV: Grant all anniversary badges during imports (#31830)

This change adds an import step to retroactively grant anniversary
badges to users.
This commit is contained in:
Selase Krakani
2025-03-18 10:45:47 +00:00
committed by GitHub
parent b1b2b8e4c8
commit fb5cdb1da4
+76
View File
@@ -100,6 +100,8 @@ class BulkImport::Generic < BulkImport::Base
import_badge_groupings
import_badges
import_user_badges
import_anniversary_user_badges
update_badge_grant_counts
import_optimized_images
@@ -2406,7 +2408,81 @@ class BulkImport::Generic < BulkImport::Base
end
user_badges.close
end
def import_anniversary_user_badges
unless SiteSetting.enable_badges?
puts "", "Skipping anniversary user badges because badges are not enabled."
return
end
puts "", "Importing anniversary user badges..."
start_time = Time.now
DB.exec(<<~SQL)
WITH
eligible_users AS (
SELECT u.id, u.created_at
FROM users u
WHERE u.active
AND NOT u.staged
AND u.id > 0
AND (u.silenced_till IS NULL OR u.silenced_till < CURRENT_TIMESTAMP)
AND (u.suspended_till IS NULL OR u.suspended_till < CURRENT_TIMESTAMP)
AND NOT EXISTS (SELECT 1 FROM anonymous_users AS au WHERE au.user_id = u.id)
),
anniversary_dates AS ( -- Series of anniversary dates starting from the user's created_at + 1 year up to the current year
SELECT
eu.id AS user_id,
(
eu.created_at +
((year_num - EXTRACT(YEAR FROM eu.created_at)) || ' years')::interval
)::timestamp AS anniversary_date
FROM eligible_users eu,
generate_series(
EXTRACT(YEAR FROM eu.created_at)::int + 1,
EXTRACT(YEAR FROM CURRENT_TIMESTAMP)::int
) AS year_num
WHERE
(
eu.created_at +
((year_num - EXTRACT(YEAR FROM eu.created_at)) || ' years')::interval
) < CURRENT_TIMESTAMP
)
INSERT INTO user_badges (granted_at, created_at, granted_by_id, user_id, badge_id, seq)
SELECT a.anniversary_date,
CURRENT_TIMESTAMP,
#{Discourse.system_user.id},
a.user_id,
#{Badge::Anniversary},
(ROW_NUMBER() OVER (PARTITION BY a.user_id ORDER BY a.anniversary_date) - 1) AS seq
FROM anniversary_dates a
JOIN eligible_users u ON a.user_id = u.id
JOIN posts AS p ON p.user_id = u.id
JOIN topics AS t ON p.topic_id = t.id
WHERE p.deleted_at IS NULL
AND NOT p.hidden
AND p.created_at BETWEEN a.anniversary_date - '1 year'::interval AND a.anniversary_date
AND t.visible
AND t.archetype <> 'private_message'
AND t.deleted_at IS NULL
AND NOT EXISTS (
SELECT 1
FROM user_badges AS ub
WHERE ub.user_id = u.id
AND ub.badge_id = #{Badge::Anniversary}
AND ub.granted_at BETWEEN a.anniversary_date - '1 year'::interval AND a.anniversary_date
)
GROUP BY a.user_id, a.anniversary_date
SQL
UserBadge.update_featured_ranks!
puts " Anniversary user badges imported in #{(Time.now - start_time).to_i} seconds."
end
def update_badge_grant_counts
puts "", "Updating badge grant counts..."
start_time = Time.now