Files
Sportstime/CLAUDE.md
Trey t 9088b46563 Initial commit: SportsTime trip planning app
- Three-scenario planning engine (A: date range, B: selected games, C: directional routes)
- GeographicRouteExplorer with anchor game support for route exploration
- Shared ItineraryBuilder for travel segment calculation
- TravelEstimator for driving time/distance estimation
- SwiftUI views for trip creation and detail display
- CloudKit integration for schedule data
- Python scraping scripts for sports schedules

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 00:46:40 -06:00

6.3 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Build & Run Commands

# Build the iOS app
xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' build

# Run tests
xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' test

# Run specific test suite
xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' -only-testing:SportsTimeTests/TripPlanningEngineTests test

# Run a single test
xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' -only-testing:SportsTimeTests/TestClassName/testMethodName test

# Data scraping (Python)
cd Scripts && pip install -r requirements.txt
python scrape_schedules.py --sport all --season 2026

Architecture Overview

This is an iOS app for planning multi-stop sports road trips. It uses Clean MVVM with feature-based modules.

Three-Layer Architecture

  1. Presentation Layer (Features/): SwiftUI Views + @Observable ViewModels organized by feature (Home, Trip, Schedule, Settings)

  2. Domain Layer (Planning/): Trip planning logic

    • TripPlanningEngine - Main orchestrator, 7-step algorithm
    • RouteOptimizer - TSP solver (exact for <8 stops, heuristic otherwise)
    • ScheduleMatcher - Finds games along route corridor
    • TripScorer - Multi-factor scoring (game quality, route efficiency, leisure balance)
  3. Data Layer (Core/):

    • Models/Domain/ - Pure Swift structs (Trip, Game, Stadium, Team)
    • Models/CloudKit/ - CKRecord wrappers for public database
    • Models/Local/ - SwiftData models for local persistence (SavedTrip, UserPreferences)
    • Services/ - CloudKitService (schedules), LocationService (geocoding/routing)

Data Storage Strategy

  • CloudKit Public DB: Read-only schedules, stadiums, teams (shared across all users)
  • SwiftData Local: User's saved trips, preferences, cached schedules
  • No network dependency for trip planning once schedules are synced

Key Data Flow

TripCreationView → TripCreationViewModel → PlanningRequest
    → TripPlanningEngine (ScheduleMatcher + RouteOptimizer + TripScorer)
    → PlanningResult → Trip → TripDetailView → SavedTrip (persist)

Important Patterns

  • ViewModels use @Observable (not ObservableObject)
  • All planning engine components are actor types for thread safety
  • Domain models are pure Codable structs; SwiftData models wrap them via encoded Data fields
  • CloudKit container ID: iCloud.com.sportstime.app

Key View Components

TripDetailView (Features/Trip/Views/TripDetailView.swift)

Displays trip itinerary with conflict detection for same-day games in different cities.

Conflict Detection System:

  • detectConflicts(for: ItineraryDay) - Checks if multiple stops have games on the same calendar day
  • Returns DayConflictInfo with hasConflict, conflictingStops, and conflictingCities

RouteOptionsCard (Expandable):

  • Shows when multiple route options exist for the same day (conflicting games in different cities)
  • Collapsed: Shows "N route options" with city list, tap to expand
  • Expanded: Shows each option as a RouteOptionCard with numbered badge (Option 1, Option 2, etc.)
  • Single routes (no conflict): Uses regular DayCard, auto-expanded

RouteOptionCard:

  • Individual option within the expandable RouteOptionsCard
  • Shows option number badge, city name, games at that stop, and travel info

DayCard Component (non-conflict mode):

  • specificStop: TripStop? - When provided, shows only that stop's games
  • primaryCityForDay - Returns the city for the card
  • gamesOnThisDay - Returns games filtered to the calendar day

Visual Design:

  • Expandable cards have orange border and branch icon
  • Option badges are blue capsules
  • Chevron indicates expand/collapse state

Scripts

Scripts/scrape_schedules.py scrapes NBA/MLB/NHL schedules from multiple sources (Basketball-Reference, Baseball-Reference, Hockey-Reference, official APIs) for cross-validation. See Scripts/DATA_SOURCES.md for source URLs and rate limits.

Test Suites

  • TripPlanningEngineTests (50 tests) - Routing logic, must-see games, required destinations, EV charging, edge cases
  • DayCardTests (11 tests) - DayCard conflict detection, warning display, stop filtering, edge cases
  • DuplicateGameIdTests (2 tests) - Regression tests for handling duplicate game IDs in JSON data

Bug Fix Protocol

Whenever fixing a bug:

  1. Write a regression test that reproduces the bug before fixing it
  2. Include edge cases - test boundary conditions, null/empty inputs, and related scenarios
  3. Confirm all tests pass by running the test suite before considering the fix complete
  4. Name tests descriptively - e.g., test_DayCard_OnlyShowsGamesFromPrimaryStop_WhenMultipleStopsOverlapSameDay

Example workflow:

# 1. Write failing test that reproduces the bug
# 2. Fix the bug
# 3. Verify the new test passes along with all existing tests
xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' test

Future Phases

Phase 2: AI-Powered Trip Planning

Natural Language Trip Planning

  • Allow users to describe trips in plain English: "plan me a baseball trip from Texas" or "I want to see the Yankees and Red Sox in one weekend"
  • Parse intent, extract constraints (sports, dates, locations, budget)
  • Generate trip suggestions from natural language input

On-Device Intelligence (Apple Foundation Models)

  • Use Apple's Foundation Models framework (iOS 26+) for on-device AI processing
  • Privacy-preserving - no data leaves the device
  • Features to enable:
    • Smart trip suggestions based on user history
    • Natural language query understanding
    • Personalized game recommendations
    • Conversational trip refinement ("add another game" / "make it shorter")

Implementation Notes:

  • Foundation Models requires iOS 26+ and Apple Silicon
  • Use @Generable for structured output parsing
  • Implement graceful fallback for unsupported devices
  • See axiom:axiom-foundation-models skill for patterns

User Instruction

Do not commit code without prompting the user first.