Getting organized

As the interest in iotaMed and the problems it is intended to solve clearly increases, we need to get our ducks in a row and make it simple to follow and to argue. Let’s do it the classic way:

  1. What is the problem?
  2. What is the solution?
  3. How do we get there?

Let’s do these three points, one by one.

What is the problem?

The problem we try to solve is actually a multitude of problems. I don’t think the below list is complete, but it’s a start.

  1. Lack of overview of the patient
  2. No connection to clinical guidelines
  3. No connection between diseases and prescriptions, except very circumstantial
  4. No ability to detect contraindications
  5. No archiving or demoting of minor or solved problems, things never go away
  6. Lack of current status display of the patient, there is only a series of historical observations
  7. In most systems, no searcheability of any kind
  8. An extreme excess of textual data that cannot possibly be read by every doctor at every encounter
  9. Rigid, proprietary, and technically inferior interfaces, making extensions with custom functionality very difficult

What is the solution?

The solution consists of several parts:

  1. The introduction of a structural high-level element called “issues”
  2. The connection of “issues” to clinical guidelines and worksheets
  3. The support of a modular structure across vendors
  4. The improvement of quality in specifications and interfaces
  5. The lessening of dependence on overly large standards
  6. Lessening of the rigidity of current data storage designs
  7. The opening of the market to smaller, best-of-breed entrepreneurs

How do we get there?

Getting there is a multiphase project. Things have to be done in a certain order:

  1. Raising awareness of the problems and locating interested parties (that is what this blog is all about right now)
  2. Creating a functioning market
  3. Developing the first minimal product conforming to this market and specs
  4. Evolve the first product, creating interconnections with existing systems
  5. Demonstrate the advantages of alternate data storage designs
  6. Invite and support other entrepreneurs to participate
  7. Invite dialig with established all-in-one vendors and buyer organizations
  8. Formalize cooperation, establish lean working groups and protocols

Conclusion

None of this is simple, but all of it is absolutely necessary. Current electronic health care systems are leading us on a path to disaster, which is increasingly clear to physicians and nurses working with these systems. They are, in short, accidents waiting to happen, due to the problems summed up in the first section above. We have no choice but to force a change to the design process, deployment process, and not least the purchasing process that has led us down this destructive path.

I’ll spend another few posts detailing the items in these lists. I may change the exact composition of the lists as I go along, but you’ll always find the current list on the iotaMed wiki.

If you want to work on the list yourself, register on the iotaMed wiki and just do it. That’s what wikis are for. Or discuss it on the Vård IT Forum.

SQL is dead, long live RDF

…um, at least as far as medical records go. SQL remains useful for a lot of other things, of course. But as far as electronic medical records are concerned, SQL is a really bad fit and should be taken out back and shot.

Medical records, in real life, consist of a pretty unpredictable stack of document types, so some form of graph database is very obviously the best fit for storage. Anything with rows and columns and predeclared types, is a very poor fit, except maybe for the patient demographics and lab data. Or maybe not even that.

The problem so far was the lack of viable implementations so instead of doing the right thing and creating the right database mechanism, most of us (me included) forced our data into some relational database, often sprinkling loose documents around the server for all those things that wouldn’t fit even if hit with a sledgehammer. All this caused mayhem with the data, concurrency, integrity, and not least, security.

I have to add here that I never personally committed the crime of writing files outside of the SQL, but squeezed them into the database however much effort it cost, but from the horrors I’ve encountered in the field, it seems not many were as driven as I was. I have, though, used Mickeysoft’s “structured storage” files for that, a bizarre experience at best.

You have to admit this is ridiculous. It leads to crazy bad databases, bad performance, horrible upgrading scenarios, and, adding insult to injury, high costs. Object-relational frameworks don’t help much and without going into specifics, I can claim they’re all junk, one way or the other, simply because the idea itself sucks.

From now on, though, there’s no excuse for cramming and mutilating medical records data into SQL databases anymore. Check out RDF first, to get a feel for what it can do. It’s part of the “semantic web” thing, so there’s a buzzword for you already.

A very good place to start is the rdf:about site, and right in the first section, there’s a paragraph that a lot of people involved in the development of medical records really should pause and contemplate, so let me quote:

