Class: ListingIssues::Sync

Inherits:
Object
  • Object
show all
Defined in:
app/services/listing_issues/sync.rb

Overview

Reconciles ListingIssue rows against what each provider currently reports.
For every candidate catalog item: upsert the issues the adapter returns
(keyed on fingerprint within (catalog_item, provider), reopening any that
recurred) and resolve open rows the provider no longer reports — so the open
set always mirrors the channel. Resolution is detection-derived only (there
is no manual "mark fixed"). Idempotent; safe to run on a schedule.

Defined Under Namespace

Classes: Result

Constant Summary collapse

AUTO_RESOLUTION_NOTE =

resolution_note stamped on rows resolved because the provider stopped
reporting them (the only way an issue resolves).

'auto: no longer reported by provider'

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(adapter, logger: Rails.logger) ⇒ Sync

Returns a new instance of Sync.

Parameters:



56
57
58
59
# File 'app/services/listing_issues/sync.rb', line 56

def initialize(adapter, logger: Rails.logger)
  @adapter = adapter
  @logger = logger
end

Class Method Details

.adaptersArray<ListingIssues::BaseAdapter>

All registered provider adapters.

Returns:



31
32
33
34
# File 'app/services/listing_issues/sync.rb', line 31

def self.adapters
  [AmazonAdapter.new, WalmartAdapter.new, WayfairAdapter.new, GoogleAdapter.new,
   RetailerProbeAdapter.new, WebsiteAdapter.new]
end

.run(logger: Rails.logger) ⇒ Hash{String=>ListingIssues::Sync::Result}

Run every provider's reconcile.

Parameters:

  • logger (Logger) (defaults to: Rails.logger)

Returns:



39
40
41
# File 'app/services/listing_issues/sync.rb', line 39

def self.run(logger: Rails.logger)
  adapters.to_h { |adapter| [adapter.provider, new(adapter, logger:).call] }
end

.run_for(catalog_item, logger: Rails.logger) ⇒ void

This method returns an undefined value.

Reconcile a single catalog item across every provider — used by the
per-item "Recheck" refresh so its listing_issues reflect the just-pulled
marketplace data (creating/updating current issues and auto-resolving any
the provider no longer reports).

Parameters:

  • catalog_item (CatalogItem)
  • logger (Logger) (defaults to: Rails.logger)


50
51
52
# File 'app/services/listing_issues/sync.rb', line 50

def self.run_for(catalog_item, logger: Rails.logger)
  adapters.each { |adapter| new(adapter, logger:).reconcile_item(catalog_item) }
end

Instance Method Details

#callListingIssues::Sync::Result



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'app/services/listing_issues/sync.rb', line 69

def call
  created = updated = resolved = items = 0

  CatalogItem.where(id: @adapter.candidate_item_ids)
             .includes(:listing_issues, *@adapter.eager_load)
             .find_each do |catalog_item|
    items += 1
    c, u, r = reconcile(catalog_item, @adapter.issues_for(catalog_item))
    created += c
    updated += u
    resolved += r
  end

  Result.new(created:, updated:, resolved:, items:).tap do |result|
    @logger.info "[ListingIssues::Sync] #{@adapter.provider}: #{result.to_h}"
  end
end

#reconcile_item(catalog_item) ⇒ Array(Integer, Integer, Integer)

Reconcile just this item against this adapter's provider.

Parameters:

Returns:

  • (Array(Integer, Integer, Integer))

    created, updated, resolved



64
65
66
# File 'app/services/listing_issues/sync.rb', line 64

def reconcile_item(catalog_item)
  reconcile(catalog_item, @adapter.issues_for(catalog_item))
end