148 lines
4.7 KiB
Ruby
148 lines
4.7 KiB
Ruby
class Api::V1::Accounts::Captain::UnitsController < Api::V1::Accounts::BaseController
|
|
before_action :ensure_captain_enabled
|
|
before_action :set_unit, only: [:show, :update, :destroy, :update_concierge]
|
|
|
|
def index
|
|
@units = Current.account.captain_units.includes(:inboxes)
|
|
@units = filter_units_by_user_access(@units)
|
|
render json: @units.map { |u| format_unit(u) }
|
|
end
|
|
|
|
def show
|
|
render json: format_unit(@unit)
|
|
end
|
|
|
|
def create
|
|
@unit = Current.account.captain_units.build(unit_params)
|
|
@unit.captain_brand_id ||= default_brand.id
|
|
ActiveRecord::Base.transaction do
|
|
@unit.save!
|
|
sync_inboxes!(@unit, inbox_ids_param)
|
|
end
|
|
render json: format_unit(@unit), status: :created
|
|
rescue ActiveRecord::RecordInvalid
|
|
render json: { errors: @unit.errors.full_messages }, status: :unprocessable_entity
|
|
end
|
|
|
|
def update
|
|
ActiveRecord::Base.transaction do
|
|
@unit.update!(unit_params)
|
|
sync_inboxes!(@unit, inbox_ids_param) if params[:captain_unit].key?(:inbox_ids)
|
|
end
|
|
render json: format_unit(@unit)
|
|
rescue ActiveRecord::RecordInvalid
|
|
render json: { errors: @unit.errors.full_messages }, status: :unprocessable_entity
|
|
end
|
|
|
|
def destroy
|
|
@unit.destroy!
|
|
head :no_content
|
|
end
|
|
|
|
def update_concierge
|
|
return render json: { error: 'Unauthorized' }, status: :unauthorized unless Current.user.administrator?
|
|
|
|
@unit.update!(concierge_params)
|
|
render json: format_unit(@unit)
|
|
rescue ActiveRecord::RecordInvalid
|
|
render json: { errors: @unit.errors.full_messages }, status: :unprocessable_entity
|
|
end
|
|
|
|
private
|
|
|
|
def ensure_captain_enabled
|
|
# Dependendo da regra de negócio, pode-se verificar as features da conta aqui original
|
|
end
|
|
|
|
# Administrador vê todas as unidades; agente só vê unidades vinculadas a
|
|
# alguma caixa de entrada a qual ele tem acesso.
|
|
def filter_units_by_user_access(scope)
|
|
return scope if Current.user.administrator?
|
|
|
|
accessible_inbox_ids = Current.user.assigned_inboxes.pluck(:id)
|
|
return scope.none if accessible_inbox_ids.empty?
|
|
|
|
scope.joins(:inboxes).where(inboxes: { id: accessible_inbox_ids }).distinct
|
|
end
|
|
|
|
def default_brand
|
|
@default_brand ||= Captain::Brand.where(account_id: Current.account.id).first ||
|
|
Captain::Brand.create!(
|
|
account_id: Current.account.id,
|
|
name: 'Marca padrão'
|
|
)
|
|
end
|
|
|
|
def set_unit
|
|
@unit = Current.account.captain_units.includes(:inboxes).find(params[:id])
|
|
end
|
|
|
|
def unit_params
|
|
params.require(:captain_unit).permit(
|
|
:name,
|
|
:inter_client_id,
|
|
:inter_client_secret,
|
|
:inter_pix_key,
|
|
:inter_account_number,
|
|
:inter_cert_content,
|
|
:inter_key_content,
|
|
:proactive_pix_polling_enabled
|
|
)
|
|
end
|
|
|
|
def concierge_params
|
|
params.require(:captain_unit).permit(
|
|
:concierge_inbox_id,
|
|
concierge_config: [:persona_name, :knowledge, { variables: {} }]
|
|
)
|
|
end
|
|
|
|
def inbox_ids_param
|
|
return [] unless params[:captain_unit].key?(:inbox_ids)
|
|
|
|
Array(params[:captain_unit][:inbox_ids]).map(&:to_i).select(&:positive?)
|
|
end
|
|
|
|
# Sincroniza a lista de inboxes de uma unit: adiciona novas, remove ausentes.
|
|
# Garante que apenas inboxes da mesma conta sejam aceitas.
|
|
def sync_inboxes!(unit, ids)
|
|
valid_ids = Current.account.inboxes.where(id: ids).pluck(:id)
|
|
|
|
# Remove vínculos não presentes na nova lista
|
|
unit.unit_inboxes.where.not(inbox_id: valid_ids).destroy_all
|
|
|
|
# Adiciona novos vínculos (ignora duplicatas via uniqueness)
|
|
existing_ids = unit.unit_inboxes.pluck(:inbox_id)
|
|
(valid_ids - existing_ids).each do |inbox_id|
|
|
unit.unit_inboxes.create!(inbox_id: inbox_id)
|
|
end
|
|
end
|
|
|
|
def format_unit(unit) # rubocop:disable Metrics/AbcSize
|
|
inboxes = unit.inboxes.to_a
|
|
{
|
|
id: unit.id,
|
|
name: unit.name,
|
|
inter_client_id: unit.inter_client_id,
|
|
inter_pix_key: unit.inter_pix_key,
|
|
inter_account_number: unit.inter_account_number,
|
|
inbox_ids: inboxes.map(&:id),
|
|
inbox_names: inboxes.map(&:name),
|
|
# Mantém inbox_id e inbox_name como atalho para compatibilidade com código legado
|
|
inbox_id: inboxes.first&.id,
|
|
inbox_name: inboxes.first&.name,
|
|
has_cert: unit.inter_cert_content.present? || unit.resolved_inter_cert_path.present?,
|
|
has_key: unit.inter_key_content.present? || unit.resolved_inter_key_path.present?,
|
|
has_client_secret: unit.inter_client_secret.present?,
|
|
proactive_pix_polling_enabled: unit.proactive_pix_polling_enabled
|
|
}.merge(format_concierge(unit))
|
|
end
|
|
|
|
def format_concierge(unit)
|
|
{
|
|
concierge_inbox_id: unit.concierge_inbox_id,
|
|
concierge_config: unit.concierge_config || {}
|
|
}
|
|
end
|
|
end
|