Stream: implementers
Topic: Specialization in Admin resources
Grahame Grieve (May 07 2019 at 09:21):
For context, see https://wolandscat.net/2019/05/06/a-fhir-experience-models-or-just-definitions/#more-1524.
My question: do you think that it would be useful for us to introduce at least an abstract ancestor for Patient/RelatedPerson/Practitioner? Vote with :thumbs_up: or :thumbs_down:
Note: I have not investigated yet whether this is actually possible - though I expect it is - nor do I know how far we can go given various operational constraints. Nor do I know how far I think we should go
John Silva (May 07 2019 at 09:57):
Does it make sense for resources that follow the workflow pattern? https://www.hl7.org/fhir/workflow.html
Grahame Grieve (May 07 2019 at 10:03):
no, because the pattern semantics are looser that direct inheritance - the rules are much harder for the second. I am generating patterns into HAPI, but it's a more flexible pattern
Nick Radov (May 07 2019 at 13:35):
Are you thinking of introducing another inheritance layer, or adding another design pattern?
Grahame Grieve (May 07 2019 at 13:38):
Strongly the first, but may fall back to the second.
Nick Radov (May 07 2019 at 13:41):
Would Person have the same abstract ancestor?
Michel Rutten (May 07 2019 at 13:57):
@Mark Kramer has demonstrated the powerful benefits of introducing additional (abstract) base classes. As a software developer, common bases classes and interfaces usually make my life easier. So in general, I'd certainly like to investigate this approach.
Grahame Grieve (May 07 2019 at 14:01):
I don't know about Person. Probably not, but needs investigation
Nick Radov (May 07 2019 at 14:11):
I like the idea from an architectural purity standpoint provided that it will be mostly just used as part of building the specification and largely hidden from regular implementers. One of the problems we had with V3 adoption is that some implementers who lacked a theoretical CS background simply didn't understand how RIM inheritance worked. So as long as we still end up with a single Patient resource page containing all of the elements and don't have to look up some common elements on a separate page for the superclass, then I think this would be a positive change.
Grahame Grieve (May 07 2019 at 15:08):
I think I can do that.
Grahame Grieve (May 07 2019 at 15:09):
but then the CS guys complain bitterly about the duplication and run around telling everyone how stupid you are ...
Peter Jordan (May 07 2019 at 15:22):
...and other CS persons argue that implementation inheritance is evil http://whats-in-a-game.com/implementation-inheritance-is-evil/ ...can I vote for both approaches? :thinking:
Michel Rutten (May 07 2019 at 15:25):
I think from a FHIR standpoint, this looks more like providing a common interface. However in concrete implementations of FHIR API libraries, this may - or may not - be implemented using implementation inheritance.
Michel Rutten (May 07 2019 at 15:26):
i.e. I don't feel like this proposal would introduce the notion of implementation inheritance into the FHIR spec itself.
Grahame Grieve (May 07 2019 at 15:28):
it goes a bit further than a fancy wrapper interface. it does specifically propose that you would have inheritance - maybe an abstract ancestor called 'Actor' and then you would do Reference(Actor) instead of Reference(Patient | RelatedPerson | Practitioner) - this is much more than just decorating with an interface
Peter Jordan (May 07 2019 at 15:29):
The RIM lives on!
Eric Haas (May 07 2019 at 16:12):
Would the next step be Reference(Event) instead of Reference(Observation|Condition)? sound like a bad idea to me.
Grahame Grieve (May 07 2019 at 16:13):
why would that be a bad idea?
Eric Haas (May 07 2019 at 16:17):
I assumed this would be exposed to human eyeballs. We dislike indirection and abstraction when all we want to see it what it refers to.
Grahame Grieve (May 07 2019 at 16:22):
well, to a certain point. Indrection is useful too. depends on balance ....
Michel Rutten (May 07 2019 at 16:23):
@Eric Haas that sounds more like a presentation issue, which can be addressed.
Michael Donnelly (May 07 2019 at 16:28):
So the problem this would potentially solve would be lack of consistency across resources, right? Is the goal this solution seeks to achieve having consistently named and described elements in similar resources?
Eric Haas (May 07 2019 at 17:10):
@Michael Donnelly we already have a mechanism in place a through workflow patterns. ( but not for 'person' entities )
Grahame Grieve (May 07 2019 at 17:28):
right. these are outside workflow. But the patterns are very loose. I'm working with them now
Michael Donnelly (May 07 2019 at 17:57):
How well is it working in your opinion, Eric?
Abbie Watson (May 07 2019 at 18:20):
Thought exercise: if we go down the rabbit hole of making abstract ancestor classes available as interoperable resources, where does that end? I'm imagining chatter between multiple systems using all of the abstract classes presented by @Mark Kramer, and am reminded of these AI systems that are inventing their own languages that needed to be shut down.
So I sort of agree with Eric Haas, that we need to keep the human readability element in place for the time being. There will be someday in the future when these abstract classes are all made available, but the tooling isn't entirely in place for what we currently have. Save the abstract ancestor classes for HL7 2030.
Eric Haas (May 07 2019 at 18:24):
It was a s#$%load of work for editors and it did help with consistency. We also tabulated all the variations which is exposed in the build here. http://build.fhir.org/event.html#mappings
Eric Haas (May 07 2019 at 18:25):
and am reminded of these AI systems that are inventing their own languages that needed to be shut down.
What does that mean?
Grahame Grieve (May 07 2019 at 18:27):
by definition, abstract resources are not available as interoperable resources, since they can't exist directly
Abbie Watson (May 07 2019 at 18:36):
@Eric Haas Microsoft Labs had to shut down one of their experiments:
https://www.fastcompany.com/90132632/ai-is-inventing-its-own-perfect-languages-should-we-let-it
Meanwhile, the reference model introduced by Mark Kramer has abstract classes like AlbuminGlobulinMRtoPtSerPlasQnLabObs
, ComprehensiveMetabolic2000SerumOrPlasmaPanel
, and such. I'm just trying to say that going down the path of abstract ancestors to it's logical conclusion may leave us somewhere we don't want to be.
Lloyd McKenzie (May 07 2019 at 18:38):
The RIM never allowed pointing to individuals independent of their role - you were always pointing to an AssignedEntity (Practitioner), RelatedEntity (RelatedPerson) or Patient. The difference with the RIM is that you always had to point to a different class to convey information such as gender, birthDate, etc. - and all such demographics was available for everyone. With FHIR we said "very few implementers actually store data that way - there are usually separate tables for practitioners, patients and relatives and each has distinct columns for gender, birthDate, etc. Furthermore, the set of demographic information commonly tracked for Patients, Practitioners and RelatedPersons is generally quite distinct - and we don't want to munge the 80% for all three use-cases together.
Lloyd McKenzie (May 07 2019 at 18:39):
The only benefit of adding a new resource is to say "this was done by someone named John Smith - but I have no clue if they were the patient, a relative of the patient or someone acting in professional capacity" - and that's a super limited edge-case.
Lloyd McKenzie (May 07 2019 at 18:41):
In addition to the 80% rule issue challenges, adding inheritance creates visibility challenges (inherited elements aren't as visible/obvious to readers) and a sorting challenge (inherited elements always appear at the top - which isn't necessarily where they should logically fit in an instance)
Grahame Grieve (May 07 2019 at 18:42):
umm no. The proposal would be to add abstract generalizations. So this is not a construct that can be used like that. Instead, it allows a software implementation to handle all 3 of those resources and share some common behavior
Lloyd McKenzie (May 07 2019 at 18:43):
We'd talked about using an interface approach to doing that that wouldn't require inheritance. I'm certainly happy for there to be an 'individual' pattern similar to the event/request/definition patterns that could be used for that purpose.
Grahame Grieve (May 07 2019 at 18:44):
why are so opposed to inheritance?
Peter Jordan (May 07 2019 at 18:53):
Most of the pushback here relates to implementation inheritance. These concerns will be amplified if the FHIR Model is mapped to a relational database ( see the 'classic' essay on ORM at http://blogs.tedneward.com/post/the-vietnam-of-computer-science/) or FHIR resources are persisted as is. Interface inheritance at the application layer is another (and very elegant) thing - 22 of the 23 GoF Patterns can be implemented using this paradigm.
Grahame Grieve (May 07 2019 at 19:35):
Interface inheritance at the application layer
Can you be specific as to what you mean by that?
Peter Jordan (May 07 2019 at 19:54):
The Business layer in a multi-layered software application - where, for example, an EHR application developer might reference and utilise the FHIR libraries.
Grahame Grieve (May 07 2019 at 19:54):
that didn't help explain
Peter Jordan (May 07 2019 at 20:00):
Maybe this is now 'old school', but multi-layered applications typically have presentation, application (business + data access) and persistence layers. https://hub.packtpub.com/what-is-multi-layered-software-architecture/. The GoF patterns are applicable to the design of application/business layer functionality.
Grahame Grieve (May 07 2019 at 20:05):
I think you're saying, we should just abandon the general implementer and only specialist insiders can do smart things
Abbie Watson (May 07 2019 at 20:05):
As opposed to other application layer design patterns. Inheritance somewhat presumes an object-oriented paradigm; but that's not necessarily always a safe assumption. Node/Javascript developers might just as likely use decorators, chained methods, monads, or other functional programming patterns. Object interfaces (denoted by IObject and similar notation in .NET) are a borrowed language feature from functional languages like lisp and scheme, and map nicely to FHIR extensions and the type of interface pattern that Michel and Lloyd have mentioned. It's a sort of happy compromise between object and functional paradigms.
Peter Jordan (May 07 2019 at 20:08):
I think you're saying, we should just abandon the general implementer and only specialist insiders can do smart things
Not at all - more a case that implementation inheritance probably isn't the best way to model business information (works far better for computer artefacts such as UI controls). From an application development perspective, interface inheritance is far more robust.
Grahame Grieve (May 07 2019 at 20:11):
given that we don't separate between interface and implementation, I'm not sure what you're saying.
Jim Steel (May 07 2019 at 20:14):
and the original discussion (or my reading of it) was about references to an abstract supertype, so its really a question of subtyping rather than inheritance in any case, I would have thought
Grahame Grieve (May 07 2019 at 20:14):
I'm not sure what the difference is there
Jim Steel (May 07 2019 at 20:15):
inheritance is unpopular ;)
Abbie Watson (May 07 2019 at 20:16):
I think the general sentiment is that if we're going to pick a language feature to lean on, there's interest in object interfaces rather than object inheritance.
Jim Steel (May 07 2019 at 20:17):
<academic> inheritance is about definitional things, so you define something in terms of another thing and it acquires the things (behaviour, structural features) of its parent. Subtyping is about whether a thing is substitutable for another thing for a given purpose. In a lot of implementations (most), inheritance will give you subtyping, but its not the only way you can get subtyping, and there are features (type parameters being a prominent one) that can mean that inheritance does not imply subtyping</academic>. I'm writing this reluctantly, though. I don't think it really changes anything
Grahame Grieve (May 07 2019 at 20:20):
well... that all sounds interesting... but I don't see how it's different in practice in the context of the dsicussion
Jim Steel (May 07 2019 at 20:22):
Yes, I think you're right. Perhaps the only upshot is, if people tell you that they hate inheritance, for something like the FHIR spec, you can probably tell them its subtyping. Or you could just ignore them. And either would probaby be justified
Peter Jordan (May 07 2019 at 20:28):
At the moment the voting is 10-7 against an abstract ancestor (presumably a Person or Actor Resource) for Patient/RelatedPerson/Practitioner. If I've misunderstood that question, I'll get my coat.
Abbie Watson (May 07 2019 at 20:28):
Going out on a limb here, because I'm not 100% sure what Lloyd had in mind regarding interfaces, but it might roughly be described as an 'extensions everything' approach. So instead of creating an Individual
resourceType as an abstract ancestor, it would be more like creating an individual
extension which Patient, RelatedPerson, Practitioners and others use to get to their current schema definitions (presumably including the patient
and/or subject
field). But I'm being handwavy and non-formal in my use of the term extension here.
Grahame Grieve (May 07 2019 at 20:29):
I'm noting the vote with interest. I'm wondering why people are voting against it
Eric Haas (May 07 2019 at 20:50):
I'll get my coat
I had to look that one up ;-)
Yunwei Wang (May 07 2019 at 21:00):
It is now 11-7
Grahame Grieve (May 07 2019 at 21:13):
fascinating. I'm going to have a go at it anyway, and see what people think about what it looks like. But I will be pessimistic about the outcome.
Lloyd McKenzie (May 08 2019 at 00:19):
I'm not against inheritance. I'm concerned about the behavior I think it'll drive. As an example, take maritalStatus. We've identified it as a core element for Patient, but not for Practitioner or RelatedPerson. If we create a hierarchy, where will it live in the hierarchy? Most modeling-oriented people will push to it to be moved to the common abstract on the grounds that it logically exists for all three and it's probably tracked by at least a tiny percentage of systems for Practitioner and perhaps RelatedPerson too. Arguing to keep it where it is will be much harder. And if we do move it up, then the 80% notion becomes messier for those implementing the specializations. With patterns and interfaces, on the other hand, it's easy enough to expose the core element from Patient and extension elements from the other two as elements (if desired) and it doesn't change resource design. It also allows for name variance where that makes things easier for the single-resource implementers while still allowing consistent names for those systems that want to manipulate resources generically.
Grahame Grieve (May 08 2019 at 10:15):
there's a consistent theme here, which is that we like the pattern/interface construct for this use. But there's no way anyone other than a few insiders could turn the pattern stuff into code - I know, because I'm trying now, and I'm not entirely sure that I'm going to succeed, even given that I have the access to edit the mappings directly
Grahame Grieve (May 08 2019 at 10:17):
so if we think that the pattern construct is useful, then we would need to:
- define a new approach for pattern where the pattern has teeth - e.g. the resources that claim to follow the pattern need to do so computationally
- allow for Reference(Pattern) so that we can leverage it in the design phase
Grahame Grieve (May 08 2019 at 10:17):
fyi, here's a little table around the current relevant resources:
Grahame Grieve (May 08 2019 at 10:18):
nicola (RIO/SS) (May 08 2019 at 10:29):
The most elegant solution of this problem, which I ever saw, is the Semantic Web/RDF - an attribute level semantic - i.e. detaching attribute from an entity (element from resource) and reuse it . Your interfaces will be - is this instance/class has a set of specific attributes or not?
Grahame Grieve (May 08 2019 at 10:31):
detaching attribute from an entity
To the degree that this is a statement about definitional method, I agree with this, and it's kind of how FHIR works. but to the degree that it's a claim that you can define data element separated from it's context of use... I don't believe in that, and the FHIR design framework is an expression of that belief
Grahame Grieve (May 08 2019 at 10:34):
the highlighted cells in that table above are all problems for designing a clean heirarchy (and I didn't even count questions of order).
- PractitionerRole doesn't have a name to use as a display
- Device uses status - different to all the other resources
- Device Name is very complicated
- Organization Name is a simple name (= HumanName.text, in principle)
- Practitioner can't indicate a preferred communication
John Silva (May 08 2019 at 10:47):
I go back to my question about the Workflow pattern -- not in the sense of using that as some object hierarchy, but that any resource that implements one of it's (sort of) abstract interfaces should at least use the names defined by the pattern. So, o-o aside, it seems like there should be some consistent naming conventions, maybe defined by patterns like Workflow, so that users know what to expect when they 'pick up' any FHIR resource, that there will be consistency in naming similar conceptual things (property names). It seems as a 'outsider to the committee discussions' that names are chosen that do not necessarily align with that of the Workflow pattern, maybe for good reason in the committee, but from an 'outsider/user' of the pattern these varied names might cause more confusion than help. (This brings up this related question, what is this discussion trying to accomplish -- an oo paradigm for FHIR resources or a consistency in naming or something else?)
Nick Radov (May 08 2019 at 13:25):
so if we think that the pattern construct is useful, then we would need to:
- define a new approach for pattern where the pattern has teeth - e.g. the resources that claim to follow the pattern need to do so computationally
- allow for Reference(Pattern) so that we can leverage it in the design phase
Thanks for taking this on. Those changes would be tremendously beneficial to the long term health of FHIR. Provided that the specification is still easy for new implementers to understand so that someone who just wants to hack together a simple JSON string for a Patient can find everything they need on the Patient page without having to hunt through a bunch of pattern pages. In other words the additional complexity introduced by using patterns (interfaces) in that way should be hidden as much as possible in the build process and lower layers of the specification.
Lloyd McKenzie (May 08 2019 at 13:46):
@John Silva The use of the pattern names is a 'should', not a 'SHALL'. As a base principle, the need to be intuitive within a domain is more important than consistency across resources. That said, where consistency doesn't interfere with domain intuitiveness, we expect names to be consistent
Grahame Grieve (May 08 2019 at 13:48):
I'm proposing to step that up a bit, and make it so they are required to be consistent for selected patterns
Lloyd McKenzie (May 08 2019 at 13:51):
Why? If we have a mapping between the names, we can generate an interface. I'd be cautious about making things harder for the 'simple' implementer for the benefit of making them easier for the 'sophisticated' implementer.
Grahame Grieve (May 08 2019 at 13:55):
says you who haven't tried to generate the interface. I'm doing it right now... it's going to fearfully difficult to make the existing patterns work for code generation. I want to make it easier for people to do that. And I don't see why that means it needs to be harder for simple implementers
John Silva (May 08 2019 at 13:59):
Has anyone thought of an aliasing mechanism? The notion is that the pattern (e.g. Workflow) defines the SHALL properties but a committee can define an alias (prop name) that meets their domain's unique naming convention? (Not sure if this makes sense or is possible in JSON/XML -- just putting it out there as a different perspective.)
Vassil Peytchev (May 08 2019 at 14:06):
At least one of the XML serialization mechanisms in .NET allows the class property name to be either used as is for the XML element or attribute name, or be redefined to a different name. I think this will work with interfaces.
Lloyd McKenzie (May 08 2019 at 14:13):
I recognize that building an interface is going to be challenging - but I think the 'challenging' bit is where there isn't a 1..1 correspondence of elements, difference in types, variations in value sets, etc. I would think that if the sole difference was name, that should be pretty easy to manage.
What we've said is that if a domain has a common term that is widely recognized in that implementation community and the 'standard pattern' term is not widely recognized or is likely to be confusing/misleading in that community, the resource would use the name that was common in the domain. Forcing the 'standard pattern' name would "make things harder" by increasing the learning curve for implementers who only care about that one domain and would also create confusion and all of the costs that come with misunderstanding/interpreting the specification.
Grahame Grieve (May 08 2019 at 14:28):
well, the question here is of balance; smaller more focused patterns can/should be more demanding than the general patterns (which we already see with FiveWs vs Event/Request/Definition)
Grahame Grieve (May 08 2019 at 14:28):
so we could define the patterns in my sheet above and say that it's reasonable for those to be more demanding again
Jean Duteau (May 08 2019 at 15:29):
any resource that implements one of it's (sort of) abstract interfaces should at least use the names defined by the pattern
This to me is the biggest problem with the current "patterns". I remember when FHIR first came out that committees were told that we could use names for data elements that matched what implementers within that community called things. Thus, instead of occurrencePeriod on the Medication Dispense resource, we have "whenPrepared" and "whenHandedOver" which finally addressed a longstanding puzzle for implementers in the dispensing space about what "effectiveTime.low and .high" actually meant. If you wanted blind consistency, you're effectively telling the pharmacy-space implementers "forget what you call things, we have to use these generic names to meet some data modeler's requirement/bugaboo of consistency.
I agree with consistency if there is no reason to be different - name vs deviceName, supportingInformation vs supportingInfo, etc. but if a committee has a reason for being different, and the bar should be very low for this difference, then they should feel empowered to call things the way their community calls them.
Thus the pattern should be a mappable construct where I show how my resource maps to the pattern and not a blind inheritance or consistency requirement.
Grahame Grieve (May 08 2019 at 15:42):
yes you've captured the current position well, I'm arguing, however, that there are smaller patterns - more focused than our current wide patterns) where the benefit of implementation justifies the requirement to stick to the rules. To be clear: the current patterns we have do not justify such rules
Melva Peters (May 08 2019 at 15:42):
+1
Nick Radov (May 08 2019 at 15:46):
yes you've captured the current position well, I'm arguing, however, that there are smaller patterns - more focused than our current wide patterns) where the benefit of implementation justifies the requirement to stick to the rules.
In principle some such patterns could be very small, perhaps as small as a single element to avoid repetitive element definitions across multiple resources.
Jose Costa Teixeira (May 08 2019 at 15:58):
I agree with consistency if there is no reason to be different - name vs deviceName, supportingInformation vs supportingInfo, etc. but if a committee has a reason for being different, and the bar should be very low for this difference, then they should feel empowered to call things the way their community calls them.
Agree, with one reflection - scope changes, opinions and consensus changes with scope or with time.
I remember some occasions of "no, this is what everyone calls it and we will never change it" and then...
Jose Costa Teixeira (May 08 2019 at 16:00):
so we should have some guidelines. still when such guidelines are asymptes and not bindind, we have some challenges.
Jose Costa Teixeira (May 08 2019 at 16:04):
in terms of progress, I gained some peace with how we are looking at another pattern - Product.
We let the resources (medication, device, nutrition, biologicallyderivedproduct) follow their path and get the people to join discussions and eventually this means that resources can align. I think it wastes a lot of effort but at least does not impose any foreign language in the committees and it allows consensus, whenever it comes.
Jose Costa Teixeira (May 08 2019 at 16:08):
I like the idea of patterns driven by real use cases, and some common discussions to force people to look at that pattern. Committees should be able to deviate by default, but there should be a check to see when deviation is no longer worth it.
Lloyd McKenzie (May 08 2019 at 20:05):
I think what makes sense is the evaluation of value. If we're going to mandate a name change (or any other kind of change), we need to weigh the cost to the single-domain communities and implementers vs. the benefit of whomever the pattern is for. That said, I really don't understand why names are such a big issue. Structural and design issues create much more grief.
Grahame Grieve (May 09 2019 at 13:25):
back to this then. Here's my proposal:
Grahame Grieve (May 09 2019 at 13:25):
Grahame Grieve (May 09 2019 at 13:29):
Actions:
- Introduce patterns for Actor, ContactableActor, and HiumanActor
- specialisation relationships amongst the patterns as implied in the table above
- created 3 tasks to resolve the consistency problems around PractitionerRole.name, Device.name, Practitioner.communication (all of which i think are supported by real life problems, not created by the pattern)
- make any inconsistencies with these patterns a hard error(unlike other patterns)
- the orange fields require some adaptation to meet the pattern requirements (in pattern implementations - will be specified in the mapping)
Nick Radov (May 09 2019 at 13:31):
Did you decide if and how Person should fit into that hierarchy?
Michael Donnelly (May 09 2019 at 13:32):
Why is "name" in orange for Patient, Practitioner, and RelatedPerson?
Grahame Grieve (May 09 2019 at 13:35):
because name in the pattern is string, but name in those resources is HumanName, so the pattern implementation will have to account for that
Grahame Grieve (May 09 2019 at 13:35):
Person does not fit into that heirarchy because it's not an actor (not a role in v3 speak)
Cooper Thompson (May 09 2019 at 13:57):
How many use cases do we have where we'd actually apply this inheritance/hierarchy/interface pattern? Is it only for Actors? Would we actually want to apply this to Events as Eric Hass mentioned? If it is only Actors, is it worth the effort to build a formal solution for this rather than a KISS solution of just having WGs manually keep things in sync? Most of the actors are owned by PA so it isn't even that much cross-WG coordination.
Grahame Grieve (May 09 2019 at 13:59):
I don't know how many other cases we have. I'm going to go looking for them.
Grahame Grieve (May 09 2019 at 14:00):
we have event, and it's looser, and I'm going to keep working through it for consistency
Grahame Grieve (May 09 2019 at 14:00):
I will be building a formal solution for this one if FHIR-I approves, so that committees know if they break it
Grahame Grieve (May 09 2019 at 14:00):
I will also get PA to formally approve this one.
Grahame Grieve (May 09 2019 at 14:01):
btw, I don't know with Actor/ContactableActor/HumanActor - whether the middle one is justified or not....
Michael Donnelly (May 09 2019 at 14:07):
The model looks solid. How would it actually be used?
Jose Costa Teixeira (May 09 2019 at 14:09):
we have been discussed this same issue for Product - medication, device, devicedefinition, medicationKnowledge, regulatedxxx, biologicallyderivedproduct, nutrition...
Not only on the product resource, but also on the way we handle ordering, delivery, usage (MedicationStatement/MedicationUsage vs DeviceUseStatement)...
Jose Costa Teixeira (May 09 2019 at 14:10):
does this problem grant such a pattern?
Grahame Grieve (May 09 2019 at 14:12):
Implementer impacts:
- instead of Reference(Patient|...) the specification would say "Reference(Actor)"
- we would ship StructureDefinitions for the patterns
- implementers generating source can generate the source for the patterns however they want (I'll do it automatically in HAPI)
- in HAPI, you'll be able to take a target of a reference and do factory.asActor(resource) and get an IActor facade to it if you want
- in non-typed languages, you can just treat them as if they are equivalent anyway, but this servers as helpful documentation
Nick Radov (May 09 2019 at 14:17):
- we would ship StructureDefinitions for the patterns
Would we add another concept to the StructureDefinitionKind value set to distinguish patterns?
Grahame Grieve (May 09 2019 at 14:20):
we already ship some patterns, so I don't think anything new is needed
Grahame Grieve (May 09 2019 at 14:21):
@Jose - Product, maybe.
Grahame Grieve (May 09 2019 at 15:26):
I'm going to do analysis around this...
Jean Duteau (May 09 2019 at 16:10):
My use case isn’t about the admin resources, but I do believe that the ability to specify Reference(Pattern) is a good thing to add to the methodology. I have seen a few resources where they are currently enumerating the choice of resources and I think that this will become onerous to add new choices in the future. I also think that it puts the requirement to know on the owner of the resource with the choice rather than the resources that may decide they want to be part of that choice.
My example is ChargeItemDefinition which currently lists three resources as the item being the choice of the charge definition. There are plenty of other resources that might make sense there but that requires those resource owners to make a request to PA to update ChangeItemDefinition. If, instead, ChargeItemDefinition just said instance: Reference(ChargeableItem), then I could introduce a new resource and declare it to match the pattern and it would automatically be allowed in a ChargeItemDefinition.
Grahame Grieve (May 09 2019 at 16:11):
yes that's where I want to go. I've been meaning to get to this but no one was pushing on it. I'm going to set it up as possible now
Jean Duteau (May 09 2019 at 16:12):
CatalogEntry is another case where Reference(Any) doesn’t make sense, but Reference(<specific set of resources>) also doesn’t seem sense. Having it say Reference(CatalogableItem) and allowing me to specify at the Resource level or Profile level that my resource is catalogable seems a good thing.
Jose Costa Teixeira (May 09 2019 at 16:25):
and supply is one other place where you would reference the product pattern
Jose Costa Teixeira (May 09 2019 at 16:26):
you deliver a product, which can be a med, a device...
Michele Mottini (May 09 2019 at 16:44):
So now for each reference we know which resources can be referenced - that makes validation trivial - in the future we'll have to navigate through a hierarchy to do that? How is that better?
Grahame Grieve (May 09 2019 at 16:52):
well, I think you are asking a presentation question, not a definition question
Grahame Grieve (May 09 2019 at 16:52):
probably I'll just show the expanded list in the tree view and UML, and in the definitions I'll show the pattern and the expansion
Jose Costa Teixeira (May 09 2019 at 16:52):
can't we formalize the hierarchy as a valueset?
Grahame Grieve (May 09 2019 at 16:53):
I will have to think about what goes in the structure definitions
Lloyd McKenzie (May 09 2019 at 18:18):
I'm opposed to HumanActor because Patient, Practitioner and RelatedPerson aren't necessarily humans. BiologicActor would be better.
Lloyd McKenzie (May 09 2019 at 18:21):
Also, Group isn't allowed to Act, only to be a subject. Perhaps 'Participant' rather than 'Actor'?
Lloyd McKenzie (May 09 2019 at 18:24):
(We thus need to be careful about using the pattern. Devices, Patients, etc. can author things but Groups cannot. And in other places, the list is more refined still.)
Jean Duteau (May 09 2019 at 18:28):
(We thus need to be careful about using the pattern. Devices, Patients, etc. can author things but Groups cannot. And in other places, the list is more refined still.)
I would totally agree to this. Although I truly believe that this new capability will help the better specification of our resources, it does force all of us to verify that resources are referencing the proper patterns appropriately. This might end up be slightly harder than seeing a specific choice of resources.
Lloyd McKenzie (May 09 2019 at 18:37):
The biggest challenge is thinking about the 80% rule - adding things that are theoretically possible but in practice are rarely/not supported
Grahame Grieve (May 09 2019 at 18:42):
Technically, in a RIM sense, these are roles not participants. I don't know if this is a naming problem or not
Grahame Grieve (May 09 2019 at 18:45):
FYI, these are the current set of reference combinations found through the FHIR specification:
Grahame Grieve (May 09 2019 at 18:45):
[ActivityDefinition, DeviceDefinition, HealthcareService, Location, MedicationKnowledge, ObservationDefinition, Organization, PlanDefinition, Practitioner, PractitionerRole, SpecimenDefinition, Substance]
[AllergyIntolerance, Condition, DiagnosticReport, DocumentReference, Observation, QuestionnaireResponse]
[AllergyIntolerance, Condition, DocumentReference, FamilyMemberHistory, Immunization, Media, Observation, Procedure]
[AllergyIntolerance, Condition]
[Appointment, AppointmentResponse, CarePlan, ServiceRequest, Task]
[Appointment, CommunicationRequest, DeviceRequest, ImmunizationRecommendation, MedicationRequest, NutritionOrder, RequestGroup, ServiceRequest, Task, VisionPrescription]
[CarePlan, DeviceRequest, ImmunizationRecommendation, MedicationRequest, NutritionOrder, ServiceRequest]
[CarePlan, ImmunizationRecommendation, MedicationRequest, NutritionOrder, ServiceRequest]
[CarePlan, ImmunizationRecommendation, MedicationRequest, ServiceRequest]
[CarePlan, MedicationRequest, ServiceRequest]
[CarePlan, RequestGroup]
[CarePlan, ServiceRequest]
[CareTeam, Device, Group, HealthcareService, Organization, Patient, Practitioner, PractitionerRole, RelatedPerson]
[CareTeam, Device, Group, Organization, Patient, Practitioner, PractitionerRole, RelatedPerson]
[CareTeam, Device, HealthcareService, Organization, Patient, Practitioner, PractitionerRole, RelatedPerson]
[CareTeam, Device, Location, Organization, Patient, Practitioner, PractitionerRole, RelatedPerson, Substance]
[CareTeam, Device, Organization, Patient, Practitioner, PractitionerRole, RelatedPerson]
[CareTeam, Organization, Patient, Practitioner, PractitionerRole, RelatedPerson]
[CareTeam, Organization, Practitioner, PractitionerRole]
[Claim, DocumentReference, Observation, Procedure, QuestionnaireResponse, ServiceRequest]
[ClaimResponse, Coverage]
[ClinicalImpression, DiagnosticReport, Observation]
[Composition, DiagnosticReport, DocumentReference]
[Condition, DiagnosticReport, DocumentReference, Media, Observation]
[Condition, DiagnosticReport, DocumentReference, Observation, Procedure]
[Condition, DiagnosticReport, DocumentReference, Observation, Questionnaire, QuestionnaireResponse]
[Condition, DiagnosticReport, DocumentReference, Observation]
[Condition, DiagnosticReport, Observation]
[Condition, ImmunizationRecommendation, Observation, Procedure]
[Condition, Media, Observation]
[Condition, MedicationRequest, MedicationStatement, NutritionOrder, Observation, RiskAssessment, ServiceRequest]
[Condition, Observation]
[Condition, Procedure]
[Contract, SupplyDelivery]
[Device, Device, DeviceMetric]
[Device, DeviceMetric]
[Device, Group, Location, Patient, Practitioner, PractitionerRole, RelatedPerson]
[Device, Group, Location, Patient, Practitioner, PractitionerRole, Specimen]
[Device, Group, Location, Patient, Substance]
[Device, Group, Location, Patient]
[Device, Group, Medication, Patient, Practitioner, PractitionerRole, Substance]
[Device, Group, Organization, Patient, Practitioner, PractitionerRole, RelatedPerson]
[Device, Group, Patient, Practitioner]
[Device, Group, Patient]
[Device, HealthcareService, Location, Organization, Patient, Practitioner, PractitionerRole]
[Device, HealthcareService, Location, Patient, Practitioner, PractitionerRole, RelatedPerson]
[Device, HealthcareService, Organization, Patient, Practitioner, PractitionerRole, RelatedPerson]
[Device, Medication, Substance]
[Device, Organization, Patient, Practitioner, PractitionerRole, RelatedPerson]
[Device, Organization, Patient, Practitioner, PractitionerRole]
[Device, Organization, Practitioner, PractitionerRole]
[Device, Patient, Practitioner, PractitionerRole, RelatedPerson]
[Device, Patient, Practitioner, PractitionerRole]
[Device, Person]
[Device, Practitioner, PractitionerRole]
[DeviceRequest, MedicationRequest, VisionPrescription]
[DiagnosticReport, ImagingStudy, Immunization, MedicationAdministration, MedicationDispense, Observation, Procedure, SupplyDelivery]
[DocumentReference, ImagingStudy, Media, MolecularSequence, Observation, QuestionnaireResponse]
[DocumentReference, Media]
[Encounter, EpisodeOfCare]
[Group, Location, Medication, Organization, Patient, PlanDefinition, Practitioner, PractitionerRole, Procedure]
[Group, Organization, Patient, Practitioner, PractitionerRole, RelatedPerson]
[Group, Organization, Patient]
[Group, Patient, Practitioner, RelatedPerson]
[Group, Patient]
[HealthcareService, Organization]
[ImagingStudy, Immunization, MedicationAdministration, MedicationDispense, MedicationStatement, Procedure]
[Immunization, ImmunizationEvaluation]
[Location, Organization, Patient]
[Location, Organization, Practitioner, PractitionerRole]
[Location, Organization]
[Location, Patient, Practitioner, RelatedPerson]
[Medication, MedicinalProduct, ObservationDefinition, Substance]
[Medication, MedicinalProduct, Substance]
[Medication, MedicinalProduct]
[Medication, Substance]
[MedicationAdministration, MedicationDispense, MedicationStatement, Observation, Procedure]
[MedicationAdministration, Observation, Procedure]
[MedicationAdministration, Procedure]
[MedicationRequest, VisionPrescription]
[MedicinalProduct, MedicinalProductPackaged]
[MolecularSequence, Observation, QuestionnaireResponse]
[Observation, Procedure]
[Organization, Patient, Practitioner, PractitionerRole, RelatedPerson]
[Organization, Patient, Practitioner, PractitionerRole]
[Organization, Patient, Practitioner, RelatedPerson]
[Organization, Patient, RelatedPerson]
[Organization, Patient]
[Organization, Practitioner, PractitionerRole, RelatedPerson]
[Organization, Practitioner, PractitionerRole]
[Organization, PractitionerRole]
[Patient, Person, Practitioner, RelatedPerson]
[Patient, Practitioner, PractitionerRole, RelatedPerson]
[Patient, RelatedPerson]
[Practitioner, PractitionerRole, RelatedPerson]
[Practitioner, PractitionerRole]
[Substance, SubstanceDefinition]
Grahame Grieve (May 09 2019 at 18:45):
97 combinations
Jean Duteau (May 09 2019 at 18:48):
There are some pretty random sets there. rather than consistency in element names, consistency in resource referencing seems something we could try to fix.
Grahame Grieve (May 09 2019 at 18:54):
this is better analysis
Grahame Grieve (May 09 2019 at 18:54):
[ActivityDefinition, DeviceDefinition, HealthcareService, Location, MedicationKnowledge, ObservationDefinition, Organization, PlanDefinition, Practitioner, PractitionerRole, SpecimenDefinition, Substance]: [CatalogEntry.referencedItem]
[CareTeam, Device, Group, HealthcareService, Organization, Patient, Practitioner, PractitionerRole, RelatedPerson]: [Communication.recipient, CommunicationRequest.recipient]
[CareTeam, Device, Group, Organization, Patient, Practitioner, PractitionerRole, RelatedPerson]: [Consent.provision.actor.reference]
[CareTeam, Device, HealthcareService, Organization, Patient, Practitioner, PractitionerRole, RelatedPerson]: [CarePlan.activity.detail.performer, DeviceRequest.performer, ServiceRequest.performer, Task.owner]
[CareTeam, Device, Location, Organization, Patient, Practitioner, PractitionerRole, RelatedPerson, Substance]: [Contract.term.action.performer]
[CareTeam, Device, Organization, Patient, Practitioner, PractitionerRole, RelatedPerson]: [CarePlan.author, CarePlan.contributor, ChargeItem.performer.actor, ImagingStudy.series.performer.actor, Media.operator, MedicationRequest.performer]
[CareTeam, Organization, Patient, Practitioner, PractitionerRole, RelatedPerson]: [CareTeam.participant.member, Observation.performer]
[CareTeam, Organization, Practitioner, PractitionerRole]: [DiagnosticReport.performer, DiagnosticReport.resultsInterpreter]
[Device, Group, Location, Patient, Practitioner, PractitionerRole, RelatedPerson]: [MeasureReport.subject]
[Device, Group, Location, Patient, Practitioner, PractitionerRole, Specimen]: [Media.subject]
[Device, Group, Location, Patient, Substance]: [Specimen.subject]
[Device, Group, Location, Patient]: [DeviceRequest.subject, DiagnosticReport.subject, List.subject, Observation.subject, ServiceRequest.subject]
[Device, Group, Medication, Patient, Practitioner, PractitionerRole, Substance]: [Group.member.entity]
[Device, Group, Organization, Patient, Practitioner, PractitionerRole, RelatedPerson]: [Contract.term.offer.party.reference, Contract.term.action.subject.reference, Contract.term.action.requester]
[Device, Group, Patient, Practitioner]: [DocumentManifest.subject, DocumentReference.subject]
[Device, Group, Patient]: [ImagingStudy.subject]
[Device, HealthcareService, Location, Organization, Patient, Practitioner, PractitionerRole]: [Account.subject]
[Device, HealthcareService, Location, Patient, Practitioner, PractitionerRole, RelatedPerson]: [Appointment.participant.actor, AppointmentResponse.actor, Schedule.actor]
[Device, HealthcareService, Organization, Patient, Practitioner, PractitionerRole, RelatedPerson]: [Communication.sender, CommunicationRequest.sender]
[Device, Organization, Patient, Practitioner, PractitionerRole, RelatedPerson]: [Signature.who, Signature.onBehalfOf, AuditEvent.agent.who, AuditEvent.source.observer, ChargeItem.enterer, CommunicationRequest.requester, Composition.author, Composition.section.author, DocumentManifest.author, DocumentReference.author, Invoice.participant.actor, MedicationDispense.performer.actor, MedicationRequest.requester, Procedure.performer.actor, Provenance.agent.who, Provenance.agent.onBehalfOf, QuestionnaireResponse.author, ServiceRequest.requester, SupplyRequest.requester, Task.requester]
[Device, Organization, Patient, Practitioner, PractitionerRole]: [Flag.author]
[Device, Organization, Practitioner, PractitionerRole]: [DeviceRequest.requester]
[Device, Patient, Practitioner, PractitionerRole, RelatedPerson]: [AdverseEvent.detector, MedicationAdministration.performer.actor, RequestGroup.action.participant]
[Device, Patient, Practitioner, PractitionerRole]: [List.source]
[Device, Practitioner, PractitionerRole]: [AdverseEvent.contributor, DetectedIssue.author, RequestGroup.author, RiskAssessment.performer]
[Group, Location, Medication, Organization, Patient, PlanDefinition, Practitioner, PractitionerRole, Procedure]: [Flag.subject]
[Group, Organization, Patient, Practitioner, PractitionerRole, RelatedPerson]: [Task.restriction.recipient]
[Group, Organization, Patient]: [Goal.subject]
[Group, Patient, Practitioner, RelatedPerson]: [AdverseEvent.subject]
[Group, Patient]: [CarePlan.subject, CareTeam.subject, ChargeItem.subject, ClinicalImpression.subject, Communication.subject, CommunicationRequest.subject, Condition.subject, DeviceUseStatement.subject, Encounter.subject, GuidanceResponse.subject, Invoice.subject, MedicationAdministration.subject, MedicationDispense.subject, MedicationRequest.subject, MedicationStatement.subject, Procedure.subject, RequestGroup.subject, RiskAssessment.subject]
[HealthcareService, Organization]: [SupplyRequest.supplier]
[Location, Organization, Patient]: [SupplyRequest.deliverTo]
[Location, Organization, Practitioner, PractitionerRole]: [MeasureReport.reporter]
[Location, Organization]: [CoverageEligibilityRequest.item.facility, Encounter.hospitalization.origin, Encounter.hospitalization.destination, SupplyRequest.deliverFrom]
[Location, Patient, Practitioner, RelatedPerson]: [MedicationDispense.receiver]
[Organization, Patient, Practitioner, PractitionerRole, RelatedPerson]: [Basic.author, Claim.payee.party, Composition.attester.party, Consent.performer, Contract.term.asset.valuedItem.responsible, Contract.term.asset.valuedItem.recipient, Contract.signer.party, DocumentManifest.recipient, ExplanationOfBenefit.payee.party, MedicationRequest.informationSource, MedicationStatement.informationSource]
[Organization, Patient, Practitioner, PractitionerRole]: [Contract.author]
[Organization, Patient, Practitioner, RelatedPerson]: [Annotation.author[x]]
[Organization, Patient, RelatedPerson]: [Account.guarantor.party, Coverage.policyHolder, Coverage.payor, Invoice.recipient]
[Organization, Patient]: [BiologicallyDerivedProduct.collection.source]
[Organization, Practitioner, PractitionerRole, RelatedPerson]: [Group.managingEntity]
[Organization, Practitioner, PractitionerRole]: [Claim.provider, Claim.careTeam.provider, ClaimResponse.requestor, ClaimResponse.addItem.provider, Contract.contentDefinition.publisher, CoverageEligibilityRequest.provider, CoverageEligibilityResponse.requestor, DocumentReference.authenticator, EnrollmentRequest.provider, EnrollmentResponse.requestProvider, ExplanationOfBenefit.provider, ExplanationOfBenefit.careTeam.provider, ExplanationOfBenefit.addItem.provider, Immunization.performer.actor, Linkage.author, MedicationDispense.substitution.responsibleParty, MessageHeader.destination.receiver, MessageHeader.sender, MessageHeader.responsible, Patient.generalPractitioner, PaymentNotice.provider, PaymentNotice.payee, PaymentReconciliation.requestor, PaymentReconciliation.detail.submitter, PaymentReconciliation.detail.payee, SupplyDelivery.supplier, VerificationResult.primarySource.who, VerificationResult.attestation.who, VerificationResult.attestation.onBehalfOf]
[Organization, PractitionerRole]: [MedicinalProduct.contact.contact]
[Patient, Person, Practitioner, RelatedPerson]: [Person.link.target]
[Patient, Practitioner, PractitionerRole, RelatedPerson]: [AdverseEvent.recorder, AllergyIntolerance.recorder, AllergyIntolerance.asserter, Condition.recorder, Condition.asserter, DeviceUseStatement.source, Goal.expressedBy, Procedure.recorder, QuestionnaireResponse.source]
[Patient, RelatedPerson]: [Consent.verification.verifiedWith, Coverage.subscriber, Patient.link.other]
[Practitioner, PractitionerRole, RelatedPerson]: [Encounter.participant.individual]
[Practitioner, PractitionerRole]: [AdverseEvent.suspectEntity.causality.author, BiologicallyDerivedProduct.collection.collector, Claim.enterer, ClinicalImpression.performer, CoverageEligibilityRequest.enterer, CoverageEligibilityRequest.item.provider, CoverageEligibilityResponse.insurance.item.provider, DetectedIssue.mitigation.author, EpisodeOfCare.careManager, ExplanationOfBenefit.enterer, ImagingStudy.referrer, ImagingStudy.interpreter, MedicationRequest.recorder, MessageHeader.enterer, MessageHeader.author, NutritionOrder.orderer, ResearchStudy.principalInvestigator, Specimen.collection.collector, SupplyDelivery.receiver, VisionPrescription.prescriber]
[AllergyIntolerance, Condition, DiagnosticReport, DocumentReference, Observation, QuestionnaireResponse]: [FamilyMemberHistory.reasonReference]
[AllergyIntolerance, Condition, DocumentReference, FamilyMemberHistory, Immunization, Media, Observation, Procedure]: [AdverseEvent.subjectMedicalHistory]
[AllergyIntolerance, Condition]: [ClinicalImpression.problem]
[Appointment, AppointmentResponse, CarePlan, ServiceRequest, Task]: [ImagingStudy.basedOn]
[Appointment, CommunicationRequest, DeviceRequest, ImmunizationRecommendation, MedicationRequest, NutritionOrder, RequestGroup, ServiceRequest, Task, VisionPrescription]: [CarePlan.activity.reference]
[CarePlan, DeviceRequest, ImmunizationRecommendation, MedicationRequest, NutritionOrder, ServiceRequest]: [Observation.basedOn]
[CarePlan, ImmunizationRecommendation, MedicationRequest, NutritionOrder, ServiceRequest]: [DiagnosticReport.basedOn]
[CarePlan, ImmunizationRecommendation, MedicationRequest, ServiceRequest]: [MedicationRequest.basedOn]
[CarePlan, MedicationRequest, ServiceRequest]: [MedicationStatement.basedOn, ServiceRequest.basedOn]
[CarePlan, RequestGroup]: [GuidanceResponse.result]
[CarePlan, ServiceRequest]: [Media.basedOn, Procedure.basedOn, QuestionnaireResponse.basedOn]
[Claim, DocumentReference, Observation, Procedure, QuestionnaireResponse, ServiceRequest]: [DeviceUseStatement.derivedFrom]
[ClaimResponse, Coverage]: [DeviceRequest.insurance, MedicationRequest.insurance, ServiceRequest.insurance, Task.insurance]
[ClinicalImpression, DiagnosticReport, Observation]: [Condition.stage.assessment]
[Composition, DiagnosticReport, DocumentReference]: [Procedure.report]
[Condition, DiagnosticReport, DocumentReference, Media, Observation]: [DeviceUseStatement.reasonReference, ImagingStudy.reasonReference]
[Condition, DiagnosticReport, DocumentReference, Observation, Procedure]: [Procedure.re
Eric Haas (May 09 2019 at 19:14):
- Do we now get a limited set of references we can use.
- I don’t think having to remember what in the actor list or the event list is a step into the light.
- How does this set of options carry over into an implementation where I support only two of the three things.
- what is the cost of this change when applied.
Grahame Grieve (May 09 2019 at 19:36):
Grahame Grieve (May 09 2019 at 19:46):
@Eric Haas
- if you want
- well, it allows you to delegate the choice, where that's appropriate - that saves you time, if you want to be saved time
- you can constrain it in an implementation
- I won't be charging you any $$ for this
Eric Haas (May 09 2019 at 20:28):
:-)
Abbie Watson (Jun 13 2019 at 17:58):
Resource referencing contains entropic information about how each resource differs, and is part of what makes each resource unique. We’ve been using a lossy/handwavy schema definitions in our client under the idea of “be explicit when sending data, and be permissive when accepting it”. So, we’ve effectively made all the resources references consistent at a lowest-common denominator. And we lose a lot of functionality by doing so. Those differing sets were hard-won through years of meetings and review. Shouldn’t toss out the baby with the bath water.
Last updated: Apr 12 2022 at 19:14 UTC