mirror of
https://github.com/we-promise/sure.git
synced 2026-04-19 12:04:08 +00:00
Add AI cache clearing infrastructure
Add ClearAiCacheJob for async cache clearing with low priority. Extend Enrichable concern with clear_ai_cache methods to unlock AI-enriched attributes and delete AI enrichment records. Trigger automatic cache clearing when OpenAI model setting changes.
This commit is contained in:
@@ -15,6 +15,8 @@ module Enrichable
|
||||
InvalidAttributeError = Class.new(StandardError)
|
||||
|
||||
included do
|
||||
has_many :data_enrichments, as: :enrichable, dependent: :destroy
|
||||
|
||||
scope :enrichable, ->(attrs) {
|
||||
attrs = Array(attrs).map(&:to_s)
|
||||
json_condition = attrs.each_with_object({}) { |attr, hash| hash[attr] = true }
|
||||
@@ -22,6 +24,28 @@ module Enrichable
|
||||
}
|
||||
end
|
||||
|
||||
class_methods do
|
||||
def clear_ai_cache(family)
|
||||
# Get all records that belong to this family
|
||||
records = if respond_to?(:joins)
|
||||
case name
|
||||
when "Transaction"
|
||||
joins(entry: :account).where(accounts: { family_id: family.id })
|
||||
when "Entry"
|
||||
joins(:account).where(accounts: { family_id: family.id })
|
||||
else
|
||||
none
|
||||
end
|
||||
else
|
||||
none
|
||||
end
|
||||
|
||||
records.find_each do |record|
|
||||
record.clear_ai_cache
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Convenience method for a single attribute
|
||||
def enrich_attribute(attr, value, source:, metadata: {})
|
||||
enrich_attributes({ attr => value }, source:, metadata:)
|
||||
@@ -124,6 +148,21 @@ module Enrichable
|
||||
end
|
||||
end
|
||||
|
||||
def clear_ai_cache
|
||||
ActiveRecord::Base.transaction do
|
||||
# Find attributes that were locked by AI enrichment
|
||||
ai_enriched_attrs = data_enrichments.where(source: "ai").pluck(:attribute_name).uniq
|
||||
|
||||
# Remove locks for AI-enriched attributes
|
||||
ai_enriched_attrs.each do |attr|
|
||||
unlock_attr!(attr) if locked?(attr)
|
||||
end
|
||||
|
||||
# Delete AI enrichment records
|
||||
data_enrichments.where(source: "ai").delete_all
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def log_enrichment(attribute_name:, attribute_value:, source:, metadata: {})
|
||||
de = DataEnrichment.find_or_create_by(
|
||||
|
||||
@@ -80,6 +80,8 @@ class Setting < RailsSettings::Base
|
||||
class << self
|
||||
alias_method :raw_onboarding_state, :onboarding_state
|
||||
alias_method :raw_onboarding_state=, :onboarding_state=
|
||||
alias_method :raw_openai_model, :openai_model
|
||||
alias_method :raw_openai_model=, :openai_model=
|
||||
|
||||
def onboarding_state
|
||||
value = raw_onboarding_state
|
||||
@@ -94,6 +96,18 @@ class Setting < RailsSettings::Base
|
||||
self.raw_onboarding_state = state
|
||||
end
|
||||
|
||||
def openai_model=(value)
|
||||
old_value = raw_openai_model
|
||||
self.raw_openai_model = value
|
||||
|
||||
if old_value != value && old_value.present?
|
||||
Rails.logger.info("OpenAI model changed from #{old_value} to #{value}, clearing AI cache for all families")
|
||||
Family.find_each do |family|
|
||||
ClearAiCacheJob.perform_later(family)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Support dynamic field access via bracket notation
|
||||
# First checks if it's a declared field, then falls back to individual dynamic entries
|
||||
def [](key)
|
||||
|
||||
Reference in New Issue
Block a user