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

@@ -297,6 +297,49 @@ struct ScenarioBPlannerTests {
// May also fail if no valid date ranges, which is acceptable
}
@Test("plan: explicit date range with out-of-range selected game returns dateRangeViolation")
func plan_explicitDateRange_selectedGameOutsideRange_returnsDateRangeViolation() {
let baseDate = Date()
let rangeStart = baseDate
let rangeEnd = baseDate.addingTimeInterval(86400 * 3)
let outOfRangeDate = baseDate.addingTimeInterval(86400 * 10)
let stadium = makeStadium(id: "stadium1", city: "New York", coordinate: nycCoord)
let selectedGame = makeGame(id: "outside-anchor", stadiumId: "stadium1", dateTime: outOfRangeDate)
let prefs = TripPreferences(
planningMode: .dateRange,
sports: [.mlb],
mustSeeGameIds: ["outside-anchor"],
startDate: rangeStart,
endDate: rangeEnd,
leisureLevel: .moderate,
lodgingType: .hotel,
numberOfDrivers: 1
)
let request = PlanningRequest(
preferences: prefs,
availableGames: [selectedGame],
teams: [:],
stadiums: ["stadium1": stadium]
)
let result = planner.plan(request: request)
guard case .failure(let failure) = result else {
Issue.record("Expected date range violation when selected game is outside explicit range")
return
}
guard case .dateRangeViolation(let violatingGames) = failure.reason else {
Issue.record("Expected .dateRangeViolation, got \(failure.reason)")
return
}
#expect(Set(violatingGames.map { $0.id }) == ["outside-anchor"])
}
// MARK: - Specification Tests: Arrival Time Validation
@Test("plan: uses arrivalBeforeGameStart validator")