gdc-sdk-node-ts 2.0.2 → 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.
Files changed (31) hide show
  1. package/README.md +72 -30
  2. package/dist/backend-profile-runtime.d.ts +48 -0
  3. package/dist/backend-profile-runtime.js +62 -0
  4. package/dist/family-organization-registration.d.ts +40 -0
  5. package/dist/family-organization-registration.js +54 -0
  6. package/dist/family-organization-search.d.ts +30 -0
  7. package/dist/family-organization-search.js +59 -0
  8. package/dist/index.d.ts +5 -0
  9. package/dist/index.js +5 -0
  10. package/dist/individual-controller-backend-runtime.d.ts +13 -0
  11. package/dist/individual-controller-backend-runtime.js +14 -0
  12. package/dist/legal-organization-onboarding-facade.d.ts +70 -0
  13. package/dist/legal-organization-onboarding-facade.js +169 -0
  14. package/dist/node-runtime-client.d.ts +47 -4
  15. package/dist/node-runtime-client.js +75 -7
  16. package/dist/orchestration/client-port.d.ts +7 -1
  17. package/dist/orchestration/individual-controller-sdk.d.ts +18 -1
  18. package/dist/orchestration/individual-controller-sdk.js +21 -0
  19. package/dist/orchestration/organization-controller-sdk.d.ts +3 -2
  20. package/dist/orchestration/organization-controller-sdk.js +3 -2
  21. package/dist/orchestration/professional-sdk.d.ts +11 -1
  22. package/dist/orchestration/professional-sdk.js +14 -0
  23. package/dist/organization-controller-backend-runtime.d.ts +65 -0
  24. package/dist/organization-controller-backend-runtime.js +83 -0
  25. package/dist/professional-backend-runtime.d.ts +36 -0
  26. package/dist/professional-backend-runtime.js +41 -0
  27. package/dist/profile-workspace.d.ts +82 -0
  28. package/dist/profile-workspace.js +127 -0
  29. package/dist/resource-operations.d.ts +24 -0
  30. package/dist/resource-operations.js +24 -1
  31. package/package.json +4 -3
@@ -1,7 +1,7 @@
1
1
  import { type NodeRuntimeClient, type PollOptions, type SubmitAndPollResult, type SubmitPayload } from './client-port.js';
2
2
  import type { RouteContext } from '../individual-onboarding.js';
3
3
  import type { SmartTokenExchangeResult, SmartTokenRequestInput } from '../smart-token.js';
4
- import type { CommunicationIngestionInput, CommunicationParticipantRuntimeSearchInput, GrantProfessionalAccessInput, GrantProfessionalAccessResult } from '../resource-operations.js';
4
+ import type { CommunicationIngestionInput, CommunicationParticipantRuntimeSearchInput, ClinicalBundleSearchInput, GrantProfessionalAccessInput, GrantProfessionalAccessResult } from '../resource-operations.js';
5
5
  /**
6
6
  * Professional-oriented facade for runtime actions that belong to the
7
7
  * professional actor itself after tenant and employee provisioning have already
@@ -29,6 +29,16 @@ export declare class ProfessionalSdk {
29
29
  * `NodeHttpClient({ ctx })` instead of being repeated on every call.
30
30
  */
31
31
  requestSmartToken(input: SmartTokenRequestInput): Promise<SmartTokenExchangeResult>;
32
+ /**
33
+ * Executes one clinical `Bundle/_search` using the professional actor
34
+ * session and tenant route context.
35
+ */
36
+ searchClinicalBundle(ctx: RouteContext, input: ClinicalBundleSearchInput): Promise<SubmitAndPollResult>;
37
+ /**
38
+ * Reads the latest IPS-oriented document projection available to the
39
+ * professional actor for one subject.
40
+ */
41
+ getLatestIps(ctx: RouteContext, input: Omit<ClinicalBundleSearchInput, 'includedTypes'>): Promise<SubmitAndPollResult>;
32
42
  /**
33
43
  * Ingests a FHIR `Communication` and waits for indexing.
34
44
  */
