fix(itinerary): add city to game items for proper constraint validation

Travel constraint validation was not working because ItineraryConstraints
had no game items to validate against - games came from RichGame objects
but were never converted to ItineraryItem for constraint checking.

Changes:
- Add city parameter to ItemKind.game enum case
- Create game ItineraryItems from RichGame data in buildItineraryData()
- Update isValidTravelPosition to compare against actual game sortOrders
- Fix tests to use appropriate game sortOrder conventions

Now travel is properly constrained to appear before arrival city games
and after departure city games.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-01-18 22:46:40 -06:00
parent 72447c61fe
commit e72da7c5a7
11 changed files with 247 additions and 254 deletions

View File

@@ -243,24 +243,27 @@ final class ItineraryReorderingLogicTests: XCTestCase {
// MARK: - travelRow Tests
func test_travelRow_findsCorrectRow() {
// Semantic model: travelRow finds travel in the section AFTER the day header
// Travel must be positioned within its correct day section
let items = buildFlatItems([
.day(1),
.game("Detroit", day: 1),
.travel(from: "Detroit", to: "Chicago", day: 2),
.day(2),
.travel(from: "Chicago", to: "Milwaukee", day: 3),
.day(3)
.travel(from: "Detroit", to: "Chicago", day: 2), // Row 3: in day 2 section
.day(3),
.travel(from: "Chicago", to: "Milwaukee", day: 3) // Row 5: in day 3 section
])
XCTAssertEqual(Logic.travelRow(in: items, forDay: 2), 2)
XCTAssertEqual(Logic.travelRow(in: items, forDay: 3), 4)
XCTAssertEqual(Logic.travelRow(in: items, forDay: 2), 3)
XCTAssertEqual(Logic.travelRow(in: items, forDay: 3), 5)
}
func test_travelRow_noTravelOnDay_returnsNil() {
// Travel is in day 2 section, so day 1 has no travel
let items = buildFlatItems([
.day(1),
.travel(from: "Detroit", to: "Chicago", day: 2),
.day(2)
.day(2),
.travel(from: "Detroit", to: "Chicago", day: 2) // In day 2 section
])
XCTAssertNil(Logic.travelRow(in: items, forDay: 1))