Skip to content

Commit 1ac1a20

Browse files
authored
Merge pull request #97 from Ardenexal/feat/sdc-docs
Implement `$populate` operation for SDC and update documentation
2 parents 169d473 + 19ecc4c commit 1ac1a20

4 files changed

Lines changed: 39 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
- [SDC] `$extract` supports version-agnostic definition/template extraction (R4/R4B/R5), `extractAllocateId` cross-resource references, fixed-value + FHIRPath calculated values, and choice slices; observation-based extraction is R4-only (non-R4 runs warn and skip)
1313
- [SDC] `$extract` output is always a `transaction` Bundle — `entry.request` is `POST Type` (no id) or `PUT Type/id` (id present), create/update only; mixed-method Questionnaires merge into one Bundle; empty extraction yields an empty Bundle plus an `information` `OperationOutcome`, and a malformed expression warns and skips that entry
1414
- [SDC] Opt-in `Provenance` generation via `ExtractContext(emitProvenance: true)`: when resources are extracted, the Bundle gains a `Provenance` entry targeting them and referencing the source `QuestionnaireResponse` (default output omits it)
15+
- [SDC] `FHIRQuestionnairePopulateService::populate($questionnaire, new PopulateContext(...))` implements `Questionnaire/$populate`, returning a `PopulateResult` (generated `QuestionnaireResponse` + optional companion `OperationOutcome`); version-agnostic (R4/R4B/R5) and offline-first — the caller supplies launch-context resources up front, bound as FHIRPath external constants (`%patient`, …)
16+
- [SDC] `$populate` supports expression-based population (`launchContext` + `initialExpression`, root/item `variable` chains, and `itemPopulationContext` repeating groups) and observation-based population (`observationLinkPeriod`, via a `PopulationDataProviderInterface`), with canonical-URL `Questionnaire` resolution through an optional `FHIRQuestionnaireResolverInterface`
1517
- [Metadata] New `SafeExtensionReader` for tolerant extension traversal (`url`, `value[x]`, nested `extension[]`, find-by-url) that degrades to absent instead of throwing on constructor-bypassed (deserialized) objects
1618
- [FHIRPath] `EvaluationContext::withResourceNode()`/`getResourceNode()` bind `%resource`/`%rootResource` to a resource distinct from the evaluation focus
1719

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ wires everything for you.
5050
<td><a href="fhirpath/overview.md">FHIRPath</a></td>
5151
</tr>
5252
<tr>
53-
<td>SDC — extract resources from a QuestionnaireResponse (<code>$extract</code>)</td>
53+
<td>SDC — populate (<code>$populate</code>) QuestionnaireResponses and extract (<code>$extract</code>) FHIR resources</td>
5454
<td><code>ardenexal/fhir-sdc</code></td>
5555
<td><a href="sdc/overview.md">SDC</a></td>
5656
</tr>

docs/getting-started/packages.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ This is a library monorepo. Each component is published as a standalone Composer
1414
| `ardenexal/fhir-serialization` | Read/write FHIR JSON or XML |
1515
| `ardenexal/fhir-validation` | Validate resources against base and profile constraints |
1616
| `ardenexal/fhir-path` | Evaluate FHIRPath 2.0 expressions |
17-
| `ardenexal/fhir-sdc` | Run SDC `$extract`turn a completed `QuestionnaireResponse` into a transaction Bundle of FHIR resources |
17+
| `ardenexal/fhir-sdc` | Run SDC `$populate` (pre-fill a `QuestionnaireResponse` from launch context) and `$extract` (turn a completed `QuestionnaireResponse` into a transaction Bundle of FHIR resources) |
1818
| `ardenexal/fhir-models` | Use the pre-generated R4 / R4B / R5 model classes |
1919
| `ardenexal/fhir-metadata` | Shared FHIR attributes and interfaces (a dependency of the others) |
2020

