import type { Practitioner, PractitionerRole, Reference } from 'fhir/r4'; import { isClinicianEnabled } from './clinicianEnabled'; import { practitionerIdOfRole, seatCapacityAdmits, type SeatStanding } from './seatStanding'; import { holdsClinicalRole } from './staffRoleCatalog'; /** * WHO MAY BE RECORDED AS HAVING ORDERED SOMETHING CLINICAL. * * MEASURED 2026-08-30 at Great River: the requester picker on a medication order offered all thirteen * staff members - HR, Marketing, Billing, the Receptionist and the Platform Manager among them. Five of * those hold no clinical role at all, and any of them could be recorded as having prescribed a drug. * * NOTHING DOWNSTREAM ACTS ON THE FIELD, so this is not an unsafe dispense - it is an inaccurate clinical * record. But it is the field a pharmacy, an audit or a malpractice review reads to answer "who ordered * this", and the product was willing to answer "the marketing coordinator". * * TWO CONDITIONS, BOTH REQUIRED, AND THIS IS THE PRODUCT'S EXISTING ANSWER RATHER THAN A NEW RULE. * The clinician SEAT is what makes somebody able to act clinically at all - without it the Practitioner * workspace is dropped at token mint - and the Practitioner WORKSPACE is what the seat is supposed to sit * on. Requiring both matters because the two have come apart in real data: a seat sat on a RECEPTIONIST * role at our own practice, and the booking picker honoured it until somebody noticed a receptionist was * bookable for a consultation. * * READ PER PERSON, NEVER PER ROLE. One human holds several roles in one organization and the seat is * granted across all of them at once, so a `find` on the first role answers about the wrong one. * * NOT FOR THE `recorder`, AND THAT DISTINCTION IS THE POINT. A prescription has two people on it: who * ORDERED it and who TYPED it. A receptionist transcribing a phone order is ordinary practice, so the * recorder stays open to whoever is entering it. Only the requester narrows. */ export const mayPrescribe = (roles: readonly PractitionerRole[], seat: SeatStanding | null): boolean => holdsClinicalRole(roles) && roles.some( (role) => role.active !== false && isClinicianEnabled(role) && seatCapacityAdmits(practitionerIdOfRole(role), seat), ); /** * The staff a clinical ORDER may name, with whoever is already on the record kept in the list. * * THE SECOND ARGUMENT IS THE CONTROL AND IT IS NOT OPTIONAL IN SPIRIT. An order signed months ago may * name somebody who has since lost their seat, changed roles or left. Filtering them out would blank the * field on a record that already answers the question - and a name that VANISHES from a signed order is * worse than a name that should not have been offered in the first place. They stay, and they stay * selected; they simply stop being offered to anybody else. */ export const prescriberOptions = ( staff: ReadonlyArray<{ practitioner: Practitioner; roles: PractitionerRole[] }>, alreadyNamed: Reference | ReadonlyArray | undefined, seat: SeatStanding | null, ): Practitioner[] => { const named = new Set( (Array.isArray(alreadyNamed) ? alreadyNamed : [alreadyNamed]) .map((reference) => reference?.reference) .filter((reference): reference is string => Boolean(reference)) .map((reference) => reference.split('/')[1]) .filter(Boolean), ); return staff .filter((entry) => mayPrescribe(entry.roles, seat) || (entry.practitioner.id !== undefined && named.has(entry.practitioner.id))) .map((entry) => entry.practitioner); };