Class: SpreeCmCommissioner::Integrations::StadiumXV1::Polling::SyncMatches

Inherits:
Object
  • Object
show all
Defined in:
app/services/spree_cm_commissioner/integrations/stadium_x_v1/polling/sync_matches.rb

Instance Method Summary collapse

Constructor Details

#initialize(client:, integration:, sync_result: nil) ⇒ SyncMatches

Returns a new instance of SyncMatches.



4
5
6
7
8
# File 'app/services/spree_cm_commissioner/integrations/stadium_x_v1/polling/sync_matches.rb', line 4

def initialize(client:, integration:, sync_result: nil)
  @client = client
  @integration = integration
  @sync_result = sync_result || SpreeCmCommissioner::Integrations::Base::SyncResult.new
end

Instance Method Details

#callObject



10
11
12
13
# File 'app/services/spree_cm_commissioner/integrations/stadium_x_v1/polling/sync_matches.rb', line 10

def call
  synced_match_mappings = sync_matches!
  cleanup_stale_mappings!(synced_match_mappings)
end

#cleanup_stale_mappings!(synced_match_mappings) ⇒ Object

Archive stale match mappings that are no longer in the external API Finds all active event taxon mappings for this integration and archives any that weren’t included in the latest API response



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'app/services/spree_cm_commissioner/integrations/stadium_x_v1/polling/sync_matches.rb', line 79

def cleanup_stale_mappings!(synced_match_mappings)
  synced_external_match_ids = synced_match_mappings.map(&:external_id)

  # Find all active match mappings (event taxons) for this integration
  active_match_mappings = SpreeCmCommissioner::IntegrationMapping.where(
    integration_id: @integration.id,
    internal_type: 'Spree::Taxon',
    status: :active
  ).where(internal_id: Spree::Taxon.where(kind: :event).select(:id))

  # Archive matches that are no longer in the API response
  active_match_mappings.find_each do |mapping|
    next if synced_external_match_ids.include?(mapping.external_id)

    # Discontinue all products associated with this match
    mapping.internal.event_products.find_each do |product|
      product.discontinue!
      @sync_result.increment_metric(:zone, :discontinued)
    end

    mapping.mark_as_archived!
    @sync_result.increment_metric(:match, :archived)
  end
end

#events_root_taxonObject



104
105
106
# File 'app/services/spree_cm_commissioner/integrations/stadium_x_v1/polling/sync_matches.rb', line 104

def events_root_taxon
  events_taxonomy.root
end

#events_taxonomyObject



108
109
110
# File 'app/services/spree_cm_commissioner/integrations/stadium_x_v1/polling/sync_matches.rb', line 108

def events_taxonomy
  @events_taxonomy ||= Spree::Taxonomy.events
end

#sync_match!(external_match) ⇒ Object

Sync a single match and create it as an event taxon under events/ Match data might be incomplete in the matches list, so we fetch full details



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'app/services/spree_cm_commissioner/integrations/stadium_x_v1/polling/sync_matches.rb', line 30

def sync_match!(external_match)
  external_match = begin
    @sync_result.track_api_call('get_match_details') { @client.get_match!(id: external_match._id) }
  rescue SpreeCmCommissioner::Integrations::ExternalClientError => e
    raise SpreeCmCommissioner::Integrations::SyncError, "Failed to sync matches: #{e.message}"
  end

  match_mapping = Spree::Taxon.find_or_initialize_integration_mapping(integration_id: @integration.id, external_id: external_match._id)
  match_taxon = match_mapping.internal

  # Track match sync and create event taxon directly under events/
  @sync_result.track(:match, match_taxon) do |tracker|
    match_taxon.assign_attributes(
      vendor: @integration.vendor,
      parent: events_root_taxon,
      taxonomy: events_taxonomy,
      name: "#{external_match.home_name} vs #{external_match.away_name}",
      kind: :event,
      from_date: external_match.match_datetime,
      to_date: external_match.match_datetime + 120.minutes,

      # seo
      meta_title: external_match.meta_title,
      meta_description: external_match.meta_description,

      # Sync common match fields for cross-integration compatibility
      # Only include fields that other integrations typically provide to avoid data gaps.
      public_metadata: {
        home_name: external_match.home_name,
        home_score: external_match.home_score,
        home_logo_url: external_match.,
        away_name: external_match.away_name,
        away_score: external_match.away_score,
        away_logo_url: external_match.,
        stadium: external_match.stadium,
        league_name: external_match.league&.name,
        league_logo_url: external_match.league&.
      }
    )
    tracker.save_if_changed!(match_taxon)
  end

  match_mapping.mark_as_active!(external_payload: external_match.to_h)
  match_mapping
end

#sync_matches!Object

Sync all available matches from the API and create them as events



16
17
18
19
20
21
22
23
24
25
26
# File 'app/services/spree_cm_commissioner/integrations/stadium_x_v1/polling/sync_matches.rb', line 16

def sync_matches!
  external_matches = begin
    @sync_result.track_api_call('get_matches') { @client.get_matches! }
  rescue SpreeCmCommissioner::Integrations::ExternalClientError => e
    raise SpreeCmCommissioner::Integrations::SyncError, "Failed to sync matches: #{e.message}"
  end

  external_matches.map do |external_match|
    sync_match!(external_match)
  end
end