71 lines
2.5 KiB
Ruby
71 lines
2.5 KiB
Ruby
class Captain::Reports::GenerateInsightsJob < ApplicationJob
|
|
queue_as :default
|
|
|
|
# Gera insights de IA para uma unidade ou inbox específica em um período.
|
|
# Pode ser disparado on-demand (botão na UI) ou pelo WeeklyInsightsJob.
|
|
def perform(account_id, unit_id, period_start, period_end, inbox_id = nil)
|
|
# Ensure dates are Date objects as they might be serialized as strings in Sidekiq
|
|
period_start = period_start.is_a?(String) ? Date.parse(period_start) : period_start
|
|
period_end = period_end.is_a?(String) ? Date.parse(period_end) : period_end
|
|
|
|
account = Account.find_by(id: account_id)
|
|
return unless account
|
|
|
|
unit = account.captain_units.find_by(id: unit_id) if unit_id
|
|
inbox = account.inboxes.find_by(id: inbox_id) if inbox_id
|
|
|
|
insight = find_or_create_insight(account_id, unit_id, inbox_id, period_start, period_end)
|
|
return if insight.processing? || insight.done?
|
|
|
|
insight.mark_processing!
|
|
run_analysis(account, unit, inbox, insight, period_start, period_end)
|
|
rescue StandardError => e
|
|
Rails.logger.error "[Captain::Reports::GenerateInsightsJob] Error: #{e.message}\n#{e.backtrace&.first(5)&.join("\n")}"
|
|
insight&.mark_failed!
|
|
end
|
|
|
|
private
|
|
|
|
def find_or_create_insight(account_id, unit_id, inbox_id, period_start, period_end)
|
|
insight = Captain::ConversationInsight.find_or_initialize_by(
|
|
account_id: account_id,
|
|
captain_unit_id: unit_id,
|
|
inbox_id: inbox_id,
|
|
period_start: period_start,
|
|
period_end: period_end
|
|
)
|
|
insight.save! if insight.new_record?
|
|
insight
|
|
end
|
|
|
|
def run_analysis(account, unit, inbox, insight, period_start, period_end)
|
|
conversations = fetch_conversations(account, unit, inbox, period_start, period_end)
|
|
insight.update!(conversations_count: conversations.count)
|
|
|
|
payload = Captain::Llm::ConversationInsightService.new(
|
|
account: account,
|
|
unit: unit,
|
|
inbox: inbox,
|
|
conversations: conversations
|
|
).analyze
|
|
|
|
insight.update!(messages_count: conversations.sum { |conv| conv.messages.count })
|
|
insight.mark_done!(payload)
|
|
end
|
|
|
|
def fetch_conversations(account, unit, inbox, period_start, period_end)
|
|
scope = account.conversations
|
|
.where(created_at: period_start.beginning_of_day..period_end.end_of_day)
|
|
.includes(:messages)
|
|
|
|
if inbox
|
|
scope = scope.where(inbox_id: inbox.id)
|
|
elsif unit
|
|
inbox_ids = unit.inboxes.pluck(:id)
|
|
scope = scope.where(inbox_id: inbox_ids) if inbox_ids.any?
|
|
end
|
|
|
|
scope.to_a
|
|
end
|
|
end
|