H1Trip Planner — Unified System (Builder + Engine + Execution)
H2Identity
Trip Planner =
- Builder → deterministic form + normalization
- Engine → pricing + projection
- Execution Layer → real-world booking + confirmation
Trip ≠ Booking
Trip = plan
Booking = execution
H2Core Flow (Locked)
Client
→ TripPlannerContext
→ normalizeStops
→ setForm
→ (create | update)TripFromPlanner
→ Prisma
→ revalidate
→ Trip Engine (pricing, days, lineItems)
→ UI
- Execution Layer:
Trip
→ BookingBundle
→ Ops (Apps Script / Manual / FareHarbor)
H2Core Concepts
H3Stops (Single Source of Truth)
form.stops[]= canonical route- Each stop:
- cityId
- nights
- computed role
- services
H3Roles (Derived Only)
- index 0 → arrival
- last index → departure
- Córdoba + Granada → core
- else → extension
H3Determinism Layer
normalizeStops()computeDisplayRole()businessRank()
Guarantees:
- no duplicates
- core cities always present
- stable ordering
- valid constraints
H2Steps (UI Only — Deprecated)
- basics
- route
- services
- hotels
- options
⚠️ UI abstraction only — not domain
H2Services Model
- defaults at form level
- per-stop override
- optional apply-to-all
H2Hotels Model
- derived from
numPax - override allowed
H2Persistence
- create →
createTripFromPlanner - edit →
updateTripFromPlanner - autosave in edit mode
H2Assistant
prompt
→ intent
→ merge
→ complete
→ normalize
→ persist
H2Execution Layer (NEW)
H3BookingBundle (Required)
Represents real-world execution of a Trip
BookingBundle {
id
tripId
status: "draft" | "pending" | "partial" | "confirmed"
items: BookingItem[]
}