wip
This commit is contained in:
@@ -31,6 +31,7 @@ struct Stadium: Identifiable, Codable, Hashable {
|
||||
let yearOpened: Int?
|
||||
let imageURL: URL?
|
||||
let timeZoneIdentifier: String?
|
||||
let primaryTeamAbbreviations: [String] // Teams that play here (e.g., ["LAC", "LAR"] for SoFi Stadium)
|
||||
|
||||
init(
|
||||
id: String,
|
||||
@@ -43,7 +44,8 @@ struct Stadium: Identifiable, Codable, Hashable {
|
||||
sport: Sport,
|
||||
yearOpened: Int? = nil,
|
||||
imageURL: URL? = nil,
|
||||
timeZoneIdentifier: String? = nil
|
||||
timeZoneIdentifier: String? = nil,
|
||||
primaryTeamAbbreviations: [String] = []
|
||||
) {
|
||||
self.id = id
|
||||
self.name = name
|
||||
@@ -56,6 +58,7 @@ struct Stadium: Identifiable, Codable, Hashable {
|
||||
self.yearOpened = yearOpened
|
||||
self.imageURL = imageURL
|
||||
self.timeZoneIdentifier = timeZoneIdentifier
|
||||
self.primaryTeamAbbreviations = primaryTeamAbbreviations
|
||||
}
|
||||
|
||||
var timeZone: TimeZone? {
|
||||
|
||||
@@ -23,6 +23,8 @@ struct Team: Identifiable, Codable, Hashable {
|
||||
let sport: Sport
|
||||
let city: String
|
||||
let stadiumId: String // FK: "stadium_mlb_fenway_park"
|
||||
let conferenceId: String? // FK: "nba_eastern", "mlb_al"
|
||||
let divisionId: String? // FK: "nba_southeast", "mlb_al_east"
|
||||
let logoURL: URL?
|
||||
let primaryColor: String?
|
||||
let secondaryColor: String?
|
||||
@@ -34,6 +36,8 @@ struct Team: Identifiable, Codable, Hashable {
|
||||
sport: Sport,
|
||||
city: String,
|
||||
stadiumId: String,
|
||||
conferenceId: String? = nil,
|
||||
divisionId: String? = nil,
|
||||
logoURL: URL? = nil,
|
||||
primaryColor: String? = nil,
|
||||
secondaryColor: String? = nil
|
||||
@@ -44,6 +48,8 @@ struct Team: Identifiable, Codable, Hashable {
|
||||
self.sport = sport
|
||||
self.city = city
|
||||
self.stadiumId = stadiumId
|
||||
self.conferenceId = conferenceId
|
||||
self.divisionId = divisionId
|
||||
self.logoURL = logoURL
|
||||
self.primaryColor = primaryColor
|
||||
self.secondaryColor = secondaryColor
|
||||
|
||||
@@ -320,6 +320,8 @@ final class CanonicalTeam {
|
||||
sport: sportEnum ?? .mlb,
|
||||
city: city,
|
||||
stadiumId: stadiumCanonicalId,
|
||||
conferenceId: conferenceId,
|
||||
divisionId: divisionId,
|
||||
logoURL: logoURL.flatMap { URL(string: $0) },
|
||||
primaryColor: primaryColor,
|
||||
secondaryColor: secondaryColor
|
||||
|
||||
@@ -47,6 +47,7 @@ actor BootstrapService {
|
||||
let primary_team_abbrevs: [String]
|
||||
let year_opened: Int?
|
||||
let timezone_identifier: String?
|
||||
let image_url: String?
|
||||
}
|
||||
|
||||
private struct JSONCanonicalTeam: Codable {
|
||||
@@ -66,8 +67,9 @@ actor BootstrapService {
|
||||
let canonical_id: String
|
||||
let sport: String
|
||||
let season: String
|
||||
let date: String
|
||||
let time: String?
|
||||
let game_datetime_utc: String? // ISO 8601 format (new canonical format)
|
||||
let date: String? // Legacy format (deprecated)
|
||||
let time: String? // Legacy format (deprecated)
|
||||
let home_team_canonical_id: String
|
||||
let away_team_canonical_id: String
|
||||
let stadium_canonical_id: String
|
||||
@@ -215,6 +217,7 @@ actor BootstrapService {
|
||||
longitude: jsonStadium.longitude,
|
||||
capacity: jsonStadium.capacity,
|
||||
yearOpened: jsonStadium.year_opened,
|
||||
imageURL: jsonStadium.image_url,
|
||||
sport: jsonStadium.sport,
|
||||
timezoneIdentifier: jsonStadium.timezone_identifier
|
||||
)
|
||||
@@ -423,10 +426,18 @@ actor BootstrapService {
|
||||
guard !seenGameIds.contains(jsonGame.canonical_id) else { continue }
|
||||
seenGameIds.insert(jsonGame.canonical_id)
|
||||
|
||||
guard let dateTime = parseDateTime(date: jsonGame.date, time: jsonGame.time ?? "7:00p") else {
|
||||
continue
|
||||
// Parse datetime: prefer ISO 8601 format, fall back to legacy date+time
|
||||
let dateTime: Date?
|
||||
if let iso8601String = jsonGame.game_datetime_utc {
|
||||
dateTime = parseISO8601(iso8601String)
|
||||
} else if let date = jsonGame.date {
|
||||
dateTime = parseDateTime(date: date, time: jsonGame.time ?? "7:00p")
|
||||
} else {
|
||||
dateTime = nil
|
||||
}
|
||||
|
||||
guard let dateTime else { continue }
|
||||
|
||||
let game = CanonicalGame(
|
||||
canonicalId: jsonGame.canonical_id,
|
||||
schemaVersion: SchemaVersion.current,
|
||||
@@ -677,6 +688,13 @@ actor BootstrapService {
|
||||
return "venue_unknown_\(venue.lowercased().replacingOccurrences(of: " ", with: "_"))"
|
||||
}
|
||||
|
||||
nonisolated private func parseISO8601(_ string: String) -> Date? {
|
||||
// Handle ISO 8601 format: "2026-03-01T18:05:00Z"
|
||||
let formatter = ISO8601DateFormatter()
|
||||
formatter.formatOptions = [.withInternetDateTime]
|
||||
return formatter.date(from: string)
|
||||
}
|
||||
|
||||
nonisolated private func parseDateTime(date: String, time: String) -> Date? {
|
||||
let formatter = DateFormatter()
|
||||
formatter.locale = Locale(identifier: "en_US_POSIX")
|
||||
|
||||
Reference in New Issue
Block a user