jumbotron 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 02e887f5ad4260dddda6dde8d391430ffbad31b7b7069dd851e9560cd6f92540
4
- data.tar.gz: 1a18545151d81f504bc9bf208316ff2b1cf68086f062cf590d0953f9ca28e546
3
+ metadata.gz: 59e55efb1ece4d237011869ce7416fd4cda99a2e95feb914c21e93a3f23aecaa
4
+ data.tar.gz: 2199925a6f4a46d2db581c63e2a5eb55b81a26483195a396a4b7c111ae41bee1
5
5
  SHA512:
6
- metadata.gz: c20c23af5c011df7a9ea866a1923e37abf79b3eea2dfe82e47b561051f3ba6bc43dfb519def7288007e71c7a801020e9d5b32f3d2a76be82c6b85061c2f9bbe1
7
- data.tar.gz: 5414a02d268f32a257752bc29e47b959c46a0dc9b6d680da58c789ff22bd6d76a56a4c264a0068bc32f91aef79a40827b4568a731807dedfcf975966a452d63c
6
+ metadata.gz: ae7c4b2c06eed8291bafcb279940f0ca45ad5b33a62cc5970a5c1d353eae0c4d8bde4173e62811d13dade3038107940a828f37b2b3e1c1d6a7f2c118f62d5447
7
+ data.tar.gz: 8ecd32a04d755e5eb0422fccbb98b10beead9f3b88de8f8e885f2b8e4f458af6a672d1bdf9a63040b88e352186cea328565263dff18d001298b1a0cf97389748
@@ -66,6 +66,21 @@ module Jumbotron
66
66
  INTERRUPTED_LIFECYCLES.include?(game.lifecycle)
67
67
  }
68
68
 
69
+ # Bounded post-final scoreboard re-observation when post-game record is still
70
+ # missing (Strategy B). Stops after window or once post_game is persisted.
71
+ policy :post_final_record,
72
+ type: :post_final_game_update,
73
+ cadence: Cadence.new(every: 15, unit: :minute),
74
+ eligible: lambda { |game, now:|
75
+ return false unless game.lifecycle == "completed"
76
+ return false if game.changed_at.nil? || game.changed_at < now - 6.hours
77
+
78
+ participants = game.game_participants
79
+ return false if participants.empty?
80
+
81
+ participants.any? { |participant| participant.record_summary_post_game.blank? }
82
+ }
83
+
69
84
  policy :far_future_lines,
70
85
  type: :future_line_update,
71
86
  cadence: Cadence.new(every: 1, unit: :week),
@@ -80,11 +80,14 @@ module Jumbotron
80
80
  raise TransformError, "venue id required" if venue.id.blank?
81
81
  raise TransformError, "venue name required" if venue.full_name.blank?
82
82
 
83
+ address = venue.respond_to?(:address) ? venue.address : nil
83
84
  Canonical::VenueInput.new(
84
85
  provider_identities: [
85
86
  Canonical::ProviderIdentityRef.new(provider: "espn", namespace: "venue", id: venue.id.to_s)
86
87
  ],
87
- name: venue.full_name.to_s
88
+ name: venue.full_name.to_s,
89
+ city: address&.city.presence,
90
+ region: address&.state.presence
88
91
  )
89
92
  end
90
93
  private_class_method :transform_venue
@@ -104,13 +107,22 @@ module Jumbotron
104
107
  ],
105
108
  team_name: name.to_s,
106
109
  team_nickname: TeamNickname.resolve(team),
110
+ team_abbreviation: team.abbreviation.presence,
107
111
  role: competitor.home_away.to_s,
108
112
  score: coerce_score(competitor.score),
109
- result: coerce_result(competitor.winner, lifecycle)
113
+ result: coerce_result(competitor.winner, lifecycle),
114
+ record_summary: total_record_summary(competitor)
110
115
  )
111
116
  end
112
117
  private_class_method :transform_participant
113
118
 
119
+ def self.total_record_summary(competitor)
120
+ records = competitor.respond_to?(:records) ? Array(competitor.records) : []
121
+ total = records.find { |record| record.type.to_s == "total" }
122
+ total&.summary.presence
123
+ end
124
+ private_class_method :total_record_summary
125
+
114
126
  def self.coerce_score(raw)
115
127
  return nil if raw.nil? || raw == ""
116
128
 
@@ -25,7 +25,8 @@ module Jumbotron
25
25
  Canonical::ProviderIdentityRef.new(provider: "espn", namespace: "team", id: team.id.to_s)
26
26
  ],
27
27
  name: name.to_s,
28
- nickname: TeamNickname.resolve(team)
28
+ nickname: TeamNickname.resolve(team),
29
+ abbreviation: team.abbreviation.presence
29
30
  )
30
31
  end
31
32
  private_class_method :transform_team
@@ -13,6 +13,7 @@ module Jumbotron
13
13
  field :winner, type: Support.types.boolean, nullable: true
14
14
  field :order, type: Support.types.integer, nullable: true
15
15
  field :team, type: Team::Result, required: true
16
+ field :records, type: Support.types.array(CompetitorRecord::Result), nullable: true
16
17
  end
17
18
 
18
19
  def self.call(payload)
@@ -25,10 +26,22 @@ module Jumbotron
25
26
  score: coerce_score(Support.payload.fetch(payload, "score")),
26
27
  winner: Support.payload.fetch(payload, "winner"),
27
28
  order: Support.payload.fetch(payload, "order"),
28
- team: Support.nest("team", Support.payload.fetch(payload, "team")) { |raw| Team.call(raw) }
29
+ team: Support.nest("team", Support.payload.fetch(payload, "team")) { |raw| Team.call(raw) },
30
+ records: map_records(Support.payload.fetch(payload, "records"))
29
31
  )
30
32
  end
31
33
 
34
+ def self.map_records(raw)
35
+ return nil if raw.equal?(Support.missing) || raw.nil?
36
+
37
+ Array(raw).each_with_index.map do |item, index|
38
+ CompetitorRecord.call(item)
39
+ rescue CommandTower::Clients::Errors::DeserializationError => e
40
+ raise CommandTower::Deserializers::Clients::Errors.prefix(e, "records[#{index}]")
41
+ end
42
+ end
43
+ private_class_method :map_records
44
+
32
45
  def self.coerce_id(raw)
33
46
  return raw if raw.equal?(Support.missing) || raw.nil? || raw.is_a?(String)
34
47
 
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jumbotron
4
+ module Deserializers
5
+ module Clients
6
+ module Espn
7
+ class CompetitorRecord
8
+ class Result < CommandTower::Deserializers::Clients::Result
9
+ field :type, type: Support.types.string, required: true
10
+ field :summary, type: Support.types.string, required: true
11
+ field :name, type: Support.types.string, nullable: true
12
+ end
13
+
14
+ def self.call(payload)
15
+ Support.ensure_hash!(payload, label: "competitor.record")
16
+
17
+ Result.build!(
18
+ type: Support.payload.fetch(payload, "type"),
19
+ summary: Support.payload.fetch(payload, "summary"),
20
+ name: Support.payload.fetch(payload, "name")
21
+ )
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -9,6 +9,7 @@ module Jumbotron
9
9
  field :id, type: Support.types.string, required: true
10
10
  field :full_name, type: Support.types.string, required: true
11
11
  field :indoor, type: Support.types.boolean, nullable: true
12
+ field :address, type: VenueAddress::Result, nullable: true
12
13
  end
13
14
 
14
15
  def self.call(payload)
@@ -17,10 +18,18 @@ module Jumbotron
17
18
  Result.build!(
18
19
  id: coerce_id(Support.payload.fetch(payload, "id")),
19
20
  full_name: Support.payload.fetch(payload, "fullName"),
20
- indoor: Support.payload.fetch(payload, "indoor")
21
+ indoor: Support.payload.fetch(payload, "indoor"),
22
+ address: map_address(Support.payload.fetch(payload, "address"))
21
23
  )
22
24
  end
23
25
 
26
+ def self.map_address(raw)
27
+ return nil if raw.equal?(Support.missing) || raw.nil?
28
+
29
+ VenueAddress.call(raw)
30
+ end
31
+ private_class_method :map_address
32
+
24
33
  def self.coerce_id(raw)
25
34
  return raw if raw.equal?(Support.missing) || raw.nil? || raw.is_a?(String)