What is meant by “semantic” in the Semantic Web is not that computers are going to understand the meaning of anything, but that the logical pieces of meaning can be mechanically manipulated by a machine to useful ends.

Once you really grok this, you realize that any attempts to make the computer understand the actual contents of the semantic web is meaningless. Not only is it far too difficult to ever achieve, but there is actually nothing to be gained. There’s nothing useful a computer can do with the information except present it to a human reader in the right form at the right time. What is important, however, is to let the computer understand just enough of the document types and links to be able to sort and arrange documents and data in such a way that the human user can benefit from accurate, complete, and manageable information displays.

It is almost trivial to see that this applies just as well to medical records. In other words, standardizing the terms of the actual contents of medical documents is a fool’s errand. It’s a pure waste of energy and time.

If a minimal effort would be expended to standardize link types and terms instead, we could fairly easily create semantic medical records, allowing human operators to utilize the available information effectively. All it would take for the medical community to realize this would be to raise their gaze and check out what the computer science community is doing with the web and then copy that. At least, that’s what we are aiming to do with the iotaMed project and I hope we won’t remain alone. What is being done using RDF on the web makes a trainload of sense, and we’re going to exploit that.

In practice, this means that you need to express medical data as RDF triples and graphs. This turns out to be nearly trivial, just as it is very easy to do for the semantic web. It’s a lot harder, and largely useless, for typical accounting data, flight booking systems, and others of that kind, but those systems should really keep using SQL as their main storage technique.

We also need a graph database implementation and we’re currently looking into Neo4j, an excellent little mixed license product that seems to fill most, if not all, requirements. But if it turns out it doesn’t, there are others out there, too. After all the years I’ve spent swearing at SQL Server and inventing workarounds for the bad fit, Neo4j and RDF is a breath of fresh air. The future is upon us, and it’s time to leave the computing middle ages behind us as far as electronic medical records are concerned.

Design for updates

When designing new system architectures, you really must design for updating unless the system is totally trivial. This isn’t hard to do if you only do it systematically and from the ground up. You can tack it on afterwards, but it’s more work than it needs to be, but it’s still worth it.

I’ll describe how it’s done for a system based on a relational database. It does not matter what is above the database, even if it’s an object-relational layer, the method is still applicable.

I have a strong feeling that the problem is trivial on graph databases, since the nodes and relations themselves allow versions by their very nature. I haven’t designed using these graph databases yet, so I’m not 100% sure, though.

The reason I’m going into this now is that the iotaMed system must be designed with upgrades in mind, avoiding downtime and big bang upgrades. Just this weekend, the Cambio Cosmic system in our province (Uppsala, Sweden) is undergoing yet another traumatic upgrade involving taking the entire system offline for a couple of days. Very often it doesn’t come up on time or without serious problems after these upgrades, putting patients at risk entirely unnecessarily. The only reason these things need to happen is because of poor system design. A little forethought when building the system could have made a world of difference. The PMI communication system I built and which is used in Sweden has never (as far as I know) been taken down for upgrades, even though upgrading of both client and server systems is an easy and regular activity, and Cosmic could relatively easily have been build the same way. But it wasn’t, obviously. It’s not rocket science, exactly, just see for yourself in what follows.

The problem

The first step is to understand why the database structure is so tightly bound to the code layers, necessitating a simultaneous upgrade of the database structure and the code that accesses it. In the common and naive form, the data access layer is made up of application code outside the database itself which directly accesses tables for reads and writes. If there are several data access layer modules, all of them contain direct knowledge of table structures and all of them need to update simultaneously with the table structures. This means that if you change table structures you need to do all the following in one fell swoop, while all users are taken offline:

  1. Change table structures
  2. Run through all data and convert it with scripts
  3. Replace all application code that directly accesses table data
  4. And while you’re at it, compound the disaster by also replacing business layer code and user interface code to use new functionality added in the data access layer and database while removing old application code that won’t work anymore with the new data structures

This is what we call a “big bang” upgrade and it practically always goes wrong (that’s the “bang” part). It’s extremely hard to avoid disasters, since you have to do very detailed testing on secondary systems and you’ll never achieve full coverage of all the code or even all the little deviant data in the production database that will inevitably screw up the upgrade. And once you’re in the middle of the upgrade, you can’t back out, unless you have full downgrade scripts ready, that have been fully tested as well. The upgrade scripts, hard as they are to get right, are actually simpler than the emergency downgrade scripts, since the latter must take into consideration that the downgrade may be started from any point in the upgrade.

