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



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

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



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

def events_root_taxon
  events_taxonomy.root
end

#events_taxonomyObject



111
112
113
# File 'app/services/spree_cm_commissioner/integrations/stadium_x_v1/polling/sync_matches.rb', line 111

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


115
116
117
118
119
120
# File 'app/services/spree_cm_commissioner/integrations/stadium_x_v1/polling/sync_matches.rb', line 115

def generate_match_permalink(match_name)
  loop do
    base_permalink = "#{events_root_taxon.permalink}/#{match_name.to_s.parameterize}-#{SecureRandom.hex(4)}"
    break base_permalink unless Spree::Taxon.exists?(permalink: base_permalink)
  end
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
75
76
77
# 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
  match_name = "#{external_match.home_name} vs #{external_match.away_name} - #{external_match.date} #{external_match.time}"
  match_permalink = match_taxon.persisted? ? match_taxon.permalink : generate_match_permalink(match_name)

  # 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: match_name,
      permalink: match_permalink,
      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