FHIR Chat · Implementing "Business Rules" · implementers

Stream: implementers

Topic: Implementing "Business Rules"


view this post on Zulip Dave Barnet (Nov 06 2019 at 14:05):

We are looking to follow the US Core or Australian Base idea of having a set of profiles that are suitable for implementation within a Nation's jurisdiction (in our case the UK). The idea is that we'll have a UK Core set of profiles that are fairly generic & so can be used in several use cases. Each use case may have its own set of business rules (for example tighten cardinalities, use specific valueSets, make certain elements mandatory for example). We are not intending to have a set of FHIR profiles for each use case, but rather have a validation engine that will test an instance written against a use case by testing against the base resorces (UK Core), and then validate against the use case specific business rules. What I'm not certain is how to write the business rules so that they are computable. For example, I could write them in bespoke template, I could use a FHIR resource such as ElementDefinition or TestScript as these have elements to add rules, or I could use something like FHIRPath.
Has anyone looked at adding business rules, and if so is there a preferred approach to documenting them?

view this post on Zulip Michel Rutten (Nov 06 2019 at 14:14):

Derived profiles seem to cover your requirements...

view this post on Zulip Dave Barnet (Nov 06 2019 at 14:27):

Yeah, I know Michel. However, we are trying not to have profiles that relate to use cases, as you tend to end up with loads of profiles (we'll be talking to Firely about this soon), so we are looking to run with a base set of profiles & use business rules to use case specific rules. For example we might say that for a particular use case maritalStatus is mandated - so rather than create a Patient profile where maritalStatus is set to [1..1] (so now we have 2 Patient profiles - one for the base & one for the use case), we are looking at have a business rule in the use case Implementation Guide to enforce the fact that martialStatus is mandated. Given that, the question is how would we code/express the business rule in the Implementation Guide?

view this post on Zulip Michele Mottini (Nov 06 2019 at 14:30):

Document the business rules as text. Implement them in your server returning meaningful error messages.

view this post on Zulip Kevin Mayfield (Nov 06 2019 at 14:50):

Have you looked at GraphDefinition? (I don't know why it's called that, it doesn't seem to describe it's use)

Having looked at some of the NHS Digital tests, it seems many of the rules could be written as GraphDefinitions
e.g. Rule (GraphDefinition) = this bundle should contain MessageDefinition (1..1), Patient (1..1)

It also looks as if it supports fhirPath

view this post on Zulip Kevin Mayfield (Nov 06 2019 at 14:52):

Having worked recently with text based rules, I find them hideous. :) [Ask me for details if you see me in your office]

view this post on Zulip Grahame Grieve (Nov 06 2019 at 22:51):

FHIR pretty much expects you to define profiles, assign them URLs etc. How would you refer to your business rules otherwise?

view this post on Zulip Grahame Grieve (Nov 06 2019 at 22:51):

not sure why you don't want to create a profile...

view this post on Zulip Lloyd McKenzie (Nov 07 2019 at 00:27):

If you want a computable set of business rules, you're going to have an extra artifact anyhow to maintain/share/etc. Profiles are the artifact that's defined for that purpose, and profiles are widely supported by tools and specification infrastructure. Why are you trying to avoid them?

view this post on Zulip Kevin Mayfield (Nov 07 2019 at 11:00):

Simple answer: I'm seeing evidence that many developers aren't following profiles, they are using examples and text based rules. [This maybe caused by local issues]

view this post on Zulip Grahame Grieve (Nov 07 2019 at 11:02):

it's always easy to hack it ;-)

view this post on Zulip Kevin Mayfield (Nov 07 2019 at 11:22):

It's also practical, so a general desire not to validate on live links. Validation would be done during testing.

view this post on Zulip Kevin Mayfield (Nov 07 2019 at 11:22):

but live links would still have rules.

view this post on Zulip Grahame Grieve (Nov 07 2019 at 11:37):

I'm not sure I follow there. Of course you want to be judicious validating in production systems, but I don't see what that has to do with the question

