After milestone 3, a booking is only requested. Whoever requested it gets an email, but what makes a booking reliable is still missing: It has to be confirmed, it can be canceled, and if nobody ever confirms it, the time is released again after a day. The fourth milestone brings these three paths and makes sure nothing gets lost between the booking and the email.

You know the building blocks from module 2.8: the outbox from lesson 2.8.4, the port IMailSender with the implementation that writes emails as files into a folder, and the confirmation link from lesson 2.8.5.

Pull request Branch Brings Where in this lesson
1 feature/m4-confirm-idempotent confirming with a question, a second click changes nothing, a page for expired links “Pull request 1”
2 feature/m4-cancel-link the cancel link; no more canceling after the start Exercise 1
3 feature/m4-cleanup unconfirmed bookings disappear after 24 hours Exercise 2
4 feature/m4-outbox-restart outbox in the booking’s transaction, email written at sending, nothing lost, nothing twice “Pull request 4”

Where the Kladde stands

After milestone 3, the solutions have this:

  • A booking (Booking) creates an appointment. It carries Name, Email and RequestedAt; EfBookingStore.AddAsync saves the appointment and the quarter hours in one step.
  • From lesson 2.8.4 there is an outbox: a table that a change writes its message into, and a background service that sends the messages and marks them as sent. From lesson 2.8.5 there is IMailSender with the implementation for a folder.
  • The confirmation link from lesson 2.8.5 expires after 24 hours. It is protected with ITimeLimitedDataProtector and leads to /booking/confirm. The page asks, only the button confirms the booking with a POST, and /booking/confirmed shows the result. The booking has ConfirmedAt and Confirm for that.

This milestone puts confirming and canceling side by side: The page from lesson 2.8.5 moves to /appointment/confirm, next to /appointment/cancel, and the email links to the new address. Because the booking has had a new shape since milestone 3, ConfirmedAt and the rule in pull request 1 appear again with it, more precisely than in lesson 2.8.5. If your files, classes or folders are named differently, keep your names and carry the steps over.