Refactor travel segments and simplify trip options

Travel segment architecture:
- Remove departureTime/arrivalTime from TravelSegment (location-based, not date-based)
- Fix travel sections appearing after destination instead of between cities
- Fix missing travel segments when revisiting same city (consecutive grouping)
- Remove unwanted rest day at end of trip

Planning engine fixes:
- All three planners now group only consecutive games at same stadium
- Visiting A → B → A creates 3 stops with proper travel between

UI simplification:
- Remove redundant sort options (mostDriving/leastDriving, mostCities/leastCities)
- Remove unused "Find Other Sports Along Route" toggle (was dead code)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-01-07 19:39:53 -06:00
parent 40a6f879e3
commit 4184af60b5
29 changed files with 140675 additions and 144310 deletions

View File

@@ -1794,45 +1794,9 @@ struct ScenarioCPlannerTests {
}
}
@Test("Departure time before arrival time")
func plan_DepartureBeforeArrival() {
let planner = ScenarioCPlanner()
let sd = sdStadium
let la = laStadium
let sf = sfStadium
let game = makeGame(stadiumId: la.id, date: date("2026-06-10 19:00"))
let startLoc = LocationInput(
name: "San Diego",
coordinate: CLLocationCoordinate2D(latitude: sd.latitude, longitude: sd.longitude)
)
let endLoc = LocationInput(
name: "San Francisco",
coordinate: CLLocationCoordinate2D(latitude: sf.latitude, longitude: sf.longitude)
)
let request = makeRequest(
games: [game],
stadiums: [sd.id: sd, la.id: la, sf.id: sf],
startLocation: startLoc,
endLocation: endLoc,
startDate: date("2026-06-01 00:00"),
endDate: date("2026-06-30 23:59")
)
let result = planner.plan(request: request)
if case .success(let options) = result {
for option in options {
for segment in option.travelSegments {
#expect(segment.departureTime < segment.arrivalTime)
}
}
} else {
Issue.record("Expected success")
}
}
// Note: "Departure time before arrival time" test removed
// Travel segments are now location-based, not time-based
// The user decides when to travel; segments only describe route info
@Test("Games filtered to date range")
func plan_GamesFilteredToDateRange() {

View File

@@ -326,18 +326,8 @@ struct TravelEstimatorTests {
#expect(twoDrivers != nil, "Should succeed with two drivers - within 32h limit")
}
@Test("estimate stops - calculates departure and arrival times")
func estimateStops_CalculatesTimes() {
let baseDate = Calendar.current.date(from: DateComponents(year: 2026, month: 4, day: 5))!
let stop1 = makeStop(city: "Los Angeles", latitude: 34.0522, longitude: -118.2437, departureDate: baseDate)
let stop2 = makeStop(city: "San Diego", latitude: 32.7157, longitude: -117.1611)
let segment = TravelEstimator.estimate(from: stop1, to: stop2, constraints: defaultConstraints())
#expect(segment != nil)
#expect(segment!.departureTime > baseDate, "Departure should be after base date (adds 8 hours)")
#expect(segment!.arrivalTime > segment!.departureTime, "Arrival should be after departure")
}
// Note: departure/arrival time tests removed - travel is now location-based, not time-based
// The user decides when to travel; segments only describe route info (distance, duration)
@Test("estimate stops - distance and duration are consistent")
func estimateStops_DistanceDurationConsistent() {