Describe the bug
On the Workflow module's on-device FhirEngineRepository, value-set-filtered CQL retrieves silently return empty, so PlanDefinition/$apply and evaluateLibrary produce wrong results. For example, exists [Condition: <valueset>] evaluates to false even when the patient has a Condition coded in that value set. No error is raised — a confident wrong recommendation, which for clinical decision support is a silent safety failure.
Root cause
cqf-fhir's repository retrieve passes a value-set code filter to the data repository as an unexpanded token — code:in <ValueSet canonical URL>. FhirEngineRepository.search routes it through SearchParamMapper.applyFilterParam, which wraps that canonical URL as a literal Coding(null, <url>) token, matching nothing.
The legacy FhirEngineRetrieveProvider.filterByValueSet used to expand the value set to its member codes before searching, but that expansion was lost when the Workflow module migrated to the cqf Repository pattern. The old FhirEngineRetrieveProvider / FhirEngineTerminologyProvider files remain in the tree but entirely commented out, behind a // TODO: These operators must be migrated to equivalent calls in the Repository classes note — i.e. an incomplete migration.
To reproduce
- Store a
Patient and a Condition coded with a member of some value set.
- Index that
ValueSet in the KnowledgeManager.
- Evaluate a tiny CQL library doing
exists [Condition: "<that value set>"] via FhirOperator.evaluateLibrary (or a PlanDefinition/$apply that depends on it) on-device.
- The retrieve returns empty and the expression evaluates to
false.
(A minimal generic reproducer test is included in the PR below.)
Expected behavior
The retrieve resolves and expands the value set to its member codes and matches the Condition (parity with the legacy filterByValueSet).
Proposed fix
In FhirEngineRepository, detect a value-set code token, resolve the ValueSet via the KnowledgeManager, expand it to member codings (preferring expansion.contains, falling back to compose.include.concept), and search by those codes — mirroring the legacy behavior, applied where the code now actually runs.
A PR with the fix and a reproducer test is up: #2965.
Describe the bug
On the Workflow module's on-device
FhirEngineRepository, value-set-filtered CQL retrieves silently return empty, soPlanDefinition/$applyandevaluateLibraryproduce wrong results. For example,exists [Condition: <valueset>]evaluates tofalseeven when the patient has aConditioncoded in that value set. No error is raised — a confident wrong recommendation, which for clinical decision support is a silent safety failure.Root cause
cqf-fhir's repository retrieve passes a value-set code filter to the data repository as an unexpanded token —
code:in <ValueSet canonical URL>.FhirEngineRepository.searchroutes it throughSearchParamMapper.applyFilterParam, which wraps that canonical URL as a literalCoding(null, <url>)token, matching nothing.The legacy
FhirEngineRetrieveProvider.filterByValueSetused to expand the value set to its member codes before searching, but that expansion was lost when the Workflow module migrated to the cqfRepositorypattern. The oldFhirEngineRetrieveProvider/FhirEngineTerminologyProviderfiles remain in the tree but entirely commented out, behind a// TODO: These operators must be migrated to equivalent calls in the Repository classesnote — i.e. an incomplete migration.To reproduce
Patientand aConditioncoded with a member of some value set.ValueSetin theKnowledgeManager.exists [Condition: "<that value set>"]viaFhirOperator.evaluateLibrary(or aPlanDefinition/$applythat depends on it) on-device.false.(A minimal generic reproducer test is included in the PR below.)
Expected behavior
The retrieve resolves and expands the value set to its member codes and matches the
Condition(parity with the legacyfilterByValueSet).Proposed fix
In
FhirEngineRepository, detect a value-set code token, resolve theValueSetvia theKnowledgeManager, expand it to member codings (preferringexpansion.contains, falling back tocompose.include.concept), and search by those codes — mirroring the legacy behavior, applied where the code now actually runs.A PR with the fix and a reproducer test is up: #2965.