gdc-sdk-node-ts 2.9.8 → 2.9.10
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 +9 -4
- package/dist/individual-onboarding.d.ts +12 -0
- package/dist/individual-onboarding.js +20 -2
- package/dist/node-runtime-client.d.ts +7 -1
- package/dist/node-runtime-client.js +9 -1
- package/dist/orchestration/client-port.d.ts +2 -1
- package/dist/orchestration/individual-controller-sdk.d.ts +7 -1
- package/dist/orchestration/individual-controller-sdk.js +9 -0
- package/dist/orchestration/individual-member-sdk.d.ts +3 -1
- package/dist/orchestration/individual-member-sdk.js +4 -0
- package/dist/orchestration/personal-sdk.d.ts +3 -1
- package/dist/orchestration/personal-sdk.js +4 -0
- package/dist/orchestration/professional-sdk.d.ts +3 -1
- package/dist/orchestration/professional-sdk.js +4 -0
- package/dist/organization-employee-lifecycle.d.ts +6 -0
- package/dist/organization-employee-lifecycle.js +25 -1
- package/dist/resource-operations.d.ts +9 -1
- package/dist/resource-operations.js +10 -1
- package/dist/server-profile-session.d.ts +31 -0
- package/dist/server-profile-session.js +54 -1
- package/package.json +2 -2
- package/dist/organization-registration-authorization.d.ts +0 -16
- package/dist/organization-registration-authorization.js +0 -34
package/README.md
CHANGED
|
@@ -686,8 +686,8 @@ modules below.
|
|
|
686
686
|
- types: `IndividualOrganizationBootstrapInput`, `OfferPreview`, `IndividualOrganizationStartResult`
|
|
687
687
|
- function: `registerIndividualOrganizationWithDeps(...)`
|
|
688
688
|
- [`src/individual-onboarding.ts`](src/individual-onboarding.ts)
|
|
689
|
-
- types: `RouteContext`, `IndividualOrganizationConfirmOrderInput`
|
|
690
|
-
-
|
|
689
|
+
- types: `RouteContext`, `IndividualOrganizationConfirmOrderInput`, `IndividualOrganizationOrderResult`
|
|
690
|
+
- functions: `confirmIndividualOrganizationOrderWithDeps(...)`, `readIndividualOrganizationControllerAssignmentIdentifier(...)`
|
|
691
691
|
- [`src/device-activation.ts`](src/device-activation.ts)
|
|
692
692
|
- types: `EmployeeDeviceActivationInput`, `EmployeeDeviceActivationRequestInput`, `EmployeeDeviceActivationResult`
|
|
693
693
|
- functions: `activateEmployeeDeviceWithActivationCodeWithDeps(...)`, `activateEmployeeDeviceWithActivationRequestWithDeps(...)`
|
|
@@ -744,7 +744,12 @@ modules below.
|
|
|
744
744
|
portal alias
|
|
745
745
|
- vital-sign helpers
|
|
746
746
|
|
|
747
|
-
###
|
|
747
|
+
### Author and attester provenance in subject sections and documents
|
|
748
|
+
|
|
749
|
+
The canonical integration boundary is
|
|
750
|
+
[Subject-section author and profile-attester contract](./docs/101-CLINICAL_AUTHOR_ATTESTER_BOUNDARIES.md).
|
|
751
|
+
It keeps technical enrollment free of per-write authorship, preserves the
|
|
752
|
+
write-specific data author and resolves the attester from the unlocked profile.
|
|
748
753
|
|
|
749
754
|
A document Bundle keeps `Composition.author` (the organization, EHR/patient
|
|
750
755
|
portal or individual that supplies the document) separate from
|
|
@@ -771,7 +776,7 @@ See [Clinical writes from a Node BFF](./docs/101-BFF_CLINICAL_WRITES.md),
|
|
|
771
776
|
- [`NodeHttpClient.ingestCommunicationAndUpdateIndex(...)`](src/node-runtime-client.ts)
|
|
772
777
|
- [`NodeHttpClient.submitCommunicationAndPoll(...)`](src/node-runtime-client.ts)
|
|
773
778
|
- [`NodeHttpClient.searchClinicalBundle(...)`](src/node-runtime-client.ts)
|
|
774
|
-
- [`NodeHttpClient.
|
|
779
|
+
- [`NodeHttpClient.updateSubjectSection(...)`](src/node-runtime-client.ts) for
|
|
775
780
|
one explicit section carried by a batch Communication; its typed entries may
|
|
776
781
|
mix `.create()`, `.update()` and exact authored `.delete()` operations
|
|
777
782
|
- [`NodeHttpClient.updateClinicalSummary(...)`](src/node-runtime-client.ts) for
|
|
@@ -27,6 +27,11 @@ export type IndividualOrganizationConfirmOrderInput = {
|
|
|
27
27
|
*/
|
|
28
28
|
export type IndividualOrganizationOrderResult = SubmitAndPollResult & Readonly<{
|
|
29
29
|
activationCode: string;
|
|
30
|
+
/**
|
|
31
|
+
* Governed RelatedPerson identifier automatically materialized by GW for
|
|
32
|
+
* the principal Organization owner/controller.
|
|
33
|
+
*/
|
|
34
|
+
controllerAssignmentIdentifier: string;
|
|
30
35
|
}>;
|
|
31
36
|
type ConfirmIndividualOrganizationOrderDeps = {
|
|
32
37
|
input: IndividualOrganizationConfirmOrderInput;
|
|
@@ -46,4 +51,11 @@ export declare function confirmIndividualOrganizationOrderWithDeps(deps: Confirm
|
|
|
46
51
|
* this reader directly; it remains public for response-adapter compatibility.
|
|
47
52
|
*/
|
|
48
53
|
export declare function readIndividualOrganizationActivationCode(responseBody: unknown): string | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Reads the principal owner/controller assignment that GW creates during the
|
|
56
|
+
* same Order transition as the individual controller licence. This is a
|
|
57
|
+
* projection from the returned RelatedPerson `resource.meta.claims`; it is not
|
|
58
|
+
* an Order claim and callers must not pre-create or search for it.
|
|
59
|
+
*/
|
|
60
|
+
export declare function readIndividualOrganizationControllerAssignmentIdentifier(responseBody: unknown): string | undefined;
|
|
49
61
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
-
import { extractPrimaryClaims } from 'gdc-common-utils-ts';
|
|
2
|
+
import { HealthcareActorRoleCodes, HL7_CODING_SYSTEM_V3_ROLE_CODE, extractPrimaryClaims, readRelatedPersonListRecords, } from 'gdc-common-utils-ts';
|
|
3
3
|
import { resolvePollOptionsFromSeconds } from './poll-options.js';
|
|
4
4
|
export async function confirmIndividualOrganizationOrderWithDeps(deps) {
|
|
5
5
|
/**
|
|
@@ -40,7 +40,11 @@ export async function confirmIndividualOrganizationOrderWithDeps(deps) {
|
|
|
40
40
|
if (!activationCode) {
|
|
41
41
|
throw new Error('confirmIndividualOrganizationOrder failed: missing controller activation code in GW Order response.');
|
|
42
42
|
}
|
|
43
|
-
|
|
43
|
+
const controllerAssignmentIdentifier = readIndividualOrganizationControllerAssignmentIdentifier(order.poll.body);
|
|
44
|
+
if (!controllerAssignmentIdentifier) {
|
|
45
|
+
throw new Error('confirmIndividualOrganizationOrder failed: missing automatic controller RESPRSN assignment in GW Order response.');
|
|
46
|
+
}
|
|
47
|
+
return { ...order, activationCode, controllerAssignmentIdentifier };
|
|
44
48
|
}
|
|
45
49
|
/**
|
|
46
50
|
* Reads the opaque controller activation code from a completed individual
|
|
@@ -51,6 +55,20 @@ export function readIndividualOrganizationActivationCode(responseBody) {
|
|
|
51
55
|
const claims = extractPrimaryClaims(responseBody);
|
|
52
56
|
return String(claims['org.schema.IndividualProduct.serialNumber'] || '').trim() || undefined;
|
|
53
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Reads the principal owner/controller assignment that GW creates during the
|
|
60
|
+
* same Order transition as the individual controller licence. This is a
|
|
61
|
+
* projection from the returned RelatedPerson `resource.meta.claims`; it is not
|
|
62
|
+
* an Order claim and callers must not pre-create or search for it.
|
|
63
|
+
*/
|
|
64
|
+
export function readIndividualOrganizationControllerAssignmentIdentifier(responseBody) {
|
|
65
|
+
const expectedRelationship = `${HL7_CODING_SYSTEM_V3_ROLE_CODE}|${HealthcareActorRoleCodes.Controller}`;
|
|
66
|
+
return readRelatedPersonListRecords(responseBody)
|
|
67
|
+
.find((record) => record.identifier
|
|
68
|
+
&& record.relationship === expectedRelationship
|
|
69
|
+
&& record.active !== 'false')
|
|
70
|
+
?.identifier;
|
|
71
|
+
}
|
|
54
72
|
function createRuntimeUuid() {
|
|
55
73
|
const fromCrypto = globalThis.crypto?.randomUUID?.();
|
|
56
74
|
if (fromCrypto) {
|
|
@@ -12,7 +12,7 @@ import { type SmartTokenRequestInput } from './smart-token.js';
|
|
|
12
12
|
import { type EmployeeDeviceActivationRequestInput, type EmployeeDeviceActivationResult, type EmployeeDeviceOtpRecoveryInput, type EmployeeDeviceOtpRecoveryResult, type EmployeeDeviceRevocationInput } from './device-activation.js';
|
|
13
13
|
import { type OrganizationLicenseOrderConfirmInput } from './organization-license-order.js';
|
|
14
14
|
import { type IndividualOrganizationRegistrationInput, type IndividualOrganizationRegistrationResult } from './individual-start.js';
|
|
15
|
-
import { type CommunicationIngestionInput, type BlockchainArtifactRegistrationInput, type VitalSignBatchCommunicationFromSearchResponseInput, type CommunicationParticipantRuntimeSearchInput, type ClinicalBundleSearchInput, type ClinicalSectionUpdateInput, type ClinicalSummaryReadResult, type ClinicalSummaryRequestInput, type ClinicalSummaryUpdateInput, type GrantProfessionalAccessInput, type GrantProfessionalAccessResult, type DigitalTwinSecondaryUseConsentInput, type DigitalTwinSecondaryUseConsentResult, type DigitalTwinSubjectLinkPurgeInput, type DigitalTwinSubjectLinkPurgeResult, type SubjectConsentSearchInput, type IndividualMemberLifecycleInput, type IndividualMemberLicenseAddInput, type IndividualMemberLicenseInvitationInput, type IndividualMemberLicenseTransitionInput, type LicenseListRuntimeSearchInput, type LicenseOfferRuntimeSearchInput, type LicenseOrderRuntimeSearchInput, type OrganizationEmployeeCreationInput, type OrganizationEmployeeLicenseAddInput, type OrganizationEmployeeLicenseOfferInput, type OrganizationEmployeeLicenseInvitationInput, type OrganizationEmployeeLifecycleInput, type OrganizationEmployeeSearchInput, type ProfessionalAccessRequestInput, type ProfessionalAccessRequestResult, type RevokeProfessionalAccessInput, type RevokeProfessionalAccessResult, type RelatedPersonUpsertInput } from './resource-operations.js';
|
|
15
|
+
import { type CommunicationIngestionInput, type BlockchainArtifactRegistrationInput, type VitalSignBatchCommunicationFromSearchResponseInput, type CommunicationParticipantRuntimeSearchInput, type ClinicalBundleSearchInput, type ClinicalSectionUpdateInput, type SubjectSectionUpdateInput, type ClinicalSummaryReadResult, type ClinicalSummaryRequestInput, type ClinicalSummaryUpdateInput, type GrantProfessionalAccessInput, type GrantProfessionalAccessResult, type DigitalTwinSecondaryUseConsentInput, type DigitalTwinSecondaryUseConsentResult, type DigitalTwinSubjectLinkPurgeInput, type DigitalTwinSubjectLinkPurgeResult, type SubjectConsentSearchInput, type IndividualMemberLifecycleInput, type IndividualMemberLicenseAddInput, type IndividualMemberLicenseInvitationInput, type IndividualMemberLicenseTransitionInput, type LicenseListRuntimeSearchInput, type LicenseOfferRuntimeSearchInput, type LicenseOrderRuntimeSearchInput, type OrganizationEmployeeCreationInput, type OrganizationEmployeeLicenseAddInput, type OrganizationEmployeeLicenseOfferInput, type OrganizationEmployeeLicenseInvitationInput, type OrganizationEmployeeLifecycleInput, type OrganizationEmployeeSearchInput, type ProfessionalAccessRequestInput, type ProfessionalAccessRequestResult, type RevokeProfessionalAccessInput, type RevokeProfessionalAccessResult, type RelatedPersonUpsertInput } from './resource-operations.js';
|
|
16
16
|
import type { LegalOrganizationOrderInput } from './host-onboarding.js';
|
|
17
17
|
import type { SmartTokenExchangeResult } from './smart-token.js';
|
|
18
18
|
import { type OrganizationEmployeeProvisioningInput, type OrganizationEmployeeProvisioningResult } from './organization-employee-lifecycle.js';
|
|
@@ -537,6 +537,12 @@ export declare class HttpRuntimeClient implements NodeRuntimeClient {
|
|
|
537
537
|
* supply or configure ledger channel or smart-contract names.
|
|
538
538
|
*/
|
|
539
539
|
updateClinicalSection(ctx: RouteContext, input: ClinicalSectionUpdateInput): Promise<SubmitAndPollResult>;
|
|
540
|
+
/**
|
|
541
|
+
* Updates one generic subject section. The attached batch/collection may
|
|
542
|
+
* contain clinical or non-clinical resources. It receives the exact
|
|
543
|
+
* attester exposed by the unlocked profile.
|
|
544
|
+
*/
|
|
545
|
+
updateSubjectSection(ctx: RouteContext, input: SubjectSectionUpdateInput): Promise<SubmitAndPollResult>;
|
|
540
546
|
/**
|
|
541
547
|
* Updates several clinical sections as one Composition-first document.
|
|
542
548
|
*
|
|
@@ -10,7 +10,7 @@ import { activateEmployeeDeviceWithActivationCodeWithDeps, activateEmployeeDevic
|
|
|
10
10
|
import { extractOfferIdFromResponseBody, extractOfferPreviewFromResponseBody, } from './order-offer-summary.js';
|
|
11
11
|
import { confirmOrganizationLicenseOrderWithDeps } from './organization-license-order.js';
|
|
12
12
|
import { registerIndividualOrganizationWithDeps } from './individual-start.js';
|
|
13
|
-
import { createOrganizationEmployeeWithDeps, issueOrganizationEmployeeLicenseWithDeps, disableIndividualMemberWithDeps, disableIndividualOrganizationWithDeps, disableOrganizationEmployeeWithDeps, listIndividualLicenseOffersWithDeps, listIndividualLicenseOrdersWithDeps, listIndividualLicensesWithDeps, addFreeIndividualMemberLicensesWithDeps, issueIndividualMemberLicenseWithDeps, transitionIndividualMemberLicenseWithDeps, listOrganizationLicenseOffersWithDeps, listOrganizationLicenseOrdersWithDeps, listOrganizationLicensesWithDeps, grantProfessionalAccessWithDeps, setDigitalTwinSecondaryUseConsentWithDeps, purgeDigitalTwinSubjectLinkWithDeps, searchSubjectConsentsWithDeps, buildClinicalSectionUpdateIngestion, buildClinicalSummaryUpdateIngestion, ingestCommunicationAndUpdateIndexWithDeps, requestProfessionalAccessWithDeps, buildVitalSignBatchCommunicationFromSearchResponse, registerBlockchainArtifactAndUpdateIndexWithDeps, requestClinicalSummaryWithDeps, revokeProfessionalAccessWithDeps, searchCommunicationParticipantsWithDeps, purgeIndividualMemberWithDeps, purgeIndividualOrganizationWithDeps, purgeOrganizationEmployeeWithDeps, prepareEmployeeLifecycleMessageForTransport, searchIndividualLicensesWithDeps, searchIndividualLicenseOffersWithDeps, searchIndividualLicenseOrdersWithDeps, searchOrganizationLicensesWithDeps, searchOrganizationLicenseOffersWithDeps, searchOrganizationLicenseOrdersWithDeps, searchOrganizationEmployeesWithDeps, searchClinicalBundleWithDeps, searchLatestIpsWithDeps, upsertRelatedPersonAndPollWithDeps, normalizeCommunicationPathFormatSegment, addFreeOrganizationEmployeeLicensesWithDeps, requestOrganizationEmployeeLicenseOfferWithDeps, } from './resource-operations.js';
|
|
13
|
+
import { createOrganizationEmployeeWithDeps, issueOrganizationEmployeeLicenseWithDeps, disableIndividualMemberWithDeps, disableIndividualOrganizationWithDeps, disableOrganizationEmployeeWithDeps, listIndividualLicenseOffersWithDeps, listIndividualLicenseOrdersWithDeps, listIndividualLicensesWithDeps, addFreeIndividualMemberLicensesWithDeps, issueIndividualMemberLicenseWithDeps, transitionIndividualMemberLicenseWithDeps, listOrganizationLicenseOffersWithDeps, listOrganizationLicenseOrdersWithDeps, listOrganizationLicensesWithDeps, grantProfessionalAccessWithDeps, setDigitalTwinSecondaryUseConsentWithDeps, purgeDigitalTwinSubjectLinkWithDeps, searchSubjectConsentsWithDeps, buildClinicalSectionUpdateIngestion, buildSubjectSectionUpdateIngestion, buildClinicalSummaryUpdateIngestion, ingestCommunicationAndUpdateIndexWithDeps, requestProfessionalAccessWithDeps, buildVitalSignBatchCommunicationFromSearchResponse, registerBlockchainArtifactAndUpdateIndexWithDeps, requestClinicalSummaryWithDeps, revokeProfessionalAccessWithDeps, searchCommunicationParticipantsWithDeps, purgeIndividualMemberWithDeps, purgeIndividualOrganizationWithDeps, purgeOrganizationEmployeeWithDeps, prepareEmployeeLifecycleMessageForTransport, searchIndividualLicensesWithDeps, searchIndividualLicenseOffersWithDeps, searchIndividualLicenseOrdersWithDeps, searchOrganizationLicensesWithDeps, searchOrganizationLicenseOffersWithDeps, searchOrganizationLicenseOrdersWithDeps, searchOrganizationEmployeesWithDeps, searchClinicalBundleWithDeps, searchLatestIpsWithDeps, upsertRelatedPersonAndPollWithDeps, normalizeCommunicationPathFormatSegment, addFreeOrganizationEmployeeLicensesWithDeps, requestOrganizationEmployeeLicenseOfferWithDeps, } from './resource-operations.js';
|
|
14
14
|
import { listOrganizationEmployeeLifecycleWithDeps, provisionOrganizationEmployeeWithDeps, } from './organization-employee-lifecycle.js';
|
|
15
15
|
import { buildRuntimeHeaders, fetchWithTimeout, parseResponseBody, postRenderedWithRuntimeConfig, } from './runtime-transport.js';
|
|
16
16
|
import { activateOrganizationInGatewayFromIcaProofWithDeps, submitLegalOrganizationCredentialReissuanceWithDeps, submitLegalOrganizationVerificationTransactionWithDeps, submitOrganizationDidBindingWithDeps, } from './runtime-host-submission.js';
|
|
@@ -1043,6 +1043,14 @@ export class HttpRuntimeClient {
|
|
|
1043
1043
|
async updateClinicalSection(ctx, input) {
|
|
1044
1044
|
return this.ingestCommunicationAndUpdateIndex(ctx, buildClinicalSectionUpdateIngestion(input));
|
|
1045
1045
|
}
|
|
1046
|
+
/**
|
|
1047
|
+
* Updates one generic subject section. The attached batch/collection may
|
|
1048
|
+
* contain clinical or non-clinical resources. It receives the exact
|
|
1049
|
+
* attester exposed by the unlocked profile.
|
|
1050
|
+
*/
|
|
1051
|
+
async updateSubjectSection(ctx, input) {
|
|
1052
|
+
return this.ingestCommunicationAndUpdateIndex(ctx, buildSubjectSectionUpdateIngestion(input));
|
|
1053
|
+
}
|
|
1046
1054
|
/**
|
|
1047
1055
|
* Updates several clinical sections as one Composition-first document.
|
|
1048
1056
|
*
|
|
@@ -19,7 +19,7 @@ import type { OrganizationLicenseOrderConfirmInput } from '../organization-licen
|
|
|
19
19
|
import type { SmartTokenExchangeResult, SmartTokenRequestInput } from '../smart-token.js';
|
|
20
20
|
import type { DigitalTwinMaterializationInput, DigitalTwinSearchInput, DigitalTwinSelectionInput } from '../digital-twin.js';
|
|
21
21
|
import type { AuthorizedIndividualSubject, AuthorizedIndividualSubjectDirectoryInput } from '../authorized-subject-directory.js';
|
|
22
|
-
import type { CommunicationIngestionInput, BlockchainArtifactRegistrationInput, CommunicationParticipantRuntimeSearchInput, ClinicalBundleSearchInput, ClinicalSectionUpdateInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, ClinicalSummaryUpdateInput, VitalSignBatchCommunicationFromSearchResponseInput, DigitalTwinGenerationInput, DigitalTwinSecondaryUseConsentInput, DigitalTwinSecondaryUseConsentResult, DigitalTwinSubjectLinkPurgeInput, DigitalTwinSubjectLinkPurgeResult, GrantProfessionalAccessInput, GrantProfessionalAccessResult, IndividualMemberLifecycleInput, IndividualMemberLicenseAddInput, IndividualMemberLicenseInvitationInput, IndividualMemberLicenseTransitionInput, IpsOrFhirImportInput, OrganizationEmployeeCreationInput, OrganizationEmployeeLicenseAddInput, OrganizationEmployeeLicenseOfferInput, OrganizationEmployeeLicenseInvitationInput, OrganizationEmployeeLifecycleInput, OrganizationEmployeeSearchInput, ProfessionalAccessRequestInput, ProfessionalAccessRequestResult, RevokeProfessionalAccessInput, RevokeProfessionalAccessResult, RelatedPersonUpsertInput, SubjectConsentSearchInput } from '../resource-operations.js';
|
|
22
|
+
import type { CommunicationIngestionInput, BlockchainArtifactRegistrationInput, CommunicationParticipantRuntimeSearchInput, ClinicalBundleSearchInput, ClinicalSectionUpdateInput, SubjectSectionUpdateInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, ClinicalSummaryUpdateInput, VitalSignBatchCommunicationFromSearchResponseInput, DigitalTwinGenerationInput, DigitalTwinSecondaryUseConsentInput, DigitalTwinSecondaryUseConsentResult, DigitalTwinSubjectLinkPurgeInput, DigitalTwinSubjectLinkPurgeResult, GrantProfessionalAccessInput, GrantProfessionalAccessResult, IndividualMemberLifecycleInput, IndividualMemberLicenseAddInput, IndividualMemberLicenseInvitationInput, IndividualMemberLicenseTransitionInput, IpsOrFhirImportInput, OrganizationEmployeeCreationInput, OrganizationEmployeeLicenseAddInput, OrganizationEmployeeLicenseOfferInput, OrganizationEmployeeLicenseInvitationInput, OrganizationEmployeeLifecycleInput, OrganizationEmployeeSearchInput, ProfessionalAccessRequestInput, ProfessionalAccessRequestResult, RevokeProfessionalAccessInput, RevokeProfessionalAccessResult, RelatedPersonUpsertInput, SubjectConsentSearchInput } from '../resource-operations.js';
|
|
23
23
|
/**
|
|
24
24
|
* Shared node-runtime activation input.
|
|
25
25
|
*
|
|
@@ -119,6 +119,7 @@ export type RuntimeClient = {
|
|
|
119
119
|
ingestCommunicationAndUpdateIndex?: (ctx: RouteContext, input: CommunicationIngestionInput) => Promise<SubmitAndPollResult>;
|
|
120
120
|
requestProfessionalAccess?: (ctx: RouteContext, input: ProfessionalAccessRequestInput) => Promise<ProfessionalAccessRequestResult>;
|
|
121
121
|
updateClinicalSection?: (ctx: RouteContext, input: ClinicalSectionUpdateInput) => Promise<SubmitAndPollResult>;
|
|
122
|
+
updateSubjectSection?: (ctx: RouteContext, input: SubjectSectionUpdateInput) => Promise<SubmitAndPollResult>;
|
|
122
123
|
updateClinicalSummary?: (ctx: RouteContext, input: ClinicalSummaryUpdateInput) => Promise<SubmitAndPollResult>;
|
|
123
124
|
requestClinicalSummary?: (ctx: RouteContext, input: ClinicalSummaryRequestInput) => Promise<ClinicalSummaryReadResult>;
|
|
124
125
|
registerBlockchainArtifactAndUpdateIndex?: (ctx: RouteContext, input: BlockchainArtifactRegistrationInput) => Promise<SubmitAndPollResult>;
|
|
@@ -7,7 +7,7 @@ import type { IndividualOrganizationConfirmOrderInput, IndividualOrganizationOrd
|
|
|
7
7
|
import type { IndividualOrganizationRegistrationInput, IndividualOrganizationRegistrationResult } from '../individual-start.js';
|
|
8
8
|
import type { NodeCapability } from '../session.js';
|
|
9
9
|
import type { IndividualOrganizationLifecycleInput } from 'gdc-sdk-core-ts';
|
|
10
|
-
import type { BlockchainArtifactRegistrationInput, ClinicalBundleSearchInput, ClinicalSectionUpdateInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, ClinicalSummaryUpdateInput, CommunicationIngestionInput, CommunicationParticipantRuntimeSearchInput, DigitalTwinGenerationInput, DigitalTwinSecondaryUseConsentInput, DigitalTwinSecondaryUseConsentResult, DigitalTwinSubjectLinkPurgeInput, DigitalTwinSubjectLinkPurgeResult, GrantProfessionalAccessInput, GrantProfessionalAccessResult, IndividualMemberLifecycleInput, IndividualMemberLicenseAddInput, IndividualMemberLicenseInvitationInput, IndividualMemberLicenseTransitionInput, IpsOrFhirImportInput, LicenseListRuntimeSearchInput, LicenseOfferRuntimeSearchInput, LicenseOrderRuntimeSearchInput, RevokeProfessionalAccessInput, RevokeProfessionalAccessResult, ProfessionalAccessRequestDecisionInput, ProfessionalAccessRequestSearchInput, RelatedPersonUpsertInput } from '../resource-operations.js';
|
|
10
|
+
import type { BlockchainArtifactRegistrationInput, ClinicalBundleSearchInput, ClinicalSectionUpdateInput, SubjectSectionUpdateInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, ClinicalSummaryUpdateInput, CommunicationIngestionInput, CommunicationParticipantRuntimeSearchInput, DigitalTwinGenerationInput, DigitalTwinSecondaryUseConsentInput, DigitalTwinSecondaryUseConsentResult, DigitalTwinSubjectLinkPurgeInput, DigitalTwinSubjectLinkPurgeResult, GrantProfessionalAccessInput, GrantProfessionalAccessResult, IndividualMemberLifecycleInput, IndividualMemberLicenseAddInput, IndividualMemberLicenseInvitationInput, IndividualMemberLicenseTransitionInput, IpsOrFhirImportInput, LicenseListRuntimeSearchInput, LicenseOfferRuntimeSearchInput, LicenseOrderRuntimeSearchInput, RevokeProfessionalAccessInput, RevokeProfessionalAccessResult, ProfessionalAccessRequestDecisionInput, ProfessionalAccessRequestSearchInput, RelatedPersonUpsertInput } from '../resource-operations.js';
|
|
11
11
|
import type { SmartTokenExchangeResult, SmartTokenRequestInput } from '../smart-token.js';
|
|
12
12
|
/**
|
|
13
13
|
* Individual-controller oriented facade over a `NodeRuntimeClient`.
|
|
@@ -113,6 +113,12 @@ export declare class IndividualControllerSdk {
|
|
|
113
113
|
* DELETE entries contain no resource body.
|
|
114
114
|
*/
|
|
115
115
|
updateClinicalSection(ctx: RouteContext, input: ClinicalSectionUpdateInput): Promise<SubmitAndPollResult>;
|
|
116
|
+
/**
|
|
117
|
+
* Updates one subject-owned section, including non-clinical sections such as
|
|
118
|
+
* appointments or contracts, while preserving the indexed Composition
|
|
119
|
+
* author/attester compatibility contract.
|
|
120
|
+
*/
|
|
121
|
+
updateSubjectSection(ctx: RouteContext, input: SubjectSectionUpdateInput): Promise<SubmitAndPollResult>;
|
|
116
122
|
/**
|
|
117
123
|
* Updates the multi-section summary through a Composition-first document.
|
|
118
124
|
* On a direct call, use the authenticated profile `actorDid` as `sender` and
|
|
@@ -166,6 +166,15 @@ export class IndividualControllerSdk {
|
|
|
166
166
|
assertFacadeCapability(this.capabilities, ActorCapabilities.IndividualIngestCommunication, ActorKinds.IndividualController, 'updateClinicalSection');
|
|
167
167
|
return requireClientMethod(this.client, 'updateClinicalSection')(ctx, input);
|
|
168
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* Updates one subject-owned section, including non-clinical sections such as
|
|
171
|
+
* appointments or contracts, while preserving the indexed Composition
|
|
172
|
+
* author/attester compatibility contract.
|
|
173
|
+
*/
|
|
174
|
+
updateSubjectSection(ctx, input) {
|
|
175
|
+
assertFacadeCapability(this.capabilities, ActorCapabilities.IndividualIngestCommunication, ActorKinds.IndividualController, 'updateSubjectSection');
|
|
176
|
+
return requireClientMethod(this.client, 'updateSubjectSection')(ctx, input);
|
|
177
|
+
}
|
|
169
178
|
/**
|
|
170
179
|
* Updates the multi-section summary through a Composition-first document.
|
|
171
180
|
* On a direct call, use the authenticated profile `actorDid` as `sender` and
|
|
@@ -2,7 +2,7 @@ import { type IndividualMemberCredentialInput, type IndividualMemberVpPayloadInp
|
|
|
2
2
|
import { type NodeRuntimeClient } from './client-port.js';
|
|
3
3
|
import type { SmartTokenExchangeResult, SmartTokenRequestInput } from '../smart-token.js';
|
|
4
4
|
import type { RouteContext } from '../individual-onboarding.js';
|
|
5
|
-
import type { ClinicalBundleSearchInput, ClinicalSectionUpdateInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, ClinicalSummaryUpdateInput, CommunicationIngestionInput, IndividualMemberLicenseTransitionInput, RelatedPersonUpsertInput } from '../resource-operations.js';
|
|
5
|
+
import type { ClinicalBundleSearchInput, ClinicalSectionUpdateInput, SubjectSectionUpdateInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, ClinicalSummaryUpdateInput, CommunicationIngestionInput, IndividualMemberLicenseTransitionInput, RelatedPersonUpsertInput } from '../resource-operations.js';
|
|
6
6
|
export declare class IndividualMemberSdk {
|
|
7
7
|
private readonly client;
|
|
8
8
|
constructor(client: NodeRuntimeClient);
|
|
@@ -31,6 +31,8 @@ export declare class IndividualMemberSdk {
|
|
|
31
31
|
ingestCommunicationAndUpdateIndex(ctx: RouteContext, input: CommunicationIngestionInput): Promise<import("gdc-sdk-core-ts/polling-model.js").SubmitAndPollResult>;
|
|
32
32
|
/** Updates one authorized clinical section through a scoped batch/collection. */
|
|
33
33
|
updateClinicalSection(ctx: RouteContext, input: ClinicalSectionUpdateInput): Promise<import("gdc-sdk-core-ts/polling-model.js").SubmitAndPollResult>;
|
|
34
|
+
/** Updates one authorized subject-owned section with its profile attester. */
|
|
35
|
+
updateSubjectSection(ctx: RouteContext, input: SubjectSectionUpdateInput): Promise<import("gdc-sdk-core-ts/polling-model.js").SubmitAndPollResult>;
|
|
34
36
|
/** Updates an authorized multi-section summary document. */
|
|
35
37
|
updateClinicalSummary(ctx: RouteContext, input: ClinicalSummaryUpdateInput): Promise<import("gdc-sdk-core-ts/polling-model.js").SubmitAndPollResult>;
|
|
36
38
|
/** Reads the member-authorized `$summary` document without mutating the subject index. */
|
|
@@ -40,6 +40,10 @@ export class IndividualMemberSdk {
|
|
|
40
40
|
updateClinicalSection(ctx, input) {
|
|
41
41
|
return requireClientMethod(this.client, 'updateClinicalSection')(ctx, input);
|
|
42
42
|
}
|
|
43
|
+
/** Updates one authorized subject-owned section with its profile attester. */
|
|
44
|
+
updateSubjectSection(ctx, input) {
|
|
45
|
+
return requireClientMethod(this.client, 'updateSubjectSection')(ctx, input);
|
|
46
|
+
}
|
|
43
47
|
/** Updates an authorized multi-section summary document. */
|
|
44
48
|
updateClinicalSummary(ctx, input) {
|
|
45
49
|
return requireClientMethod(this.client, 'updateClinicalSummary')(ctx, input);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type NodeRuntimeClient, type PollOptions, type SubmitAndPollResult, type SubmitPayload } from './client-port.js';
|
|
2
2
|
import type { IndividualOrganizationRegistrationInput, IndividualOrganizationRegistrationResult } from '../individual-start.js';
|
|
3
3
|
import type { RouteContext } from '../individual-onboarding.js';
|
|
4
|
-
import type { BlockchainArtifactRegistrationInput, ClinicalBundleSearchInput, ClinicalSectionUpdateInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, ClinicalSummaryUpdateInput, CommunicationIngestionInput, CommunicationParticipantRuntimeSearchInput, DigitalTwinGenerationInput, GrantProfessionalAccessInput, GrantProfessionalAccessResult, ProfessionalAccessRequestDecisionInput, ProfessionalAccessRequestSearchInput, IpsOrFhirImportInput, LicenseListRuntimeSearchInput, LicenseOfferRuntimeSearchInput, LicenseOrderRuntimeSearchInput } from '../resource-operations.js';
|
|
4
|
+
import type { BlockchainArtifactRegistrationInput, ClinicalBundleSearchInput, ClinicalSectionUpdateInput, SubjectSectionUpdateInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, ClinicalSummaryUpdateInput, CommunicationIngestionInput, CommunicationParticipantRuntimeSearchInput, DigitalTwinGenerationInput, GrantProfessionalAccessInput, GrantProfessionalAccessResult, ProfessionalAccessRequestDecisionInput, ProfessionalAccessRequestSearchInput, IpsOrFhirImportInput, LicenseListRuntimeSearchInput, LicenseOfferRuntimeSearchInput, LicenseOrderRuntimeSearchInput } from '../resource-operations.js';
|
|
5
5
|
import type { SmartTokenExchangeResult, SmartTokenRequestInput } from '../smart-token.js';
|
|
6
6
|
export declare class PersonalSdk {
|
|
7
7
|
private readonly client;
|
|
@@ -22,6 +22,8 @@ export declare class PersonalSdk {
|
|
|
22
22
|
ingestCommunicationAndUpdateIndex(ctx: RouteContext, input: CommunicationIngestionInput): Promise<SubmitAndPollResult>;
|
|
23
23
|
/** Updates one exact clinical section through a section-scoped batch/collection. */
|
|
24
24
|
updateClinicalSection(ctx: RouteContext, input: ClinicalSectionUpdateInput): Promise<SubmitAndPollResult>;
|
|
25
|
+
/** Updates one generic subject-owned section with its profile attester. */
|
|
26
|
+
updateSubjectSection(ctx: RouteContext, input: SubjectSectionUpdateInput): Promise<SubmitAndPollResult>;
|
|
25
27
|
/** Updates the multi-section clinical summary through a Composition-first document. */
|
|
26
28
|
updateClinicalSummary(ctx: RouteContext, input: ClinicalSummaryUpdateInput): Promise<SubmitAndPollResult>;
|
|
27
29
|
/** Reads the current subject through Communication `$summary`; it performs no ingestion. */
|
|
@@ -38,6 +38,10 @@ export class PersonalSdk {
|
|
|
38
38
|
updateClinicalSection(ctx, input) {
|
|
39
39
|
return requireClientMethod(this.client, 'updateClinicalSection')(ctx, input);
|
|
40
40
|
}
|
|
41
|
+
/** Updates one generic subject-owned section with its profile attester. */
|
|
42
|
+
updateSubjectSection(ctx, input) {
|
|
43
|
+
return requireClientMethod(this.client, 'updateSubjectSection')(ctx, input);
|
|
44
|
+
}
|
|
41
45
|
/** Updates the multi-section clinical summary through a Composition-first document. */
|
|
42
46
|
updateClinicalSummary(ctx, input) {
|
|
43
47
|
return requireClientMethod(this.client, 'updateClinicalSummary')(ctx, input);
|
|
@@ -2,7 +2,7 @@ import { type ProfessionalEmployeeCredentialInput, type ProfessionalSmartVpPaylo
|
|
|
2
2
|
import { type NodeRuntimeClient, type PollOptions, type SubmitAndPollResult, type SubmitPayload } from './client-port.js';
|
|
3
3
|
import type { RouteContext } from '../individual-onboarding.js';
|
|
4
4
|
import type { SmartTokenExchangeResult, SmartTokenRequestInput } from '../smart-token.js';
|
|
5
|
-
import type { BlockchainArtifactRegistrationInput, CommunicationIngestionInput, CommunicationParticipantRuntimeSearchInput, ClinicalBundleSearchInput, ClinicalSectionUpdateInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, ClinicalSummaryUpdateInput, GrantProfessionalAccessInput, GrantProfessionalAccessResult, ProfessionalAccessRequestInput, ProfessionalAccessRequestResult, ProfessionalAccessRequestSearchInput, VitalSignBatchCommunicationFromSearchResponseInput } from '../resource-operations.js';
|
|
5
|
+
import type { BlockchainArtifactRegistrationInput, CommunicationIngestionInput, CommunicationParticipantRuntimeSearchInput, ClinicalBundleSearchInput, ClinicalSectionUpdateInput, SubjectSectionUpdateInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, ClinicalSummaryUpdateInput, GrantProfessionalAccessInput, GrantProfessionalAccessResult, ProfessionalAccessRequestInput, ProfessionalAccessRequestResult, ProfessionalAccessRequestSearchInput, VitalSignBatchCommunicationFromSearchResponseInput } from '../resource-operations.js';
|
|
6
6
|
/**
|
|
7
7
|
* Professional-oriented facade for runtime actions that belong to the
|
|
8
8
|
* professional actor itself after tenant and employee provisioning have already
|
|
@@ -85,6 +85,8 @@ export declare class ProfessionalSdk {
|
|
|
85
85
|
listProfessionalAccessRequests(ctx: RouteContext, input: ProfessionalAccessRequestSearchInput): Promise<SubmitAndPollResult>;
|
|
86
86
|
/** Updates one consent-authorized clinical section through a scoped batch/collection. */
|
|
87
87
|
updateClinicalSection(ctx: RouteContext, input: ClinicalSectionUpdateInput): Promise<SubmitAndPollResult>;
|
|
88
|
+
/** Updates one consent-authorized subject section with its profile attester. */
|
|
89
|
+
updateSubjectSection(ctx: RouteContext, input: SubjectSectionUpdateInput): Promise<SubmitAndPollResult>;
|
|
88
90
|
/** Updates a consent-authorized multi-section summary document. */
|
|
89
91
|
updateClinicalSummary(ctx: RouteContext, input: ClinicalSummaryUpdateInput): Promise<SubmitAndPollResult>;
|
|
90
92
|
/**
|
|
@@ -106,6 +106,10 @@ export class ProfessionalSdk {
|
|
|
106
106
|
updateClinicalSection(ctx, input) {
|
|
107
107
|
return requireClientMethod(this.client, 'updateClinicalSection')(ctx, input);
|
|
108
108
|
}
|
|
109
|
+
/** Updates one consent-authorized subject section with its profile attester. */
|
|
110
|
+
updateSubjectSection(ctx, input) {
|
|
111
|
+
return requireClientMethod(this.client, 'updateSubjectSection')(ctx, input);
|
|
112
|
+
}
|
|
109
113
|
/** Updates a consent-authorized multi-section summary document. */
|
|
110
114
|
updateClinicalSummary(ctx, input) {
|
|
111
115
|
return requireClientMethod(this.client, 'updateClinicalSummary')(ctx, input);
|
|
@@ -38,6 +38,12 @@ export type OrganizationEmployeeProvisioningDeps = Readonly<{
|
|
|
38
38
|
export declare function provisionOrganizationEmployeeWithDeps(routeContext: RouteContext, input: OrganizationEmployeeProvisioningInput, deps: OrganizationEmployeeProvisioningDeps): Promise<OrganizationEmployeeProvisioningResult>;
|
|
39
39
|
/** Reads the technical employee id that must own the subsequently issued seat. */
|
|
40
40
|
export declare function readEmployeeResourceId(value: unknown): string | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Reads the concrete PractitionerRole assignment created inside an Employee
|
|
43
|
+
* receipt. This UUID, not the employee DID or contact, becomes the
|
|
44
|
+
* professional profile attester reference.
|
|
45
|
+
*/
|
|
46
|
+
export declare function readEmployeeProfessionalAssignmentIdentifier(value: unknown): string | undefined;
|
|
41
47
|
/** Reads the effective positive installation allowance returned by `License/_issue`. */
|
|
42
48
|
export declare function readEmployeeLicenseMaxDevices(value: unknown): number | undefined;
|
|
43
49
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
2
|
import { createHash } from 'node:crypto';
|
|
3
|
-
import { ActorKinds, EmployeeActivationGrantVersions, projectOrganizationEmployeeLifecycle, readEmployeeActivationCode, } from 'gdc-common-utils-ts';
|
|
3
|
+
import { ActorKinds, ResourceTypesFhirR4, EmployeeActivationGrantVersions, projectOrganizationEmployeeLifecycle, readEmployeeActivationCode, } from 'gdc-common-utils-ts';
|
|
4
4
|
import { buildStableActorIdentifier } from 'gdc-common-utils-ts/utils/actor-identifier';
|
|
5
5
|
import { ClaimsOfferSchemaorg } from 'gdc-common-utils-ts/constants/schemaorg';
|
|
6
6
|
/**
|
|
@@ -64,6 +64,30 @@ export function readEmployeeResourceId(value) {
|
|
|
64
64
|
}
|
|
65
65
|
return undefined;
|
|
66
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Reads the concrete PractitionerRole assignment created inside an Employee
|
|
69
|
+
* receipt. This UUID, not the employee DID or contact, becomes the
|
|
70
|
+
* professional profile attester reference.
|
|
71
|
+
*/
|
|
72
|
+
export function readEmployeeProfessionalAssignmentIdentifier(value) {
|
|
73
|
+
for (const candidate of nestedRecords(value)) {
|
|
74
|
+
const response = record(candidate.response);
|
|
75
|
+
const status = parseHttpStatus(response?.status);
|
|
76
|
+
if (status !== undefined && (status < 200 || status >= 300))
|
|
77
|
+
continue;
|
|
78
|
+
const resource = record(candidate.resource) || candidate;
|
|
79
|
+
const contained = Array.isArray(resource?.contained) ? resource.contained : [];
|
|
80
|
+
for (const item of contained) {
|
|
81
|
+
const assignment = record(item);
|
|
82
|
+
if (assignment?.resourceType !== ResourceTypesFhirR4.PractitionerRole)
|
|
83
|
+
continue;
|
|
84
|
+
const identifier = String(assignment.id || '').trim();
|
|
85
|
+
if (identifier)
|
|
86
|
+
return identifier;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
67
91
|
/** Reads the effective positive installation allowance returned by `License/_issue`. */
|
|
68
92
|
export function readEmployeeLicenseMaxDevices(value) {
|
|
69
93
|
for (const candidate of nestedRecords(value)) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type DeviceAppType } from 'gdc-common-utils-ts/constants/device';
|
|
2
|
-
import { type ClinicalSectionUpdateCommunicationInput, type ClinicalUpdateCommunicationInput, type ClinicalSummaryReadResult, type ClinicalSummaryRequestInput, type PermissionRequestCommunicationInput } from 'gdc-sdk-core-ts';
|
|
2
|
+
import { type ClinicalSectionUpdateCommunicationInput, type SubjectSectionUpdateCommunicationInput, type ClinicalUpdateCommunicationInput, type ClinicalSummaryReadResult, type ClinicalSummaryRequestInput, type PermissionRequestCommunicationInput } from 'gdc-sdk-core-ts';
|
|
3
3
|
import type { LicenseOfferSearchState, LicenseOrderSearchState } from 'gdc-common-utils-ts/utils/license-commercial-search';
|
|
4
4
|
import type { LicenseListSearchState } from 'gdc-common-utils-ts/utils/license-list-search';
|
|
5
5
|
import type { BundleSearchQuery, CommMsgExtendedCommunicationOutboxJob, CommunicationOutboxJob, CommunicationInput, DateRange, EmployeeSearchValue, IndividualOrganizationLifecycleInput, TransportProfile, SubmitPayload } from 'gdc-sdk-core-ts';
|
|
@@ -315,6 +315,12 @@ type ClinicalUpdateRuntimeOptions = Readonly<{
|
|
|
315
315
|
* unless an explicit successor policy applies.
|
|
316
316
|
*/
|
|
317
317
|
export type ClinicalSectionUpdateInput = ClinicalSectionUpdateCommunicationInput & ClinicalUpdateRuntimeOptions;
|
|
318
|
+
/**
|
|
319
|
+
* Preferred generic section mutation for data owned by a human, animal, or
|
|
320
|
+
* other governed subject. It keeps the current Composition-compatible flat
|
|
321
|
+
* author and attester claims used by confidential indexing.
|
|
322
|
+
*/
|
|
323
|
+
export type SubjectSectionUpdateInput = SubjectSectionUpdateCommunicationInput & ClinicalUpdateRuntimeOptions;
|
|
318
324
|
/**
|
|
319
325
|
* Updates one complete multi-section clinical summary document.
|
|
320
326
|
*
|
|
@@ -326,6 +332,8 @@ export type ClinicalSectionUpdateInput = ClinicalSectionUpdateCommunicationInput
|
|
|
326
332
|
*/
|
|
327
333
|
export type ClinicalSummaryUpdateInput = ClinicalUpdateCommunicationInput & ClinicalUpdateRuntimeOptions;
|
|
328
334
|
export declare function buildClinicalSectionUpdateIngestion(input: ClinicalSectionUpdateInput): CommunicationIngestionInput;
|
|
335
|
+
/** Builds the generic subject-section ingestion job. */
|
|
336
|
+
export declare function buildSubjectSectionUpdateIngestion(input: SubjectSectionUpdateInput): CommunicationIngestionInput;
|
|
329
337
|
export declare function buildClinicalSummaryUpdateIngestion(input: ClinicalSummaryUpdateInput): CommunicationIngestionInput;
|
|
330
338
|
export type BlockchainArtifactRegistrationInput = {
|
|
331
339
|
subject: string;
|
|
@@ -7,7 +7,7 @@ import { BundleEditor, buildCommunicationParticipantSearchBundle, buildBlockchai
|
|
|
7
7
|
import { EmployeeBundleOperations, EmployeeResourceTypes, } from 'gdc-common-utils-ts/utils/employee';
|
|
8
8
|
import { DeviceAppTypes, DeviceUserClasses } from 'gdc-common-utils-ts/constants/device';
|
|
9
9
|
import { CommunicationCategoryCodes } from 'gdc-common-utils-ts/constants/communication';
|
|
10
|
-
import { addFhirResourceToCommunication, createCommunicationResource, buildClinicalSummaryCommunicationJob, buildPermissionRequestCommunication, createClinicalSectionUpdateOutboxJob, createClinicalSummaryUpdateOutboxJob, readClinicalSummaryOperationResult, TransportProfiles, } from 'gdc-sdk-core-ts';
|
|
10
|
+
import { addFhirResourceToCommunication, createCommunicationResource, buildClinicalSummaryCommunicationJob, buildPermissionRequestCommunication, createClinicalSectionUpdateOutboxJob, createSubjectSectionUpdateOutboxJob, createClinicalSummaryUpdateOutboxJob, readClinicalSummaryOperationResult, TransportProfiles, } from 'gdc-sdk-core-ts';
|
|
11
11
|
import { GwCoreLifecycleRequestMethod, GwCoreLifecycleRequestType, GwCoreLifecycleTodo, } from './constants/lifecycle.js';
|
|
12
12
|
import { buildEmployeeSearchBundle, ConsentClaims, } from 'gdc-sdk-core-ts';
|
|
13
13
|
import { ClaimConsent } from 'gdc-common-utils-ts/models/consent-rule';
|
|
@@ -20,6 +20,15 @@ export function buildClinicalSectionUpdateIngestion(input) {
|
|
|
20
20
|
pollOptions: input.pollOptions,
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
|
+
/** Builds the generic subject-section ingestion job. */
|
|
24
|
+
export function buildSubjectSectionUpdateIngestion(input) {
|
|
25
|
+
return {
|
|
26
|
+
communicationJob: createSubjectSectionUpdateOutboxJob(input),
|
|
27
|
+
clinicalFormat: input.clinicalFormat,
|
|
28
|
+
transportProfile: input.transportProfile,
|
|
29
|
+
pollOptions: input.pollOptions,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
23
32
|
export function buildClinicalSummaryUpdateIngestion(input) {
|
|
24
33
|
return {
|
|
25
34
|
communicationJob: createClinicalSummaryUpdateOutboxJob(input),
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { JWK } from 'gdc-common-utils-ts/models/jwk';
|
|
2
2
|
import type { ActorKind } from 'gdc-common-utils-ts/models/actor-session';
|
|
3
|
+
import { type RelatedPersonListSelection } from 'gdc-common-utils-ts/utils/related-person-list';
|
|
4
|
+
import { type CompositionAttesterMode } from 'gdc-common-utils-ts/models/interoperable-claims/composition-claims';
|
|
3
5
|
import type { LegalOrganizationVerificationTransactionInput } from 'gdc-common-utils-ts/utils/legal-organization-verification-transaction';
|
|
4
6
|
import { type ClinicalCreatorBindingInput } from 'gdc-common-utils-ts/utils/fhir-ips-creator-identity';
|
|
5
7
|
import { type AppInfo, type ConfidentialStorageProfile, type PollOptions, type SubmitAndPollResult, type ClinicalCreatorBinding, type ClinicalCreatorIpsExport, type ClinicalSourceAuthorSelection } from 'gdc-sdk-core-ts';
|
|
@@ -15,6 +17,26 @@ import type { SecureDidcommTransportAdapter } from 'gdc-sdk-core-ts';
|
|
|
15
17
|
import { type PinProtectedProfileSecret, type ProfileProtectionOptions, type ServerProfileSealer } from './server-profile-protection.js';
|
|
16
18
|
export type { ServerProfileSealer } from './server-profile-protection.js';
|
|
17
19
|
export type ServerActorMode = 'self' | 'controller' | 'member';
|
|
20
|
+
/** FHIR attester assignment bound to one authenticated server profile. */
|
|
21
|
+
export type ServerProfileAttester = Readonly<{
|
|
22
|
+
mode: CompositionAttesterMode;
|
|
23
|
+
party: Readonly<{
|
|
24
|
+
reference: string;
|
|
25
|
+
}>;
|
|
26
|
+
}>;
|
|
27
|
+
/**
|
|
28
|
+
* Builds the canonical `urn:uuid` attester reference from a real
|
|
29
|
+
* RelatedPerson/PractitionerRole assignment returned by GW.
|
|
30
|
+
*/
|
|
31
|
+
export declare function buildProfileAttester(input: Readonly<{
|
|
32
|
+
assignmentIdentifier: string;
|
|
33
|
+
mode: CompositionAttesterMode;
|
|
34
|
+
}>): ServerProfileAttester;
|
|
35
|
+
/**
|
|
36
|
+
* Selects a real active contact/member from a RelatedPerson search response
|
|
37
|
+
* and turns its governed identifier into the personal profile attester.
|
|
38
|
+
*/
|
|
39
|
+
export declare function buildRelatedPersonProfileAttester(relatedPersonSearchResponseBody: unknown, selection: RelatedPersonListSelection): ServerProfileAttester;
|
|
18
40
|
/** Durable public metadata plus PIN-and-host protected private material. */
|
|
19
41
|
export type ServerProfileRecord = Readonly<{
|
|
20
42
|
profileId: string;
|
|
@@ -31,6 +53,8 @@ export type ServerProfileRecord = Readonly<{
|
|
|
31
53
|
clientId: string;
|
|
32
54
|
/** Stable non-secret id of the browser/app installation registered by DCR. */
|
|
33
55
|
clientInstanceId?: string;
|
|
56
|
+
/** Profile identity used as Composition attester; never a per-write author. */
|
|
57
|
+
attester?: ServerProfileAttester;
|
|
34
58
|
/** Stable FHIR creator/permission identity; channel and device values are aliases only. */
|
|
35
59
|
clinicalCreatorBinding?: ClinicalCreatorBinding;
|
|
36
60
|
deviceDid: string;
|
|
@@ -126,6 +150,11 @@ export type ServerProfileEnrollmentInput = Readonly<{
|
|
|
126
150
|
* derives the identity from the wallet key it creates for this profile.
|
|
127
151
|
*/
|
|
128
152
|
clientInstanceId?: string;
|
|
153
|
+
/**
|
|
154
|
+
* Server-selected RelatedPerson/PractitionerRole assignment for this
|
|
155
|
+
* profile. It is persisted locally and is not sent as document authorship.
|
|
156
|
+
*/
|
|
157
|
+
attester?: ServerProfileAttester;
|
|
129
158
|
/**
|
|
130
159
|
* Server-authorized stable creator identity imported from FHIR or generated
|
|
131
160
|
* locally. Enrollment adds the operational actor DID and registered DCR
|
|
@@ -216,6 +245,8 @@ export type ResolvedServerProfileSession = Readonly<{
|
|
|
216
245
|
subjectDid: string;
|
|
217
246
|
scopes: string[];
|
|
218
247
|
accessToken: string;
|
|
248
|
+
/** Attester bound to this authenticated and unlocked profile. */
|
|
249
|
+
attester?: ServerProfileAttester;
|
|
219
250
|
secureTransportAdapter: SecureDidcommTransportAdapter;
|
|
220
251
|
/** Storage adapter available only while the PIN-unlocked session is alive. */
|
|
221
252
|
confidentialStorageAdapter: Readonly<{
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
2
|
import { randomBytes } from 'node:crypto';
|
|
3
3
|
import { ActorKinds } from 'gdc-common-utils-ts/constants/actor-session';
|
|
4
|
-
import {
|
|
4
|
+
import { UrnPrefixes } from 'gdc-common-utils-ts/constants/urn';
|
|
5
|
+
import { normalizeUuid } from 'gdc-common-utils-ts/utils/normalize-uuid';
|
|
6
|
+
import { selectRelatedPersonListRecord, } from 'gdc-common-utils-ts/utils/related-person-list';
|
|
7
|
+
import { CompositionAttesterModes, } from 'gdc-common-utils-ts/models/interoperable-claims/composition-claims';
|
|
8
|
+
import { FhirIpsCreatorKinds, normalizeClinicalCreatorBinding, } from 'gdc-common-utils-ts/utils/fhir-ips-creator-identity';
|
|
5
9
|
import { getHealthcareRoleByClaim } from 'gdc-common-utils-ts/constants/healthcare';
|
|
6
10
|
import { readLegalOrganizationVerificationCredentialPairFromResponseBody, readServiceControllerCredentialFromResponseBody, } from 'gdc-common-utils-ts/utils/legal-organization-verification-result';
|
|
7
11
|
import { addLegalRepresentativeCredential, addOrganizationCredential, addServiceControllerCredential, createVP, } from 'gdc-common-utils-ts/utils/vp-token';
|
|
@@ -15,6 +19,44 @@ import { DigitalTwinSdk } from './orchestration/digital-twin-sdk.js';
|
|
|
15
19
|
import { buildIdentityOpenIdSmartTokenPath } from './runtime-paths.js';
|
|
16
20
|
import { createProfileDeviceActivationRequest } from './device-activation.js';
|
|
17
21
|
import { ProfilePinRejectedError, openServerProfileSecret, protectServerProfileSecret, } from './server-profile-protection.js';
|
|
22
|
+
/**
|
|
23
|
+
* Builds the canonical `urn:uuid` attester reference from a real
|
|
24
|
+
* RelatedPerson/PractitionerRole assignment returned by GW.
|
|
25
|
+
*/
|
|
26
|
+
export function buildProfileAttester(input) {
|
|
27
|
+
const hexadecimal = normalizeUuid(String(input.assignmentIdentifier || '').trim());
|
|
28
|
+
if (!hexadecimal) {
|
|
29
|
+
throw new TypeError('Profile attester assignmentIdentifier must be a UUID returned by RelatedPerson or PractitionerRole data.');
|
|
30
|
+
}
|
|
31
|
+
const uuid = [
|
|
32
|
+
hexadecimal.slice(0, 8),
|
|
33
|
+
hexadecimal.slice(8, 12),
|
|
34
|
+
hexadecimal.slice(12, 16),
|
|
35
|
+
hexadecimal.slice(16, 20),
|
|
36
|
+
hexadecimal.slice(20),
|
|
37
|
+
].join('-');
|
|
38
|
+
return Object.freeze({
|
|
39
|
+
mode: input.mode,
|
|
40
|
+
party: Object.freeze({ reference: `${UrnPrefixes.Uuid}${uuid}` }),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Selects a real active contact/member from a RelatedPerson search response
|
|
45
|
+
* and turns its governed identifier into the personal profile attester.
|
|
46
|
+
*/
|
|
47
|
+
export function buildRelatedPersonProfileAttester(relatedPersonSearchResponseBody, selection) {
|
|
48
|
+
const relationship = selectRelatedPersonListRecord(relatedPersonSearchResponseBody, { ...selection, activeOnly: selection.activeOnly ?? true });
|
|
49
|
+
if (!relationship) {
|
|
50
|
+
throw new Error('No matching active RelatedPerson was returned by the member/contact search.');
|
|
51
|
+
}
|
|
52
|
+
if (!relationship.identifier) {
|
|
53
|
+
throw new Error('The selected RelatedPerson response has no governed assignment identifier.');
|
|
54
|
+
}
|
|
55
|
+
return buildProfileAttester({
|
|
56
|
+
assignmentIdentifier: relationship.identifier,
|
|
57
|
+
mode: CompositionAttesterModes.Personal,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
18
60
|
/**
|
|
19
61
|
* Coordinates device registration, two-factor profile protection and SMART sessions.
|
|
20
62
|
*
|
|
@@ -38,6 +80,14 @@ export class ServerProfileSessionManager {
|
|
|
38
80
|
const normalizedClinicalCreatorBinding = input.clinicalCreatorBinding
|
|
39
81
|
? normalizeClinicalCreatorBinding(input.clinicalCreatorBinding)
|
|
40
82
|
: undefined;
|
|
83
|
+
const attester = input.attester || (normalizedClinicalCreatorBinding
|
|
84
|
+
? buildProfileAttester({
|
|
85
|
+
assignmentIdentifier: normalizedClinicalCreatorBinding.authorIdentifier,
|
|
86
|
+
mode: normalizedClinicalCreatorBinding.kind === FhirIpsCreatorKinds.Professional
|
|
87
|
+
? CompositionAttesterModes.Professional
|
|
88
|
+
: CompositionAttesterModes.Personal,
|
|
89
|
+
})
|
|
90
|
+
: undefined);
|
|
41
91
|
requireEnrollment({
|
|
42
92
|
...input,
|
|
43
93
|
...(normalizedClinicalCreatorBinding
|
|
@@ -130,6 +180,7 @@ export class ServerProfileSessionManager {
|
|
|
130
180
|
allowedSubjectDids: unique(input.allowedSubjectDids),
|
|
131
181
|
clientId,
|
|
132
182
|
clientInstanceId,
|
|
183
|
+
...(attester ? { attester } : {}),
|
|
133
184
|
...(clinicalCreatorBinding ? { clinicalCreatorBinding } : {}),
|
|
134
185
|
deviceDid,
|
|
135
186
|
publicJwks: publicKeys.filter((entry) => entry.purpose !== 'document-at-rest').map((entry) => entry.publicJwk),
|
|
@@ -197,6 +248,7 @@ export class ServerProfileSessionManager {
|
|
|
197
248
|
keyIds: [],
|
|
198
249
|
},
|
|
199
250
|
} : {}),
|
|
251
|
+
...(previous.attester ? { attester: previous.attester } : {}),
|
|
200
252
|
});
|
|
201
253
|
await this.options.store.deleteSessionsForProfile(profile.profileId);
|
|
202
254
|
return profile;
|
|
@@ -486,6 +538,7 @@ export class ServerProfileSessionManager {
|
|
|
486
538
|
subjectDid: session.subjectDid,
|
|
487
539
|
scopes: session.scopes,
|
|
488
540
|
accessToken: await this.options.sealer.unseal(session.sealedAccessToken, `${sessionId}:access-token`),
|
|
541
|
+
...(profile.attester ? { attester: profile.attester } : {}),
|
|
489
542
|
secureTransportAdapter: {
|
|
490
543
|
pack: (message) => wallet.packForRecipientWithContext(bindTransportActor(message, profile.actorDid, profile.clientId), profile.providerDid, { context }),
|
|
491
544
|
unpack: async (jwe) => (await wallet.unpackWithContext(jwe, { context })).content,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gdc-sdk-node-ts",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.10",
|
|
4
4
|
"description": "Next-generation Node runtime package for the GDC SDK family",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Antifraud Services Inc.",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"gdc-common-utils-ts": "2.9.10",
|
|
42
|
-
"gdc-sdk-core-ts": "2.9.
|
|
42
|
+
"gdc-sdk-core-ts": "2.9.8"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/node": "^20.14.10",
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { VerifiableCredentialV2 } from 'gdc-common-utils-ts/models/verifiable-credential';
|
|
2
|
-
import type { IWallet, WalletExecutionContext, WalletKeySelection } from 'gdc-sdk-core-ts';
|
|
3
|
-
/** Input required to add one human-authorizer proof to the out-of-band VC. */
|
|
4
|
-
export type SignOrganizationRegistrationAuthorizationInput = Readonly<{
|
|
5
|
-
credential: VerifiableCredentialV2;
|
|
6
|
-
wallet: IWallet;
|
|
7
|
-
context: WalletExecutionContext;
|
|
8
|
-
key: WalletKeySelection;
|
|
9
|
-
verificationMethod: string;
|
|
10
|
-
createdAt?: string;
|
|
11
|
-
}>;
|
|
12
|
-
/**
|
|
13
|
-
* Adds one detached JWS proof made by the already-unlocked professional
|
|
14
|
-
* profile. The browser never receives the private key or clear wallet seed.
|
|
15
|
-
*/
|
|
16
|
-
export declare function signOrganizationRegistrationAuthorizationCredential(input: SignOrganizationRegistrationAuthorizationInput): Promise<VerifiableCredentialV2>;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { canonicalizeOrganizationRegistrationAuthorizationCredential, } from 'gdc-common-utils-ts/utils/organization-registration-authorization';
|
|
2
|
-
/**
|
|
3
|
-
* Adds one detached JWS proof made by the already-unlocked professional
|
|
4
|
-
* profile. The browser never receives the private key or clear wallet seed.
|
|
5
|
-
*/
|
|
6
|
-
export async function signOrganizationRegistrationAuthorizationCredential(input) {
|
|
7
|
-
if (!input.wallet.signDetachedJws) {
|
|
8
|
-
throw new Error('Wallet does not support detached organization authorization proofs.');
|
|
9
|
-
}
|
|
10
|
-
const verificationMethod = String(input.verificationMethod || '').trim();
|
|
11
|
-
if (!verificationMethod)
|
|
12
|
-
throw new Error('Organization authorization proof requires verificationMethod.');
|
|
13
|
-
const payload = canonicalizeOrganizationRegistrationAuthorizationCredential(input.credential);
|
|
14
|
-
const jws = await input.wallet.signDetachedJws(input.context, {
|
|
15
|
-
payload,
|
|
16
|
-
header: { typ: 'application/vc+ld+json' },
|
|
17
|
-
key: input.key,
|
|
18
|
-
});
|
|
19
|
-
const existingProofs = Array.isArray(input.credential.proof)
|
|
20
|
-
? input.credential.proof
|
|
21
|
-
: input.credential.proof
|
|
22
|
-
? [input.credential.proof]
|
|
23
|
-
: [];
|
|
24
|
-
return {
|
|
25
|
-
...input.credential,
|
|
26
|
-
proof: [...existingProofs, {
|
|
27
|
-
type: 'JsonWebSignature2020',
|
|
28
|
-
created: input.createdAt || new Date().toISOString(),
|
|
29
|
-
proofPurpose: 'contractAgreement',
|
|
30
|
-
verificationMethod,
|
|
31
|
-
jws,
|
|
32
|
-
}],
|
|
33
|
-
};
|
|
34
|
-
}
|