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:
@@ -272,7 +272,7 @@ final class ScenarioCPlanner: ScenarioPlanner {
|
||||
/// Finds all stadiums in a given city (case-insensitive match).
|
||||
private func findStadiumsInCity(
|
||||
cityName: String,
|
||||
stadiums: [UUID: Stadium]
|
||||
stadiums: [String: Stadium]
|
||||
) -> [Stadium] {
|
||||
let normalizedCity = cityName.lowercased().trimmingCharacters(in: .whitespaces)
|
||||
return stadiums.values.filter { stadium in
|
||||
@@ -296,14 +296,14 @@ final class ScenarioCPlanner: ScenarioPlanner {
|
||||
private func findDirectionalStadiums(
|
||||
from start: CLLocationCoordinate2D,
|
||||
to end: CLLocationCoordinate2D,
|
||||
stadiums: [UUID: Stadium]
|
||||
) -> Set<UUID> {
|
||||
stadiums: [String: Stadium]
|
||||
) -> Set<String> {
|
||||
let directDistance = distanceBetween(start, end)
|
||||
|
||||
// Allow detours up to 50% longer than direct distance
|
||||
let maxDetourDistance = directDistance * 1.5
|
||||
|
||||
var directionalIds: Set<UUID> = []
|
||||
var directionalIds: Set<String> = []
|
||||
|
||||
for (id, stadium) in stadiums {
|
||||
let stadiumCoord = stadium.coordinate
|
||||
@@ -349,8 +349,8 @@ final class ScenarioCPlanner: ScenarioPlanner {
|
||||
/// Create a date range from start_game.date to end_game.date
|
||||
///
|
||||
private func generateDateRanges(
|
||||
startStadiumIds: Set<UUID>,
|
||||
endStadiumIds: Set<UUID>,
|
||||
startStadiumIds: Set<String>,
|
||||
endStadiumIds: Set<String>,
|
||||
allGames: [Game],
|
||||
request: PlanningRequest
|
||||
) -> [DateInterval] {
|
||||
@@ -417,7 +417,7 @@ final class ScenarioCPlanner: ScenarioPlanner {
|
||||
/// Creates separate stops when visiting the same city with other cities in between.
|
||||
private func buildStops(
|
||||
from games: [Game],
|
||||
stadiums: [UUID: Stadium]
|
||||
stadiums: [String: Stadium]
|
||||
) -> [ItineraryStop] {
|
||||
guard !games.isEmpty else { return [] }
|
||||
|
||||
@@ -426,7 +426,7 @@ final class ScenarioCPlanner: ScenarioPlanner {
|
||||
|
||||
// Group consecutive games at the same stadium
|
||||
var stops: [ItineraryStop] = []
|
||||
var currentStadiumId: UUID? = nil
|
||||
var currentStadiumId: String? = nil
|
||||
var currentGames: [Game] = []
|
||||
|
||||
for game in sortedGames {
|
||||
@@ -458,8 +458,8 @@ final class ScenarioCPlanner: ScenarioPlanner {
|
||||
/// Creates an ItineraryStop from a group of games at the same stadium.
|
||||
private func createStop(
|
||||
from games: [Game],
|
||||
stadiumId: UUID,
|
||||
stadiums: [UUID: Stadium]
|
||||
stadiumId: String,
|
||||
stadiums: [String: Stadium]
|
||||
) -> ItineraryStop? {
|
||||
guard !games.isEmpty else { return nil }
|
||||
|
||||
@@ -496,7 +496,7 @@ final class ScenarioCPlanner: ScenarioPlanner {
|
||||
start: LocationInput,
|
||||
end: LocationInput,
|
||||
games: [Game],
|
||||
stadiums: [UUID: Stadium]
|
||||
stadiums: [String: Stadium]
|
||||
) -> [ItineraryStop] {
|
||||
|
||||
var stops: [ItineraryStop] = []
|
||||
|
||||
Reference in New Issue
Block a user