Skip to content

Reporting Export Stamp Extension

Canonical../StructureDefinition/reporting-export-stamp
Statusdraft (experimental) · 1.26.0
BaseExtension (constraint)
ContextBundle.meta (element)
SourceFSH · JSON

The disclosure stamp an identified reporting extract carries: which custodian the file was produced for, under what declared purpose, as of what instant, and from which stored ingest position. An extract is a FHIR collection Bundle of patient stubs handed to a requester as a file rather than stored on a server, and the stamp is how the file can still be answered for once it has left.

FSH

The authored source of truth: extensions/ReportingExportStampExtension.fsh (edit on GitHub). One FSH file may define several related artifacts.

// ReportingExportStampExtension.fsh
// The disclosure stamp an identified reporting extract carries, as TYPED VALUES on `Bundle.meta`.
//
// WHAT AN EXTRACT IS. A report run can be exported as a FHIR collection Bundle of minimal Patient
// stubs -- the membership, and nothing else about any patient. That Bundle is a file handed to a
// requester, not a resource stored on a FHIR server: nothing searches it, nothing resolves it, and
// re-exporting the same run at the same anchor produces the same bytes. It carries a stamp so the
// file can still be answered for once it has left: which custodian, for what declared purpose, as
// of when, from which stored position.
//
// WHY THE STAMP RIDES `meta`. `Bundle` is not a `DomainResource` and has no `extension` element of
// its own -- `Bundle.meta` is the only place on a Bundle an extension can be carried, so that is
// where this one is contexted. Nothing is given up by that choice here. The usual reason to prefer
// `meta.tag` over `meta.extension` is `_tag` search, and an extract is a file that no server
// searches.
//
// WHY THE VALUES ARE ELEMENTS AND NOT TAG LABELS. R4 defines `Coding.display` as "a representation
// of the meaning of the code in the system, following the rules of the system": it is the LABEL the
// declaring system fixes for the code, which is why a terminology service is entitled to check it
// and `$validate-code` does. A key/value bag built out of `meta.tag` codings therefore has nowhere
// to put a value -- a stamp in that shape carries field names and no facts, and a validating
// consumer gets an error where it expected a custodian. An extension has `value[x]`, which is the
// element that exists to hold a value, and a datatype to go with it.
//
// THE TYPES EARN THEIR KEEP. `asOf` is an `instant`, so a consumer parses a point in time rather
// than trusting a string, and the ambiguity a free-text date invites cannot be written in the first
// place. `purpose` is a `CodeableConcept` bound to HL7's PurposeOfUse, which is the published
// vocabulary for this exact fact and already carries codes for health quality improvement and for
// healthcare research; a purpose with no code there rides as an additional local coding or as
// `text`, which is what an extensible binding is for.
//
// THERE IS NO `run` SUB-EXTENSION, DELIBERATELY. The run is already on the Bundle, as
// `Bundle.identifier` under `NamingSystem/reporting-run`. Carrying it a second time here would give
// one fact two homes and a way to disagree with itself.
//
// TWO VALUES STAY OPAQUE, AND TYPING THEM DOES NOT CHANGE THAT. `hic` is a custodian stamp and
// `watermarkPosition` is a stored ingest position carried verbatim. Both are `string` because
// neither has a form this specification fixes; a consumer carries and correlates them and does not
// parse them.
//
// MIGRATION. Write this extension. `CodeSystem/reporting-export-stamp` named the same fields for a
// key/value carriage on `meta.tag` and is retired in favour of this. Stamps already written in the
// earlier carriage are not described here, and moving them is outstanding work.

Extension: ReportingExportStamp
Id:        reporting-export-stamp
Title:     "Reporting Export Stamp Extension"
Description: """
The disclosure stamp an identified reporting extract carries: which custodian the file was produced
for, under what declared purpose, as of what instant, and from which stored ingest position. An
extract is a FHIR collection Bundle of patient stubs handed to a requester as a file rather than
stored on a server, and the stamp is how the file can still be answered for once it has left.

**It rides `Bundle.meta`, because a `Bundle` has no `extension` of its own.** `Bundle` is not a
`DomainResource`, so `meta` is the only place on it an extension can be carried. No search is given
up by that: an extract is a file, and nothing searches it.

**The values are elements, with datatypes.** `asOf` is an `instant` and `purpose` is a
`CodeableConcept`, so a consumer reads a point in time and a code rather than text it has to
interpret. `Coding.display` is defined by R4 as a representation of the meaning of a code, fixed by
the system that declares that code, so it is not somewhere a value can be carried -- an element with
a `value[x]` is.

**The run is not here.** It is `Bundle.identifier`, under the reporting-run naming system, and that
is where a consumer reads it from. One fact, one home.

**`hic` and `watermarkPosition` are opaque.** Neither has a form this specification fixes. Carry
them, correlate them, and do not parse them; an ingest position is comparable only against another
position from the same source.

**Nothing clinical carries this.** It describes an artefact's provenance, so it appears on the
Bundle of an extract and nowhere on a patient's chart.

**MIGRATION.** Write this extension. The same fields were previously named as the codes of a code
system, for a key/value carriage on `Bundle.meta.tag`; that code system is retired in favour of this
extension. Stamps already written in the earlier carriage are not part of this specification, are
not produced going forward, and moving them is outstanding work that is not described here.
"""
* ^url = "../StructureDefinition/reporting-export-stamp"
* ^status = #draft
* ^experimental = true
* ^context[0].type = #element
* ^context[0].expression = "Bundle.meta"

* extension contains
    hic 1..1 MS and
    purpose 1..1 MS and
    asOf 1..1 MS and
    watermarkPosition 0..1 MS

* extension[hic].value[x] only string
* extension[hic].value[x] 1..1
* extension[hic] ^short = "The custodian the extract was stamped for (opaque)"
* extension[hic] ^definition = "The health information custodian the extract was produced for. An opaque token: do not parse it, and do not read it as an `Organization` identifier -- it names the custodian of the disclosure, not a resource in this store."

* extension[purpose].value[x] only CodeableConcept
* extension[purpose].value[x] 1..1
* extension[purpose].value[x] from http://terminology.hl7.org/ValueSet/v3-PurposeOfUse (extensible)
* extension[purpose] ^short = "The purpose declared for the disclosure"
* extension[purpose] ^definition = """
The purpose declared for the disclosure, as a coded concept.

Bound to HL7's PurposeOfUse, which is the published vocabulary for this fact: quality improvement
and research both have codes there already. The binding is extensible because the closed set an
extract is declared under is a property of the disclosure rather than of this specification, and
pinning that list here would freeze a snapshot of it. A purpose that PurposeOfUse has no code for carries an
additional local coding, or `text` alone.

An extract with no declared purpose is refused rather than exported, which is why this element is
required.
"""

* extension[asOf].value[x] only instant
* extension[asOf].value[x] 1..1
* extension[asOf] ^short = "The instant the run was anchored at"
* extension[asOf] ^definition = "The instant the run was anchored at -- NOT the moment the file was produced. Two exports of one run at one anchor carry the same value, which is what makes them the same extract."

* extension[watermarkPosition].value[x] only string
* extension[watermarkPosition].value[x] 1..1
* extension[watermarkPosition] ^short = "The run's stored ingest position, verbatim (opaque)"
* extension[watermarkPosition] ^definition = "The run's stored ingest position, carried verbatim. An opaque token whose form is not fixed by this specification; it is comparable only against another position from the same source, and carries no meaning on its own."