feat: rewrite bootstrap, fix CloudKit sync, update canonical data, and UI fixes

- Rewrite BootstrapService: remove all legacy code paths (JSONStadium,
  JSONGame, bootstrapStadiumsLegacy, bootstrapGamesLegacy, venue aliases,
  createDefaultLeagueStructure), require canonical JSON files only
- Add clearCanonicalData() to handle partial bootstrap recovery (prevents
  duplicate key crashes from interrupted first-launch)
- Fix nullable stadium_canonical_id in games (4 MLS games have null)
- Fix CKModels: logoUrl case, conference/division field keys
- Fix CanonicalSyncService: sync conferenceCanonicalId/divisionCanonicalId
- Add sports_canonical.json and DemoMode.swift
- Delete legacy stadiums.json and games.json
- Update all canonical resource JSON files with latest data
- Fix TripWizardView horizontal scrolling with GeometryReader constraint
- Update RegionMapSelector, TripDetailView, TripOptionsView UI improvements
- Add DateRangePicker, PlanningModeStep, SportsStep enhancements
- Update UI tests and marketing-videos config

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-02-06 00:06:19 -06:00
parent 12f959ab8d
commit fdcecafaa3
29 changed files with 93279 additions and 157943 deletions

View File

@@ -34,9 +34,11 @@ struct CKTeam {
static let cityKey = "city"
static let stadiumRefKey = "stadiumRef"
static let stadiumCanonicalIdKey = "stadiumCanonicalId"
static let logoURLKey = "logoURL"
static let logoURLKey = "logoUrl"
static let primaryColorKey = "primaryColor"
static let secondaryColorKey = "secondaryColor"
static let conferenceCanonicalIdKey = "conferenceCanonicalId"
static let divisionCanonicalIdKey = "divisionCanonicalId"
let record: CKRecord
@@ -68,6 +70,16 @@ struct CKTeam {
record[CKTeam.stadiumCanonicalIdKey] as? String
}
/// The conference canonical ID string from CloudKit (e.g., "nba_eastern")
var conferenceCanonicalId: String? {
record[CKTeam.conferenceCanonicalIdKey] as? String
}
/// The division canonical ID string from CloudKit (e.g., "nba_southeast")
var divisionCanonicalId: String? {
record[CKTeam.divisionCanonicalIdKey] as? String
}
var team: Team? {
// Use teamId field, or fall back to record name
let id = (record[CKTeam.idKey] as? String) ?? record.recordID.recordName
@@ -99,6 +111,8 @@ struct CKTeam {
sport: sport,
city: city,
stadiumId: stadiumId,
conferenceId: record[CKTeam.conferenceCanonicalIdKey] as? String,
divisionId: record[CKTeam.divisionCanonicalIdKey] as? String,
logoURL: logoURL,
primaryColor: record[CKTeam.primaryColorKey] as? String,
secondaryColor: record[CKTeam.secondaryColorKey] as? String

View File

@@ -564,4 +564,5 @@ nonisolated enum BundledDataTimestamp {
static let stadiums = ISO8601DateFormatter().date(from: "2026-01-08T00:00:00Z") ?? Date()
static let games = ISO8601DateFormatter().date(from: "2026-01-08T00:00:00Z") ?? Date()
static let leagueStructure = ISO8601DateFormatter().date(from: "2026-01-08T00:00:00Z") ?? Date()
static let sports = ISO8601DateFormatter().date(from: "2026-01-08T00:00:00Z") ?? Date()
}