view this post on Zulip Kevin Mayfield (Nov 07 2019 at 11:42):

I think I'm seeing rules and validation as two separate things in practice. Rules being mandated on operational links.

So an operational link may have a business rule that a SNOMED code in Observation is mandatory

view this post on Zulip Kevin Mayfield (Nov 07 2019 at 11:48):

What @Dave Barnet didn't mention is a general dislike of multiple/many profiles coming from implementers.

view this post on Zulip Grahame Grieve (Nov 07 2019 at 12:45):

I understand that, but what I don't really follow is some magical separation of 'I made some rules' and 'I made a profile'. What matters is what the rules are. Why would expressing them in a more computer processible way be a problem? I think it's a proxy for the real issue, which is managing contention between rule making (semi) authorities

view this post on Zulip Lloyd McKenzie (Nov 07 2019 at 15:39):

If you're wanting to define rules in a computable way that can be consumed by various servers and enforced consistently, Profiles are the way FHIR does that. If the issue is that developers don't like reading the way that profiles express the rules and you think they'd be more likely to read a text expression, we could look at generating a text expression. (My personal experience is that diagram-based and table-based representations are much easier to consume and understand than pages of SHALL and SHOULD statements as was commonly found in CDA IGs.)

view this post on Zulip Eric Haas (Nov 07 2019 at 15:52):

USCore does indeed express the rules text like cda. I dont think that will solve the problem of human nature trying to take a shortcut and start with the example first approach.

view this post on Zulip Eric Haas (Nov 07 2019 at 15:53):

Just a reminder to take the examples seriously

view this post on Zulip John Moehrke (Nov 07 2019 at 15:54):

That is what testing is for... By testing MORE than was shown in examples one catches those that only coded to the examples. Test plans and Test tools are just as critical to compliance as good specifications.

view this post on Zulip Eric Haas (Nov 07 2019 at 15:54):

And make more example friendly igs

view this post on Zulip Morten Ernebjerg (Nov 07 2019 at 16:33):