docs/sdc/overview.md

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
---
2-
description: Extract FHIR resources from a completed QuestionnaireResponse.
2+
description: Populate QuestionnaireResponses and extract FHIR resources for SDC Questionnaires.
33
icon: file-export
44
---
55

66
# Overview
77

88
The SDC component implements [Structured Data Capture](https://build.fhir.org/ig/HL7/sdc/)
9-
operations for FHIR PHP model objects. Today it delivers
9+
operations for FHIR PHP model objects. Today it delivers two operations:
1010
`QuestionnaireResponse/$extract` — turning a completed `QuestionnaireResponse` into FHIR
11-
resources per the [SDC extraction operation](https://build.fhir.org/ig/HL7/sdc/en/extraction.html).
11+
resources per the [SDC extraction operation](https://build.fhir.org/ig/HL7/sdc/en/extraction.html)
12+
and `Questionnaire/$populate` — pre-filling a `QuestionnaireResponse` from launch context per the
13+
[SDC populate operation](https://build.fhir.org/ig/HL7/sdc/en/populate.html).
1214
It supports R4, R4B, and R5.
1315

14-
## Quick start
16+
## `$extract` quick start
1517

1618
```php
1719
use Ardenexal\FHIRTools\Component\Sdc\ExtractContext;
@@ -30,6 +32,27 @@ $bundle = $result->getResource(); // a transaction Bundle (always)
3032
$issues = $result->getIssues(); // an OperationOutcome, or null when nothing to report
3133
```
3234

35+
## `$populate` quick start
36+
37+
```php
38+
use Ardenexal\FHIRTools\Component\Sdc\BundlePopulationDataProvider;
39+
use Ardenexal\FHIRTools\Component\Sdc\FHIRQuestionnairePopulateService;
40+
use Ardenexal\FHIRTools\Component\Sdc\PopulateContext;
41+
use Ardenexal\FHIRTools\Component\Serialization\FhirVersion;
42+
43+
$service = new FHIRQuestionnairePopulateService();
44+
45+
$result = $service->populate($questionnaire, new PopulateContext(
46+
fhirVersion: FhirVersion::R4, // output model namespace (R4 / R4B / R5)
47+
launchContextResources: ['patient' => $patient], // bound as FHIRPath %patient, …
48+
subject: 'Patient/123', // sets QuestionnaireResponse.subject (optional)
49+
dataProvider: new BundlePopulationDataProvider($dataBundle), // observation-based (optional)
50+
));
51+
52+
$response = $result->getResponse(); // a QuestionnaireResponse (status: in-progress)
53+
$issues = $result->getIssues(); // an OperationOutcome, or null when nothing to report
54+
```
55+
3356
## What it does
3457

3558
* **Three extraction methods** — observation-based (R4 only), definition-based
@@ -44,8 +67,14 @@ $issues = $result->getIssues(); // an OperationOutcome, or null when nothing t
4467
* **Opt-in `Provenance`** — pass `emitProvenance: true` to add a `Provenance` entry linking
4568
the extracted resources back to the source `QuestionnaireResponse`.
4669

47-
`Questionnaire/$populate` is scaffolded (conformance harness in place) but has no public API
48-
yet.
70+
`Questionnaire/$populate` pre-fills a `QuestionnaireResponse` from a `Questionnaire`'s SDC
71+
population directives — expression-based (`launchContext` + `initialExpression`, `variable`
72+
chains, `itemPopulationContext`) and observation-based (`observationLinkPeriod`). Call
73+
`FHIRQuestionnairePopulateService::populate($questionnaire, new PopulateContext(...))`; the
74+
returned `PopulateResult` carries the generated `QuestionnaireResponse` (status
75+
`in-progress`) plus an optional `OperationOutcome`. Population is offline-first and
76+
FHIRPath-only — the component README is canonical for the supported-mechanisms table and
77+
exclusions.
4978

5079
## Reference
5180

0 commit comments

Comments
 (0)