fhir-data-utils-ts 0.6.7 → 0.6.8
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/CHANGELOG.md +7 -0
- package/README.md +13 -0
- package/dist/data/clinical-document-encounter-journey.data.d.ts +172 -0
- package/dist/data/clinical-document-encounter-journey.data.js +152 -0
- package/dist/data/index.d.ts +1 -0
- package/dist/data/index.js +1 -0
- package/dist/data/ips-all-sections.data.d.ts +19 -0
- package/dist/data/ips-all-sections.data.js +25 -6
- package/dist/data/ips-clinical-artifact-schemas.data.d.ts +13 -0
- package/dist/data/ips-clinical-artifact-schemas.data.js +57 -7
- package/docs/CLINICAL_DOCUMENT_ENCOUNTER_EXPLORATION.md +41 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- Add section-specific Observation authoring profiles for vital signs,
|
|
6
|
+
laboratory results, social history and pregnancy history. Each profile owns
|
|
7
|
+
its IPS section, HL7 Observation category and initial claims.
|
|
8
|
+
- Add a reusable synthetic document directory in which every document starts
|
|
9
|
+
with Composition, points to its Encounter context and shares a chronological
|
|
10
|
+
parent/child Encounter journey. ResearchSubject is deliberately absent.
|
|
11
|
+
|
|
5
12
|
- Export data-only, coverage-excluded authoring schemas for the six minimum IPS
|
|
6
13
|
resource families used by shared Personal and Professional forms:
|
|
7
14
|
AllergyIntolerance, MedicationStatement, Immunization, Condition, Procedure
|
package/README.md
CHANGED
|
@@ -209,6 +209,19 @@ journeys, emergency ServiceRequest plus triage Task, and cohort
|
|
|
209
209
|
CommunicationRequest against a frozen Group snapshot. See
|
|
210
210
|
[the contract guide](docs/CARE_EMERGENCY_ALERT_CONTRACTS.md). Product policy,
|
|
211
211
|
access, encryption and delivery do not belong in these builders.
|
|
212
|
+
|
|
213
|
+
## Clinical documents and Encounter journeys
|
|
214
|
+
|
|
215
|
+
A FHIR document always starts with `Composition`; `Encounter` is its optional
|
|
216
|
+
care context through `Composition.encounter`, not the document root. The same
|
|
217
|
+
section viewer can therefore render an IPS, emergency note, progress note or
|
|
218
|
+
diagnostic report by reading the Composition title/type and section graph.
|
|
219
|
+
|
|
220
|
+
Encounter navigation is a separate journey graph. Child service encounters
|
|
221
|
+
use `Encounter.partOf` for the strict care hierarchy and their periods provide
|
|
222
|
+
chronological previous/next navigation. The individual remains the clinical
|
|
223
|
+
subject. `ResearchSubject` is not used for care delivery or document browsing.
|
|
224
|
+
See [Clinical documents and Encounter exploration](docs/CLINICAL_DOCUMENT_ENCOUNTER_EXPLORATION.md).
|
|
212
225
|
# Coding-review workflow
|
|
213
226
|
|
|
214
227
|
Imported wording remains in the resource's canonical `*-text` flat claim. Each
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/** Product-neutral synthetic document directory linked to a chronological Encounter hierarchy. */
|
|
2
|
+
export declare const FHIR_CLINICAL_DOCUMENT_ENCOUNTER_JOURNEY_TEST_DATA: Readonly<{
|
|
3
|
+
subject: Readonly<{
|
|
4
|
+
reference: "Patient/jane-doe-demo";
|
|
5
|
+
displayName: "Jane Doe";
|
|
6
|
+
}>;
|
|
7
|
+
encounterCount: number;
|
|
8
|
+
documentCount: 3;
|
|
9
|
+
encounters: readonly (Readonly<{
|
|
10
|
+
resourceType: "Encounter";
|
|
11
|
+
id: "admission-demo";
|
|
12
|
+
status: "in-progress";
|
|
13
|
+
class: Readonly<{
|
|
14
|
+
code: "IMP";
|
|
15
|
+
display: "Inpatient encounter";
|
|
16
|
+
}>;
|
|
17
|
+
subject: Readonly<{
|
|
18
|
+
reference: "Patient/jane-doe-demo";
|
|
19
|
+
}>;
|
|
20
|
+
serviceProvider: Readonly<{
|
|
21
|
+
reference: "Organization/demo-hospital";
|
|
22
|
+
}>;
|
|
23
|
+
actualPeriod: Readonly<{
|
|
24
|
+
start: "2026-10-03T08:00:00Z";
|
|
25
|
+
}>;
|
|
26
|
+
}> | Readonly<{
|
|
27
|
+
resourceType: "Encounter";
|
|
28
|
+
id: string;
|
|
29
|
+
status: "completed" | "in-progress";
|
|
30
|
+
class: Readonly<{
|
|
31
|
+
code: "IMP";
|
|
32
|
+
display: "Inpatient encounter";
|
|
33
|
+
}>;
|
|
34
|
+
subject: Readonly<{
|
|
35
|
+
reference: "Patient/jane-doe-demo";
|
|
36
|
+
}>;
|
|
37
|
+
serviceType: readonly {
|
|
38
|
+
concept: Readonly<{
|
|
39
|
+
text: string;
|
|
40
|
+
}>;
|
|
41
|
+
}[];
|
|
42
|
+
serviceProvider: Readonly<{
|
|
43
|
+
reference: "Organization/demo-hospital";
|
|
44
|
+
}>;
|
|
45
|
+
actualPeriod: Readonly<{
|
|
46
|
+
end?: string | undefined;
|
|
47
|
+
start: string;
|
|
48
|
+
}>;
|
|
49
|
+
location: readonly {
|
|
50
|
+
location: Readonly<{
|
|
51
|
+
reference: `Location/${string}`;
|
|
52
|
+
display: string;
|
|
53
|
+
}>;
|
|
54
|
+
}[];
|
|
55
|
+
partOf: Readonly<{
|
|
56
|
+
reference: "Encounter/admission-demo";
|
|
57
|
+
}>;
|
|
58
|
+
}>)[];
|
|
59
|
+
documents: readonly Readonly<{
|
|
60
|
+
resourceType: "Bundle";
|
|
61
|
+
id: `bundle-${string}`;
|
|
62
|
+
identifier: Readonly<{
|
|
63
|
+
system: "urn:ietf:rfc:3986";
|
|
64
|
+
value: `urn:uuid:${string}`;
|
|
65
|
+
}>;
|
|
66
|
+
type: "document";
|
|
67
|
+
timestamp: string;
|
|
68
|
+
entry: readonly (Readonly<{
|
|
69
|
+
fullUrl: string;
|
|
70
|
+
resource: Readonly<{
|
|
71
|
+
resourceType: "Composition";
|
|
72
|
+
id: string;
|
|
73
|
+
status: "final";
|
|
74
|
+
type: Readonly<{
|
|
75
|
+
text: string;
|
|
76
|
+
}>;
|
|
77
|
+
subject: readonly {
|
|
78
|
+
reference: "Patient/jane-doe-demo";
|
|
79
|
+
}[];
|
|
80
|
+
encounter: Readonly<{
|
|
81
|
+
reference: string;
|
|
82
|
+
}>;
|
|
83
|
+
date: string;
|
|
84
|
+
author: readonly {
|
|
85
|
+
reference: string;
|
|
86
|
+
}[];
|
|
87
|
+
title: string;
|
|
88
|
+
section: readonly {
|
|
89
|
+
title: string;
|
|
90
|
+
entry: readonly {
|
|
91
|
+
reference: string;
|
|
92
|
+
}[];
|
|
93
|
+
}[];
|
|
94
|
+
}>;
|
|
95
|
+
}> | Readonly<{
|
|
96
|
+
fullUrl: "Patient/jane-doe-demo";
|
|
97
|
+
resource: Readonly<{
|
|
98
|
+
resourceType: "Patient";
|
|
99
|
+
id: "jane-doe-demo";
|
|
100
|
+
name: readonly {
|
|
101
|
+
given: readonly string[];
|
|
102
|
+
family: string;
|
|
103
|
+
}[];
|
|
104
|
+
}>;
|
|
105
|
+
}> | Readonly<{
|
|
106
|
+
fullUrl: "Organization/demo-hospital";
|
|
107
|
+
resource: Readonly<{
|
|
108
|
+
resourceType: "Organization";
|
|
109
|
+
id: "demo-hospital";
|
|
110
|
+
name: "Demo Hospital";
|
|
111
|
+
}>;
|
|
112
|
+
}> | Readonly<{
|
|
113
|
+
fullUrl: "Encounter/admission-demo";
|
|
114
|
+
resource: Readonly<{
|
|
115
|
+
resourceType: "Encounter";
|
|
116
|
+
id: "admission-demo";
|
|
117
|
+
status: "in-progress";
|
|
118
|
+
class: Readonly<{
|
|
119
|
+
code: "IMP";
|
|
120
|
+
display: "Inpatient encounter";
|
|
121
|
+
}>;
|
|
122
|
+
subject: Readonly<{
|
|
123
|
+
reference: "Patient/jane-doe-demo";
|
|
124
|
+
}>;
|
|
125
|
+
serviceProvider: Readonly<{
|
|
126
|
+
reference: "Organization/demo-hospital";
|
|
127
|
+
}>;
|
|
128
|
+
actualPeriod: Readonly<{
|
|
129
|
+
start: "2026-10-03T08:00:00Z";
|
|
130
|
+
}>;
|
|
131
|
+
}>;
|
|
132
|
+
}> | Readonly<{
|
|
133
|
+
fullUrl: string;
|
|
134
|
+
resource: Readonly<{
|
|
135
|
+
resourceType: "Encounter";
|
|
136
|
+
id: string;
|
|
137
|
+
status: "completed" | "in-progress";
|
|
138
|
+
class: Readonly<{
|
|
139
|
+
code: "IMP";
|
|
140
|
+
display: "Inpatient encounter";
|
|
141
|
+
}>;
|
|
142
|
+
subject: Readonly<{
|
|
143
|
+
reference: "Patient/jane-doe-demo";
|
|
144
|
+
}>;
|
|
145
|
+
serviceType: readonly {
|
|
146
|
+
concept: Readonly<{
|
|
147
|
+
text: string;
|
|
148
|
+
}>;
|
|
149
|
+
}[];
|
|
150
|
+
serviceProvider: Readonly<{
|
|
151
|
+
reference: "Organization/demo-hospital";
|
|
152
|
+
}>;
|
|
153
|
+
actualPeriod: Readonly<{
|
|
154
|
+
end?: string | undefined;
|
|
155
|
+
start: string;
|
|
156
|
+
}>;
|
|
157
|
+
location: readonly {
|
|
158
|
+
location: Readonly<{
|
|
159
|
+
reference: `Location/${string}`;
|
|
160
|
+
display: string;
|
|
161
|
+
}>;
|
|
162
|
+
}[];
|
|
163
|
+
partOf: Readonly<{
|
|
164
|
+
reference: "Encounter/admission-demo";
|
|
165
|
+
}>;
|
|
166
|
+
}>;
|
|
167
|
+
}> | Readonly<{
|
|
168
|
+
fullUrl: string;
|
|
169
|
+
resource: Readonly<Record<string, unknown>>;
|
|
170
|
+
}>)[];
|
|
171
|
+
}>[];
|
|
172
|
+
}>;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/** Product-neutral synthetic document directory linked to a chronological Encounter hierarchy. */
|
|
2
|
+
const subject = Object.freeze({
|
|
3
|
+
reference: 'Patient/jane-doe-demo',
|
|
4
|
+
displayName: 'Jane Doe',
|
|
5
|
+
});
|
|
6
|
+
const organizationReference = 'Organization/demo-hospital';
|
|
7
|
+
const parentEncounterReference = 'Encounter/admission-demo';
|
|
8
|
+
const parentEncounter = Object.freeze({
|
|
9
|
+
resourceType: 'Encounter',
|
|
10
|
+
id: 'admission-demo',
|
|
11
|
+
status: 'in-progress',
|
|
12
|
+
class: Object.freeze({ code: 'IMP', display: 'Inpatient encounter' }),
|
|
13
|
+
subject: Object.freeze({ reference: subject.reference }),
|
|
14
|
+
serviceProvider: Object.freeze({ reference: organizationReference }),
|
|
15
|
+
actualPeriod: Object.freeze({ start: '2026-10-03T08:00:00Z' }),
|
|
16
|
+
});
|
|
17
|
+
function stage(input) {
|
|
18
|
+
return Object.freeze({
|
|
19
|
+
resourceType: 'Encounter',
|
|
20
|
+
id: input.id,
|
|
21
|
+
status: input.status,
|
|
22
|
+
class: Object.freeze({ code: 'IMP', display: 'Inpatient encounter' }),
|
|
23
|
+
subject: Object.freeze({ reference: subject.reference }),
|
|
24
|
+
serviceType: Object.freeze([{ concept: Object.freeze({ text: input.serviceDisplay }) }]),
|
|
25
|
+
serviceProvider: Object.freeze({ reference: organizationReference }),
|
|
26
|
+
actualPeriod: Object.freeze({ start: input.start, ...(input.end ? { end: input.end } : {}) }),
|
|
27
|
+
location: Object.freeze([{ location: Object.freeze({ reference: `Location/${input.id}`, display: input.locationDisplay }) }]),
|
|
28
|
+
partOf: Object.freeze({ reference: parentEncounterReference }),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
const emergencyEncounter = stage({
|
|
32
|
+
id: 'emergency-demo',
|
|
33
|
+
status: 'completed',
|
|
34
|
+
serviceDisplay: 'Emergency department',
|
|
35
|
+
locationDisplay: 'Emergency bay',
|
|
36
|
+
start: '2026-10-03T08:05:00Z',
|
|
37
|
+
end: '2026-10-03T10:10:00Z',
|
|
38
|
+
});
|
|
39
|
+
const imagingEncounter = stage({
|
|
40
|
+
id: 'imaging-demo',
|
|
41
|
+
status: 'completed',
|
|
42
|
+
serviceDisplay: 'Diagnostic imaging',
|
|
43
|
+
locationDisplay: 'Imaging department',
|
|
44
|
+
start: '2026-10-03T10:10:00Z',
|
|
45
|
+
end: '2026-10-03T11:00:00Z',
|
|
46
|
+
});
|
|
47
|
+
const intensiveCareEncounter = stage({
|
|
48
|
+
id: 'intensive-care-demo',
|
|
49
|
+
status: 'in-progress',
|
|
50
|
+
serviceDisplay: 'Intensive care',
|
|
51
|
+
locationDisplay: 'Intensive care unit',
|
|
52
|
+
start: '2026-10-03T11:00:00Z',
|
|
53
|
+
});
|
|
54
|
+
const encounters = Object.freeze([
|
|
55
|
+
parentEncounter,
|
|
56
|
+
emergencyEncounter,
|
|
57
|
+
imagingEncounter,
|
|
58
|
+
intensiveCareEncounter,
|
|
59
|
+
]);
|
|
60
|
+
function documentBundle(input) {
|
|
61
|
+
const compositionReference = `Composition/${input.id}`;
|
|
62
|
+
const clinicalReference = `${input.clinicalResource.resourceType}/${input.clinicalResource.id}`;
|
|
63
|
+
const encounterReference = `Encounter/${input.encounter.id}`;
|
|
64
|
+
const composition = Object.freeze({
|
|
65
|
+
resourceType: 'Composition',
|
|
66
|
+
id: input.id,
|
|
67
|
+
status: 'final',
|
|
68
|
+
type: Object.freeze({ text: input.type }),
|
|
69
|
+
subject: Object.freeze([{ reference: subject.reference }]),
|
|
70
|
+
encounter: Object.freeze({ reference: encounterReference }),
|
|
71
|
+
date: input.timestamp,
|
|
72
|
+
author: Object.freeze([{ reference: organizationReference }]),
|
|
73
|
+
title: input.title,
|
|
74
|
+
section: Object.freeze([{
|
|
75
|
+
title: input.sectionTitle,
|
|
76
|
+
entry: Object.freeze([{ reference: clinicalReference }]),
|
|
77
|
+
}]),
|
|
78
|
+
});
|
|
79
|
+
return Object.freeze({
|
|
80
|
+
resourceType: 'Bundle',
|
|
81
|
+
id: `bundle-${input.id}`,
|
|
82
|
+
identifier: Object.freeze({ system: 'urn:ietf:rfc:3986', value: `urn:uuid:${input.id}` }),
|
|
83
|
+
type: 'document',
|
|
84
|
+
timestamp: input.timestamp,
|
|
85
|
+
entry: Object.freeze([
|
|
86
|
+
Object.freeze({ fullUrl: compositionReference, resource: composition }),
|
|
87
|
+
Object.freeze({ fullUrl: subject.reference, resource: Object.freeze({ resourceType: 'Patient', id: 'jane-doe-demo', name: Object.freeze([{ given: Object.freeze(['Jane']), family: 'Doe' }]) }) }),
|
|
88
|
+
Object.freeze({ fullUrl: organizationReference, resource: Object.freeze({ resourceType: 'Organization', id: 'demo-hospital', name: 'Demo Hospital' }) }),
|
|
89
|
+
Object.freeze({ fullUrl: parentEncounterReference, resource: parentEncounter }),
|
|
90
|
+
Object.freeze({ fullUrl: encounterReference, resource: input.encounter }),
|
|
91
|
+
Object.freeze({ fullUrl: clinicalReference, resource: input.clinicalResource }),
|
|
92
|
+
]),
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
const emergencyNote = documentBundle({
|
|
96
|
+
id: 'emergency-note-demo',
|
|
97
|
+
title: 'Emergency assessment',
|
|
98
|
+
type: 'Emergency department note',
|
|
99
|
+
encounter: emergencyEncounter,
|
|
100
|
+
sectionTitle: 'Emergency assessment',
|
|
101
|
+
timestamp: '2026-10-03T10:00:00Z',
|
|
102
|
+
clinicalResource: Object.freeze({
|
|
103
|
+
resourceType: 'ClinicalImpression',
|
|
104
|
+
id: 'emergency-assessment-demo',
|
|
105
|
+
status: 'completed',
|
|
106
|
+
subject: Object.freeze({ reference: subject.reference }),
|
|
107
|
+
encounter: Object.freeze({ reference: `Encounter/${emergencyEncounter.id}` }),
|
|
108
|
+
summary: 'Initial emergency assessment completed',
|
|
109
|
+
}),
|
|
110
|
+
});
|
|
111
|
+
const imagingReport = documentBundle({
|
|
112
|
+
id: 'imaging-report-demo',
|
|
113
|
+
title: 'Diagnostic imaging report',
|
|
114
|
+
type: 'Diagnostic imaging report',
|
|
115
|
+
encounter: imagingEncounter,
|
|
116
|
+
sectionTitle: 'Imaging result',
|
|
117
|
+
timestamp: '2026-10-03T10:55:00Z',
|
|
118
|
+
clinicalResource: Object.freeze({
|
|
119
|
+
resourceType: 'DiagnosticReport',
|
|
120
|
+
id: 'imaging-result-demo',
|
|
121
|
+
status: 'final',
|
|
122
|
+
subject: Object.freeze({ reference: subject.reference }),
|
|
123
|
+
encounter: Object.freeze({ reference: `Encounter/${imagingEncounter.id}` }),
|
|
124
|
+
code: Object.freeze({ text: 'Diagnostic imaging assessment' }),
|
|
125
|
+
conclusion: 'No acute finding requiring intervention',
|
|
126
|
+
}),
|
|
127
|
+
});
|
|
128
|
+
const intensiveCareNote = documentBundle({
|
|
129
|
+
id: 'intensive-care-note-demo',
|
|
130
|
+
title: 'Intensive care progress note',
|
|
131
|
+
type: 'Progress note',
|
|
132
|
+
encounter: intensiveCareEncounter,
|
|
133
|
+
sectionTitle: 'Current assessment',
|
|
134
|
+
timestamp: '2026-10-03T11:30:00Z',
|
|
135
|
+
clinicalResource: Object.freeze({
|
|
136
|
+
resourceType: 'Observation',
|
|
137
|
+
id: 'intensive-care-observation-demo',
|
|
138
|
+
status: 'final',
|
|
139
|
+
subject: Object.freeze({ reference: subject.reference }),
|
|
140
|
+
encounter: Object.freeze({ reference: `Encounter/${intensiveCareEncounter.id}` }),
|
|
141
|
+
code: Object.freeze({ text: 'Current clinical status' }),
|
|
142
|
+
valueString: 'Stable under continuous monitoring',
|
|
143
|
+
effectiveDateTime: '2026-10-03T11:25:00Z',
|
|
144
|
+
}),
|
|
145
|
+
});
|
|
146
|
+
export const FHIR_CLINICAL_DOCUMENT_ENCOUNTER_JOURNEY_TEST_DATA = Object.freeze({
|
|
147
|
+
subject,
|
|
148
|
+
encounterCount: encounters.length,
|
|
149
|
+
documentCount: 3,
|
|
150
|
+
encounters,
|
|
151
|
+
documents: Object.freeze([emergencyNote, imagingReport, intensiveCareNote]),
|
|
152
|
+
});
|
package/dist/data/index.d.ts
CHANGED
package/dist/data/index.js
CHANGED
|
@@ -1,4 +1,23 @@
|
|
|
1
1
|
/** Repository-safe synthetic IPS document used by portal demos and visual tests. */
|
|
2
|
+
/** Canonical LOINC section codes used by the reusable IPS reader and editors. */
|
|
3
|
+
export declare const FHIR_IPS_SECTION_CODES: Readonly<{
|
|
4
|
+
readonly Problems: "11450-4";
|
|
5
|
+
readonly Allergies: "48765-2";
|
|
6
|
+
readonly Medications: "10160-0";
|
|
7
|
+
readonly Immunizations: "11369-6";
|
|
8
|
+
readonly DiagnosticResults: "30954-2";
|
|
9
|
+
readonly Procedures: "47519-4";
|
|
10
|
+
readonly MedicalDevices: "46264-8";
|
|
11
|
+
readonly VitalSigns: "8716-3";
|
|
12
|
+
readonly SocialHistory: "29762-2";
|
|
13
|
+
readonly Alerts: "104605-1";
|
|
14
|
+
readonly Goals: "81338-6";
|
|
15
|
+
readonly AdvanceDirectives: "42348-3";
|
|
16
|
+
readonly FunctionalStatus: "47420-5";
|
|
17
|
+
readonly PastIllness: "11348-0";
|
|
18
|
+
readonly PregnancyHistory: "10162-6";
|
|
19
|
+
readonly PlanOfCare: "18776-5";
|
|
20
|
+
}>;
|
|
2
21
|
/** Primary IPS section placement for the minimum shared clinical authoring forms. */
|
|
3
22
|
export declare const FHIR_IPS_PRIMARY_AUTHORING_SECTION_CODE_BY_RESOURCE_TYPE: Readonly<{
|
|
4
23
|
readonly Condition: "11450-4";
|
|
@@ -20,14 +20,33 @@ const sectionDefinitions = Object.freeze([
|
|
|
20
20
|
['10162-6', 'Pregnancy history', 'Observation', 'Not pregnant'],
|
|
21
21
|
['18776-5', 'Plan of care', 'CarePlan', 'Emergency follow-up plan'],
|
|
22
22
|
]);
|
|
23
|
+
/** Canonical LOINC section codes used by the reusable IPS reader and editors. */
|
|
24
|
+
export const FHIR_IPS_SECTION_CODES = Object.freeze({
|
|
25
|
+
Problems: sectionDefinitions[0][0],
|
|
26
|
+
Allergies: sectionDefinitions[1][0],
|
|
27
|
+
Medications: sectionDefinitions[2][0],
|
|
28
|
+
Immunizations: sectionDefinitions[3][0],
|
|
29
|
+
DiagnosticResults: sectionDefinitions[4][0],
|
|
30
|
+
Procedures: sectionDefinitions[5][0],
|
|
31
|
+
MedicalDevices: sectionDefinitions[6][0],
|
|
32
|
+
VitalSigns: sectionDefinitions[7][0],
|
|
33
|
+
SocialHistory: sectionDefinitions[8][0],
|
|
34
|
+
Alerts: sectionDefinitions[9][0],
|
|
35
|
+
Goals: sectionDefinitions[10][0],
|
|
36
|
+
AdvanceDirectives: sectionDefinitions[11][0],
|
|
37
|
+
FunctionalStatus: sectionDefinitions[12][0],
|
|
38
|
+
PastIllness: sectionDefinitions[13][0],
|
|
39
|
+
PregnancyHistory: sectionDefinitions[14][0],
|
|
40
|
+
PlanOfCare: sectionDefinitions[15][0],
|
|
41
|
+
});
|
|
23
42
|
/** Primary IPS section placement for the minimum shared clinical authoring forms. */
|
|
24
43
|
export const FHIR_IPS_PRIMARY_AUTHORING_SECTION_CODE_BY_RESOURCE_TYPE = Object.freeze({
|
|
25
|
-
Condition:
|
|
26
|
-
AllergyIntolerance:
|
|
27
|
-
MedicationStatement:
|
|
28
|
-
Immunization:
|
|
29
|
-
Procedure:
|
|
30
|
-
Observation:
|
|
44
|
+
Condition: FHIR_IPS_SECTION_CODES.Problems,
|
|
45
|
+
AllergyIntolerance: FHIR_IPS_SECTION_CODES.Allergies,
|
|
46
|
+
MedicationStatement: FHIR_IPS_SECTION_CODES.Medications,
|
|
47
|
+
Immunization: FHIR_IPS_SECTION_CODES.Immunizations,
|
|
48
|
+
Procedure: FHIR_IPS_SECTION_CODES.Procedures,
|
|
49
|
+
Observation: FHIR_IPS_SECTION_CODES.VitalSigns,
|
|
31
50
|
});
|
|
32
51
|
function concept(text, code) {
|
|
33
52
|
return { text, coding: [{ system: SNOMED_SYSTEM, code, display: text }] };
|
|
@@ -15,6 +15,19 @@ export type FhirIpsClinicalArtifactSchema = Readonly<{
|
|
|
15
15
|
/** Source-text claims for which a user may explicitly confirm a terminology candidate. */
|
|
16
16
|
terminologyTextClaims: readonly string[];
|
|
17
17
|
}>;
|
|
18
|
+
export declare const FhirIpsObservationArtifactKinds: Readonly<{
|
|
19
|
+
readonly VitalSigns: "vital-signs";
|
|
20
|
+
readonly Laboratory: "laboratory";
|
|
21
|
+
readonly SocialHistory: "social-history";
|
|
22
|
+
readonly PregnancyHistory: "pregnancy-history";
|
|
23
|
+
}>;
|
|
24
|
+
export type FhirIpsObservationArtifactKind = typeof FhirIpsObservationArtifactKinds[keyof typeof FhirIpsObservationArtifactKinds];
|
|
25
|
+
export type FhirIpsObservationArtifactSchema = FhirIpsClinicalArtifactSchema & Readonly<{
|
|
26
|
+
kind: FhirIpsObservationArtifactKind;
|
|
27
|
+
initialClaims: Readonly<Record<string, string>>;
|
|
28
|
+
}>;
|
|
29
|
+
/** Section-specific Observation authoring contracts; a resource type alone is not a sufficient selector. */
|
|
30
|
+
export declare const FHIR_IPS_OBSERVATION_ARTIFACT_SCHEMAS: Readonly<Record<FhirIpsObservationArtifactKind, FhirIpsObservationArtifactSchema>>;
|
|
18
31
|
/**
|
|
19
32
|
* Minimum reusable IPS authoring surface for Personal and Professional portals.
|
|
20
33
|
*
|
|
@@ -4,8 +4,8 @@ import { ConditionClaim } from '../claims/condition-claims.js';
|
|
|
4
4
|
import { ImmunizationClaim } from '../claims/immunization-claims.js';
|
|
5
5
|
import { MedicationStatementClaim } from '../claims/medication-statement-claims.js';
|
|
6
6
|
import { ProcedureClaim } from '../claims/procedure-claims.js';
|
|
7
|
-
import { ObservationClaim } from '../observation-claims.js';
|
|
8
|
-
import { FHIR_IPS_PRIMARY_AUTHORING_SECTION_CODE_BY_RESOURCE_TYPE } from './ips-all-sections.data.js';
|
|
7
|
+
import { ObservationCategoryCodes, ObservationClaim } from '../observation-claims.js';
|
|
8
|
+
import { FHIR_IPS_PRIMARY_AUTHORING_SECTION_CODE_BY_RESOURCE_TYPE, FHIR_IPS_SECTION_CODES } from './ips-all-sections.data.js';
|
|
9
9
|
export const FhirIpsClinicalArtifactTypes = Object.freeze({
|
|
10
10
|
AllergyIntolerance: 'AllergyIntolerance',
|
|
11
11
|
MedicationStatement: 'MedicationStatement',
|
|
@@ -14,6 +14,60 @@ export const FhirIpsClinicalArtifactTypes = Object.freeze({
|
|
|
14
14
|
Procedure: 'Procedure',
|
|
15
15
|
Observation: 'Observation',
|
|
16
16
|
});
|
|
17
|
+
export const FhirIpsObservationArtifactKinds = Object.freeze({
|
|
18
|
+
VitalSigns: 'vital-signs',
|
|
19
|
+
Laboratory: 'laboratory',
|
|
20
|
+
SocialHistory: 'social-history',
|
|
21
|
+
PregnancyHistory: 'pregnancy-history',
|
|
22
|
+
});
|
|
23
|
+
const observationRequiredClaims = Object.freeze([
|
|
24
|
+
ObservationClaim.Category,
|
|
25
|
+
ObservationClaim.CodeText,
|
|
26
|
+
ObservationClaim.Status,
|
|
27
|
+
]);
|
|
28
|
+
const observationOptionalClaims = Object.freeze([
|
|
29
|
+
ObservationClaim.Code,
|
|
30
|
+
ObservationClaim.CodeDisplay,
|
|
31
|
+
ObservationClaim.Date,
|
|
32
|
+
ObservationClaim.EffectiveDateTime,
|
|
33
|
+
ObservationClaim.Encounter,
|
|
34
|
+
ObservationClaim.Performer,
|
|
35
|
+
ObservationClaim.Method,
|
|
36
|
+
ObservationClaim.Specimen,
|
|
37
|
+
ObservationClaim.Device,
|
|
38
|
+
ObservationClaim.ValueQuantityNumber,
|
|
39
|
+
ObservationClaim.ValueQuantityUnit,
|
|
40
|
+
ObservationClaim.ValueString,
|
|
41
|
+
ObservationClaim.ValueConcept,
|
|
42
|
+
ObservationClaim.ValueConceptText,
|
|
43
|
+
ObservationClaim.ValueConceptDisplay,
|
|
44
|
+
ObservationClaim.ReferenceRangeLowNumber,
|
|
45
|
+
ObservationClaim.ReferenceRangeHighNumber,
|
|
46
|
+
ObservationClaim.ReferenceRangeUnit,
|
|
47
|
+
ObservationClaim.ReferenceRangeText,
|
|
48
|
+
ObservationClaim.Note,
|
|
49
|
+
]);
|
|
50
|
+
function observationSchema(kind, sectionCode, category) {
|
|
51
|
+
return Object.freeze({
|
|
52
|
+
kind,
|
|
53
|
+
resourceType: FhirIpsClinicalArtifactTypes.Observation,
|
|
54
|
+
sectionCode,
|
|
55
|
+
requiredClaims: observationRequiredClaims,
|
|
56
|
+
optionalClaims: observationOptionalClaims,
|
|
57
|
+
terminologyTextClaims: Object.freeze([ObservationClaim.CodeText]),
|
|
58
|
+
initialClaims: Object.freeze({
|
|
59
|
+
[ObservationClaim.Category]: category,
|
|
60
|
+
[ObservationClaim.Status]: 'final',
|
|
61
|
+
}),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/** Section-specific Observation authoring contracts; a resource type alone is not a sufficient selector. */
|
|
65
|
+
export const FHIR_IPS_OBSERVATION_ARTIFACT_SCHEMAS = Object.freeze({
|
|
66
|
+
[FhirIpsObservationArtifactKinds.VitalSigns]: observationSchema(FhirIpsObservationArtifactKinds.VitalSigns, FHIR_IPS_SECTION_CODES.VitalSigns, ObservationCategoryCodes.VitalSigns.claim),
|
|
67
|
+
[FhirIpsObservationArtifactKinds.Laboratory]: observationSchema(FhirIpsObservationArtifactKinds.Laboratory, FHIR_IPS_SECTION_CODES.DiagnosticResults, ObservationCategoryCodes.Laboratory.claim),
|
|
68
|
+
[FhirIpsObservationArtifactKinds.SocialHistory]: observationSchema(FhirIpsObservationArtifactKinds.SocialHistory, FHIR_IPS_SECTION_CODES.SocialHistory, ObservationCategoryCodes.SocialHistory.claim),
|
|
69
|
+
[FhirIpsObservationArtifactKinds.PregnancyHistory]: observationSchema(FhirIpsObservationArtifactKinds.PregnancyHistory, FHIR_IPS_SECTION_CODES.PregnancyHistory, ObservationCategoryCodes.Survey.claim),
|
|
70
|
+
});
|
|
17
71
|
/**
|
|
18
72
|
* Minimum reusable IPS authoring surface for Personal and Professional portals.
|
|
19
73
|
*
|
|
@@ -59,10 +113,6 @@ export const FHIR_IPS_CLINICAL_ARTIFACT_SCHEMAS = Object.freeze({
|
|
|
59
113
|
terminologyTextClaims: Object.freeze([ProcedureClaim.CodeText]),
|
|
60
114
|
}),
|
|
61
115
|
[FhirIpsClinicalArtifactTypes.Observation]: Object.freeze({
|
|
62
|
-
|
|
63
|
-
sectionCode: FHIR_IPS_PRIMARY_AUTHORING_SECTION_CODE_BY_RESOURCE_TYPE.Observation,
|
|
64
|
-
requiredClaims: Object.freeze([ObservationClaim.Category, ObservationClaim.CodeText, ObservationClaim.Status]),
|
|
65
|
-
optionalClaims: Object.freeze([ObservationClaim.Code, ObservationClaim.CodeDisplay, ObservationClaim.Date, ObservationClaim.EffectiveDateTime, ObservationClaim.Performer, ObservationClaim.Method, ObservationClaim.Specimen, ObservationClaim.Device, ObservationClaim.ValueQuantityNumber, ObservationClaim.ValueQuantityUnit, ObservationClaim.ValueString, ObservationClaim.ValueConcept, ObservationClaim.ReferenceRangeLowNumber, ObservationClaim.ReferenceRangeHighNumber, ObservationClaim.ReferenceRangeUnit, ObservationClaim.ReferenceRangeText, ObservationClaim.Note]),
|
|
66
|
-
terminologyTextClaims: Object.freeze([ObservationClaim.CodeText]),
|
|
116
|
+
...FHIR_IPS_OBSERVATION_ARTIFACT_SCHEMAS[FhirIpsObservationArtifactKinds.VitalSigns],
|
|
67
117
|
}),
|
|
68
118
|
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Clinical documents and Encounter exploration
|
|
2
|
+
|
|
3
|
+
## The two connected graphs
|
|
4
|
+
|
|
5
|
+
A clinical document is a `Bundle` with `type=document`. Its first resource is
|
|
6
|
+
always a `Composition`. The Composition gives the document its human title,
|
|
7
|
+
type, authorship, subject and sections. IPS is one document profile; an
|
|
8
|
+
emergency note, progress note or diagnostic report uses the same document
|
|
9
|
+
shape with a different Composition type and section set.
|
|
10
|
+
|
|
11
|
+
The care journey is an Encounter graph, not a ResearchSubject graph. The
|
|
12
|
+
individual remains the subject of each Encounter. A document associates with
|
|
13
|
+
the care step it describes through `Composition.encounter`, and clinical
|
|
14
|
+
entries such as Observation or DiagnosticReport may repeat that Encounter
|
|
15
|
+
reference when their own FHIR definition provides it.
|
|
16
|
+
|
|
17
|
+
## Navigation
|
|
18
|
+
|
|
19
|
+
One parent Encounter can represent the admission or overall episode represented
|
|
20
|
+
inside the current provider. Emergency, imaging, surgery, ward and intensive
|
|
21
|
+
care steps can be independent child Encounters linked with `Encounter.partOf`.
|
|
22
|
+
Their actual periods provide a deterministic chronological order for previous
|
|
23
|
+
and next navigation. `EncounterHistory` records status/class/location
|
|
24
|
+
milestones for one Encounter; it does not replace the Encounter hierarchy.
|
|
25
|
+
|
|
26
|
+
The reusable viewer receives authorized documents and Encounters. Selecting an
|
|
27
|
+
Encounter shows documents whose `Composition.encounter` references it. Opening
|
|
28
|
+
one of those documents renders its Composition sections with the same reader
|
|
29
|
+
used for IPS. Missing permissions remain missing data; the browser must not
|
|
30
|
+
infer or fetch another subject merely because two Encounter references are
|
|
31
|
+
related.
|
|
32
|
+
|
|
33
|
+
## Write boundaries
|
|
34
|
+
|
|
35
|
+
- A multi-section attested clinical document is Composition-first.
|
|
36
|
+
- A single-section native update may be sent independently and carries its
|
|
37
|
+
section at the Communication boundary.
|
|
38
|
+
- Encounter, EncounterHistory, Composition and each clinical entry remain
|
|
39
|
+
independently persisted claims-first resources.
|
|
40
|
+
- Authorization, audit and provider persistence belong to the BFF/GW; the
|
|
41
|
+
shared fixture and viewer grant no access.
|