fix: 12 planning engine bugs + App Store preview export at 886x1920
Planning engine fixes (from adversarial code review): - Bug #1: sortByLeisure tie-breaking uses totalDrivingHours - Bug #2: allDates/calculateRestDays guard-let-break prevents infinite loop - Bug #3: same-day trip no longer rejected (>= in dateRange guard) - Bug #4: ScenarioD rationale shows game count not stop count - Bug #5: ScenarioD departureDate advanced to next day after last game - Bug #6: ScenarioC date range boundary uses <= instead of < - Bug #7: DrivingConstraints clamps maxHoursPerDriverPerDay via max(1.0,...) - Bug #8: effectiveTripDuration uses inclusive day counting (+1) - Bug #9: TripWizardViewModel validates endDate >= startDate - Bug #10: allDates() uses min/max instead of first/last for robustness - Bug #12: arrivalBeforeGameStart accounts for game end time at departure - Bug #15: ScenarioBPlanner replaces force unwraps with safe unwrapping Tests: 16 regression test suites + updated existing test expectations Marketing: Remotion canvas set to 886x1920 for App Store preview spec Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -70,7 +70,8 @@ final class ScenarioDPlanner: ScenarioPlanner {
|
||||
// ──────────────────────────────────────────────────────────────────
|
||||
// Step 1: Validate team selection
|
||||
// ──────────────────────────────────────────────────────────────────
|
||||
guard let teamId = request.preferences.followTeamId else {
|
||||
guard let teamId = request.preferences.followTeamId
|
||||
?? request.preferences.selectedTeamIds.first else {
|
||||
return .failure(
|
||||
PlanningFailure(
|
||||
reason: .missingTeamSelection,
|
||||
@@ -261,7 +262,7 @@ final class ScenarioDPlanner: ScenarioPlanner {
|
||||
travelSegments: itinerary.travelSegments,
|
||||
totalDrivingHours: itinerary.totalDrivingHours,
|
||||
totalDistanceMiles: itinerary.totalDistanceMiles,
|
||||
geographicRationale: "Follow Team: \(stops.count) games - \(cities)"
|
||||
geographicRationale: "Follow Team: \(itinerary.stops.reduce(0) { $0 + $1.games.count }) games - \(cities)"
|
||||
)
|
||||
itineraryOptions.append(option)
|
||||
}
|
||||
@@ -396,6 +397,7 @@ final class ScenarioDPlanner: ScenarioPlanner {
|
||||
)
|
||||
|
||||
let lastGameDate = sortedGames.last?.gameDate ?? Date()
|
||||
let calendar = Calendar.current
|
||||
|
||||
return ItineraryStop(
|
||||
city: city,
|
||||
@@ -403,7 +405,7 @@ final class ScenarioDPlanner: ScenarioPlanner {
|
||||
coordinate: coordinate,
|
||||
games: sortedGames.map { $0.id },
|
||||
arrivalDate: sortedGames.first?.gameDate ?? Date(),
|
||||
departureDate: lastGameDate,
|
||||
departureDate: calendar.date(byAdding: .day, value: 1, to: lastGameDate) ?? lastGameDate.addingTimeInterval(86400),
|
||||
location: location,
|
||||
firstGameStart: sortedGames.first?.startTime
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user