# China Itinerary Engine — Full Specification (Issue Snapshot)

> The original issue text included a long embedded specification. The source excerpt available in the task context was truncated mid-type definition, so this file preserves the full text that was provided to the coding agent.

## MVP: Implement Round 1 & Round 2 first

## 1. Overview

This project builds a modular itinerary-planning engine for travel across China using:

- A curated list of 50 cities
- A static dataset of train + flight connections
- A routing algorithm to determine the optimal order of visiting cities
- Lodging cost estimation based on average hotel prices

The system is designed in four rounds, but only Round 1 and Round 2 are required for the MVP.

## 2. Rounds Summary

### Round 1 — Routing (MVP)

- User selects any subset of the 50 cities
- System computes the optimal visit order
- Optimization goals:
  - cheapest
  - fastest
  - balanced
- Uses static connection dataset (time + cost estimates)

### Round 2 — Nights & Lodging (MVP)

- User assigns number of nights per city
- System calculates:
  - lodging cost
  - total trip cost
  - total duration

### Round 3 — Dates & Real Transport (future)

- User chooses start date
- System generates exact dates per city
- System fetches real trains/flights
- Replaces estimated legs with real schedules

### Round 4 — Boutique Hotels (future)

- Curated boutique hotels per city
- User selects one per city
- System updates lodging cost
- Optional: booking links or concierge request

## 3. Data Model

### 3.1 City

```ts
type CityId = string;

interface City {
  id: CityId;
  name: string;
  province: string;
  avgHotelPriceCny: {
    budget: number;
    mid: number;
    boutique: number;
  };
  recommendedMinNights: number;
  recommendedMaxNights: number;
}
```

### 3.2 Connection (static dataset)

```ts
type TransportMode = "train_hsr" | "train_cr" | "flight_dom" | "flight_intl";

interface Connection {
  fromCityId: CityId;
  toCityId: CityId;
  mode: TransportMode;
  timeHours: number;
  distanceKm: number;
  priceCnyEst: number;
}
```

Dataset structure:

```text
connections/
  beijing.json
  shanghai.json
  guangzhou.json
  ...
```

Each file:

```ts
interface CityConnections {
  fromCityId: CityId;
  connections: Connection[];
}
```

### 3.3 User Input

```ts
interface ItineraryRequest {
  selectedCityIds: CityId[];
  startCityId?: CityId;
  endCityId?: CityId;
  roundTrip?: boolean;
  optimizationGoal: "cheapest" | "fastest" | "balanced";
  hotelTier: "budget" | "mid" | "boutique";
  nightsPerCity?: Record<CityId, number>;
}
```