The result is that these upgrades are usually done without any emergency downgrade scripts. It’s like the high wire without a safety net. The only recourse is a total restore from backups, taking enormous amounts of time and leaving you shamefaced and nervous back at the spot you started after a long traumatic weekend. Since backing down is a public defeat, you’re under emotional pressure to press ahead at almost any cost, even in the face of evidence that things will probably go badly wrong, as long as there’s a chance of muddling through. Your ego is on the line.

This is no way to upgrade critical medical systems, but this is how they do it. Shudder.

The solution

The solution is to isolate the database structures from the application code. If different data access layers in application code can coexist, using each their own view of how the database is structured, while still accessing the same actual data within transactions, you can let two versions of application code stacks coexist while accessing the same data. If you can swing this, you’re free to change the database table structure without the application code in the data access layer even noticing. This implies that you can simply add a new view on the database that you need for a new version of the application, add in the new application code and start running it without removing the old application code or clients. New version clients, business layers, and data access layers run in parallel to old versions, so you can let the upgrade be slowly distributed out over the user population, allowing you to reverse the rollout at any point in time. Let it take weeks, if you wish. Or even leave some old clients there forever, if there’s a need for that.

To achieve the needed insulation, simply disallow any direct access to any tables whatsoever from application code. All accesses must be done through stored procedures or views.

SQL VIEWs where actually designed to achieve exactly this: different views on the table data, removing direct dependency of the application code on the tables, so the problem was clearly defined, known, and solved even before SQL hit the scene, so why are we even arguing this now? As an aside, I never use VIEWs, only stored procedures, since I can achieve the same effect with less constraints, but that does not detract anything from the argument that the problem was both recognized and solved ages ago.

Let’s assume you need to change the name of a table for some reason. (I never do that, I’m just taking a really radical example that ought to make your hair stand on end.) First, you edit the stored procedures that access the table to check if the old table name still exists, and if not, start using the new table name. Then you create the new table. Then you create trigger code on the old table that updates the new table with any changes. Then you use the core of that trigger code to run as a batch to transfer all the old table contents that aren’t accessed to the new table. You check a couple of times during actual use if the tables keep matching in contents. You drop the old table (or rename it if you’re chicken, and drop it later). Finally, you remove the check for the old table name in the stored procedures that access the table. Yes, this is somewhat “exciting”, but I’ve done this a number of times on critical systems and it works. And if you can do this, you can do anything.

A much simpler scenario is if you add columns to a table for a new version of your app. If the new column can safely remain invisible to the old version, just add it on the fly, using the right default values so any constraints don’t fire. Add a new stored procedure that is used for the new version of the application, implementing the parameters and functionality the new version needs. The old stored procedure won’t even know the column is there. If the new column must be set some particular way depending on old values, add a trigger for that and batch update the new column using the core of that trigger in a batch command. Again, there is absolutely no need to take down the database or even kick out users while doing all this. Once the new stored procedure is there, you can roll out new applications and have them come on line one by one, leaving old versions running undisturbed.

You can dream up almost any change in table structure, including new tables, splitting one table into two, combining and splitting columns, creating or removing dependencies between columns and tables, and I can catch all of that using a fairly simple combination of stored procedures, triggers, and the occasional user function. And all of it can be done on a live production database with very low risk (caveat: if you know what you’re doing).

To keep things easy and clean, I always use a set of stored procedures per application, where the application prefix is a prefix in the naming of the stored procedure. That lets you see at a glance which app is using which stored procedure. I never let two different apps use the same procedure (you can always let both stored procedures call a common third procedure to reduce code duplication). Versions of a procedure are named with a numeric postfix so they can coexist. Versions are only created if they have different behaviours as seen from the application code. So a procedure to find a patient, used by an iotaPad app, could be named “IP_FindPatient_2” if it was the third version (the first is without postfix, the second version with _1, etc).

Finally, since you only use stored procedures from application code, no application need have any read or write access at all to your database, only execute access to all the stored procedures with a prefix matching the app. This makes for a very easily verified set of GRANTs and a secure database.

