import type { Appointment, Slot } from 'fhir/r4'; import type { SaveOperation } from '../saveOperation'; export type NewBookingOutcome = /** The booking may have been made, but the person or dialog that asked moved on: nothing more is shown or sent. */ | { kind: 'retired'; booked?: Appointment } | { kind: 'booked'; booked: Appointment; failedTasks: Task[] }; // A new booking from the desk: its time, the appointment, then its tasks. `operation` is started before the first // wait and belongs to whoever asked, so a booking made after they were replaced is never shown to, nor finished // under, whoever replaced them. A booking already made stands; only its continuation is dropped. export async function bookNewAppointment(params: { operation: SaveOperation; hold: () => Promise; create: (slot: Slot) => Promise; publish: (booked: Appointment) => void; tasks: Task[]; assign: (booked: Appointment, tasks: Task[], operation: SaveOperation) => Promise; }): Promise> { const { operation } = params; const slot = await params.hold(); // An unused booking hold stores nothing and lapses on its own. if (!operation.belongs()) return { kind: 'retired' }; const booked = await params.create(slot); if (!operation.belongs()) return { kind: 'retired', booked }; params.publish(booked); if (params.tasks.length === 0) return { kind: 'booked', booked, failedTasks: [] }; const failedTasks = await params.assign(booked, params.tasks, operation); if (!operation.belongs()) return { kind: 'retired', booked }; return { kind: 'booked', booked, failedTasks }; }