79 lines
2.7 KiB
Ruby
79 lines
2.7 KiB
Ruby
# == Schema Information
|
|
#
|
|
# Table name: captain_contact_memories
|
|
#
|
|
# id :bigint not null, primary key
|
|
# account_id :bigint not null
|
|
# contact_id :bigint not null
|
|
# memory_type :string not null
|
|
# content :text not null
|
|
# evidence :text not null
|
|
# confidence :float not null
|
|
# scope :string not null, default: 'global'
|
|
# embedding :vector(1536)
|
|
# source_conversation_id :bigint
|
|
# source_unit_id :bigint
|
|
# source_inbox_id :bigint
|
|
# expires_at :datetime
|
|
# last_verified_at :datetime not null
|
|
# superseded_at :datetime
|
|
# superseded_by_id :bigint
|
|
# deleted_at :datetime
|
|
# metadata :jsonb not null, default: {}
|
|
# created_at :datetime not null
|
|
# updated_at :datetime not null
|
|
#
|
|
class Captain::ContactMemory < ApplicationRecord
|
|
self.table_name = 'captain_contact_memories'
|
|
|
|
MEMORY_TYPES = %w[
|
|
preferencia data_comemorativa vinculo_social padrao_comportamental
|
|
reclamacao feedback_positivo restricao vinculo_comercial contexto_pessoal
|
|
].freeze
|
|
|
|
belongs_to :account
|
|
belongs_to :contact
|
|
belongs_to :source_conversation, class_name: 'Conversation', optional: true
|
|
belongs_to :source_unit, class_name: 'Captain::Unit', optional: true
|
|
belongs_to :source_inbox, class_name: 'Inbox', optional: true
|
|
belongs_to :superseded_by, class_name: 'Captain::ContactMemory', optional: true
|
|
|
|
has_neighbors :embedding, normalize: true
|
|
|
|
validates :memory_type, presence: true, inclusion: { in: MEMORY_TYPES }
|
|
validates :content, presence: true, length: { maximum: 1000 }
|
|
validates :evidence, presence: true
|
|
validates :confidence, presence: true, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 1 }
|
|
validates :scope, presence: true
|
|
|
|
scope :active, lambda {
|
|
where(deleted_at: nil, superseded_at: nil)
|
|
.where('expires_at IS NULL OR expires_at > ?', Time.current)
|
|
}
|
|
|
|
scope :for_contact, ->(id) { where(contact_id: id) }
|
|
scope :by_type, ->(type) { where(memory_type: type) }
|
|
|
|
scope :scope_compatible, lambda { |unit_id|
|
|
if unit_id.present?
|
|
where(scope: ['global', "unit:#{unit_id}"])
|
|
else
|
|
where(scope: 'global')
|
|
end
|
|
}
|
|
|
|
def soft_delete!
|
|
update!(deleted_at: Time.current)
|
|
end
|
|
|
|
def supersede_by!(other)
|
|
update!(superseded_at: Time.current, superseded_by_id: other.id)
|
|
end
|
|
|
|
def recall_weight
|
|
return 0.7 if expires_at.present? && expires_at < Time.current
|
|
|
|
1.0
|
|
end
|
|
end
|