Why this scheme isn’t used in products like Cambio Cosmic is a mystery to me. It can’t be laziness, since they’re working their butts off trying not to annihilate all the medical records we have, while stressing out both medical staff and their own programmers to the point of cardiac arrest everytime something goes wrong. A little forethought would have saved so much time and problems it’s almost unreal.

But on one point you can be certain: that little forethought is a definite requirement for the iotaMed project. It wouldn’t hurt if the other guys tried it as well, though.

iotaDB

iotaMed is intended as an organizing overlay to existing information. It adds the guideline layer, including knowledge transfer and checklist functionality, to the classic electronic health care record. The information needed cannot be stored in the existing EHR systems, simply because they lack the necessary concepts. In other words, we do need our own database to contain the iotaMed information, even though we may leave all the “old” information where it already resides in the legacy EHR. Even the new information added through iotaMed will result in new information to be added to legacy EHR systems, even though that information, by necessity, is as poor as the information currently stored there. There simply is no way to turn this particular toad (the legacy EHR) into a prince.

So, what do we choose for an iotaMed database, that is for the iotaDB? It’s painfully obvious to most that a relational database is very unsuited to this purpose and has always been. Using relational databases for medical information has never been a good idea due to the unstructured or semi-structured nature of medical data. Every EHR I’ve seen that uses relational databases has been a Frankenstein’s monster of inefficiency and inflexibility. It the wrong choice, pure and simple.

Lately, graph databases are becoming popular, and seem to be a much better fit for this purpose. Entities used in medical databases are practically always of variable structure, with a huge number of possible value types, but with only a small number of value types used in each instance. If implemented in a relational database, this results in sparse tables, or more often in blatant misuse of the database where one column is used to define the value type of another column, so that just about anything can be dumped into a single table. It’s horrible.

The “issue”, “issue worksheet”, “clinical guideline”, “item”, and “observation” objects clearly form a graph that would be difficult to squeeze into a relational DB, but would fit nicely into a graph database.

Currently, I’m looking at Neo4j, since it seems to be one of the more evolved open source graph databases.There’s a nice intro to Neo4j here. Neo4j does not seem to have a language binding for Objective-C yet, and it needs Java to run, but since I’m planning on deploying iPads logically tethered to an OSX machine, the Neo4j can run there. The interface between Objective-C and Java would then effectively be a server side proxy app. If somebody already did this, I’d appreciate hearing from you, though.

A medication change

In the previous post I did a simple medication domain model. After a brief exchange of comments on my Swedish blog, I was quickly made to realize it was far too simple, so let’s see how it looks today:

In this diagram, I’ve replaced the “prescription” object with a “prescription worksheet” that works very similarly to an issue worksheet. It’s all very logical; each pharmacological therapy or product comes with a set of guidelines that include when it’s to be used, what steps to take before using it, what values to check, etc. All of this is very similar to a clinical guideline but centered around a prescription. So it makes a lot of sense to treat it almost exactly the same way as issues, except it isn’t kept at the same position in the object dependency tree. We don’t want the prescriptions up there commingling with diseases, but rather somewhere lower in the tree.

However, the items and the values of those items (“observation”) can overlap with those used in issues. For instance, the item “creatinine concentration in serum” can be used both in an issue and a prescription worksheet, if the prescription guideline says that the product should not be used, or used differently, in renal failure. So some items will be used in prescriptions, some in issues, and some in both.

Medication Domain Model

In conventional EHR systems, medications are usually just a list found under the patient. The problem here is that there is no direct relationship between the medication and the reason it is administered, simply because there is no concept that could function as “reason”. Lucky us, with iotaMed we do have “issues” so that’s what we’ll use.

A “prescription” is an order for a particular drug, for example “Aspirin, twice daily”, while a “refill” is the order to the pharmacy, for example “Aspirin, box of 100”. (Highly simplified.)

Since a “prescription” is for a particular issue, that is a particular symptom or disease, it should be a child of the issue in some way. Since it will typically appear in a clinical guideline under the section “Treatment”, it will appear as a line item.

Encapsulated lifetime

