Stream: shorthand
Topic: Is this differential correct?
Jean Duteau (Jul 09 2021 at 15:42):
I have an error when the publisher runs against my IG which I've raised in a different thread. But I'm wondering if the differential that is being produced for my profile is correct. Here is my FSH:
* careTeam MS
* careTeam.extension contains CareTeamClaimScope named careTeamClaimScope 1..1 MS
* careTeam.sequence MS
* careTeam.provider MS
* careTeam.provider only Reference(PASPractitioner or PASOrganization)
* careTeam.role MS
* careTeam ^slicing.discriminator.type = #value
* careTeam ^slicing.discriminator.path = "extension('http://hl7.org/fhir/us/davinci-pas/StructureDefinition/extension-careTeamClaimScope').valueBoolean"
* careTeam ^slicing.rules = #open
* careTeam ^slicing.description = "Slice based on whether the care team member belongs to the overall claim or to an individual claim item."
* careTeam contains OverallClaimMember 0..14 and ItemClaimMember 0..10
I also have the two different slice info that I didn't include. Here is what I'm getting in the differential and it seems strange.
For the extension:
{
"id": "Claim.careTeam.extension",
"path": "Claim.careTeam.extension",
"slicing": {
"discriminator": [
{
"type": "value",
"path": "url"
}
],
"ordered": false,
"rules": "open"
},
"min": 1
},
{
"id": "Claim.careTeam.extension:careTeamClaimScope",
"path": "Claim.careTeam.extension",
"sliceName": "careTeamClaimScope",
"min": 1,
"max": "1",
"type": [
{
"code": "Extension",
"profile": [
"http://hl7.org/fhir/us/davinci-pas/StructureDefinition/extension-careTeamClaimScope"
]
}
],
"mustSupport": true
},
For the slices:
{
"id": "Claim.careTeam:OverallClaimMember",
"path": "Claim.careTeam",
"sliceName": "OverallClaimMember",
"min": 0,
"max": "14"
},
{
"id": "Claim.careTeam:OverallClaimMember.extension:careTeamClaimScope",
"path": "Claim.careTeam.extension",
"sliceName": "careTeamClaimScope"
},
{
"id": "Claim.careTeam:OverallClaimMember.extension:careTeamClaimScope.valueBoolean",
"path": "Claim.careTeam.extension.valueBoolean",
"min": 0,
"max": "1",
"patternBoolean": true
},
I will admit to not completely understanding how extensions and slicing interact in differentials, so I'm really just looking for confirmation that SUSHI is generating this correctly.
Chris Moesel (Jul 09 2021 at 16:06):
To be honest, I'm not sure. I don't know if each slice on Claim.careTeam
should be redeclaring the careTeamClaimScope
sliceName within their own slice or not (e.g., in your last code snippet, should that second element be there?). I think it's right -- because technically a tool should be able to process a differential _without_ looking at the id
(using path
only) - which is why, in general, we need to declare slicenames in a differential even when they are inherited from a parent. So I think that's right -- but it is kind of tricky.
One thing that's not quite right is that you declare the discriminator type as #value
but you're using patternBoolean
to fix the value. Although I think the FHIR core team is considering eliminating the distinction between #value
and #pattern
in R5, I think they need to match in R4. So either change the discriminator type to #pattern
or change the assignment to use (exactly)
so that fixedBoolean
is used rather than patternBoolean
.
Jean Duteau (Jul 09 2021 at 16:12):
Thanks for the info. I did change that to (exactly) and it didn't make my error go away. :) It is a strange difference for primitive types - saying that my boolean has to have a pattern of true is pretty much the same thing as saying it's fixed to true.
Jean Duteau (Jul 09 2021 at 16:23):
After looking at the code, I think that the 2nd element you identified isn't correct:
{
"id": "Claim.careTeam:OverallClaimMember.extension:careTeamClaimScope",
"path": "Claim.careTeam.extension",
"sliceName": "careTeamClaimScope"
},
The code assumes that if there is a child element with a path that ends in '.extension' and has a 'sliceName', that it has a type with a profile:
StructureDefinition exsd = worker.fetchResource(StructureDefinition.class, t.getType().get(0).getProfile().get(0).getValue());
This is right for the first definition of the extension but, if it is looking here, it fails.
Jean Duteau (Jul 09 2021 at 16:47):
I just overrode the profile and added in the type information to that extension declaration and the publisher processed the validation fine, so I think this is a SUSHI bug that I'll raise.
Chris Moesel (Jul 09 2021 at 17:08):
Hmm... interesting... IMO, the type should not be necessary, as the type should fallback (or inherit) from the base element being sliced. We've already declared the extension slice and its corresponding type. I do not know why we need to declare the type again. That said, this stuff is tricky, and perhaps the type is needed just to keep the tooling sane. Thanks for logging the bug -- hopefully the fix is not too difficult!
saying that my boolean has to have a pattern of true is pretty much the same thing as saying it's fixed to true
I guess it depends on your definition of "pretty much". Remember that in FHIR, primitives are still elements, capable of holding an id
and extension
-- so when you use pattern
, you allow for the data to additionally carry an id
or extension
; when you use fixed
you're saying those cannot be present.
Jean Duteau (Jul 09 2021 at 17:51):
I always raised an issue on the publisher side in case that code should be changed.
Lloyd McKenzie (Jul 09 2021 at 19:34):
I think the element should be .value and the id should be .value:valueBoolean
Last updated: Apr 12 2022 at 19:14 UTC