I'm absolutely a fan of using profiles to express business rules. But I think it's also true that "reading profiles" and turning them reliably into code is often quite hard for developers, at least if they don't have previous experience with similar standards (based on personal and shared experience). It's a complex format and there are quite a few things to keep an eye out for (is-modifers indicated with a tiny ?! in the rendering, FHIRPath constraints hiding on nested elements etc.). Of course, that complexity is really there and will not go away, but I think exploring ways of making it easier to consume for devs would be a worthwhile thing to pursue (I'd be happy to chip in my 5ct).

view this post on Zulip Lloyd McKenzie (Nov 07 2019 at 16:37):

We're always open to new/better ways of rendering information that makes it faster/easier/more likely to create compliant implementations

view this post on Zulip Michele Mottini (Nov 07 2019 at 16:39):

+1 for textual descriptions. Those in Argonaut / US Core are perfect (or see the Cerner documentation for another nice example: https://fhir.cerner.com/millennium/dstu2/individuals/patient/)

view this post on Zulip Jose Costa Teixeira (Nov 07 2019 at 18:16):

Would be good to link the text to the actual constraint and vice-versa. Something that says "Click here if you want to see why this constraint is here".

view this post on Zulip Jose Costa Teixeira (Nov 07 2019 at 18:17):

For this, we'd probably need business rules to be identifiable chunks of text. Not sure we have that.

view this post on Zulip Jose Costa Teixeira (Nov 07 2019 at 18:18):

(i'm jumping in because I made a side comment in the Atlanta IG training about having "requirements" as an entity. That is probably not the role of FHIR but...)

view this post on Zulip Kevin Mayfield (Nov 08 2019 at 08:31):

Agree with @Morten Ernebjerg I've been implementing FHIR for several years and so familiar with profiles. Where I struggle is identifying new business rules within profiles - to be honest I mostly miss them.
Most projects seem to be more concerned about adherence to rules rather than FHIR conformance.

An example is here https://nhsconnect.github.io/gpconnect/accessrecord_structured_development_medicationrequest.html#extensionrepeatinformation
This extension has a rule: which is mandatory if the order is a repeat, it must not be present if not.

You could create two derived profiles to enforce this rule (this profile is already derived) or create a constraint (which I would probably miss).
I think I would prefer ruleset, which states which profile I should use and what are the extra rules.

This sounds similar to FHIR Graph Definition. Am I correct in believing many of the rules on the link above, could be defined in a GraphDefinition (@Lloyd McKenzie ).

This same resource is returned in a FHIR Bundle which also has business rules (), again I think GraphDefinition would work here as a way of defining rules. (@Jonny Rylands thoughts). These rules are best illustrated in this diagram https://nhsconnect.github.io/gpconnect/accessrecord_structured_development_retrieve_patient_record.html#bundle-population-illustrated.

view this post on Zulip Michel Rutten (Nov 08 2019 at 11:47):

I guess discoverability of constraints is mainly related to presentation/rendering, more so than the actual underlying representation/wire format. I'm not sure if/how this would improve by expressing your business logic in some other way.

view this post on Zulip Dave Barnet (Nov 08 2019 at 14:53):

Lots of useful discussion. Just to try out the "make a profile" solution, here's a few scenarios (I'm relally thinking messaging & validation rather then REST)

Scenario 1 Patient.name - the base profile we use has Patient.name as optional. A project comes along that mandates Patient.name - is that reason enough to create a profile of Patient that mandates Patient.name?
Scenario 2 Condition.code - the base profile we use has a preferred binding to a large condition SNOMED CT refset. A project wants to use condition to capture whether a mother suffers from a recognised post-natal list of conditions. They provide a valueSet. Is this reason enough to have a Condition profile that binds the code element to this new valueSet?
Scenario 3 Observation - We need to standarise units from pathology lab tests - is this reason enough to create Observation profiles for each lab test that fix codes (type of test) and expected units?

view this post on Zulip Eric Haas (Nov 08 2019 at 15:02):

Observation Definition and graph definition are shortcuts to profiling. But still needs to be documented clearly.

view this post on Zulip Kevin Mayfield (Nov 08 2019 at 16:19):

I'm not sure they are shortcuts. Have played around with ObservationDefinition and it was pretty straight forward (from a dev perspective) to understand and use, especially when compared to equivalents in Observation profiles (I'd start coming close to being anti-fhir if pushed to use multiple obs profiles).

view this post on Zulip Lloyd McKenzie (Nov 08 2019 at 16:26):

GraphDefinition would be good for defining invariants that hold across resources - particularly those that don't have direct relationships with each other. Invariants within a resource would still be expected to be handled within a profile though. (Our ability to render profiles may not be ideal, but our capabilities and experience with authoring GraphDefinitions, let alone rendering them in an understandable way, is significantly less.

view this post on Zulip Kevin Mayfield (Nov 08 2019 at 16:28):

However for RESTful interactions I am a fan of using profiles only.

For messaging, firstly I want to know what should be in the message bundle. What I want is something this HL7v2 for ADT^A04 which I believe is what GraphDefinition can do.

ADTA04.PNG

view this post on Zulip Kevin Mayfield (Nov 08 2019 at 16:30):

From there I would go to the profiles, so PID being Patient would say CareConnect-Patient-1.
If a derived profile is used I only want to know what the diff is, I'm not going to want to wade through a full profile.

view this post on Zulip Grahame Grieve (Nov 08 2019 at 19:52):

my responses:

  • Scenario 1 is definitely a profile whatever you try to call it
  • Scenario 2 depends. It might be a value set condition buried in a Trigger Definition. It's not clear that it's a 'profile'
  • Scenario 3: no I advise against using profiles in this case; there's no useful differentiation in structure between 1000s of different numerical lab tests. There's about 10 or so relevant data patterns; use ObservationDefinition to describe the 1000s of variants.

view this post on Zulip Kevin Mayfield (Nov 09 2019 at 09:24):

Scenario 2 is more complex. On a practical level a lot of things need to happen before the rule is followed (mostly around SNOMED, code conversions, term server interactions and validation engines), so at best it's going to be guidance.

view this post on Zulip Grahame Grieve (Nov 09 2019 at 09:37):

Sure. But my point is, there are other computable places in FHIR than profiles for stuff like this

view this post on Zulip Lin Zhang (Nov 09 2019 at 10:45):

Given readability and expressivity of the CQL, is it possible to use CQL for the rules in the FHIR profile? Just a wierd idea :)

