From c3cd5d65dafd6519504558479b5bc1b6a96df2b5 Mon Sep 17 00:00:00 2001 From: Keegan George Date: Mon, 9 Jun 2025 12:32:27 -0700 Subject: [PATCH] DEV: Add spam --- .../discourse_ai/admin/ai_spam_controller.rb | 38 +++++++++- config/locales/client.en.yml | 1 + .../requests/admin/ai_spam_controller_spec.rb | 72 +++++++++++++++++++ 3 files changed, 110 insertions(+), 1 deletion(-) diff --git a/app/controllers/discourse_ai/admin/ai_spam_controller.rb b/app/controllers/discourse_ai/admin/ai_spam_controller.rb index 52ef6f4b..141a237e 100644 --- a/app/controllers/discourse_ai/admin/ai_spam_controller.rb +++ b/app/controllers/discourse_ai/admin/ai_spam_controller.rb @@ -10,6 +10,11 @@ module DiscourseAi end def update + # Get the initial settings for logging changes + initial_settings = AiModerationSetting.spam + initial_custom_instructions = initial_settings&.data&.dig("custom_instructions") + initial_llm_model_id = initial_settings&.llm_model_id + updated_params = {} if allowed_params.key?(:llm_model_id) llm_model_id = updated_params[:llm_model_id] = allowed_params[:llm_model_id] @@ -36,6 +41,9 @@ module DiscourseAi else AiModerationSetting.create!(updated_params.merge(setting_type: :spam)) end + + # Log any changes to custom_instructions or llm_model_id + log_ai_spam_update(initial_llm_model_id, initial_custom_instructions, allowed_params) end is_enabled = ActiveModel::Type::Boolean.new.cast(allowed_params[:is_enabled]) @@ -112,6 +120,34 @@ module DiscourseAi end private + + def log_ai_spam_update(initial_llm_model_id, initial_custom_instructions, params) + # Track changes for logging + changes_to_log = {} + + # Only track llm_model_id changes when it's in the params AND has actually changed + if params.key?(:llm_model_id) && initial_llm_model_id.to_s != params[:llm_model_id].to_s + # Get model names for better logging + old_model_name = LlmModel.find_by(id: initial_llm_model_id)&.display_name || initial_llm_model_id + new_model_name = LlmModel.find_by(id: params[:llm_model_id])&.display_name || params[:llm_model_id] + + changes_to_log[:llm_model_id] = "#{old_model_name} → #{new_model_name}" + end + + # Only track custom_instructions changes when it's in the params AND has actually changed + if params.key?(:custom_instructions) && initial_custom_instructions != params[:custom_instructions] + changes_to_log[:custom_instructions] = params[:custom_instructions] + end + + # Log the changes if any were made to llm_model_id or custom_instructions + if changes_to_log.present? + # Log the changes using StaffActionLogger (without a subject as requested) + StaffActionLogger.new(current_user).log_custom( + "update_ai_spam_settings", + changes_to_log + ) + end + end def allowed_params params.permit(:is_enabled, :llm_model_id, :custom_instructions) @@ -134,4 +170,4 @@ module DiscourseAi end end end -end +end \ No newline at end of file diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 616d44cc..0573bcd7 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -39,6 +39,7 @@ en: create_ai_embedding: "Create AI embedding" update_ai_embedding: "Update AI embedding" delete_ai_embedding: "Delete AI embedding" + update_ai_spam_settings: "Update AI spam settings" js: discourse_automation: diff --git a/spec/requests/admin/ai_spam_controller_spec.rb b/spec/requests/admin/ai_spam_controller_spec.rb index ccf05af7..6597fbef 100644 --- a/spec/requests/admin/ai_spam_controller_spec.rb +++ b/spec/requests/admin/ai_spam_controller_spec.rb @@ -119,6 +119,78 @@ RSpec.describe DiscourseAi::Admin::AiSpamController do "custom instructions new", ) end + + it "logs staff action when custom_instructions change" do + put "/admin/plugins/discourse-ai/ai-spam.json", + params: { + is_enabled: true, + llm_model_id: llm_model.id, + custom_instructions: "updated instructions" + } + + expect(response.status).to eq(200) + + # Verify the log was created with the right subject + history = UserHistory.where(action: UserHistory.actions[:custom_staff], custom_type: "update_ai_spam_settings").last + expect(history).to be_present + expect(history.subject).to eq("AI Spam Detection") + expect(history.details).to include("custom_instructions_changed") + end + + it "logs staff action when llm_model_id changes" do + # Create another model to change to + new_llm_model = Fabricate(:llm_model, name: "New Test Model", display_name: "New Test Model") + + put "/admin/plugins/discourse-ai/ai-spam.json", + params: { + llm_model_id: new_llm_model.id + } + + expect(response.status).to eq(200) + + # Verify the log was created with the right subject + history = UserHistory.where(action: UserHistory.actions[:custom_staff], custom_type: "update_ai_spam_settings").last + expect(history).to be_present + expect(history.subject).to eq("AI Spam Detection") + expect(history.details).to include("llm_model_id") + end + + it "does not log staff action when only is_enabled changes" do + # Check initial count of logs + initial_count = UserHistory.where(action: UserHistory.actions[:custom_staff], custom_type: "update_ai_spam_settings").count + + # Update only the is_enabled setting + put "/admin/plugins/discourse-ai/ai-spam.json", + params: { + is_enabled: false + } + + expect(response.status).to eq(200) + + # Verify no new log was created + current_count = UserHistory.where(action: UserHistory.actions[:custom_staff], custom_type: "update_ai_spam_settings").count + expect(current_count).to eq(initial_count) + end + + it "logs both custom_instructions and llm_model_id changes in one entry" do + # Create another model to change to + new_llm_model = Fabricate(:llm_model, name: "Another Test Model", display_name: "Another Test Model") + + put "/admin/plugins/discourse-ai/ai-spam.json", + params: { + llm_model_id: new_llm_model.id, + custom_instructions: "new instructions for both changes" + } + + expect(response.status).to eq(200) + + # Verify the log was created with all changes + history = UserHistory.where(action: UserHistory.actions[:custom_staff], custom_type: "update_ai_spam_settings").last + expect(history).to be_present + expect(history.subject).to eq("AI Spam Detection") + expect(history.details).to include("llm_model_id") + expect(history.details).to include("custom_instructions_changed") + end end end end