The app from the last lesson has clean view models, but its data is hard-coded. Now the data comes from the Kladde's web API from K2, the app signs in to Entra ID, the appointments sit on the computer as a cache, and three failure cases are state in the view model: no network, no valid sign-in, an appointment that overlaps.

Where the Kladde stands

W5.2.1 applies: the library with view models, interfaces and tests. From K2 you need the web API for contacts and appointments with Entra sign-in and the rule that an overlap is answered with 409 and the code appointment.time.overlaps. The API side of the sign-in (bearer token next to the cookie, roles) is in W2.2.2 and is the same for WinUI; here is the client. IKladdeData grows by two return types:

C#
public enum CreateOutcome { Created, Overlaps, Rejected }

public enum DataSource { Server, Cache }

public sealed record AppointmentList(IReadOnlyList<Appointment> Items, DataSource Source, DateTimeOffset? CachedAt);

// in IKladdeData:
Task<AppointmentList> GetAppointmentsAsync(CancellationToken cancellationToken);

Task<CreateOutcome> AddAppointmentAsync(NewAppointment appointment, CancellationToken cancellationToken);