Files
Sportstime/ARCHITECTURE.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

16 KiB

Sport Travel Planner - Architecture Document

1. High-Level Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│                              PRESENTATION LAYER                              │
│  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐            │
│  │  HomeView   │ │  TripView   │ │ScheduleView│ │ SettingsView│            │
│  └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘            │
│         │               │               │               │                    │
│  ┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐            │
│  │HomeViewModel│ │TripViewModel│ │ScheduleVM  │ │ SettingsVM  │            │
│  └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘            │
└─────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                              DOMAIN LAYER                                    │
│  ┌─────────────────────┐  ┌─────────────────────┐  ┌─────────────────────┐  │
│  │   TripPlanner       │  │   RouteOptimizer    │  │   ScheduleMatcher   │  │
│  │   (Orchestrator)    │  │   (Algorithm)       │  │   (Game Finder)     │  │
│  └──────────┬──────────┘  └──────────┬──────────┘  └──────────┬──────────┘  │
│             │                        │                        │              │
│  ┌──────────▼────────────────────────▼────────────────────────▼──────────┐  │
│  │                        TripPlanningEngine                              │  │
│  │  • Constraint Solver  • Route Graph  • Scoring (CoreML)               │  │
│  └───────────────────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                              DATA LAYER                                      │
│  ┌─────────────────────┐  ┌─────────────────────┐  ┌─────────────────────┐  │
│  │  TripRepository     │  │  ScheduleRepository │  │  StadiumRepository  │  │
│  │  (SwiftData)        │  │  (CloudKit)         │  │  (CloudKit)         │  │
│  └─────────────────────┘  └─────────────────────┘  └─────────────────────┘  │
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────────┐│
│  │                         CloudKit Sync Manager                           ││
│  │  • Public Database (Schedules, Stadiums)                                ││
│  │  • Shared Database (Collaborative Trips - Phase 2)                      ││
│  └─────────────────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────────────────┘

2. Project Structure

SportsTime/
├── Core/
│   ├── Models/
│   │   ├── Domain/           # Pure Swift domain models
│   │   │   ├── Sport.swift
│   │   │   ├── Team.swift
│   │   │   ├── Game.swift
│   │   │   ├── Stadium.swift
│   │   │   ├── Trip.swift
│   │   │   ├── TripStop.swift
│   │   │   ├── TravelSegment.swift
│   │   │   └── TripPreferences.swift
│   │   ├── CloudKit/         # CKRecord-backed models
│   │   │   ├── CKGame.swift
│   │   │   ├── CKStadium.swift
│   │   │   └── CKTeam.swift
│   │   └── Local/            # SwiftData models
│   │       ├── SavedTrip.swift
│   │       ├── UserPreferences.swift
│   │       └── CachedSchedule.swift
│   ├── Services/
│   │   ├── CloudKitService.swift
│   │   ├── LocationService.swift
│   │   ├── DistanceMatrixService.swift
│   │   └── ExportService.swift
│   ├── Utilities/
│   │   └── DateFormatter+Extensions.swift
│   └── Extensions/
│       └── CLLocation+Extensions.swift
├── Features/
│   ├── Home/
│   │   ├── Views/
│   │   │   └── HomeView.swift
│   │   └── ViewModels/
│   │       └── HomeViewModel.swift
│   ├── Trip/
│   │   ├── Views/
│   │   │   ├── TripCreationView.swift
│   │   │   ├── TripDetailView.swift
│   │   │   ├── TripStopCard.swift
│   │   │   └── TripPreferencesForm.swift
│   │   └── ViewModels/
│   │       ├── TripCreationViewModel.swift
│   │       └── TripDetailViewModel.swift
│   ├── Schedule/
│   │   ├── Views/
│   │   │   ├── ScheduleListView.swift
│   │   │   └── GameCard.swift
│   │   └── ViewModels/
│   │       └── ScheduleViewModel.swift
│   └── Settings/
│       ├── Views/
│       │   └── SettingsView.swift
│       └── ViewModels/
│           └── SettingsViewModel.swift
├── Planning/
│   ├── Engine/
│   │   ├── TripPlanningEngine.swift
│   │   ├── RouteOptimizer.swift
│   │   ├── ScheduleMatcher.swift
│   │   └── ConstraintSolver.swift
│   ├── Scoring/
│   │   ├── TripScorer.swift
│   │   └── RoutePreferenceModel.mlmodel
│   └── Models/
│       ├── PlanningRequest.swift
│       ├── PlanningResult.swift
│       └── RouteGraph.swift
├── Export/
│   ├── PDFGenerator.swift
│   ├── TripShareManager.swift
│   └── Templates/
│       └── TripPDFTemplate.swift
└── Resources/
    └── Assets.xcassets

3. Data Flow

Trip Creation Flow

User Input → TripCreationViewModel → PlanningRequest
                                           │
                                           ▼
                                   TripPlanningEngine
                                           │
                    ┌──────────────────────┼──────────────────────┐
                    ▼                      ▼                      ▼
            ScheduleMatcher         RouteOptimizer         ConstraintSolver
                    │                      │                      │
                    └──────────────────────┼──────────────────────┘
                                           ▼
                                   TripScorer (CoreML)
                                           │
                                           ▼
                                   PlanningResult → Trip
                                           │
                                           ▼
                              TripDetailView (Display)
                                           │
                                           ▼
                              SavedTrip (SwiftData persist)

