Skip to content

Set resourceDefinition on instances of additional resources - #1660

Open
glichtner wants to merge 2 commits into
FHIR:masterfrom
glichtner:fix/additional-resource-definition
Open

glichtner wants to merge 2 commits into
FHIR:masterfrom
glichtner:fix/additional-resource-definition

Conversation

@glichtner

Copy link
Copy Markdown
Contributor

Summary

In FHIR R6, an instance of an additional resource carries resourceDefinition in JSON, right after resourceType: the canonical of the resource's definition, always with its version (JSON representation of additional resources, normative):

{
  "resourceType" : "ViewDefinition",
  "resourceDefinition" : "http://hl7.org/fhir/uv/sql-on-fhir/StructureDefinition/ViewDefinition|2.0.0-pre",
  "id": "a-valid-id",
  // etc
}

SUSHI does not write resourceDefinition, so the validator rejects every FSH instance of an additional resource, and the IG Publisher reports it as a QA error.

This affects, for example, IGs with instances of PublicationRecord from hl7.fhir.uv.ebm-incubator.

Example

The full example can be found here: https://github.com/glichtner/additional-resource-definition-example

A dependency package defines AdditionalRecord, a specialization of DomainResource that sets http://hl7.org/fhir/tools/StructureDefinition/additional-resource to true. The IG depends on it and contains:

Instance: example-record
InstanceOf: AdditionalRecord
Usage: #example
* title = "Example record"

Expected:

{
  "resourceType": "AdditionalRecord",
  "resourceDefinition": "http://hl7.org/fhir/StructureDefinition/AdditionalRecord|0.1.0",
  "id": "example-record",
  "title": "Example record"
}

Actual with 3.21.0:

{
  "resourceType": "AdditionalRecord",
  "id": "example-record",
  "title": "Example record"
}

The IG Publisher (3.0.2) then reports:

ERROR: AdditionalRecord/example-record: AdditionalRecord: This resource is an additional resource, so must have a resourceDefinition of 'http://hl7.org/fhir/StructureDefinition/AdditionalRecord|0.1.0'

The validator expects exactly the versioned canonical of the specialization, also for instances of a profile on the additional resource (InstanceValidator.start()). The Java JSON composer writes the property the same way: after resourceType, from the additional-resource extension of the type's StructureDefinition.

Reproduce

Example

See https://github.com/glichtner/additional-resource-definition-example. ./reproduce.sh builds the dependency with SUSHI, installs it into the package cache, and runs SUSHI on the IG. It exits with code 1 with SUSHI 3.21.0 and with code 0 with this branch (./reproduce.sh node /path/to/sushi/dist/app.js). With PUBLISHER_JAR set, it also builds the IG: one QA error with 3.21.0, none with this branch.

Tests

New tests in test/export/InstanceExporter.test.ts (#Additional Resources), each with a FSH-defined additional resource:

  • an instance gets resourceDefinition with the configured version, right after resourceType;
  • an instance of a profile on the resource gets the definition of the resource, not of the profile;
  • an explicit ^version on the resource is used;
  • without any version, resourceDefinition is the url alone;
  • an inline instance in a Bundle gets resourceDefinition too;
  • no resourceDefinition when the extension is false, or for core resources.
npx jest test/export/InstanceExporter.test.ts -t "#Additional Resources"

Without the change in src/, the first five fail and the two negative cases pass. npm run check passes (104 suites; 3,584 tests passed, 8 skipped, 7 todo).

On a real IG with a PublicationRecord instance (279 resources), the export differs from 3.21.0 only in that instance, which gains "resourceDefinition": "http://hl7.org/fhir/StructureDefinition/PublicationRecord|0.1.0-snapshot".

Fix

exportInstance() already walks from the InstanceOf definition to its specialization to check for abstract types. If that specialization has the additional-resource extension set to true, the instance gets resourceDefinition = <url>|<version>. InstanceDefinition.toJSON() orders it after resourceType.

SUSHI exports the definitions of the FSH project without a version, and the IG Publisher gives them the IG version. For those, SUSHI uses the configured version. A definition from a package uses its own version. If no version is known, the url is written alone, as the Java composer does.

In the FHIR R6 JSON format, an instance of an additional resource carries
resourceDefinition, the versioned canonical of the resource definition,
right after resourceType. SUSHI now sets it when the specialization that the
instance is based on has the additional-resource extension. For definitions
from the FSH project, which SUSHI exports without a version, it uses the
configured version, which the IG Publisher assigns to them.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant