fix: use dynamic team lookup in scraper for stadium renames

Replace hardcoded stadiumTeamMap with AppDataProvider lookup so
stadium renames (e.g., AT&T Center → Frost Bank Center) work
automatically via CloudKit sync without code changes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-01-12 20:36:36 -06:00
parent 393bb8d6f8
commit d39e8cff30

View File

@@ -134,7 +134,7 @@ actor HistoricalGameScraper {
print("🌐 [Scraper] Parsing HTML (\(data.count) bytes)")
let targetTeams = findTeamNamesForStadium(stadium)
let targetTeams = await findTeamNamesForStadium(stadium)
guard !targetTeams.isEmpty else {
print("🌐 [Scraper] ❌ No team mapping for stadium: \(stadium.name)")
return nil
@@ -208,99 +208,21 @@ actor HistoricalGameScraper {
}
/// Returns an array of possible names for the home team (team name + city variations)
private func findTeamNamesForStadium(_ stadium: Stadium) -> [String] {
// Map stadium name to array of possible names (team name, city, abbreviations)
// Sports-Reference sites often use city names instead of team names
let stadiumTeamMap: [String: [String]] = [
// MLB
"Chase Field": ["Diamondbacks", "Arizona", "ARI"],
"Truist Park": ["Braves", "Atlanta", "ATL"],
"Oriole Park at Camden Yards": ["Orioles", "Baltimore", "BAL"],
"Fenway Park": ["Red Sox", "Boston", "BOS"],
"Wrigley Field": ["Cubs", "Chicago", "CHC"],
"Guaranteed Rate Field": ["White Sox", "Chicago", "CHW"],
"Great American Ball Park": ["Reds", "Cincinnati", "CIN"],
"Progressive Field": ["Guardians", "Cleveland", "Indians", "CLE"],
"Coors Field": ["Rockies", "Colorado", "COL"],
"Comerica Park": ["Tigers", "Detroit", "DET"],
"Minute Maid Park": ["Astros", "Houston", "HOU"],
"Kauffman Stadium": ["Royals", "Kansas City", "KCR"],
"Angel Stadium": ["Angels", "LA Angels", "Los Angeles", "Anaheim", "LAA"],
"Dodger Stadium": ["Dodgers", "LA Dodgers", "Los Angeles", "LAD"],
"loanDepot park": ["Marlins", "Miami", "Florida", "MIA"],
"American Family Field": ["Brewers", "Milwaukee", "MIL"],
"Target Field": ["Twins", "Minnesota", "MIN"],
"Citi Field": ["Mets", "NY Mets", "New York", "NYM"],
"Yankee Stadium": ["Yankees", "NY Yankees", "New York", "NYY"],
"Oakland Coliseum": ["Athletics", "Oakland", "OAK"],
"Citizens Bank Park": ["Phillies", "Philadelphia", "PHI"],
"PNC Park": ["Pirates", "Pittsburgh", "PIT"],
"Petco Park": ["Padres", "San Diego", "SDP"],
"Oracle Park": ["Giants", "San Francisco", "SF Giants", "SFG"],
"T-Mobile Park": ["Mariners", "Seattle", "SEA"],
"Busch Stadium": ["Cardinals", "St. Louis", "STL"],
"Tropicana Field": ["Rays", "Tampa Bay", "TBR"],
"Globe Life Field": ["Rangers", "Texas", "TEX"],
"Rogers Centre": ["Blue Jays", "Toronto", "TOR"],
"Nationals Park": ["Nationals", "Washington", "WSN"],
/// Uses AppDataProvider to dynamically look up teams by stadium ID, so new stadiums
/// and renames are automatically supported via CloudKit sync.
private func findTeamNamesForStadium(_ stadium: Stadium) async -> [String] {
// Access MainActor-isolated AppDataProvider
let teams = await MainActor.run { AppDataProvider.shared.teams }
// NBA
"Footprint Center": ["Suns", "Phoenix", "PHX"],
"State Farm Arena": ["Hawks", "Atlanta", "ATL"],
"TD Garden": ["Celtics", "Boston", "BOS"],
"Barclays Center": ["Nets", "Brooklyn", "BKN"],
"Spectrum Center": ["Hornets", "Charlotte", "CHA"],
"United Center": ["Bulls", "Chicago", "CHI"],
"Rocket Mortgage FieldHouse": ["Cavaliers", "Cavs", "Cleveland", "CLE"],
"American Airlines Center": ["Mavericks", "Mavs", "Dallas", "DAL"],
"Ball Arena": ["Nuggets", "Denver", "DEN"],
"Little Caesars Arena": ["Pistons", "Detroit", "DET"],
"Chase Center": ["Warriors", "Golden State", "GSW"],
"Toyota Center": ["Rockets", "Houston", "HOU"],
"Gainbridge Fieldhouse": ["Pacers", "Indiana", "IND"],
"Crypto.com Arena": ["Lakers", "LA Lakers", "Los Angeles", "LAL"],
"FedExForum": ["Grizzlies", "Memphis", "MEM"],
"Kaseya Center": ["Heat", "Miami", "MIA"],
"Fiserv Forum": ["Bucks", "Milwaukee", "MIL"],
"Target Center": ["Timberwolves", "Wolves", "Minnesota", "MIN"],
"Smoothie King Center": ["Pelicans", "New Orleans", "NOP"],
"Madison Square Garden": ["Knicks", "NY Knicks", "New York", "NYK"],
"Paycom Center": ["Thunder", "Oklahoma City", "OKC"],
"Amway Center": ["Magic", "Orlando", "ORL"],
"Wells Fargo Center": ["76ers", "Sixers", "Philadelphia", "PHI"],
"Moda Center": ["Trail Blazers", "Blazers", "Portland", "POR"],
"Golden 1 Center": ["Kings", "Sacramento", "SAC"],
"AT&T Center": ["Spurs", "San Antonio", "SAS"],
"Scotiabank Arena": ["Raptors", "Toronto", "TOR"],
"Delta Center": ["Jazz", "Utah", "UTA"],
"Capital One Arena": ["Wizards", "Washington", "WAS"],
// Find the team that plays at this stadium using canonical ID
guard let team = teams.first(where: { $0.stadiumId == stadium.id }) else {
print("🌐 [Scraper] No team found for stadium ID: \(stadium.id)")
return []
}
// NHL
"Mullett Arena": ["Coyotes", "Arizona", "ARI"],
"Climate Pledge Arena": ["Kraken", "Seattle", "SEA"],
"Prudential Center": ["Devils", "New Jersey", "NJD"],
"UBS Arena": ["Islanders", "NY Islanders", "New York", "NYI"],
"PPG Paints Arena": ["Penguins", "Pens", "Pittsburgh", "PIT"],
"Amerant Bank Arena": ["Panthers", "Florida", "FLA"],
"Amalie Arena": ["Lightning", "Tampa Bay", "TBL"],
"Enterprise Center": ["Blues", "St. Louis", "STL"],
"Canada Life Centre": ["Jets", "Winnipeg", "WPG"],
"Rogers Place": ["Oilers", "Edmonton", "EDM"],
"Scotiabank Saddledome": ["Flames", "Calgary", "CGY"],
"Rogers Arena": ["Canucks", "Vancouver", "VAN"],
"SAP Center": ["Sharks", "San Jose", "SJS"],
"Honda Center": ["Ducks", "Anaheim", "ANA"],
"T-Mobile Arena": ["Golden Knights", "Vegas", "Las Vegas", "VGK"],
"Xcel Energy Center": ["Wild", "Minnesota", "MIN"],
"Bridgestone Arena": ["Predators", "Preds", "Nashville", "NSH"],
"PNC Arena": ["Hurricanes", "Canes", "Carolina", "CAR"],
"Nationwide Arena": ["Blue Jackets", "Columbus", "CBJ"],
"KeyBank Center": ["Sabres", "Buffalo", "BUF"],
"Bell Centre": ["Canadiens", "Habs", "Montreal", "MTL"],
"Canadian Tire Centre": ["Senators", "Sens", "Ottawa", "OTT"],
]
return stadiumTeamMap[stadium.name] ?? []
// Return variations that Sports-Reference sites might use
// (team name, city, abbreviation)
return [team.name, team.city, team.abbreviation]
}
func clearCache() {