@@ -31,6 +31,20 @@ export class ProfessionalSdk {
31
31
  requestSmartToken(input) {
32
32
  return requireClientMethod(this.client, 'requestSmartToken')(input);
33
33
  }
34
+ /**
35
+ * Executes one clinical `Bundle/_search` using the professional actor
36
+ * session and tenant route context.
37
+ */
38
+ searchClinicalBundle(ctx, input) {
39
+ return requireClientMethod(this.client, 'searchClinicalBundle')(ctx, input);
40
+ }
41
+ /**
42
+ * Reads the latest IPS-oriented document projection available to the
43
+ * professional actor for one subject.
44
+ */
45
+ getLatestIps(ctx, input) {
46
+ return requireClientMethod(this.client, 'getLatestIps')(ctx, input);
47
+ }
34
48
  /**
35
49
  * Ingests a FHIR `Communication` and waits for indexing.
36
50
  */
@@ -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, };
@@ -274,6 +274,20 @@ export type GrantProfessionalAccessResult = {
274
274
  consentClaims: Record<string, unknown>;
275
275
  claimsCid?: string;
276
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
+ };
277
291
  export type DigitalTwinGenerationInput = {
278
292
  compositionPayload: {
279
293
  thid?: string;
@@ -548,6 +562,16 @@ export declare function grantProfessionalAccessWithDeps(routeCtx: RouteContext,
548
562
  intervalMs?: number;
549
563
  }) => Promise<SubmitAndPollResult>;
550
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>;
551
575
  export declare function generateDigitalTwinFromSubjectDataWithDeps(routeCtx: RouteContext, input: DigitalTwinGenerationInput, deps: {
552
576
  digitalTwinCompositionApiBatchPath: (ctx: RouteContext) => string;
553
577
  digitalTwinCompositionApiPollPath: (ctx: RouteContext) => string;
@@ -4,7 +4,7 @@ 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
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,
@@ -358,6 +358,29 @@ export async function grantProfessionalAccessWithDeps(routeCtx, input, deps) {
358
358
  claimsCid: built.claimsCid,
359
359
  };
360
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
+ }
361
384
  export async function generateDigitalTwinFromSubjectDataWithDeps(routeCtx, input, deps) {
362
385
  const payload = {
363
386
  thid: input.compositionPayload.thid || `digital-twin-${createRuntimeUuid()}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gdc-sdk-node-ts",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
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.",
@@ -16,6 +16,7 @@
16
16
  "local:close": "PORTS=3000 bash ./scripts/local-close.sh",
17
17
  "docker:close": "PORTS=8000 bash ./scripts/local-close.sh",
18
18
  "test": "npm run build && node --test tests/*.test.mjs",
19
+ "test:e2e:101:live-full-cycle": "npm run build && RUN_LIVE_101_FULL_CYCLE_E2E=1 node --test tests/101-live-full-cycle-bff-runtime.e2e.test.mjs",
19
20
  "test:e2e:live-gw": "npm run build && RUN_LIVE_GW_E2E=1 node --test tests/live-gw-node-runtime.e2e.test.mjs",
20
21
  "test:e2e:live-gw:professional": "npm run build && RUN_LIVE_GW_E2E=1 LIVE_GW_E2E_SUITE=professional node --test tests/live-gw-node-runtime.e2e.test.mjs",
21
22
  "test:e2e:live-gw:individual": "npm run build && RUN_LIVE_GW_E2E=1 LIVE_GW_E2E_SUITE=individual node --test tests/live-gw-node-runtime.e2e.test.mjs",
@@ -30,8 +31,8 @@
30
31
  "test:e2e:live-gw:clean": "bash ./scripts/run-live-gw-clean.sh"
31
32
  },
32
33
  "dependencies": {
33
- "gdc-common-utils-ts": "^2.0.4",
34
- "gdc-sdk-core-ts": "^2.0.3"
34
+ "gdc-common-utils-ts": "^2.0.6",
35
+ "gdc-sdk-core-ts": "^2.0.4"
35
36
  },
36
37
  "devDependencies": {
37
38
  "@types/node": "^20.14.10",