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:
@@ -174,12 +174,14 @@ final class PhotoImportViewModel {
|
||||
|
||||
// Create the visit
|
||||
let visit = StadiumVisit(
|
||||
canonicalStadiumId: match.stadium.id.uuidString,
|
||||
stadiumUUID: match.stadium.id,
|
||||
stadiumId: match.stadium.id,
|
||||
stadiumNameAtVisit: match.stadium.name,
|
||||
visitDate: match.game.dateTime,
|
||||
sport: match.game.sport,
|
||||
visitType: .game,
|
||||
gameId: match.game.id,
|
||||
homeTeamId: match.homeTeam.id,
|
||||
awayTeamId: match.awayTeam.id,
|
||||
homeTeamName: match.homeTeam.fullName,
|
||||
awayTeamName: match.awayTeam.fullName,
|
||||
finalScore: match.formattedFinalScore,
|
||||
|
||||
@@ -41,10 +41,10 @@ final class ProgressViewModel {
|
||||
let visitedStadiumIds = Set(
|
||||
visits
|
||||
.filter { $0.sportEnum == selectedSport }
|
||||
.compactMap { visit -> UUID? in
|
||||
.compactMap { visit -> String? in
|
||||
// Match visit's canonical stadium ID to a stadium
|
||||
stadiums.first { stadium in
|
||||
stadium.id == visit.stadiumUUID
|
||||
stadium.id == visit.stadiumId
|
||||
}?.id
|
||||
}
|
||||
)
|
||||
@@ -62,11 +62,11 @@ final class ProgressViewModel {
|
||||
}
|
||||
|
||||
/// Stadium visit status indexed by stadium ID
|
||||
var stadiumVisitStatus: [UUID: StadiumVisitStatus] {
|
||||
var statusMap: [UUID: StadiumVisitStatus] = [:]
|
||||
var stadiumVisitStatus: [String: StadiumVisitStatus] {
|
||||
var statusMap: [String: StadiumVisitStatus] = [:]
|
||||
|
||||
// Group visits by stadium
|
||||
let visitsByStadium = Dictionary(grouping: visits.filter { $0.sportEnum == selectedSport }) { $0.stadiumUUID }
|
||||
let visitsByStadium = Dictionary(grouping: visits.filter { $0.sportEnum == selectedSport }) { $0.stadiumId }
|
||||
|
||||
for stadium in stadiums {
|
||||
if let stadiumVisits = visitsByStadium[stadium.id], !stadiumVisits.isEmpty {
|
||||
@@ -114,7 +114,7 @@ final class ProgressViewModel {
|
||||
.sorted { $0.visitDate > $1.visitDate }
|
||||
.prefix(10)
|
||||
.compactMap { visit -> VisitSummary? in
|
||||
guard let stadium = stadiums.first(where: { $0.id == visit.stadiumUUID }),
|
||||
guard let stadium = stadiums.first(where: { $0.id == visit.stadiumId }),
|
||||
let sport = visit.sportEnum else {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import MapKit
|
||||
|
||||
struct ProgressMapView: View {
|
||||
let stadiums: [Stadium]
|
||||
let visitStatus: [UUID: StadiumVisitStatus]
|
||||
let visitStatus: [String: StadiumVisitStatus]
|
||||
@Binding var selectedStadium: Stadium?
|
||||
|
||||
// Fixed region for continental US - map is locked to this view
|
||||
|
||||
@@ -389,8 +389,7 @@ struct StadiumVisitSheet: View {
|
||||
|
||||
// Create the visit
|
||||
let visit = StadiumVisit(
|
||||
canonicalStadiumId: stadium.id.uuidString, // Simplified - in production use StadiumIdentityService
|
||||
stadiumUUID: stadium.id,
|
||||
stadiumId: stadium.id,
|
||||
stadiumNameAtVisit: stadium.name,
|
||||
visitDate: visitDate,
|
||||
sport: selectedSport,
|
||||
|
||||
@@ -523,7 +523,7 @@ extension VisitSource {
|
||||
|
||||
#Preview {
|
||||
let stadium = Stadium(
|
||||
id: UUID(),
|
||||
id: "stadium_preview_oracle_park",
|
||||
name: "Oracle Park",
|
||||
city: "San Francisco",
|
||||
state: "CA",
|
||||
|
||||
Reference in New Issue
Block a user