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

@@ -353,6 +353,36 @@ struct GameDAGRouterTests {
#expect(!combinedRoutes.isEmpty, "NYC to Chicago over 2 days should be feasible")
}
@Test("findRoutes: anchor routes can span gaps larger than 5 days")
func findRoutes_anchorRoutesAllowLongDateGaps() {
let today = calendar.startOfDay(for: Date())
let day0 = today
let day1 = calendar.date(byAdding: .day, value: 1, to: today)!
let day8 = calendar.date(byAdding: .day, value: 8, to: today)!
let sharedStadium = makeStadium(city: "New York", coord: nycCoord)
let bridgeStadium = makeStadium(city: "Boston", coord: bostonCoord)
let anchorStart = makeGame(stadiumId: sharedStadium.id, date: day0)
let bridgeGame = makeGame(stadiumId: bridgeStadium.id, date: day1)
let anchorEnd = makeGame(stadiumId: sharedStadium.id, date: day8)
let routes = GameDAGRouter.findRoutes(
games: [anchorStart, bridgeGame, anchorEnd],
stadiums: [sharedStadium.id: sharedStadium, bridgeStadium.id: bridgeStadium],
constraints: constraints,
anchorGameIds: [anchorStart.id, anchorEnd.id]
)
#expect(!routes.isEmpty, "Expected a route that includes both anchors across an 8-day gap")
for route in routes {
let ids = Set(route.map { $0.id })
#expect(ids.contains(anchorStart.id), "Route should include start anchor")
#expect(ids.contains(anchorEnd.id), "Route should include end anchor")
}
}
// MARK: - Property Tests
@Test("Property: route count never exceeds maxOptions (75)")