I discussed the importance of scope and framing in a recent blog post concluding that the framing and scope of the overall problem domain must be broad enough to model reality but that solutions must be broken-up into components each of limited scope.

This is a natural conclusion from a domain-driven design approach in which the design of clinical systems begins with a deep understanding of the domain. An issue for clinicians and those who develop information systems is that there are domain concepts which are implicit and assumed; assumptions and heuristics and understanding built up over many years of working in clinical practice.

An example are the processes and workflow in clinical practice. A development team can work on a system to allow users to request tests but until the scope of the problem is sufficiently broadened to include a model of clinical workflow, a solution risks causing a mismatch between reality and software. I touch on mismatches in my domain-driven clinical information system paper.

Experience and a sense of aesthetics are important. A clumsy model results in a clumsy user interface and user dissatisfaction, despite a long list of requirements which the design team have succeeding in delivering.

The current system

In Wales, we have a “Welsh Clinical Portal” application which is meant to turn into a complete solution for almost all healthcare staff under the banner of “Once for Wales”. However, it is already acknowledged that the system is not suitable for primary care or the emergency unit of organisations across Wales, or indeed, operating theatres or the community.

I feel very strongly that user-facing applications should be process and workflow-driven, improving care and supporting care in specific clinical situations. However, to prevent duplication of effort, such applications such be stupid. They should possess little or no logic but use functionality provided by a national platform to make sense of what they are trying to achieve. Our user-facing applications become simply thin wrappers around a service-orientated architecture as part of that platform. A user-interface may be smart but only in it adapts in a smart way to what the user is doing.

As I outlined previously:

The current solution tries to be everything to everyone. It supports requesting tests for an arbitrary date, or set of dates. It is accessible only within the WCP application itself; its user interface, its functionality and the services it uses to implement its functionality are not available outside of WCP.

The main issues as I see it are:

  • The current system supports only laboratory tests and different screens are planned to support requesting other tests such as radiology.
  • The core functionality should be available to other software via an application programming interface (API) which enforces business rules supporting the domain logic on which test requesting must depend.
  • A single user-interface may not be appropriate in all workflows.
  • A core default user interface should also be available to other software so that it may be embedded in different systems to suit different workflows.
  • There are problems with the existing user interface.

Should I focus on redesigning the user interface, or challenge the current architecture?

I’ll go with the latter, although we can make the user interface much smarter as well.

Applying domain-driven design in test requesting

I’m going to use a redesign of the test requesting workflow as an example of applying domain-driven design.

Explicit rules vs. implicit assumptions

Business rules and assumptions are frequently overlooked when clinicians and designers meet. They contain implicit knowledge that is routine, mundane, automatic and most importantly, assumed. It is important to fully explore a problem domain and challenge implicit assumption in both workflow and process.

In addition, these assumptions will vary; not just between different professions within healthcare but even within the same specialism. Indeed, I must admit to creating contradictory and inconsistent perspectives in my own clinical practice when creating my own EPR and realising my mistake only at the time of implementation.


Examine and judge all assumptions; make the rules that drive your system(s) explicit.

Declarative vs. imperative systems

Declarative environments allows the rules and logic of a system to be expressed without describing the procedure that must be followed in order to apply that logic. This is very different to a procedural (or “imperative”) approach in which rules and logic are present by virtue of how they have been interpreted and turned into a sequence of commands by a programmer. In declarative programming, the logic and rules are explicit; in procedural programming, they are implicit.

Non-programmers might assume that declarative programming must be the most common method to build software in the modern age, given that the rules and logic are expressed logically and explicitly. In fact, this is not the case, and the most commonly used programming languages today are procedural programming languages. There are a variety of reasons for this which are outside of the scope of this article.

Complex business environments - and I very much include healthcare information technology - are frequently made up of many different systems all with different responsibilities and scope. Business rules can be distributed across systems making it difficult to understand how or why something unexpected has happened when a set of unusual circumstances come together and result in a critical incident. We want healthcare software to be deterministic; we want to prove that a system does what we say it does. It makes sense therefore to build in business rules management into the design of any clinical information system so that our software can leverage those business rules and adapt when those rules change in the future.


Favour explicit rules written declaratively in the language of the business.

Architectural design / aesthetics

In Section 5 of Domain-driven design for clinical systems, I introduce a number of fundamental architectural decisions such as layering, the use of a service-orientated approach and model-view-controller designs. I will not repeat those here.

I introduced this diagram in my blog post about scope and framing of clinical problems: Test Requesting

Importantly, this schematic emphasises the importance of breaking-up our test requesting solution into components representing those that face the user (our user interface) and those that face our other services (our business interfaces). Interfaces to the user fundamentally depend on the workflow that our clinical information system is meant to support. In addition, computing hardware changes frequently with new handheld devices and new ways of working, so it is important to ensure separation between user-facing applications and underlying business logic.


Always design to support multiple user interfaces on multiple devices.

This rule forces several important architectural decisions, particularly if one abides by the next rule as well:


Don’t repeat yourself

Critically, it means that all business logic must exist at the service-layer of your architecture and then your user-facing applications are stupid in that they delegate all control logic to other services, but smart in the way that they fit in and support clinical workflow.

Test requesting

So for test requesting, our user interface via a web browser might look like this:

Landing Page

  • Generic test requesting, not just for laboratory tests. Do you expect me to use a different screen to request different types of tests such as radiology? We extend the frame of our overall problem.
  • No modal dialogs but a smart user interface that reacts to our keypresses and mouse clicks, adapting itself appropriately. Why make the user click a button to send the request and then show them a modal alert? Instead, make the button inactive and tell them what needs to be done to make it active.
  • If additional information is required, then adaptive forms appear to request that information:

Adding Free Text

Here the user can see what needs to be done to complete the form: enter information about thyroid function and then enter their password:

To make a test a favourite, we allow users to toggle the heart icon. To choose from our favourites, we do this:

Adding Favourites

And finally, when the request is ready to be sent:

Ready For Request

The information about thyroid status and whether the patient takes thyroxine should really be completed automatically from what we already know about the patient. For now however, WCP doesn’t have this information readily available. In our design however, we must consider how information could be auto-completed.


Plan for the future.

What do we need?

Architecturally, we need:

  • A service to provide fast full-text searching for tests.
  • A test handbook service - a declarative repository of investigations and the rules that manage those investigations. This test handbook must also add support for explicitly declaring additional information required at the point-of-request as well as hooks to allow external services to help manage the requesting workflow for that test. This test handbook service conceptually is a business rules engine, declaring exactly what is permitted and when.
  • As a result, a request-workflow service must be designed to handle all tests in a generic way but, for certain investigations, a more custom service URL can be specified in which more complex logic can be performed in an imperative manner.
  • Each request-workflow service must consider how access to structured electronic health record information might support their use. For example, logic supporting thyroid function may auto-complete the “taking thyroxine” pop-up by simply looking at a FHIR representation of the current medication list at the time of the test.
  • Services to provide support for the lists of locations and clinicians bound to the specific workflow and currently logged-in user.
  • A service to register and list favourite investigations for individual clinicians and groups of clinicians.
  • Underlying services to actually action the test request.

Almost all of this functionality is already available, but is available only to the existing application.


In conclusion, I have widened the scope of the overall solution to include all investigations and not only laboratory tests, but modularised the architecture and narrowed the scope of these individual components.