gdc-common-utils-ts 1.4.12 → 1.4.14
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/README.md +8 -0
- package/dist/i18n/clinical-sections.i18n.d.ts +6 -0
- package/dist/i18n/clinical-sections.i18n.js +15 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/models/clinical-sections.d.ts +1 -1
- package/dist/models/clinical-sections.en.d.ts +126 -51
- package/dist/models/clinical-sections.en.js +78 -55
- package/dist/models/clinical-workbook-summary.d.ts +126 -0
- package/dist/models/clinical-workbook-summary.js +67 -0
- package/dist/models/index.d.ts +2 -0
- package/dist/models/index.js +2 -0
- package/dist/models/interoperable-claims/communication-claims.d.ts +2 -1
- package/dist/models/interoperable-claims/communication-claims.js +2 -1
- package/dist/models/loinc-document-ontology.d.ts +55 -0
- package/dist/models/loinc-document-ontology.js +57 -0
- package/dist/utils/communication-fhir-r4.d.ts +23 -0
- package/dist/utils/communication-fhir-r4.js +189 -0
- package/dist/utils/fhir-validator.d.ts +54 -0
- package/dist/utils/fhir-validator.js +84 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,6 +4,13 @@ Shared TypeScript utilities for GDC client and connector code. This package prov
|
|
|
4
4
|
|
|
5
5
|
It is intentionally not a full backend orchestration layer.
|
|
6
6
|
|
|
7
|
+
## Non-Negotiable Conventions
|
|
8
|
+
|
|
9
|
+
- FHIR SearchParameter names must use canonical FHIR naming (lowercase, with `-` when defined by FHIR).
|
|
10
|
+
- Never use invented camelCase parameter names for FHIR claims/search keys (example: `Communication.part-of` is valid, `Communication.partOf` is not).
|
|
11
|
+
- Only define custom names when no canonical FHIR SearchParameter exists.
|
|
12
|
+
- `resource.meta.claims` is the canonical claims container and must be preserved across conversions/transports.
|
|
13
|
+
|
|
7
14
|
## Install
|
|
8
15
|
|
|
9
16
|
```bash
|
|
@@ -48,6 +55,7 @@ The `utils` export exposes reusable helpers for DID and message handling, such a
|
|
|
48
55
|
- `utils/content`
|
|
49
56
|
- `utils/normalize`
|
|
50
57
|
- `utils/fhir-cid` for recursive FHIR canonicalization + CID generation + `meta.versionId` assignment
|
|
58
|
+
- `utils/fhir-validator` for adapter-based FHIR validation (`validateFhirResource`, pluggable formal validator)
|
|
51
59
|
- conversion, formatting, and multibase helpers
|
|
52
60
|
|
|
53
61
|
These helpers support DIDComm-style message construction and related transport/data-shaping workflows.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type ClinicalSectionI18nMap = Readonly<Record<`org.loinc.${string}`, string>>;
|
|
2
|
+
export declare const clinicalSectionsBaseI18nEn: Readonly<Record<`org.loinc.${string}`, string>>;
|
|
3
|
+
export declare const clinicalDocTypesI18nEn: Readonly<Record<`org.loinc.${string}`, string>>;
|
|
4
|
+
export declare const clinicalSectionAdditionalI18nEn: Readonly<Record<`org.loinc.${string}`, string>>;
|
|
5
|
+
export declare const clinicalSectionI18nEn: ClinicalSectionI18nMap;
|
|
6
|
+
export declare const clinicalSectionsI18nEn: Readonly<Record<`org.loinc.${string}`, string>>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { clinicalDocTypes, clinicalSectionAdditional, clinicalSectionsBase, } from '../models/clinical-sections.en.js';
|
|
2
|
+
import { loincI18nKey } from '../models/clinical-sections.js';
|
|
3
|
+
function toClinicalI18nMap(source) {
|
|
4
|
+
const entries = Object.entries(source).map(([code, label]) => [loincI18nKey(code), label]);
|
|
5
|
+
return Object.freeze(Object.fromEntries(entries));
|
|
6
|
+
}
|
|
7
|
+
export const clinicalSectionsBaseI18nEn = toClinicalI18nMap(clinicalSectionsBase);
|
|
8
|
+
export const clinicalDocTypesI18nEn = toClinicalI18nMap(clinicalDocTypes);
|
|
9
|
+
export const clinicalSectionAdditionalI18nEn = toClinicalI18nMap(clinicalSectionAdditional);
|
|
10
|
+
export const clinicalSectionI18nEn = Object.freeze({
|
|
11
|
+
...clinicalSectionsBaseI18nEn,
|
|
12
|
+
...clinicalDocTypesI18nEn,
|
|
13
|
+
...clinicalSectionAdditionalI18nEn,
|
|
14
|
+
});
|
|
15
|
+
export const clinicalSectionsI18nEn = clinicalSectionI18nEn;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -30,7 +30,7 @@ export type ClinicalSectionDescriptor = {
|
|
|
30
30
|
};
|
|
31
31
|
export declare function loincI18nKey(code: string): string;
|
|
32
32
|
export type SupportedClinicalSectionCode = keyof typeof clinicalSectionTitleEn;
|
|
33
|
-
export declare const supportedClinicalSectionCodes: readonly ("
|
|
33
|
+
export declare const supportedClinicalSectionCodes: readonly ("61144-2" | "82810-3" | "87520-3" | "10190-7" | "18726-0" | "10154-3" | "10164-2" | "10183-2" | "10184-0" | "10187-3" | "10210-3" | "10216-0" | "10218-6" | "10222-8" | "10223-6" | "11329-0" | "48768-6" | "51848-0" | "57852-6" | "18776-5" | "18841-7" | "60591-5" | "11493-4" | "11535-2" | "11537-8" | "29299-5" | "29549-3" | "29554-3" | "42344-2" | "42346-7" | "42349-1" | "46241-6" | "55109-3" | "55122-6" | "59768-2" | "59769-0" | "59770-8" | "59771-6" | "59772-4" | "59773-2" | "59775-7" | "59776-5" | "61149-1" | "61150-9" | "69730-0" | "8648-8" | "8653-8" | "11503-0" | "56796-6" | "10157-6" | "10160-0" | "11348-0" | "11369-6" | "11450-4" | "29762-2" | "30954-2" | "42348-3" | "46240-8" | "46264-8" | "47420-5" | "47519-4" | "48765-2" | "56446-8" | "8716-3")[];
|
|
34
34
|
export declare const clinicalSectionRegistry: Readonly<Record<string, ClinicalSectionDescriptor>>;
|
|
35
35
|
export { clinicalSectionTitleEn };
|
|
36
36
|
export declare function getClinicalSectionByCode(code: string): ClinicalSectionDescriptor | undefined;
|
|
@@ -5,71 +5,146 @@
|
|
|
5
5
|
* - This file is intentionally separate from the section registry so apps can:
|
|
6
6
|
* - use these labels as a default (e.g., server-side rendering), and/or
|
|
7
7
|
* - override them via i18n resources keyed by `org.loinc.<CODE>`.
|
|
8
|
-
* -
|
|
8
|
+
* - Source layers:
|
|
9
|
+
* - Base / IPS-aligned sections: HL7 FHIR `doc-section-codes` for `Composition.section`.
|
|
10
|
+
* - Additional labels: project-specific additions and Excel-driven taxonomy entries.
|
|
11
|
+
* - Keep section labels and document-type labels separate in UI permission filters to avoid duplicates.
|
|
12
|
+
* - Broader data-space artifact families such as `RelatedPerson`, `Appointment`, `Communication`,
|
|
13
|
+
* or other sector-independent profiles should live in their own registries.
|
|
9
14
|
*/
|
|
10
|
-
export declare const
|
|
15
|
+
export declare const clinicalSectionsBase: {
|
|
16
|
+
readonly '10157-6': "History of family member diseases";
|
|
17
|
+
readonly '10160-0': "History of Medication use";
|
|
18
|
+
readonly '11348-0': "History of Past illness";
|
|
19
|
+
readonly '11369-6': "History of Immunization";
|
|
20
|
+
readonly '11450-4': "Problem list";
|
|
21
|
+
readonly '29762-2': "Social history";
|
|
22
|
+
readonly '30954-2': "Relevant diagnostic tests/laboratory data";
|
|
23
|
+
readonly '42348-3': "Advance directives";
|
|
24
|
+
readonly '46240-8': "History of Hospitalizations+Outpatient visits";
|
|
25
|
+
readonly '46264-8': "History of medical device use";
|
|
26
|
+
readonly '47420-5': "Functional status";
|
|
27
|
+
readonly '47519-4': "History of Procedures";
|
|
28
|
+
readonly '48765-2': "Allergies and adverse reactions";
|
|
29
|
+
readonly '56446-8': "Appointment summary";
|
|
30
|
+
readonly '8716-3': "Vital signs";
|
|
31
|
+
};
|
|
32
|
+
export declare const clinicalDocTypes: {
|
|
11
33
|
readonly '10154-3': "Chief complaint Narrative - Reported";
|
|
12
|
-
readonly '
|
|
13
|
-
readonly '
|
|
14
|
-
readonly '
|
|
15
|
-
readonly '
|
|
16
|
-
readonly '
|
|
17
|
-
readonly '10187-3': "Review of systems Narrative - Reported";
|
|
18
|
-
readonly '10210-3': "Physical findings of General status Narrative";
|
|
34
|
+
readonly '10164-2': "History of Present illness";
|
|
35
|
+
readonly '10183-2': "Hospital discharge medications";
|
|
36
|
+
readonly '10184-0': "Hospital discharge physical findings";
|
|
37
|
+
readonly '10187-3': "Review of systems";
|
|
38
|
+
readonly '10210-3': "Physical findings of General status";
|
|
19
39
|
readonly '10216-0': "Surgical operation note fluids Narrative";
|
|
20
|
-
readonly '10218-6': "Surgical operation note postoperative diagnosis
|
|
21
|
-
readonly '10222-8': "Surgical operation note surgical complications [Interpretation]
|
|
22
|
-
readonly '10223-6': "Surgical operation note surgical procedure
|
|
23
|
-
readonly '11329-0': "History general
|
|
24
|
-
readonly '
|
|
25
|
-
readonly '
|
|
26
|
-
readonly '
|
|
27
|
-
readonly '11535-2': "Hospital discharge Dx Narrative";
|
|
28
|
-
readonly '11537-8': "Surgical drains Narrative";
|
|
40
|
+
readonly '10218-6': "Surgical operation note postoperative diagnosis";
|
|
41
|
+
readonly '10222-8': "Surgical operation note surgical complications [Interpretation]";
|
|
42
|
+
readonly '10223-6': "Surgical operation note surgical procedure";
|
|
43
|
+
readonly '11329-0': "History general";
|
|
44
|
+
readonly '48768-6': "Payment sources Document";
|
|
45
|
+
readonly '51848-0': "Evaluation note";
|
|
46
|
+
readonly '57852-6': "Problem list Narrative - Reported";
|
|
29
47
|
readonly '18776-5': "Plan of care note";
|
|
30
48
|
readonly '18841-7': "Hospital consultations Document";
|
|
49
|
+
readonly '60591-5': "Patient summary";
|
|
50
|
+
readonly '11493-4': "Hospital discharge studies summary";
|
|
51
|
+
readonly '11535-2': "Hospital discharge Dx";
|
|
52
|
+
readonly '11537-8': "Surgical drains";
|
|
31
53
|
readonly '29299-5': "Reason for visit Narrative";
|
|
32
|
-
readonly '
|
|
33
|
-
readonly '
|
|
34
|
-
readonly '
|
|
35
|
-
readonly '
|
|
36
|
-
readonly '
|
|
37
|
-
readonly '
|
|
38
|
-
readonly '42346-7': "Medications on admission (narrative)";
|
|
39
|
-
readonly '42348-3': "Advance directives";
|
|
40
|
-
readonly '42349-1': "Reason for referral (narrative)";
|
|
41
|
-
readonly '46240-8': "History of Hospitalizations+Outpatient visits Narrative";
|
|
42
|
-
readonly '46241-6': "Hospital admission diagnosis Narrative - Reported";
|
|
43
|
-
readonly '46264-8': "History of medical device use";
|
|
44
|
-
readonly '47420-5': "Functional status assessment note";
|
|
45
|
-
readonly '47519-4': "History of Procedures Document";
|
|
46
|
-
readonly '48765-2': "Allergies and adverse reactions Document";
|
|
47
|
-
readonly '48768-6': "Payment sources Document";
|
|
48
|
-
readonly '51848-0': "Evaluation note";
|
|
54
|
+
readonly '29549-3': "Medication administered";
|
|
55
|
+
readonly '29554-3': "Procedure";
|
|
56
|
+
readonly '42344-2': "Discharge diet";
|
|
57
|
+
readonly '42346-7': "Medications on admission";
|
|
58
|
+
readonly '42349-1': "Reason for referral";
|
|
59
|
+
readonly '46241-6': "Hospital admission diagnosis";
|
|
49
60
|
readonly '55109-3': "Complications Document";
|
|
50
|
-
readonly '55122-6': "Surgical operation note implants
|
|
51
|
-
readonly '
|
|
52
|
-
readonly '
|
|
53
|
-
readonly '
|
|
54
|
-
readonly '
|
|
55
|
-
readonly '
|
|
56
|
-
readonly '
|
|
57
|
-
readonly '
|
|
58
|
-
readonly '
|
|
59
|
-
readonly '
|
|
60
|
-
readonly '
|
|
61
|
-
readonly '61150-9': "Subjective Narrative";
|
|
61
|
+
readonly '55122-6': "Surgical operation note implants";
|
|
62
|
+
readonly '59768-2': "Procedure indications [Interpretation]";
|
|
63
|
+
readonly '59769-0': "Postprocedure diagnosis";
|
|
64
|
+
readonly '59770-8': "Procedure estimated blood loss";
|
|
65
|
+
readonly '59771-6': "Procedure implants";
|
|
66
|
+
readonly '59772-4': "Planned procedure";
|
|
67
|
+
readonly '59773-2': "Procedure specimens taken";
|
|
68
|
+
readonly '59775-7': "Procedure disposition";
|
|
69
|
+
readonly '59776-5': "Procedure findings";
|
|
70
|
+
readonly '61149-1': "Objective";
|
|
71
|
+
readonly '61150-9': "Subjective";
|
|
62
72
|
readonly '69730-0': "Instructions";
|
|
63
|
-
readonly '8648-8': "Hospital course
|
|
73
|
+
readonly '8648-8': "Hospital course";
|
|
64
74
|
readonly '8653-8': "Hospital Discharge instructions";
|
|
65
|
-
readonly '
|
|
66
|
-
readonly '
|
|
67
|
-
|
|
75
|
+
readonly '11503-0': "Medical records (generic)";
|
|
76
|
+
readonly '56796-6': "Healthcare (general)";
|
|
77
|
+
};
|
|
78
|
+
export declare const clinicalSectionAdditional: {
|
|
79
|
+
readonly '61144-2': "Diet";
|
|
80
|
+
readonly '82810-3': "History of pregnancy";
|
|
81
|
+
readonly '87520-3': "Health insurance coverage";
|
|
82
|
+
readonly '10190-7': "Mental status";
|
|
83
|
+
readonly '18726-0': "Radiology studies";
|
|
84
|
+
};
|
|
85
|
+
export declare const clinicalSectionTitleEn: {
|
|
68
86
|
readonly '61144-2': "Diet";
|
|
69
87
|
readonly '82810-3': "History of pregnancy";
|
|
70
88
|
readonly '87520-3': "Health insurance coverage";
|
|
71
89
|
readonly '10190-7': "Mental status";
|
|
72
90
|
readonly '18726-0': "Radiology studies";
|
|
91
|
+
readonly '10154-3': "Chief complaint Narrative - Reported";
|
|
92
|
+
readonly '10164-2': "History of Present illness";
|
|
93
|
+
readonly '10183-2': "Hospital discharge medications";
|
|
94
|
+
readonly '10184-0': "Hospital discharge physical findings";
|
|
95
|
+
readonly '10187-3': "Review of systems";
|
|
96
|
+
readonly '10210-3': "Physical findings of General status";
|
|
97
|
+
readonly '10216-0': "Surgical operation note fluids Narrative";
|
|
98
|
+
readonly '10218-6': "Surgical operation note postoperative diagnosis";
|
|
99
|
+
readonly '10222-8': "Surgical operation note surgical complications [Interpretation]";
|
|
100
|
+
readonly '10223-6': "Surgical operation note surgical procedure";
|
|
101
|
+
readonly '11329-0': "History general";
|
|
102
|
+
readonly '48768-6': "Payment sources Document";
|
|
103
|
+
readonly '51848-0': "Evaluation note";
|
|
104
|
+
readonly '57852-6': "Problem list Narrative - Reported";
|
|
105
|
+
readonly '18776-5': "Plan of care note";
|
|
106
|
+
readonly '18841-7': "Hospital consultations Document";
|
|
107
|
+
readonly '60591-5': "Patient summary";
|
|
108
|
+
readonly '11493-4': "Hospital discharge studies summary";
|
|
109
|
+
readonly '11535-2': "Hospital discharge Dx";
|
|
110
|
+
readonly '11537-8': "Surgical drains";
|
|
111
|
+
readonly '29299-5': "Reason for visit Narrative";
|
|
112
|
+
readonly '29549-3': "Medication administered";
|
|
113
|
+
readonly '29554-3': "Procedure";
|
|
114
|
+
readonly '42344-2': "Discharge diet";
|
|
115
|
+
readonly '42346-7': "Medications on admission";
|
|
116
|
+
readonly '42349-1': "Reason for referral";
|
|
117
|
+
readonly '46241-6': "Hospital admission diagnosis";
|
|
118
|
+
readonly '55109-3': "Complications Document";
|
|
119
|
+
readonly '55122-6': "Surgical operation note implants";
|
|
120
|
+
readonly '59768-2': "Procedure indications [Interpretation]";
|
|
121
|
+
readonly '59769-0': "Postprocedure diagnosis";
|
|
122
|
+
readonly '59770-8': "Procedure estimated blood loss";
|
|
123
|
+
readonly '59771-6': "Procedure implants";
|
|
124
|
+
readonly '59772-4': "Planned procedure";
|
|
125
|
+
readonly '59773-2': "Procedure specimens taken";
|
|
126
|
+
readonly '59775-7': "Procedure disposition";
|
|
127
|
+
readonly '59776-5': "Procedure findings";
|
|
128
|
+
readonly '61149-1': "Objective";
|
|
129
|
+
readonly '61150-9': "Subjective";
|
|
130
|
+
readonly '69730-0': "Instructions";
|
|
131
|
+
readonly '8648-8': "Hospital course";
|
|
132
|
+
readonly '8653-8': "Hospital Discharge instructions";
|
|
73
133
|
readonly '11503-0': "Medical records (generic)";
|
|
74
134
|
readonly '56796-6': "Healthcare (general)";
|
|
135
|
+
readonly '10157-6': "History of family member diseases";
|
|
136
|
+
readonly '10160-0': "History of Medication use";
|
|
137
|
+
readonly '11348-0': "History of Past illness";
|
|
138
|
+
readonly '11369-6': "History of Immunization";
|
|
139
|
+
readonly '11450-4': "Problem list";
|
|
140
|
+
readonly '29762-2': "Social history";
|
|
141
|
+
readonly '30954-2': "Relevant diagnostic tests/laboratory data";
|
|
142
|
+
readonly '42348-3': "Advance directives";
|
|
143
|
+
readonly '46240-8': "History of Hospitalizations+Outpatient visits";
|
|
144
|
+
readonly '46264-8': "History of medical device use";
|
|
145
|
+
readonly '47420-5': "Functional status";
|
|
146
|
+
readonly '47519-4': "History of Procedures";
|
|
147
|
+
readonly '48765-2': "Allergies and adverse reactions";
|
|
148
|
+
readonly '56446-8': "Appointment summary";
|
|
149
|
+
readonly '8716-3': "Vital signs";
|
|
75
150
|
};
|
|
@@ -5,77 +5,100 @@
|
|
|
5
5
|
* - This file is intentionally separate from the section registry so apps can:
|
|
6
6
|
* - use these labels as a default (e.g., server-side rendering), and/or
|
|
7
7
|
* - override them via i18n resources keyed by `org.loinc.<CODE>`.
|
|
8
|
-
* -
|
|
8
|
+
* - Source layers:
|
|
9
|
+
* - Base / IPS-aligned sections: HL7 FHIR `doc-section-codes` for `Composition.section`.
|
|
10
|
+
* - Additional labels: project-specific additions and Excel-driven taxonomy entries.
|
|
11
|
+
* - Keep section labels and document-type labels separate in UI permission filters to avoid duplicates.
|
|
12
|
+
* - Broader data-space artifact families such as `RelatedPerson`, `Appointment`, `Communication`,
|
|
13
|
+
* or other sector-independent profiles should live in their own registries.
|
|
9
14
|
*/
|
|
10
|
-
export const
|
|
15
|
+
export const clinicalSectionsBase = {
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Base / IPS-aligned section labels
|
|
18
|
+
// Source: https://hl7.org/fhir/R4/valueset-doc-section-codes.html
|
|
19
|
+
// These labels are normalized for section use: document suffixes such as
|
|
20
|
+
// Narrative / Document / note are removed when the concept is used as a section.
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
'10157-6': 'History of family member diseases',
|
|
23
|
+
'10160-0': 'History of Medication use',
|
|
24
|
+
'11348-0': 'History of Past illness',
|
|
25
|
+
'11369-6': 'History of Immunization',
|
|
26
|
+
'11450-4': 'Problem list',
|
|
27
|
+
'29762-2': 'Social history',
|
|
28
|
+
'30954-2': 'Relevant diagnostic tests/laboratory data',
|
|
29
|
+
'42348-3': 'Advance directives',
|
|
30
|
+
'46240-8': 'History of Hospitalizations+Outpatient visits',
|
|
31
|
+
'46264-8': 'History of medical device use',
|
|
32
|
+
'47420-5': 'Functional status',
|
|
33
|
+
'47519-4': 'History of Procedures',
|
|
34
|
+
'48765-2': 'Allergies and adverse reactions',
|
|
35
|
+
'56446-8': 'Appointment summary',
|
|
36
|
+
'8716-3': 'Vital signs',
|
|
37
|
+
};
|
|
38
|
+
export const clinicalDocTypes = {
|
|
11
39
|
// ---------------------------------------------------------------------------
|
|
12
|
-
//
|
|
40
|
+
// Document-oriented labels used as buckets or wrappers in the UI.
|
|
41
|
+
// Source: FHIR/IPS document taxonomy and project-specific document buckets.
|
|
13
42
|
// ---------------------------------------------------------------------------
|
|
14
43
|
'10154-3': 'Chief complaint Narrative - Reported',
|
|
15
|
-
'
|
|
16
|
-
'
|
|
17
|
-
'
|
|
18
|
-
'
|
|
19
|
-
'
|
|
20
|
-
'10187-3': 'Review of systems Narrative - Reported',
|
|
21
|
-
'10210-3': 'Physical findings of General status Narrative',
|
|
44
|
+
'10164-2': 'History of Present illness',
|
|
45
|
+
'10183-2': 'Hospital discharge medications',
|
|
46
|
+
'10184-0': 'Hospital discharge physical findings',
|
|
47
|
+
'10187-3': 'Review of systems',
|
|
48
|
+
'10210-3': 'Physical findings of General status',
|
|
22
49
|
'10216-0': 'Surgical operation note fluids Narrative',
|
|
23
|
-
'10218-6': 'Surgical operation note postoperative diagnosis
|
|
24
|
-
'10222-8': 'Surgical operation note surgical complications [Interpretation]
|
|
25
|
-
'10223-6': 'Surgical operation note surgical procedure
|
|
26
|
-
'11329-0': 'History general
|
|
27
|
-
'
|
|
28
|
-
'
|
|
29
|
-
'
|
|
30
|
-
'11535-2': 'Hospital discharge Dx Narrative',
|
|
31
|
-
'11537-8': 'Surgical drains Narrative',
|
|
50
|
+
'10218-6': 'Surgical operation note postoperative diagnosis',
|
|
51
|
+
'10222-8': 'Surgical operation note surgical complications [Interpretation]',
|
|
52
|
+
'10223-6': 'Surgical operation note surgical procedure',
|
|
53
|
+
'11329-0': 'History general',
|
|
54
|
+
'48768-6': 'Payment sources Document',
|
|
55
|
+
'51848-0': 'Evaluation note',
|
|
56
|
+
'57852-6': 'Problem list Narrative - Reported',
|
|
32
57
|
'18776-5': 'Plan of care note',
|
|
33
58
|
'18841-7': 'Hospital consultations Document',
|
|
59
|
+
'60591-5': 'Patient summary',
|
|
60
|
+
'11493-4': 'Hospital discharge studies summary',
|
|
61
|
+
'11535-2': 'Hospital discharge Dx',
|
|
62
|
+
'11537-8': 'Surgical drains',
|
|
34
63
|
'29299-5': 'Reason for visit Narrative',
|
|
35
|
-
'
|
|
36
|
-
'
|
|
37
|
-
'
|
|
38
|
-
'
|
|
39
|
-
'
|
|
40
|
-
'
|
|
41
|
-
'42346-7': 'Medications on admission (narrative)',
|
|
42
|
-
'42348-3': 'Advance directives',
|
|
43
|
-
'42349-1': 'Reason for referral (narrative)',
|
|
44
|
-
'46240-8': 'History of Hospitalizations+Outpatient visits Narrative',
|
|
45
|
-
'46241-6': 'Hospital admission diagnosis Narrative - Reported',
|
|
46
|
-
'46264-8': 'History of medical device use',
|
|
47
|
-
'47420-5': 'Functional status assessment note',
|
|
48
|
-
'47519-4': 'History of Procedures Document',
|
|
49
|
-
'48765-2': 'Allergies and adverse reactions Document',
|
|
50
|
-
'48768-6': 'Payment sources Document',
|
|
51
|
-
'51848-0': 'Evaluation note',
|
|
64
|
+
'29549-3': 'Medication administered',
|
|
65
|
+
'29554-3': 'Procedure',
|
|
66
|
+
'42344-2': 'Discharge diet',
|
|
67
|
+
'42346-7': 'Medications on admission',
|
|
68
|
+
'42349-1': 'Reason for referral',
|
|
69
|
+
'46241-6': 'Hospital admission diagnosis',
|
|
52
70
|
'55109-3': 'Complications Document',
|
|
53
|
-
'55122-6': 'Surgical operation note implants
|
|
54
|
-
'
|
|
55
|
-
'
|
|
56
|
-
'
|
|
57
|
-
'
|
|
58
|
-
'
|
|
59
|
-
'
|
|
60
|
-
'
|
|
61
|
-
'
|
|
62
|
-
'
|
|
63
|
-
'
|
|
64
|
-
'61150-9': 'Subjective Narrative',
|
|
71
|
+
'55122-6': 'Surgical operation note implants',
|
|
72
|
+
'59768-2': 'Procedure indications [Interpretation]',
|
|
73
|
+
'59769-0': 'Postprocedure diagnosis',
|
|
74
|
+
'59770-8': 'Procedure estimated blood loss',
|
|
75
|
+
'59771-6': 'Procedure implants',
|
|
76
|
+
'59772-4': 'Planned procedure',
|
|
77
|
+
'59773-2': 'Procedure specimens taken',
|
|
78
|
+
'59775-7': 'Procedure disposition',
|
|
79
|
+
'59776-5': 'Procedure findings',
|
|
80
|
+
'61149-1': 'Objective',
|
|
81
|
+
'61150-9': 'Subjective',
|
|
65
82
|
'69730-0': 'Instructions',
|
|
66
|
-
'8648-8': 'Hospital course
|
|
83
|
+
'8648-8': 'Hospital course',
|
|
67
84
|
'8653-8': 'Hospital Discharge instructions',
|
|
68
|
-
'
|
|
85
|
+
'11503-0': 'Medical records (generic)',
|
|
86
|
+
'56796-6': 'Healthcare (general)',
|
|
87
|
+
};
|
|
88
|
+
export const clinicalSectionAdditional = {
|
|
69
89
|
// ---------------------------------------------------------------------------
|
|
70
|
-
//
|
|
90
|
+
// Additional Excel / project-driven sections
|
|
91
|
+
// Source: local workbook derived from the LOINC ontology tables and product needs.
|
|
92
|
+
// Keep these out of the base permission list to avoid duplicate section semantics.
|
|
71
93
|
// ---------------------------------------------------------------------------
|
|
72
|
-
'60591-5': 'Patient summary',
|
|
73
|
-
'11450-4': 'Problem list',
|
|
74
94
|
'61144-2': 'Diet',
|
|
75
95
|
'82810-3': 'History of pregnancy',
|
|
76
96
|
'87520-3': 'Health insurance coverage',
|
|
77
97
|
'10190-7': 'Mental status',
|
|
78
98
|
'18726-0': 'Radiology studies',
|
|
79
|
-
|
|
80
|
-
|
|
99
|
+
};
|
|
100
|
+
export const clinicalSectionTitleEn = {
|
|
101
|
+
...clinicalSectionsBase,
|
|
102
|
+
...clinicalDocTypes,
|
|
103
|
+
...clinicalSectionAdditional,
|
|
81
104
|
};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workbook summary extracted from rows marked Include = Y/y.
|
|
3
|
+
*
|
|
4
|
+
* Source workbook: Sections-from-LOINC_Document_Ontology_Tables.xlsx
|
|
5
|
+
* This summary is separate from the full LP taxonomy and from the clinical section registry.
|
|
6
|
+
*/
|
|
7
|
+
export declare const clinicalWorkbookSummaryLabelI18nEn: Readonly<{
|
|
8
|
+
readonly 'org.loinc.LP447691-9': "Administrative information";
|
|
9
|
+
readonly 'org.loinc.LP173390-8': "Certificate";
|
|
10
|
+
readonly 'org.loinc.LP173394-0': "Consent";
|
|
11
|
+
readonly 'org.loinc.LP173404-7': "Health insurance card";
|
|
12
|
+
readonly 'org.loinc.LP181119-1': "Action plan";
|
|
13
|
+
readonly 'org.loinc.LP181204-1': "Prescription";
|
|
14
|
+
readonly 'org.loinc.LP173421-1': "Report";
|
|
15
|
+
readonly 'org.loinc.LP437010-4': "Goals, preferences, and priorities for care experience";
|
|
16
|
+
readonly 'org.loinc.LP310260-7': "Care management";
|
|
17
|
+
readonly 'org.loinc.LP173209-0': "Plan of care";
|
|
18
|
+
readonly 'org.loinc.LP200117-2': "Summary of encounters";
|
|
19
|
+
readonly 'org.loinc.LP203673-1': "Notification";
|
|
20
|
+
readonly 'org.loinc.LP172918-7': "Anesthesiology";
|
|
21
|
+
readonly 'org.loinc.LP172919-5': "Audiology";
|
|
22
|
+
readonly 'org.loinc.LP172923-7': "Chiropractic medicine";
|
|
23
|
+
readonly 'org.loinc.LP172934-4': "Dentistry";
|
|
24
|
+
readonly 'org.loinc.LP172935-1': "Dermatology";
|
|
25
|
+
readonly 'org.loinc.LP172957-5': "Medical toxicology";
|
|
26
|
+
readonly 'org.loinc.LP183499-5': "Trauma";
|
|
27
|
+
readonly 'org.loinc.LP172943-5': "Family medicine";
|
|
28
|
+
readonly 'org.loinc.LP172894-0': "Forensic medicine";
|
|
29
|
+
readonly 'org.loinc.LP172946-8': "General medicine";
|
|
30
|
+
readonly 'org.loinc.LP172911-2': "Acupuncture";
|
|
31
|
+
readonly 'org.loinc.LP172941-9': "Endocrinology";
|
|
32
|
+
readonly 'org.loinc.LP172945-0': "Gastroenterology";
|
|
33
|
+
readonly 'org.loinc.LP172947-6': "Geriatric medicine";
|
|
34
|
+
readonly 'org.loinc.LP175685-9': "Hematology";
|
|
35
|
+
readonly 'org.loinc.LP172951-8': "Infectious disease";
|
|
36
|
+
readonly 'org.loinc.LP175686-7': "Medical Oncology";
|
|
37
|
+
readonly 'org.loinc.LP172962-5': "Nephrology";
|
|
38
|
+
readonly 'org.loinc.LP173015-1': "Pulmonary disease";
|
|
39
|
+
readonly 'org.loinc.LP173023-5': "Rheumatology";
|
|
40
|
+
readonly 'org.loinc.LP248728-0': "Sleep medicine";
|
|
41
|
+
readonly 'org.loinc.LP417852-3': "Solid organ transplant";
|
|
42
|
+
readonly 'org.loinc.LP173027-6': "Sports medicine";
|
|
43
|
+
readonly 'org.loinc.LP172956-7': "Medical genetics";
|
|
44
|
+
readonly 'org.loinc.LP173011-0': "Psychiatry";
|
|
45
|
+
readonly 'org.loinc.LP173012-8': "Psychology";
|
|
46
|
+
readonly 'org.loinc.LP345049-3': "Cleft and Craniofacial";
|
|
47
|
+
readonly 'org.loinc.LP172964-1': "Neurology";
|
|
48
|
+
readonly 'org.loinc.LP172968-2': "Nuclear medicine";
|
|
49
|
+
readonly 'org.loinc.LP172899-9': "Nutrition and dietetics";
|
|
50
|
+
readonly 'org.loinc.LP172971-6': "Obstetrics and gynecology";
|
|
51
|
+
readonly 'org.loinc.LP172973-2': "Occupational therapy";
|
|
52
|
+
readonly 'org.loinc.LP172901-3': "Oncology";
|
|
53
|
+
readonly 'org.loinc.LP172974-0': "Ophthalmology";
|
|
54
|
+
readonly 'org.loinc.LP434870-4': "Orthopaedic";
|
|
55
|
+
readonly 'org.loinc.LP172979-9': "Orthotics prosthetics";
|
|
56
|
+
readonly 'org.loinc.LP434767-2': "Osteopathic medicine";
|
|
57
|
+
readonly 'org.loinc.LP172980-7': "Otolaryngology";
|
|
58
|
+
readonly 'org.loinc.LP172982-3': "Palliative care";
|
|
59
|
+
readonly 'org.loinc.LP172984-9': "Pathology";
|
|
60
|
+
readonly 'org.loinc.LP173002-9': "Pediatrics";
|
|
61
|
+
readonly 'org.loinc.LP173004-5': "Physical medicine and rehabilitation";
|
|
62
|
+
readonly 'org.loinc.LP173008-6': "Podiatry";
|
|
63
|
+
readonly 'org.loinc.LP173018-5': "Radiology";
|
|
64
|
+
readonly 'org.loinc.LP173036-7': "Urology";
|
|
65
|
+
readonly 'org.loinc.LP248732-2': "Womens health";
|
|
66
|
+
}>;
|
|
67
|
+
export declare const clinicalWorkbookSummaryLabelsEn: Readonly<{
|
|
68
|
+
readonly 'org.loinc.LP447691-9': "Administrative information";
|
|
69
|
+
readonly 'org.loinc.LP173390-8': "Certificate";
|
|
70
|
+
readonly 'org.loinc.LP173394-0': "Consent";
|
|
71
|
+
readonly 'org.loinc.LP173404-7': "Health insurance card";
|
|
72
|
+
readonly 'org.loinc.LP181119-1': "Action plan";
|
|
73
|
+
readonly 'org.loinc.LP181204-1': "Prescription";
|
|
74
|
+
readonly 'org.loinc.LP173421-1': "Report";
|
|
75
|
+
readonly 'org.loinc.LP437010-4': "Goals, preferences, and priorities for care experience";
|
|
76
|
+
readonly 'org.loinc.LP310260-7': "Care management";
|
|
77
|
+
readonly 'org.loinc.LP173209-0': "Plan of care";
|
|
78
|
+
readonly 'org.loinc.LP200117-2': "Summary of encounters";
|
|
79
|
+
readonly 'org.loinc.LP203673-1': "Notification";
|
|
80
|
+
readonly 'org.loinc.LP172918-7': "Anesthesiology";
|
|
81
|
+
readonly 'org.loinc.LP172919-5': "Audiology";
|
|
82
|
+
readonly 'org.loinc.LP172923-7': "Chiropractic medicine";
|
|
83
|
+
readonly 'org.loinc.LP172934-4': "Dentistry";
|
|
84
|
+
readonly 'org.loinc.LP172935-1': "Dermatology";
|
|
85
|
+
readonly 'org.loinc.LP172957-5': "Medical toxicology";
|
|
86
|
+
readonly 'org.loinc.LP183499-5': "Trauma";
|
|
87
|
+
readonly 'org.loinc.LP172943-5': "Family medicine";
|
|
88
|
+
readonly 'org.loinc.LP172894-0': "Forensic medicine";
|
|
89
|
+
readonly 'org.loinc.LP172946-8': "General medicine";
|
|
90
|
+
readonly 'org.loinc.LP172911-2': "Acupuncture";
|
|
91
|
+
readonly 'org.loinc.LP172941-9': "Endocrinology";
|
|
92
|
+
readonly 'org.loinc.LP172945-0': "Gastroenterology";
|
|
93
|
+
readonly 'org.loinc.LP172947-6': "Geriatric medicine";
|
|
94
|
+
readonly 'org.loinc.LP175685-9': "Hematology";
|
|
95
|
+
readonly 'org.loinc.LP172951-8': "Infectious disease";
|
|
96
|
+
readonly 'org.loinc.LP175686-7': "Medical Oncology";
|
|
97
|
+
readonly 'org.loinc.LP172962-5': "Nephrology";
|
|
98
|
+
readonly 'org.loinc.LP173015-1': "Pulmonary disease";
|
|
99
|
+
readonly 'org.loinc.LP173023-5': "Rheumatology";
|
|
100
|
+
readonly 'org.loinc.LP248728-0': "Sleep medicine";
|
|
101
|
+
readonly 'org.loinc.LP417852-3': "Solid organ transplant";
|
|
102
|
+
readonly 'org.loinc.LP173027-6': "Sports medicine";
|
|
103
|
+
readonly 'org.loinc.LP172956-7': "Medical genetics";
|
|
104
|
+
readonly 'org.loinc.LP173011-0': "Psychiatry";
|
|
105
|
+
readonly 'org.loinc.LP173012-8': "Psychology";
|
|
106
|
+
readonly 'org.loinc.LP345049-3': "Cleft and Craniofacial";
|
|
107
|
+
readonly 'org.loinc.LP172964-1': "Neurology";
|
|
108
|
+
readonly 'org.loinc.LP172968-2': "Nuclear medicine";
|
|
109
|
+
readonly 'org.loinc.LP172899-9': "Nutrition and dietetics";
|
|
110
|
+
readonly 'org.loinc.LP172971-6': "Obstetrics and gynecology";
|
|
111
|
+
readonly 'org.loinc.LP172973-2': "Occupational therapy";
|
|
112
|
+
readonly 'org.loinc.LP172901-3': "Oncology";
|
|
113
|
+
readonly 'org.loinc.LP172974-0': "Ophthalmology";
|
|
114
|
+
readonly 'org.loinc.LP434870-4': "Orthopaedic";
|
|
115
|
+
readonly 'org.loinc.LP172979-9': "Orthotics prosthetics";
|
|
116
|
+
readonly 'org.loinc.LP434767-2': "Osteopathic medicine";
|
|
117
|
+
readonly 'org.loinc.LP172980-7': "Otolaryngology";
|
|
118
|
+
readonly 'org.loinc.LP172982-3': "Palliative care";
|
|
119
|
+
readonly 'org.loinc.LP172984-9': "Pathology";
|
|
120
|
+
readonly 'org.loinc.LP173002-9': "Pediatrics";
|
|
121
|
+
readonly 'org.loinc.LP173004-5': "Physical medicine and rehabilitation";
|
|
122
|
+
readonly 'org.loinc.LP173008-6': "Podiatry";
|
|
123
|
+
readonly 'org.loinc.LP173018-5': "Radiology";
|
|
124
|
+
readonly 'org.loinc.LP173036-7': "Urology";
|
|
125
|
+
readonly 'org.loinc.LP248732-2': "Womens health";
|
|
126
|
+
}>;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workbook summary extracted from rows marked Include = Y/y.
|
|
3
|
+
*
|
|
4
|
+
* Source workbook: Sections-from-LOINC_Document_Ontology_Tables.xlsx
|
|
5
|
+
* This summary is separate from the full LP taxonomy and from the clinical section registry.
|
|
6
|
+
*/
|
|
7
|
+
export const clinicalWorkbookSummaryLabelI18nEn = Object.freeze({
|
|
8
|
+
'org.loinc.LP447691-9': "Administrative information",
|
|
9
|
+
'org.loinc.LP173390-8': "Certificate",
|
|
10
|
+
'org.loinc.LP173394-0': "Consent",
|
|
11
|
+
'org.loinc.LP173404-7': "Health insurance card",
|
|
12
|
+
'org.loinc.LP181119-1': "Action plan",
|
|
13
|
+
'org.loinc.LP181204-1': "Prescription",
|
|
14
|
+
'org.loinc.LP173421-1': "Report",
|
|
15
|
+
'org.loinc.LP437010-4': "Goals, preferences, and priorities for care experience",
|
|
16
|
+
'org.loinc.LP310260-7': "Care management",
|
|
17
|
+
'org.loinc.LP173209-0': "Plan of care",
|
|
18
|
+
'org.loinc.LP200117-2': "Summary of encounters",
|
|
19
|
+
'org.loinc.LP203673-1': "Notification",
|
|
20
|
+
'org.loinc.LP172918-7': "Anesthesiology",
|
|
21
|
+
'org.loinc.LP172919-5': "Audiology",
|
|
22
|
+
'org.loinc.LP172923-7': "Chiropractic medicine",
|
|
23
|
+
'org.loinc.LP172934-4': "Dentistry",
|
|
24
|
+
'org.loinc.LP172935-1': "Dermatology",
|
|
25
|
+
'org.loinc.LP172957-5': "Medical toxicology",
|
|
26
|
+
'org.loinc.LP183499-5': "Trauma",
|
|
27
|
+
'org.loinc.LP172943-5': "Family medicine",
|
|
28
|
+
'org.loinc.LP172894-0': "Forensic medicine",
|
|
29
|
+
'org.loinc.LP172946-8': "General medicine",
|
|
30
|
+
'org.loinc.LP172911-2': "Acupuncture",
|
|
31
|
+
'org.loinc.LP172941-9': "Endocrinology",
|
|
32
|
+
'org.loinc.LP172945-0': "Gastroenterology",
|
|
33
|
+
'org.loinc.LP172947-6': "Geriatric medicine",
|
|
34
|
+
'org.loinc.LP175685-9': "Hematology",
|
|
35
|
+
'org.loinc.LP172951-8': "Infectious disease",
|
|
36
|
+
'org.loinc.LP175686-7': "Medical Oncology",
|
|
37
|
+
'org.loinc.LP172962-5': "Nephrology",
|
|
38
|
+
'org.loinc.LP173015-1': "Pulmonary disease",
|
|
39
|
+
'org.loinc.LP173023-5': "Rheumatology",
|
|
40
|
+
'org.loinc.LP248728-0': "Sleep medicine",
|
|
41
|
+
'org.loinc.LP417852-3': "Solid organ transplant",
|
|
42
|
+
'org.loinc.LP173027-6': "Sports medicine",
|
|
43
|
+
'org.loinc.LP172956-7': "Medical genetics",
|
|
44
|
+
'org.loinc.LP173011-0': "Psychiatry",
|
|
45
|
+
'org.loinc.LP173012-8': "Psychology",
|
|
46
|
+
'org.loinc.LP345049-3': "Cleft and Craniofacial",
|
|
47
|
+
'org.loinc.LP172964-1': "Neurology",
|
|
48
|
+
'org.loinc.LP172968-2': "Nuclear medicine",
|
|
49
|
+
'org.loinc.LP172899-9': "Nutrition and dietetics",
|
|
50
|
+
'org.loinc.LP172971-6': "Obstetrics and gynecology",
|
|
51
|
+
'org.loinc.LP172973-2': "Occupational therapy",
|
|
52
|
+
'org.loinc.LP172901-3': "Oncology",
|
|
53
|
+
'org.loinc.LP172974-0': "Ophthalmology",
|
|
54
|
+
'org.loinc.LP434870-4': "Orthopaedic",
|
|
55
|
+
'org.loinc.LP172979-9': "Orthotics prosthetics",
|
|
56
|
+
'org.loinc.LP434767-2': "Osteopathic medicine",
|
|
57
|
+
'org.loinc.LP172980-7': "Otolaryngology",
|
|
58
|
+
'org.loinc.LP172982-3': "Palliative care",
|
|
59
|
+
'org.loinc.LP172984-9': "Pathology",
|
|
60
|
+
'org.loinc.LP173002-9': "Pediatrics",
|
|
61
|
+
'org.loinc.LP173004-5': "Physical medicine and rehabilitation",
|
|
62
|
+
'org.loinc.LP173008-6': "Podiatry",
|
|
63
|
+
'org.loinc.LP173018-5': "Radiology",
|
|
64
|
+
'org.loinc.LP173036-7': "Urology",
|
|
65
|
+
'org.loinc.LP248732-2': "Womens health",
|
|
66
|
+
});
|
|
67
|
+
export const clinicalWorkbookSummaryLabelsEn = clinicalWorkbookSummaryLabelI18nEn;
|
package/dist/models/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from './bundle';
|
|
|
4
4
|
export * from './comm';
|
|
5
5
|
export * from './clinical-sections';
|
|
6
6
|
export * from './clinical-sections.en';
|
|
7
|
+
export * from './clinical-workbook-summary';
|
|
7
8
|
export * from './confidential-job';
|
|
8
9
|
export * from './confidential-message';
|
|
9
10
|
export * from './confidential-storage';
|
|
@@ -20,6 +21,7 @@ export * from './jwe';
|
|
|
20
21
|
export * from './jwk';
|
|
21
22
|
export * from './jws';
|
|
22
23
|
export * from './jwt';
|
|
24
|
+
export * from './loinc-document-ontology';
|
|
23
25
|
export * from './oidc4ida.common.model';
|
|
24
26
|
export * from './oidc4ida.document.model';
|
|
25
27
|
export * from './oidc4ida.electronicRecord.model';
|
package/dist/models/index.js
CHANGED
|
@@ -4,6 +4,7 @@ export * from './bundle.js';
|
|
|
4
4
|
export * from './comm.js';
|
|
5
5
|
export * from './clinical-sections.js';
|
|
6
6
|
export * from './clinical-sections.en.js';
|
|
7
|
+
export * from './clinical-workbook-summary.js';
|
|
7
8
|
export * from './confidential-job.js';
|
|
8
9
|
export * from './confidential-message.js';
|
|
9
10
|
export * from './confidential-storage.js';
|
|
@@ -20,6 +21,7 @@ export * from './jwe.js';
|
|
|
20
21
|
export * from './jwk.js';
|
|
21
22
|
export * from './jws.js';
|
|
22
23
|
export * from './jwt.js';
|
|
24
|
+
export * from './loinc-document-ontology.js';
|
|
23
25
|
export * from './oidc4ida.common.model.js';
|
|
24
26
|
export * from './oidc4ida.document.model.js';
|
|
25
27
|
export * from './oidc4ida.electronicRecord.model.js';
|
|
@@ -9,6 +9,7 @@ export declare const CommunicationClaim: {
|
|
|
9
9
|
readonly ContentAttachmentData: "Communication.content-attachment-data";
|
|
10
10
|
readonly ContentAttachmentType: "Communication.content-attachment-type";
|
|
11
11
|
readonly ContentAttachmentTitle: "Communication.content-attachment-title";
|
|
12
|
-
readonly PartOf: "Communication.
|
|
12
|
+
readonly PartOf: "Communication.part-of";
|
|
13
|
+
readonly PartOfLegacy: "Communication.partOf";
|
|
13
14
|
};
|
|
14
15
|
export type CommunicationClaimKey = typeof CommunicationClaim[keyof typeof CommunicationClaim];
|
|
@@ -11,5 +11,6 @@ export const CommunicationClaim = {
|
|
|
11
11
|
ContentAttachmentData: 'Communication.content-attachment-data',
|
|
12
12
|
ContentAttachmentType: 'Communication.content-attachment-type',
|
|
13
13
|
ContentAttachmentTitle: 'Communication.content-attachment-title',
|
|
14
|
-
PartOf: 'Communication.
|
|
14
|
+
PartOf: 'Communication.part-of',
|
|
15
|
+
PartOfLegacy: 'Communication.partOf',
|
|
15
16
|
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LOINC Document Ontology helpers for Communication ingestion workflows.
|
|
3
|
+
*
|
|
4
|
+
* Source:
|
|
5
|
+
* - https://loinc.org/kb/users-guide/document-ontology/
|
|
6
|
+
*
|
|
7
|
+
* Notes:
|
|
8
|
+
* - LP codes are represented as bare codes (e.g., "LP173418-7").
|
|
9
|
+
* - When a claim requires a coding token value, prefer `LOINC|<CODE>`.
|
|
10
|
+
*/
|
|
11
|
+
export declare const LOINC_TOKEN_PREFIX: "LOINC|";
|
|
12
|
+
export declare function toLoincToken(code: string): `${typeof LOINC_TOKEN_PREFIX}${string}`;
|
|
13
|
+
export declare const loincOntology: Readonly<{
|
|
14
|
+
KindOfDocument: Readonly<{
|
|
15
|
+
Note: Readonly<{
|
|
16
|
+
code: "LP173418-7";
|
|
17
|
+
AdverseEventNote: Readonly<{
|
|
18
|
+
code: "LP173419-5";
|
|
19
|
+
}>;
|
|
20
|
+
Alert: Readonly<{
|
|
21
|
+
code: "LP173420-3";
|
|
22
|
+
}>;
|
|
23
|
+
AppointmentReminder: Readonly<{
|
|
24
|
+
code: "LP434808-4";
|
|
25
|
+
}>;
|
|
26
|
+
ArrivalNotificationNote: Readonly<{
|
|
27
|
+
code: "LP436847-0";
|
|
28
|
+
}>;
|
|
29
|
+
ComprehensivePlanOfCareNote: Readonly<{
|
|
30
|
+
code: "LP436848-8";
|
|
31
|
+
}>;
|
|
32
|
+
ClinicalNote: Readonly<{
|
|
33
|
+
code: "LP447692-7";
|
|
34
|
+
}>;
|
|
35
|
+
ScreeningInvitationLetter: Readonly<{
|
|
36
|
+
code: "LP448671-0";
|
|
37
|
+
}>;
|
|
38
|
+
ImplantedDeviceNote: Readonly<{
|
|
39
|
+
code: "LP450051-0";
|
|
40
|
+
}>;
|
|
41
|
+
RepositoryInitialEvaluationNote: Readonly<{
|
|
42
|
+
code: "LP436851-2";
|
|
43
|
+
}>;
|
|
44
|
+
}>;
|
|
45
|
+
}>;
|
|
46
|
+
}>;
|
|
47
|
+
/**
|
|
48
|
+
* Defaults agreed for Communication ingestion:
|
|
49
|
+
* - datatype: KindOfDocument.Note
|
|
50
|
+
* - category: Arrival notification note
|
|
51
|
+
*/
|
|
52
|
+
export declare const communicationIngestionDefaults: Readonly<{
|
|
53
|
+
datatype: `LOINC|${string}`;
|
|
54
|
+
category: `LOINC|${string}`;
|
|
55
|
+
}>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LOINC Document Ontology helpers for Communication ingestion workflows.
|
|
3
|
+
*
|
|
4
|
+
* Source:
|
|
5
|
+
* - https://loinc.org/kb/users-guide/document-ontology/
|
|
6
|
+
*
|
|
7
|
+
* Notes:
|
|
8
|
+
* - LP codes are represented as bare codes (e.g., "LP173418-7").
|
|
9
|
+
* - When a claim requires a coding token value, prefer `LOINC|<CODE>`.
|
|
10
|
+
*/
|
|
11
|
+
export const LOINC_TOKEN_PREFIX = 'LOINC|';
|
|
12
|
+
export function toLoincToken(code) {
|
|
13
|
+
return `${LOINC_TOKEN_PREFIX}${code}`;
|
|
14
|
+
}
|
|
15
|
+
export const loincOntology = Object.freeze({
|
|
16
|
+
KindOfDocument: Object.freeze({
|
|
17
|
+
Note: Object.freeze({
|
|
18
|
+
code: 'LP173418-7',
|
|
19
|
+
AdverseEventNote: Object.freeze({
|
|
20
|
+
code: 'LP173419-5',
|
|
21
|
+
}),
|
|
22
|
+
Alert: Object.freeze({
|
|
23
|
+
code: 'LP173420-3',
|
|
24
|
+
}),
|
|
25
|
+
AppointmentReminder: Object.freeze({
|
|
26
|
+
code: 'LP434808-4',
|
|
27
|
+
}),
|
|
28
|
+
ArrivalNotificationNote: Object.freeze({
|
|
29
|
+
code: 'LP436847-0',
|
|
30
|
+
}),
|
|
31
|
+
ComprehensivePlanOfCareNote: Object.freeze({
|
|
32
|
+
code: 'LP436848-8',
|
|
33
|
+
}),
|
|
34
|
+
ClinicalNote: Object.freeze({
|
|
35
|
+
code: 'LP447692-7',
|
|
36
|
+
}),
|
|
37
|
+
ScreeningInvitationLetter: Object.freeze({
|
|
38
|
+
code: 'LP448671-0',
|
|
39
|
+
}),
|
|
40
|
+
ImplantedDeviceNote: Object.freeze({
|
|
41
|
+
code: 'LP450051-0',
|
|
42
|
+
}),
|
|
43
|
+
RepositoryInitialEvaluationNote: Object.freeze({
|
|
44
|
+
code: 'LP436851-2',
|
|
45
|
+
}),
|
|
46
|
+
}),
|
|
47
|
+
}),
|
|
48
|
+
});
|
|
49
|
+
/**
|
|
50
|
+
* Defaults agreed for Communication ingestion:
|
|
51
|
+
* - datatype: KindOfDocument.Note
|
|
52
|
+
* - category: Arrival notification note
|
|
53
|
+
*/
|
|
54
|
+
export const communicationIngestionDefaults = Object.freeze({
|
|
55
|
+
datatype: toLoincToken(loincOntology.KindOfDocument.Note.code),
|
|
56
|
+
category: toLoincToken(loincOntology.KindOfDocument.Note.ArrivalNotificationNote.code),
|
|
57
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type CommunicationClaims = Record<string, unknown>;
|
|
2
|
+
export type CommunicationTransformMode = 'strict' | 'normalize';
|
|
3
|
+
export type TransformCommunicationClaimsToResourceFhirR4Options = {
|
|
4
|
+
mode?: CommunicationTransformMode;
|
|
5
|
+
defaultStatus?: string;
|
|
6
|
+
};
|
|
7
|
+
export type TransformCommunicationClaimsToResourceFhirR4Result = {
|
|
8
|
+
resources: Array<Record<string, unknown>>;
|
|
9
|
+
warnings: string[];
|
|
10
|
+
};
|
|
11
|
+
export declare function validateCommunicationResourceFhirR4(resource: Record<string, unknown>): Promise<{
|
|
12
|
+
ok: boolean;
|
|
13
|
+
issues: Array<{
|
|
14
|
+
severity: 'error' | 'warning';
|
|
15
|
+
code: string;
|
|
16
|
+
diagnostics: string;
|
|
17
|
+
expression?: string;
|
|
18
|
+
}>;
|
|
19
|
+
}>;
|
|
20
|
+
export declare function transformCommunicationClaimsToResourceFhirR4(communicationClaims: CommunicationClaims[], options?: TransformCommunicationClaimsToResourceFhirR4Options): TransformCommunicationClaimsToResourceFhirR4Result;
|
|
21
|
+
export declare function extractCommunicationClaimsFromResourceFhirR4(resource: Record<string, unknown>, options?: {
|
|
22
|
+
preferMetaClaims?: boolean;
|
|
23
|
+
}): CommunicationClaims;
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { validateFhirResource } from './fhir-validator.js';
|
|
2
|
+
export async function validateCommunicationResourceFhirR4(resource) {
|
|
3
|
+
return validateFhirResource(resource, 'r4');
|
|
4
|
+
}
|
|
5
|
+
export function transformCommunicationClaimsToResourceFhirR4(communicationClaims, options = {}) {
|
|
6
|
+
const mode = options.mode ?? 'strict';
|
|
7
|
+
const defaultStatus = options.defaultStatus ?? 'completed';
|
|
8
|
+
const warnings = [];
|
|
9
|
+
const resources = communicationClaims.map((claims, index) => {
|
|
10
|
+
const payloadAttachmentData = toStringOrUndefined(claims['Communication.content-attachment-data']);
|
|
11
|
+
const payloadAttachmentType = toStringOrUndefined(claims['Communication.content-attachment-type']);
|
|
12
|
+
const payloadAttachmentTitle = toStringOrUndefined(claims['Communication.content-attachment-title']);
|
|
13
|
+
const payloadAttachmentUrl = toStringOrUndefined(claims['Communication.content-attachment-url']);
|
|
14
|
+
const payloadReference = toStringOrUndefined(claims['Communication.content-reference']);
|
|
15
|
+
const payloadCodeRaw = toStringOrUndefined(claims['Communication.content-code']);
|
|
16
|
+
const hasAttachment = Boolean(payloadAttachmentData || payloadAttachmentType || payloadAttachmentTitle || payloadAttachmentUrl);
|
|
17
|
+
const hasReference = Boolean(payloadReference);
|
|
18
|
+
const hasCode = Boolean(payloadCodeRaw);
|
|
19
|
+
const payloadKinds = [hasAttachment, hasReference, hasCode].filter(Boolean).length;
|
|
20
|
+
if (payloadKinds > 1) {
|
|
21
|
+
const msg = `Communication[${index}] has more than one payload kind (attachment/reference/code).`;
|
|
22
|
+
if (mode === 'strict')
|
|
23
|
+
throw new Error(msg);
|
|
24
|
+
warnings.push(`${msg} Keeping attachment > reference > code.`);
|
|
25
|
+
}
|
|
26
|
+
const noteValues = normalizeNoteValues(claims['Communication.note'] ?? claims['Communication.text']);
|
|
27
|
+
if (noteValues.length > 1) {
|
|
28
|
+
const msg = `Communication[${index}] has more than one note.`;
|
|
29
|
+
if (mode === 'strict')
|
|
30
|
+
throw new Error(msg);
|
|
31
|
+
warnings.push(`${msg} Keeping first note only.`);
|
|
32
|
+
}
|
|
33
|
+
const payload = buildPayload({
|
|
34
|
+
hasAttachment,
|
|
35
|
+
hasReference,
|
|
36
|
+
hasCode,
|
|
37
|
+
payloadAttachmentData,
|
|
38
|
+
payloadAttachmentType,
|
|
39
|
+
payloadAttachmentTitle,
|
|
40
|
+
payloadAttachmentUrl,
|
|
41
|
+
payloadReference,
|
|
42
|
+
payloadCodeRaw,
|
|
43
|
+
});
|
|
44
|
+
const partOf = toStringOrUndefined(claims['Communication.part-of'] ?? claims['Communication.partOf']);
|
|
45
|
+
if (claims['Communication.partOf'] !== undefined) {
|
|
46
|
+
const msg = `Communication[${index}] uses legacy key 'Communication.partOf'. Use 'Communication.part-of'.`;
|
|
47
|
+
if (mode === 'strict')
|
|
48
|
+
throw new Error(msg);
|
|
49
|
+
warnings.push(msg);
|
|
50
|
+
}
|
|
51
|
+
const resource = {
|
|
52
|
+
resourceType: 'Communication',
|
|
53
|
+
status: toStringOrUndefined(claims['Communication.status']) || defaultStatus,
|
|
54
|
+
meta: {
|
|
55
|
+
claims: { ...claims },
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
const identifier = toStringOrUndefined(claims['Communication.identifier']);
|
|
59
|
+
if (identifier)
|
|
60
|
+
resource['identifier'] = [{ value: identifier }];
|
|
61
|
+
const sent = toStringOrUndefined(claims['Communication.sent']);
|
|
62
|
+
if (sent)
|
|
63
|
+
resource['sent'] = sent;
|
|
64
|
+
const category = toStringOrUndefined(claims['Communication.category']);
|
|
65
|
+
if (category)
|
|
66
|
+
resource['category'] = [{ coding: [parseSystemCode(category)] }];
|
|
67
|
+
const subject = toStringOrUndefined(claims['Communication.subject']);
|
|
68
|
+
if (subject)
|
|
69
|
+
resource['subject'] = { reference: subject };
|
|
70
|
+
const recipient = toStringOrUndefined(claims['Communication.recipient']);
|
|
71
|
+
if (recipient)
|
|
72
|
+
resource['recipient'] = [{ reference: recipient }];
|
|
73
|
+
const sender = toStringOrUndefined(claims['Communication.sender']);
|
|
74
|
+
if (sender)
|
|
75
|
+
resource['sender'] = { reference: sender };
|
|
76
|
+
if (partOf)
|
|
77
|
+
resource['partOf'] = [{ reference: partOf }];
|
|
78
|
+
if (payload)
|
|
79
|
+
resource['payload'] = [payload];
|
|
80
|
+
if (noteValues.length)
|
|
81
|
+
resource['note'] = [{ text: noteValues[0] }];
|
|
82
|
+
return resource;
|
|
83
|
+
});
|
|
84
|
+
return { resources, warnings };
|
|
85
|
+
}
|
|
86
|
+
export function extractCommunicationClaimsFromResourceFhirR4(resource, options = {}) {
|
|
87
|
+
const preferMetaClaims = options.preferMetaClaims !== false;
|
|
88
|
+
const existingClaims = resource?.meta?.claims;
|
|
89
|
+
if (preferMetaClaims && existingClaims && typeof existingClaims === 'object') {
|
|
90
|
+
return { ...existingClaims };
|
|
91
|
+
}
|
|
92
|
+
const claims = {};
|
|
93
|
+
claims['@context'] = 'org.hl7.fhir.r4';
|
|
94
|
+
const identifierValue = resource?.identifier?.[0]?.value;
|
|
95
|
+
const status = resource?.status;
|
|
96
|
+
const sent = resource?.sent;
|
|
97
|
+
const subjectRef = resource?.subject?.reference;
|
|
98
|
+
const recipientRef = resource?.recipient?.[0]?.reference;
|
|
99
|
+
const senderRef = resource?.sender?.reference;
|
|
100
|
+
const partOfRef = resource?.partOf?.[0]?.reference;
|
|
101
|
+
const noteText = resource?.note?.[0]?.text;
|
|
102
|
+
const categoryCoding = resource?.category?.[0]?.coding?.[0];
|
|
103
|
+
const payload = resource?.payload?.[0];
|
|
104
|
+
const contentReference = payload?.contentReference?.reference;
|
|
105
|
+
const contentAttachment = payload?.contentAttachment;
|
|
106
|
+
const contentCodeableConcept = payload?.contentCodeableConcept?.coding?.[0];
|
|
107
|
+
setIf(claims, 'Communication.identifier', identifierValue);
|
|
108
|
+
setIf(claims, 'Communication.status', status);
|
|
109
|
+
setIf(claims, 'Communication.sent', sent);
|
|
110
|
+
setIf(claims, 'Communication.subject', subjectRef);
|
|
111
|
+
setIf(claims, 'Communication.recipient', recipientRef);
|
|
112
|
+
setIf(claims, 'Communication.sender', senderRef);
|
|
113
|
+
setIf(claims, 'Communication.part-of', partOfRef);
|
|
114
|
+
setIf(claims, 'Communication.text', noteText);
|
|
115
|
+
setIf(claims, 'Communication.note', noteText);
|
|
116
|
+
if (categoryCoding) {
|
|
117
|
+
const system = toStringOrUndefined(categoryCoding.system);
|
|
118
|
+
const code = toStringOrUndefined(categoryCoding.code);
|
|
119
|
+
if (system && code)
|
|
120
|
+
claims['Communication.category'] = `${system}|${code}`;
|
|
121
|
+
else if (code)
|
|
122
|
+
claims['Communication.category'] = code;
|
|
123
|
+
}
|
|
124
|
+
setIf(claims, 'Communication.content-reference', contentReference);
|
|
125
|
+
if (contentAttachment) {
|
|
126
|
+
setIf(claims, 'Communication.content-attachment-data', contentAttachment.data);
|
|
127
|
+
setIf(claims, 'Communication.content-attachment-type', contentAttachment.contentType);
|
|
128
|
+
setIf(claims, 'Communication.content-attachment-title', contentAttachment.title);
|
|
129
|
+
setIf(claims, 'Communication.content-attachment-url', contentAttachment.url);
|
|
130
|
+
}
|
|
131
|
+
if (contentCodeableConcept) {
|
|
132
|
+
const system = toStringOrUndefined(contentCodeableConcept.system);
|
|
133
|
+
const code = toStringOrUndefined(contentCodeableConcept.code);
|
|
134
|
+
if (system && code)
|
|
135
|
+
claims['Communication.content-code'] = `${system}|${code}`;
|
|
136
|
+
else if (code)
|
|
137
|
+
claims['Communication.content-code'] = code;
|
|
138
|
+
}
|
|
139
|
+
return claims;
|
|
140
|
+
}
|
|
141
|
+
function setIf(claims, key, value) {
|
|
142
|
+
const text = toStringOrUndefined(value);
|
|
143
|
+
if (text)
|
|
144
|
+
claims[key] = text;
|
|
145
|
+
}
|
|
146
|
+
function normalizeNoteValues(raw) {
|
|
147
|
+
if (typeof raw === 'string' && raw.trim())
|
|
148
|
+
return [raw.trim()];
|
|
149
|
+
if (Array.isArray(raw)) {
|
|
150
|
+
return raw.map((item) => (typeof item === 'string' ? item.trim() : '')).filter(Boolean);
|
|
151
|
+
}
|
|
152
|
+
return [];
|
|
153
|
+
}
|
|
154
|
+
function buildPayload(input) {
|
|
155
|
+
const { hasAttachment, hasReference, hasCode, payloadAttachmentData, payloadAttachmentType, payloadAttachmentTitle, payloadAttachmentUrl, payloadReference, payloadCodeRaw, } = input;
|
|
156
|
+
if (hasAttachment) {
|
|
157
|
+
const value = {};
|
|
158
|
+
if (payloadAttachmentData)
|
|
159
|
+
value['data'] = payloadAttachmentData;
|
|
160
|
+
if (payloadAttachmentType)
|
|
161
|
+
value['contentType'] = payloadAttachmentType;
|
|
162
|
+
if (payloadAttachmentTitle)
|
|
163
|
+
value['title'] = payloadAttachmentTitle;
|
|
164
|
+
if (payloadAttachmentUrl)
|
|
165
|
+
value['url'] = payloadAttachmentUrl;
|
|
166
|
+
return { contentAttachment: value };
|
|
167
|
+
}
|
|
168
|
+
if (hasReference)
|
|
169
|
+
return { contentReference: { reference: payloadReference } };
|
|
170
|
+
if (hasCode && payloadCodeRaw)
|
|
171
|
+
return { contentCodeableConcept: { coding: [parseSystemCode(payloadCodeRaw)] } };
|
|
172
|
+
return undefined;
|
|
173
|
+
}
|
|
174
|
+
function parseSystemCode(value) {
|
|
175
|
+
const trimmed = String(value || '').trim();
|
|
176
|
+
const separatorIndex = trimmed.indexOf('|');
|
|
177
|
+
if (separatorIndex > 0) {
|
|
178
|
+
const system = trimmed.slice(0, separatorIndex).trim();
|
|
179
|
+
const code = trimmed.slice(separatorIndex + 1).trim();
|
|
180
|
+
return { system, code };
|
|
181
|
+
}
|
|
182
|
+
return { code: trimmed };
|
|
183
|
+
}
|
|
184
|
+
function toStringOrUndefined(value) {
|
|
185
|
+
if (value === undefined || value === null)
|
|
186
|
+
return undefined;
|
|
187
|
+
const text = String(value).trim();
|
|
188
|
+
return text || undefined;
|
|
189
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export type FhirVersion = 'r4' | 'r5' | string;
|
|
2
|
+
export type FhirValidationIssue = {
|
|
3
|
+
severity: 'error' | 'warning';
|
|
4
|
+
code: string;
|
|
5
|
+
diagnostics: string;
|
|
6
|
+
expression?: string;
|
|
7
|
+
};
|
|
8
|
+
export type FhirValidationResult = {
|
|
9
|
+
ok: boolean;
|
|
10
|
+
issues: FhirValidationIssue[];
|
|
11
|
+
};
|
|
12
|
+
export type FhirValidatorAdapter = {
|
|
13
|
+
/**
|
|
14
|
+
* Stable adapter id for observability/configuration.
|
|
15
|
+
* Example: `basic`, `hl7-official-cli`, `hapi`.
|
|
16
|
+
*/
|
|
17
|
+
id: string;
|
|
18
|
+
/**
|
|
19
|
+
* Returns true when this adapter can validate the requested FHIR version.
|
|
20
|
+
*/
|
|
21
|
+
supports(version: FhirVersion): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Validates one resource and returns OperationOutcome-like issues.
|
|
24
|
+
*/
|
|
25
|
+
validate(resource: Record<string, unknown>, version: FhirVersion): Promise<FhirValidationResult> | FhirValidationResult;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Registers a custom FHIR validator adapter.
|
|
29
|
+
* Adapters are checked in registration order.
|
|
30
|
+
*/
|
|
31
|
+
export declare function registerFhirValidatorAdapter(adapter: FhirValidatorAdapter): void;
|
|
32
|
+
/**
|
|
33
|
+
* Clears all registered adapters.
|
|
34
|
+
* Intended for tests or explicit runtime reconfiguration.
|
|
35
|
+
*/
|
|
36
|
+
export declare function clearFhirValidatorAdapters(): void;
|
|
37
|
+
/**
|
|
38
|
+
* Returns currently registered adapters (read-only copy).
|
|
39
|
+
*/
|
|
40
|
+
export declare function listFhirValidatorAdapters(): FhirValidatorAdapter[];
|
|
41
|
+
/**
|
|
42
|
+
* Validates a FHIR resource using the first registered adapter that supports the requested version.
|
|
43
|
+
* Falls back to built-in structural validation when no adapter matches.
|
|
44
|
+
*
|
|
45
|
+
* This utility is intentionally adapter-based so SDK/GW can share one validation entrypoint while
|
|
46
|
+
* keeping the formal validator implementation pluggable per deployment.
|
|
47
|
+
*/
|
|
48
|
+
export declare function validateFhirResource(resource: Record<string, unknown>, version?: FhirVersion): Promise<FhirValidationResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Minimal built-in structural validation.
|
|
51
|
+
* This does not replace a formal HL7 profile validator; it provides a safe baseline
|
|
52
|
+
* and deterministic checks for common gateway constraints.
|
|
53
|
+
*/
|
|
54
|
+
export declare function validateFhirResourceBasic(resource: Record<string, unknown>, _version?: FhirVersion): FhirValidationResult;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const validators = [];
|
|
2
|
+
/**
|
|
3
|
+
* Registers a custom FHIR validator adapter.
|
|
4
|
+
* Adapters are checked in registration order.
|
|
5
|
+
*/
|
|
6
|
+
export function registerFhirValidatorAdapter(adapter) {
|
|
7
|
+
validators.push(adapter);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Clears all registered adapters.
|
|
11
|
+
* Intended for tests or explicit runtime reconfiguration.
|
|
12
|
+
*/
|
|
13
|
+
export function clearFhirValidatorAdapters() {
|
|
14
|
+
validators.length = 0;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Returns currently registered adapters (read-only copy).
|
|
18
|
+
*/
|
|
19
|
+
export function listFhirValidatorAdapters() {
|
|
20
|
+
return [...validators];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Validates a FHIR resource using the first registered adapter that supports the requested version.
|
|
24
|
+
* Falls back to built-in structural validation when no adapter matches.
|
|
25
|
+
*
|
|
26
|
+
* This utility is intentionally adapter-based so SDK/GW can share one validation entrypoint while
|
|
27
|
+
* keeping the formal validator implementation pluggable per deployment.
|
|
28
|
+
*/
|
|
29
|
+
export async function validateFhirResource(resource, version = 'r4') {
|
|
30
|
+
const adapter = validators.find((item) => item.supports(version));
|
|
31
|
+
if (adapter)
|
|
32
|
+
return adapter.validate(resource, version);
|
|
33
|
+
return validateFhirResourceBasic(resource, version);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Minimal built-in structural validation.
|
|
37
|
+
* This does not replace a formal HL7 profile validator; it provides a safe baseline
|
|
38
|
+
* and deterministic checks for common gateway constraints.
|
|
39
|
+
*/
|
|
40
|
+
export function validateFhirResourceBasic(resource, _version = 'r4') {
|
|
41
|
+
const issues = [];
|
|
42
|
+
const resourceType = String(resource?.resourceType || '').trim();
|
|
43
|
+
if (!resourceType) {
|
|
44
|
+
issues.push({
|
|
45
|
+
severity: 'error',
|
|
46
|
+
code: 'required',
|
|
47
|
+
diagnostics: 'Missing required field: resourceType.',
|
|
48
|
+
expression: 'resourceType',
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
if (resourceType === 'Communication') {
|
|
52
|
+
const status = String(resource?.status || '').trim();
|
|
53
|
+
if (!status) {
|
|
54
|
+
issues.push({
|
|
55
|
+
severity: 'error',
|
|
56
|
+
code: 'required',
|
|
57
|
+
diagnostics: 'Communication.status is required.',
|
|
58
|
+
expression: 'Communication.status',
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
const payload = resource?.payload;
|
|
62
|
+
if (Array.isArray(payload) && payload.length > 1) {
|
|
63
|
+
issues.push({
|
|
64
|
+
severity: 'warning',
|
|
65
|
+
code: 'business-rule',
|
|
66
|
+
diagnostics: 'Gateway convention recommends one payload per Communication.',
|
|
67
|
+
expression: 'Communication.payload',
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
const note = resource?.note;
|
|
71
|
+
if (Array.isArray(note) && note.length > 1) {
|
|
72
|
+
issues.push({
|
|
73
|
+
severity: 'warning',
|
|
74
|
+
code: 'business-rule',
|
|
75
|
+
diagnostics: 'Gateway convention recommends one note per Communication.',
|
|
76
|
+
expression: 'Communication.note',
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
ok: issues.every((issue) => issue.severity !== 'error'),
|
|
82
|
+
issues,
|
|
83
|
+
};
|
|
84
|
+
}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export * from './didcomm-submit';
|
|
|
10
10
|
export * from './didcomm-submit-policy';
|
|
11
11
|
export * from './format-converter';
|
|
12
12
|
export * from './fhir-cid';
|
|
13
|
+
export * from './communication-fhir-r4';
|
|
14
|
+
export * from './fhir-validator';
|
|
13
15
|
export * from './jwt';
|
|
14
16
|
export * from './manager-error';
|
|
15
17
|
export * from './multibase58';
|
package/dist/utils/index.js
CHANGED
|
@@ -10,6 +10,8 @@ export * from './didcomm-submit.js';
|
|
|
10
10
|
export * from './didcomm-submit-policy.js';
|
|
11
11
|
export * from './format-converter.js';
|
|
12
12
|
export * from './fhir-cid.js';
|
|
13
|
+
export * from './communication-fhir-r4.js';
|
|
14
|
+
export * from './fhir-validator.js';
|
|
13
15
|
export * from './jwt.js';
|
|
14
16
|
export * from './manager-error.js';
|
|
15
17
|
export * from './multibase58.js';
|