If you look carefully, you’ll see that each “prescription” can relate to more than one “issue worksheet”, which allows it to relate to more than one “issue”, since a different “issue worksheet” belongs to another “issue”. This is necessary since a prescription could serve a purpose for more than one disease. For instance, an ACE inhibitor is beneficial both in heart failure and to prevent diabetic kidney problems. And it is also used to treat hypertension.

Making “prescriptions” dependent on “issues” makes it much easier to stop medications when they’re no longer necessary. What we often see in practice today, with the crippled EHR systems we have, is that medications are continued indefinitely since it is often unclear exactly why it was started in the first place. Most systems allow a comment to be printed on the medication label describing the intent in a language the patient is meant to understand, but this is just a bad workaround. Often it is not filled in and if it is, it is sometimes incomplete. It is, after all, just a text field.

In iotaMed, however, it is abundantly clear exactly why a medication is prescribed and this allows the system to prompt for continuation or interruption of the prescription as the issue itself is activated or deactivated. Using an object term, we can say that the “lifetime of the prescription is encapsulated in the issue lifetime”, as it should be.

Contraindications

Current EHR systems usually issue warnings for interactions between prescribed products. This isn’t as great as it is made out to be. Generally, these systems stink. They throw up meaningless and frankly ridiculous warnings so often that nobody pays attention anymore. I can’t count the number of times our system has warned me that eardrops can cause unwanted pregnancies. I kid you not.

Also, interactions aren’t the main problem we have with medications. The main problem is contraindications, but since EHR systems can’t handle that, we’re supposed to believe that interactions are more important. Don’t fall for it, they’re not.

All medications have a list of contraindications, that is, conditions that if present makes their use dangerous. Some drugs for urinary problems, for instance, may not be given if the patient has glaucoma. A number of products should not be given if the patient has prostate problems, or heart problems, or asthma, or any number of other conditions. But if the EHR system has no idea what diseases and conditions the patient has, it can’t detect contraindications and there you are.

iotaMed, however, is built on the presence of issues, which are exactly those conditions we need. If we try to prescribe a medication for one condition that is contraindicated in the presence of another condition which the same patient has (as an issue), then the system can easily point out the conflict and stop you from doing something really stupid.

Domain analysis vs application design

Before I get into today’s topic, I’ll just have to point you to a review of the Apple iPad by a doctor. Main point: it fits in a regular white coat pocket. Very important.

In Sweden, we do have a problem, though, since doctors in general aren’t allowed old fashioned white coats, but go around dressed in the same pajamas everyone else has. The idea seems to be that doctors should be as indistinguishable from nurses and administrative staff as possible to keep the patients on their toes and make the doctors more amenable to accept lower salaries. So big pockets are out, here. But the iPad could change that (desperate hope). Wait… an idea is being born… an Apple branded white coat with an iPad pocket? An iCoat?

After this interruption, back to the regular programming. Last week I drew a diagram as part of the “domain analysis”, without explaining what that means. Sorry about that, I’ll explain it now. First, “domain analysis” is a process that produces, among other things, a “domain model”. I should actually have used the term “domain model” last week, it’s more correct.

A “domain model” describes the actual parts and interactions of the systems in reality, not in a software application. In my case, it describes the concepts that I as a doctor would use when seeing a patient. When you look at my diagram from last week, you’ll see “clinical guideline”, “issue”, “item”, and so on, which don’t really exist in reality, so it isn’t a pure domain model either. When drawing that diagram I did something impure, but very useful, and that is describing how to model the reality we want to automate using concepts that describe that reality to a software engineer, without necessarily being real terms used by doctors.

On the other hand, the actual computing system implementing a solution for this domain need not at all declare classes and objects that correspond to what I put in the diagram, so it’s not a software design diagram either. It may, for instance, be much more convenient to design “issue worksheet” as a group of classes, none of which directly corresponds to that “issue worksheet”.

In other words, my “domain model” is a bastard construct, neither a real “domain model” or a real “application design model”, but it is darn useful. It can be explained to domain workers (in our case, doctors) and they are able to see what I’m driving at, and it can be explained to software developers, so they can form a picture of what the actual workflow is that we need to support. This model allows understanding and discussion of the problem domain. It’s a bastard, but a good bastard.

