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

@@ -35,7 +35,7 @@ struct TripPlanningEngineTests {
/// Creates a stadium at a known location
private func makeStadium(
id: UUID = UUID(),
id: String = "stadium_test_\(UUID().uuidString)",
city: String,
lat: Double,
lon: Double,
@@ -55,10 +55,10 @@ struct TripPlanningEngineTests {
/// Creates a game at a stadium
private func makeGame(
id: UUID = UUID(),
stadiumId: UUID,
homeTeamId: UUID = UUID(),
awayTeamId: UUID = UUID(),
id: String = "game_test_\(UUID().uuidString)",
stadiumId: String,
homeTeamId: String = "team_test_\(UUID().uuidString)",
awayTeamId: String = "team_test_\(UUID().uuidString)",
dateTime: Date,
sport: Sport = .mlb
) -> Game {
@@ -78,7 +78,7 @@ struct TripPlanningEngineTests {
startDate: Date,
endDate: Date,
games: [Game],
stadiums: [UUID: Stadium],
stadiums: [String: Stadium],
numberOfDrivers: Int = 1,
maxDrivingHoursPerDriver: Double = 8.0,
allowRepeatCities: Bool = true
@@ -104,11 +104,11 @@ struct TripPlanningEngineTests {
/// Creates a PlanningRequest for Scenario B (selected games)
private func makeScenarioBRequest(
mustSeeGameIds: Set<UUID>,
mustSeeGameIds: Set<String>,
startDate: Date,
endDate: Date,
games: [Game],
stadiums: [UUID: Stadium],
stadiums: [String: Stadium],
numberOfDrivers: Int = 1,
maxDrivingHoursPerDriver: Double = 8.0,
allowRepeatCities: Bool = true
@@ -140,7 +140,7 @@ struct TripPlanningEngineTests {
startDate: Date,
endDate: Date,
games: [Game],
stadiums: [UUID: Stadium],
stadiums: [String: Stadium],
numberOfDrivers: Int = 1,
maxDrivingHoursPerDriver: Double = 8.0
) -> PlanningRequest {
@@ -169,8 +169,8 @@ struct TripPlanningEngineTests {
@Test("7.1 - Engine delegates to Scenario A correctly")
func test_engine_ScenarioA_DelegatesCorrectly() {
// Setup: Date range only request (Scenario A)
let chicagoId = UUID()
let milwaukeeId = UUID()
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
@@ -202,8 +202,8 @@ struct TripPlanningEngineTests {
@Test("7.2 - Engine delegates to Scenario B correctly")
func test_engine_ScenarioB_DelegatesCorrectly() {
// Setup: Selected games request (Scenario B)
let chicagoId = UUID()
let milwaukeeId = UUID()
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
@@ -244,9 +244,9 @@ struct TripPlanningEngineTests {
@Test("7.3 - Engine delegates to Scenario C correctly")
func test_engine_ScenarioC_DelegatesCorrectly() {
// Setup: Start/end locations request (Scenario C)
let chicagoId = UUID()
let clevelandId = UUID()
let detroitId = UUID()
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
let clevelandId = "stadium_cleveland_\(UUID().uuidString)"
let detroitId = "stadium_detroit_\(UUID().uuidString)"
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
let cleveland = makeStadium(id: clevelandId, city: "Cleveland", lat: 41.4993, lon: -81.6944)
@@ -294,8 +294,8 @@ struct TripPlanningEngineTests {
@Test("7.4 - Scenarios are mutually exclusive")
func test_engine_ScenariosAreMutuallyExclusive() {
// Setup: Create requests that could theoretically match multiple scenarios
let chicagoId = UUID()
let clevelandId = UUID()
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
let clevelandId = "stadium_cleveland_\(UUID().uuidString)"
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
let cleveland = makeStadium(id: clevelandId, city: "Cleveland", lat: 41.4993, lon: -81.6944)
@@ -350,9 +350,9 @@ struct TripPlanningEngineTests {
@Test("7.5 - Result contains travel segments")
func test_engine_Result_ContainsTravelSegments() {
// Setup: Multi-city trip that requires travel
let chicagoId = UUID()
let milwaukeeId = UUID()
let detroitId = UUID()
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
let detroitId = "stadium_detroit_\(UUID().uuidString)"
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
@@ -396,8 +396,8 @@ struct TripPlanningEngineTests {
@Test("7.6 - Result contains itinerary days")
func test_engine_Result_ContainsItineraryDays() {
// Setup: Multi-day trip
let chicagoId = UUID()
let milwaukeeId = UUID()
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
@@ -445,7 +445,7 @@ struct TripPlanningEngineTests {
func test_engine_Result_IncludesWarnings_WhenApplicable() {
// Setup: Request that would normally violate repeat cities
// but allowRepeatCities=true so it should succeed without warnings
let chicagoId = UUID()
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
@@ -497,8 +497,8 @@ struct TripPlanningEngineTests {
func test_engine_NumberOfDrivers_AffectsMaxDailyDriving() {
// Setup: Long distance trip that requires significant driving
// NYC to Chicago is ~790 miles (~13 hours of driving)
let nycId = UUID()
let chicagoId = UUID()
let nycId = "stadium_nyc_\(UUID().uuidString)"
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
let nyc = makeStadium(id: nycId, city: "New York", lat: 40.7128, lon: -73.9352)
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
@@ -593,8 +593,8 @@ struct TripPlanningEngineTests {
@Test("7.10 - AllowRepeatCities is propagated to DAG")
func test_engine_AllowRepeatCities_PropagatedToDAG() {
// Setup: Games that would require visiting the same city twice
let chicagoId = UUID()
let milwaukeeId = UUID()
let chicagoId = "stadium_chicago_\(UUID().uuidString)"
let milwaukeeId = "stadium_milwaukee_\(UUID().uuidString)"
let chicago = makeStadium(id: chicagoId, city: "Chicago", lat: 41.8781, lon: -87.6298)
let milwaukee = makeStadium(id: milwaukeeId, city: "Milwaukee", lat: 43.0389, lon: -87.9065)
@@ -657,8 +657,8 @@ struct TripPlanningEngineTests {
func test_engine_ImpossibleConstraints_ReturnsNoResult() {
// Setup: Create an impossible constraint scenario
// Games at the same time on same day in cities far apart (can't make both)
let nycId = UUID()
let laId = UUID()
let nycId = "stadium_nyc_\(UUID().uuidString)"
let laId = "stadium_la_\(UUID().uuidString)"
// NYC to LA is ~2,800 miles - impossible to drive same day
let nyc = makeStadium(id: nycId, city: "New York", lat: 40.7128, lon: -73.9352)
@@ -711,7 +711,7 @@ struct TripPlanningEngineTests {
@Test("7.12 - Empty input returns error")
func test_engine_EmptyInput_ThrowsError() {
// Setup: Request with no games
let stadiumId = UUID()
let stadiumId = "stadium_test_\(UUID().uuidString)"
let stadium = makeStadium(id: stadiumId, city: "Chicago", lat: 41.8781, lon: -87.6298)
let stadiums = [stadiumId: stadium]