Skip to content

Commit

Permalink
Merge pull request #796 from aehrc/issue/692
Browse files Browse the repository at this point in the history
Issue/692
  • Loading branch information
fongsean authored May 20, 2024
2 parents 676fafe + 642535f commit 9cfd492
Show file tree
Hide file tree
Showing 12 changed files with 309 additions and 51 deletions.
4 changes: 2 additions & 2 deletions apps/smart-forms-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
"homepage": "https://github.com/aehrc/smart-forms#readme",
"dependencies": {
"@aehrc/sdc-assemble": "^1.2.0",
"@aehrc/sdc-populate": "^1.9.0",
"@aehrc/smart-forms-renderer": "^0.28.0",
"@aehrc/sdc-populate": "^2.0.1",
"@aehrc/smart-forms-renderer": "^0.29.0",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@fontsource/material-icons": "^5.0.16",
Expand Down
14 changes: 12 additions & 2 deletions documentation/docs/sdc/advanced/fundamental.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,24 @@ Multiple initial values can be used in repeating items. There can only be one in

#### Basic Usage

<IframeContainer storyUrl="https://smartforms.csiro.au/storybook/index.html?path=/story/component-sdc-8-1-4-advanced-other--read-only">
<IframeContainer storyUrl="https://smartforms.csiro.au/storybook/index.html?path=/story/component-sdc-9-1-4-form-behavior-other-control--initial-single">
<iframe
src="https://smartforms.csiro.au/storybook/iframe.html?args=&id=component-sdc-8-1-4-advanced-other--read-only"
src="https://smartforms.csiro.au/storybook/iframe.html?args=&id=component-sdc-9-1-4-form-behavior-other-control--initial-single"
width="100%"
height="100"
/>
</IframeContainer>

#### Repeats Usage

<IframeContainer storyUrl="https://smartforms.csiro.au/storybook/index.html?path=/story/component-sdc-9-1-4-form-behavior-other-control--initial-repeats">
<iframe
src="https://smartforms.csiro.au/storybook/iframe.html?args=&id=component-sdc-9-1-4-form-behavior-other-control--initial-repeats"
width="100%"
height="390"
/>
</IframeContainer>

### Hidden

Allows the item to be hidden from the user interface.
Expand Down
254 changes: 249 additions & 5 deletions documentation/docs/sdc/population.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import IframeContainer from '../../src/react/IframeContainer';

Pre-population is a mechanism to pre-fill form questions with information already present in the clinical system. It is a way to reduce the burden on the user to fill in information that is already known.

For a detailed explanation, see the [Form Population](https://hl7.org/fhir/uv/sdc/populate.html) section in the SDC spec.
For a detailed explanation, see the [Form Population](https://hl7.org/fhir/uv/sdc/populate.html) section in the SDC spec. Smart Forms supports [expression-based population](http://hl7.org/fhir/uv/sdc/populate.html#expression-based-population).

The elements/extensions that fall under this category are:

Expand Down Expand Up @@ -90,7 +90,7 @@ Below is an example of how a variable extension using the `application/x-fhir-qu
It specifies a variable called "Condition" and it's value is to be retrieved by executing the query `Condition?patient={{%patient.id}}` on the launching system.
`{{%patient.id}}` is a reference to a defined launchContext, which will be replaced with the actual patient ID before the query is executed.

After the query is executed, the expression can be consumed by pre-population expressions during the pre-population process.
After the query is executed, the expression can be consumed by initialExpressions during the pre-population process.

```json
{
Expand All @@ -107,7 +107,193 @@ For usages, refer to initial, initialExpression, and calculatedExpression sectio

### SourceQueries

[//]: # 'TODO'
The sourceQueries extension is used to contain a reference pointing to a [batch/transaction](http://hl7.org/fhir/R4/http.html#transaction) bundle containing queries to be executed against the FHIR server during pre-population.

According to the SDC spec, the sourceQueries extension is meant to be used in [StructureMap-based population](http://hl7.org/fhir/uv/sdc/populate.html#structuremap-based-population) and not [Expression-based population](http://hl7.org/fhir/uv/sdc/populate.html#expression-based-population).
Smart Forms supports the use of sourceQueries in Expression-based population for backward-compatibility of previously-defined questionnaires.
It is encouraged to use the extensions defined in http://hl7.org/fhir/uv/sdc/populate.html#expression-based-population to be conformant.

#### Example

Below is an example of how the sourceQueries extension is defined in the questionnaire, and how an initialExpression can consume it.
Note that this uses a expression-based population mechanism.

It specifies a sourceQueries extension which references a contained batch resource called "PrePopQuery".
During pre-processing, `{{%patient.id}}` instances in the batch will be replaced with the actual patient ID before the query is executed.

```json
{
"resourceType": "Questionnaire",
// ...
"contained": [
{
"resourceType": "Bundle",
"id": "PrePopQuery",
"type": "batch",
"entry": [
{
"fullUrl": "urn:uuid:38a25157-b8e4-42e4-9525-7954fed52553",
"request": {
"method": "GET",
"url": "Observation?code=8302-2&_count=1&_sort=-date&patient={{%patient.id}}"
}
}
]
}
],
"extension": [
{
"url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-sourceQueries",
"valueReference": {
"reference": "#PrePopQuery"
}
}
]
}
```

After the batch query is executed, it can be consumed by initialExpressions during the pre-population process like a regular Bundle resource.

```json
{
"url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression",
"valueExpression": {
"language": "text/fhirpath",
"expression": "%PrePopQuery.entry[0].resource.entry.resource.value.value"
}
}
```

#### Basic Usage

<IframeContainer storyUrl="https://smartforms.csiro.au/storybook/index.html?path=/story/component-sdc-12-form-population--source-queries-bmi-calculator">
<iframe
src="https://smartforms.csiro.au/storybook/iframe.html?args=&id=component-sdc-12-form-population--source-queries-bmi-calculator"
width="100%"
height="310"
/>
</IframeContainer>

:::tip

Use the "Pre-populate form" button in the usage examples on this page to see pre-population in action.

:::

### ItemPopulationContext

The itemPopulationContext extension is used to define a context that is available for use in initialExpressions during the pre-population process.
In simple terms, it acts as a variable used to aid in pre-population. It is especially useful for pre-populating repeating groups.

For more information, refer to http://hl7.org/fhir/uv/sdc/expressions.html#itemPopulationContext.

#### Example

Below is an example of how the itemPopulationContext extension is defined, and how initialExpressions can consume it.
This is notably an example of pre-populating an [AU Core](https://build.fhir.org/ig/hl7au/au-fhir-core/) patient's home address repeating group.

```json
{
"extension": [
{
"url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-itemPopulationContext",
"valueExpression": {
"name": "HomeAddressRepeat",
"language": "text/fhirpath",
"expression": "%patient.address.where(use='home' and (type.empty() or type!='postal'))" // %patient is a reference to a launchContext patient resource
}
}
],
"linkId": "home-address-repeat-group",
"type": "group",
"repeats": true,
"item": [
{
"extension": [
{
"url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression",
"valueExpression": {
"language": "text/fhirpath",
"expression": "%HomeAddressRepeat.select(line.join(', '))"
}
}
],
"linkId": "street-address",
"definition": "http://hl7.org.au/fhir/StructureDefinition/au-address#Address.line",
"text": "Street address",
"type": "string"
},
{
"extension": [
{
"url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression",
"valueExpression": {
"language": "text/fhirpath",
"expression": "%HomeAddressRepeat.city"
}
}
],
"linkId": "city",
"definition": "http://hl7.org.au/fhir/StructureDefinition/au-address#Address.city",
"text": "City",
"type": "string"
},
{
"extension": [
{
"url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression",
"valueExpression": {
"language": "text/fhirpath",
"expression": "%HomeAddressRepeat.state"
}
}
],
"linkId": "state",
"definition": "http://hl7.org.au/fhir/StructureDefinition/au-address#Address.state",
"text": "State",
"type": "choice",
"answerValueSet": "https://healthterminologies.gov.au/fhir/ValueSet/australian-states-territories-2"
},
{
"extension": [
{
"url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression",
"valueExpression": {
"language": "text/fhirpath",
"expression": "%HomeAddressRepeat.postalCode"
}
}
],
"linkId": "postcode",
"definition": "http://hl7.org.au/fhir/StructureDefinition/au-address#Address.postalCode",
"text": "Postcode",
"type": "string"
}
]
}
```

This example is available in Storybook under **Repeat Group Usage**.

#### Repeat Group Usage

<IframeContainer storyUrl="https://smartforms.csiro.au/storybook/index.html?path=/story/component-sdc-12-form-population--item-population-context-home-address">
<iframe
src="https://smartforms.csiro.au/storybook/iframe.html?args=&id=component-sdc-12-form-population--item-population-context-home-address"
width="100%"
height="550"
/>
</IframeContainer>

#### Group Table Usage

<IframeContainer storyUrl="https://smartforms.csiro.au/storybook/index.html?path=/story/component-sdc-12-form-population--item-population-context-medical-history">
<iframe
src="https://smartforms.csiro.au/storybook/iframe.html?args=&id=component-sdc-12-form-population--item-population-context-medical-history"
width="100%"
height="700"
/>
</IframeContainer>

### Initial

Expand All @@ -125,10 +311,68 @@ Multiple initial values can be used in repeating items. There can only be one in

#### Basic Usage

<IframeContainer storyUrl="https://smartforms.csiro.au/storybook/index.html?path=/story/component-sdc-8-1-4-advanced-other--read-only">
<IframeContainer storyUrl="https://smartforms.csiro.au/storybook/index.html?path=/story/component-sdc-9-1-4-form-behavior-other-control--initial-single">
<iframe
src="https://smartforms.csiro.au/storybook/iframe.html?args=&id=component-sdc-9-1-4-form-behavior-other-control--initial-single"
width="100%"
height="100"
/>
</IframeContainer>

#### Repeats Usage

<IframeContainer storyUrl="https://smartforms.csiro.au/storybook/index.html?path=/story/component-sdc-9-1-4-form-behavior-other-control--initial-repeats">
<iframe
src="https://smartforms.csiro.au/storybook/iframe.html?args=&id=component-sdc-9-1-4-form-behavior-other-control--initial-repeats"
width="100%"
height="390"
/>
</IframeContainer>

### InitialExpression

Allows one or more values to be pre-filled in the answer by evaluating its expression when it goes through the pre-population process.

It relies on a source FHIR server, extensions defining pre-population queries i.e. launchContext, x-fhir-query variables, sourceQueries or itemPopulationContext, as well as FHIRPath evaluation to provide the initial values.

For more information, refer to http://hl7.org/fhir/uv/sdc/expressions.html#initialExpression.

#### Basic Usage

<IframeContainer storyUrl="https://smartforms.csiro.au/storybook/index.html?path=/story/component-sdc-12-form-population--initial-expression">
<iframe
src="https://smartforms.csiro.au/storybook/iframe.html?args=&id=component-sdc-8-1-4-advanced-other--read-only"
src="https://smartforms.csiro.au/storybook/iframe.html?args=&id=component-sdc-12-form-population--initial-expression"
width="100%"
height="100"
/>
</IframeContainer>

Besides this basic usage, all the usage examples on this page utilizes InitialExpressions for pre-population.

### CalculatedExpression

CalculatedExpressions can be used in conjunction with InitialExpressions to calculate a value based on the initial values provided.

For information related to using calculatedExpressions without pre-population, refer to [Calculations](/smart-forms/docs/sdc/calculations#calculatedexpression).

In the two usage examples below, the final result i.e. BMI and CVD risk score are calculated based on the pre-populated initial values.

#### BMI Calculation Usage

<IframeContainer storyUrl="https://smartforms.csiro.au/storybook/index.html?path=/story/component-sdc-12-form-population--calculated-expression-bmi-calculator-prepop">
<iframe
src="https://smartforms.csiro.au/storybook/iframe.html?args=&id=component-sdc-12-form-population--calculated-expression-bmi-calculator-prepop"
width="100%"
height="310"
/>
</IframeContainer>

#### Absolute Cardiovascular Risk Calculation usage

<IframeContainer storyUrl="https://smartforms.csiro.au/storybook/index.html?path=/story/component-sdc-12-form-population--calculated-expression-cvd-risk-calculator-prepop">
<iframe
src="http://localhost:6006/iframe.html?args=&id=component-sdc-12-form-population--calculated-expression-cvd-risk-calculator-prepop"
width="100%"
height="960"
/>
</IframeContainer>
2 changes: 1 addition & 1 deletion documentation/docs/sdc/terminology.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ There are two ways to define an answerValueSet:

2. Referencing a ValueSet defined in a [contained resource](https://hl7.org/fhir/r4/references.html#contained)

```
```json
{
"resourceType": "Questionnaire",
// ...
Expand Down
23 changes: 5 additions & 18 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/sdc-populate/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aehrc/sdc-populate",
"version": "2.0.0",
"version": "2.0.1",
"description": "Performs the $populate operation from the HL7 FHIR SDC (Structured Data Capture) specification: http://hl7.org/fhir/uv/sdc",
"main": "lib/index.js",
"scripts": {
Expand Down
Loading

0 comments on commit 9cfd492

Please sign in to comment.