26
35
 
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jumbotron
4
+ module Deserializers
5
+ module Clients
6
+ module Espn
7
+ class VenueAddress
8
+ class Result < CommandTower::Deserializers::Clients::Result
9
+ field :city, type: Support.types.string, nullable: true
10
+ field :state, type: Support.types.string, nullable: true
11
+ field :country, type: Support.types.string, nullable: true
12
+ end
13
+
14
+ def self.call(payload)
15
+ Support.ensure_hash!(payload, label: "venue.address")
16
+
17
+ Result.build!(
18
+ city: Support.payload.fetch(payload, "city"),
19
+ state: Support.payload.fetch(payload, "state"),
20
+ country: Support.payload.fetch(payload, "country")
21
+ )
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -4,13 +4,17 @@ module Jumbotron
4
4
  module Canonical
5
5
  ProviderIdentityRef = Data.define(:provider, :namespace, :id)
6
6
 
7
- TeamInput = Data.define(:provider_identities, :name, :nickname) do
8
- def initialize(provider_identities:, name:, nickname: nil)
7
+ TeamInput = Data.define(:provider_identities, :name, :nickname, :abbreviation) do
8
+ def initialize(provider_identities:, name:, nickname: nil, abbreviation: nil)
9
9
  super
10
10
  end
11
11
  end
12
12
 
13
- VenueInput = Data.define(:provider_identities, :name)
13
+ VenueInput = Data.define(:provider_identities, :name, :city, :region) do
14
+ def initialize(provider_identities:, name:, city: nil, region: nil)
15
+ super
16
+ end
17
+ end
14
18
 
15
19
  ParticipantInput = Data.define(
16
20
  :provider_identities,
@@ -18,9 +22,20 @@ module Jumbotron
18
22
  :role,
19
23
  :score,
20
24
  :result,
21
- :team_nickname
25
+ :team_nickname,
26
+ :team_abbreviation,
27
+ :record_summary
22
28
  ) do
23
- def initialize(provider_identities:, team_name:, role:, score:, result:, team_nickname: nil)
29
+ def initialize(
30
+ provider_identities:,
31
+ team_name:,
32
+ role:,
33
+ score:,
34
+ result:,
35
+ team_nickname: nil,
36
+ team_abbreviation: nil,
37
+ record_summary: nil
38
+ )
24
39
  super
25
40
  end
26
41
  end
@@ -19,13 +19,21 @@ module Jumbotron
19
19
  :season_phase,
20
20
  :kind
21
21
  )
22
- Team = Data.define(:id, :name, :nickname, :key) do
23
- def initialize(id:, name:, key:, nickname: nil)
24
- super(id:, name:, nickname:, key:)
22
+ Team = Data.define(:id, :name, :nickname, :key, :abbreviation) do
23
+ def initialize(id:, name:, key:, nickname: nil, abbreviation: nil)
24
+ super(id:, name:, nickname:, key:, abbreviation:)
25
+ end
26
+ end
27
+ Venue = Data.define(:id, :name, :city, :region) do
28
+ def initialize(id:, name:, city: nil, region: nil)
29
+ super
30
+ end
31
+ end
32
+ Participant = Data.define(:role, :score, :result, :team, :record) do
33
+ def initialize(role:, score:, result:, team:, record: nil)
34
+ super
25
35
  end
26
36
  end
27
- Venue = Data.define(:id, :name)
28
- Participant = Data.define(:role, :score, :result, :team)
29
37
  GameSegment = Data.define(:kind, :number)
30
38
  # Clock label text. Name is canonical/public contract, not Kernel#display.
31
39
  GameClock = Data.define(:mode, :seconds, :display) # rubocop:disable Lint/DataDefineOverride
@@ -8,6 +8,7 @@ module Jumbotron
8
8
  future_game_update
9
9
  live_game_update
10
10
  interrupted_game_update
11
+ post_final_game_update
11
12
  ].freeze
12
13
 
13
14
  validate :adapter_id, required: true
@@ -20,7 +20,7 @@ module Jumbotron
20
20
  end
21
21
 
22
22
  games = Game.where(league_id: league.id)
23
- .includes(:season, :season_phase, :schedule_group)
23
+ .includes(:season, :season_phase, :schedule_group, :game_participants)
24
24
  .select { |game| policy.eligible?(game, now: now) }
25
25
 
26
26
  context.league = league