view this post on Zulip Grahame Grieve (Nov 09 2019 at 11:35):

well... CQL is optimised for queries across resources. The inside resource bit is FHIRPath which is common with profiles. and it's possible to have a profile that says nothing in structured content, just makes a bunch of fhirpath invariants

view this post on Zulip Lin Zhang (Nov 09 2019 at 14:23):

Appreciate so much for your explanation

view this post on Zulip Kevin Mayfield (Nov 09 2019 at 14:56):

@Grahame Grieve agree. Any worked through examples - if not I'll look at doing some.

view this post on Zulip Eric Haas (Nov 09 2019 at 17:12):

I am very interested in rendering a graph definition as a table or a DAG to make it more useful for readers. Has anybody done that already before I give it a go.?

view this post on Zulip Grahame Grieve (Nov 09 2019 at 19:59):

like this? http://hl7.org.au/fhir/rcpa/cprofiles.html

view this post on Zulip Kevin Mayfield (Nov 10 2019 at 08:23):

I've had a go at rendering https://data.developer.nhs.uk/ccri/term/graph/7 (and a GraphDefinition)
to help describe how to build a Bundle I'm currently working on.

Some of the rules on the response, are below:

Screenshot-2019-11-10-at-08.10.34.png

Although the patient profile doesn't require a generalPractitioner, the response does and graphDefinition has allowed me to override that.

Probably a better example are the lists. The lists differ by code and which resource is in the list.

Screenshot-2019-11-10-at-08.14.07.png

This rule is quite brief and for that reason I don't think it justifies a profile.

view this post on Zulip Grahame Grieve (Nov 10 2019 at 08:42):

what is it that 'justifies a profile'?

view this post on Zulip Kevin Mayfield (Nov 10 2019 at 08:56):

I think that's the question.

view this post on Zulip Grahame Grieve (Nov 10 2019 at 09:03):

well, our answer so far is: any time you want to make rules about what is acceptable in a resource. But you don't seem to like that answer very much, because you seem to think that there's some...weight...price... to having a profile

view this post on Zulip Kevin Mayfield (Nov 10 2019 at 10:40):

Don't think it's as simple as that.

I'd say I'm trying to profile/define Bundle responses (most UK standards are messaging or document based).

I believe some of the response requirements shouldn't be profiled. I need to look further though.

view this post on Zulip Eric Haas (Nov 11 2019 at 16:38):

is this https://nhsconnect.github.io/gpconnect/accessrecord_structured_development_retrieve_patient_record.html#bundle-population-illustrated

rendered from a GraphDefinition as well?

view this post on Zulip Kevin Mayfield (Nov 11 2019 at 17:17):

Nope. I think it's a good candidate for it though (working on an example for it)

view this post on Zulip Kevin Mayfield (Nov 11 2019 at 17:20):

Leaning towards Rene's view in here though https://chat.fhir.org/#narrow/stream/179177-conformance/topic/GraphDefinition.20as.20a.20conformance.20resource

view this post on Zulip René Spronk (Nov 21 2019 at 11:05):

FWIW Friday at the DevDays in Amsterdam, there'll be a tutorial about GraphDefinition at 11:05 in The Richard.

view this post on Zulip Kevin Mayfield (Nov 21 2019 at 11:06):

Wish I was there.


Last updated: Apr 12 2022 at 19:14 UTC