Class: Ace::Support::Models::Atoms::ProviderCatalogReconciler

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/support/models/atoms/provider_catalog_reconciler.rb

Overview

Reconciles an observed local selection with a bundled native catalog. Missing entries on first observation carry no evidence of consent.

Class Method Summary collapse

Class Method Details

.reconcile(config, catalog) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/ace/support/models/atoms/provider_catalog_reconciler.rb', line 13

def self.reconcile(config, catalog)
  local = ProviderConfigReader.extract_models(config)
  offered = ProviderConfigReader.extract_models(catalog)
  previous = config["sync_state"]
  previous = nil unless valid_state?(previous)
  removed = previous ? (previous["removed"] + previous["accepted"] - local).uniq : []
  unknown = previous ? previous["unknown"] - local : offered - local
  added = previous ? offered - previous["catalog"] - local - removed - unknown : []
  models = local + added
  state = {
    "catalog" => offered,
    "catalog_digest" => Digest::SHA256.hexdigest(JSON.generate(catalog)),
    "accepted" => models.dup,
    "unknown" => unknown,
    "removed" => removed - local
  }
  desired = config.reject { |key, _| key.start_with?("_source_") }
  # Preserve hash-form local model metadata, as well as order/default.
  desired["models"] = if config["models"].is_a?(Hash)
    config["models"].merge(added.to_h { |id| [id, {}] })
  else
    models
  end
  desired["sync_state"] = state
  {
    config: desired, added: added, offered: (unknown & offered),
    removed: state["removed"], changed: desired != config.reject { |key, _| key.start_with?("_source_") }
  }
end