---
phase: 09-trip-planner-modes-tdd
plan: 01
type: tdd
---
Test-driven validation of Scenario A (date range planning) timezone boundary handling and same-day multi-city conflict detection.
Purpose: Ensure date range boundaries respect timezone context and detect impossible same-day games in different cities. Tests define correctness - code must match.
Output: Working timezone boundary handling and conflict detection with passing TDD tests.
~/.claude/get-shit-done/workflows/execute-phase.md
./summary.md
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/08-dag-system-tdd/08-01-SUMMARY.md
@.planning/phases/08-dag-system-tdd/08-02-SUMMARY.md
@SportsTime/Planning/Engine/ScenarioAPlanner.swift
@SportsTimeTests/ScenarioAPlannerSwiftTests.swift
@SportsTimeTests/GameDAGRouterTests.swift
**Tech stack available:** Swift Testing framework, GameDAGRouter with dynamic beam scaling
**Established patterns:** Swift Testing @Test/@Suite, TDD RED-GREEN-REFACTOR, makeStadium/makeGame/date helpers
**Constraining decisions:**
- Phase 08-01: Tests validate behavior via findRoutes() rather than testing internal methods directly
- Phase 08-02: Dynamic beam width scaling for performance (800+ games use width 50)
**Issues being addressed:** None (new test coverage)
Feature 1: Timezone boundary handling for date range
SportsTimeTests/ScenarioAPlannerSwiftTests.swift
SportsTime/Planning/Engine/ScenarioAPlanner.swift
Test cases for date range timezone boundary correctness:
**Case 1: Game at range start in different timezone (included)**
- Date range: Jan 5 00:00 PST to Jan 10 23:59 PST
- Game: Jan 5 19:00 EST (New York) = Jan 5 16:00 PST
- Expected: Game included (within PST range)
**Case 2: Game just before range start in different timezone (excluded)**
- Date range: Jan 5 00:00 PST to Jan 10 23:59 PST
- Game: Jan 4 22:00 EST (New York) = Jan 4 19:00 PST
- Expected: Game excluded (before PST range start)
**Case 3: Game at range end in different timezone (included)**
- Date range: Jan 5 00:00 PST to Jan 10 23:59 PST
- Game: Jan 10 21:00 EST (New York) = Jan 10 18:00 PST
- Expected: Game included (within PST range)
**Case 4: Game just after range end in different timezone (excluded)**
- Date range: Jan 5 00:00 PST to Jan 10 23:59 PST
- Game: Jan 11 02:00 EST (New York) = Jan 10 23:00 PST
- Expected: Game excluded (after PST range end when converted)
Note: DateInterval.contains() handles Date correctly across timezones - verify it works as expected.
If tests fail due to timezone conversion issues:
1. Verify DateInterval uses absolute Date comparison (it should)
2. Check game.startTime is constructed in correct timezone
3. Ensure date range boundaries are interpreted in user's timezone (not UTC)
4. Fix ScenarioAPlanner filtering logic if needed
Feature 2: Same-day multi-city conflict detection
SportsTimeTests/ScenarioAPlannerSwiftTests.swift
SportsTime/Planning/Engine/ScenarioAPlanner.swift
Test cases for impossible same-day game scheduling:
**Case 1: Same-day games in cities <4 hours apart (feasible)**
- LA game at 1pm, San Diego game at 7pm (120 miles, 2hr drive)
- Expected: Both games in route (enough time to drive between)
**Case 2: Same-day games in distant cities (infeasible)**
- LA game at 1pm, San Francisco game at 7pm (380 miles, 6hr drive)
- Expected: Route picks ONE game (cannot attend both same day)
**Case 3: Same-day games in opposite coasts (obviously infeasible)**
- LA game at 1pm, New York game at 7pm EST (2800 miles)
- Expected: Route picks ONE game (impossible same day)
**Case 4: Three same-day games, two feasible combinations**
- LA 1pm, Anaheim 4pm (30mi), San Diego 7pm (90mi from Anaheim)
- Expected: Route includes LA→Anaheim→SD OR picks best option
- Constraint: Cannot include NY game on same day
Current behavior: GameDAGRouter.canTransition() checks time/distance feasibility.
Tests verify routes respect these constraints when multiple same-day options exist.
If tests fail:
1. GameDAGRouter.canTransition() may need to check calendar day conflicts
2. ScenarioAPlanner may need to pre-filter impossible same-day combinations
3. RouteFilters may need same-day conflict detection
4. Fix the appropriate layer (likely GameDAGRouter or ScenarioAPlanner)
Do NOT weaken test assertions - fix the code to match expected behavior.
All tests pass:
```bash
xcodebuild -project SportsTime.xcodeproj -scheme SportsTime \
-destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' \
-only-testing:SportsTimeTests/ScenarioAPlannerSwiftTests test
```
Specific tests to verify:
- Timezone boundary tests: 4 new tests (range start/end, before/after, cross-timezone)
- Same-day conflict tests: 4 new tests (feasible close, infeasible far, opposite coasts, three-game selection)
- 8 new tests added to ScenarioAPlannerSwiftTests.swift
- All tests follow TDD pattern (RED → GREEN → REFACTOR)
- Each feature produces 2-3 commits (test, feat, optional refactor)
- No test assertions weakened
- All existing tests continue to pass
- Tests use existing helper patterns (makeStadium, makeGame, date)