fhir-data-utils-ts 0.4.0 → 0.6.0
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 +35 -0
- package/CHANGELOG.md +52 -0
- package/README.md +35 -0
- package/dist/appointment-communication-test-data.d.ts +63 -0
- package/dist/appointment-communication-test-data.js +77 -0
- package/dist/builders/department-service-graph.d.ts +32 -0
- package/dist/builders/department-service-graph.js +102 -0
- package/dist/builders/device-compliance-graph.d.ts +51 -0
- package/dist/builders/device-compliance-graph.js +115 -0
- package/dist/builders/index.d.ts +3 -0
- package/dist/builders/index.js +3 -0
- package/dist/builders/service-schedule-graph.d.ts +58 -0
- package/dist/builders/service-schedule-graph.js +149 -0
- package/dist/claims/appointment-claims.d.ts +6 -0
- package/dist/claims/appointment-claims.js +6 -0
- package/dist/claims/device-metric-claims.d.ts +16 -0
- package/dist/claims/device-metric-claims.js +25 -0
- package/dist/claims/healthcare-service-claims.d.ts +32 -0
- package/dist/claims/healthcare-service-claims.js +54 -0
- package/dist/claims/index.d.ts +4 -0
- package/dist/claims/index.js +4 -0
- package/dist/claims/location-claims.d.ts +3 -0
- package/dist/claims/location-claims.js +6 -0
- package/dist/claims/organization-claims.d.ts +3 -1
- package/dist/claims/organization-claims.js +4 -1
- package/dist/claims/procedure-claims.d.ts +2 -0
- package/dist/claims/procedure-claims.js +4 -0
- package/dist/claims/regulated-authorization-claims.d.ts +17 -0
- package/dist/claims/regulated-authorization-claims.js +27 -0
- package/dist/claims/schedule-slot-claims.d.ts +45 -0
- package/dist/claims/schedule-slot-claims.js +70 -0
- package/dist/constants/fhir-resource-types.d.ts +9 -0
- package/dist/constants/fhir-resource-types.js +3 -0
- package/dist/converters/convert-appointment-communication.d.ts +14 -0
- package/dist/converters/convert-appointment-communication.js +97 -0
- package/dist/converters/convert-appointment.js +16 -7
- package/dist/converters/convert-device-metric.d.ts +3 -0
- package/dist/converters/convert-device-metric.js +37 -0
- package/dist/converters/convert-document-reference.js +5 -0
- package/dist/converters/convert-healthcare-service.d.ts +7 -0
- package/dist/converters/convert-healthcare-service.js +60 -0
- package/dist/converters/convert-location.d.ts +4 -0
- package/dist/converters/convert-location.js +41 -3
- package/dist/converters/convert-organization.d.ts +2 -0
- package/dist/converters/convert-organization.js +20 -3
- package/dist/converters/convert-procedure.d.ts +2 -0
- package/dist/converters/convert-procedure.js +21 -0
- package/dist/converters/convert-regulated-authorization.d.ts +3 -0
- package/dist/converters/convert-regulated-authorization.js +34 -0
- package/dist/converters/convert-schedule-slot.d.ts +9 -0
- package/dist/converters/convert-schedule-slot.js +96 -0
- package/dist/converters/convert-shared.d.ts +10 -0
- package/dist/converters/convert-shared.js +19 -0
- package/dist/converters/index.d.ts +6 -0
- package/dist/converters/index.js +6 -0
- package/dist/converters/materialize-claims-first-resource.d.ts +16 -0
- package/dist/converters/materialize-claims-first-resource.js +61 -0
- package/dist/fhir-bundle.d.ts +21 -0
- package/dist/fhir-bundle.js +74 -0
- package/dist/group-r5.d.ts +12 -0
- package/dist/group-r5.js +20 -0
- package/dist/healthcare-service-specialty-map.d.ts +32 -0
- package/dist/healthcare-service-specialty-map.js +151 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/docs/CLINICAL_TYPED_ACCESSOR_BOUNDARY.md +44 -0
- package/docs/COMMUNICATION_BUNDLE_CONTRACT.md +61 -0
- package/docs/HEALTHCARE_SERVICE_DEPARTMENT_CATALOG.md +190 -0
- package/docs/UHC_FHIR_UTILS_MIGRATION.md +20 -1
- package/package.json +5 -1
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Candidate SNOMED CT C80 to LOINC specialty map supplied for review.
|
|
3
|
+
*
|
|
4
|
+
* This is not an official SNOMED or LOINC map. The declared relationship is
|
|
5
|
+
* preserved so consumers can automate only strict equivalence and present
|
|
6
|
+
* wider, related, inexact or unmatched rows for professional governance.
|
|
7
|
+
*/
|
|
8
|
+
export const ClinicalSpecialtyMappingEquivalence = Object.freeze({
|
|
9
|
+
Equivalent: 'equivalent',
|
|
10
|
+
Wider: 'wider',
|
|
11
|
+
RelatedTo: 'relatedto',
|
|
12
|
+
Inexact: 'inexact',
|
|
13
|
+
Unmatched: 'unmatched',
|
|
14
|
+
});
|
|
15
|
+
const E = ClinicalSpecialtyMappingEquivalence.Equivalent;
|
|
16
|
+
const W = ClinicalSpecialtyMappingEquivalence.Wider;
|
|
17
|
+
const R = ClinicalSpecialtyMappingEquivalence.RelatedTo;
|
|
18
|
+
const I = ClinicalSpecialtyMappingEquivalence.Inexact;
|
|
19
|
+
const U = ClinicalSpecialtyMappingEquivalence.Unmatched;
|
|
20
|
+
const suppliedRows = Object.freeze([
|
|
21
|
+
['408467006', 'Adult mental illness', 'LP172958-3', 'Mental health', W],
|
|
22
|
+
['394577000', 'Anesthetics', 'LP172918-7', 'Anesthesiology', E],
|
|
23
|
+
['394578005', 'Audiological medicine', 'LP172919-5', 'Audiology', I],
|
|
24
|
+
['421661004', 'Blood banking and transfusion medicine', 'LP172920-3', 'Blood banking and transfusion medicine', E],
|
|
25
|
+
['408462000', 'Burns care', 'LP268363-1', 'Burn management', I],
|
|
26
|
+
['394579002', 'Cardiology', 'LA7179-0', 'Medicine.cardiology', E],
|
|
27
|
+
['394804000', 'Clinical cytogenetics and molecular genetics', 'LP172929-4', 'Clinical genetics', W],
|
|
28
|
+
['394580004', 'Clinical genetics', 'LP172929-4', 'Clinical genetics', E],
|
|
29
|
+
['394803006', 'Clinical hematology', 'LP175685-9', 'Hematology', I],
|
|
30
|
+
['408480009', 'Clinical immunology', 'LP345043-6', 'Immunology', W],
|
|
31
|
+
['408454008', 'Clinical microbiology', 'LP208903-7', 'Pathology - Medical microbiology', I],
|
|
32
|
+
['394809005', 'Clinical neuro-physiology', 'LP172931-0', 'Clinical neurophysiology', E],
|
|
33
|
+
['394592004', 'Clinical oncology', 'LP172901-3', 'Oncology', I],
|
|
34
|
+
['394600006', 'Clinical pharmacology', 'LP220238-2', 'Clinical pharmacology', E],
|
|
35
|
+
['394601005', 'Clinical physiology', undefined, undefined, U],
|
|
36
|
+
['394581000', 'Community medicine', 'LP204156-6', 'Community health care', I],
|
|
37
|
+
['408478003', 'Critical care medicine', 'LP172933-6', 'Critical care medicine', E],
|
|
38
|
+
['394812008', 'Dental medicine specialties', 'LP172934-4', 'Dentistry', W],
|
|
39
|
+
['408444009', 'Dental-General dental practice', 'LP172934-4', 'Dentistry', W],
|
|
40
|
+
['394582007', 'Dermatology', 'LP172935-1', 'Dermatology', E],
|
|
41
|
+
['408475000', 'Diabetic medicine', 'LP172938-5', 'Diabetology', E],
|
|
42
|
+
['410005002', 'Dive medicine', 'LP173035-9', 'Undersea and hyperbaric medicine', I],
|
|
43
|
+
['394583002', 'Endocrinology', 'LP172941-9', 'Endocrinology', E],
|
|
44
|
+
['419772000', 'Family practice', 'LP172943-5', 'Family medicine', E],
|
|
45
|
+
['394584008', 'Gastroenterology', 'LP172945-0', 'Gastroenterology', E],
|
|
46
|
+
['408443003', 'General medical practice', 'LP173010-2', 'Primary care', I],
|
|
47
|
+
['394802001', 'General medicine', 'LP172946-8', 'General medicine', E],
|
|
48
|
+
['394915009', 'General pathology', 'LP172984-9', 'Pathology', I],
|
|
49
|
+
['394814009', 'General practice', 'LP173010-2', 'Primary care', I],
|
|
50
|
+
['394808002', 'Genito-urinary medicine', 'LP173036-7', 'Urology', W],
|
|
51
|
+
['394811001', 'Geriatric medicine', 'LP172947-6', 'Geriatric medicine', E],
|
|
52
|
+
['408446006', 'Gynecological oncology', 'LP202989-2', 'Gynecologic oncology', E],
|
|
53
|
+
['394586005', 'Gynecology', 'LP221284-5', 'Gynecology', E],
|
|
54
|
+
['394916005', 'Hematopathology', 'LP172984-9', 'Pathology', W],
|
|
55
|
+
['408472002', 'Hepatology', 'LP172950-0', 'Hepatology', E],
|
|
56
|
+
['394597005', 'Histopathology', 'LP208907-8', 'Anatomic pathology', W],
|
|
57
|
+
['394598000', 'Immunopathology', 'LP345043-6', 'Immunology', W],
|
|
58
|
+
['394807007', 'Infectious diseases', 'LP172951-8', 'Infectious disease', E],
|
|
59
|
+
['419192003', 'Internal medicine', 'LP172952-6', 'Internal medicine', E],
|
|
60
|
+
['408468001', 'Learning disability', undefined, undefined, U],
|
|
61
|
+
['394593009', 'Medical oncology', 'LP175686-7', 'Medical Oncology', E],
|
|
62
|
+
['394813003', 'Medical ophthalmology', 'LP172974-0', 'Ophthalmology', W],
|
|
63
|
+
['410001006', 'Military medicine', undefined, undefined, U],
|
|
64
|
+
['394589003', 'Nephrology', 'LP172962-5', 'Nephrology', E],
|
|
65
|
+
['394591006', 'Neurology', 'LP172964-1', 'Neurology', E],
|
|
66
|
+
['394599008', 'Neuropathology', 'LP208907-8', 'Anatomic pathology', W],
|
|
67
|
+
['394649004', 'Nuclear medicine', 'LP172968-2', 'Nuclear medicine', E],
|
|
68
|
+
['408470005', 'Obstetrics', 'LP221283-7', 'Obstetrics', E],
|
|
69
|
+
['394585009', 'Obstetrics and gynecology', 'LP172971-6', 'Obstetrics and gynecology', E],
|
|
70
|
+
['394821009', 'Occupational medicine', 'LP172972-4', 'Occupational medicine', E],
|
|
71
|
+
['422191005', 'Ophthalmic surgery', 'LP172974-0', 'Ophthalmology', W],
|
|
72
|
+
['394594003', 'Ophthalmology', 'LP172974-0', 'Ophthalmology', E],
|
|
73
|
+
['416304004', 'Osteopathic manipulative medicine', 'LP434767-2', 'Osteopathic medicine', I],
|
|
74
|
+
['418960008', 'Otolaryngology', 'LP172980-7', 'Otolaryngology', E],
|
|
75
|
+
['394882004', 'Pain management', 'LP172981-5', 'Pain medicine', I],
|
|
76
|
+
['394806003', 'Palliative medicine', 'LP172982-3', 'Palliative care', I],
|
|
77
|
+
['394588006', 'Pediatric (Child and adolescent) psychiatry', 'LP172922-9', 'Child and adolescent psychiatry', E],
|
|
78
|
+
['408459003', 'Pediatric cardiology', 'LP172985-6', 'Pediatric cardiology', E],
|
|
79
|
+
['394607009', 'Pediatric dentistry', 'LP172934-4', 'Dentistry', W],
|
|
80
|
+
['419610006', 'Pediatric endocrinology', 'LP172989-8', 'Pediatric endocrinology', E],
|
|
81
|
+
['418058008', 'Pediatric gastroenterology', 'LP172990-6', 'Pediatric gastroenterology', E],
|
|
82
|
+
['420208008', 'Pediatric genetics', 'LP172956-7', 'Medical genetics', W],
|
|
83
|
+
['418652005', 'Pediatric hematology', 'LP172991-4', 'Pediatric hematology-oncology', W],
|
|
84
|
+
['418535003', 'Pediatric immunology', 'LP345043-6', 'Immunology', W],
|
|
85
|
+
['418862001', 'Pediatric infectious diseases', 'LP172992-2', 'Pediatric infectious diseases', E],
|
|
86
|
+
['419365004', 'Pediatric nephrology', 'LP172993-0', 'Pediatric nephrology', E],
|
|
87
|
+
['418002000', 'Pediatric oncology', 'LP172991-4', 'Pediatric hematology-oncology', I],
|
|
88
|
+
['419983000', 'Pediatric ophthalmology', 'LP172974-0', 'Ophthalmology', W],
|
|
89
|
+
['419170002', 'Pediatric pulmonology', 'LP172995-5', 'Pediatric pulmonology', E],
|
|
90
|
+
['419472004', 'Pediatric rheumatology', 'LP172998-9', 'Pediatric rheumatology', E],
|
|
91
|
+
['394539006', 'Pediatric surgery', 'LP172999-7', 'Pediatric surgery', E],
|
|
92
|
+
['420112009', 'Pediatric surgery-bone marrow transplantation', 'LP417851-5', 'Bone Marrow Transplant', I],
|
|
93
|
+
['409968004', 'Preventive medicine', 'LP173009-4', 'Preventive medicine', E],
|
|
94
|
+
['394587001', 'Psychiatry', 'LP173011-0', 'Psychiatry', E],
|
|
95
|
+
['394913002', 'Psychotherapy', 'LP173012-8', 'Psychology', R],
|
|
96
|
+
['408440000', 'Public health medicine', 'LP173014-4', 'Public health', I],
|
|
97
|
+
['418112009', 'Pulmonary medicine', 'LP173015-1', 'Pulmonary disease', I],
|
|
98
|
+
['419815003', 'Radiation oncology', 'LP173016-9', 'Radiation oncology', E],
|
|
99
|
+
['394914008', 'Radiology', 'LP173018-5', 'Radiology', E],
|
|
100
|
+
['408455009', 'Radiology-Interventional radiology', 'LP172896-5', 'Interventional radiology', E],
|
|
101
|
+
['394602003', 'Rehabilitation', 'LP173004-5', 'Physical medicine and rehabilitation', I],
|
|
102
|
+
['408447002', 'Respite care', 'LP173240-5', 'Respite', R],
|
|
103
|
+
['394810000', 'Rheumatology', 'LP173023-5', 'Rheumatology', E],
|
|
104
|
+
['408450004', 'Sleep studies', 'LP248728-0', 'Sleep medicine', I],
|
|
105
|
+
['408476004', 'Surgery-Bone and marrow transplantation', 'LP417851-5', 'Bone Marrow Transplant', I],
|
|
106
|
+
['408469009', 'Surgery-Breast surgery', 'LA7201-2', 'Surgery.breast', E],
|
|
107
|
+
['408466002', 'Surgery-Cardiac surgery', 'LP207300-7', 'Cardiac surgery', E],
|
|
108
|
+
['408471009', 'Surgery-Cardiothoracic transplantation', 'LP173033-4', 'Transplant surgery', W],
|
|
109
|
+
['408464004', 'Surgery-Colorectal surgery', 'LP172932-8', 'Colon and rectal surgery', E],
|
|
110
|
+
['408441001', 'Surgery-Dental-Endodontics', 'LP172934-4', 'Dentistry', W],
|
|
111
|
+
['408465003', 'Surgery-Dental-Oral and maxillofacial surgery', 'LP172902-1', 'Oral and maxillofacial surgery', E],
|
|
112
|
+
['394605001', 'Surgery-Dental-Oral surgery', 'LP172902-1', 'Oral and maxillofacial surgery', I],
|
|
113
|
+
['394608004', 'Surgery-Dental-Orthodontics / Dentistry-surgical-Orthodontics', 'LP172934-4', 'Dentistry', W],
|
|
114
|
+
['408461007', 'Surgery-Dental-Periodontal surgery', 'LP172934-4', 'Dentistry', W],
|
|
115
|
+
['408460008', 'Prosthodontics / surgical-Prosthodontics', 'LP172934-4', 'Dentistry', W],
|
|
116
|
+
['394606000', 'Surgery-Dentistry-Restorative dentistry', 'LP172934-4', 'Dentistry', W],
|
|
117
|
+
['408449004', 'Surgery-Dentistry--surgical', 'LP172934-4', 'Dentistry', W],
|
|
118
|
+
['418018006', 'Surgery-Dermatologic surgery', 'LP172935-1', 'Dermatology', W],
|
|
119
|
+
['394604002', 'Surgery-Ear, nose and throat surgery', 'LP172980-7', 'Otolaryngology', I],
|
|
120
|
+
['394609007', 'Surgery-general', 'LA7205-3', 'Surgery.general', E],
|
|
121
|
+
['408474001', 'Surgery-Hepatobiliary and pancreatic surgery', 'LP172950-0', 'Hepatology', W],
|
|
122
|
+
['394610002', 'Surgery-Neurosurgery', 'LP172963-3', 'Neurological surgery', E],
|
|
123
|
+
['394611003', 'Surgery-Plastic surgery', 'LP173006-0', 'Plastic surgery', E],
|
|
124
|
+
['408477008', 'Surgery-Transplantation surgery', 'LP173033-4', 'Transplant surgery', E],
|
|
125
|
+
['394801008', 'Surgery-Trauma and orthopedics', 'LP434806-8', 'Orthopaedic surgery', I],
|
|
126
|
+
['408463005', 'Surgery-Vascular', 'LP173039-1', 'Vascular surgery', E],
|
|
127
|
+
['419321007', 'Surgical oncology', 'LP207940-0', 'Surgical oncology', E],
|
|
128
|
+
['394576009', 'Surgical-Accident & emergency', 'LP172940-1', 'Emergency medicine', I],
|
|
129
|
+
['394590007', 'Thoracic medicine', 'LP173031-8', 'Thoracic and cardiac surgery', R],
|
|
130
|
+
['409967009', 'Toxicology', 'LP172957-5', 'Medical toxicology', I],
|
|
131
|
+
['408448007', 'Tropical medicine', undefined, undefined, U],
|
|
132
|
+
['419043006', 'Urological oncology', 'LP173036-7', 'Urology', W],
|
|
133
|
+
['394612005', 'Urology', 'LP173036-7', 'Urology', E],
|
|
134
|
+
['394733009', 'Medical specialty--OTHER--NOT LISTED', 'LA46-8', 'Other', I],
|
|
135
|
+
['394732004', 'Surgical specialty--OTHER-NOT LISTED', 'LA46-8', 'Other', I],
|
|
136
|
+
]);
|
|
137
|
+
export const SnomedC80ToLoincSpecialtyConceptMap = Object.freeze(suppliedRows.map(([snomedCode, snomedDisplay, loincCode, loincDisplay, equivalence = U]) => Object.freeze({
|
|
138
|
+
snomedSystem: 'http://snomed.info/sct',
|
|
139
|
+
snomedCode,
|
|
140
|
+
snomedDisplay,
|
|
141
|
+
...(loincCode ? { loincSystem: 'http://loinc.org', loincCode, loincDisplay } : {}),
|
|
142
|
+
equivalence,
|
|
143
|
+
automatic: equivalence === E,
|
|
144
|
+
})));
|
|
145
|
+
/** Returns a portable LOINC specialty only for a strict reviewed equivalence. */
|
|
146
|
+
export function findAutomaticLoincSpecialty(snomedCode) {
|
|
147
|
+
const mapping = SnomedC80ToLoincSpecialtyConceptMap.find(item => item.snomedCode === snomedCode);
|
|
148
|
+
if (!mapping?.automatic || !mapping.loincCode || !mapping.loincDisplay)
|
|
149
|
+
return undefined;
|
|
150
|
+
return Object.freeze({ system: 'http://loinc.org', code: mapping.loincCode, display: mapping.loincDisplay });
|
|
151
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -24,3 +24,5 @@ export * from './fhir-tokens.js';
|
|
|
24
24
|
export * from './related-person.js';
|
|
25
25
|
export * from './imaging-types.js';
|
|
26
26
|
export * from './subscription-r5.js';
|
|
27
|
+
export * from './healthcare-service-specialty-map.js';
|
|
28
|
+
export * from './appointment-communication-test-data.js';
|
package/dist/index.js
CHANGED
|
@@ -24,3 +24,5 @@ export * from './fhir-tokens.js';
|
|
|
24
24
|
export * from './related-person.js';
|
|
25
25
|
export * from './imaging-types.js';
|
|
26
26
|
export * from './subscription-r5.js';
|
|
27
|
+
export * from './healthcare-service-specialty-map.js';
|
|
28
|
+
export * from './appointment-communication-test-data.js';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Clinical Typed Accessor Boundary
|
|
2
|
+
|
|
3
|
+
This package owns the FHIR-neutral claim and projection layer. It does not own
|
|
4
|
+
the mutable SDK `BundleReader` / `BundleEditor` session API.
|
|
5
|
+
|
|
6
|
+
The clinical fields required by the current GDC typed editors are already
|
|
7
|
+
canonical here and survive the native FHIR R4 boundary:
|
|
8
|
+
|
|
9
|
+
| Clinical field | Canonical flat claim | Native FHIR R4 projection |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| Observed allergy reaction severity | `AllergyIntolerance.severity` | `AllergyIntolerance.reaction[].severity` |
|
|
12
|
+
| Medication treatment end | `MedicationStatement.effective-period-end` | `MedicationStatement.effectivePeriod.end` |
|
|
13
|
+
| Immunization administration route | `Immunization.route` | `Immunization.route` |
|
|
14
|
+
| Immunization administration site | `Immunization.site` | `Immunization.site` |
|
|
15
|
+
| Observation reference-range text | `Observation.reference-range-text` | `Observation.referenceRange[].text` |
|
|
16
|
+
|
|
17
|
+
`fhir-data-utils-ts` therefore must preserve these fields in claim catalogs,
|
|
18
|
+
FHIR converters and resource graphs. It must not copy the GDC SDK's mutable
|
|
19
|
+
editor classes or transport-aware Bundle session behavior.
|
|
20
|
+
|
|
21
|
+
The layer split is:
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
fhir-data-utils-ts
|
|
25
|
+
canonical claims + R4/R5/R6 import/export
|
|
26
|
+
↓
|
|
27
|
+
sos-data-utils-ts
|
|
28
|
+
product-neutral multichannel field schemas
|
|
29
|
+
↓
|
|
30
|
+
sos-sdk-core-ts / sos-sdk-node-ts
|
|
31
|
+
shared orchestration and runtime adapters
|
|
32
|
+
↓
|
|
33
|
+
vet-* / uhc-*
|
|
34
|
+
product forms, portal editors and telephone/chat dialogue
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
When Vet or UHC adds a visual, chat or telephone editor for one of these
|
|
38
|
+
fields, it must consume the canonical claim key from this package. It must not
|
|
39
|
+
maintain a second literal, converter or incompatible getter/setter model.
|
|
40
|
+
|
|
41
|
+
The mutable GDC Bundle API remains documented separately in
|
|
42
|
+
[`gdc-common-utils-ts`](https://github.com/Global-DataCare/gdc-common-utils-ts/blob/main/docs/101-CLINICAL-ENTRY-GETTERS-SETTERS.md)
|
|
43
|
+
and exposed to Node applications by
|
|
44
|
+
[`gdc-sdk-node-ts`](https://github.com/Global-DataCare/gdc-sdk-node-ts/blob/main/docs/101-CLINICAL-ENTRY-GETTERS-SETTERS.md).
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Communication Bundle contract
|
|
2
|
+
|
|
3
|
+
Every cross-participant clinical or administrative exchange uses the same
|
|
4
|
+
two-level FHIR envelope. This is the portable contract for Vet, UHC and
|
|
5
|
+
SOSChain channels; HTTP, DIDComm, encryption and recipient resolution remain
|
|
6
|
+
in their owning SDK or service.
|
|
7
|
+
|
|
8
|
+
```text
|
|
9
|
+
outer Bundle (type=batch)
|
|
10
|
+
└── Communication
|
|
11
|
+
└── payload.contentAttachment
|
|
12
|
+
├── contentType = application/fhir+json
|
|
13
|
+
└── data = base64(inner Bundle)
|
|
14
|
+
├── type=document | batch | collection
|
|
15
|
+
└── Appointment, DocumentReference, Observation, ...
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The outer batch is the delivery command. The Communication supplies sender,
|
|
19
|
+
recipient, subject, status and conversation context. Its single attachment is
|
|
20
|
+
always the inner Bundle. A PDF, image, audio file or `text/calendar` event is
|
|
21
|
+
not another direct Communication attachment: it is a `DocumentReference`
|
|
22
|
+
resource inside the inner Bundle. This keeps one entry point for parsing,
|
|
23
|
+
authorization, persistence and audit regardless of channel.
|
|
24
|
+
|
|
25
|
+
Inner Bundle types keep their ordinary FHIR meaning:
|
|
26
|
+
|
|
27
|
+
- `document` starts with `Composition` and represents an attested document;
|
|
28
|
+
- `batch` contains executable entries and every entry has `request.method` and
|
|
29
|
+
`request.url`;
|
|
30
|
+
- `collection` groups related resources without execution or document order.
|
|
31
|
+
|
|
32
|
+
## Neutral tools and high-level ownership
|
|
33
|
+
|
|
34
|
+
`fhir-data-utils-ts` owns only the FHIR tools. It validates and projects a
|
|
35
|
+
received exchange without owning mutable application sessions:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { readCommunicationBundlePayloads } from 'fhir-data-utils-ts'
|
|
39
|
+
|
|
40
|
+
const payloads = readCommunicationBundlePayloads(receivedOuterBatch)
|
|
41
|
+
const innerBundle = payloads[0].bundle
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The validator fails closed when the outer resource is not a batch Bundle, an outer
|
|
45
|
+
batch entry lacks its request, the Communication has anything other than one
|
|
46
|
+
FHIR Bundle attachment, or the inner Bundle violates its declared type.
|
|
47
|
+
|
|
48
|
+
`sos-sdk-core` owns the high-level Bundle and Communication editor/reader used
|
|
49
|
+
by SOS, Vet and UHC. `sos-data-utils` owns its cross-sector input contracts and
|
|
50
|
+
fixtures. The historical `gdc-*` editors remain compatibility surfaces until
|
|
51
|
+
their consumers migrate; this package neither imports nor wraps them.
|
|
52
|
+
|
|
53
|
+
At the GW persistence boundary, the validated native resources are projected
|
|
54
|
+
to independent `resource.meta.claims` rows. Direct flat-claim CRUD is an
|
|
55
|
+
internal storage operation; it is not a replacement wire format for this
|
|
56
|
+
cross-participant exchange contract.
|
|
57
|
+
|
|
58
|
+
`projectAppointmentCommunicationBatchToFlatGraph(...)` is the first typed
|
|
59
|
+
projection using this boundary. It preserves Appointment timing and references
|
|
60
|
+
and emits the calendar DocumentReference independently. Consumers must not
|
|
61
|
+
decode the attachment or recreate these claims with literals.
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Organization departments and healthcare-service catalogs
|
|
2
|
+
|
|
3
|
+
This contract keeps four different concepts separate:
|
|
4
|
+
|
|
5
|
+
1. A legal provider is a FHIR `Organization`.
|
|
6
|
+
2. A suborganization or department is another `Organization` whose
|
|
7
|
+
`partOf` references exactly one parent Organization.
|
|
8
|
+
3. An offered capability is a `HealthcareService` whose `providedBy`
|
|
9
|
+
references the department that provides it.
|
|
10
|
+
4. A physical or virtual delivery place is a `Location`; one
|
|
11
|
+
`HealthcareService` can reference several Locations.
|
|
12
|
+
|
|
13
|
+
A department and every offered `HealthcareService` remain distinct FHIR
|
|
14
|
+
resources. A claims-first directory projects one
|
|
15
|
+
`Organization/<department-id>` and one `HealthcareService/<service-id>` per
|
|
16
|
+
offered service. A blood bank can therefore expose blood donation and plasma
|
|
17
|
+
donation independently. Each service can own different Location references and
|
|
18
|
+
be the actor of a different Schedule; Slot duration and availability follow
|
|
19
|
+
that Schedule rather than the department.
|
|
20
|
+
|
|
21
|
+
`buildServiceScheduleFlatGraph(...)` implements that boundary. It emits one
|
|
22
|
+
independent claims-first `Schedule` plus independent `Slot` rows. A 15-minute
|
|
23
|
+
blood-donation interval and a one-hour plasma-donation interval are represented
|
|
24
|
+
by different `Slot.start`/`Slot.end` pairs; duration is never an invented flat
|
|
25
|
+
claim. `Schedule.actor` contains the applicable `HealthcareService` and
|
|
26
|
+
`Location`, while `Schedule.service-type-reference` retains the exact service.
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
const bloodAvailability = buildServiceScheduleFlatGraph({
|
|
30
|
+
scheduleId: 'blood-donation-weekday',
|
|
31
|
+
scheduleIdentifier: 'urn:uuid:blood-donation-weekday',
|
|
32
|
+
name: 'Blood donation weekday schedule',
|
|
33
|
+
healthcareServiceReference: 'HealthcareService/blood-donation',
|
|
34
|
+
locationReference: 'Location/blood-donation-room',
|
|
35
|
+
serviceType: 'http://terminology.hl7.org/CodeSystem/service-type|117',
|
|
36
|
+
planningHorizon: { start: '2026-10-01', end: '2026-10-31' },
|
|
37
|
+
slots: [{
|
|
38
|
+
slotId: 'blood-20261001-0900',
|
|
39
|
+
slotIdentifier: 'urn:uuid:blood-20261001-0900',
|
|
40
|
+
status: 'free',
|
|
41
|
+
start: '2026-10-01T09:00:00-07:00',
|
|
42
|
+
end: '2026-10-01T09:15:00-07:00',
|
|
43
|
+
}],
|
|
44
|
+
})
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The adapters use the published R5 `CodeableReference(HealthcareService)` shape
|
|
48
|
+
for `Schedule.serviceType` and `Slot.serviceType`. Schedule and Slot remain
|
|
49
|
+
separate resources because slots change more frequently than their planning
|
|
50
|
+
container.
|
|
51
|
+
|
|
52
|
+
## Reservable capacity inside one place
|
|
53
|
+
|
|
54
|
+
A public donation or extraction point is a parent `Location`. Each independently
|
|
55
|
+
reservable room, booth, chair or bed is a child `Location.partOf` that parent.
|
|
56
|
+
`buildSchedulableLocationFlatResource(...)` creates those child Locations; a
|
|
57
|
+
clone may reuse coordinates but must use a new Location id and identifier.
|
|
58
|
+
|
|
59
|
+
Equipment is not disguised as a place. An apheresis machine is a FHIR `Device`.
|
|
60
|
+
The Schedule's actor list combines the offered `HealthcareService` with every
|
|
61
|
+
resource that must be available together, for example:
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
HealthcareService/plasma-donation
|
|
65
|
+
Location/plasma-donation-station-1
|
|
66
|
+
Device/apheresis-machine-1
|
|
67
|
+
PractitionerRole/plasma-professional-1
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Closing one station suspends its Location or blocks/deactivates its Schedule;
|
|
71
|
+
it does not cancel sibling stations. FHIR R4 materializes the governed physical
|
|
72
|
+
coding as `Location.physicalType`; R5 materializes it as `Location.form`.
|
|
73
|
+
|
|
74
|
+
## Equipment calibration and authorization
|
|
75
|
+
|
|
76
|
+
A machine used as schedule capacity is still a stable `Device`. Its lifecycle
|
|
77
|
+
has two independent evidence streams:
|
|
78
|
+
|
|
79
|
+
- `buildDeviceCalibrationFlatGraph(...)` records the completed technical work
|
|
80
|
+
as a `Procedure` whose subject and focal device are the machine, records the
|
|
81
|
+
corresponding `DeviceMetric.calibration` state/time, and can attach a
|
|
82
|
+
`DocumentReference` carrying the certificate hash. The maintenance
|
|
83
|
+
Organization and acting PractitionerRole are performers, not public
|
|
84
|
+
regulators.
|
|
85
|
+
- `buildDeviceOperatingAuthorizationFlatResource(...)` records an R5
|
|
86
|
+
`RegulatedAuthorization` issued by the regulator to the holder for the
|
|
87
|
+
installed Location, DeviceDefinition, Organization or governed activity.
|
|
88
|
+
FHIR R5 does not allow an individual Device instance as that resource's
|
|
89
|
+
subject, so installation-specific authorization targets the installed
|
|
90
|
+
Location and retains the individual Device through the associated evidence
|
|
91
|
+
graph.
|
|
92
|
+
|
|
93
|
+
Both builders emit only minimal resource identity and `resource.meta.claims`.
|
|
94
|
+
The product authorization layer must validate the submitting organization's
|
|
95
|
+
credential, the acting role, jurisdiction and current assignment; this neutral
|
|
96
|
+
package deliberately does not decide whether an assistant, laboratory
|
|
97
|
+
technician, maintenance technician or inspector is permitted. Scheduling may
|
|
98
|
+
derive machine eligibility only after authoritative readback shows an active
|
|
99
|
+
Device, a current required calibration and a valid operating authorization.
|
|
100
|
+
It must not trust a browser-supplied `available` boolean.
|
|
101
|
+
|
|
102
|
+
`buildDepartmentServicesFlatGraph(...)` authors the department row followed by
|
|
103
|
+
one row for every service. Its input accepts complete `system|value`
|
|
104
|
+
identifiers, complete `system|code` service/category/specialty tokens and typed
|
|
105
|
+
`Organization/...` or `Location/...` references. It rejects bare split
|
|
106
|
+
fragments and duplicate service ids. The builder writes only `resourceType`,
|
|
107
|
+
`id` and `meta.claims`; it never persists a nested FHIR resource.
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
const [department, bloodDonation, plasmaDonation] = buildDepartmentServicesFlatGraph({
|
|
111
|
+
departmentId: 'blood-bank',
|
|
112
|
+
departmentIdentifier: 'https://example.invalid/departments|blood-bank',
|
|
113
|
+
parentOrganizationReference: 'Organization/provider',
|
|
114
|
+
name: 'Blood bank',
|
|
115
|
+
services: [{
|
|
116
|
+
serviceId: 'blood-donation',
|
|
117
|
+
serviceIdentifier: 'https://example.invalid/services|blood-donation',
|
|
118
|
+
name: 'Blood donation',
|
|
119
|
+
serviceType: ['https://example.invalid/CodeSystem/service-type|blood-donation'],
|
|
120
|
+
locationReferences: ['Location/blood-donation-room'],
|
|
121
|
+
}, {
|
|
122
|
+
serviceId: 'plasma-donation',
|
|
123
|
+
serviceIdentifier: 'https://example.invalid/services|plasma-donation',
|
|
124
|
+
name: 'Plasma donation',
|
|
125
|
+
serviceType: ['https://example.invalid/CodeSystem/service-type|plasma-donation'],
|
|
126
|
+
locationReferences: ['Location/plasma-donation-room'],
|
|
127
|
+
}],
|
|
128
|
+
})
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Two service Locations may carry identical coordinates and copied public media
|
|
132
|
+
when they describe separate operational rooms or check-in configurations. They
|
|
133
|
+
must still have distinct Location identities if schedules or instructions
|
|
134
|
+
differ. If the physical delivery place is genuinely the same resource, both
|
|
135
|
+
services may reference that one Location instead.
|
|
136
|
+
|
|
137
|
+
## Claims-first boundary
|
|
138
|
+
|
|
139
|
+
`HealthcareServiceClaim` contains the complete resource-specific FHIR R4
|
|
140
|
+
search surface. `healthcareServiceFlatToFhirR4` and
|
|
141
|
+
`healthcareServiceFhirR4ToFlat` are the only native-R4 adapter boundary.
|
|
142
|
+
Repeatable coding identities remain complete `system|code` tokens; labels are
|
|
143
|
+
resolved by the terminology service and are not trusted storage identity.
|
|
144
|
+
`HealthcareService.comment` and R5 `Organization.description` are governed
|
|
145
|
+
materialization claims, but are not falsely advertised as R4 SearchParameters.
|
|
146
|
+
|
|
147
|
+
`materializeClaimsFirstResourceToFhirR5(...)` accepts only minimal resource
|
|
148
|
+
identity plus `resource.meta.claims`. It rejects nested native FHIR fields and
|
|
149
|
+
materializes Organization, HealthcareService, Location, Schedule or Slot only for export,
|
|
150
|
+
interop, hashing or credential generation. The resulting R5 object is never
|
|
151
|
+
persisted as a second business source of truth.
|
|
152
|
+
|
|
153
|
+
`LocationClaim` also preserves the official WGS84 longitude, latitude and
|
|
154
|
+
optional altitude needed by a marketplace. Schema.org `Place.image`,
|
|
155
|
+
Organization logos and governed object-storage evidence remain downstream
|
|
156
|
+
catalog concerns because FHIR R4 `Location` has no native image field.
|
|
157
|
+
|
|
158
|
+
## Professional group boundary
|
|
159
|
+
|
|
160
|
+
`normalizeGroupR5ProfessionalServiceTeam` requires one singular
|
|
161
|
+
`Group.managingEntity` reference to one department Organization. A
|
|
162
|
+
professional can belong to several Groups, but one Group cannot span several
|
|
163
|
+
departments in this initial contract. Group membership is descriptive and
|
|
164
|
+
does not grant read, search, appointment, break-glass or communication access.
|
|
165
|
+
|
|
166
|
+
The department needs no independent DID document merely to own a Group or
|
|
167
|
+
HealthcareService. A stable registered Group endpoint can receive a reply for
|
|
168
|
+
the unit. Transport sender, clinical-document author and professional attester
|
|
169
|
+
remain different identities:
|
|
170
|
+
|
|
171
|
+
- product policy may set the legal Organization as `Composition.author`;
|
|
172
|
+
- the acting `PractitionerRole` is the professional attester;
|
|
173
|
+
- the authenticated employee/device is transport audit evidence; and
|
|
174
|
+
- a reply is addressed to the Group endpoint, not authored by the Group.
|
|
175
|
+
|
|
176
|
+
Those authorization, endpoint-registration and authorship policies belong to
|
|
177
|
+
the BFF/high-level SDK, not this neutral package.
|
|
178
|
+
|
|
179
|
+
## C80 to LOINC candidate mapping
|
|
180
|
+
|
|
181
|
+
`SnomedC80ToLoincSpecialtyConceptMap` preserves the supplied 115 distinct C80
|
|
182
|
+
rows and their reviewed relationship to LOINC Subject Matter Domain or
|
|
183
|
+
LL402-9 codes. It is candidate evidence, not an official SNOMED or LOINC map.
|
|
184
|
+
Only rows explicitly classified as strict `equivalent` are returned by
|
|
185
|
+
`findAutomaticLoincSpecialty`. Wider, related, inexact and unmatched rows must
|
|
186
|
+
remain visible for terminology governance and are never applied automatically.
|
|
187
|
+
|
|
188
|
+
Service type and clinical specialty are not interchangeable. For example,
|
|
189
|
+
respite is retained as a related type-of-service candidate rather than being
|
|
190
|
+
silently promoted to a specialty.
|
|
@@ -22,6 +22,7 @@ and transport assumptions must not be copied.
|
|
|
22
22
|
| Old area | Decision | Current destination or gate |
|
|
23
23
|
| --- | --- | --- |
|
|
24
24
|
| `Bundle` and `Composition` traversal | Rewrite from tests | Neutral graph and explicit R4/R5/R6 adapters; preserve author, attester and section boundaries |
|
|
25
|
+
| `gdc-common-utils-ts` Communication attached-Bundle editor/reader | Preserve as read-only migration evidence | Neutral validation/projection tools live here; the replacement high-level editor/reader belongs to `sos-sdk-core`, with shared input contracts in `sos-data-utils` |
|
|
25
26
|
| `CodeableConcept`, `Identifier`, `Reference`, `Quantity` | Rewrite and reuse behavior | Small typed value modules with round-trip tests |
|
|
26
27
|
| `Observation` and resource parameter models | Rewrite | Canonical claim catalogs plus version-specific projection adapters |
|
|
27
28
|
| `Parameters` conversion | Rewrite | A typed FHIR Parameters module; never a transport-specific envelope |
|
|
@@ -45,8 +46,15 @@ and transport assumptions must not be copied.
|
|
|
45
46
|
| `uhc-fhir-utils-typescript` imaging | DICOMDIR structural types only | Byte parsing and pixel extraction require a separately versioned imaging package |
|
|
46
47
|
| `sos-data-utils-ts` | Cross-sector terminology contract and fixtures, Immunization graph and reminder planning | SOS authorization, repository and emergency policy |
|
|
47
48
|
| `vet-data-utils-ts` | Product-neutral FHIR R5 Group and ResearchStudy contracts/search projections | Animal identity, veterinary sections, species, insurance, payment and other Vet policy |
|
|
49
|
+
| Provider catalogs | R4 HealthcareService claims/converter, geocoded Location claims, one-department professional Group normalization and reviewed C80-to-LOINC candidate mappings | Schema.org images/logo storage, marketplace sector policy, endpoint authorization and communication routing |
|
|
48
50
|
| UHC/Vet SDKs | No transport client was copied | SMART clients, Oracle clients, BFF calls and product workflows remain SDK responsibilities |
|
|
49
51
|
|
|
52
|
+
The frozen `gdc-*` implementation remains compatibility evidence. New Vet,
|
|
53
|
+
UHC and SOS code uses the replacement high-level API in `sos-sdk-core`, which
|
|
54
|
+
composes the neutral tools exported here. Neither shared replacement package
|
|
55
|
+
imports `gdc-*`. DIDComm wrapping, post-quantum encryption, endpoint selection
|
|
56
|
+
and delivery retries remain in the SDK/service layer.
|
|
57
|
+
|
|
50
58
|
The migration surface is executable rather than documentary only:
|
|
51
59
|
|
|
52
60
|
- every migrated claim family has a named catalog and shared list helpers;
|
|
@@ -56,10 +64,21 @@ The migration surface is executable rather than documentary only:
|
|
|
56
64
|
searchable metadata without embedding DICOM object bytes;
|
|
57
65
|
- FHIR primitives, typed searches, Bundle traversal and fallback conversion
|
|
58
66
|
have strict success and rejection tests;
|
|
67
|
+
- Communication exchange is authored and read only as outer batch Bundle to
|
|
68
|
+
Communication to inner document/batch/collection Bundle, with files modeled
|
|
69
|
+
as inner DocumentReference resources;
|
|
59
70
|
- Immunization graphs and reminders live once under `src/builders/`; the former
|
|
60
71
|
root modules are deprecated re-export shims;
|
|
61
72
|
- Group and ResearchStudy expose named claim constants, preserve member/party
|
|
62
|
-
correlation as separate rows and reject authorization-shaped data;
|
|
73
|
+
correlation as separate rows and reject authorization-shaped data;
|
|
74
|
+
- Organization departments remain distinct from offered HealthcareServices;
|
|
75
|
+
every independently schedulable service keeps its own stable identity and
|
|
76
|
+
Location references, while professional Group ownership remains explicit;
|
|
77
|
+
- `buildServiceScheduleFlatGraph(...)` and the R5 Schedule/Slot adapters keep
|
|
78
|
+
per-service planning horizons and slot intervals shared between Vet and UHC;
|
|
79
|
+
- schedulable child Locations preserve `partOf`, while Schedule actors can
|
|
80
|
+
combine the service with Location, Device and PractitionerRole capacity;
|
|
81
|
+
and
|
|
63
82
|
- `npm run check` enforces minimum line, function and branch coverage across
|
|
64
83
|
converters, builders and core FHIR modules.
|
|
65
84
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fhir-data-utils-ts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "FHIR-version-neutral flat-claim and SearchParameter data utilities",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -103,6 +103,10 @@
|
|
|
103
103
|
"types": "./dist/group-r5.d.ts",
|
|
104
104
|
"default": "./dist/group-r5.js"
|
|
105
105
|
},
|
|
106
|
+
"./healthcare-service-specialty-map": {
|
|
107
|
+
"types": "./dist/healthcare-service-specialty-map.d.ts",
|
|
108
|
+
"default": "./dist/healthcare-service-specialty-map.js"
|
|
109
|
+
},
|
|
106
110
|
"./research-study-r5": {
|
|
107
111
|
"types": "./dist/research-study-r5.d.ts",
|
|
108
112
|
"default": "./dist/research-study-r5.js"
|