Skip to main content

Creating Custom FHIR Transformation Services

Overview of Custom FHIR Transformation Services

Custom FHIR® Transformations allow users to define the transformations that will take place when converting HL7 or CCD messages to v4 FHIR bundles. Users can also define pre-transformations for HL7 and CCD and post-transformations for FHIR bundles. The following diagrams outline the workflows for converting from both HL7 and CCD.

When converting from HL7, DTL is used for both the pre- and post-transformations:

When converting from CCD, XSL is used for the pre-transformation and DTL is used for the post-transformation:

Uploading Custom Components

  1. In the InterSystems® Cloud Services Portal, select your FHIR Transformation Services deployment, then select Files from the left menu.

  2. Select Upload File and then choose a file from your machine to upload. The uploaded files are stored in an s3 bucket with the name [deployment_id]-buffer.

    Note:

    Only .cls, .xml, and .xsl files are supported.

  3. Once you have uploaded all the necessary files, select Update Configuration to restart the deployment with the updated components.

portal with FTS files tab selected and opened

Custom Lookup Tables

For each transformation, users should create the following lookup tables. In each example [source] should be replaced with a name that specifies the data source and [client] should be replaced with a name that specifies the client that will be receiving the transformed data:

Metadata

This table determines the data source, the recipient, and the metadata values that should be included in the FHIR bundles. See the following example, filling in [source] and [client] with the values that match the mapping table values for source and client. The meta-source, meta-xyz, and vendor-source-id values are only required if you are including the meta elements in each resource of the FHIR bundle.

<Document name="Metadata.LUT">
<lookupTable>
<entry table="Metadata" key="site">[source]</entry>
<entry table="Metadata" key="client">[client]</entry>
<entry table="Metadata" key="meta-source">[desired-meta-source]</entry>
<entry table="Metadata" key="meta-xyz">[desired-meta-xyz]</entry>
<entry table="Metadata" key="vendor-source-id">[ISC-or-other-vendor]</entry>
</lookupTable>
</Document>
[source]

This table is used to define the schema that should be applied to all inbound messages. If nothing is defined, the HL7 2.5.1 schema is used.

<Document name="[source].LUT">
<lookupTable>
<entry table="[source]" key="Schema">[source]To[client]251</entry>
</lookupTable>
</Document>
[source].Config.HL7Transform

This table defines the pre-transformation DTL that will be used on the inbound HL7 messages before the FTS transformation.

[source].Config.FHIRProfile

This table defines the post-transformation DTL(s) that will be used on the FHIR bundle after an FTS transformation from HL7 to FHIR.

[source].Config.CCD-FHIRProfile

This table defines the post-transformation DTL(s) that will be used on the FHIR bundle after an FTS transformation from CCD to FHIR.

HL7 to HL7 Pre-Transformation

The default FTS transformation from HL7 to FHIR expects a compliant 2.5.1 HL7 message as the input. The pre-transformation allows you to transform non-compliant HL7 messages from the source into 2.5.1 compliant messages.

The pre-transformation uses a custom lookup table that specifies a single DTL used for each message event.

The DTL must:

  • extend Ens.DataTransformDTL.

  • be in the XFUSER class package.

  • specify an IDKEY of DTL.

The custom lookup table should cover all possible message events that the data source could send. For example:

</Document>
<Document name="[Source].Config.HL7Transform.LUT">
<lookupTable>
<entry table="[Source].Config.HL7Transform" key="ADT^A01">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A02">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A03">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A04">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A05">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A06">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A07">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A08">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A09">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A10">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A11">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A12">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A13">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A14">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A15">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A16">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A17">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A18">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A20">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A21">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A22">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A23">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A24">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A25">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A26">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A27">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A28">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A29">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A30">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A31">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A32">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A33">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A34">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A35">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A36">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A37">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A38">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A39">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A40">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A41">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A42">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A43">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A44">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A45">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A46">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A47">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A48">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A49">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A50">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A51">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A52">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A53">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A54">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A55">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A60">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A61">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
<entry table="[Source].Config.HL7Transform" key="ADT^A62">XFUSER.Base.Transform.HL7ToHL7.[Source]PreTransform</entry>
</lookupTable>
</Document>

CCD to CCD Pre-Transformation

The pre-transformation CCD to CDD pre-transformation allows you to manipulate the data in an inbound CCD message into a format that can be processed by the CCD to FHIR core transformation. The custom table should point to a custom xsl document:

<Document name="[client-or-site].Config.CCD-PreTransform.LUT">
   <lookupTable>
      <entry table="[client-or-site].Config.CCD-PreTransform" key="CCDA">/SDA3/Custom/[client-or-site]_PreTransform_CCD.xsl</entry>
   </lookupTable>
</Document>

The key value must be "CCDA" and the xsl path must be "/SDA3/Custom/[client-or-site]_PreTransform_CCD.xsl".

FHIR to FHIR Post-Transformation

The FHIR-to-FHIR post-transformation allows you to convert the standard FHIR output messages to different FHIR outputs that have had one or more profiles applied.

The post-transformation uses a custom lookup table that specifies a DTL. The same DTL can be for the FHIR-to-FHIR post-transformation after either HL7-to-FHIR transformations or CCD-to-FHIR transformations. However, separate lookup tables must be used for each.

The DTL must:

  • extend Ens.DataTransformDTL.

  • be in the XFUSER class package.

  • specify an IDKEY of DTL.

HL7 example:

<Document name="[client-or-site].Config.FHIRProfile.LUT">
<lookupTable>
<entry table="[client-or-site].Config.FHIRProfile" key="[KeyName]">XFUSER.Base.Transform.FHIRToFHIR.Custom.[Source].Bundle</entry>
</lookupTable>
</Document>

CCD example:

<Document name="[client-or-site].Config.CCD-FHIRProfile.LUT">
<lookupTable>
<entry table="[client-or-site].Config.CCD-FHIRProfile" key="[KeyName]">XFUSER.Base.Transform.FHIRToFHIR.Custom.[Source].Bundle</entry>
</lookupTable>
</Document>

If the lookup table contains multiple profiles (entries), the entries will be run in alphabetical order using the key value. If you want to change the order in which the profiles are run, modify the key values, so they are ordered alphabetically. The key value is not used for anything else in this process.

All profiles found at either the site or client level will be run, so it is not recommended to include the same entries on both tables.

US Core FHIR to FHIR Post-Transformation

FHIR Transformation Services offers an out-of-the-box US Core FHIR to FHIR post-transformation. To enable the US Core profile as part of a site’s post process, include the XF.Base.Transform.FHIRToFHIR.USCvR4.Bundle class either or both of the Config.FHIRProfile and Config.CCD-FHIRProfile table entries. For example:

<entry table="[site or client].Config.CCD-FHIRProfile" key="USCore">XF.Base.Transform.FHIRToFHIR.USCvR4.Bundle</entry>

This post-transformation uses the HL7 FHIR US Core Implementation GuideOpens in a new tab. It implements the Mandatory requirements and does not attempt to enforce the Must Support items.

FeedbackOpens in a new tab