Accept every booking and derive discrepancies from the rebuilt trip
Decision
Accept every booking whatever its dates. Detect conflicts each time the trip is rebuilt, and report anything that doesn't fit the plan as a discrepancy, such as a hotel whose dates run past its destination's or a leg whose destination no longer exists. Detection runs in ztp-core, so the server and the app derive the same discrepancies (ADR-0073).
Show discrepancies in the app as notices the user can dismiss. A discrepancy's id is a hash of its content, including the entity and the dates involved, so a dismissal belongs to that exact conflict and the notice returns when the underlying data changes. A dismissal is itself an effect in the log.
Why
Real trip planning is messy. People book a hotel before the dates are settled, and after extending a stay the reservation doesn't match for a while. We started out rejecting a booking whose dates fell outside its destination. It felt safe and was wrong, because it made people get everything right before they could record what they'd already booked.
A conflict can appear from either side. Extending a stay creates a mismatch without touching the booking, so detection belongs where the whole trip is visible, at rebuild.
Rejected alternatives
- Validating bookings against the plan on write. It blocks recording a real booking until the plan agrees with it.
- Computing discrepancies when a booking is written and storing them. A later plan edit changes which bookings conflict without writing a booking, so the stored set goes stale.
Consequences
People can record a booking at any stage of planning. The app points out possible problems as information and blocks nothing. The data model admits inconsistent state, so everything that reads a trip has to cope with dates that don't line up.