fhir-data-utils-ts 0.6.19 → 0.6.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codex/skills/govern-fhir-data-utilities/SKILL.md +8 -11
- package/.codex/skills/govern-fhir-observation-components/SKILL.md +11 -13
- package/.codex/skills/preserve-fhir-flat-coding-review/SKILL.md +5 -5
- package/CHANGELOG.md +30 -13
- package/README.md +18 -26
- package/dist/builders/immunization-reminders.d.ts +1 -1
- package/dist/builders/immunization-reminders.js +1 -1
- package/dist/claims/communication-request-claims.d.ts +2 -0
- package/dist/claims/communication-request-claims.js +4 -0
- package/dist/clinical-terminology.d.ts +1 -1
- package/dist/converters/convert-communication-request.js +23 -4
- package/dist/data/communication-request-form-schema.data.d.ts +24 -0
- package/dist/data/communication-request-form-schema.data.js +28 -4
- package/dist/data/index.d.ts +1 -0
- package/dist/data/index.js +1 -0
- package/dist/data/loinc-subject-matter-domain.data.d.ts +684 -0
- package/dist/data/loinc-subject-matter-domain.data.js +179 -0
- package/dist/fhir-search-parameters.d.ts +1 -1
- package/dist/fhir-search-parameters.js +1 -1
- package/dist/imaging-types.d.ts +1 -1
- package/dist/search-models/index.d.ts +1 -1
- package/dist/search-models/index.js +1 -1
- package/docs/CARE_EMERGENCY_ALERT_CONTRACTS.md +2 -2
- package/docs/CLINICAL_TYPED_ACCESSOR_BOUNDARY.md +6 -11
- package/docs/COMMUNICATION_BUNDLE_CONTRACT.md +6 -7
- package/package.json +1 -1
- package/docs/UHC_FHIR_UTILS_MIGRATION.md +0 -181
|
@@ -1,25 +1,23 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: govern-fhir-data-utilities
|
|
3
|
-
description: Complete or audit migrations, claim catalogs, converters, builders, tests and releases in fhir-data-utils-ts. Use for shared FHIR types or utilities
|
|
3
|
+
description: Complete or audit migrations, claim catalogs, converters, builders, tests and releases in fhir-data-utils-ts. Use for shared FHIR types or utilities recovered from standards-based compatibility evidence; raw flat-claim literals; duplicate root and family modules; Observation components; Immunization graphs; Group or ResearchStudy projections; package exports; coverage gates; or downstream promotion.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Govern FHIR Data Utilities
|
|
7
7
|
|
|
8
8
|
## Keep ownership explicit
|
|
9
9
|
|
|
10
|
-
1.
|
|
11
|
-
|
|
10
|
+
1. Inventory every relevant standards-based source family before declaring a
|
|
11
|
+
migration complete.
|
|
12
12
|
2. Treat `gdc-*` repositories as read-only evidence unless the user explicitly
|
|
13
13
|
changes that scope. Never patch them as part of this migration.
|
|
14
14
|
3. Keep neutral FHIR data semantics here. Keep HTTP, SMART, DIDComm, storage,
|
|
15
15
|
authorization and product policy in their owning services or sector packages.
|
|
16
16
|
4. Define every flat key once in its owning named catalog. Import that symbol in
|
|
17
17
|
converters, builders, tests and examples; never repeat a claim-path literal.
|
|
18
|
-
5. For SHC and DGC archaeology,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
consolidation. Do not copy an earlier helper when a later governed contract
|
|
22
|
-
exists.
|
|
18
|
+
5. For SHC and DGC archaeology, prefer the latest governed standards-based
|
|
19
|
+
implementation evidence. Do not copy an earlier helper when a later
|
|
20
|
+
governed contract exists.
|
|
23
21
|
|
|
24
22
|
## Separate catalogs, adapters and builders
|
|
25
23
|
|
|
@@ -68,9 +66,8 @@ description: Complete or audit migrations, claim catalogs, converters, builders,
|
|
|
68
66
|
subscriber persistence, authentication or product notification policy.
|
|
69
67
|
- Validate and project the canonical outer `Bundle[type=batch]` ->
|
|
70
68
|
`Communication` -> inner `Bundle[type=document|batch|collection]` structure
|
|
71
|
-
here, but keep
|
|
72
|
-
|
|
73
|
-
import frozen `gdc-*`. Arbitrary files are DocumentReference entries in the
|
|
69
|
+
here, but keep high-level editors/readers and application data contracts in
|
|
70
|
+
downstream libraries. Arbitrary files are DocumentReference entries in the
|
|
74
71
|
inner Bundle, never a second direct Communication attachment. Direct
|
|
75
72
|
flat-claim CRUD is an internal persistence boundary, not this wire format.
|
|
76
73
|
- Keep ImagingStudy searchable metadata, clinical references and protected
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: govern-fhir-observation-components
|
|
3
|
-
description: Implement or audit neutral FHIR Observation claim catalogs, vital-sign terminology, parent-owned component graphs, reduced component indexes, historical array and bp aliases, and R4/R5 projection adapters. Use when changing Observation.component, blood pressure, assessment scales, device readings, flat claims, portal or assistant vital-sign builders, or migrating
|
|
3
|
+
description: Implement or audit neutral FHIR Observation claim catalogs, vital-sign terminology, parent-owned component graphs, reduced component indexes, historical array and bp aliases, and R4/R5 projection adapters. Use when changing Observation.component, blood pressure, assessment scales, device readings, flat claims, portal or assistant vital-sign builders, or migrating neutral compatibility code.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Govern FHIR Observation Components
|
|
@@ -9,12 +9,12 @@ description: Implement or audit neutral FHIR Observation claim catalogs, vital-s
|
|
|
9
9
|
|
|
10
10
|
1. Treat native FHIR import/export as an adapter boundary. Keep flat claims as
|
|
11
11
|
the version-neutral internal contract.
|
|
12
|
-
2. Read `src/observation-claims.ts`, `src/vital-sign-observations.ts
|
|
13
|
-
tests
|
|
14
|
-
3. Treat
|
|
15
|
-
|
|
16
|
-
4. Keep product policies
|
|
17
|
-
|
|
12
|
+
2. Read `src/observation-claims.ts`, `src/vital-sign-observations.ts` and their
|
|
13
|
+
tests before changing behavior.
|
|
14
|
+
3. Treat external compatibility repositories as read-only evidence unless the
|
|
15
|
+
user explicitly changes that scope.
|
|
16
|
+
4. Keep product policies downstream. This package owns only neutral FHIR data
|
|
17
|
+
semantics.
|
|
18
18
|
|
|
19
19
|
## Preserve the component contract
|
|
20
20
|
|
|
@@ -79,15 +79,13 @@ description: Implement or audit neutral FHIR Observation claim catalogs, vital-s
|
|
|
79
79
|
|
|
80
80
|
## Audit migrations completely
|
|
81
81
|
|
|
82
|
-
- Inventory the
|
|
83
|
-
|
|
84
|
-
complete.
|
|
82
|
+
- Inventory the relevant standards-based source and compatibility evidence
|
|
83
|
+
before calling a migration complete.
|
|
85
84
|
- Move only neutral FHIR data types, claim catalogs, conversion rules and pure
|
|
86
85
|
helpers here. Keep transport clients and sector authorization/policy in
|
|
87
86
|
their owning package.
|
|
88
|
-
- Record every migrated, retired or intentionally retained family in
|
|
89
|
-
|
|
90
|
-
audit.
|
|
87
|
+
- Record every migrated, retired or intentionally retained family in neutral
|
|
88
|
+
repository documentation; an unmentioned file is an incomplete audit.
|
|
91
89
|
- Expose each supported family through a stable package subpath and prove the
|
|
92
90
|
packed artifact, not only root source imports.
|
|
93
91
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: preserve-fhir-flat-coding-review
|
|
3
|
-
description: Preserve the neutral flat-claim contract for imported local clinical text, terminology proposals and confirmed codings. Use when changing
|
|
3
|
+
description: Preserve the neutral flat-claim contract for imported local clinical text, terminology proposals and confirmed codings. Use when changing ingestion, ResearchSubject batches, contained clinical resources, coding-review UI/API contracts, examples, fixtures or tests.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Preserve FHIR Flat Coding Review
|
|
@@ -24,7 +24,7 @@ redeclare governed claim paths, code systems, UUIDs or example values.
|
|
|
24
24
|
`userSelected` as a draft or promotion flag.
|
|
25
25
|
- Group review UI with the package-owned clinical families: allergies and
|
|
26
26
|
intolerances, procedures, diagnostics and immunizations. Do not duplicate
|
|
27
|
-
resource-type lists in
|
|
27
|
+
resource-type lists in downstream consumers.
|
|
28
28
|
- A localized generated label may use a language-qualified `-text_<BCP47>`
|
|
29
29
|
companion. It must not overwrite the imported local text before explicit
|
|
30
30
|
review.
|
|
@@ -60,9 +60,9 @@ redeclare governed claim paths, code systems, UUIDs or example values.
|
|
|
60
60
|
## Boundaries
|
|
61
61
|
|
|
62
62
|
- This is FHIR-neutral shared data behavior. It belongs in
|
|
63
|
-
`fhir-data-utils-ts`, not
|
|
64
|
-
-
|
|
65
|
-
|
|
63
|
+
`fhir-data-utils-ts`, not in downstream or frozen compatibility packages.
|
|
64
|
+
- Importers and sector applications consume the same contract and may add
|
|
65
|
+
policy without forking its claim shape.
|
|
66
66
|
- Do not put HTTP clients, gateway policy, product authorization or terminology
|
|
67
67
|
catalogs in this package.
|
|
68
68
|
- Tests and examples import package-owned fixtures/builders. Do not scatter raw
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- Re-establish the public repository from a clean source snapshot while
|
|
6
|
+
retaining this changelog as the package release record.
|
|
7
|
+
|
|
8
|
+
## 0.6.21 - 2026-10-21
|
|
9
|
+
|
|
10
|
+
- Add the shared CommunicationRequest form, flat-claim and materialization
|
|
11
|
+
fields needed for categorized public alerts, related attachments and bounded
|
|
12
|
+
occurrence periods without introducing a proprietary alert resource.
|
|
13
|
+
|
|
14
|
+
## 0.6.20 - 2026-10-12
|
|
15
|
+
|
|
16
|
+
- Export the deduplicated official LOINC Document Ontology subject-matter-
|
|
17
|
+
domain catalogue supplied from the LOINC Knowledge Base for human-health
|
|
18
|
+
selectors. Keep it explicitly separate from veterinary service types.
|
|
19
|
+
|
|
20
|
+
## 0.6.19 - 2026-10-12
|
|
21
|
+
|
|
5
22
|
- Add the official `HealthcareService.appointmentRequired` flat claim and
|
|
6
23
|
R4/R5 materialization round trip. Availability remains authoritative in the
|
|
7
24
|
associated Schedule and Slot resources and is not duplicated on the service.
|
|
@@ -50,8 +67,8 @@
|
|
|
50
67
|
- Give every reusable IPS authoring schema canonical initial claims so portal
|
|
51
68
|
components do not invent resource status defaults.
|
|
52
69
|
|
|
53
|
-
- Recover
|
|
54
|
-
|
|
70
|
+
- Recover useful locale-aware behavior from historical compatibility helpers
|
|
71
|
+
as strict FHIR temporal presentation tools.
|
|
55
72
|
Date-only values retain their calendar day, instants render with the user's
|
|
56
73
|
locale and IANA time zone, editor date/time fields compose a canonical FHIR
|
|
57
74
|
instant with optional seconds defaulted to `00`, and inclusive ranges treat
|
|
@@ -78,8 +95,8 @@
|
|
|
78
95
|
document so portals can update the Composition without duplicating LOINC
|
|
79
96
|
section codes.
|
|
80
97
|
|
|
81
|
-
- Recover neutral SHC and EU DGC QR prefix classification from
|
|
82
|
-
|
|
98
|
+
- Recover neutral SHC and EU DGC QR prefix classification from compatibility
|
|
99
|
+
evidence, with exported repository-safe `*.data.ts` examples.
|
|
83
100
|
Recognition explicitly provides no decoding, verification or authorization.
|
|
84
101
|
|
|
85
102
|
- Export one repository-safe, telephone-free IPS demo document with all sixteen
|
|
@@ -91,8 +108,8 @@
|
|
|
91
108
|
historical source modules remain compatibility reexports.
|
|
92
109
|
- Remove notification-channel policy from the general root and `builders`
|
|
93
110
|
surfaces. The historical reminder subpath and non-standard `Task.channel`
|
|
94
|
-
claim remain deprecated compatibility only while
|
|
95
|
-
|
|
111
|
+
claim remain deprecated compatibility only while consumers migrate;
|
|
112
|
+
downstream applications own channel choices and dispatch behavior.
|
|
96
113
|
|
|
97
114
|
## 0.6.2 - 2026-09-30
|
|
98
115
|
|
|
@@ -115,7 +132,7 @@
|
|
|
115
132
|
the frozen shared implementation: outer batch Bundle, one FHIR Bundle
|
|
116
133
|
attachment per Communication, and validated document/batch/collection inner
|
|
117
134
|
Bundles. Reject direct clinical or binary Communication payloads while
|
|
118
|
-
leaving high-level mutable editors
|
|
135
|
+
leaving high-level mutable editors downstream.
|
|
119
136
|
- Add a typed Appointment exchange projection that preserves start/end,
|
|
120
137
|
participants, slots and supporting information while keeping an ICS calendar
|
|
121
138
|
file as an independent DocumentReference flat-claim resource.
|
|
@@ -246,9 +263,9 @@
|
|
|
246
263
|
modifying that frozen source repository.
|
|
247
264
|
- Recover strict FHIR primitives, value/search/token utilities, Bundle readers,
|
|
248
265
|
resource search/template types, terminology model types, RelatedPerson and
|
|
249
|
-
telecom helpers, and DICOMDIR structural types from
|
|
266
|
+
telecom helpers, and DICOMDIR structural types from compatibility evidence.
|
|
250
267
|
- Move cross-sector terminology, Immunization graph/reminder, Group R5 and
|
|
251
|
-
ResearchStudy R5 contracts
|
|
268
|
+
ResearchStudy R5 contracts into their neutral standards-based owner.
|
|
252
269
|
- Require component Observations to use independently indexable graph entries;
|
|
253
270
|
deprecated JSON-array component claims remain read-only compatibility input.
|
|
254
271
|
- Add stable package subpaths for every migrated contract family.
|
|
@@ -285,12 +302,12 @@
|
|
|
285
302
|
JSON repeatable-component encoding, generic component index projection and
|
|
286
303
|
explicit R4/R5 projection boundary. Historical component CSV and `bp-*`
|
|
287
304
|
aliases remain read-only compatibility inputs.
|
|
288
|
-
- Record the reuse/rewrite/retire audit of
|
|
289
|
-
|
|
290
|
-
|
|
305
|
+
- Record the reuse/rewrite/retire audit of historical compatibility utilities
|
|
306
|
+
without adding obsolete product, transport, SHA-1, DICOM or build
|
|
307
|
+
dependencies to the neutral package.
|
|
291
308
|
- Add the neutral contained-resource coding-review contract: canonical imported
|
|
292
309
|
`*-text`, resource-scoped `meta.codingProposals[]`, batch traversal, candidate
|
|
293
|
-
confirmation and reusable governed fixtures for
|
|
310
|
+
confirmation and reusable governed fixtures for downstream consumers.
|
|
294
311
|
- Add channel-neutral FHIR-like vital-sign Observation builders and lossless device-batch normalization while preserving device source without inventing professional attestation.
|
|
295
312
|
- Introduce product-neutral flat-claim resource graphs, parent-owned
|
|
296
313
|
`contained-reference-list`, narrative `language`/`xhtml`, and governed
|
package/README.md
CHANGED
|
@@ -2,26 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
FHIR-neutral data contracts for flat claims, governed SearchParameter names,
|
|
4
4
|
resource graphs and explicit R4/R5/R6 projection adapters. This package has no
|
|
5
|
-
network clients and no dependency on
|
|
5
|
+
network clients and no dependency on downstream product packages.
|
|
6
6
|
|
|
7
7
|
Release order is local-first: local tarball consumers, complete local matrix,
|
|
8
8
|
merge and push `main`, publish bottom-up, install exact registry versions, then
|
|
9
9
|
staging. Never commit `file:`, Git or workspace dependencies.
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Public source history
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
↓
|
|
17
|
-
sos-data-utils-ts
|
|
18
|
-
└─ cross-sector clinical catalogs and shared SOS/Vet/UHC data contracts
|
|
19
|
-
├─ vet-data-utils-ts: animal species and veterinary policy
|
|
20
|
-
└─ uhc-data-utils-ts: human-health policy
|
|
13
|
+
The public repository begins from a clean 2026 source snapshot. The retained
|
|
14
|
+
[`CHANGELOG.md`](CHANGELOG.md) records package releases without republishing
|
|
15
|
+
the former Git push history.
|
|
21
16
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
## Ownership boundary
|
|
18
|
+
|
|
19
|
+
This package owns only standards-based FHIR SearchParameters, flat-claim
|
|
20
|
+
graphs, validation and explicit R4/R5/R6 projection rules. Sector terminology,
|
|
21
|
+
product policy, transport, authorization, mutable editors, network clients and
|
|
22
|
+
application workflows belong downstream and are deliberately unnamed here.
|
|
25
23
|
|
|
26
24
|
FHIR resource graphs use independent entries. A parent links children only
|
|
27
25
|
through `<ResourceType>.contained-reference-list`; children do not carry
|
|
@@ -48,8 +46,8 @@ Cross-participant data always uses an outer FHIR batch Bundle containing
|
|
|
48
46
|
Communication entries. Each Communication carries exactly one
|
|
49
47
|
`application/fhir+json` inner document, batch or collection Bundle; arbitrary
|
|
50
48
|
files are DocumentReference resources inside that Bundle. This package owns
|
|
51
|
-
strict parsing and projection tools;
|
|
52
|
-
|
|
49
|
+
strict parsing and projection tools; mutable editors, transport and
|
|
50
|
+
cross-sector policy belong downstream. See
|
|
53
51
|
[Communication Bundle contract](docs/COMMUNICATION_BUNDLE_CONTRACT.md).
|
|
54
52
|
|
|
55
53
|
Reservable equipment remains a `Device` actor of its service-specific
|
|
@@ -70,10 +68,10 @@ The root export and stable subpaths provide:
|
|
|
70
68
|
- complete flat-claim catalogs and claim helpers for the resource families
|
|
71
69
|
formerly scattered through `gdc-common-utils-ts`;
|
|
72
70
|
- explicit R4/R5 conversion adapters, including Consent and PractitionerRole;
|
|
73
|
-
-
|
|
71
|
+
- resource search/template types, terminology model types,
|
|
74
72
|
RelatedPerson/telecom helpers and type-only DICOMDIR tree contract;
|
|
75
73
|
- cross-sector terminology, Immunization graphs/reminders, and FHIR R5 Group
|
|
76
|
-
and ResearchStudy contracts
|
|
74
|
+
and ResearchStudy contracts;
|
|
77
75
|
- native FHIR R5 SubscriptionTopic/Subscription configuration builders,
|
|
78
76
|
official search catalogs and a strict notification-Bundle parser; terminal
|
|
79
77
|
asynchronous job messages remain claims-first Communication resources.
|
|
@@ -156,18 +154,13 @@ top-level Observations with a professional attester. Ledger hashing, index
|
|
|
156
154
|
updates, Digital Twin and research eligibility remain owning-service policy.
|
|
157
155
|
See [Daily vital-sign document lifecycle](docs/VITAL_SIGN_DAILY_DOCUMENT.md).
|
|
158
156
|
|
|
159
|
-
See [the UHC FHIR utilities migration](docs/UHC_FHIR_UTILS_MIGRATION.md) for the
|
|
160
|
-
reuse/rewrite/retire inventory and the rule for moving frozen contracts without
|
|
161
|
-
changing any `gdc-*` repository.
|
|
162
|
-
|
|
163
157
|
See [Clinical typed accessor boundary](docs/CLINICAL_TYPED_ACCESSOR_BOUNDARY.md)
|
|
164
158
|
for the exact division between canonical clinical claims/converters here,
|
|
165
|
-
|
|
166
|
-
by runtime SDKs.
|
|
159
|
+
downstream schemas and mutable Bundle getters/setters.
|
|
167
160
|
|
|
168
161
|
## Coding review for imported clinical text
|
|
169
162
|
|
|
170
|
-
|
|
163
|
+
Coding review uses one neutral contract from
|
|
171
164
|
`fhir-data-utils-ts/coding-review-flat-claims`:
|
|
172
165
|
|
|
173
166
|
- imported wording is the canonical `<ResourceType>.<code-field>-text` claim;
|
|
@@ -209,8 +202,7 @@ packed artifact and installs it in an isolated consumer before publication.
|
|
|
209
202
|
|
|
210
203
|
## Care, emergency and population-alert graphs
|
|
211
204
|
|
|
212
|
-
The package provides the neutral FHIR foundation for
|
|
213
|
-
journeys proven first in VetChain/PetChain: Location-linked Encounter care
|
|
205
|
+
The package provides the neutral FHIR foundation for Location-linked Encounter care
|
|
214
206
|
journeys, emergency ServiceRequest plus triage Task, and cohort
|
|
215
207
|
CommunicationRequest against a frozen Group snapshot. See
|
|
216
208
|
[the contract guide](docs/CARE_EMERGENCY_ALERT_CONTRACTS.md). Product policy,
|
|
@@ -7,7 +7,7 @@ export declare const ImmunizationReminderTaskValues: Readonly<{
|
|
|
7
7
|
}>;
|
|
8
8
|
/**
|
|
9
9
|
* @deprecated Compatibility only. Notification-channel policy belongs to the
|
|
10
|
-
* consuming
|
|
10
|
+
* consuming downstream package, not to the general FHIR data package.
|
|
11
11
|
*/
|
|
12
12
|
export declare const ImmunizationReminderChannels: readonly ["push", "email", "sms", "whatsapp", "telephone"];
|
|
13
13
|
export type ImmunizationReminderChannel = (typeof ImmunizationReminderChannels)[number];
|
|
@@ -10,7 +10,7 @@ export const ImmunizationReminderTaskValues = Object.freeze({
|
|
|
10
10
|
});
|
|
11
11
|
/**
|
|
12
12
|
* @deprecated Compatibility only. Notification-channel policy belongs to the
|
|
13
|
-
* consuming
|
|
13
|
+
* consuming downstream package, not to the general FHIR data package.
|
|
14
14
|
*/
|
|
15
15
|
export const ImmunizationReminderChannels = Object.freeze([
|
|
16
16
|
'push',
|
|
@@ -20,6 +20,8 @@ export declare const CommunicationRequestClaim: Readonly<{
|
|
|
20
20
|
readonly InformationProvider: "CommunicationRequest.information-provider";
|
|
21
21
|
readonly AuthoredOn: "CommunicationRequest.authored-on";
|
|
22
22
|
readonly Occurrence: "CommunicationRequest.occurrence";
|
|
23
|
+
readonly OccurrencePeriodStart: "CommunicationRequest.occurrence-period-start";
|
|
24
|
+
readonly OccurrencePeriodEnd: "CommunicationRequest.occurrence-period-end";
|
|
23
25
|
readonly ReasonCode: "CommunicationRequest.reason-code";
|
|
24
26
|
readonly ReasonReference: "CommunicationRequest.reason-reference";
|
|
25
27
|
readonly PayloadContent: "CommunicationRequest.payload-content";
|
|
@@ -19,6 +19,8 @@ export const CommunicationRequestClaim = Object.freeze({
|
|
|
19
19
|
InformationProvider: 'CommunicationRequest.information-provider',
|
|
20
20
|
AuthoredOn: 'CommunicationRequest.authored-on',
|
|
21
21
|
Occurrence: 'CommunicationRequest.occurrence',
|
|
22
|
+
OccurrencePeriodStart: 'CommunicationRequest.occurrence-period-start',
|
|
23
|
+
OccurrencePeriodEnd: 'CommunicationRequest.occurrence-period-end',
|
|
22
24
|
ReasonCode: 'CommunicationRequest.reason-code',
|
|
23
25
|
ReasonReference: 'CommunicationRequest.reason-reference',
|
|
24
26
|
PayloadContent: 'CommunicationRequest.payload-content',
|
|
@@ -48,6 +50,8 @@ export const CommunicationRequestClaimSpecs = Object.freeze([
|
|
|
48
50
|
{ key: CommunicationRequestClaim.InformationProvider, meaning: 'Actors expected to provide or review message information.', example: 'PractitionerRole/doctor-1' },
|
|
49
51
|
{ key: CommunicationRequestClaim.AuthoredOn, meaning: 'Request authoring time.', example: '2026-09-26T11:00:00Z' },
|
|
50
52
|
{ key: CommunicationRequestClaim.Occurrence, meaning: 'Requested delivery time.', example: '2026-09-26T11:30:00Z' },
|
|
53
|
+
{ key: CommunicationRequestClaim.OccurrencePeriodStart, meaning: 'Start of the requested delivery period.', example: '2026-09-26T11:30:00Z' },
|
|
54
|
+
{ key: CommunicationRequestClaim.OccurrencePeriodEnd, meaning: 'End of the requested delivery period.', example: '2026-09-27T11:30:00Z' },
|
|
51
55
|
{ key: CommunicationRequestClaim.ReasonCode, meaning: 'Coded reasons for the request.', example: 'http://snomed.info/sct|246205007' },
|
|
52
56
|
{ key: CommunicationRequestClaim.ReasonReference, meaning: 'Resource references supporting the request reason.', example: 'Condition/condition-1' },
|
|
53
57
|
{ key: CommunicationRequestClaim.PayloadContent, meaning: 'R4 string payload compatibility value.', example: 'Family update ready for review.' },
|
|
@@ -18,7 +18,7 @@ export declare const ClinicalTerminologySourceScopes: Readonly<{
|
|
|
18
18
|
readonly AtcVet: "ATCVET";
|
|
19
19
|
}>;
|
|
20
20
|
export type ClinicalTerminologySourceScope = typeof ClinicalTerminologySourceScopes[keyof typeof ClinicalTerminologySourceScopes];
|
|
21
|
-
/** Product-neutral terminology candidate returned to
|
|
21
|
+
/** Product-neutral terminology candidate returned to downstream channels. */
|
|
22
22
|
export type ClinicalTerminologyCandidate = Readonly<{
|
|
23
23
|
/** Governed source-scope identifier returned by the deployment capability. */
|
|
24
24
|
source: string;
|
|
@@ -18,7 +18,7 @@ export function communicationRequestFlatToFhirR4(claims) {
|
|
|
18
18
|
requester: claims[CommunicationRequestClaim.Requester] ? { reference: claims[CommunicationRequestClaim.Requester] } : undefined,
|
|
19
19
|
sender: firstReference(claims[CommunicationRequestClaim.InformationProvider]),
|
|
20
20
|
recipient: referenceCsv(claims[CommunicationRequestClaim.Recipient]), authoredOn: claims[CommunicationRequestClaim.AuthoredOn],
|
|
21
|
-
|
|
21
|
+
...occurrenceToFhir(claims),
|
|
22
22
|
reasonCode: claims[CommunicationRequestClaim.ReasonCode] ? [{ coding: codingListFromCsv(claims[CommunicationRequestClaim.ReasonCode]) }] : undefined,
|
|
23
23
|
reasonReference: referenceCsv(claims[CommunicationRequestClaim.ReasonReference]),
|
|
24
24
|
payload: payloadR4(claims),
|
|
@@ -44,7 +44,8 @@ export function communicationRequestFhirR4ToFlat(resource) {
|
|
|
44
44
|
[CommunicationRequestClaim.Requester]: referenceToValue(resource.requester),
|
|
45
45
|
[CommunicationRequestClaim.InformationProvider]: referenceToValue(resource.sender),
|
|
46
46
|
[CommunicationRequestClaim.Recipient]: referenceListToCsv(resource.recipient),
|
|
47
|
-
[CommunicationRequestClaim.AuthoredOn]: resource.authoredOn,
|
|
47
|
+
[CommunicationRequestClaim.AuthoredOn]: resource.authoredOn,
|
|
48
|
+
...occurrenceToFlat(resource),
|
|
48
49
|
[CommunicationRequestClaim.ReasonCode]: codingListToCsv(resource.reasonCode?.flatMap(value => value.coding ?? [])),
|
|
49
50
|
[CommunicationRequestClaim.ReasonReference]: referenceListToCsv(resource.reasonReference),
|
|
50
51
|
...payloadToFlat(resource),
|
|
@@ -82,7 +83,7 @@ function communicationRequestFlatToFhirR5Resource(claims) {
|
|
|
82
83
|
requester: claims[CommunicationRequestClaim.Requester] ? { reference: claims[CommunicationRequestClaim.Requester] } : undefined,
|
|
83
84
|
recipient: referenceCsv(claims[CommunicationRequestClaim.Recipient]),
|
|
84
85
|
informationProvider: referenceCsv(claims[CommunicationRequestClaim.InformationProvider]),
|
|
85
|
-
authoredOn: claims[CommunicationRequestClaim.AuthoredOn],
|
|
86
|
+
authoredOn: claims[CommunicationRequestClaim.AuthoredOn], ...occurrenceToFhir(claims),
|
|
86
87
|
reason: reasonsR5(claims), payload: payloadR5(claims), note: annotation(claims[CommunicationRequestClaim.Note]),
|
|
87
88
|
};
|
|
88
89
|
}
|
|
@@ -107,7 +108,7 @@ function communicationRequestFhirR5ResourceToFlat(resource) {
|
|
|
107
108
|
[CommunicationRequestClaim.Recipient]: referenceListToCsv(resource.recipient),
|
|
108
109
|
[CommunicationRequestClaim.InformationProvider]: referenceListToCsv(resource.informationProvider),
|
|
109
110
|
[CommunicationRequestClaim.AuthoredOn]: resource.authoredOn,
|
|
110
|
-
|
|
111
|
+
...occurrenceToFlat(resource),
|
|
111
112
|
[CommunicationRequestClaim.ReasonCode]: codingListToCsv(reasons?.flatMap(value => value.concept?.coding ?? [])),
|
|
112
113
|
[CommunicationRequestClaim.ReasonReference]: reasons?.map(value => value.reference?.reference).filter((value) => Boolean(value)).join(',') || undefined,
|
|
113
114
|
...payloadToFlat(resource), [CommunicationRequestClaim.Note]: annotationText(resource.note),
|
|
@@ -134,6 +135,24 @@ function optionalBoolean(value) {
|
|
|
134
135
|
}
|
|
135
136
|
function annotation(value) { return value ? [{ text: value }] : undefined; }
|
|
136
137
|
function annotationText(value) { return value?.[0]?.text; }
|
|
138
|
+
function occurrenceToFhir(claims) {
|
|
139
|
+
const occurrenceDateTime = claims[CommunicationRequestClaim.Occurrence];
|
|
140
|
+
const start = claims[CommunicationRequestClaim.OccurrencePeriodStart];
|
|
141
|
+
const end = claims[CommunicationRequestClaim.OccurrencePeriodEnd];
|
|
142
|
+
if (occurrenceDateTime && (start || end))
|
|
143
|
+
throw new TypeError('communication_request_occurrence_choice_invalid');
|
|
144
|
+
return occurrenceDateTime ? { occurrenceDateTime } : start || end ? { occurrencePeriod: compact({ start, end }) } : {};
|
|
145
|
+
}
|
|
146
|
+
function occurrenceToFlat(resource) {
|
|
147
|
+
const period = resource.occurrencePeriod;
|
|
148
|
+
if (resource.occurrenceDateTime && period)
|
|
149
|
+
throw new TypeError('communication_request_occurrence_choice_invalid');
|
|
150
|
+
return compact({
|
|
151
|
+
[CommunicationRequestClaim.Occurrence]: resource.occurrenceDateTime,
|
|
152
|
+
[CommunicationRequestClaim.OccurrencePeriodStart]: period?.start,
|
|
153
|
+
[CommunicationRequestClaim.OccurrencePeriodEnd]: period?.end,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
137
156
|
function payloadR4(claims) {
|
|
138
157
|
if (claims[CommunicationRequestClaim.PayloadReference])
|
|
139
158
|
return [{ contentReference: { reference: claims[CommunicationRequestClaim.PayloadReference] } }];
|
|
@@ -7,13 +7,17 @@ export type CommunicationRequestFormData = Readonly<{
|
|
|
7
7
|
status: typeof CommunicationRequestStatuses[number];
|
|
8
8
|
intent: typeof CommunicationRequestIntents[number];
|
|
9
9
|
priority?: typeof CommunicationRequestPriorities[number];
|
|
10
|
+
category?: string;
|
|
10
11
|
subject: string;
|
|
12
|
+
about?: readonly string[];
|
|
11
13
|
encounter?: string;
|
|
12
14
|
requester: string;
|
|
13
15
|
recipients: readonly string[];
|
|
14
16
|
informationProviders?: readonly string[];
|
|
15
17
|
authoredOn?: string;
|
|
16
18
|
occurrence?: string;
|
|
19
|
+
occurrencePeriodStart?: string;
|
|
20
|
+
occurrencePeriodEnd?: string;
|
|
17
21
|
payloadReference?: string;
|
|
18
22
|
payloadAttachmentContentType?: string;
|
|
19
23
|
payloadAttachmentData?: string;
|
|
@@ -45,10 +49,22 @@ export declare const FHIR_COMMUNICATION_REQUEST_FORM_SCHEMA: Readonly<{
|
|
|
45
49
|
type: "string";
|
|
46
50
|
enum: readonly ["routine", "urgent", "asap", "stat"];
|
|
47
51
|
}>;
|
|
52
|
+
category: Readonly<{
|
|
53
|
+
type: "string";
|
|
54
|
+
pattern: "^https?://[^|,]+\\|[^|,]+$";
|
|
55
|
+
}>;
|
|
48
56
|
subject: Readonly<{
|
|
49
57
|
type: "string";
|
|
50
58
|
pattern: "^[A-Za-z][A-Za-z0-9]+/[A-Za-z0-9.-]{1,64}$";
|
|
51
59
|
}>;
|
|
60
|
+
about: Readonly<{
|
|
61
|
+
type: "array";
|
|
62
|
+
uniqueItems: true;
|
|
63
|
+
items: Readonly<{
|
|
64
|
+
type: "string";
|
|
65
|
+
pattern: "^[A-Za-z][A-Za-z0-9]+/[A-Za-z0-9.-]{1,64}$";
|
|
66
|
+
}>;
|
|
67
|
+
}>;
|
|
52
68
|
encounter: Readonly<{
|
|
53
69
|
type: "string";
|
|
54
70
|
pattern: "^[A-Za-z][A-Za-z0-9]+/[A-Za-z0-9.-]{1,64}$";
|
|
@@ -82,6 +98,14 @@ export declare const FHIR_COMMUNICATION_REQUEST_FORM_SCHEMA: Readonly<{
|
|
|
82
98
|
type: "string";
|
|
83
99
|
format: "date-time";
|
|
84
100
|
}>;
|
|
101
|
+
occurrencePeriodStart: Readonly<{
|
|
102
|
+
type: "string";
|
|
103
|
+
format: "date-time";
|
|
104
|
+
}>;
|
|
105
|
+
occurrencePeriodEnd: Readonly<{
|
|
106
|
+
type: "string";
|
|
107
|
+
format: "date-time";
|
|
108
|
+
}>;
|
|
85
109
|
payloadReference: Readonly<{
|
|
86
110
|
type: "string";
|
|
87
111
|
pattern: "^[A-Za-z][A-Za-z0-9]+/[A-Za-z0-9.-]{1,64}$";
|
|
@@ -20,10 +20,14 @@ export const FHIR_COMMUNICATION_REQUEST_FORM_SCHEMA = Object.freeze({
|
|
|
20
20
|
status: Object.freeze({ type: 'string', enum: CommunicationRequestStatuses }),
|
|
21
21
|
intent: Object.freeze({ type: 'string', enum: CommunicationRequestIntents }),
|
|
22
22
|
priority: Object.freeze({ type: 'string', enum: CommunicationRequestPriorities }),
|
|
23
|
-
|
|
23
|
+
category: codingSchema(),
|
|
24
|
+
subject: referenceSchema(),
|
|
25
|
+
about: Object.freeze({ type: 'array', uniqueItems: true, items: referenceSchema() }),
|
|
26
|
+
encounter: referenceSchema(), requester: referenceSchema(),
|
|
24
27
|
recipients: Object.freeze({ type: 'array', minItems: 1, uniqueItems: true, items: referenceSchema() }),
|
|
25
28
|
informationProviders: Object.freeze({ type: 'array', uniqueItems: true, items: referenceSchema() }),
|
|
26
|
-
authoredOn: dateTimeSchema(), occurrence: dateTimeSchema(),
|
|
29
|
+
authoredOn: dateTimeSchema(), occurrence: dateTimeSchema(),
|
|
30
|
+
occurrencePeriodStart: dateTimeSchema(), occurrencePeriodEnd: dateTimeSchema(), payloadReference: referenceSchema(),
|
|
27
31
|
payloadAttachmentContentType: Object.freeze({ type: 'string', minLength: 1 }),
|
|
28
32
|
payloadAttachmentData: Object.freeze({ type: 'string', minLength: 1, contentEncoding: 'base64' }),
|
|
29
33
|
payloadAttachmentTitle: Object.freeze({ type: 'string', minLength: 1 }),
|
|
@@ -38,21 +42,34 @@ export function communicationRequestFormDataToFlatClaims(input) {
|
|
|
38
42
|
const recipients = references(input.recipients, 'communication_request_recipient_required');
|
|
39
43
|
const providers = input.informationProviders?.length
|
|
40
44
|
? references(input.informationProviders, 'communication_request_information_provider_invalid') : undefined;
|
|
45
|
+
const about = input.about?.length ? references(input.about, 'communication_request_about_invalid') : undefined;
|
|
41
46
|
if (input.payloadAttachmentData && !input.payloadAttachmentContentType) {
|
|
42
47
|
throw new TypeError('communication_request_attachment_content_type_required');
|
|
43
48
|
}
|
|
49
|
+
const occurrence = dateTime(input.occurrence);
|
|
50
|
+
const occurrencePeriodStart = dateTime(input.occurrencePeriodStart);
|
|
51
|
+
const occurrencePeriodEnd = dateTime(input.occurrencePeriodEnd);
|
|
52
|
+
if (occurrence && (occurrencePeriodStart || occurrencePeriodEnd))
|
|
53
|
+
throw new TypeError('communication_request_occurrence_choice_invalid');
|
|
54
|
+
if (occurrencePeriodStart && occurrencePeriodEnd && Date.parse(occurrencePeriodEnd) <= Date.parse(occurrencePeriodStart)) {
|
|
55
|
+
throw new TypeError('communication_request_occurrence_period_invalid');
|
|
56
|
+
}
|
|
44
57
|
return compact({
|
|
45
58
|
[CommunicationRequestClaim.Identifier]: optional(input.identifier),
|
|
46
59
|
[CommunicationRequestClaim.Status]: input.status,
|
|
47
60
|
[CommunicationRequestClaim.Intent]: input.intent,
|
|
48
61
|
[CommunicationRequestClaim.Priority]: optional(input.priority),
|
|
62
|
+
[CommunicationRequestClaim.Category]: coding(input.category),
|
|
49
63
|
[CommunicationRequestClaim.Subject]: reference(input.subject, 'communication_request_subject_invalid'),
|
|
64
|
+
[CommunicationRequestClaim.About]: about?.join(','),
|
|
50
65
|
[CommunicationRequestClaim.Encounter]: input.encounter ? reference(input.encounter, 'communication_request_encounter_invalid') : undefined,
|
|
51
66
|
[CommunicationRequestClaim.Requester]: reference(input.requester, 'communication_request_requester_invalid'),
|
|
52
67
|
[CommunicationRequestClaim.Recipient]: recipients.join(','),
|
|
53
68
|
[CommunicationRequestClaim.InformationProvider]: providers?.join(','),
|
|
54
69
|
[CommunicationRequestClaim.AuthoredOn]: dateTime(input.authoredOn),
|
|
55
|
-
[CommunicationRequestClaim.Occurrence]:
|
|
70
|
+
[CommunicationRequestClaim.Occurrence]: occurrence,
|
|
71
|
+
[CommunicationRequestClaim.OccurrencePeriodStart]: occurrencePeriodStart,
|
|
72
|
+
[CommunicationRequestClaim.OccurrencePeriodEnd]: occurrencePeriodEnd,
|
|
56
73
|
[CommunicationRequestClaim.PayloadReference]: input.payloadReference ? reference(input.payloadReference, 'communication_request_payload_reference_invalid') : undefined,
|
|
57
74
|
[CommunicationRequestClaim.PayloadAttachmentContentType]: optional(input.payloadAttachmentContentType),
|
|
58
75
|
[CommunicationRequestClaim.PayloadAttachmentData]: optional(input.payloadAttachmentData),
|
|
@@ -64,10 +81,14 @@ export function communicationRequestFlatClaimsToFormData(claims) {
|
|
|
64
81
|
return compact({
|
|
65
82
|
identifier: claims[CommunicationRequestClaim.Identifier], status: claims[CommunicationRequestClaim.Status],
|
|
66
83
|
intent: claims[CommunicationRequestClaim.Intent], priority: claims[CommunicationRequestClaim.Priority],
|
|
67
|
-
|
|
84
|
+
category: claims[CommunicationRequestClaim.Category],
|
|
85
|
+
subject: claims[CommunicationRequestClaim.Subject], about: splitOptional(claims[CommunicationRequestClaim.About]),
|
|
86
|
+
encounter: claims[CommunicationRequestClaim.Encounter],
|
|
68
87
|
requester: claims[CommunicationRequestClaim.Requester], recipients: split(claims[CommunicationRequestClaim.Recipient]),
|
|
69
88
|
informationProviders: splitOptional(claims[CommunicationRequestClaim.InformationProvider]),
|
|
70
89
|
authoredOn: claims[CommunicationRequestClaim.AuthoredOn], occurrence: claims[CommunicationRequestClaim.Occurrence],
|
|
90
|
+
occurrencePeriodStart: claims[CommunicationRequestClaim.OccurrencePeriodStart],
|
|
91
|
+
occurrencePeriodEnd: claims[CommunicationRequestClaim.OccurrencePeriodEnd],
|
|
71
92
|
payloadReference: claims[CommunicationRequestClaim.PayloadReference],
|
|
72
93
|
payloadAttachmentContentType: claims[CommunicationRequestClaim.PayloadAttachmentContentType],
|
|
73
94
|
payloadAttachmentData: claims[CommunicationRequestClaim.PayloadAttachmentData],
|
|
@@ -75,12 +96,15 @@ export function communicationRequestFlatClaimsToFormData(claims) {
|
|
|
75
96
|
});
|
|
76
97
|
}
|
|
77
98
|
function referenceSchema() { return Object.freeze({ type: 'string', pattern: '^[A-Za-z][A-Za-z0-9]+/[A-Za-z0-9.-]{1,64}$' }); }
|
|
99
|
+
function codingSchema() { return Object.freeze({ type: 'string', pattern: '^https?://[^|,]+\\|[^|,]+$' }); }
|
|
78
100
|
function dateTimeSchema() { return Object.freeze({ type: 'string', format: 'date-time' }); }
|
|
79
101
|
function optional(value) { const text = String(value ?? '').trim(); return text || undefined; }
|
|
80
102
|
function dateTime(value) { const text = optional(value); if (text && Number.isNaN(Date.parse(text)))
|
|
81
103
|
throw new TypeError('communication_request_datetime_invalid'); return text; }
|
|
82
104
|
function reference(value, error) { const text = optional(value); if (!text || !/^[A-Za-z][A-Za-z0-9]+\/[A-Za-z0-9.-]{1,64}$/u.test(text))
|
|
83
105
|
throw new TypeError(error); return text; }
|
|
106
|
+
function coding(value) { const text = optional(value); if (text && !/^https?:\/\/[^|,]+\|[^|,]+$/u.test(text))
|
|
107
|
+
throw new TypeError('communication_request_category_invalid'); return text; }
|
|
84
108
|
function references(values, error) { if (!Array.isArray(values) || !values.length)
|
|
85
109
|
throw new TypeError(error); const result = [...new Set(values.map(value => reference(value, error)))]; if (result.length !== values.length)
|
|
86
110
|
throw new TypeError(error); return result; }
|
package/dist/data/index.d.ts
CHANGED
|
@@ -6,3 +6,4 @@ export * from './health-credential-qr.data.js';
|
|
|
6
6
|
export * from './ips-clinical-artifact-schemas.data.js';
|
|
7
7
|
export * from './clinical-document-encounter-journey.data.js';
|
|
8
8
|
export * from './communication-request-form-schema.data.js';
|
|
9
|
+
export * from './loinc-subject-matter-domain.data.js';
|
package/dist/data/index.js
CHANGED
|
@@ -6,3 +6,4 @@ export * from './health-credential-qr.data.js';
|
|
|
6
6
|
export * from './ips-clinical-artifact-schemas.data.js';
|
|
7
7
|
export * from './clinical-document-encounter-journey.data.js';
|
|
8
8
|
export * from './communication-request-form-schema.data.js';
|
|
9
|
+
export * from './loinc-subject-matter-domain.data.js';
|