gdc-sdk-node-ts 0.12.0 → 2.0.4
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 +118 -12
- package/dist/backend-profile-runtime.d.ts +262 -0
- package/dist/backend-profile-runtime.js +498 -0
- package/dist/consent-claim-helpers.d.ts +2 -1
- package/dist/family-organization-registration.d.ts +40 -0
- package/dist/family-organization-registration.js +54 -0
- package/dist/family-organization-search.d.ts +30 -0
- package/dist/family-organization-search.js +59 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/dist/individual-controller-backend-runtime.d.ts +59 -0
- package/dist/individual-controller-backend-runtime.js +67 -0
- package/dist/legal-organization-onboarding-facade.d.ts +70 -0
- package/dist/legal-organization-onboarding-facade.js +169 -0
- package/dist/node-runtime-client.d.ts +98 -2
- package/dist/node-runtime-client.js +178 -6
- package/dist/orchestration/client-port.d.ts +31 -1
- package/dist/orchestration/individual-controller-sdk.d.ts +23 -1
- package/dist/orchestration/individual-controller-sdk.js +28 -0
- package/dist/orchestration/organization-controller-sdk.d.ts +22 -1
- package/dist/orchestration/organization-controller-sdk.js +25 -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 +16 -1
- package/dist/orchestration/professional-sdk.js +21 -0
- package/dist/organization-controller-backend-runtime.d.ts +65 -0
- package/dist/organization-controller-backend-runtime.js +83 -0
- package/dist/professional-backend-runtime.d.ts +36 -0
- package/dist/professional-backend-runtime.js +41 -0
- package/dist/profile-workspace.d.ts +82 -0
- package/dist/profile-workspace.js +127 -0
- package/dist/resource-operations.d.ts +79 -5
- package/dist/resource-operations.js +50 -5
- package/package.json +8 -3
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { SubmitAndPollResult } from 'gdc-sdk-core-ts';
|
|
2
|
+
import type { ProfileLoadRequest } from 'gdc-sdk-core-ts';
|
|
3
|
+
import type { LicenseListRuntimeSearchInput, LicenseOfferRuntimeSearchInput, LicenseOrderRuntimeSearchInput, OrganizationEmployeeCreationInput, OrganizationEmployeeLifecycleInput, OrganizationEmployeeSearchInput } from './resource-operations.js';
|
|
4
|
+
import type { HostRouteContext, HostedTenantLifecycleInput } from './host-onboarding.js';
|
|
5
|
+
import type { OrganizationLicenseOrderConfirmInput } from './organization-license-order.js';
|
|
6
|
+
import type { RouteContext } from './individual-onboarding.js';
|
|
7
|
+
import { type BackendOrganizationControllerProfile, type BackendProfileRuntimeClient } from './backend-profile-runtime.js';
|
|
8
|
+
/**
|
|
9
|
+
* Backend use-case facade for the organization-controller happy path.
|
|
10
|
+
*
|
|
11
|
+
* This wrapper keeps the step-by-step tutorial surface high-level for:
|
|
12
|
+
* - license seat discovery
|
|
13
|
+
* - employee provisioning and lifecycle
|
|
14
|
+
* - tenant disable/purge cleanup
|
|
15
|
+
*/
|
|
16
|
+
export declare class OrganizationControllerBackendRuntime {
|
|
17
|
+
private readonly profileRuntime;
|
|
18
|
+
constructor(profileRuntime: BackendProfileRuntimeClient);
|
|
19
|
+
/**
|
|
20
|
+
* Loads one organization-controller backend profile and materializes its
|
|
21
|
+
* actor facade in one step.
|
|
22
|
+
*/
|
|
23
|
+
loadProfile(input: ProfileLoadRequest): Promise<BackendOrganizationControllerProfile>;
|
|
24
|
+
/**
|
|
25
|
+
* Lists organization-owned license seats.
|
|
26
|
+
*/
|
|
27
|
+
listLicenses(profile: BackendOrganizationControllerProfile, ctx: RouteContext, input?: LicenseListRuntimeSearchInput): Promise<SubmitAndPollResult>;
|
|
28
|
+
/**
|
|
29
|
+
* Lists commercial offers available to contract more seats.
|
|
30
|
+
*/
|
|
31
|
+
listLicenseOffers(profile: BackendOrganizationControllerProfile, ctx: RouteContext, input?: LicenseOfferRuntimeSearchInput): Promise<SubmitAndPollResult>;
|
|
32
|
+
/**
|
|
33
|
+
* Lists already-created commercial orders.
|
|
34
|
+
*/
|
|
35
|
+
listLicenseOrders(profile: BackendOrganizationControllerProfile, ctx: RouteContext, input?: LicenseOrderRuntimeSearchInput): Promise<SubmitAndPollResult>;
|
|
36
|
+
/**
|
|
37
|
+
* Confirms one already-paid organization order so additional seats become
|
|
38
|
+
* usable by employees.
|
|
39
|
+
*/
|
|
40
|
+
confirmOrganizationLicenseOrder(profile: BackendOrganizationControllerProfile, ctx: RouteContext, input: OrganizationLicenseOrderConfirmInput): Promise<SubmitAndPollResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Creates one employee under the current tenant.
|
|
43
|
+
*/
|
|
44
|
+
createEmployee(profile: BackendOrganizationControllerProfile, ctx: RouteContext, input: OrganizationEmployeeCreationInput): Promise<SubmitAndPollResult>;
|
|
45
|
+
/**
|
|
46
|
+
* Lists/searches employees under the current tenant.
|
|
47
|
+
*/
|
|
48
|
+
searchEmployees(profile: BackendOrganizationControllerProfile, ctx: RouteContext, input: OrganizationEmployeeSearchInput): Promise<SubmitAndPollResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Disables one employee without purging it yet.
|
|
51
|
+
*/
|
|
52
|
+
disableEmployee(profile: BackendOrganizationControllerProfile, ctx: RouteContext, input: OrganizationEmployeeLifecycleInput): Promise<SubmitAndPollResult>;
|
|
53
|
+
/**
|
|
54
|
+
* Purges one already-disabled employee.
|
|
55
|
+
*/
|
|
56
|
+
purgeEmployee(profile: BackendOrganizationControllerProfile, ctx: RouteContext, input: OrganizationEmployeeLifecycleInput): Promise<SubmitAndPollResult>;
|
|
57
|
+
/**
|
|
58
|
+
* Disables the tenant after dependent actors have been disabled.
|
|
59
|
+
*/
|
|
60
|
+
disableTenant(profile: BackendOrganizationControllerProfile, hostCtx: HostRouteContext, input: HostedTenantLifecycleInput): Promise<SubmitAndPollResult>;
|
|
61
|
+
/**
|
|
62
|
+
* Purges the tenant after employee and individual cleanup.
|
|
63
|
+
*/
|
|
64
|
+
purgeTenant(profile: BackendOrganizationControllerProfile, hostCtx: HostRouteContext, input: HostedTenantLifecycleInput): Promise<SubmitAndPollResult>;
|
|
65
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
+
import { loadBackendOrganizationControllerProfile, } from './backend-profile-runtime.js';
|
|
3
|
+
/**
|
|
4
|
+
* Backend use-case facade for the organization-controller happy path.
|
|
5
|
+
*
|
|
6
|
+
* This wrapper keeps the step-by-step tutorial surface high-level for:
|
|
7
|
+
* - license seat discovery
|
|
8
|
+
* - employee provisioning and lifecycle
|
|
9
|
+
* - tenant disable/purge cleanup
|
|
10
|
+
*/
|
|
11
|
+
export class OrganizationControllerBackendRuntime {
|
|
12
|
+
constructor(profileRuntime) {
|
|
13
|
+
this.profileRuntime = profileRuntime;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Loads one organization-controller backend profile and materializes its
|
|
17
|
+
* actor facade in one step.
|
|
18
|
+
*/
|
|
19
|
+
loadProfile(input) {
|
|
20
|
+
return loadBackendOrganizationControllerProfile(this.profileRuntime, input);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Lists organization-owned license seats.
|
|
24
|
+
*/
|
|
25
|
+
listLicenses(profile, ctx, input = {}) {
|
|
26
|
+
return profile.sdk.listLicenses(ctx, input);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Lists commercial offers available to contract more seats.
|
|
30
|
+
*/
|
|
31
|
+
listLicenseOffers(profile, ctx, input = {}) {
|
|
32
|
+
return profile.sdk.listLicenseOffers(ctx, input);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Lists already-created commercial orders.
|
|
36
|
+
*/
|
|
37
|
+
listLicenseOrders(profile, ctx, input = {}) {
|
|
38
|
+
return profile.sdk.listLicenseOrders(ctx, input);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Confirms one already-paid organization order so additional seats become
|
|
42
|
+
* usable by employees.
|
|
43
|
+
*/
|
|
44
|
+
confirmOrganizationLicenseOrder(profile, ctx, input) {
|
|
45
|
+
return profile.sdk.confirmOrganizationLicenseOrder(ctx, input);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Creates one employee under the current tenant.
|
|
49
|
+
*/
|
|
50
|
+
createEmployee(profile, ctx, input) {
|
|
51
|
+
return profile.sdk.createOrganizationEmployee(ctx, input);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Lists/searches employees under the current tenant.
|
|
55
|
+
*/
|
|
56
|
+
searchEmployees(profile, ctx, input) {
|
|
57
|
+
return profile.sdk.searchOrganizationEmployees(ctx, input);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Disables one employee without purging it yet.
|
|
61
|
+
*/
|
|
62
|
+
disableEmployee(profile, ctx, input) {
|
|
63
|
+
return profile.sdk.disableEmployee(ctx, input);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Purges one already-disabled employee.
|
|
67
|
+
*/
|
|
68
|
+
purgeEmployee(profile, ctx, input) {
|
|
69
|
+
return profile.sdk.purgeEmployee(ctx, input);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Disables the tenant after dependent actors have been disabled.
|
|
73
|
+
*/
|
|
74
|
+
disableTenant(profile, hostCtx, input) {
|
|
75
|
+
return profile.sdk.disableTenant(hostCtx, input);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Purges the tenant after employee and individual cleanup.
|
|
79
|
+
*/
|
|
80
|
+
purgeTenant(profile, hostCtx, input) {
|
|
81
|
+
return profile.sdk.purgeTenant(hostCtx, input);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { SubmitAndPollResult } from 'gdc-sdk-core-ts';
|
|
2
|
+
import type { ProfileLoadRequest } from 'gdc-sdk-core-ts';
|
|
3
|
+
import type { RouteContext } from './individual-onboarding.js';
|
|
4
|
+
import type { SmartTokenExchangeResult, SmartTokenRequestInput } from './smart-token.js';
|
|
5
|
+
import type { ClinicalBundleSearchInput } from './resource-operations.js';
|
|
6
|
+
import { type BackendProfessionalProfile, type BackendProfileRuntimeClient } from './backend-profile-runtime.js';
|
|
7
|
+
/**
|
|
8
|
+
* Backend use-case facade for the current professional happy path.
|
|
9
|
+
*
|
|
10
|
+
* This mirrors the individual-controller runtime wrapper, but for the actor
|
|
11
|
+
* that:
|
|
12
|
+
* - loads one protected professional profile,
|
|
13
|
+
* - requests one SMART token,
|
|
14
|
+
* - reads one authorized clinical bundle or latest IPS bundle.
|
|
15
|
+
*/
|
|
16
|
+
export declare class ProfessionalBackendRuntime {
|
|
17
|
+
private readonly profileRuntime;
|
|
18
|
+
constructor(profileRuntime: BackendProfileRuntimeClient);
|
|
19
|
+
/**
|
|
20
|
+
* Loads one professional backend profile and materializes its actor facade in
|
|
21
|
+
* one step.
|
|
22
|
+
*/
|
|
23
|
+
loadProfile(input: ProfileLoadRequest): Promise<BackendProfessionalProfile>;
|
|
24
|
+
/**
|
|
25
|
+
* Requests one SMART/OpenID token from the professional actor facade.
|
|
26
|
+
*/
|
|
27
|
+
requestSmartToken(profile: BackendProfessionalProfile, input: SmartTokenRequestInput): Promise<SmartTokenExchangeResult>;
|
|
28
|
+
/**
|
|
29
|
+
* Searches one authorized clinical bundle through the professional facade.
|
|
30
|
+
*/
|
|
31
|
+
searchClinicalBundle(profile: BackendProfessionalProfile, ctx: RouteContext, input: ClinicalBundleSearchInput): Promise<SubmitAndPollResult>;
|
|
32
|
+
/**
|
|
33
|
+
* Reads the latest IPS-oriented bundle through the professional facade.
|
|
34
|
+
*/
|
|
35
|
+
getLatestIps(profile: BackendProfessionalProfile, ctx: RouteContext, input: Omit<ClinicalBundleSearchInput, 'includedTypes'>): Promise<SubmitAndPollResult>;
|
|
36
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
+
import { loadBackendProfessionalProfile, } from './backend-profile-runtime.js';
|
|
3
|
+
/**
|
|
4
|
+
* Backend use-case facade for the current professional happy path.
|
|
5
|
+
*
|
|
6
|
+
* This mirrors the individual-controller runtime wrapper, but for the actor
|
|
7
|
+
* that:
|
|
8
|
+
* - loads one protected professional profile,
|
|
9
|
+
* - requests one SMART token,
|
|
10
|
+
* - reads one authorized clinical bundle or latest IPS bundle.
|
|
11
|
+
*/
|
|
12
|
+
export class ProfessionalBackendRuntime {
|
|
13
|
+
constructor(profileRuntime) {
|
|
14
|
+
this.profileRuntime = profileRuntime;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Loads one professional backend profile and materializes its actor facade in
|
|
18
|
+
* one step.
|
|
19
|
+
*/
|
|
20
|
+
loadProfile(input) {
|
|
21
|
+
return loadBackendProfessionalProfile(this.profileRuntime, input);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Requests one SMART/OpenID token from the professional actor facade.
|
|
25
|
+
*/
|
|
26
|
+
requestSmartToken(profile, input) {
|
|
27
|
+
return profile.sdk.requestSmartToken(input);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Searches one authorized clinical bundle through the professional facade.
|
|
31
|
+
*/
|
|
32
|
+
searchClinicalBundle(profile, ctx, input) {
|
|
33
|
+
return profile.sdk.searchClinicalBundle(ctx, input);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Reads the latest IPS-oriented bundle through the professional facade.
|
|
37
|
+
*/
|
|
38
|
+
getLatestIps(profile, ctx, input) {
|
|
39
|
+
return profile.sdk.getLatestIps(ctx, input);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { CommunicationAttachedBundleSession, IndividualBundleVault, buildVitalSignObservationClaims, createSummaryOperationRequestParameters, createSummaryOperationRequestParametersResource, summarizeClinicalBundle, toClinicalResourceExpandedViews, type BuildVitalSignObservationClaimsInput } from 'gdc-common-utils-ts';
|
|
2
|
+
import type { BackendOrganizationControllerProfile, BackendProfessionalProfile } from './backend-profile-runtime.js';
|
|
3
|
+
export type IpsRequestDraft = Readonly<{
|
|
4
|
+
subjectId: string;
|
|
5
|
+
purpose?: string;
|
|
6
|
+
sectionList: readonly string[];
|
|
7
|
+
summaryOperationRequestParameters: ReturnType<typeof createSummaryOperationRequestParameters>;
|
|
8
|
+
summaryOperationRequestReferencePath: string;
|
|
9
|
+
summaryOperationRequestParametersResource: ReturnType<typeof createSummaryOperationRequestParametersResource>;
|
|
10
|
+
}>;
|
|
11
|
+
export type ProcessedClinicalBundleResponse = Readonly<{
|
|
12
|
+
totalErrors: number;
|
|
13
|
+
totalSections: number;
|
|
14
|
+
totalResources: number;
|
|
15
|
+
totalResourcesInSection: Readonly<Record<string, number>>;
|
|
16
|
+
totalNarratives: number;
|
|
17
|
+
totalNotes: number;
|
|
18
|
+
summary: ReturnType<typeof summarizeClinicalBundle>;
|
|
19
|
+
views: ReturnType<typeof toClinicalResourceExpandedViews>;
|
|
20
|
+
}>;
|
|
21
|
+
declare function buildProcessedClinicalBundleResponse(body: unknown): ProcessedClinicalBundleResponse;
|
|
22
|
+
declare class ProfessionalSubjectIpsWorkspace {
|
|
23
|
+
private readonly subjectId;
|
|
24
|
+
private readonly bundleVault;
|
|
25
|
+
constructor(subjectId: string, bundleVault: IndividualBundleVault);
|
|
26
|
+
prepareRequestBundleIps: {
|
|
27
|
+
new: (sectionList?: readonly string[], purpose?: string) => IpsRequestDraft;
|
|
28
|
+
};
|
|
29
|
+
processResponseBundleIps(body: unknown): ProcessedClinicalBundleResponse;
|
|
30
|
+
rememberResponseBundleIps(body: unknown): Promise<IndividualBundleVault>;
|
|
31
|
+
addVitalSign(input: BuildVitalSignObservationClaimsInput): Promise<IndividualBundleVault>;
|
|
32
|
+
get cache(): IndividualBundleVault;
|
|
33
|
+
}
|
|
34
|
+
declare class ProfessionalSubjectWorkspace {
|
|
35
|
+
private readonly profile;
|
|
36
|
+
private readonly cacheBySubject;
|
|
37
|
+
constructor(profile: BackendProfessionalProfile, cacheBySubject?: Map<string, IndividualBundleVault>);
|
|
38
|
+
use(subjectId: string): Promise<ProfessionalSubjectIpsWorkspace>;
|
|
39
|
+
}
|
|
40
|
+
export declare class ProfessionalProfileWorkspace {
|
|
41
|
+
readonly profile: BackendProfessionalProfile;
|
|
42
|
+
readonly subject: ProfessionalSubjectWorkspace;
|
|
43
|
+
constructor(profile: BackendProfessionalProfile);
|
|
44
|
+
}
|
|
45
|
+
export declare class OrganizationControllerProfileWorkspace {
|
|
46
|
+
readonly profile: BackendOrganizationControllerProfile;
|
|
47
|
+
readonly organization: {
|
|
48
|
+
bundleEditor: {
|
|
49
|
+
consentTemplate: (initialBundle?: Record<string, any>) => import("gdc-common-utils-ts").ConsentAccessEditor;
|
|
50
|
+
invoice: () => import("gdc-common-utils-ts").InvoiceBundleEditor;
|
|
51
|
+
clinicalCommunication: (initialBundle?: Record<string, any>, communicationClaims?: Record<string, unknown>) => CommunicationAttachedBundleSession;
|
|
52
|
+
};
|
|
53
|
+
employee: {
|
|
54
|
+
processResponseDirectory: (body: unknown) => Readonly<{
|
|
55
|
+
identifier?: string;
|
|
56
|
+
email?: string;
|
|
57
|
+
role?: string;
|
|
58
|
+
worksFor?: string;
|
|
59
|
+
memberOf?: string;
|
|
60
|
+
memberOfOrgTaxId?: string;
|
|
61
|
+
resourceId?: string;
|
|
62
|
+
status?: string;
|
|
63
|
+
claims: Record<string, unknown>;
|
|
64
|
+
}>[];
|
|
65
|
+
};
|
|
66
|
+
license: {
|
|
67
|
+
processResponseList: (body: unknown) => Readonly<{
|
|
68
|
+
contracted: number;
|
|
69
|
+
free: number;
|
|
70
|
+
used: number;
|
|
71
|
+
available: number;
|
|
72
|
+
issued: number;
|
|
73
|
+
active: number;
|
|
74
|
+
inactive: number;
|
|
75
|
+
}>;
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
constructor(profile: BackendOrganizationControllerProfile);
|
|
79
|
+
}
|
|
80
|
+
export declare function createProfessionalProfileWorkspace(profile: BackendProfessionalProfile): ProfessionalProfileWorkspace;
|
|
81
|
+
export declare function createOrganizationControllerProfileWorkspace(profile: BackendOrganizationControllerProfile): OrganizationControllerProfileWorkspace;
|
|
82
|
+
export { buildProcessedClinicalBundleResponse, buildVitalSignObservationClaims, };
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
+
import { CommunicationAttachedBundleSession, IndividualBundleVault, VaultMemRepository, buildVitalSignObservationClaims, createConsentAccessEditor, createInvoiceBundleEditor, createSummaryOperationRequestParameters, createSummaryOperationRequestParametersResource, createSummaryOperationRequestReferencePath, readEmployeeSearchResults, summarizeClinicalBundle, summarizeLicenseListRecords, toClinicalResourceExpandedViews, } from 'gdc-common-utils-ts';
|
|
3
|
+
function normalizeSectionList(sectionList) {
|
|
4
|
+
return Array.from(new Set((sectionList || []).map((item) => String(item || '').trim()).filter(Boolean)));
|
|
5
|
+
}
|
|
6
|
+
function unwrapBody(body) {
|
|
7
|
+
const root = body && typeof body === 'object' ? body : {};
|
|
8
|
+
return root.body && typeof root.body === 'object' ? root.body : root;
|
|
9
|
+
}
|
|
10
|
+
function buildClinicalSectionCounts(views) {
|
|
11
|
+
const out = {};
|
|
12
|
+
for (const view of views) {
|
|
13
|
+
const sections = String(view.common.claims['Composition.section'] || '').split(',').map((item) => item.trim()).filter(Boolean);
|
|
14
|
+
if (sections.length === 0) {
|
|
15
|
+
out.unknown = (out.unknown || 0) + 1;
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
for (const section of sections) {
|
|
19
|
+
out[section] = (out[section] || 0) + 1;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return out;
|
|
23
|
+
}
|
|
24
|
+
function buildProcessedClinicalBundleResponse(body) {
|
|
25
|
+
const bundle = unwrapBody(body);
|
|
26
|
+
const views = toClinicalResourceExpandedViews(bundle);
|
|
27
|
+
const summary = summarizeClinicalBundle(bundle);
|
|
28
|
+
return {
|
|
29
|
+
totalErrors: 0,
|
|
30
|
+
totalSections: Object.keys(buildClinicalSectionCounts(views)).length,
|
|
31
|
+
totalResources: summary.totalEntries,
|
|
32
|
+
totalResourcesInSection: buildClinicalSectionCounts(views),
|
|
33
|
+
totalNarratives: summary.xhtmlEntries,
|
|
34
|
+
totalNotes: summary.notedEntries,
|
|
35
|
+
summary,
|
|
36
|
+
views,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
class ProfessionalSubjectIpsWorkspace {
|
|
40
|
+
constructor(subjectId, bundleVault) {
|
|
41
|
+
this.subjectId = subjectId;
|
|
42
|
+
this.bundleVault = bundleVault;
|
|
43
|
+
this.prepareRequestBundleIps = {
|
|
44
|
+
new: (sectionList, purpose) => {
|
|
45
|
+
const normalizedSections = normalizeSectionList(sectionList);
|
|
46
|
+
const summaryOperationRequestParameters = createSummaryOperationRequestParameters({
|
|
47
|
+
subjectId: this.subjectId,
|
|
48
|
+
filterSections: normalizedSections,
|
|
49
|
+
});
|
|
50
|
+
return {
|
|
51
|
+
subjectId: this.subjectId,
|
|
52
|
+
purpose: typeof purpose === 'string' && purpose.trim() ? purpose.trim() : undefined,
|
|
53
|
+
sectionList: normalizedSections,
|
|
54
|
+
summaryOperationRequestParameters,
|
|
55
|
+
summaryOperationRequestReferencePath: createSummaryOperationRequestReferencePath(summaryOperationRequestParameters),
|
|
56
|
+
summaryOperationRequestParametersResource: createSummaryOperationRequestParametersResource(summaryOperationRequestParameters),
|
|
57
|
+
};
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
processResponseBundleIps(body) {
|
|
62
|
+
return buildProcessedClinicalBundleResponse(body);
|
|
63
|
+
}
|
|
64
|
+
async rememberResponseBundleIps(body) {
|
|
65
|
+
await this.bundleVault.importBundleDocument(unwrapBody(body));
|
|
66
|
+
return this.bundleVault;
|
|
67
|
+
}
|
|
68
|
+
async addVitalSign(input) {
|
|
69
|
+
await this.bundleVault.upsertVitalSign(input);
|
|
70
|
+
return this.bundleVault;
|
|
71
|
+
}
|
|
72
|
+
get cache() {
|
|
73
|
+
return this.bundleVault;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
class ProfessionalSubjectWorkspace {
|
|
77
|
+
constructor(profile, cacheBySubject = new Map()) {
|
|
78
|
+
this.profile = profile;
|
|
79
|
+
this.cacheBySubject = cacheBySubject;
|
|
80
|
+
}
|
|
81
|
+
async use(subjectId) {
|
|
82
|
+
const normalizedSubjectId = String(subjectId || '').trim() || String(this.profile.profile.descriptor.subjectDid || '').trim();
|
|
83
|
+
let bundleVault = this.cacheBySubject.get(normalizedSubjectId);
|
|
84
|
+
if (!bundleVault) {
|
|
85
|
+
bundleVault = await new IndividualBundleVault({
|
|
86
|
+
vaultRepository: new VaultMemRepository(),
|
|
87
|
+
individualId: normalizedSubjectId,
|
|
88
|
+
}).initialize();
|
|
89
|
+
this.cacheBySubject.set(normalizedSubjectId, bundleVault);
|
|
90
|
+
}
|
|
91
|
+
return new ProfessionalSubjectIpsWorkspace(normalizedSubjectId, bundleVault);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
export class ProfessionalProfileWorkspace {
|
|
95
|
+
constructor(profile) {
|
|
96
|
+
this.profile = profile;
|
|
97
|
+
this.subject = new ProfessionalSubjectWorkspace(profile);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
export class OrganizationControllerProfileWorkspace {
|
|
101
|
+
constructor(profile) {
|
|
102
|
+
this.profile = profile;
|
|
103
|
+
this.organization = {
|
|
104
|
+
bundleEditor: {
|
|
105
|
+
consentTemplate: (initialBundle) => createConsentAccessEditor(initialBundle ? { initialBundle: initialBundle } : undefined),
|
|
106
|
+
invoice: () => createInvoiceBundleEditor(),
|
|
107
|
+
clinicalCommunication: (initialBundle, communicationClaims) => new CommunicationAttachedBundleSession({
|
|
108
|
+
...(initialBundle ? { initialBundle: initialBundle } : {}),
|
|
109
|
+
...(communicationClaims ? { communicationClaims } : {}),
|
|
110
|
+
}),
|
|
111
|
+
},
|
|
112
|
+
employee: {
|
|
113
|
+
processResponseDirectory: (body) => readEmployeeSearchResults(body),
|
|
114
|
+
},
|
|
115
|
+
license: {
|
|
116
|
+
processResponseList: (body) => summarizeLicenseListRecords(body),
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
export function createProfessionalProfileWorkspace(profile) {
|
|
122
|
+
return new ProfessionalProfileWorkspace(profile);
|
|
123
|
+
}
|
|
124
|
+
export function createOrganizationControllerProfileWorkspace(profile) {
|
|
125
|
+
return new OrganizationControllerProfileWorkspace(profile);
|
|
126
|
+
}
|
|
127
|
+
export { buildProcessedClinicalBundleResponse, buildVitalSignObservationClaims, };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IndividualOrganizationLifecycleEditor } from 'gdc-common-utils-ts';
|
|
2
|
+
import type { LicenseOfferSearchState, LicenseOrderSearchState } from 'gdc-common-utils-ts/utils/license-commercial-search';
|
|
3
|
+
import type { LicenseListSearchState } from 'gdc-common-utils-ts/utils/license-list-search';
|
|
2
4
|
import type { BundleSearchQuery, CommunicationInput, DateRange, EmployeeSearchValue } from 'gdc-sdk-core-ts';
|
|
3
5
|
import type { SubmitAndPollResult } from './orchestration/client-port.js';
|
|
4
6
|
import type { RouteContext } from './individual-onboarding.js';
|
|
@@ -66,7 +68,7 @@ export type OrganizationEmployeeSearchInput = {
|
|
|
66
68
|
* The semantic filter set comes from the shared license controller facade.
|
|
67
69
|
*/
|
|
68
70
|
export type LicenseListRuntimeSearchInput = {
|
|
69
|
-
licenseQuery?: Partial<
|
|
71
|
+
licenseQuery?: Partial<LicenseListSearchState>;
|
|
70
72
|
requestThid?: string;
|
|
71
73
|
pollOptions?: {
|
|
72
74
|
timeoutMs?: number;
|
|
@@ -78,7 +80,7 @@ export type LicenseListRuntimeSearchInput = {
|
|
|
78
80
|
* actor facades.
|
|
79
81
|
*/
|
|
80
82
|
export type LicenseOfferRuntimeSearchInput = {
|
|
81
|
-
offerQuery?: Partial<
|
|
83
|
+
offerQuery?: Partial<LicenseOfferSearchState>;
|
|
82
84
|
requestThid?: string;
|
|
83
85
|
pollOptions?: {
|
|
84
86
|
timeoutMs?: number;
|
|
@@ -90,7 +92,7 @@ export type LicenseOfferRuntimeSearchInput = {
|
|
|
90
92
|
* through actor facades.
|
|
91
93
|
*/
|
|
92
94
|
export type LicenseOrderRuntimeSearchInput = {
|
|
93
|
-
orderQuery?: Partial<
|
|
95
|
+
orderQuery?: Partial<LicenseOrderSearchState>;
|
|
94
96
|
requestThid?: string;
|
|
95
97
|
pollOptions?: {
|
|
96
98
|
timeoutMs?: number;
|
|
@@ -109,7 +111,12 @@ export type IndividualOrganizationLifecycleInput = {
|
|
|
109
111
|
* Canonical claims used by GW CORE to locate the hosted individual/family
|
|
110
112
|
* registration.
|
|
111
113
|
*/
|
|
112
|
-
organizationClaims
|
|
114
|
+
organizationClaims?: Record<string, unknown>;
|
|
115
|
+
/**
|
|
116
|
+
* Preferred high-level shared editor for lifecycle callers that want to
|
|
117
|
+
* avoid assembling raw claims inline.
|
|
118
|
+
*/
|
|
119
|
+
organizationEditor?: IndividualOrganizationLifecycleEditor;
|
|
113
120
|
/**
|
|
114
121
|
* Optional canonical resource id when already known by the caller.
|
|
115
122
|
*/
|
|
@@ -160,6 +167,39 @@ export type CommunicationIngestionInput = {
|
|
|
160
167
|
intervalMs?: number;
|
|
161
168
|
};
|
|
162
169
|
};
|
|
170
|
+
/**
|
|
171
|
+
* Runtime participant query for `Communication/_search`.
|
|
172
|
+
*
|
|
173
|
+
* Search semantics:
|
|
174
|
+
* - `subject` scopes which individual communication sections to inspect
|
|
175
|
+
* - `userActorId` and `targetActorId` both match sender OR any recipient
|
|
176
|
+
* - `senderActorId` and `recipientActorId` constrain one side explicitly
|
|
177
|
+
* - `actorId` is the generic sender-or-recipient filter
|
|
178
|
+
* - `*` means "all" for the corresponding operand
|
|
179
|
+
*
|
|
180
|
+
* Canonical prefixes are normalized by shared `gdc-common-utils-ts` helpers:
|
|
181
|
+
* - `did:`
|
|
182
|
+
* - `email:` / `mailto:`
|
|
183
|
+
* - `tel:` / `phone:`
|
|
184
|
+
*/
|
|
185
|
+
export type CommunicationParticipantRuntimeSearchInput = {
|
|
186
|
+
searchParams?: Record<string, string | number | boolean | Array<string | number | boolean> | undefined>;
|
|
187
|
+
subject?: string | string[];
|
|
188
|
+
actorId?: string | string[];
|
|
189
|
+
senderActorId?: string | string[];
|
|
190
|
+
recipientActorId?: string | string[];
|
|
191
|
+
userActorId?: string | string[];
|
|
192
|
+
targetActorId?: string | string[];
|
|
193
|
+
periodStart?: string;
|
|
194
|
+
periodEnd?: string;
|
|
195
|
+
requestThid?: string;
|
|
196
|
+
pollOptions?: {
|
|
197
|
+
timeoutMs?: number;
|
|
198
|
+
intervalMs?: number;
|
|
199
|
+
};
|
|
200
|
+
page?: number;
|
|
201
|
+
count?: number;
|
|
202
|
+
};
|
|
163
203
|
export type ClinicalDateRange = DateRange;
|
|
164
204
|
export type ClinicalBundleSearchInput = Omit<BundleSearchQuery, 'section' | 'searchParams'> & {
|
|
165
205
|
section?: string | string[];
|
|
@@ -234,6 +274,20 @@ export type GrantProfessionalAccessResult = {
|
|
|
234
274
|
consentClaims: Record<string, unknown>;
|
|
235
275
|
claimsCid?: string;
|
|
236
276
|
};
|
|
277
|
+
export type RevokeProfessionalAccessInput = {
|
|
278
|
+
consentClaims: Record<string, unknown>;
|
|
279
|
+
periodEnd?: string;
|
|
280
|
+
dataType?: string;
|
|
281
|
+
pollOptions?: {
|
|
282
|
+
timeoutMs?: number;
|
|
283
|
+
intervalMs?: number;
|
|
284
|
+
};
|
|
285
|
+
};
|
|
286
|
+
export type RevokeProfessionalAccessResult = {
|
|
287
|
+
thid: string;
|
|
288
|
+
consent: SubmitAndPollResult;
|
|
289
|
+
consentClaims: Record<string, unknown>;
|
|
290
|
+
};
|
|
237
291
|
export type DigitalTwinGenerationInput = {
|
|
238
292
|
compositionPayload: {
|
|
239
293
|
thid?: string;
|
|
@@ -465,6 +519,16 @@ export declare function ingestCommunicationAndUpdateIndexWithDeps(routeCtx: Rout
|
|
|
465
519
|
intervalMs?: number;
|
|
466
520
|
}) => Promise<SubmitAndPollResult>;
|
|
467
521
|
}): Promise<SubmitAndPollResult>;
|
|
522
|
+
export declare function searchCommunicationParticipantsWithDeps(routeCtx: RouteContext, input: CommunicationParticipantRuntimeSearchInput, deps: {
|
|
523
|
+
communicationSearchPath: (ctx: RouteContext) => string;
|
|
524
|
+
communicationSearchPollPath: (ctx: RouteContext) => string;
|
|
525
|
+
submitAndPoll: (submitPath: string, pollPath: string, payload: {
|
|
526
|
+
thid?: string;
|
|
527
|
+
} & Record<string, unknown>, pollOptions?: {
|
|
528
|
+
timeoutMs?: number;
|
|
529
|
+
intervalMs?: number;
|
|
530
|
+
}) => Promise<SubmitAndPollResult>;
|
|
531
|
+
}): Promise<SubmitAndPollResult>;
|
|
468
532
|
export declare function searchClinicalBundleWithDeps(routeCtx: RouteContext, input: ClinicalBundleSearchInput, deps: {
|
|
469
533
|
bundleSearchPath: (ctx: RouteContext) => string;
|
|
470
534
|
bundleSearchPollPath: (ctx: RouteContext) => string;
|
|
@@ -498,6 +562,16 @@ export declare function grantProfessionalAccessWithDeps(routeCtx: RouteContext,
|
|
|
498
562
|
intervalMs?: number;
|
|
499
563
|
}) => Promise<SubmitAndPollResult>;
|
|
500
564
|
}): Promise<GrantProfessionalAccessResult>;
|
|
565
|
+
export declare function revokeProfessionalAccessWithDeps(routeCtx: RouteContext, input: RevokeProfessionalAccessInput, deps: {
|
|
566
|
+
individualConsentR4BatchPath: (ctx: RouteContext) => string;
|
|
567
|
+
individualConsentR4PollPath: (ctx: RouteContext) => string;
|
|
568
|
+
submitAndPoll: (submitPath: string, pollPath: string, payload: {
|
|
569
|
+
thid?: string;
|
|
570
|
+
} & Record<string, unknown>, pollOptions?: {
|
|
571
|
+
timeoutMs?: number;
|
|
572
|
+
intervalMs?: number;
|
|
573
|
+
}) => Promise<SubmitAndPollResult>;
|
|
574
|
+
}): Promise<RevokeProfessionalAccessResult>;
|
|
501
575
|
export declare function generateDigitalTwinFromSubjectDataWithDeps(routeCtx: RouteContext, input: DigitalTwinGenerationInput, deps: {
|
|
502
576
|
digitalTwinCompositionApiBatchPath: (ctx: RouteContext) => string;
|
|
503
577
|
digitalTwinCompositionApiPollPath: (ctx: RouteContext) => string;
|
|
@@ -2,9 +2,9 @@
|
|
|
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 { createInteroperableResourceOperationEditor,
|
|
5
|
+
import { buildCommunicationParticipantSearchBundle, createInteroperableResourceOperationEditor, IndividualOrganizationLifecycleEditor, LicenseOfferSearchEditor, LicenseOrderSearchEditor, InteroperableLifecycleStatuses, LicenseListSearchEditor, } from 'gdc-common-utils-ts';
|
|
6
6
|
import { GwCoreLifecycleRequestMethod, GwCoreLifecycleRequestType, GwCoreLifecycleTodo, } from './constants/lifecycle.js';
|
|
7
|
-
import { buildEmployeeBatchEntry, buildEmployeeSearchBundle, } from 'gdc-sdk-core-ts';
|
|
7
|
+
import { buildEmployeeBatchEntry, buildEmployeeSearchBundle, ConsentClaims, } from 'gdc-sdk-core-ts';
|
|
8
8
|
export async function createOrganizationEmployeeWithDeps(routeCtx, input, options, deps) {
|
|
9
9
|
const payload = buildEmployeeLifecyclePayload({
|
|
10
10
|
routeCtx,
|
|
@@ -117,6 +117,7 @@ export async function disableIndividualOrganizationWithDeps(routeCtx, input, opt
|
|
|
117
117
|
routeCtx,
|
|
118
118
|
requestType: input.dataType || GwCoreLifecycleRequestType.IndividualOrganizationDisable,
|
|
119
119
|
organizationClaims: input.organizationClaims,
|
|
120
|
+
organizationEditor: input.organizationEditor,
|
|
120
121
|
resourceId: input.resourceId,
|
|
121
122
|
thidPrefix: 'individual-organization-disable',
|
|
122
123
|
});
|
|
@@ -127,6 +128,7 @@ export async function purgeIndividualOrganizationWithDeps(routeCtx, input, optio
|
|
|
127
128
|
routeCtx,
|
|
128
129
|
requestType: input.dataType || GwCoreLifecycleRequestType.IndividualOrganizationPurge,
|
|
129
130
|
organizationClaims: input.organizationClaims,
|
|
131
|
+
organizationEditor: input.organizationEditor,
|
|
130
132
|
resourceId: input.resourceId,
|
|
131
133
|
thidPrefix: 'individual-organization-purge',
|
|
132
134
|
});
|
|
@@ -280,6 +282,25 @@ export async function ingestCommunicationAndUpdateIndexWithDeps(routeCtx, input,
|
|
|
280
282
|
: payload;
|
|
281
283
|
return deps.submitAndPoll(deps.individualCommunicationBatchPath(routeCtx, pathFormatSegment), deps.individualCommunicationPollPath(routeCtx, pathFormatSegment), convertedPayload, input.pollOptions);
|
|
282
284
|
}
|
|
285
|
+
export async function searchCommunicationParticipantsWithDeps(routeCtx, input, deps) {
|
|
286
|
+
const payload = {
|
|
287
|
+
thid: input.requestThid || `communication-search-${createRuntimeUuid()}`,
|
|
288
|
+
body: buildCommunicationParticipantSearchBundle({
|
|
289
|
+
searchParams: input.searchParams,
|
|
290
|
+
subject: input.subject,
|
|
291
|
+
actorId: input.actorId,
|
|
292
|
+
senderActorId: input.senderActorId,
|
|
293
|
+
recipientActorId: input.recipientActorId,
|
|
294
|
+
userActorId: input.userActorId,
|
|
295
|
+
targetActorId: input.targetActorId,
|
|
296
|
+
periodStart: input.periodStart,
|
|
297
|
+
periodEnd: input.periodEnd,
|
|
298
|
+
page: input.page,
|
|
299
|
+
count: input.count,
|
|
300
|
+
}),
|
|
301
|
+
};
|
|
302
|
+
return deps.submitAndPoll(deps.communicationSearchPath(routeCtx), deps.communicationSearchPollPath(routeCtx), payload, input.pollOptions);
|
|
303
|
+
}
|
|
283
304
|
export async function searchClinicalBundleWithDeps(routeCtx, input, deps) {
|
|
284
305
|
const query = buildBundleSearchQuery(input);
|
|
285
306
|
const payload = {
|
|
@@ -337,6 +358,29 @@ export async function grantProfessionalAccessWithDeps(routeCtx, input, deps) {
|
|
|
337
358
|
claimsCid: built.claimsCid,
|
|
338
359
|
};
|
|
339
360
|
}
|
|
361
|
+
export async function revokeProfessionalAccessWithDeps(routeCtx, input, deps) {
|
|
362
|
+
const revokedClaims = ConsentClaims
|
|
363
|
+
.fromClaims(input.consentClaims)
|
|
364
|
+
.setPeriodEnd(String(input.periodEnd || new Date().toISOString()).trim())
|
|
365
|
+
.toClaims();
|
|
366
|
+
const thid = `consent-revoke-${createRuntimeUuid()}`;
|
|
367
|
+
const consentPayload = {
|
|
368
|
+
thid,
|
|
369
|
+
body: {
|
|
370
|
+
data: [{
|
|
371
|
+
type: input.dataType || 'Consent-grant-request-v1.0',
|
|
372
|
+
meta: { claims: revokedClaims },
|
|
373
|
+
resource: { resourceType: 'Consent', meta: { claims: revokedClaims } },
|
|
374
|
+
}],
|
|
375
|
+
},
|
|
376
|
+
};
|
|
377
|
+
const consent = await deps.submitAndPoll(deps.individualConsentR4BatchPath(routeCtx), deps.individualConsentR4PollPath(routeCtx), consentPayload, input.pollOptions);
|
|
378
|
+
return {
|
|
379
|
+
thid,
|
|
380
|
+
consent,
|
|
381
|
+
consentClaims: revokedClaims,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
340
384
|
export async function generateDigitalTwinFromSubjectDataWithDeps(routeCtx, input, deps) {
|
|
341
385
|
const payload = {
|
|
342
386
|
thid: input.compositionPayload.thid || `digital-twin-${createRuntimeUuid()}`,
|
|
@@ -384,9 +428,10 @@ function buildEmployeeLifecyclePayload(input) {
|
|
|
384
428
|
};
|
|
385
429
|
}
|
|
386
430
|
function buildIndividualOrganizationLifecyclePayload(input) {
|
|
387
|
-
const
|
|
388
|
-
|
|
389
|
-
.setClaims(
|
|
431
|
+
const payload = input.organizationEditor
|
|
432
|
+
? new IndividualOrganizationLifecycleEditor(input.organizationEditor.getState())
|
|
433
|
+
: new IndividualOrganizationLifecycleEditor().setClaims(input.organizationClaims || {});
|
|
434
|
+
payload
|
|
390
435
|
.setRequestType(input.requestType)
|
|
391
436
|
.setThreadId(`${input.thidPrefix}-${createRuntimeUuid()}`);
|
|
392
437
|
if (input.resourceId) {
|