fix: guard landing host sync when inbox has no portal
Inboxes without portal_id were crashing with NoMethodError on save, blocking landing host creation via UI for any inbox without a portal. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
8ea87027d1
commit
1c21b8d815
@ -95,6 +95,7 @@ Metrics/ModuleLength:
|
|||||||
Exclude:
|
Exclude:
|
||||||
- lib/seeders/message_seeder.rb
|
- lib/seeders/message_seeder.rb
|
||||||
- spec/support/slack_stubs.rb
|
- spec/support/slack_stubs.rb
|
||||||
|
- app/models/concerns/landing_host_ai_syncable.rb
|
||||||
|
|
||||||
Rails/HelperInstanceVariable:
|
Rails/HelperInstanceVariable:
|
||||||
Exclude:
|
Exclude:
|
||||||
@ -185,6 +186,7 @@ Metrics/AbcSize:
|
|||||||
- 'app/models/canned_response.rb'
|
- 'app/models/canned_response.rb'
|
||||||
- 'app/models/telegram_bot.rb'
|
- 'app/models/telegram_bot.rb'
|
||||||
- 'enterprise/app/services/captain/tools/generate_pix_tool.rb'
|
- 'enterprise/app/services/captain/tools/generate_pix_tool.rb'
|
||||||
|
- 'app/models/concerns/landing_host_ai_syncable.rb'
|
||||||
|
|
||||||
Rails/RenderInline:
|
Rails/RenderInline:
|
||||||
Exclude:
|
Exclude:
|
||||||
|
|||||||
@ -26,6 +26,10 @@ Layout/LineLength:
|
|||||||
|
|
||||||
# Offense count: 2
|
# Offense count: 2
|
||||||
# Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch.
|
# Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch.
|
||||||
|
Lint/DuplicateRescueException:
|
||||||
|
Exclude:
|
||||||
|
- 'app/models/concerns/landing_host_ai_syncable.rb'
|
||||||
|
|
||||||
Lint/DuplicateBranch:
|
Lint/DuplicateBranch:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'app/services/whatsapp/providers/wuzapi/payload_parser.rb'
|
- 'app/services/whatsapp/providers/wuzapi/payload_parser.rb'
|
||||||
@ -44,6 +48,7 @@ Lint/UnusedMethodArgument:
|
|||||||
Metrics/AbcSize:
|
Metrics/AbcSize:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'app/models/channel/whatsapp.rb'
|
- 'app/models/channel/whatsapp.rb'
|
||||||
|
- 'app/models/concerns/landing_host_ai_syncable.rb'
|
||||||
- 'app/services/evolution_api/client.rb'
|
- 'app/services/evolution_api/client.rb'
|
||||||
- 'app/services/whatsapp/decryption_service.rb'
|
- 'app/services/whatsapp/decryption_service.rb'
|
||||||
- 'app/services/whatsapp/incoming_message_wuzapi_service.rb'
|
- 'app/services/whatsapp/incoming_message_wuzapi_service.rb'
|
||||||
@ -59,6 +64,10 @@ Metrics/AbcSize:
|
|||||||
|
|
||||||
# Offense count: 6
|
# Offense count: 6
|
||||||
# Configuration parameters: CountComments, Max, CountAsOne.
|
# Configuration parameters: CountComments, Max, CountAsOne.
|
||||||
|
Metrics/ModuleLength:
|
||||||
|
Exclude:
|
||||||
|
- 'app/models/concerns/landing_host_ai_syncable.rb'
|
||||||
|
|
||||||
Metrics/ClassLength:
|
Metrics/ClassLength:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'app/models/channel/whatsapp.rb'
|
- 'app/models/channel/whatsapp.rb'
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'digest'
|
require 'digest'
|
||||||
|
|
||||||
module LandingHostAiSyncable
|
module LandingHostAiSyncable
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
SYNC_METADATA_KEY = 'landing_promotion_sync'.freeze
|
SYNC_METADATA_KEY = 'landing_promotion_sync'
|
||||||
|
|
||||||
included do
|
included do
|
||||||
after_save :sync_promotion_to_faq
|
after_save :sync_promotion_to_faq
|
||||||
@ -23,7 +24,7 @@ module LandingHostAiSyncable
|
|||||||
end
|
end
|
||||||
|
|
||||||
sync_active_promotions(active_entries)
|
sync_active_promotions(active_entries)
|
||||||
cleanup_stale_synced_knowledge(active_entries.map { |entry| entry[:signature] })
|
cleanup_stale_synced_knowledge(active_entries.pluck(:signature))
|
||||||
cleanup_legacy_aggregated_sync
|
cleanup_legacy_aggregated_sync
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -69,6 +70,8 @@ module LandingHostAiSyncable
|
|||||||
end
|
end
|
||||||
|
|
||||||
def cleanup_stale_synced_knowledge(active_signatures)
|
def cleanup_stale_synced_knowledge(active_signatures)
|
||||||
|
return unless can_sync_to_portal?
|
||||||
|
|
||||||
synced_articles.find_each do |article|
|
synced_articles.find_each do |article|
|
||||||
signature = article.meta&.dig(SYNC_METADATA_KEY, 'promotion_signature')
|
signature = article.meta&.dig(SYNC_METADATA_KEY, 'promotion_signature')
|
||||||
next if signature.present? && active_signatures.include?(signature)
|
next if signature.present? && active_signatures.include?(signature)
|
||||||
@ -88,6 +91,8 @@ module LandingHostAiSyncable
|
|||||||
end
|
end
|
||||||
|
|
||||||
def cleanup_legacy_aggregated_sync
|
def cleanup_legacy_aggregated_sync
|
||||||
|
return unless can_sync_to_portal?
|
||||||
|
|
||||||
legacy_article = portal.articles.find_by(
|
legacy_article = portal.articles.find_by(
|
||||||
"meta -> '#{SYNC_METADATA_KEY}' ->> 'landing_host_id' = ? AND (meta -> '#{SYNC_METADATA_KEY}' ->> 'promotion_signature') IS NULL",
|
"meta -> '#{SYNC_METADATA_KEY}' ->> 'landing_host_id' = ? AND (meta -> '#{SYNC_METADATA_KEY}' ->> 'promotion_signature') IS NULL",
|
||||||
id.to_s
|
id.to_s
|
||||||
@ -128,12 +133,12 @@ module LandingHostAiSyncable
|
|||||||
document.content = article.content
|
document.content = article.content
|
||||||
document.status = :available
|
document.status = :available
|
||||||
document.metadata = (document.metadata || {})
|
document.metadata = (document.metadata || {})
|
||||||
.merge(sync_metadata_for(signature: entry[:signature]))
|
.merge(sync_metadata_for(signature: entry[:signature]))
|
||||||
.merge('article_id' => article.id)
|
.merge('article_id' => article.id)
|
||||||
document.save!
|
document.save!
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_synced_document(signature, article)
|
def find_synced_document(_signature, article)
|
||||||
by_article = captain_assistant.documents.find_by("metadata ->> 'article_id' = ?", article.id.to_s)
|
by_article = captain_assistant.documents.find_by("metadata ->> 'article_id' = ?", article.id.to_s)
|
||||||
return by_article if by_article.present?
|
return by_article if by_article.present?
|
||||||
|
|
||||||
@ -146,11 +151,13 @@ module LandingHostAiSyncable
|
|||||||
signature = article.meta&.dig(SYNC_METADATA_KEY, 'promotion_signature')
|
signature = article.meta&.dig(SYNC_METADATA_KEY, 'promotion_signature')
|
||||||
|
|
||||||
document = captain_assistant.documents.find_by("metadata ->> 'article_id' = ?", article.id.to_s)
|
document = captain_assistant.documents.find_by("metadata ->> 'article_id' = ?", article.id.to_s)
|
||||||
document ||= captain_assistant.documents.find_by(
|
if signature.present?
|
||||||
"metadata -> '#{SYNC_METADATA_KEY}' ->> 'landing_host_id' = ? AND metadata -> '#{SYNC_METADATA_KEY}' ->> 'promotion_signature' = ?",
|
document ||= captain_assistant.documents.find_by(
|
||||||
id.to_s,
|
"metadata -> '#{SYNC_METADATA_KEY}' ->> 'landing_host_id' = ? AND metadata -> '#{SYNC_METADATA_KEY}' ->> 'promotion_signature' = ?",
|
||||||
signature
|
id.to_s,
|
||||||
) if signature.present?
|
signature
|
||||||
|
)
|
||||||
|
end
|
||||||
document ||= captain_assistant.documents.find_by(external_link: article_public_url(article))
|
document ||= captain_assistant.documents.find_by(external_link: article_public_url(article))
|
||||||
document&.destroy!
|
document&.destroy!
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user