Automating my day job as a junior doctor in Australia
One tedious data entry task at a time
Because of my decision to distribute Weekend as a standalone Vue application for the reasons described below, I've forked the project into a demo version that you can play with without generating real pathology request forms or using real patient data.
It may not surprise you to learn that there are many other things that ought to be automated in our hospitals too.
Since my last article about automation, I announced that I'm greatly reducing my clinical hours to spend my time building technology to make our hospitals safer and more efficient.
With far more time on hand to build these sorts of tools now, I'm excited to present my next automation project: Weekend - a standalone web application designed to get Queensland's junior doctors home on time on a Friday afternoon.
Many of Australia's hospitals still depend heavily on pen and paper. While this surprisingly does have some significant benefits, like workflow simplicity, reliability, resistance to "down time" and so on, it has obvious drawbacks.
For one, a paper-based system encourages (and indeed mandates) double, triple and quadruple handling of patient information. Not only is this unbearably time-consuming, it also heavily increases the administration burden for junior doctors.
One of the places this triple-handling of information handling occurs is in the context of ordering blood tests for the inpatients under your care - especially over the weekend.
Ordering a blood test using pen and paper involves finding a pathology request form, writing out the patient's name, date of birth and hospital ID, the patient's current bed location, the tests you want taken, the date you want them taken on, your name, your boss' name, your provider number and of course, a signature.
Going into a weekend, where hospitals naturally reduce their staffing levels significantly, it's expected that you, as the "day team" resident, will order safe and appropriate testing for your patients for Saturday, Sunday and Monday morning.
Unfortunately, this means that if you've got 25 patients and need to order tests on Saturday, Sunday AND Monday, you need to fill out 75 of these forms. And at a conservative estimate of 1 minute per form, you're looking at almost an hour and a half of work on a Friday.
I've known this was a problem for a while, although the outrageousness of it all hadn't really sunk in until I recently saw one of my general surgery co-residents photocopying half-completed blood test request forms in an attempt to speed up his workflow.
There had to be a better way. So I asked myself, could this tedious data entry task be automated in some way?
As luck would have it, Yes.
The idea was quite simple. If I could find a way to connect to an existing hospital system, known as [redacted hospital system name], I could probably pull patient information in a similar fashion to the way I did for Pathology.js, my last automation tool.
With the patient information in hand, from there I could get a template of our pathology request forms, and simply print the required information into the right boxes of the forms, saving the end user heaps of time. Additionally, as a side-benefit, I could generate a summary of all the blood tests that have been ordered for a given team, allowing other team members to know what the plan is over the weekend (in terms of blood tests, anyway).
As I've grown as a software developer, I've come to appreciate the benefits of planning my projects more. Even though this is a small project that I could whip up in a day or so, I've found that having a plan written down (however trivial) really helps me stay on track.
Here was my plan of features for Weekend:
Vague and scarcely legible - I know. I'd make a great doctor with handwriting like that.
In terms of graphic design and CSS, I liked the default Vue colours styles so much that I integrated them very heavily into Weekend:
I actually had the idea to build Weekend more than a month ago. However, when planning how I was going to approach the build, I encountered a fairly interesting technical problem that I couldn't work out how I was going to solve, until recently.
To understand this technical problem, we need to understand two of the clear objectives of Weekend:
#1 Patient data should not leave the computer that Weekend is running on.
If this happens, you expose yourself to a whole range of security and ethical issues, and it's a rabbit hole I'd never want to go down for a project of this complexity.
#2 There should be some degree of authentication in place to prevent strangers on the web writing their own pathology request forms to commit Medicare fraud.
The actual forms themselves are a relatively protected species in hospitals for this reason.
As it turns out, unfortunately these two goals are almost in direction contradiction to each other. To understand why, we need to understand how most apps authenticate their users.
Principles of authentication
Many software tools have the need to authenticate their users at some point. In layman's terms, this means confirming your identity in some way. Usually this is to protect some sort of restricted functionality. For example, Facebook authenticates you before you view one of your friend's profiles, or the private messages you share with them. Uber checks your identity before it lets you order a car - and so on.
For the most part, the only way to authenticate someone securely is to do that remotely on your server, as shown in the diagram below, using the Facebook example:
The important thing to note here is that the decision around which functionality the user should be allowed to access is made on the server, a place that is entirely in the control of the developers of the app. "Tom's photo" is not even available on the client device until the server has authenticated the user and sent the relevant data.
A beginner might be tempted to authenticate a user inside their own client application. This is fine for some small projects, but is inherently vulnerable to hacking. See the below diagram:
Note here that all the authentication logic is contained inside the client device - in this case a mobile phone (but it could also be a web browser as is the case for Weekend).
When you write code that is being run on a client device, that code is technically in control of the operator of that device. If your users were sneaky or malicious enough, they can quite easily modify the code on their device to run in any way they want to.
In this client-side authentication example, there's a block of code running somewhere that looks a bit like this:
But given that we now know that malicious users can modify code running on client devices, they could change the above block to look like this:
Now, any time the app would have previously checked whether the user was logged in, it will now instead check whether 1 is greater than 0 - which last time I checked, will always be true. This would grant the user access to all the protected app functionality without needing to be correctly authenticated.
(Also known as getting hacked).
To prevent this malicious authentication issue, the easiest thing to do is simply have all the authentication logic stored on your server - a device you control and operate. Importantly, malicious users can't modify the code you've got written there in most situations (if they can, you've got lots of other problems).
A paradox in my design
Now that we know that client-side authentication is a bad idea, we can better appreciate the technical issue I was having.
Let me remind you that my intention was to have no patient data leave the machine, but to also have a secure remotely authenticated application to protect the integrity of the blood test request forms.
If we now know that data must leave the machine to be correctly authenticated, how can objectives 1 and 2 possibly co-exist?
I was stuck with this problem for quite a long time, and that ultimately led to be binning this project.
It wasn't until I stumbled across this StackOverflow thread where a user described his desire to run his Vue application locally without the need for a web server.
For whatever reason, I had previously assumed that because I was using a front-end web framework, that I had to distribute my application on the web.
In that thread, an awesome user named Gene Parcellano mentioned that it's possible to compile a Vue application into a folder and then run it from the filesystem. What this means is that instead of authenticating users across the web, I could simply deploy the application directly into already authenticated environments, such as on a hospital computer desktop.
That way, only users with access to the hospital computer would be able to run the application, and I wouldn't have to face the awful design paradox described above.
Shout out to Gene if you're reading.
Let's run some napkin sums:
1 hour saved per week x 12 inpatient doctors x $80/hr (overtime rates) x 52 weeks per year
Equals $49,900 in value for my hospital alone this year. And given that Weekend could be deployed at almost any public hospital in Queensland, that's a whole lot of value! Not bad for what was a 1.5 day build when all was said and done.
Such is the business case for automation.
Do you have a dusty health workflow process that needs automating? Please get in touch.
If you're interested in following my journey trying to build automation technology to improve healthcare in Australia and the world, leave me your email and I'll let you know when I'm up to no good.