import type { Appointment } from 'fhir/r4'; import { appointmentPatientId } from './appointmentParticipants'; import { ORGANIZATION_TAG_SYSTEM } from './carePlanAuthorship'; /** What an appointment read asked for; a held appointment shows only on the reads whose query it meets. */ export type AppointmentQuery = { patientId?: string; organizationId?: string; start?: string; end?: string; statuses?: readonly string[]; actors?: readonly string[]; }; // A date-only upper bound covers that whole day, as the search does. const boundAt = (bound: string, upper: boolean): number => Date.parse(bound) + (upper && /^\d{4}-\d{2}-\d{2}$/.test(bound) ? 86_400_000 - 1 : 0); export const appointmentInQuery = (appointment: Appointment, query: AppointmentQuery): boolean => { if (query.patientId !== undefined && appointmentPatientId(appointment) !== query.patientId) return false; if (query.organizationId) { const practice = appointment.meta?.tag?.find((tag) => tag.system === ORGANIZATION_TAG_SYSTEM)?.code; if (practice !== query.organizationId) return false; } if (query.statuses?.length && !query.statuses.includes(appointment.status)) return false; if (query.actors && !(appointment.participant ?? []).some((participant) => participant.actor?.reference !== undefined && query.actors?.includes(participant.actor.reference))) return false; if (query.start || query.end) { const at = Date.parse(appointment.start ?? ''); if (!Number.isFinite(at)) return false; if (query.start && at < boundAt(query.start, false)) return false; if (query.end && at > boundAt(query.end, true)) return false; } return true; };