# Architectural Guidance - Common CQL Artifacts for FHIR (US-Based) v1.0.0

* [**Table of Contents**](toc.md)
* **Architectural Guidance**

## Architectural Guidance

| |
| :--- |
| *Page standards status:*[Informative](http://hl7.org/fhir/R4/versions.html#std-process) |

This topic provides architectural guidance for implementers supporting FHIR and CQL-based questionnaires, typically from a DTR-style application.

This discussion assumes the following:

* A Questionnaire resource with any number of `item` elements, nested to any degree
* A Questionnaire may include any number of `initialExpression`, `candidateExpression` and `calculatedExpression` extensions referencing CQL expressions to be evaluated

This guidance is provided as a complement to the conformance expectations and guidance described in [Pre-populating QuestionnaireResponses](https://hl7.org/fhir/us/davinci-dtr/specification.html#pre-populating-questionnaireresponses) in the DTR implementation guide.

### Initial Data Retrieval

#### Data Access Within CQL

All data access within CQL occurs within the [Retrieve](https://cql.hl7.org/02-authorsguide.html#retrieve) expression. When CQL is packaged within a Library resource, these retrieves are surfaced as `dataRequirement` elements according to the mapping defined in the [Data Requirements](http://hl7.org/fhir/uv/cql/STU2/conformance.html#parameters-and-data-requirements) of the Using CQL With FHIR IG. These data requirements allow the complete data expectations for the CQL within the library to be communicated. However, these elements in the Library resource represent the total data requirements for the library, whereas the Questionnaire may only reference some of the expressions in the library, or the initial state of the Questionnaire may be such that only a subset of questions are enabled and therefore need population.

To address this, static analysis of the CQL can be used to determine the set of data requirements for an expression (or set of expressions), as described in the [Artifact Data Requirements](https://cql.hl7.org/05-languagesemantics.html#artifact-data-requirements) section of the CQL specification. The [DataRequirementsProcessor](https://github.com/cqframework/clinical_quality_language/blob/master/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/fhir/DataRequirementsProcessor.java) provides an implementation of this capability. This component can accept a list of the expressions that should be analyzed to determine data requirements.

Note that this process of analyzing data requirements is simplified by the practice of having all the expressions in a given questionnaire reference a single CQL library, the "primary artifact library". This approach is used in measure development and provides a way to organize content per artifact. Expressions from other libraries can still be used, but must be referenced by declaring a passthrough expression in the primary artifact library. This can be an undue burden for questionnaire authors, so this is not considered best-practice for questionnaires. However, all the examples in this implementation guide take this approach to simplify data requirements analysis processing.

In addition to gathering the **effective** data requirements through dependency tracing of specific expressions, data requirements can be **collapsed** (i.e. minimized to eliminate duplicate or overlapping requests). These techniques can be combined to ensure that applications can minimize the number of queries used to retrieve data necessary to evaluate the CQL logic within the questionnaire.

### Additional Data Retrieval and Flow Control

* Managing queries that depend on user-entered data
* Managing when queries need to be re-run
* Guidance on adaptive query capabilities

TODO: Provide guidance about making the determination between sending libraries up front versus questionnaire specific libraries (https://hl7.org/fhir/us/davinci-dtr/specification.html#adaptive-form-considerations)

### Terminology Considerations

https://hl7.org/fhir/us/davinci-dtr/specification.html#value-set-and-code-system-guidance

Note that questionnaires may reference value sets that are not included in the questionnaire package. In particular, best practice for value sets that do not have expansions (for example because the value set definition is more concisely expressed as a condition, or the value set is too large) is that they not be included in the questionnaire package.

Value set references will be encountered in two different ways in CQL used by a Questionnaire:

1. Within`retrieve`expressions, as the terminology filter
1. Outside of retrieves, as part of a value set membership test

In both cases, the required terminology will need to be made available to the CQL engine. Different approaches can be taken by different CQL engines, but in general they follow:

1. Provide pre-expanded value sets to the engine
1. Provide a terminology service interface to the engine, allowing value sets to be expanded on demand

The first approach is somewhat simpler, though may be less performant, especially when the number and/or size of the value sets is large.

In addition, for performance, the second approach will likely be implemented with caching.

As well, depending on the sensitivity of the questions to updates in code systems, the expansion of value sets used may need to be performed with version-specific references to the code systems and value sets involved.

When questionnaires and CQL libraries reference value sets, they may do so with a version-specific, or a version-independent reference. CQL libraries often use version-independent references for value sets to minimize the maintenance overhead involved in updating value set versions. To establish the versions of value sets referenced in this way, a [Version Manifest](http://hl7.org/fhir/uv/crmi/STU1/version-manifest.html) may be used if there is a need to indicate a specific version for a particular deployment.

When a value set reference appears within a `retrieve`, the corresponding DataRequirement will include the value set reference. For example:

```
define "Glucose Tests":
  [Observation: "Glucose Test Codes"]

```

```
{
    "type": "Observation",
    "codeFilter": [{
        "path": "code",
        "valueSet": "http://example.org/ValueSet/glucose-test-codes"
    }]
}

```

This data requirement can be satisfied with an appropriate FHIR query:

```
[base]/Observation?subject=Patient/123&code:in=http://example.org/ValueSet/glucose-test-codes

```

However, use of this approach requires that the EHR's FHIR server 1) supports the `:in` modifier for code-based searches, 2) either has or can get the Glucose Test Codes value set, and 3) can perform (or ask for) an appropriate expansion of the value set. To address the situation where the EHR does not or cannot support code-based searching with value sets, the query may be executed by either:

1. Choosing a less-selective filter (such as`category=laboratory`in this case) (or no filter at all) and then filtering the result in the CQL

```
[base]/Observation?subject=Patient/123&category=laboratory

```

2. Performing the expansion and in-lining the codes

```
[base]/Observation?subject=Patient/123&code=12345,23456,34567

```

> Note that when in-lining large value sets, the resulting search may overflow practical URL length restrictions. In these cases, a POST may be used, and/or the query may be split into multiple requests and combined.

### Performant Data Access

As with any data processing application, when processing CQL, accessing the data often takes the majority of the time. As such, ensuring performant data access is a key aspect of delivering performant applications that make use of CQL.

When retrieving the set of data required to evaluate a CQL expression, the search parameter to use may vary depending on the capabilities of the server being accessed. For example, the `code` search parameter for Condition resources is optional in USCore, so systems may not support that as an access path. In these cases, applications can make use of a [Module Configuration Library](http://hl7.org/fhir/uv/crmi/STU1/StructureDefinition-crmi-moduleconfigurationlibrary.html) to provide alternative FHIR queries.

For example, given a CQL retrieve expression requesting Conditions from a particular value set:

```
define "Diabetes Conditions":
  [Condition: "Diabetes"]

```

When accessing this data from a server that does not support the `Condition.code` search parameter, a less-selective filter may be used initially:

```
[base]/Condition?category=problem-list-item

```

followed by subsequent filtering locally based on the `"Diabetes"` value set.

In addition, multi-threading requests to the server can reduce the overall time required to retrieve the data.

### Conventions

As with any content development effort, to facilitate readability and maintainability of CQL, best-practice is to follow and contribute to the conventions established by the community:

* **[Conventions](https://cql.hl7.org/14-g-formattingconventions.html)**: Overall formatting conventions and best practices
* **[Using CQL](http://hl7.org/fhir/uv/cql/STU2/using-cql.html)**: Best-practices and conformance requirements for using CQL with FHIR
* **[Well-known Documentation Tags](https://github.com/cqframework/clinical_quality_language/wiki/Well-Known-CQL-Documentation-Tags)**

