0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-05 22:42:07 +08:00
discourse/app/serializers/user_history_serializer.rb
Krzysztof Kotlarek d792c77895
FEATURE: Link staff action log entries to originating reviewable (#39519)
The staff action log records moderation actions (post deletions, user
suspensions, silences, user approvals, etc.) as `UserHistory` rows, but
entries triggered from the reviewable queue have no reference back to
the reviewable that caused them. When auditing a decision in the log,
staff can't jump to the flagged post, queued post, or user-approval
review that produced it.

Link to review is visible in the log:
<img width="900" height="674" alt="Screenshot 2026-04-24 at 2 17 04 pm"
src="https://github.com/user-attachments/assets/791ebc58-0a4d-4c2c-a363-efe482f5f755"
/>
2026-04-30 09:15:45 +08:00

74 lines
1.7 KiB
Ruby
Vendored

# frozen_string_literal: true
class UserHistorySerializer < ApplicationSerializer
attributes :action_name,
:details,
:context,
:ip_address,
:email,
:created_at,
:subject,
:previous_value,
:new_value,
:topic_id,
:post_id,
:category_id,
:reviewable_id,
:action,
:custom_type,
:id
has_one :acting_user, serializer: BasicUserSerializer, embed: :objects
has_one :target_user, serializer: BasicUserSerializer, embed: :objects
def action_name
key = UserHistory.actions.key(object.action)
%i[custom custom_staff].include?(key) ? object.custom_type : key.to_s
end
def details
redact_content? ? redacted_content : object.details
end
def context
redact_content? ? nil : object.context
end
def new_value
return nil if redact_content?
if object.new_value
object.new_value_is_json? ? ::JSON.parse(object.new_value) : object.new_value
else
nil
end
end
def previous_value
return nil if redact_content?
if object.previous_value
object.previous_value_is_json? ? ::JSON.parse(object.previous_value) : object.previous_value
else
nil
end
end
def ip_address
return nil unless scope.can_see_ip?
object.ip_address.try(:to_s)
end
def include_reviewable_id?
object.reviewable_id.present?
end
private
def redact_content?
return @redact_content if defined?(@redact_content)
@redact_content = !scope.can_see_staff_action_log_content?(object)
end
def redacted_content
I18n.t("staff_action_logs.redacted")
end
end