Hi all,
At SolDevelo we’ve been tasked by MSF to deliver better repeat prescribing and dispensing, and we want to build it in O3 itself, in a way the community agrees. I’ve seen several threads that have already designed parts of this. The intention for this post is to collect the decisions from various threads, verify the state and agree on the way we implement it.
The need
Some treatments run for a long time. For example, a treatment lasts a year, and the doctor prescribes 2 months at a time, knowing the patient will be back (not actual numbers).
Two people are involved:
- The pharmacist is legally responsible for dispensing the right medication the right number of times. They need to see how many times a prescription has been dispensed, and the system must not allow more than was prescribed. MSF sees the pharmacist as the main user.
- The prescriber must still review what they prescribe, so repeating a prescription must not skip that review.
What O3 does today
We tested this on MSF’s LIME distribution (dispensing app 1.11.2-pre, patient chart 12.3.5-pre, default settings):
- Refills are not counted. An order with 2 refills (3 fills) accepted 5 dispenses posted through the FHIR API, and the dispensing app still offered Dispense, with the card showing “Refills 2”. The history lists the fills without totaling them.
- The quantity limit is frontend only.
restrictTotalQuantityDispensedis off by default. When it is on, it caps tablets at quantity × (1 + refills) in the dispense form, and marks the order completed after the last fill. Dispenses posted to the API are not checked. - Refills stop at day 90. A request older than
medicationRequestExpirationPeriodInDays(90) cannot be dispensed, whatever its refills. A 2-month supply with 5 refills stops after the second fill. - A renewal does not stop the original. If the original still has refills, both orders can be dispensed.
- Renew puts the order straight into the basket. The order form does not open, so the prescriber can sign without seeing the details.
What the community has already worked out
- Dispensing: “Completed” status (2022) described the refill rule: an order is dispensable while “The number of dispensing records associated with the order < (1+numRefills)”. It was left to the pharmacist for the first release.
- Should renewing a medication auto-stop the original prescription? (2026) ended with a concrete plan from @dennis : keep RENEW explicit, require
previousOrder, and expire the previous order one second before the renewal starts. - Medication Refill/Reorder terminology produced Renew in O3. @dennis also suggested that Renew should open the order form, rather than only adding the order to the basket.
- Duplicate dispensing validation on the backend (2025) proposed a server-side check, because “frontend checks can be bypassed”.
As far as we can see, none of these has a ticket or work in progress. If someone is already on one of them, please say so and we will work with you.
Part 1: what we plan to implement
These follow designs already discussed. Unless there are objections, we will file the tickets and send the PRs:
- RENEW stops the original, following @dennis plan in t/49428. This is a core change (
OrderServiceImpl). - Renew opens the order form, so the prescriber reviews each line before it goes into the basket. Question 5 below asks whether today’s one-click behaviour should stay as an option.
Part 2: open questions
-
How should O3 support repeats? Several models are in use:
- (a) Refills counted on one order. The doctor prescribes “2 months + 5 refills”. Dispensing shows “Fill 2 of 6”, the last fill and the next due date, and blocks a fill after the last one. This is the 2022 rule, and the model that seems to be present in other dispensing systems.
- (b) Whole span with a quantity limit. The doctor prescribes 12 months and the total quantity. The pharmacy gives 2 months at a time against
restrictTotalQuantityDispensed. This exists today but counts tablets, not fills. - (c) A new prescription each cycle. The prescriber renews and reviews at every visit, so each order is dispensed once.
We lean towards (a) for the pharmacist, with (c) for patients who see the prescriber at every visit.
-
Where should the limit be enforced? In the dispensing app only (as today), in a backend validator (@burke has said dispensing logic belongs outside core, so a module or fhir2?), or both? Could this extend the duplicate-dispense validator? We would favor the backend, but should it belong to totally seperate module?
-
When does a repeat prescription expire? Options: keep the global 90-day setting; derive it per order from the start date + duration × (1 + refills); or add an explicit end date (FHIR
validityPeriod.end). -
Does a partial dispense count as a fill? For example, 30 tablets given against a 56-tablet fill.
-
One-click renew: should Renew always open the form, or should today’s one-click behaviour stay as a configurable option?
We would like to settle the direction in the next week or couple, and then start the implementation. Reviewers and anyone with the same need are very welcome.
I’ve tagged several people that ware involved in the dispensing threads over the years: