fix(captain): allow agents to manage FAQs
This commit is contained in:
parent
d670c5644b
commit
689cc114f8
@ -1,6 +1,6 @@
|
||||
class Api::V1::Accounts::Captain::AssistantResponsesController < Api::V1::Accounts::BaseController
|
||||
before_action :current_account
|
||||
before_action -> { check_authorization(Captain::Assistant) }
|
||||
before_action -> { check_authorization(Captain::AssistantResponse) }
|
||||
|
||||
before_action :set_current_page, only: [:index]
|
||||
before_action :set_assistant, only: [:create]
|
||||
@ -21,6 +21,7 @@ class Api::V1::Accounts::Captain::AssistantResponsesController < Api::V1::Accoun
|
||||
@response = Current.account.captain_assistant_responses.new(response_params)
|
||||
@response.documentable = Current.user
|
||||
@response.save!
|
||||
Captain::Llm::UpdateEmbeddingJob.perform_now(@response, "#{@response.question}: #{@response.answer}")
|
||||
end
|
||||
|
||||
def update
|
||||
@ -28,7 +29,7 @@ class Api::V1::Accounts::Captain::AssistantResponsesController < Api::V1::Accoun
|
||||
end
|
||||
|
||||
def destroy
|
||||
@response.destroy!
|
||||
@response.destroy
|
||||
head :no_content
|
||||
end
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
class Api::V1::Accounts::Captain::BulkActionsController < Api::V1::Accounts::BaseController
|
||||
before_action :current_account
|
||||
before_action -> { check_authorization(Captain::Assistant) }
|
||||
before_action -> { check_authorization(Captain::AssistantResponse) }
|
||||
before_action :validate_params
|
||||
before_action :type_matches?
|
||||
|
||||
@ -19,7 +19,7 @@ class Api::V1::Accounts::Captain::BulkActionsController < Api::V1::Accounts::Bas
|
||||
end
|
||||
|
||||
def type_matches?
|
||||
return false if MODEL_TYPE.include?(params[:type])
|
||||
return if MODEL_TYPE.include?(params[:type])
|
||||
|
||||
render json: { success: false }, status: :unprocessable_entity
|
||||
end
|
||||
@ -37,7 +37,7 @@ class Api::V1::Accounts::Captain::BulkActionsController < Api::V1::Accounts::Bas
|
||||
|
||||
case params[:fields][:status]
|
||||
when 'approve'
|
||||
responses.pending.update!(status: 'approved')
|
||||
responses.pending.update(status: 'approved')
|
||||
responses
|
||||
when 'delete'
|
||||
responses.destroy_all
|
||||
|
||||
33
enterprise/app/policies/captain/assistant_response_policy.rb
Normal file
33
enterprise/app/policies/captain/assistant_response_policy.rb
Normal file
@ -0,0 +1,33 @@
|
||||
class Captain::AssistantResponsePolicy < ApplicationPolicy
|
||||
def index?
|
||||
@account_user.administrator? || @account_user.agent?
|
||||
end
|
||||
|
||||
def show?
|
||||
index?
|
||||
end
|
||||
|
||||
def create?
|
||||
manage?
|
||||
end
|
||||
|
||||
def update?
|
||||
manage?
|
||||
end
|
||||
|
||||
def destroy?
|
||||
manage?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def manage?
|
||||
return true if @account_user.administrator?
|
||||
|
||||
if @account_user.custom_role.present?
|
||||
return @account_user.custom_role.permissions.include?('knowledge_base_manage')
|
||||
end
|
||||
|
||||
@account_user.agent?
|
||||
end
|
||||
end
|
||||
@ -6,6 +6,7 @@ RSpec.describe 'Api::V1::Accounts::Captain::AssistantResponses', type: :request
|
||||
let(:document) { create(:captain_document, assistant: assistant, account: account) }
|
||||
let(:admin) { create(:user, account: account, role: :administrator) }
|
||||
let(:agent) { create(:user, account: account, role: :agent) }
|
||||
let(:agent_with_custom_role) { create(:user, account: account, role: :agent) }
|
||||
let(:another_assistant) { create(:captain_assistant, account: account) }
|
||||
let(:another_document) { create(:captain_document, account: account, assistant: assistant) }
|
||||
|
||||
@ -179,6 +180,46 @@ RSpec.describe 'Api::V1::Accounts::Captain::AssistantResponses', type: :request
|
||||
expect(json_response[:answer]).to eq('Test answer')
|
||||
end
|
||||
|
||||
it 'creates a new response if the user is an agent' do
|
||||
expect do
|
||||
post "/api/v1/accounts/#{account.id}/captain/assistant_responses",
|
||||
params: valid_params,
|
||||
headers: agent.create_new_auth_token,
|
||||
as: :json
|
||||
end.to change(Captain::AssistantResponse, :count).by(1)
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(json_response[:question]).to eq('Test question?')
|
||||
end
|
||||
|
||||
it 'creates a new response if the user has a custom role with knowledge base permission' do
|
||||
custom_role = create(:custom_role, account: account, permissions: ['knowledge_base_manage'])
|
||||
AccountUser.find_by!(account: account, user: agent_with_custom_role).update!(custom_role: custom_role)
|
||||
|
||||
expect do
|
||||
post "/api/v1/accounts/#{account.id}/captain/assistant_responses",
|
||||
params: valid_params,
|
||||
headers: agent_with_custom_role.create_new_auth_token,
|
||||
as: :json
|
||||
end.to change(Captain::AssistantResponse, :count).by(1)
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
|
||||
it 'does not create a response if the custom role lacks knowledge base permission' do
|
||||
custom_role = create(:custom_role, account: account, permissions: ['conversation_manage'])
|
||||
AccountUser.find_by!(account: account, user: agent_with_custom_role).update!(custom_role: custom_role)
|
||||
|
||||
expect do
|
||||
post "/api/v1/accounts/#{account.id}/captain/assistant_responses",
|
||||
params: valid_params,
|
||||
headers: agent_with_custom_role.create_new_auth_token,
|
||||
as: :json
|
||||
end.not_to change(Captain::AssistantResponse, :count)
|
||||
|
||||
expect(response).to have_http_status(:forbidden)
|
||||
end
|
||||
|
||||
context 'with invalid params' do
|
||||
let(:invalid_params) do
|
||||
{
|
||||
@ -197,22 +238,6 @@ RSpec.describe 'Api::V1::Accounts::Captain::AssistantResponses', type: :request
|
||||
|
||||
expect(response).to have_http_status(:unprocessable_entity)
|
||||
end
|
||||
|
||||
it 'returns unprocessable entity when question exceeds 255 characters' do
|
||||
long_question = 'a' * 256
|
||||
post "/api/v1/accounts/#{account.id}/captain/assistant_responses",
|
||||
params: {
|
||||
assistant_response: {
|
||||
question: long_question,
|
||||
answer: 'Test answer',
|
||||
assistant_id: assistant.id
|
||||
}
|
||||
},
|
||||
headers: admin.create_new_auth_token,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:unprocessable_entity)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -239,6 +264,16 @@ RSpec.describe 'Api::V1::Accounts::Captain::AssistantResponses', type: :request
|
||||
expect(json_response[:answer]).to eq('Updated answer')
|
||||
end
|
||||
|
||||
it 'updates the response if the user is an agent' do
|
||||
patch "/api/v1/accounts/#{account.id}/captain/assistant_responses/#{response_record.id}",
|
||||
params: update_params,
|
||||
headers: agent.create_new_auth_token,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:ok)
|
||||
expect(json_response[:question]).to eq('Updated question?')
|
||||
end
|
||||
|
||||
context 'with invalid params' do
|
||||
let(:invalid_params) do
|
||||
{
|
||||
@ -266,7 +301,7 @@ RSpec.describe 'Api::V1::Accounts::Captain::AssistantResponses', type: :request
|
||||
it 'deletes the response' do
|
||||
expect do
|
||||
delete "/api/v1/accounts/#{account.id}/captain/assistant_responses/#{response_record.id}",
|
||||
headers: admin.create_new_auth_token,
|
||||
headers: agent.create_new_auth_token,
|
||||
as: :json
|
||||
end.to change(Captain::AssistantResponse, :count).by(-1)
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ RSpec.describe 'Api::V1::Accounts::Captain::BulkActions', type: :request do
|
||||
let(:assistant) { create(:captain_assistant, account: account) }
|
||||
let(:admin) { create(:user, account: account, role: :administrator) }
|
||||
let(:agent) { create(:user, account: account, role: :agent) }
|
||||
let(:agent_with_custom_role) { create(:user, account: account, role: :agent) }
|
||||
let!(:pending_responses) do
|
||||
create_list(
|
||||
:captain_assistant_response,
|
||||
@ -32,7 +33,7 @@ RSpec.describe 'Api::V1::Accounts::Captain::BulkActions', type: :request do
|
||||
it 'approves the responses and returns the updated records' do
|
||||
post "/api/v1/accounts/#{account.id}/captain/bulk_actions",
|
||||
params: valid_params,
|
||||
headers: admin.create_new_auth_token,
|
||||
headers: agent.create_new_auth_token,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:ok)
|
||||
@ -59,7 +60,7 @@ RSpec.describe 'Api::V1::Accounts::Captain::BulkActions', type: :request do
|
||||
expect do
|
||||
post "/api/v1/accounts/#{account.id}/captain/bulk_actions",
|
||||
params: delete_params,
|
||||
headers: admin.create_new_auth_token,
|
||||
headers: agent.create_new_auth_token,
|
||||
as: :json
|
||||
end.to change(Captain::AssistantResponse, :count).by(-2)
|
||||
|
||||
@ -73,6 +74,40 @@ RSpec.describe 'Api::V1::Accounts::Captain::BulkActions', type: :request do
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user has a custom role' do
|
||||
let(:approve_params) do
|
||||
{
|
||||
type: 'AssistantResponse',
|
||||
ids: pending_responses.map(&:id),
|
||||
fields: { status: 'approve' }
|
||||
}
|
||||
end
|
||||
|
||||
it 'allows bulk actions with knowledge base permission' do
|
||||
custom_role = create(:custom_role, account: account, permissions: ['knowledge_base_manage'])
|
||||
AccountUser.find_by!(account: account, user: agent_with_custom_role).update!(custom_role: custom_role)
|
||||
|
||||
post "/api/v1/accounts/#{account.id}/captain/bulk_actions",
|
||||
params: approve_params,
|
||||
headers: agent_with_custom_role.create_new_auth_token,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:ok)
|
||||
end
|
||||
|
||||
it 'rejects bulk actions without knowledge base permission' do
|
||||
custom_role = create(:custom_role, account: account, permissions: ['conversation_manage'])
|
||||
AccountUser.find_by!(account: account, user: agent_with_custom_role).update!(custom_role: custom_role)
|
||||
|
||||
post "/api/v1/accounts/#{account.id}/captain/bulk_actions",
|
||||
params: approve_params,
|
||||
headers: agent_with_custom_role.create_new_auth_token,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with invalid type' do
|
||||
let(:invalid_params) do
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user