@@ -14,7 +14,8 @@ module Jumbotron
14
14
  team_input: Jumbotron::Canonical::TeamInput.new(
15
15
  provider_identities: participant_input.provider_identities,
16
16
  name: participant_input.team_name,
17
- nickname: participant_input.team_nickname
17
+ nickname: participant_input.team_nickname,
18
+ abbreviation: participant_input.team_abbreviation
18
19
  ),
19
20
  observed_at: observed_at,
20
21
  change_set: change_set
@@ -46,16 +47,18 @@ module Jumbotron
46
47
  end
47
48
 
48
49
  def create_new!(team)
49
- gp = game.game_participants.create!(
50
+ attrs = {
50
51
  team: team,
51
52
  role: participant_input.role,
52
53
  score: participant_input.score,
53
54
  result: participant_input.result,
54
55
  observed_at: observed_at,
55
56
  changed_at: observed_at
56
- )
57
+ }.merge(initial_record_attrs)
58
+ gp = game.game_participants.create!(attrs)
57
59
  change_set.record(subject: gp, attribute: "role", previous: nil, new_value: gp.role)
58
60
  change_set.record(subject: gp, attribute: "score", previous: nil, new_value: gp.score)
61
+ record_create_history!(gp)
59
62
  gp
60
63
  end
61
64
 
@@ -78,11 +81,96 @@ module Jumbotron
78
81
  participant.public_send("#{key}=", value)
79
82
  material = true
80
83
  end
84
+ material |= apply_record_snapshots!(participant)
81
85
  participant.observed_at = observed_at
82
86
  participant.changed_at = observed_at if material
83
87
  participant.save!
84
88
  participant
85
89
  end
90
+
91
+ def initial_record_attrs
92
+ summary = participant_input.record_summary
93
+ return {} if summary.blank?
94
+
95
+ attrs = {
96
+ record_summary_current: summary,
97
+ record_observed_at: observed_at
98
+ }
99
+ if game.lifecycle == "completed"
100
+ attrs[:record_summary_post_game] = summary
101
+ elsif game.lifecycle != "cancelled"
102
+ attrs[:record_summary_entering] = summary
103
+ end
104
+ attrs
105
+ end
106
+
107
+ def record_create_history!(participant)
108
+ %i[
109
+ record_summary_entering
110
+ record_summary_current
111
+ record_summary_post_game
112
+ ].each do |attr|
113
+ value = participant.public_send(attr)
114
+ next if value.blank?
115
+
116
+ change_set.record(subject: participant, attribute: attr.to_s, previous: nil, new_value: value)
117
+ end
118
+ end
119
+
120
+ def apply_record_snapshots!(participant)
121
+ summary = participant_input.record_summary
122
+ return false if summary.blank?
123
+
124
+ material = false
125
+ if participant.record_summary_current != summary
126
+ change_set.record(
127
+ subject: participant,
128
+ attribute: "record_summary_current",
129
+ previous: participant.record_summary_current,
130
+ new_value: summary
131
+ )
132
+ participant.record_summary_current = summary
133
+ material = true
134
+ end
135
+ participant.record_observed_at = observed_at
136
+
137
+ if game.lifecycle == "completed"
138
+ material |= apply_post_game_record!(participant, summary)
139
+ elsif game.lifecycle != "cancelled"
140
+ material |= assign_entering_record!(participant, summary)
141
+ end
142
+ material
143
+ end
144
+
145
+ def assign_entering_record!(participant, summary) # rubocop:disable Naming/PredicateMethod
146
+ return false if participant.record_summary_entering == summary
147
+
148
+ change_set.record(
149
+ subject: participant,
150
+ attribute: "record_summary_entering",
151
+ previous: participant.record_summary_entering,
152
+ new_value: summary
153
+ )
154
+ participant.record_summary_entering = summary
155
+ true
156
+ end
157
+
158
+ # Authoritative post-game only: never invent W–L; if total still equals
159
+ # entering on a completed observation, leave post_game nil (Strategy B).
160
+ def apply_post_game_record!(participant, summary) # rubocop:disable Naming/PredicateMethod
161
+ entering = participant.record_summary_entering
162
+ return false if entering.present? && summary == entering
163
+ return false if participant.record_summary_post_game == summary
164
+
165
+ change_set.record(
166
+ subject: participant,
167
+ attribute: "record_summary_post_game",
168
+ previous: participant.record_summary_post_game,
169
+ new_value: summary
170
+ )
171
+ participant.record_summary_post_game = summary
172
+ true
173
+ end
86
174
  end
