With the third milestone, the calendar opens to the outside. Visitors to the website see the free times of a day and request an appointment, without script and without an account. You’ve built parts of it already: the rule for free times in lesson 2.5.6, the booking in steps, a first rate limit and a honeypot field in lesson 2.6.6. Now everything comes together, and something is added that only milestone 2 makes possible: a booking occupies the same quarter hours as an appointment of the office. Then the database can protect the two against each other.

Pull request Branch Brings Where in this lesson
1 feature/m3-booking-options opening hours per weekday, breaks, days ahead, checked at startup “Pull request 1”
2 feature/m3-free-slots the complete rule for free times exercise 1
3 feature/m3-booking-is-appointment a booking is an appointment; “taken in the meantime” “Pull request 3”
4 feature/m3-limits rate limit per visitor address, honeypot field “Pull request 4” and exercise 2

Where the Kladde stands

After milestone 2, this holds in the solutions:

  • BookingOptions from lesson 2.3.4 has known, since lesson 2.5.6, the opening hours per weekday (Hours), a lunch break (BreakStart, BreakEnd), the length of an appointment (SlotMinutes), the lead time (LeadHours) and the time zone (TimeZoneId). The options live in Kladde.Web and are validated at startup; ToRules() turns them into the core’s BookingRules.
  • FreeSlots in Kladde.Core computes the free times of a day (lesson 2.5.6), with the edge cases past day, day of the clock change, lunch break and full day.
  • A booking is a table of its own with a start, a name and an email address. A unique index on the start has prevented the same time from being booked twice since lesson 2.4.10.
  • The booking page /appointment leads through day, time and details in steps; since lesson 2.6.6 it’s limited and has a honeypot field. After booking, /appointment/booked shows the appointment (lesson 2.5.6).
  • Since lesson 2.8.5, a booking counts only once the person has confirmed the link in their email. The confirmation goes beyond the outbox from lesson 2.8.4.
  • The office’s appointments have occupied their quarter hours in AppointmentSlots since milestone 2.

The problem in this state: bookings and the office’s appointments know about each other only through the rule in the model. If a visitor books 10:00 while someone in the office is just entering 9:30 to 10:30, both pass their check, and the database considers both valid.

The examples in this lesson put the options into the core themselves and call the time zone TimeZone. With the solution of lesson 2.5.6, BookingOptions stay in Kladde.Web and BookingRules in the core. Pull request 1 then brings only what’s new: a list of breaks instead of the one lunch break, DaysAhead and the check against the quarter hours from milestone 2; ToRules() passes everything on to the rule. If your files, classes or folders are named differently, keep your names and carry the steps over.