4. CloudKit Schema

Public Database Records

Record Type Fields
Team id, name, abbreviation, sport, city, stadiumRef
Stadium id, name, city, state, latitude, longitude, capacity, teamRefs
Game id, homeTeamRef, awayTeamRef, stadiumRef, dateTime, sport, season
Sport id, name, seasonStart, seasonEnd, iconName

Relationships

  • Team → Stadium (reference)
  • Game → Team (home, away references)
  • Game → Stadium (reference)

5. Trip Planning Algorithm

Step 1: Input Parsing

Parse user preferences into PlanningRequest:
- Start/End locations (geocoded)
- Date range
- Must-see games (locked stops)
- Travel mode (drive/fly)
- Constraints (max hours/day, EV, lodging type)

Step 2: Game Discovery

FOR each sport in selected sports:
    Query games within date range
    Filter by geographic relevance (within reasonable detour)
    Include must-see games regardless of detour
    Score games by:
        - Team popularity
        - Rivalry factor
        - Venue uniqueness

Step 3: Route Graph Construction

Build weighted graph:
    Nodes = [Start, Stadiums with games, End]
    Edges = Travel segments with:
        - Distance
        - Drive time (or flight availability)
        - Scenic score (if scenic preference)
        - EV charging availability

Step 4: Constraint Solving

Apply hard constraints:
    - Must-see games are mandatory nodes
    - Max stops OR max duration
    - Game times must be reachable

Apply soft constraints (scored):
    - Leisure level (rest days)
    - Driving hours per day
    - Scenic preference

Step 5: Route Optimization

IF stops < 8:
    Use exact TSP solution (branch and bound)
ELSE:
    Use nearest-neighbor heuristic + 2-opt improvement

Respect temporal constraints (game dates)

Step 6: Itinerary Generation

FOR each day in trip:
    Assign:
        - Travel segments
        - Game attendance
        - Lodging location
        - Rest periods (based on leisure level)
        - EV charging stops (if applicable)

Step 7: Scoring & Ranking

Score final itinerary:
    - Game quality score
    - Route efficiency score
    - Fatigue score (inverse)
    - User preference alignment

Return top 3 alternatives if possible

6. CoreML Strategy

On-Device Models

Model Purpose Input Output
RoutePreferenceModel Score route alternatives Route features vector Preference score 0-1
LeisureBalancer Optimize rest distribution Trip features Rest day placement
PersonalizationModel Learn user preferences Historical trips Preference weights

Training Approach

  1. Initial Model: Pre-trained on synthetic trip data
  2. On-Device Learning: Core ML updatable model
  3. Features: Trip duration, sports mix, driving hours, scenic detours, game density

Model Integration

// Scoring a route option
let scorer = try RoutePreferenceModel()
let input = RoutePreferenceModelInput(
    totalDistance: route.distance,
    gameCount: route.games.count,
    scenicScore: route.scenicRating,
    avgDriveHours: route.averageDailyDrive,
    leisureRatio: route.restDays / route.totalDays
)
let score = try scorer.prediction(input: input).preferenceScore

7. SwiftUI Screen Flow

┌─────────────────┐
│   Launch/Splash │
└────────┬────────┘
         ▼
┌─────────────────┐
│    HomeView     │◄──────────────────────────────────┐
│  - Saved Trips  │                                   │
│  - Quick Start  │                                   │
│  - Schedule     │                                   │
└────────┬────────┘                                   │
         │                                            │
         ▼                                            │
┌─────────────────┐     ┌─────────────────┐          │
│TripCreationView │────►│ GamePickerSheet │          │
│  - Preferences  │     │ (Must-See Games)│          │
│  - Locations    │     └─────────────────┘          │
│  - Constraints  │                                   │
└────────┬────────┘                                   │
         │ "Plan Trip"                                │
         ▼                                            │
┌─────────────────┐                                   │
│ PlanningView    │                                   │
│ (Loading State) │                                   │
└────────┬────────┘                                   │
         ▼                                            │
┌─────────────────┐     ┌─────────────────┐          │
│ TripDetailView  │────►│  ExportSheet    │          │
│  - Day-by-Day   │     │  - PDF          │          │
│  - Map View     │     │  - Share        │          │
│  - Games List   │     │  - Email        │          │
│  - Save Trip    │     └─────────────────┘          │
└────────┬────────┘                                   │
         │ Save                                       │
         ▼                                            │
┌─────────────────┐                                   │
│  SavedTripsView │───────────────────────────────────┘
└─────────────────┘

8. Key Dependencies

  • SwiftData: Local persistence for trips and preferences
  • CloudKit: Shared schedules and stadium data
  • MapKit: Route visualization and distance calculations
  • CoreML: On-device trip scoring and personalization
  • PDFKit: Trip export functionality
  • CoreLocation: User location and geocoding