refactor: change domain model IDs from UUID to String canonical IDs

This refactor fixes the achievement system by using stable canonical string
IDs (e.g., "stadium_mlb_fenway_park") instead of random UUIDs. This ensures
stadium mappings for achievements are consistent across app launches and
CloudKit sync operations.

Changes:
- Stadium, Team, Game: id property changed from UUID to String
- Trip, TripStop, TripPreferences: updated to use String IDs for games/stadiums
- CKModels: removed UUID parsing, use canonical IDs directly
- AchievementEngine: now matches against canonical stadium IDs
- All test files updated to use String IDs instead of UUID()

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-01-12 09:24:33 -06:00
parent 4b2cacaeba
commit 1703ca5b0f
53 changed files with 642 additions and 727 deletions

View File

@@ -15,8 +15,8 @@ actor PDFAssetPrefetcher {
struct PrefetchedAssets {
let routeMap: UIImage?
let cityMaps: [String: UIImage]
let teamLogos: [UUID: UIImage]
let stadiumPhotos: [UUID: UIImage]
let teamLogos: [String: UIImage]
let stadiumPhotos: [String: UIImage]
let cityPOIs: [String: [POISearchService.POI]]
var isEmpty: Bool {
@@ -63,7 +63,7 @@ actor PDFAssetPrefetcher {
/// - Returns: All prefetched assets
func prefetchAssets(
for trip: Trip,
games: [UUID: RichGame],
games: [String: RichGame],
progressCallback: ((PrefetchProgress) async -> Void)? = nil
) async -> PrefetchedAssets {
var progress = PrefetchProgress()
@@ -71,8 +71,8 @@ actor PDFAssetPrefetcher {
// Collect unique teams and stadiums from games
var teams: [Team] = []
var stadiums: [Stadium] = []
var seenTeamIds: Set<UUID> = []
var seenStadiumIds: Set<UUID> = []
var seenTeamIds: Set<String> = []
var seenStadiumIds: Set<String> = []
for (_, richGame) in games {
if !seenTeamIds.contains(richGame.homeTeam.id) {

View File

@@ -111,8 +111,8 @@ actor RemoteImageService {
}
/// Fetch team logos by team ID
func fetchTeamLogos(teams: [Team]) async -> [UUID: UIImage] {
let urlToTeam: [URL: UUID] = Dictionary(
func fetchTeamLogos(teams: [Team]) async -> [String: UIImage] {
let urlToTeam: [URL: String] = Dictionary(
uniqueKeysWithValues: teams.compactMap { team in
guard let logoURL = team.logoURL else { return nil }
return (logoURL, team.id)
@@ -121,7 +121,7 @@ actor RemoteImageService {
let images = await fetchImages(from: Array(urlToTeam.keys))
var result: [UUID: UIImage] = [:]
var result: [String: UIImage] = [:]
for (url, image) in images {
if let teamId = urlToTeam[url] {
result[teamId] = image
@@ -132,8 +132,8 @@ actor RemoteImageService {
}
/// Fetch stadium photos by stadium ID
func fetchStadiumPhotos(stadiums: [Stadium]) async -> [UUID: UIImage] {
let urlToStadium: [URL: UUID] = Dictionary(
func fetchStadiumPhotos(stadiums: [Stadium]) async -> [String: UIImage] {
let urlToStadium: [URL: String] = Dictionary(
uniqueKeysWithValues: stadiums.compactMap { stadium in
guard let imageURL = stadium.imageURL else { return nil }
return (imageURL, stadium.id)
@@ -142,7 +142,7 @@ actor RemoteImageService {
let images = await fetchImages(from: Array(urlToStadium.keys))
var result: [UUID: UIImage] = [:]
var result: [String: UIImage] = [:]
for (url, image) in images {
if let stadiumId = urlToStadium[url] {
result[stadiumId] = image