If you subscribe to “domain-driven design”, you won’t like it, though, since you have to implement domain concepts as software design concepts, else it’s not “domain-driven design”. In this case, you’d be forced to implement classes for “issue”, “issue worksheet”, “privacy”, etc. In my opinion, that’s a naive and unnecessary constraint on software design that doesn’t give enough advantage in return to warrant the suboptimal design that results. So sue me.

iotaMed domain analysis

As is simply too painfully obvious, current EHR systems aren’t fit for purpose. There is a serious defect in the domain analysis, so that fundamental concepts such as “disease” and “clinical guideline” are simply missing from the EHR domain analysis.

Let’s discuss the parts in this highly simplified diagram. The objects in green are unique to iotaMed and are missing in current EHR systems.

Patient

The patient object is the root of the tree. We’re assumed to already have created or chosen the patient here.

Issue

A patient has zero, or any number of “issues”. An “issue” is a disease, for instance “diabetes” or a symptom such as “headache” or “vertigo”.

Privacy

Access control is contained in the “privacy” object and the privacy object is connected to the issue. This is a major departure from how access control is normally done in EHR systems. Regular EHR systems tie the access control to the department or doctor that handles the patient, departing from the assumption that the information that the patient desires to protect is tied to the department or doctor that created or recorded the information. This is often the case, but not always, and when it is, it is by coincidence and not an essential attribute. For example: most of what a psychiatrist says belongs in the psychiatric domain so at first blush it seems only reasonable to limit access to records originating with the psychiatrist. But if the psychiatrist now treats the patient for a cold, which he can, then the cold becomes protected information, which is clearly absurd.

Another example is if a psychiatrist treats two different diseases, such as parkinsonism and depression, and the patient wishes for the depression to be protected but not parkinsonism. In that case, it becomes very difficult for the psychiatrist to keep the access control masks correct. We’re clearly using the wrong concepts and entities here.

Obviously, the privacy in real life is attached to the “issue”. If a patient wants to keep his depression a secret, it doesn’t matter which doctor is involved, it’s the depression itself that should be privacy protected. Hence the iotaMed design where the privacy record attaches to the issue.

Clinical Guideline

A “Clinical Guideline” is a template maintained by the medical authorities, which describes in outline form how a particular disease or symptom should be worked up and managed. It also contains differential diagnoses, treatments, new scientific discoveries, links to external documentation, reporting sheets, etc. Whenever an “Issue Worksheet” is created, one “Clinical Guideline” is attached and its contents copied into the “Issue Worksheet”. The relationship between the “Clinical Guideline” and the “Issue Worksheet” is maintained so that changes in the “Clinical Guideline” can be propagated to the already instantiated “Issue Worksheets” in use. An example would be if a new drug of choice has been selected for a particular disease, then the iotaMed system can alert the physician at next encounter that he should consider if that change should be done for the individual patient or not. This link-back allows effective distribution of new evidence-based knowledge into clinical practice without undue delay.

An issue that is not easily identifiable with a known condition, or if no clinical guideline exists that is suitable, the issue worksheet is connected to a dummy clinical guideline that does not contain any items.

Issue Worksheet

The “Issue Worksheet” is an interactive instance of the clinical guideline template. On this sheet, observations can be added or removed. Entire items can be added or deleted, such that any clinical guideline that is preloaded can be rearranged for the particular patient.

If the user creates an issue with an empty (dummy) clinical guideline, the issue worksheet starts out empty, so the user needs to add items to it before proceeding. This way, the user forms his ad hoc issue worksheet, which can later be replaced with a “real” issue worksheet based on a real clinical guideline as the narrowing down of the diagnosis proceeds.

Item

An issue worksheet contains a number of items. Each item is a clinical data point such as history, an allergy, a lab result, a blood pressure. The issue is a variable, not the value itself, which is an “observation”.

Observation

An observation is one data point in the clinical work. It is, for example, a blood pressure, a lab value, a description of the palpation of the abdomen, a description of the auscultation of heart sounds, or the patient subjective history for the encounter. For each item in an issue worksheet, there can be zero or any observations per encounter. In other words, for each encounter you can have none, one, or several blood pressures taken. Each observation allows free text comments as well.

Encounter

An encounter has a date and time of examination or conclusion. Each observation may belong to an encounter, but doesn’t have to. A lab result, for instance, is not encounter related. An observation never belongs to more than one encounter. Also, each encounter is related to one doctor, the responsible physician. In some cases, such as in training situations or operations, there may be multiple doctors.

