mirror of
https://github.com/discourse/discourse.git
synced 2026-08-05 21:57:36 +08:00
For upcoming changes, we were having a problem where we
were notifying admins of upcoming changes in brand new sites.
A previous fix 2e5afb46e2f5c0547bc298b2bd1a9c39e813dc17 tried
to remedy this, but since it relies on the `new_site?` method, which
isn't true after 1 hour, the next time the scheduled notifications are
run for an admin they will be sent them even if their site is relatively
new.
This commit attempts to conclusively fix the issue by inserting
upcoming change `admins_notified_automatic_promotion` and
`admins_notified_available_change` events via `BackfillNotifiedEvents`
for changes that exist in particular statuses when the site is first
created. These events will have `event_data: {"backfilled" => true}`
to distinguish them from others.
It also fixes an adjacent issue where an admin was notified of a
plugin's upcoming changes as soon as they enable the plugin,
which isn't useful as the intent of upcoming changes is to notify
of changes for things the admin has already been using.
**Before this change, on brand new site with current upcoming change
state**
<img width="401" height="429" alt="image"
src="https://github.com/user-attachments/assets/a89cd641-59aa-4c48-a57c-9692021df176"
/>
**After this change**
No notification to show :) But when I moved an upcoming change to `beta`
it showed
the notification for the enabled upcoming change correctly:
<img width="378" height="174" alt="image"
src="https://github.com/user-attachments/assets/20e4096f-e83f-4c06-970d-a9b43561b12e"
/>
94 lines
3.2 KiB
Ruby
Vendored
94 lines
3.2 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
# Notify admins of all upcoming changes' promotions,
|
|
# which is called from the Jobs::Scheduled::CheckUpcomingChanges job.
|
|
class UpcomingChanges::NotifyPromotions
|
|
include Service::Base
|
|
|
|
model :changes_already_notified_about_promotion, optional: true
|
|
model :changes_already_promoted, optional: true
|
|
model :admin_user_ids
|
|
model :change_notification_statuses
|
|
|
|
private
|
|
|
|
def fetch_changes_already_notified_about_promotion
|
|
UpcomingChangeEvent.change_names_with_event(:admins_notified_automatic_promotion)
|
|
end
|
|
|
|
def fetch_changes_already_promoted
|
|
UpcomingChangeEvent.change_names_with_event(:automatically_promoted)
|
|
end
|
|
|
|
def fetch_admin_user_ids
|
|
User.human_users.admins.pluck(:id)
|
|
end
|
|
|
|
def fetch_change_notification_statuses(
|
|
changes_already_notified_about_promotion:,
|
|
changes_already_promoted:,
|
|
admin_user_ids:
|
|
)
|
|
SiteSetting.upcoming_change_site_settings.index_with do |setting_name|
|
|
status_hash = {}
|
|
|
|
# NOTE: Make sure to handle additional error_key values in the
|
|
# CheckUpcomingChanges job's verbose_log.
|
|
UpcomingChanges::NotifyPromotion.call(
|
|
params: {
|
|
setting_name: setting_name.to_sym,
|
|
changes_already_notified_about_promotion:,
|
|
changes_already_promoted:,
|
|
admin_user_ids:,
|
|
},
|
|
guardian: Discourse.system_user.guardian,
|
|
) do |result|
|
|
status_hash[:success] = result.success?
|
|
|
|
on_failed_policy(:setting_is_available) do |policy|
|
|
status_hash[:error] = "Setting #{setting_name} is not available"
|
|
status_hash[:error_key] = :setting_not_available
|
|
end
|
|
|
|
on_failed_policy(:should_notify_admins) do |policy|
|
|
status_hash[:error] = "Setting #{setting_name} should not notify admins about promotion"
|
|
status_hash[:error_key] = :should_not_notify_admins
|
|
end
|
|
|
|
on_failed_policy(:change_should_be_displayed) do |policy|
|
|
status_hash[
|
|
:error
|
|
] = "Setting #{setting_name} is not displayed on this site, skipping promotion notification"
|
|
status_hash[:error_key] = :should_not_be_displayed
|
|
end
|
|
|
|
on_failed_policy(:meets_or_exceeds_status) do |policy|
|
|
status_hash[
|
|
:error
|
|
] = "Setting #{setting_name} does not meet or exceed the promotion status"
|
|
status_hash[:error_key] = :does_not_meet_or_exceed_promotion_status
|
|
end
|
|
|
|
on_failed_policy(:promotion_not_already_handled) do |policy|
|
|
status_hash[:error] = "Setting #{setting_name} has already been promoted"
|
|
status_hash[:error_key] = :already_promoted
|
|
end
|
|
|
|
on_failed_policy(:admin_has_not_manually_toggled) do |policy|
|
|
status_hash[
|
|
:error
|
|
] = "Setting #{setting_name} has been manually opted in or out by an admin, we did not notify admins about promotion"
|
|
status_hash[:error_key] = :already_manually_toggled
|
|
end
|
|
|
|
on_exceptions do |exception|
|
|
status_hash[:error] = exception.message
|
|
status_hash[:error_key] = :unexpected_error
|
|
status_hash[:backtrace] = exception.backtrace
|
|
end
|
|
end
|
|
|
|
status_hash
|
|
end
|
|
end
|
|
end
|