feat: improve planning engine travel handling, itinerary reordering, and scenario planners

Add TravelInfo initializers and city normalization helpers to fix repeat
city-pair disambiguation. Improve drag-and-drop reordering with segment
index tracking and source-row-aware zone calculation. Enhance all five
scenario planners with better next-day departure handling and travel
segment placement. Add comprehensive tests across all planners.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-02-13 08:55:23 -06:00
parent 1c97f35754
commit 9736773475
19 changed files with 928 additions and 171 deletions

View File

@@ -197,6 +197,47 @@ struct ScenarioCPlannerTests {
#expect(failure.reason == .noGamesInRange)
}
@Test("plan: city names with state suffixes match stadium city names")
func plan_cityNamesWithStateSuffixes_matchStadiumCities() {
let baseDate = Date()
let endDate = baseDate.addingTimeInterval(86400 * 10)
let startLocation = LocationInput(name: "Chicago, IL", coordinate: chicagoCoord)
let endLocation = LocationInput(name: "New York, NY", coordinate: nycCoord)
let chicagoStadium = makeStadium(id: "chicago", city: "Chicago", coordinate: chicagoCoord)
let nycStadium = makeStadium(id: "nyc", city: "New York", coordinate: nycCoord)
let chicagoGame = makeGame(id: "chi-game", stadiumId: "chicago", dateTime: baseDate.addingTimeInterval(86400 * 1))
let nycGame = makeGame(id: "nyc-game", stadiumId: "nyc", dateTime: baseDate.addingTimeInterval(86400 * 4))
let prefs = TripPreferences(
planningMode: .locations,
startLocation: startLocation,
endLocation: endLocation,
sports: [.mlb],
startDate: baseDate,
endDate: endDate,
leisureLevel: .moderate,
lodgingType: .hotel,
numberOfDrivers: 2
)
let request = PlanningRequest(
preferences: prefs,
availableGames: [chicagoGame, nycGame],
teams: [:],
stadiums: ["chicago": chicagoStadium, "nyc": nycStadium]
)
let result = planner.plan(request: request)
guard case .success = result else {
Issue.record("Expected success with city/state location labels matching plain stadium cities")
return
}
}
// MARK: - Specification Tests: Directional Filtering
@Test("plan: directional filtering includes stadiums toward destination")