fhir-data-utils-ts 0.3.5 → 0.3.6
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 +5 -0
- package/CHANGELOG.md +9 -0
- package/README.md +7 -0
- package/dist/builders/diagnostic-report-graph.d.ts +31 -0
- package/dist/builders/diagnostic-report-graph.js +86 -0
- package/dist/builders/index.d.ts +1 -0
- package/dist/builders/index.js +1 -0
- package/dist/claim-helpers/claims-helpers-diagnostic-report.d.ts +12 -0
- package/dist/claim-helpers/claims-helpers-diagnostic-report.js +40 -0
- package/dist/claims/diagnostic-report-claims.d.ts +3 -36
- package/dist/claims/diagnostic-report-claims.js +4 -12
- package/dist/flat-claim-resource-graph.js +7 -6
- package/docs/UHC_FHIR_UTILS_MIGRATION.md +7 -0
- package/package.json +1 -1
|
@@ -38,6 +38,11 @@ description: Complete or audit migrations, claim catalogs, converters, builders,
|
|
|
38
38
|
storage remain in a separately versioned imaging/storage package.
|
|
39
39
|
- Preserve `Encounter.appointment`; an Appointment lifecycle transition must
|
|
40
40
|
not sever the encounter from the scheduling event that originated it.
|
|
41
|
+
- Build laboratory panels with `buildDiagnosticReportFlatGraph(...)`.
|
|
42
|
+
`DiagnosticReport.code` is mandatory and names the report/panel; result
|
|
43
|
+
measurements are independent `Observation` entries and formatted PDF/image
|
|
44
|
+
evidence is an independent `DocumentReference`. Preliminary state does not
|
|
45
|
+
itself authorize ledger or research projection.
|
|
41
46
|
|
|
42
47
|
## Change with executable contracts
|
|
43
48
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.6 - 2026-09-26
|
|
4
|
+
|
|
5
|
+
- Add a product-neutral claims-first DiagnosticReport graph builder for coded
|
|
6
|
+
laboratory panels, independent Observation results and PDF/image
|
|
7
|
+
DocumentReference evidence.
|
|
8
|
+
- Correct the document builder to emit the canonical DocumentReference claim
|
|
9
|
+
catalog and complete list helpers for report results, performers, specimens
|
|
10
|
+
and graph references.
|
|
11
|
+
|
|
3
12
|
## 0.3.5 - 2026-09-26
|
|
4
13
|
|
|
5
14
|
- Preserve the originating `Encounter.appointment` reference and expose the
|
package/README.md
CHANGED
|
@@ -29,6 +29,13 @@ through `<ResourceType>.contained-reference-list`; children do not carry
|
|
|
29
29
|
as `<ResourceType>.language`, `.narrative-status` and `.xhtml`. Native FHIR is
|
|
30
30
|
materialized only by an explicit R4/R5/R6 import or export adapter.
|
|
31
31
|
|
|
32
|
+
Laboratory authoring uses `buildDiagnosticReportFlatGraph(...)`.
|
|
33
|
+
`DiagnosticReport.code` is the coded report or panel type, atomic results are
|
|
34
|
+
independent LOINC-coded `Observation` entries, and PDF/JPEG/PNG evidence is an
|
|
35
|
+
independent `DocumentReference`. Preliminary reports can be reviewed and
|
|
36
|
+
securely exchanged; ledger and research eligibility remain downstream policy
|
|
37
|
+
and normally require the confirmed final lifecycle state.
|
|
38
|
+
|
|
32
39
|
## Public contract
|
|
33
40
|
|
|
34
41
|
The root export and stable subpaths provide:
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type DiagnosticReportStatus } from '../constants/clinical-statuses.js';
|
|
2
|
+
import { type FlatClaimResourceEntry } from '../flat-claim-resource-graph.js';
|
|
3
|
+
export type DiagnosticReportCoding = Readonly<{
|
|
4
|
+
system: string;
|
|
5
|
+
code: string;
|
|
6
|
+
display?: string;
|
|
7
|
+
text?: string;
|
|
8
|
+
}>;
|
|
9
|
+
export type DiagnosticReportFlatInput = Readonly<{
|
|
10
|
+
entryId: string;
|
|
11
|
+
identifier: string;
|
|
12
|
+
status: DiagnosticReportStatus;
|
|
13
|
+
subjectReference: string;
|
|
14
|
+
issuedAt: string;
|
|
15
|
+
reportCode: DiagnosticReportCoding;
|
|
16
|
+
encounterReference?: string;
|
|
17
|
+
performerReferences?: readonly string[];
|
|
18
|
+
results?: readonly FlatClaimResourceEntry[];
|
|
19
|
+
attachments?: readonly FlatClaimResourceEntry[];
|
|
20
|
+
}>;
|
|
21
|
+
/**
|
|
22
|
+
* Builds a claims-first DiagnosticReport graph for human, animal, or One Health
|
|
23
|
+
* laboratory reports. `DiagnosticReport.code` identifies the report/panel;
|
|
24
|
+
* atomic measurements remain independent `Observation` entries and PDF/JPEG/
|
|
25
|
+
* PNG evidence remains independent `DocumentReference` entries.
|
|
26
|
+
*
|
|
27
|
+
* `preliminary` reports can be exchanged and reviewed, but downstream ledger
|
|
28
|
+
* and secondary-use policy decides whether only `final` is eligible for those
|
|
29
|
+
* projections. This builder does not confer authority or consent.
|
|
30
|
+
*/
|
|
31
|
+
export declare function buildDiagnosticReportFlatGraph(input: DiagnosticReportFlatInput): readonly FlatClaimResourceEntry[];
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// Copyright 2026 ConnectHealth.info (Connecting Solution & Applications Ltd.) under the Apache License, Version 2.0.
|
|
2
|
+
import { DiagnosticReportClaim } from '../claims/diagnostic-report-claims.js';
|
|
3
|
+
import { DiagnosticReportStatuses } from '../constants/clinical-statuses.js';
|
|
4
|
+
import { ResourceTypesFhirR4 } from '../constants/fhir-resource-types.js';
|
|
5
|
+
import { buildFlatClaimResourceEntry, linkFlatClaimResourceEntries, } from '../flat-claim-resource-graph.js';
|
|
6
|
+
const DIAGNOSTIC_REPORT_STATUSES = new Set(Object.values(DiagnosticReportStatuses));
|
|
7
|
+
/**
|
|
8
|
+
* Builds a claims-first DiagnosticReport graph for human, animal, or One Health
|
|
9
|
+
* laboratory reports. `DiagnosticReport.code` identifies the report/panel;
|
|
10
|
+
* atomic measurements remain independent `Observation` entries and PDF/JPEG/
|
|
11
|
+
* PNG evidence remains independent `DocumentReference` entries.
|
|
12
|
+
*
|
|
13
|
+
* `preliminary` reports can be exchanged and reviewed, but downstream ledger
|
|
14
|
+
* and secondary-use policy decides whether only `final` is eligible for those
|
|
15
|
+
* projections. This builder does not confer authority or consent.
|
|
16
|
+
*/
|
|
17
|
+
export function buildDiagnosticReportFlatGraph(input) {
|
|
18
|
+
const status = required(input.status, 'diagnostic_report_status_required');
|
|
19
|
+
if (!DIAGNOSTIC_REPORT_STATUSES.has(status))
|
|
20
|
+
throw new TypeError('diagnostic_report_status_invalid');
|
|
21
|
+
const claims = {
|
|
22
|
+
[DiagnosticReportClaim.Identifier]: required(input.identifier, 'diagnostic_report_identifier_required'),
|
|
23
|
+
[DiagnosticReportClaim.Status]: status,
|
|
24
|
+
[DiagnosticReportClaim.Subject]: required(input.subjectReference, 'diagnostic_report_subject_required'),
|
|
25
|
+
[DiagnosticReportClaim.Date]: isoDateTime(input.issuedAt, 'diagnostic_report_date_invalid'),
|
|
26
|
+
[DiagnosticReportClaim.Code]: codingToken(input.reportCode),
|
|
27
|
+
};
|
|
28
|
+
if (input.reportCode.display?.trim())
|
|
29
|
+
claims[DiagnosticReportClaim.CodeDisplay] = input.reportCode.display.trim();
|
|
30
|
+
if (input.reportCode.text?.trim())
|
|
31
|
+
claims[DiagnosticReportClaim.CodeText] = input.reportCode.text.trim();
|
|
32
|
+
if (input.encounterReference?.trim()) {
|
|
33
|
+
claims[DiagnosticReportClaim.Encounter] = required(input.encounterReference, 'diagnostic_report_encounter_invalid');
|
|
34
|
+
}
|
|
35
|
+
if (input.performerReferences?.length) {
|
|
36
|
+
claims[DiagnosticReportClaim.Performer] = referenceList(input.performerReferences, 'diagnostic_report_performer_invalid');
|
|
37
|
+
}
|
|
38
|
+
const results = [...(input.results ?? [])];
|
|
39
|
+
if (results.some(entry => entry.resourceType !== ResourceTypesFhirR4.Observation)) {
|
|
40
|
+
throw new TypeError('diagnostic_report_result_invalid');
|
|
41
|
+
}
|
|
42
|
+
const attachments = [...(input.attachments ?? [])];
|
|
43
|
+
if (attachments.some(entry => entry.resourceType !== ResourceTypesFhirR4.DocumentReference)) {
|
|
44
|
+
throw new TypeError('diagnostic_report_attachment_invalid');
|
|
45
|
+
}
|
|
46
|
+
if (results.length)
|
|
47
|
+
claims[DiagnosticReportClaim.Result] = results.map(entry => entry.reference).join(',');
|
|
48
|
+
const report = buildFlatClaimResourceEntry({
|
|
49
|
+
entryId: input.entryId,
|
|
50
|
+
resourceType: ResourceTypesFhirR4.DiagnosticReport,
|
|
51
|
+
claims,
|
|
52
|
+
});
|
|
53
|
+
const children = [...results, ...attachments];
|
|
54
|
+
const graph = [report, ...children];
|
|
55
|
+
return children.length
|
|
56
|
+
? linkFlatClaimResourceEntries(graph, {
|
|
57
|
+
parentEntryId: report.entryId,
|
|
58
|
+
childEntryIds: children.map(entry => entry.entryId),
|
|
59
|
+
})
|
|
60
|
+
: graph;
|
|
61
|
+
}
|
|
62
|
+
function codingToken(value) {
|
|
63
|
+
const system = required(value.system, 'diagnostic_report_code_system_required');
|
|
64
|
+
const code = required(value.code, 'diagnostic_report_code_required');
|
|
65
|
+
if (system.includes('|') || code.includes('|') || system.includes(',') || code.includes(',')) {
|
|
66
|
+
throw new TypeError('diagnostic_report_code_invalid');
|
|
67
|
+
}
|
|
68
|
+
return `${system}|${code}`;
|
|
69
|
+
}
|
|
70
|
+
function referenceList(values, error) {
|
|
71
|
+
const normalized = [...new Set(values.map(value => required(value, error)))];
|
|
72
|
+
if (normalized.some(value => value.includes(',')))
|
|
73
|
+
throw new TypeError(error);
|
|
74
|
+
return normalized.join(',');
|
|
75
|
+
}
|
|
76
|
+
function isoDateTime(value, error) {
|
|
77
|
+
const normalized = required(value, error);
|
|
78
|
+
if (!/^\d{4}-\d{2}-\d{2}T/.test(normalized) || Number.isNaN(Date.parse(normalized)))
|
|
79
|
+
throw new TypeError(error);
|
|
80
|
+
return normalized;
|
|
81
|
+
}
|
|
82
|
+
function required(value, error) {
|
|
83
|
+
if (typeof value !== 'string' || !value.trim())
|
|
84
|
+
throw new TypeError(error);
|
|
85
|
+
return value.trim();
|
|
86
|
+
}
|
package/dist/builders/index.d.ts
CHANGED
package/dist/builders/index.js
CHANGED
|
@@ -8,8 +8,20 @@ export declare function getDiagnosticReportIdentifier(claims: DiagnosticReportIn
|
|
|
8
8
|
export declare function setDiagnosticReportIdentifier(claims: DiagnosticReportInteroperableClaims, value: string): DiagnosticReportInteroperableClaims;
|
|
9
9
|
export declare function getDiagnosticReportResultList(claims: DiagnosticReportInteroperableClaims): string[];
|
|
10
10
|
export declare function setDiagnosticReportResultList(claims: DiagnosticReportInteroperableClaims, values: string | readonly string[]): DiagnosticReportInteroperableClaims;
|
|
11
|
+
export declare function addDiagnosticReportResultList(claims: DiagnosticReportInteroperableClaims, values: string | readonly string[]): DiagnosticReportInteroperableClaims;
|
|
12
|
+
export declare function removeDiagnosticReportResultList(claims: DiagnosticReportInteroperableClaims, values: string | readonly string[]): DiagnosticReportInteroperableClaims;
|
|
13
|
+
export declare function getDiagnosticReportPerformerList(claims: DiagnosticReportInteroperableClaims): string[];
|
|
14
|
+
export declare function setDiagnosticReportPerformerList(claims: DiagnosticReportInteroperableClaims, values: string | readonly string[]): DiagnosticReportInteroperableClaims;
|
|
15
|
+
export declare function addDiagnosticReportPerformerList(claims: DiagnosticReportInteroperableClaims, values: string | readonly string[]): DiagnosticReportInteroperableClaims;
|
|
16
|
+
export declare function removeDiagnosticReportPerformerList(claims: DiagnosticReportInteroperableClaims, values: string | readonly string[]): DiagnosticReportInteroperableClaims;
|
|
17
|
+
export declare function getDiagnosticReportSpecimenList(claims: DiagnosticReportInteroperableClaims): string[];
|
|
18
|
+
export declare function setDiagnosticReportSpecimenList(claims: DiagnosticReportInteroperableClaims, values: string | readonly string[]): DiagnosticReportInteroperableClaims;
|
|
19
|
+
export declare function addDiagnosticReportSpecimenList(claims: DiagnosticReportInteroperableClaims, values: string | readonly string[]): DiagnosticReportInteroperableClaims;
|
|
20
|
+
export declare function removeDiagnosticReportSpecimenList(claims: DiagnosticReportInteroperableClaims, values: string | readonly string[]): DiagnosticReportInteroperableClaims;
|
|
11
21
|
export declare function getDiagnosticReportContainedResourceReferenceList(claims: DiagnosticReportInteroperableClaims): string[];
|
|
12
22
|
export declare function setDiagnosticReportContainedResourceReferenceList(claims: DiagnosticReportInteroperableClaims, values: string | readonly string[]): DiagnosticReportInteroperableClaims;
|
|
23
|
+
export declare function addDiagnosticReportContainedResourceReferenceList(claims: DiagnosticReportInteroperableClaims, values: string | readonly string[]): DiagnosticReportInteroperableClaims;
|
|
24
|
+
export declare function removeDiagnosticReportContainedResourceReferenceList(claims: DiagnosticReportInteroperableClaims, values: string | readonly string[]): DiagnosticReportInteroperableClaims;
|
|
13
25
|
/** @deprecated Use `getDiagnosticReportContainedResourceReferenceList`. */
|
|
14
26
|
export declare function getDiagnosticReportContainedDocumentIdentifierList(claims: DiagnosticReportInteroperableClaims): string[];
|
|
15
27
|
/** @deprecated Use `setDiagnosticReportContainedResourceReferenceList`. */
|
|
@@ -24,6 +24,36 @@ export function getDiagnosticReportResultList(claims) {
|
|
|
24
24
|
export function setDiagnosticReportResultList(claims, values) {
|
|
25
25
|
return setDiagnosticReportClaimList(claims, DiagnosticReportClaim.Result, values);
|
|
26
26
|
}
|
|
27
|
+
export function addDiagnosticReportResultList(claims, values) {
|
|
28
|
+
return addDiagnosticReportClaimList(claims, DiagnosticReportClaim.Result, values);
|
|
29
|
+
}
|
|
30
|
+
export function removeDiagnosticReportResultList(claims, values) {
|
|
31
|
+
return removeDiagnosticReportClaimList(claims, DiagnosticReportClaim.Result, values);
|
|
32
|
+
}
|
|
33
|
+
export function getDiagnosticReportPerformerList(claims) {
|
|
34
|
+
return getDiagnosticReportClaimList(claims, DiagnosticReportClaim.Performer);
|
|
35
|
+
}
|
|
36
|
+
export function setDiagnosticReportPerformerList(claims, values) {
|
|
37
|
+
return setDiagnosticReportClaimList(claims, DiagnosticReportClaim.Performer, values);
|
|
38
|
+
}
|
|
39
|
+
export function addDiagnosticReportPerformerList(claims, values) {
|
|
40
|
+
return addDiagnosticReportClaimList(claims, DiagnosticReportClaim.Performer, values);
|
|
41
|
+
}
|
|
42
|
+
export function removeDiagnosticReportPerformerList(claims, values) {
|
|
43
|
+
return removeDiagnosticReportClaimList(claims, DiagnosticReportClaim.Performer, values);
|
|
44
|
+
}
|
|
45
|
+
export function getDiagnosticReportSpecimenList(claims) {
|
|
46
|
+
return getDiagnosticReportClaimList(claims, DiagnosticReportClaim.Specimen);
|
|
47
|
+
}
|
|
48
|
+
export function setDiagnosticReportSpecimenList(claims, values) {
|
|
49
|
+
return setDiagnosticReportClaimList(claims, DiagnosticReportClaim.Specimen, values);
|
|
50
|
+
}
|
|
51
|
+
export function addDiagnosticReportSpecimenList(claims, values) {
|
|
52
|
+
return addDiagnosticReportClaimList(claims, DiagnosticReportClaim.Specimen, values);
|
|
53
|
+
}
|
|
54
|
+
export function removeDiagnosticReportSpecimenList(claims, values) {
|
|
55
|
+
return removeDiagnosticReportClaimList(claims, DiagnosticReportClaim.Specimen, values);
|
|
56
|
+
}
|
|
27
57
|
export function getDiagnosticReportContainedResourceReferenceList(claims) {
|
|
28
58
|
const canonical = getDiagnosticReportClaimList(claims, DiagnosticReportClaim.ContainedReferenceList);
|
|
29
59
|
const legacy = getDiagnosticReportClaimList(claims, DiagnosticReportClaim.ContainedDocuments);
|
|
@@ -37,6 +67,16 @@ export function setDiagnosticReportContainedResourceReferenceList(claims, values
|
|
|
37
67
|
delete cleaned[DiagnosticReportClaim.ContainedDocuments];
|
|
38
68
|
return cleaned;
|
|
39
69
|
}
|
|
70
|
+
export function addDiagnosticReportContainedResourceReferenceList(claims, values) {
|
|
71
|
+
return setDiagnosticReportContainedResourceReferenceList(claims, [
|
|
72
|
+
...getDiagnosticReportContainedResourceReferenceList(claims),
|
|
73
|
+
...(Array.isArray(values) ? values : [values]),
|
|
74
|
+
]);
|
|
75
|
+
}
|
|
76
|
+
export function removeDiagnosticReportContainedResourceReferenceList(claims, values) {
|
|
77
|
+
const removals = new Set(Array.isArray(values) ? values : [values]);
|
|
78
|
+
return setDiagnosticReportContainedResourceReferenceList(claims, getDiagnosticReportContainedResourceReferenceList(claims).filter(value => !removals.has(value)));
|
|
79
|
+
}
|
|
40
80
|
/** @deprecated Use `getDiagnosticReportContainedResourceReferenceList`. */
|
|
41
81
|
export function getDiagnosticReportContainedDocumentIdentifierList(claims) {
|
|
42
82
|
return getDiagnosticReportContainedResourceReferenceList(claims);
|
|
@@ -33,31 +33,6 @@ export declare const DiagnosticReportClaim: {
|
|
|
33
33
|
*/
|
|
34
34
|
readonly ContainedDocuments: "DiagnosticReport.contained-documents";
|
|
35
35
|
};
|
|
36
|
-
/**
|
|
37
|
-
* TODO(ips-next):
|
|
38
|
-
* Add resource-level claim helpers in `src/utils/claims-helpers-diagnostic-report.ts`
|
|
39
|
-
* following the same contract already used by Consent/Medication/Condition/Allergy:
|
|
40
|
-
* - `getDiagnosticReportClaimList(...)`
|
|
41
|
-
* - `setDiagnosticReportClaimList(...)`
|
|
42
|
-
* - `addDiagnosticReportClaimList(...)`
|
|
43
|
-
* - `removeDiagnosticReportClaimList(...)`
|
|
44
|
-
* - focused helpers for:
|
|
45
|
-
* - `get/set/add/removeDiagnosticReportResultList`
|
|
46
|
-
* - `get/set/add/removeDiagnosticReportPerformerList`
|
|
47
|
-
* - `get/set/add/removeDiagnosticReportSpecimenList`
|
|
48
|
-
* - `get/set/add/removeDiagnosticReportContainedResourceReferences`
|
|
49
|
-
* - `get/setDiagnosticReportPresentedFormContentType`
|
|
50
|
-
* - `get/setDiagnosticReportPresentedFormData`
|
|
51
|
-
* - `get/setDiagnosticReportPresentedFormUrl`
|
|
52
|
-
*
|
|
53
|
-
* Keep naming aligned with canonical FHIR search parameter names
|
|
54
|
-
* (lowercase with `-`) and reuse the existing `SearchParamNames` + contextualized
|
|
55
|
-
* claim-key mapping pattern.
|
|
56
|
-
*
|
|
57
|
-
* This file is intentionally type-first only for now so GW Core and
|
|
58
|
-
* `common-utils` can already exercise the rest of the bundle workflow without
|
|
59
|
-
* committing to the DiagnosticReport editing surface yet.
|
|
60
|
-
*/
|
|
61
36
|
export type DiagnosticReportClaimKey = typeof DiagnosticReportClaim[keyof typeof DiagnosticReportClaim];
|
|
62
37
|
export declare const DiagnosticReportClaimSpecs: ClaimSpec[];
|
|
63
38
|
export declare const DiagnosticReportSearchParamNames: {
|
|
@@ -95,15 +70,7 @@ export declare enum DiagnosticReportClaimsFhirApi {
|
|
|
95
70
|
}
|
|
96
71
|
export declare const DiagnosticReportSearchParamToClaimKey: Record<DiagnosticReportSearchParamName, DiagnosticReportClaimsFhirApi>;
|
|
97
72
|
/**
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* Do not invent camelCase names. Prefer official FHIR search parameter names
|
|
103
|
-
* or explicit attachment aliases such as `presented-form-*` and
|
|
104
|
-
* `contained-reference-list`.
|
|
105
|
-
*
|
|
106
|
-
* Keep `DiagnosticReport` paused at the typing/mapping layer until:
|
|
107
|
-
* 1. `claims-helpers-diagnostic-report.ts` exists
|
|
108
|
-
* 2. GW Core readers/tests consume the same shared claim keys
|
|
73
|
+
* Operational attachment and graph claims remain separate from the official
|
|
74
|
+
* SearchParameter catalog above. They support claims-first authoring without
|
|
75
|
+
* pretending that those aliases are searchable FHIR parameters.
|
|
109
76
|
*/
|
|
@@ -54,7 +54,7 @@ export const DiagnosticReportClaimSpecs = [
|
|
|
54
54
|
{ key: DiagnosticReportClaim.PresentedFormContentType, meaning: 'FHIR presentedForm attachment content type.', example: 'application/pdf' },
|
|
55
55
|
{ key: DiagnosticReportClaim.PresentedFormData, meaning: 'FHIR presentedForm inline base64 payload.', example: 'JVBERi0xLjc...' },
|
|
56
56
|
{ key: DiagnosticReportClaim.PresentedFormUrl, meaning: 'FHIR presentedForm external URL.', example: 'https://example.org/report.pdf' },
|
|
57
|
-
{ key: DiagnosticReportClaim.
|
|
57
|
+
{ key: DiagnosticReportClaim.ContainedReferenceList, meaning: 'Canonical CSV of independent result and evidence resource references linked by this report.', example: 'Observation/result-1,DocumentReference/report-1' },
|
|
58
58
|
];
|
|
59
59
|
export const DiagnosticReportSearchParamNames = {
|
|
60
60
|
BasedOn: 'based-on',
|
|
@@ -106,15 +106,7 @@ export const DiagnosticReportSearchParamToClaimKey = {
|
|
|
106
106
|
[DiagnosticReportSearchParamNames.Subject]: DiagnosticReportClaimsFhirApi.Subject,
|
|
107
107
|
};
|
|
108
108
|
/**
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* Do not invent camelCase names. Prefer official FHIR search parameter names
|
|
114
|
-
* or explicit attachment aliases such as `presented-form-*` and
|
|
115
|
-
* `contained-reference-list`.
|
|
116
|
-
*
|
|
117
|
-
* Keep `DiagnosticReport` paused at the typing/mapping layer until:
|
|
118
|
-
* 1. `claims-helpers-diagnostic-report.ts` exists
|
|
119
|
-
* 2. GW Core readers/tests consume the same shared claim keys
|
|
109
|
+
* Operational attachment and graph claims remain separate from the official
|
|
110
|
+
* SearchParameter catalog above. They support claims-first authoring without
|
|
111
|
+
* pretending that those aliases are searchable FHIR parameters.
|
|
120
112
|
*/
|
|
@@ -70,16 +70,16 @@ export function normalizeLegacyContainedClaims(entry) {
|
|
|
70
70
|
*/
|
|
71
71
|
export function buildDocumentReferenceFlatEntry(input) {
|
|
72
72
|
const claims = {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
[DocumentReferenceClaim.Identifier]: requiredToken(input.identifier, 'document_reference_identifier_required'),
|
|
74
|
+
[DocumentReferenceClaim.ContentType]: input.contentType,
|
|
75
|
+
[DocumentReferenceClaim.ContentHash]: requiredToken(input.contentHash, 'document_reference_contenthash_required'),
|
|
76
76
|
};
|
|
77
77
|
if (input.title?.trim())
|
|
78
|
-
claims[
|
|
78
|
+
claims[DocumentReferenceClaim.Description] = input.title.trim();
|
|
79
79
|
if (input.url?.trim())
|
|
80
|
-
claims[
|
|
80
|
+
claims[DocumentReferenceClaim.Location] = input.url.trim();
|
|
81
81
|
if (input.dataBase64?.trim())
|
|
82
|
-
claims[
|
|
82
|
+
claims[DocumentReferenceClaim.ContentData] = input.dataBase64.trim();
|
|
83
83
|
return buildFlatClaimResourceEntry({ entryId: input.entryId, resourceType: 'DocumentReference', claims });
|
|
84
84
|
}
|
|
85
85
|
function splitCsv(value) {
|
|
@@ -106,3 +106,4 @@ function requiredResourceType(value) {
|
|
|
106
106
|
throw new TypeError('flat_claim_resource_type_invalid');
|
|
107
107
|
return normalized;
|
|
108
108
|
}
|
|
109
|
+
import { DocumentReferenceClaim } from './claims/document-reference-claims.js';
|
|
@@ -83,6 +83,13 @@ one native `Observation.component[]`; it does not export three independent
|
|
|
83
83
|
native Observations. Component entries do not use `is-contained`,
|
|
84
84
|
`contained-parent-reference` or `contained-reference-list`.
|
|
85
85
|
|
|
86
|
+
Diagnostic laboratory authoring is owned here by
|
|
87
|
+
`buildDiagnosticReportFlatGraph(...)`: `DiagnosticReport.code` identifies the
|
|
88
|
+
report/panel, independent Observation entries carry atomic results, and
|
|
89
|
+
independent DocumentReference entries carry PDF/image evidence. Sector roles,
|
|
90
|
+
confirmation, ledger eligibility, consent and research policy remain outside
|
|
91
|
+
this package.
|
|
92
|
+
|
|
86
93
|
Aligned JSON arrays and the older comma-separated `Observation.component-*`
|
|
87
94
|
claims are accepted only by the migration reader. No current writer emits
|
|
88
95
|
either representation.
|