You’ll find this page in the iota wiki as well: see here.

A Physician’s Bill of Rights

Jeff Atwood wrote “The Programmer’s Bill of Rights” a couple of years back, and it’s entirely applicable to physicians using electronic health care records, so I paraphrased it here for our domain. Here goes.

It’s unbelievable to me that a hospital or a healthcare organisation would pay a doctor more than $100,000 in salary, yet cripple him or her with terrible computing hardware and software. This makes no business or medical sense whatsoever. And yet I see it all the time. It’s shocking how many physicians aren’t provided with the essential things they need to succeed and to treat patients.

I propose we adopt a Physician’s Bill of Rights To Computing, protecting the rights of doctors by preventing their organisations from denying them the fundamentals they need to do their job.

  1. Every physician shall have two monitors
    With the low prices of LCDs and the ubiquity of dual-output video cards, you’d be crazy to limit your doctors to a single screen. The productivity benefits, and the improvement in digesting information, are obvious by now.
  2. Every physician shall have a fast PC
    Doctors are required to run a lot of software to get their jobs done: electronic medical records, pharmacy web interfaces, clinical guidelines, lab software, electronic dictation UI, and not least, Lotus Notes. Running all this software requires a fast PC with lots of memory. The faster a doctor’s PC is, the faster he can cycle through the EHR, prescription, messaging, and clinical guidelines. Time spent staring at a frozen desktop is wasted time.
  3. Every doctor shall have a comfortable chair
    Let’s face it. We make our lvings largely by sitting on our butts for 8 hours a day or more. Why not spend it in a comfortable, well-designed chair, instead of the broken down surplus junk most of us try to avoid falling out of. Sure, you hire doctors primarily for their giant brains and knowledge, but don’t forget their other assets.
  4. Every doctor shall have a fast network connection
    Good doctors use the network all the time. Whenever your doctor has to wait for servers and network responses, he’s losing concentration and time.
  5. Every doctor shall have software suitable to his work
    This is the most important of all these points and the most obvious. Without the right software, your doctors can’t do a good job and you’re wasting money, time, and the patient’s health this way.

These points aren’t extravagant demands. They’re fundamental to the quality of work life for a physician. If the organisation you work for isn’t getting this right, making it right is neither expensive nor difficult. Demand your rights as a physician! And remember: you can either change your organisation, or change your job.

The missing entities

There’s a reason why our medical records systems don’t work and that reason goes back quite a way. As I’ve mentioned before, it goes back to when IT people started implementing the paper records in computers, assuming the paper records contained a complete model of the medical management of the patient, which they didn’t. Automating that crippled model resultet in an automated crippled medical records system. All general medical records systems I’ve ever seen are based on a model somewhat like this:

As you can see, it’s a mess in general, but the problem I’m particularly focusing on is that the main entity, once the patient has been chosen, is the “Encounter”. Everything then dangles of either the encounter or the patient, making it totally impossible to find anything. If you search for information under the patient, you’ll find everything, but if you search under encounters, you’ll typically find nothing. For example, if I want to know if the patient ever said something in particular, or ever showed a particular clinical sign, I first have to know during which encounter that thing happened, if it ever happened. But if I knew that, I wouldn’t need to search for it, would I? Oh, by the way, did you see where they put the symptoms or diseases the patient has? No? Well, neither do I, because they didn’t. It’s not there. The ICD-10 codes don’t fill that function.

This entity relation diagram (ERD) is nuts. Not even a rank beginner would normally analyze a domain this poorly. But somehow it happened and keeps happening.

Let’s see how it should look:

Now we’re getting somewhere. A patient has issues, for which we, in turn, follow clinical guidelines, treat with medicines which in turn are refilled using prescriptions. Referrals are for issues, not for patients as in the first, bad, analysis. With this ERD as a basis, everything else falls into place. There are hundreds of entities missing in these two diagrams, but adding them to the correct, second, diagram is pretty easy and doesn’t break anything. Not so for the first ERD, the one we see in all current systems.

I actually made these two simplified diagrams for the iotaMed wiki. If you want to improve on them, please do that there. That’s what wikis are for.