87
175
  end
88
176
  end
@@ -58,6 +58,7 @@ module Jumbotron
58
58
  team.changed_at = observed_at
59
59
  end
60
60
  apply_nickname!(team)
61
+ apply_abbreviation!(team)
61
62
  # key is immutable after assignment — never regenerate from name or provider id
62
63
  team.observed_at = observed_at
63
64
  team.save!
@@ -68,6 +69,7 @@ module Jumbotron
68
69
  team = Team.create!(
69
70
  name: team_input.name,
70
71
  nickname: team_input.nickname,
72
+ abbreviation: team_input.abbreviation,
71
73
  key: allocate_key!(team_input.name),
72
74
  observed_at: observed_at,
73
75
  changed_at: observed_at
@@ -82,6 +84,14 @@ module Jumbotron
82
84
  new_value: team.nickname
83
85
  )
84
86
  end
87
+ if team.abbreviation.present?
88
+ change_set.record(
89
+ subject: team,
90
+ attribute: "abbreviation",
91
+ previous: nil,
92
+ new_value: team.abbreviation
93
+ )
94
+ end
85
95
  team
86
96
  end
87
97
 
@@ -99,6 +109,20 @@ module Jumbotron
99
109
  team.changed_at = observed_at
100
110
  end
101
111
 
112
+ def apply_abbreviation!(team)
113
+ return if team_input.abbreviation.nil?
114
+ return if team.abbreviation == team_input.abbreviation
115
+
116
+ change_set.record(
117
+ subject: team,
118
+ attribute: "abbreviation",
119
+ previous: team.abbreviation,
120
+ new_value: team_input.abbreviation
121
+ )
122
+ team.abbreviation = team_input.abbreviation
123
+ team.changed_at = observed_at
124
+ end
125
+
102
126
  def allocate_key!(name)
103
127
  base = Jumbotron::TeamKey.normalize(name)
104
128
  return base unless Team.exists?(key: base)
@@ -52,6 +52,7 @@ module Jumbotron
52
52
 
53
53
  def update_existing!(venue_id)
54
54
  venue = Venue.lock.find(venue_id)
55
+ material = false
55
56
  if venue.name != venue_input.name
56
57
  change_set.record(
57
58
  subject: venue,
@@ -60,8 +61,10 @@ module Jumbotron
60
61
  new_value: venue_input.name
61
62
  )
62
63
  venue.name = venue_input.name
63
- venue.changed_at = observed_at
64
+ material = true
64
65
  end
66
+ material |= apply_location!(venue)
67
+ venue.changed_at = observed_at if material
65
68
  venue.observed_at = observed_at
66
69
  venue.save!
67
70
  venue
@@ -70,13 +73,42 @@ module Jumbotron
70
73
  def create_new!
71
74
  venue = Venue.create!(
72
75
  name: venue_input.name,
76
+ city: venue_input.city,
77
+ region: venue_input.region,
73
78
  observed_at: observed_at,
74
79
  changed_at: observed_at
75
80
  )
76
81
  change_set.record(subject: venue, attribute: "name", previous: nil, new_value: venue.name)
82
+ if venue.city.present?
83
+ change_set.record(subject: venue, attribute: "city", previous: nil, new_value: venue.city)
84
+ end
85
+ if venue.region.present?
86
+ change_set.record(subject: venue, attribute: "region", previous: nil, new_value: venue.region)
87
+ end
77
88
  venue
78
89
  end
79
90
 
91
+ def apply_location!(venue)
92
+ material = false
93
+ {
94
+ city: venue_input.city,
95
+ region: venue_input.region
96
+ }.each do |key, value|
97
+ next if value.nil?
98
+ next if venue.public_send(key) == value
99
+
100
+ change_set.record(
101
+ subject: venue,
102
+ attribute: key.to_s,
103
+ previous: venue.public_send(key),
104
+ new_value: value
105
+ )
106
+ venue.public_send("#{key}=", value)
107
+ material = true
108
+ end
109
+ material
110
+ end
111
+
80
112
  def recover_after_race!
81
113
  ref = venue_input.provider_identities.first
