gdc-sdk-node-ts 2.3.18 → 2.3.19
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 +11 -0
- package/dist/gateway-active-consent-provider.d.ts +19 -0
- package/dist/gateway-active-consent-provider.js +70 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/node-runtime-client.d.ts +7 -1
- package/dist/node-runtime-client.js +13 -1
- package/dist/orchestration/client-port.d.ts +2 -1
- package/dist/orchestration/individual-controller-sdk.d.ts +5 -1
- package/dist/orchestration/individual-controller-sdk.js +11 -0
- package/dist/orchestration/personal-sdk.d.ts +5 -1
- package/dist/orchestration/personal-sdk.js +10 -0
- package/dist/orchestration/professional-sdk.d.ts +8 -1
- package/dist/orchestration/professional-sdk.js +12 -0
- package/dist/resource-operations.d.ts +57 -1
- package/dist/resource-operations.js +74 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -406,9 +406,20 @@ data ingestion/search.
|
|
|
406
406
|
- professional access grant
|
|
407
407
|
- invitation / OTP / relationship PIN runtime wiring
|
|
408
408
|
- permission-request `Communication`
|
|
409
|
+
- composed professional request submission and subject decision correlation
|
|
409
410
|
- communication ingestion and search
|
|
410
411
|
- SMART token retrieval
|
|
411
412
|
|
|
413
|
+
`ProfessionalSdk.requestProfessionalAccess(...)` is the bootstrap operation
|
|
414
|
+
for the inverse flow: it persists a subject-scoped permission-request
|
|
415
|
+
`Communication` using the configured HTTP bearer and transport profile, without
|
|
416
|
+
requiring SMART. The subject later answers through
|
|
417
|
+
`respondToProfessionalAccessRequest(...)`; that facade uses the normal Consent
|
|
418
|
+
grant/deny operation and retains the original Communication identifier/thread.
|
|
419
|
+
`listProfessionalAccessRequests(...)` provides the subject/requester inbox view,
|
|
420
|
+
and `GatewayActiveConsentProvider` supplies `evaluateRequestedAccess(...)` from
|
|
421
|
+
the GW Consent source of truth rather than a parallel application table.
|
|
422
|
+
|
|
412
423
|
## Main Flows
|
|
413
424
|
|
|
414
425
|
### 1. Controller invites a related person or professional
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ConsentRule } from 'gdc-common-utils-ts/models/consent-rule';
|
|
2
|
+
import type { ActiveConsentProvider } from 'gdc-sdk-core-ts';
|
|
3
|
+
import type { RouteContext } from './individual-onboarding.js';
|
|
4
|
+
import { type NodeRuntimeClient } from './orchestration/client-port.js';
|
|
5
|
+
/**
|
|
6
|
+
* GW-backed implementation of the runtime-neutral ActiveConsentProvider.
|
|
7
|
+
*
|
|
8
|
+
* The configured client decides HTTP authentication and transport protection.
|
|
9
|
+
* This adapter does not introduce an application-owned Consent table.
|
|
10
|
+
*/
|
|
11
|
+
export declare class GatewayActiveConsentProvider implements ActiveConsentProvider {
|
|
12
|
+
private readonly client;
|
|
13
|
+
private readonly routeContext;
|
|
14
|
+
constructor(client: NodeRuntimeClient, routeContext: RouteContext);
|
|
15
|
+
/** Loads and normalizes the active Consent rules owned by one subject. */
|
|
16
|
+
getActiveConsentsForSubject(subject: string): Promise<ConsentRule[]>;
|
|
17
|
+
}
|
|
18
|
+
/** Extracts canonical Consent claim maps from current GW Bundle wrappers. */
|
|
19
|
+
export declare function extractConsentRules(value: unknown): ConsentRule[];
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
+
import { ResourceTypesFhirR4 } from 'gdc-common-utils-ts/constants/fhir-resource-types';
|
|
3
|
+
import { ClaimConsent } from 'gdc-common-utils-ts/models/consent-rule';
|
|
4
|
+
import { isConsentRuleActive } from 'gdc-common-utils-ts/utils/consent';
|
|
5
|
+
import { requireClientMethod } from './orchestration/client-port.js';
|
|
6
|
+
/**
|
|
7
|
+
* GW-backed implementation of the runtime-neutral ActiveConsentProvider.
|
|
8
|
+
*
|
|
9
|
+
* The configured client decides HTTP authentication and transport protection.
|
|
10
|
+
* This adapter does not introduce an application-owned Consent table.
|
|
11
|
+
*/
|
|
12
|
+
export class GatewayActiveConsentProvider {
|
|
13
|
+
constructor(client, routeContext) {
|
|
14
|
+
this.client = client;
|
|
15
|
+
this.routeContext = routeContext;
|
|
16
|
+
}
|
|
17
|
+
/** Loads and normalizes the active Consent rules owned by one subject. */
|
|
18
|
+
async getActiveConsentsForSubject(subject) {
|
|
19
|
+
const normalizedSubject = String(subject || '').trim();
|
|
20
|
+
if (!normalizedSubject.startsWith('did:')) {
|
|
21
|
+
throw new Error('Active Consent lookup requires a subject DID.');
|
|
22
|
+
}
|
|
23
|
+
const result = await requireClientMethod(this.client, 'searchClinicalBundle')(this.routeContext, {
|
|
24
|
+
subject: normalizedSubject,
|
|
25
|
+
includedTypes: [ResourceTypesFhirR4.Consent],
|
|
26
|
+
});
|
|
27
|
+
return extractConsentRules(result.poll.body)
|
|
28
|
+
.filter((rule) => isConsentRuleActive(rule, { subject: normalizedSubject }));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** Extracts canonical Consent claim maps from current GW Bundle wrappers. */
|
|
32
|
+
export function extractConsentRules(value) {
|
|
33
|
+
const candidates = [];
|
|
34
|
+
const seenObjects = new Set();
|
|
35
|
+
const seenRules = new Set();
|
|
36
|
+
function visit(node) {
|
|
37
|
+
if (!node || typeof node !== 'object')
|
|
38
|
+
return;
|
|
39
|
+
if (seenObjects.has(node))
|
|
40
|
+
return;
|
|
41
|
+
seenObjects.add(node);
|
|
42
|
+
if (Array.isArray(node)) {
|
|
43
|
+
node.forEach(visit);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const record = node;
|
|
47
|
+
const claims = record.claims && typeof record.claims === 'object'
|
|
48
|
+
? record.claims
|
|
49
|
+
: undefined;
|
|
50
|
+
for (const candidate of [record, claims]) {
|
|
51
|
+
if (!candidate || !looksLikeConsentRule(candidate))
|
|
52
|
+
continue;
|
|
53
|
+
const rule = candidate;
|
|
54
|
+
const key = String(rule[ClaimConsent.identifier] || JSON.stringify(rule));
|
|
55
|
+
if (!seenRules.has(key)) {
|
|
56
|
+
seenRules.add(key);
|
|
57
|
+
candidates.push(rule);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
Object.values(record).forEach(visit);
|
|
61
|
+
}
|
|
62
|
+
visit(value);
|
|
63
|
+
return candidates;
|
|
64
|
+
}
|
|
65
|
+
function looksLikeConsentRule(value) {
|
|
66
|
+
return Boolean(String(value[ClaimConsent.subject] || '').trim()
|
|
67
|
+
&& String(value[ClaimConsent.actorIdentifier] || '').trim()
|
|
68
|
+
&& String(value[ClaimConsent.decision] || '').trim()
|
|
69
|
+
&& String(value[ClaimConsent.action] || '').trim());
|
|
70
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -29,6 +29,7 @@ export * from './node-managed-wallet.js';
|
|
|
29
29
|
export * from './did-web-recipient.js';
|
|
30
30
|
export * from './constants/lifecycle.js';
|
|
31
31
|
export * from './consent-claim-helpers.js';
|
|
32
|
+
export * from './gateway-active-consent-provider.js';
|
|
32
33
|
export * from './session.js';
|
|
33
34
|
export * from './node-runtime-client.js';
|
|
34
35
|
export * from './gdc-session-bridge.js';
|
package/dist/index.js
CHANGED
|
@@ -30,6 +30,7 @@ export * from './node-managed-wallet.js';
|
|
|
30
30
|
export * from './did-web-recipient.js';
|
|
31
31
|
export * from './constants/lifecycle.js';
|
|
32
32
|
export * from './consent-claim-helpers.js';
|
|
33
|
+
export * from './gateway-active-consent-provider.js';
|
|
33
34
|
export * from './session.js';
|
|
34
35
|
export * from './node-runtime-client.js';
|
|
35
36
|
export * from './gdc-session-bridge.js';
|
|
@@ -11,7 +11,7 @@ import { type SmartTokenRequestInput } from './smart-token.js';
|
|
|
11
11
|
import { type EmployeeDeviceActivationRequestInput, type EmployeeDeviceActivationResult } from './device-activation.js';
|
|
12
12
|
import { type OrganizationLicenseOrderConfirmInput } from './organization-license-order.js';
|
|
13
13
|
import { type IndividualOrganizationBootstrapInput, type IndividualOrganizationStartResult } from './individual-start.js';
|
|
14
|
-
import { type CommunicationIngestionInput, type BlockchainArtifactRegistrationInput, type VitalSignBatchCommunicationFromSearchResponseInput, type CommunicationParticipantRuntimeSearchInput, type ClinicalBundleSearchInput, type ClinicalSectionUpdateInput, type ClinicalSummaryReadResult, type ClinicalSummaryRequestInput, type ClinicalSummaryUpdateInput, type GrantProfessionalAccessInput, type GrantProfessionalAccessResult, type IndividualMemberLifecycleInput, type IndividualMemberLicenseAddInput, type IndividualMemberLicenseInvitationInput, type IndividualMemberLicenseTransitionInput, type LicenseListRuntimeSearchInput, type LicenseOfferRuntimeSearchInput, type LicenseOrderRuntimeSearchInput, type OrganizationEmployeeCreationInput, type OrganizationEmployeeLifecycleInput, type OrganizationEmployeeSearchInput, type RevokeProfessionalAccessInput, type RevokeProfessionalAccessResult, type RelatedPersonUpsertInput } from './resource-operations.js';
|
|
14
|
+
import { type CommunicationIngestionInput, type BlockchainArtifactRegistrationInput, type VitalSignBatchCommunicationFromSearchResponseInput, type CommunicationParticipantRuntimeSearchInput, type ClinicalBundleSearchInput, type ClinicalSectionUpdateInput, type ClinicalSummaryReadResult, type ClinicalSummaryRequestInput, type ClinicalSummaryUpdateInput, type GrantProfessionalAccessInput, type GrantProfessionalAccessResult, type IndividualMemberLifecycleInput, type IndividualMemberLicenseAddInput, type IndividualMemberLicenseInvitationInput, type IndividualMemberLicenseTransitionInput, type LicenseListRuntimeSearchInput, type LicenseOfferRuntimeSearchInput, type LicenseOrderRuntimeSearchInput, type OrganizationEmployeeCreationInput, type OrganizationEmployeeLifecycleInput, type OrganizationEmployeeSearchInput, type ProfessionalAccessRequestInput, type ProfessionalAccessRequestResult, type RevokeProfessionalAccessInput, type RevokeProfessionalAccessResult, type RelatedPersonUpsertInput } from './resource-operations.js';
|
|
15
15
|
import type { LegalOrganizationOrderInput } from './host-onboarding.js';
|
|
16
16
|
import type { SmartTokenExchangeResult } from './smart-token.js';
|
|
17
17
|
import type { NodeRuntimeClient, PollOptions, PollResult, SubmitAndPollResult, SubmitPayload, SubmitResponse } from './orchestration/client-port.js';
|
|
@@ -409,6 +409,12 @@ export declare class HttpRuntimeClient implements NodeRuntimeClient {
|
|
|
409
409
|
* @param input Communication payload plus route/format options.
|
|
410
410
|
*/
|
|
411
411
|
ingestCommunicationAndUpdateIndex(ctx: RouteContext, input: CommunicationIngestionInput): Promise<SubmitAndPollResult>;
|
|
412
|
+
/**
|
|
413
|
+
* Records a subject-scoped permission-request Communication before SMART
|
|
414
|
+
* authorization exists. The configured bearer authenticates HTTP and the
|
|
415
|
+
* configured secure transport adapter signs/encrypts DIDComm when enabled.
|
|
416
|
+
*/
|
|
417
|
+
requestProfessionalAccess(ctx: RouteContext, input: ProfessionalAccessRequestInput): Promise<ProfessionalAccessRequestResult>;
|
|
412
418
|
/**
|
|
413
419
|
* Updates exactly one clinical section.
|
|
414
420
|
*
|
|
@@ -12,7 +12,7 @@ import { activateEmployeeDeviceWithActivationCodeWithDeps, activateEmployeeDevic
|
|
|
12
12
|
import { extractOfferIdFromResponseBody, extractOfferPreviewFromResponseBody, } from './order-offer-summary.js';
|
|
13
13
|
import { confirmOrganizationLicenseOrderWithDeps } from './organization-license-order.js';
|
|
14
14
|
import { startIndividualOrganizationWithDeps } from './individual-start.js';
|
|
15
|
-
import { createOrganizationEmployeeWithDeps, disableIndividualMemberWithDeps, disableIndividualOrganizationWithDeps, disableOrganizationEmployeeWithDeps, listIndividualLicenseOffersWithDeps, listIndividualLicenseOrdersWithDeps, listIndividualLicensesWithDeps, addFreeIndividualMemberLicensesWithDeps, issueIndividualMemberLicenseWithDeps, transitionIndividualMemberLicenseWithDeps, listOrganizationLicenseOffersWithDeps, listOrganizationLicenseOrdersWithDeps, listOrganizationLicensesWithDeps, grantProfessionalAccessWithDeps, buildClinicalSectionUpdateIngestion, buildClinicalSummaryUpdateIngestion, ingestCommunicationAndUpdateIndexWithDeps, buildVitalSignBatchCommunicationFromSearchResponse, registerBlockchainArtifactAndUpdateIndexWithDeps, requestClinicalSummaryWithDeps, revokeProfessionalAccessWithDeps, searchCommunicationParticipantsWithDeps, purgeIndividualMemberWithDeps, purgeIndividualOrganizationWithDeps, purgeOrganizationEmployeeWithDeps, prepareEmployeeLifecycleMessageForTransport, searchIndividualLicensesWithDeps, searchIndividualLicenseOffersWithDeps, searchIndividualLicenseOrdersWithDeps, searchOrganizationLicensesWithDeps, searchOrganizationLicenseOffersWithDeps, searchOrganizationLicenseOrdersWithDeps, searchOrganizationEmployeesWithDeps, searchClinicalBundleWithDeps, searchLatestIpsWithDeps, upsertRelatedPersonAndPollWithDeps, normalizeCommunicationPathFormatSegment, } from './resource-operations.js';
|
|
15
|
+
import { createOrganizationEmployeeWithDeps, disableIndividualMemberWithDeps, disableIndividualOrganizationWithDeps, disableOrganizationEmployeeWithDeps, listIndividualLicenseOffersWithDeps, listIndividualLicenseOrdersWithDeps, listIndividualLicensesWithDeps, addFreeIndividualMemberLicensesWithDeps, issueIndividualMemberLicenseWithDeps, transitionIndividualMemberLicenseWithDeps, listOrganizationLicenseOffersWithDeps, listOrganizationLicenseOrdersWithDeps, listOrganizationLicensesWithDeps, grantProfessionalAccessWithDeps, buildClinicalSectionUpdateIngestion, buildClinicalSummaryUpdateIngestion, ingestCommunicationAndUpdateIndexWithDeps, requestProfessionalAccessWithDeps, buildVitalSignBatchCommunicationFromSearchResponse, registerBlockchainArtifactAndUpdateIndexWithDeps, requestClinicalSummaryWithDeps, revokeProfessionalAccessWithDeps, searchCommunicationParticipantsWithDeps, purgeIndividualMemberWithDeps, purgeIndividualOrganizationWithDeps, purgeOrganizationEmployeeWithDeps, prepareEmployeeLifecycleMessageForTransport, searchIndividualLicensesWithDeps, searchIndividualLicenseOffersWithDeps, searchIndividualLicenseOrdersWithDeps, searchOrganizationLicensesWithDeps, searchOrganizationLicenseOffersWithDeps, searchOrganizationLicenseOrdersWithDeps, searchOrganizationEmployeesWithDeps, searchClinicalBundleWithDeps, searchLatestIpsWithDeps, upsertRelatedPersonAndPollWithDeps, normalizeCommunicationPathFormatSegment, } from './resource-operations.js';
|
|
16
16
|
import { submitAndPollWithMethods } from './orchestration/client-port.js';
|
|
17
17
|
import { buildRuntimeHeaders, fetchWithTimeout, parseResponseBody, pollBatchResponseWithRuntimeConfig, postJsonWithRuntimeConfig, postRenderedWithRuntimeConfig, } from './runtime-transport.js';
|
|
18
18
|
import { activateOrganizationInGatewayFromIcaProofWithDeps, submitLegalOrganizationIssueWithDeps, submitLegalOrganizationVerificationTransactionWithDeps, submitOrganizationDidBindingWithDeps, } from './runtime-host-submission.js';
|
|
@@ -749,6 +749,18 @@ export class HttpRuntimeClient {
|
|
|
749
749
|
submitAndPoll: this.submitAndPoll.bind(this),
|
|
750
750
|
});
|
|
751
751
|
}
|
|
752
|
+
/**
|
|
753
|
+
* Records a subject-scoped permission-request Communication before SMART
|
|
754
|
+
* authorization exists. The configured bearer authenticates HTTP and the
|
|
755
|
+
* configured secure transport adapter signs/encrypts DIDComm when enabled.
|
|
756
|
+
*/
|
|
757
|
+
async requestProfessionalAccess(ctx, input) {
|
|
758
|
+
return requestProfessionalAccessWithDeps(ctx, input, {
|
|
759
|
+
individualCommunicationBatchPath: this.paths.individualCommunicationBatchPath.bind(this.paths),
|
|
760
|
+
individualCommunicationPollPath: this.paths.individualCommunicationPollPath.bind(this.paths),
|
|
761
|
+
submitAndPoll: (submitPath, pollPath, payload, pollOptions) => this.submitClinicalMessageAndPoll(submitPath, pollPath, payload, input.transportProfile || this.transportProfile, pollOptions),
|
|
762
|
+
});
|
|
763
|
+
}
|
|
752
764
|
/**
|
|
753
765
|
* Updates exactly one clinical section.
|
|
754
766
|
*
|
|
@@ -13,7 +13,7 @@ import type { FamilyOrganizationSearchInput } from '../family-organization-searc
|
|
|
13
13
|
import type { EnsureFamilyOrganizationRegistrationInput, EnsureFamilyOrganizationRegistrationResult } from '../family-organization-registration.js';
|
|
14
14
|
import type { OrganizationLicenseOrderConfirmInput } from '../organization-license-order.js';
|
|
15
15
|
import type { SmartTokenExchangeResult, SmartTokenRequestInput } from '../smart-token.js';
|
|
16
|
-
import type { CommunicationIngestionInput, BlockchainArtifactRegistrationInput, CommunicationParticipantRuntimeSearchInput, ClinicalBundleSearchInput, ClinicalSectionUpdateInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, ClinicalSummaryUpdateInput, VitalSignBatchCommunicationFromSearchResponseInput, DigitalTwinGenerationInput, GrantProfessionalAccessInput, GrantProfessionalAccessResult, IndividualMemberLifecycleInput, IndividualMemberLicenseAddInput, IndividualMemberLicenseInvitationInput, IndividualMemberLicenseTransitionInput, IpsOrFhirImportInput, OrganizationEmployeeCreationInput, OrganizationEmployeeLifecycleInput, OrganizationEmployeeSearchInput, RevokeProfessionalAccessInput, RevokeProfessionalAccessResult, RelatedPersonUpsertInput } from '../resource-operations.js';
|
|
16
|
+
import type { CommunicationIngestionInput, BlockchainArtifactRegistrationInput, CommunicationParticipantRuntimeSearchInput, ClinicalBundleSearchInput, ClinicalSectionUpdateInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, ClinicalSummaryUpdateInput, VitalSignBatchCommunicationFromSearchResponseInput, DigitalTwinGenerationInput, GrantProfessionalAccessInput, GrantProfessionalAccessResult, IndividualMemberLifecycleInput, IndividualMemberLicenseAddInput, IndividualMemberLicenseInvitationInput, IndividualMemberLicenseTransitionInput, IpsOrFhirImportInput, OrganizationEmployeeCreationInput, OrganizationEmployeeLifecycleInput, OrganizationEmployeeSearchInput, ProfessionalAccessRequestInput, ProfessionalAccessRequestResult, RevokeProfessionalAccessInput, RevokeProfessionalAccessResult, RelatedPersonUpsertInput } from '../resource-operations.js';
|
|
17
17
|
/**
|
|
18
18
|
* Shared node-runtime activation input.
|
|
19
19
|
*
|
|
@@ -89,6 +89,7 @@ export type RuntimeClient = {
|
|
|
89
89
|
disableIndividualOrganization?: (ctx: RouteContext, input: IndividualOrganizationLifecycleInput, pollOptions?: PollOptions) => Promise<SubmitAndPollResult>;
|
|
90
90
|
purgeIndividualOrganization?: (ctx: RouteContext, input: IndividualOrganizationLifecycleInput, pollOptions?: PollOptions) => Promise<SubmitAndPollResult>;
|
|
91
91
|
ingestCommunicationAndUpdateIndex?: (ctx: RouteContext, input: CommunicationIngestionInput) => Promise<SubmitAndPollResult>;
|
|
92
|
+
requestProfessionalAccess?: (ctx: RouteContext, input: ProfessionalAccessRequestInput) => Promise<ProfessionalAccessRequestResult>;
|
|
92
93
|
updateClinicalSection?: (ctx: RouteContext, input: ClinicalSectionUpdateInput) => Promise<SubmitAndPollResult>;
|
|
93
94
|
updateClinicalSummary?: (ctx: RouteContext, input: ClinicalSummaryUpdateInput) => Promise<SubmitAndPollResult>;
|
|
94
95
|
requestClinicalSummary?: (ctx: RouteContext, input: ClinicalSummaryRequestInput) => Promise<ClinicalSummaryReadResult>;
|
|
@@ -7,7 +7,7 @@ import type { IndividualOrganizationConfirmOrderInput, RouteContext } from '../i
|
|
|
7
7
|
import type { IndividualOrganizationBootstrapInput, IndividualOrganizationStartResult } 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, GrantProfessionalAccessInput, GrantProfessionalAccessResult, IndividualMemberLifecycleInput, IndividualMemberLicenseAddInput, IndividualMemberLicenseInvitationInput, IndividualMemberLicenseTransitionInput, IpsOrFhirImportInput, LicenseListRuntimeSearchInput, LicenseOfferRuntimeSearchInput, LicenseOrderRuntimeSearchInput, RevokeProfessionalAccessInput, RevokeProfessionalAccessResult, RelatedPersonUpsertInput } from '../resource-operations.js';
|
|
10
|
+
import type { BlockchainArtifactRegistrationInput, ClinicalBundleSearchInput, ClinicalSectionUpdateInput, ClinicalSummaryReadResult, ClinicalSummaryRequestInput, ClinicalSummaryUpdateInput, CommunicationIngestionInput, CommunicationParticipantRuntimeSearchInput, DigitalTwinGenerationInput, 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`.
|
|
@@ -70,6 +70,10 @@ export declare class IndividualControllerSdk {
|
|
|
70
70
|
* Grants access to a professional through a consent flow.
|
|
71
71
|
*/
|
|
72
72
|
grantProfessionalAccess(ctx: RouteContext, input: GrantProfessionalAccessInput): Promise<GrantProfessionalAccessResult>;
|
|
73
|
+
/** Approves or denies a permission request while retaining its correlation. */
|
|
74
|
+
respondToProfessionalAccessRequest(ctx: RouteContext, input: ProfessionalAccessRequestDecisionInput): Promise<GrantProfessionalAccessResult>;
|
|
75
|
+
/** Lists canonical permission requests addressed to this subject. */
|
|
76
|
+
listProfessionalAccessRequests(ctx: RouteContext, input: ProfessionalAccessRequestSearchInput): Promise<SubmitAndPollResult>;
|
|
73
77
|
/**
|
|
74
78
|
* Closes an existing professional consent by setting its period end.
|
|
75
79
|
*/
|
|
@@ -3,6 +3,8 @@ import { ActorCapabilities, ActorKinds } from 'gdc-common-utils-ts/constants/act
|
|
|
3
3
|
import { buildIndividualControllerIdentityVpPayload, buildUnsignedIndividualControllerIdentityVpJwt, getIndividualControllerIdentitySameAs, getIndividualControllerIdentityVC, getIndividualSubjectVC, } from 'gdc-common-utils-ts';
|
|
4
4
|
import { requireClientMethod, submitAndPollWithClient, } from './client-port.js';
|
|
5
5
|
import { assertFacadeCapability } from './capability-guard.js';
|
|
6
|
+
import { buildProfessionalAccessRequestDecisionGrant } from '../resource-operations.js';
|
|
7
|
+
import { buildProfessionalAccessRequestSearchInput } from '../resource-operations.js';
|
|
6
8
|
/**
|
|
7
9
|
* Individual-controller oriented facade over a `NodeRuntimeClient`.
|
|
8
10
|
*
|
|
@@ -96,6 +98,15 @@ export class IndividualControllerSdk {
|
|
|
96
98
|
assertFacadeCapability(this.capabilities, ActorCapabilities.ConsentGrantProfessionalAccess, ActorKinds.IndividualController, 'grantProfessionalAccess');
|
|
97
99
|
return requireClientMethod(this.client, 'grantProfessionalAccess')(ctx, input);
|
|
98
100
|
}
|
|
101
|
+
/** Approves or denies a permission request while retaining its correlation. */
|
|
102
|
+
respondToProfessionalAccessRequest(ctx, input) {
|
|
103
|
+
assertFacadeCapability(this.capabilities, ActorCapabilities.ConsentGrantProfessionalAccess, ActorKinds.IndividualController, 'respondToProfessionalAccessRequest');
|
|
104
|
+
return requireClientMethod(this.client, 'grantProfessionalAccess')(ctx, buildProfessionalAccessRequestDecisionGrant(input));
|
|
105
|
+
}
|
|
106
|
+
/** Lists canonical permission requests addressed to this subject. */
|
|
107
|
+
listProfessionalAccessRequests(ctx, input) {
|
|
108
|
+
return requireClientMethod(this.client, 'searchCommunicationParticipants')(ctx, buildProfessionalAccessRequestSearchInput(input));
|
|
109
|
+
}
|
|
99
110
|
/**
|
|
100
111
|
* Closes an existing professional consent by setting its period end.
|
|
101
112
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type NodeRuntimeClient, type PollOptions, type SubmitAndPollResult, type SubmitPayload } from './client-port.js';
|
|
2
2
|
import type { IndividualOrganizationBootstrapInput, IndividualOrganizationStartResult } 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, IpsOrFhirImportInput, LicenseListRuntimeSearchInput, LicenseOfferRuntimeSearchInput, LicenseOrderRuntimeSearchInput } from '../resource-operations.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';
|
|
5
5
|
import type { SmartTokenExchangeResult, SmartTokenRequestInput } from '../smart-token.js';
|
|
6
6
|
export declare class PersonalSdk {
|
|
7
7
|
private readonly client;
|
|
@@ -10,6 +10,10 @@ export declare class PersonalSdk {
|
|
|
10
10
|
startIndividualOrganization(input: IndividualOrganizationBootstrapInput): Promise<IndividualOrganizationStartResult>;
|
|
11
11
|
/** Grants professional access via Consent for a subject. */
|
|
12
12
|
grantProfessionalAccess(ctx: RouteContext, input: GrantProfessionalAccessInput): Promise<GrantProfessionalAccessResult>;
|
|
13
|
+
/** Approves or denies a permission request while retaining its correlation. */
|
|
14
|
+
respondToProfessionalAccessRequest(ctx: RouteContext, input: ProfessionalAccessRequestDecisionInput): Promise<GrantProfessionalAccessResult>;
|
|
15
|
+
/** Lists canonical permission requests addressed to this subject. */
|
|
16
|
+
listProfessionalAccessRequests(ctx: RouteContext, input: ProfessionalAccessRequestSearchInput): Promise<SubmitAndPollResult>;
|
|
13
17
|
/** Imports IPS/FHIR payload and updates document index projections. */
|
|
14
18
|
importIpsOrFhirAndUpdateIndex(ctx: RouteContext, input: IpsOrFhirImportInput): Promise<SubmitAndPollResult>;
|
|
15
19
|
/** Ingests canonical Communication and waits for projection completion. */
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
2
|
import { requireClientMethod, submitAndPollWithClient, } from './client-port.js';
|
|
3
|
+
import { buildProfessionalAccessRequestDecisionGrant } from '../resource-operations.js';
|
|
4
|
+
import { buildProfessionalAccessRequestSearchInput } from '../resource-operations.js';
|
|
3
5
|
export class PersonalSdk {
|
|
4
6
|
constructor(client) {
|
|
5
7
|
this.client = client;
|
|
@@ -12,6 +14,14 @@ export class PersonalSdk {
|
|
|
12
14
|
grantProfessionalAccess(ctx, input) {
|
|
13
15
|
return requireClientMethod(this.client, 'grantProfessionalAccess')(ctx, input);
|
|
14
16
|
}
|
|
17
|
+
/** Approves or denies a permission request while retaining its correlation. */
|
|
18
|
+
respondToProfessionalAccessRequest(ctx, input) {
|
|
19
|
+
return requireClientMethod(this.client, 'grantProfessionalAccess')(ctx, buildProfessionalAccessRequestDecisionGrant(input));
|
|
20
|
+
}
|
|
21
|
+
/** Lists canonical permission requests addressed to this subject. */
|
|
22
|
+
listProfessionalAccessRequests(ctx, input) {
|
|
23
|
+
return requireClientMethod(this.client, 'searchCommunicationParticipants')(ctx, buildProfessionalAccessRequestSearchInput(input));
|
|
24
|
+
}
|
|
15
25
|
/** Imports IPS/FHIR payload and updates document index projections. */
|
|
16
26
|
importIpsOrFhirAndUpdateIndex(ctx, input) {
|
|
17
27
|
return requireClientMethod(this.client, 'importIpsOrFhirAndUpdateIndex')(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, VitalSignBatchCommunicationFromSearchResponseInput } from '../resource-operations.js';
|
|
5
|
+
import type { BlockchainArtifactRegistrationInput, CommunicationIngestionInput, CommunicationParticipantRuntimeSearchInput, ClinicalBundleSearchInput, ClinicalSectionUpdateInput, 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
|
|
@@ -75,6 +75,13 @@ export declare class ProfessionalSdk {
|
|
|
75
75
|
* Ingests a FHIR `Communication` and waits for indexing.
|
|
76
76
|
*/
|
|
77
77
|
ingestCommunicationAndUpdateIndex(ctx: RouteContext, input: CommunicationIngestionInput): Promise<SubmitAndPollResult>;
|
|
78
|
+
/**
|
|
79
|
+
* Requests subject-controlled access without requiring a SMART token. The
|
|
80
|
+
* runtime persists one canonical permission-request Communication.
|
|
81
|
+
*/
|
|
82
|
+
requestProfessionalAccess(ctx: RouteContext, input: ProfessionalAccessRequestInput): Promise<ProfessionalAccessRequestResult>;
|
|
83
|
+
/** Lists permission requests sent by or involving this professional. */
|
|
84
|
+
listProfessionalAccessRequests(ctx: RouteContext, input: ProfessionalAccessRequestSearchInput): Promise<SubmitAndPollResult>;
|
|
78
85
|
/** Updates one consent-authorized clinical section through a scoped batch/collection. */
|
|
79
86
|
updateClinicalSection(ctx: RouteContext, input: ClinicalSectionUpdateInput): Promise<SubmitAndPollResult>;
|
|
80
87
|
/** Updates a consent-authorized multi-section summary document. */
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Always create JSDoc, do not use strings inline in keys nor values, use types instead, and reuse the data test examples.
|
|
3
3
|
import { buildProfessionalIdentityVpPayload, buildUnsignedProfessionalIdentityVpJwt, getProfessionalIdentitySameAs, getProfessionalIdentityVC, } from 'gdc-common-utils-ts';
|
|
4
4
|
import { requireClientMethod, submitAndPollWithClient, } from './client-port.js';
|
|
5
|
+
import { buildProfessionalAccessRequestSearchInput } from '../resource-operations.js';
|
|
5
6
|
/**
|
|
6
7
|
* Professional-oriented facade for runtime actions that belong to the
|
|
7
8
|
* professional actor itself after tenant and employee provisioning have already
|
|
@@ -89,6 +90,17 @@ export class ProfessionalSdk {
|
|
|
89
90
|
ingestCommunicationAndUpdateIndex(ctx, input) {
|
|
90
91
|
return requireClientMethod(this.client, 'ingestCommunicationAndUpdateIndex')(ctx, input);
|
|
91
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Requests subject-controlled access without requiring a SMART token. The
|
|
95
|
+
* runtime persists one canonical permission-request Communication.
|
|
96
|
+
*/
|
|
97
|
+
requestProfessionalAccess(ctx, input) {
|
|
98
|
+
return requireClientMethod(this.client, 'requestProfessionalAccess')(ctx, input);
|
|
99
|
+
}
|
|
100
|
+
/** Lists permission requests sent by or involving this professional. */
|
|
101
|
+
listProfessionalAccessRequests(ctx, input) {
|
|
102
|
+
return requireClientMethod(this.client, 'searchCommunicationParticipants')(ctx, buildProfessionalAccessRequestSearchInput(input));
|
|
103
|
+
}
|
|
92
104
|
/** Updates one consent-authorized clinical section through a scoped batch/collection. */
|
|
93
105
|
updateClinicalSection(ctx, input) {
|
|
94
106
|
return requireClientMethod(this.client, 'updateClinicalSection')(ctx, input);
|
|
@@ -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 } from 'gdc-sdk-core-ts';
|
|
2
|
+
import { type ClinicalSectionUpdateCommunicationInput, 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';
|
|
@@ -232,6 +232,32 @@ export type CommunicationIngestionInput = {
|
|
|
232
232
|
intervalMs?: number;
|
|
233
233
|
};
|
|
234
234
|
};
|
|
235
|
+
/**
|
|
236
|
+
* Canonical professional-to-subject permission request.
|
|
237
|
+
*
|
|
238
|
+
* This operation records a `Communication`; it never creates Consent or
|
|
239
|
+
* requires a SMART token. HTTP authentication and optional secure DIDComm
|
|
240
|
+
* transport remain concerns of the configured runtime client.
|
|
241
|
+
*/
|
|
242
|
+
export type ProfessionalAccessRequestInput = Omit<PermissionRequestCommunicationInput, 'missing'> & Readonly<{
|
|
243
|
+
missing: Readonly<{
|
|
244
|
+
sections: string[];
|
|
245
|
+
resourceTypes: string[];
|
|
246
|
+
pairs?: PermissionRequestCommunicationInput['missing']['pairs'];
|
|
247
|
+
}>;
|
|
248
|
+
transportProfile?: TransportProfile;
|
|
249
|
+
pollOptions?: {
|
|
250
|
+
timeoutMs?: number;
|
|
251
|
+
intervalMs?: number;
|
|
252
|
+
};
|
|
253
|
+
}>;
|
|
254
|
+
/** Result of persisting one canonical permission-request Communication. */
|
|
255
|
+
export type ProfessionalAccessRequestResult = Readonly<{
|
|
256
|
+
thid: string;
|
|
257
|
+
communicationIdentifier: string;
|
|
258
|
+
communication: CommunicationInput;
|
|
259
|
+
delivery: SubmitAndPollResult;
|
|
260
|
+
}>;
|
|
235
261
|
type ClinicalUpdateRuntimeOptions = Readonly<{
|
|
236
262
|
transportProfile?: TransportProfile;
|
|
237
263
|
clinicalFormat?: string;
|
|
@@ -326,6 +352,10 @@ export type CommunicationParticipantRuntimeSearchInput = {
|
|
|
326
352
|
page?: number;
|
|
327
353
|
count?: number;
|
|
328
354
|
};
|
|
355
|
+
/** Subject/requester filters for canonical permission-request Communications. */
|
|
356
|
+
export type ProfessionalAccessRequestSearchInput = CommunicationParticipantRuntimeSearchInput;
|
|
357
|
+
/** Restricts a Communication participant search to permission requests. */
|
|
358
|
+
export declare function buildProfessionalAccessRequestSearchInput(input: ProfessionalAccessRequestSearchInput): CommunicationParticipantRuntimeSearchInput;
|
|
329
359
|
export type ClinicalDateRange = DateRange;
|
|
330
360
|
export type ClinicalBundleSearchInput = Omit<BundleSearchQuery, 'section' | 'searchParams'> & {
|
|
331
361
|
section?: string | string[];
|
|
@@ -390,6 +420,10 @@ export type GrantProfessionalAccessInput = {
|
|
|
390
420
|
consentIdentifier?: string;
|
|
391
421
|
consentDate?: string;
|
|
392
422
|
decision?: 'permit' | 'deny';
|
|
423
|
+
/** Permission-request Communication identifier or thread being answered. */
|
|
424
|
+
eventBasedOn?: string;
|
|
425
|
+
/** Canonical permission-request Communication reference. */
|
|
426
|
+
sourceReference?: string;
|
|
393
427
|
attachmentContentType?: string;
|
|
394
428
|
attachmentBase64?: string;
|
|
395
429
|
dataType?: string;
|
|
@@ -406,6 +440,13 @@ export type GrantProfessionalAccessResult = {
|
|
|
406
440
|
consentClaims: Record<string, unknown>;
|
|
407
441
|
claimsCid?: string;
|
|
408
442
|
};
|
|
443
|
+
/** Subject decision that remains correlated to the originating request. */
|
|
444
|
+
export type ProfessionalAccessRequestDecisionInput = Omit<GrantProfessionalAccessInput, 'eventBasedOn' | 'sourceReference'> & Readonly<{
|
|
445
|
+
requestThid: string;
|
|
446
|
+
requestCommunicationIdentifier?: string;
|
|
447
|
+
}>;
|
|
448
|
+
/** Converts one request decision into the canonical correlated Consent grant. */
|
|
449
|
+
export declare function buildProfessionalAccessRequestDecisionGrant(input: ProfessionalAccessRequestDecisionInput): GrantProfessionalAccessInput;
|
|
409
450
|
export type RevokeProfessionalAccessInput = {
|
|
410
451
|
consentClaims: Record<string, unknown>;
|
|
411
452
|
periodEnd?: string;
|
|
@@ -685,6 +726,21 @@ export declare function ingestCommunicationAndUpdateIndexWithDeps(routeCtx: Rout
|
|
|
685
726
|
intervalMs?: number;
|
|
686
727
|
}) => Promise<SubmitAndPollResult>;
|
|
687
728
|
}): Promise<SubmitAndPollResult>;
|
|
729
|
+
/**
|
|
730
|
+
* Builds and persists one professional access request against the subject's
|
|
731
|
+
* provider route. The request is deliberately independent from SMART because
|
|
732
|
+
* no subject consent exists yet.
|
|
733
|
+
*/
|
|
734
|
+
export declare function requestProfessionalAccessWithDeps(routeCtx: RouteContext, input: ProfessionalAccessRequestInput, deps: {
|
|
735
|
+
individualCommunicationBatchPath: (ctx: RouteContext, pathFormatSegment: string) => string;
|
|
736
|
+
individualCommunicationPollPath: (ctx: RouteContext, pathFormatSegment: string) => string;
|
|
737
|
+
submitAndPoll: (submitPath: string, pollPath: string, payload: {
|
|
738
|
+
thid?: string;
|
|
739
|
+
} & Record<string, unknown>, pollOptions?: {
|
|
740
|
+
timeoutMs?: number;
|
|
741
|
+
intervalMs?: number;
|
|
742
|
+
}) => Promise<SubmitAndPollResult>;
|
|
743
|
+
}): Promise<ProfessionalAccessRequestResult>;
|
|
688
744
|
export declare function searchCommunicationParticipantsWithDeps(routeCtx: RouteContext, input: CommunicationParticipantRuntimeSearchInput, deps: {
|
|
689
745
|
communicationSearchPath: (ctx: RouteContext) => string;
|
|
690
746
|
communicationSearchPollPath: (ctx: RouteContext) => string;
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
import { HealthcareBasicSections, ResourceTypesFhirR4 } from 'gdc-common-utils-ts/constants';
|
|
3
3
|
import { Format } from 'gdc-common-utils-ts/constants/Schemas';
|
|
4
4
|
import { RelatedPersonClaim } from 'gdc-common-utils-ts/models/interoperable-claims/related-person-claims';
|
|
5
|
+
import { CommunicationClaim } from 'gdc-common-utils-ts/models/interoperable-claims/communication-claims';
|
|
5
6
|
import { BundleEditor, buildCommunicationParticipantSearchBundle, buildBlockchainArtifactDocumentReference, BundleQuery, createInteroperableResourceOperationEditor, IndividualOrganizationLifecycleEditor, LicenseOfferSearchEditor, LicenseOrderSearchEditor, InteroperableLifecycleStatuses, LicenseListSearchEditor, buildLicenseIssueEntry, buildLicensePurchaseEntry, } from 'gdc-common-utils-ts';
|
|
6
7
|
import { EmployeeBundleOperations, EmployeeResourceTypes, } from 'gdc-common-utils-ts/utils/employee';
|
|
7
|
-
import { addFhirResourceToCommunication, createCommunicationResource, buildClinicalSummaryCommunicationJob, createClinicalSectionUpdateOutboxJob, createClinicalSummaryUpdateOutboxJob, readClinicalSummaryOperationResult, TransportProfiles, } from 'gdc-sdk-core-ts';
|
|
8
|
+
import { addFhirResourceToCommunication, createCommunicationResource, buildClinicalSummaryCommunicationJob, buildPermissionRequestCommunication, createClinicalSectionUpdateOutboxJob, createClinicalSummaryUpdateOutboxJob, readClinicalSummaryOperationResult, TransportProfiles, } from 'gdc-sdk-core-ts';
|
|
8
9
|
import { GwCoreLifecycleRequestMethod, GwCoreLifecycleRequestType, GwCoreLifecycleTodo, } from './constants/lifecycle.js';
|
|
9
10
|
import { buildEmployeeSearchBundle, ConsentClaims, } from 'gdc-sdk-core-ts';
|
|
10
11
|
export function buildClinicalSectionUpdateIngestion(input) {
|
|
@@ -23,6 +24,30 @@ export function buildClinicalSummaryUpdateIngestion(input) {
|
|
|
23
24
|
pollOptions: input.pollOptions,
|
|
24
25
|
};
|
|
25
26
|
}
|
|
27
|
+
/** Restricts a Communication participant search to permission requests. */
|
|
28
|
+
export function buildProfessionalAccessRequestSearchInput(input) {
|
|
29
|
+
return {
|
|
30
|
+
...input,
|
|
31
|
+
searchParams: {
|
|
32
|
+
...input.searchParams,
|
|
33
|
+
[CommunicationClaim.Category]: 'permission-request',
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/** Converts one request decision into the canonical correlated Consent grant. */
|
|
38
|
+
export function buildProfessionalAccessRequestDecisionGrant(input) {
|
|
39
|
+
const requestThid = String(input.requestThid || '').trim();
|
|
40
|
+
if (!requestThid)
|
|
41
|
+
throw new Error('Permission request decision requires requestThid.');
|
|
42
|
+
const communicationIdentifier = String(input.requestCommunicationIdentifier || '').trim();
|
|
43
|
+
return {
|
|
44
|
+
...input,
|
|
45
|
+
eventBasedOn: communicationIdentifier || requestThid,
|
|
46
|
+
sourceReference: communicationIdentifier
|
|
47
|
+
? `Communication?identifier=${encodeURIComponent(communicationIdentifier)}`
|
|
48
|
+
: `Communication?thid=${encodeURIComponent(requestThid)}`,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
26
51
|
export async function createOrganizationEmployeeWithDeps(routeCtx, input, options, deps) {
|
|
27
52
|
const payload = buildEmployeeLifecyclePayload({
|
|
28
53
|
routeCtx,
|
|
@@ -388,6 +413,52 @@ export async function ingestCommunicationAndUpdateIndexWithDeps(routeCtx, input,
|
|
|
388
413
|
: payload;
|
|
389
414
|
return deps.submitAndPoll(deps.individualCommunicationBatchPath(routeCtx, pathFormatSegment), deps.individualCommunicationPollPath(routeCtx, pathFormatSegment), convertedPayload, input.pollOptions);
|
|
390
415
|
}
|
|
416
|
+
/**
|
|
417
|
+
* Builds and persists one professional access request against the subject's
|
|
418
|
+
* provider route. The request is deliberately independent from SMART because
|
|
419
|
+
* no subject consent exists yet.
|
|
420
|
+
*/
|
|
421
|
+
export async function requestProfessionalAccessWithDeps(routeCtx, input, deps) {
|
|
422
|
+
const subject = String(input.subject || '').trim();
|
|
423
|
+
const missingSections = input.missing.sections.map((value) => String(value || '').trim()).filter(Boolean);
|
|
424
|
+
const missingResourceTypes = input.missing.resourceTypes.map((value) => String(value || '').trim()).filter(Boolean);
|
|
425
|
+
const requesterTargets = [
|
|
426
|
+
input.requester.did,
|
|
427
|
+
input.requester.email,
|
|
428
|
+
input.requester.phone,
|
|
429
|
+
input.requester.organizationDid,
|
|
430
|
+
].map((value) => String(value || '').trim()).filter(Boolean);
|
|
431
|
+
if (!subject.startsWith('did:'))
|
|
432
|
+
throw new Error('Professional access request requires a subject DID.');
|
|
433
|
+
if (requesterTargets.length === 0)
|
|
434
|
+
throw new Error('Professional access request requires an authenticated requester target.');
|
|
435
|
+
if (missingSections.length === 0 && missingResourceTypes.length === 0) {
|
|
436
|
+
throw new Error('Professional access request requires at least one missing permission.');
|
|
437
|
+
}
|
|
438
|
+
const thid = String(input.thid || '').trim() || `permission-request-${createRuntimeUuid()}`;
|
|
439
|
+
const communicationIdentifier = String(input.communicationIdentifier || '').trim()
|
|
440
|
+
|| `urn:uuid:${createRuntimeUuid()}`;
|
|
441
|
+
const communication = buildPermissionRequestCommunication({
|
|
442
|
+
...input,
|
|
443
|
+
subject,
|
|
444
|
+
thid,
|
|
445
|
+
communicationIdentifier,
|
|
446
|
+
missing: {
|
|
447
|
+
sections: missingSections,
|
|
448
|
+
resourceTypes: missingResourceTypes,
|
|
449
|
+
pairs: input.missing.pairs || [
|
|
450
|
+
...missingSections.map((section) => ({ section, reason: 'missing-consent' })),
|
|
451
|
+
...missingResourceTypes.map((resourceType) => ({ resourceType, reason: 'missing-consent' })),
|
|
452
|
+
],
|
|
453
|
+
},
|
|
454
|
+
});
|
|
455
|
+
const delivery = await ingestCommunicationAndUpdateIndexWithDeps(routeCtx, {
|
|
456
|
+
communicationPayload: communication,
|
|
457
|
+
pathFormatSegment: 'r4',
|
|
458
|
+
pollOptions: input.pollOptions,
|
|
459
|
+
}, deps);
|
|
460
|
+
return { thid, communicationIdentifier, communication, delivery };
|
|
461
|
+
}
|
|
391
462
|
export async function searchCommunicationParticipantsWithDeps(routeCtx, input, deps) {
|
|
392
463
|
const payload = {
|
|
393
464
|
thid: input.requestThid || `communication-search-${createRuntimeUuid()}`,
|
|
@@ -641,6 +712,8 @@ export async function grantProfessionalAccessWithDeps(routeCtx, input, deps) {
|
|
|
641
712
|
consentIdentifier: input.consentIdentifier,
|
|
642
713
|
consentDate: input.consentDate,
|
|
643
714
|
decision: input.decision,
|
|
715
|
+
eventBasedOn: input.eventBasedOn,
|
|
716
|
+
sourceReference: input.sourceReference,
|
|
644
717
|
attachmentContentType: input.attachmentContentType,
|
|
645
718
|
attachmentBase64: input.attachmentBase64,
|
|
646
719
|
}, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gdc-sdk-node-ts",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.19",
|
|
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.",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"test:e2e:live-gw:clean": "bash ./scripts/run-live-gw-clean.sh"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"gdc-common-utils-ts": "^2.3.
|
|
40
|
+
"gdc-common-utils-ts": "^2.3.21",
|
|
41
41
|
"gdc-sdk-core-ts": "~2.3.14"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|