/** * - may THIS staff member be offered a door to the front-desk pool, about THIS patient? * * SPENCER, 2026-08-16 * * *"I think they should be able to message a specific receptionist AND should have the ability to just * message 'front desk' so whichever receptionist can get to it first takes it."* * * *"if billing recognized an issue with a **patient's** invoices/payments and wants the front desk to * know right away about it before a patient checks in. They'll want whoever is working now and can * take it quickly to get the message, not try and message a specific receptionist directly and hope * they have time to see it before the patient comes in."* * * **THE UNIT IS WHO IS ON THE DESK RIGHT NOW**, not who the sender happens to know - and it is * time-critical by construction, because the value expires when the patient reaches the desk. * * **AND THE MESSAGE NAMES THE PATIENT** (Spencer's (A) ruling, same day; see * `akashic-docs/messaging/front-desk-pool.md` ยง3a). That is why this predicate takes a patient at all: * the pool thread is keyed on one, and a door offered without one is a click that cannot complete. * * THREE WAYS TO GET THIS WRONG, EACH ALREADY PAID FOR SOMEWHERE */ export interface FrontDeskDoorInput { /** * Does this practice actually HAVE a front desk? Derived from active receptionist roles by * `organizationIdsWithFrontDesk`, never authored. * * **A DOOR ONTO NOBODY IS WORSE THAN NO DOOR.** The pool resolves its members BY ROLE at read time, * so at a practice with no receptionist the message sits unread with nobody it could notify - and the * sender has been told the office knows. */ // UNDEFINED IS NOT KNOWN: a colleague without staff access is refused the staff read, so an // empty list is a refusal, not an empty practice. Unknown offers; the server answers on send. organizationHasFrontDesk: boolean | undefined; /** * Is the caller themselves the front desk? * * *Front desk* as a route to messaging YOURSELF is nonsense, and the patient side never faced it * because a patient is never in the pool. It is also not merely cosmetic: a receptionist who * "claims" a thread they opened has told the rest of the desk that somebody is handling something * nobody sent. */ callerIsReceptionist: boolean; /** * The patient this message is about - `undefined` when the surface does not know one. * * UNDER THE (A) RULING THIS IS THE WHOLE REASON THE DOOR IS PLACED WHERE IT IS. HR, Billing, * Marketing and the Platform Manager **cannot read a Patient at all** (`GET /R4/Patient` lists only * Practitioners and Receptionists, with no `requiredPermission` to grant through, and `Patient.read` * is minted only for those two). So they can never NAME a patient from a cold directory - the door * has to live on a surface that already holds one, which is exactly where the use case starts. */ patientId?: string; /** * The capability service's answer for the route that opens the thread, or `undefined` for NOT KNOWN. * * **`=== false` ONLY, never truthiness** - the deliberate shape established. `undefined` * means the capability endpoint has not answered, and hiding a door on "we have not asked yet" is a * surface that flickers; hiding it on a real denial is honesty. an unknown answer OFFERS, and the * request itself is the backstop. */ mayOpenThread?: boolean; } /** * **PURE, AND THAT IS THE POINT.** Every surface that holds a patient can offer this door - the * invoice today, an appointment or a chart tomorrow - and the moment there are two of them, a rule * re-derived per surface is a rule that disagrees with itself. One predicate, one set of reasons. */ export const mayOfferFrontDeskDoor = (input: FrontDeskDoorInput): boolean => { if (input.organizationHasFrontDesk === false) return false; if (input.callerIsReceptionist) return false; if (!input.patientId) return false; return input.mayOpenThread !== false; };