82
114
  identity = ProviderIdentity.find_by!(
@@ -61,7 +61,12 @@ module Jumbotron
61
61
  def build_venue(venue)
62
62
  return if venue.nil?
63
63
 
64
- Jumbotron::Public::Venue.new(id: venue.id, name: venue.name)
64
+ Jumbotron::Public::Venue.new(
65
+ id: venue.id,
66
+ name: venue.name,
67
+ city: venue.city,
68
+ region: venue.region
69
+ )
65
70
  end
66
71
 
67
72
  def build_participant(participant)
@@ -69,15 +74,28 @@ module Jumbotron
69
74
  role: participant.role,
70
75
  score: participant.score,
71
76
  result: participant.result,
77
+ record: resolve_presentation_record(participant),
72
78
  team: Jumbotron::Public::Team.new(
73
79
  id: participant.team.id,
74
80
  name: participant.team.name,
75
81
  nickname: participant.team.nickname,
76
- key: participant.team.key
82
+ key: participant.team.key,
83
+ abbreviation: participant.team.abbreviation
77
84
  )
78
85
  )
79
86
  end
80
87
 
88
+ # Lifecycle-resolved game-time record for presentation. Never falls back to
89
+ # entering when completed post-game is missing.
90
+ def resolve_presentation_record(participant)
91
+ case game.lifecycle
92
+ when "scheduled", "in_progress", "postponed", "suspended"
93
+ participant.record_summary_entering
94
+ when "completed"
95
+ participant.record_summary_post_game
96
+ end
97
+ end
98
+
81
99
  def map_currents(lines)
82
100
  return [] unless Array(includes).include?(:current_lines)
83
101
 
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddGamePresentationContractFields < ActiveRecord::Migration[8.0]
4
+ def change
5
+ change_table :jumbotron_game_participants, bulk: true do |t|
6
+ t.string :record_summary_entering
7
+ t.string :record_summary_current
8
+ t.string :record_summary_post_game
9
+ t.datetime :record_observed_at
10
+ end
11
+
12
+ change_table :jumbotron_venues, bulk: true do |t|
13
+ t.string :city
14
+ t.string :region
15
+ end
16
+
17
+ add_column :jumbotron_teams, :abbreviation, :string
18
+ end
19
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Jumbotron
4
- VERSION = "0.1.6"
4
+ VERSION = "0.1.7"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jumbotron
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - matt-taylor
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-08-28 00:00:00.000000000 Z
11
+ date: 2026-08-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: command_tower
@@ -91,6 +91,7 @@ files:
91
91
  - app/deserializers/jumbotron/deserializers/clients/espn/competition_odds/side_quote.rb
92
92
  - app/deserializers/jumbotron/deserializers/clients/espn/competition_odds/team_odds.rb
93
93
  - app/deserializers/jumbotron/deserializers/clients/espn/competitor.rb
94
+ - app/deserializers/jumbotron/deserializers/clients/espn/competitor_record.rb
94
95
  - app/deserializers/jumbotron/deserializers/clients/espn/event.rb
95
96
  - app/deserializers/jumbotron/deserializers/clients/espn/scoreboard/get.rb
96
97
  - app/deserializers/jumbotron/deserializers/clients/espn/season.rb
@@ -99,6 +100,7 @@ files:
99
100
  - app/deserializers/jumbotron/deserializers/clients/espn/team.rb
100
101
  - app/deserializers/jumbotron/deserializers/clients/espn/teams/get.rb
101
102
  - app/deserializers/jumbotron/deserializers/clients/espn/venue.rb
103
+ - app/deserializers/jumbotron/deserializers/clients/espn/venue_address.rb
102
104
  - app/deserializers/jumbotron/deserializers/clients/espn/week.rb
103
105
  - app/deserializers/jumbotron/deserializers/public/game.rb
104
106
  - app/deserializers/jumbotron/deserializers/public/game_ids.rb
@@ -208,6 +210,7 @@ files:
208
210
  - db/migrate/20260820000001_add_progress_to_jumbotron_games.rb
209
211
  - db/migrate/20260827150001_add_key_to_jumbotron_teams.rb
210
212
  - db/migrate/20260828180001_add_nickname_to_jumbotron_teams.rb
213
+ - db/migrate/20260828220001_add_game_presentation_contract_fields.rb
211
214
  - docs/testing.md
212
215
  - docs/upgrades/0.1.2.md
213
216
  - docs/upgrades/0.1.3.md