The second milestone finishes the office’s appointments. They belong to contacts, they appear in the week calendar and in the appointment list, and above all they never overlap. This last rule is the heart of the lesson. It has been in the model since K1. What’s new is that the database enforces it even when two people save at the same instant, and for appointments of any length.

The split into pull requests:

Pull request Branch Brings Where in this lesson
1 feature/m2-appointment-times the rules for the times, the planner in the core exercise 1 and “The planner”
2 feature/m2-occupied-quarters occupied quarter hours in the database, 409 on an overlap “Pull request 2” and exercise 2
3 feature/m2-appointment-contact the contact in the form, the next appointments on the contact page exercise 3
4 feature/m2-names-in-calendar the contacts’ names in the week calendar and in the appointment list exercise 3

Where the Kladde stands

After milestone 1, this holds in the solutions:

  • Appointment in Kladde.Core has Id, Title, Time (the value object TimeRange from K1 with Start and End, both DateTimeOffset) and int? ContactId. In EF Core, Time is a complex type with the columns Start and End.
  • TimeRange.Overlaps is the rule from K1: two time ranges overlap if each one starts before the other one ends. Touching isn’t overlapping; 9:00 to 10:00 and 10:00 to 11:00 fit next to each other.
  • The public booking has fixed lengths. For it, a unique index on the start has prevented double booking since lesson 2.4.10.
  • The week calendar is an island with InteractiveServer (2.5.8), the appointment list a QuickGrid (2.5.9). Both show the title, but not the contact.
  • Since milestone 1, the appointments of a deleted contact are kept; their ContactId is then null.

In the solutions of module 2.4, the storage looks different: an appointment can have several contacts there (table AppointmentContacts), and Kladde.Data stores it as an AppointmentRow with the columns Start and End (lessons 2.4.6 and 2.4.11). Then carry the steps over like this: the quarter hours from pull request 2 attach to AppointmentRow, the form from exercise 3 chooses one or several contacts, and the projection reads the names through AppointmentContacts. The rule in the model and the constraint in the database stay the same.

If your files, classes or folders are named differently, keep your names and carry the steps over.