Accept all bookings, surface conflicts as notices
Context
Early mutations like set_accommodation and set_reservation rejected bookings whose dates fell outside the destination's date range. This felt safe but was wrong — real trip planning is messy. You book a hotel before firming up dates. You extend a stay and the reservation temporarily doesn't match. Rejecting the input forces the user to get everything perfect before recording what they've already booked.
Decision
Accept all bookings regardless of date conflicts. Detect discrepancies on read, not write.
A detect_discrepancies() function runs when building the trip view and checks:
- Accommodation dates outside destination dates
- Reservation times outside destination dates
- Transport endpoints referencing non-existent destinations (orphaned transport)
Discrepancies surface as dismissible notices in an iOS Review tab with badge count. Dismissed notices re-activate if the underlying data changes.
Consequences
Users can record bookings at any stage of planning without fighting validation gates. The app surfaces potential issues without blocking progress — "your hotel dates extend past your Paris dates" as information, not an error.
The cost is that the data model allows inconsistent state, which means every consumer of trip data needs to handle the possibility that dates don't align. But that's reality — and the discrepancy system makes it visible rather than hidden.