gdc-sdk-front-ts 0.6.5 → 0.6.7
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 +277 -9
- package/dist/ProfileManager.d.ts +22 -0
- package/dist/ProfileManager.js +155 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +8 -0
- package/dist/orchestration/client-port.d.ts +161 -0
- package/dist/orchestration/client-port.js +26 -0
- package/dist/orchestration/facades.d.ts +65 -0
- package/dist/orchestration/facades.js +142 -0
- package/dist/orchestration/host-onboarding-sdk.d.ts +9 -0
- package/dist/orchestration/host-onboarding-sdk.js +16 -0
- package/dist/orchestration/individual-controller-sdk.d.ts +18 -0
- package/dist/orchestration/individual-controller-sdk.js +43 -0
- package/dist/orchestration/individual-member-sdk.d.ts +8 -0
- package/dist/orchestration/individual-member-sdk.js +13 -0
- package/dist/orchestration/organization-controller-sdk.d.ts +11 -0
- package/dist/orchestration/organization-controller-sdk.js +22 -0
- package/dist/orchestration/organization-employee-sdk.d.ts +8 -0
- package/dist/orchestration/organization-employee-sdk.js +13 -0
- package/dist/orchestration/personal-sdk.d.ts +13 -0
- package/dist/orchestration/personal-sdk.js +28 -0
- package/dist/orchestration/professional-sdk.d.ts +10 -0
- package/dist/orchestration/professional-sdk.js +19 -0
- package/dist/services.d.ts +58 -10
- package/dist/services.js +88 -5
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -14,22 +14,35 @@ Use this package when your frontend needs to:
|
|
|
14
14
|
This package is frontend-facing. It should explain app flows, not gateway route
|
|
15
15
|
details.
|
|
16
16
|
|
|
17
|
+
Architectural rule:
|
|
18
|
+
|
|
19
|
+
- `gdc-sdk-front-ts` should converge on the same actor-scoped facade boundaries
|
|
20
|
+
as `gdc-sdk-node-ts`
|
|
21
|
+
- transport and adapter details may differ
|
|
22
|
+
- business ownership must not differ by runtime
|
|
23
|
+
|
|
17
24
|
## Start Here
|
|
18
25
|
|
|
19
26
|
If you are integrating this package for the first time, open these in order:
|
|
20
27
|
|
|
21
|
-
1. [docs/
|
|
22
|
-
|
|
23
|
-
|
|
28
|
+
1. [gdc-sdk-core-ts/docs/101-SDK_PACKAGE_BOUNDARIES.md](https://github.com/Global-DataCare/gdc-sdk-core-ts/blob/main/docs/101-SDK_PACKAGE_BOUNDARIES.md)
|
|
29
|
+
Why `core`, `node`, and `front` are separate packages, what each one owns,
|
|
30
|
+
and why frontend facades should mirror backend actor boundaries.
|
|
31
|
+
1. [docs/101-SDK_INTEGRATION.md](./docs/101-SDK_INTEGRATION.md)
|
|
32
|
+
Real frontend/native setup, imports, `new ClientSDK(...)`,
|
|
33
|
+
`initializeCommunicationIdentity(...)`, provider discovery, and
|
|
24
34
|
`initializeSession(...)`.
|
|
25
35
|
2. [docs/DATASPACE_DISCOVERY_FRONTEND_TODO.md](./docs/DATASPACE_DISCOVERY_FRONTEND_TODO.md)
|
|
26
36
|
Frontend discovery guide for BFF-first provider/operator discovery, UI card
|
|
27
37
|
mapping, and copy/paste backend DTO consumption.
|
|
28
|
-
3. [gdc-sdk-core-ts/docs/
|
|
38
|
+
3. [gdc-sdk-core-ts/docs/101-SDK_FLOWS.md](https://github.com/Global-DataCare/gdc-sdk-core-ts/blob/main/docs/101-SDK_FLOWS.md)
|
|
29
39
|
Shared business-flow map by actor family.
|
|
30
|
-
4. [gdc-
|
|
40
|
+
4. [gdc-sdk-node-ts/docs/101-LIVE_GW_LOCAL.md](https://github.com/Global-DataCare/gdc-sdk-node-ts/blob/main/docs/101-LIVE_GW_LOCAL.md)
|
|
41
|
+
Canonical local/TTY/Docker GW reference when the frontend team also needs a
|
|
42
|
+
real local GW running for end-to-end checks.
|
|
43
|
+
5. [gdc-common-utils-ts/src/examples/frontend-session.ts](https://github.com/Global-DataCare/gdc-common-utils-ts/blob/main/src/examples/frontend-session.ts)
|
|
31
44
|
Shared profile/session payload source of truth.
|
|
32
|
-
|
|
45
|
+
6. [gdc-common-utils-ts/docs/101-LIFECYCLE.md](https://github.com/Global-DataCare/gdc-common-utils-ts/blob/main/docs/101-LIFECYCLE.md)
|
|
33
46
|
Canonical lifecycle semantics and reusable placeholders for UI and portal flows.
|
|
34
47
|
|
|
35
48
|
If you need the shortest path:
|
|
@@ -37,12 +50,267 @@ If you need the shortest path:
|
|
|
37
50
|
- app identity required by GW CORE:
|
|
38
51
|
`appId` mandatory, `appVersion` optional with default `v1.0`
|
|
39
52
|
- frontend technical identity:
|
|
40
|
-
[`initializeCommunicationIdentity(...)`](./docs/
|
|
53
|
+
[`initializeCommunicationIdentity(...)`](./docs/101-SDK_INTEGRATION.md)
|
|
41
54
|
for the technical device/channel profile identity, not the legal organization id
|
|
42
55
|
- main runtime class:
|
|
43
56
|
[`ClientSDK`](src/ClientSDK.ts)
|
|
44
57
|
- profile/session bootstrap:
|
|
45
|
-
[`initializeSession(...)`](./docs/
|
|
58
|
+
[`initializeSession(...)`](./docs/101-SDK_INTEGRATION.md)
|
|
59
|
+
|
|
60
|
+
## Frontend Runtime Modes
|
|
61
|
+
|
|
62
|
+
There are two frontend integration modes. New developers should choose the
|
|
63
|
+
mode first, before choosing classes or helpers.
|
|
64
|
+
|
|
65
|
+
### 1. Portal web / non confidential app
|
|
66
|
+
|
|
67
|
+
Use this mode when:
|
|
68
|
+
|
|
69
|
+
- the frontend is a Vite/web portal
|
|
70
|
+
- the portal backend holds controller/professional keys in AWS KMS
|
|
71
|
+
- the frontend does not send DIDComm directly to GW CORE
|
|
72
|
+
|
|
73
|
+
Recommended entry point:
|
|
74
|
+
|
|
75
|
+
- start from the shared editors/builders in `gdc-sdk-core-ts`
|
|
76
|
+
- send the resulting payload or bundle to the portal backend
|
|
77
|
+
- let the backend handle KMS, DIDComm, submit, and poll
|
|
78
|
+
|
|
79
|
+
Main references:
|
|
80
|
+
|
|
81
|
+
- [gdc-sdk-core-ts/docs/101-EMPLOYEES.md](https://github.com/Global-DataCare/gdc-sdk-core-ts/blob/main/docs/101-EMPLOYEES.md)
|
|
82
|
+
- [gdc-sdk-core-ts/docs/101-CONSENT_COMMUNICATION.md](https://github.com/Global-DataCare/gdc-sdk-core-ts/blob/main/docs/101-CONSENT_COMMUNICATION.md)
|
|
83
|
+
- [gdc-common-utils-ts/docs/101-CONSENT_ACCESS.md](https://github.com/Global-DataCare/gdc-common-utils-ts/blob/main/docs/101-CONSENT_ACCESS.md)
|
|
84
|
+
- [gdc-sdk-core-ts/tests/101-employees.test.mjs](https://github.com/Global-DataCare/gdc-sdk-core-ts/blob/main/tests/101-employees.test.mjs)
|
|
85
|
+
- [gdc-common-utils-ts/__tests__/101-consent-bundle-editor.test.ts](https://github.com/Global-DataCare/gdc-common-utils-ts/blob/main/__tests__/101-consent-bundle-editor.test.ts)
|
|
86
|
+
|
|
87
|
+
Use:
|
|
88
|
+
|
|
89
|
+
- `EmployeeBundleSession` for employee create/search payloads
|
|
90
|
+
- `CommunicationAttachedBundleSession` for `Communication`-carried bundles
|
|
91
|
+
- `createConsentAccessEditor(...)` for consent editing inside a communication bundle
|
|
92
|
+
|
|
93
|
+
Controller-only employee flow in a portal web app:
|
|
94
|
+
|
|
95
|
+
Use this example only when the current frontend screen belongs to the
|
|
96
|
+
organization-controller/admin side.
|
|
97
|
+
|
|
98
|
+
Do not reuse this employee example for:
|
|
99
|
+
|
|
100
|
+
- professional screens
|
|
101
|
+
- individual/family screens
|
|
102
|
+
- generic end-user screens
|
|
103
|
+
|
|
104
|
+
Those actor families should start from their own business flow:
|
|
105
|
+
|
|
106
|
+
- professionals
|
|
107
|
+
- consent-aware access
|
|
108
|
+
- SMART token
|
|
109
|
+
- communication/index flows
|
|
110
|
+
- individuals / family
|
|
111
|
+
- consent editing
|
|
112
|
+
- related-person flows
|
|
113
|
+
- IPS/FHIR import or read flows
|
|
114
|
+
|
|
115
|
+
### Create
|
|
116
|
+
|
|
117
|
+
Use `EmployeeBundleSession` to prepare one employee create bundle. The browser
|
|
118
|
+
does not send it directly to GW CORE.
|
|
119
|
+
The portal backend wraps it into its own request/envelope, then applies KMS,
|
|
120
|
+
DIDComm, submit, and poll.
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
import { EmployeeBundleSession } from 'gdc-sdk-core-ts';
|
|
124
|
+
import {
|
|
125
|
+
EXAMPLE_EMPLOYEE_DOCTOR_ACTIVE,
|
|
126
|
+
EXAMPLE_PROVIDER_ORGANIZATION_DID,
|
|
127
|
+
} from 'gdc-common-utils-ts/examples';
|
|
128
|
+
import { ClaimsPersonSchemaorg } from 'gdc-common-utils-ts/constants/schemaorg';
|
|
129
|
+
|
|
130
|
+
// This editor lives only in frontend memory.
|
|
131
|
+
// It helps the UI build the canonical employee payload before sending it to
|
|
132
|
+
// the portal backend.
|
|
133
|
+
const bundleEditor = new EmployeeBundleSession()
|
|
134
|
+
.setIdentifier(EXAMPLE_EMPLOYEE_DOCTOR_ACTIVE.identifier)
|
|
135
|
+
.setEmail(EXAMPLE_EMPLOYEE_DOCTOR_ACTIVE.email)
|
|
136
|
+
.setRole(EXAMPLE_EMPLOYEE_DOCTOR_ACTIVE.role)
|
|
137
|
+
.addClaim(ClaimsPersonSchemaorg.memberOf, EXAMPLE_PROVIDER_ORGANIZATION_DID);
|
|
138
|
+
|
|
139
|
+
// `employeeCreateBatchBundle` is the canonical one-entry employee `_batch` bundle.
|
|
140
|
+
// Your Vite frontend normally sends this bundle to its own backend, not
|
|
141
|
+
// directly to GW CORE.
|
|
142
|
+
const employeeCreateBatchBundle = bundleEditor.toBundleBatch({
|
|
143
|
+
method: 'POST',
|
|
144
|
+
resourceId: EXAMPLE_EMPLOYEE_DOCTOR_ACTIVE.identifier,
|
|
145
|
+
});
|
|
146
|
+
console.log(employeeCreateBatchBundle);
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Search
|
|
150
|
+
|
|
151
|
+
Search is a different operation and should be built separately.
|
|
152
|
+
|
|
153
|
+
`email + role` is the recommended exact operational lookup.
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
import { EmployeeBundleSession } from 'gdc-sdk-core-ts';
|
|
157
|
+
import { EXAMPLE_EMPLOYEE_DOCTOR_ACTIVE } from 'gdc-common-utils-ts/examples';
|
|
158
|
+
|
|
159
|
+
const employeeSearchBundle = new EmployeeBundleSession()
|
|
160
|
+
.setEmail(EXAMPLE_EMPLOYEE_DOCTOR_ACTIVE.email)
|
|
161
|
+
.setRole(EXAMPLE_EMPLOYEE_DOCTOR_ACTIVE.role)
|
|
162
|
+
.toBundleSearch();
|
|
163
|
+
|
|
164
|
+
console.log(employeeSearchBundle);
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Other valid search shapes:
|
|
168
|
+
|
|
169
|
+
- by `email` only: all active profiles for that mailbox
|
|
170
|
+
- by `role` only: all active employees for that role
|
|
171
|
+
- with no filters: all employees
|
|
172
|
+
- by `identifier`: one exact technical or historical profile
|
|
173
|
+
|
|
174
|
+
### Disable
|
|
175
|
+
|
|
176
|
+
Disable is a lifecycle operation. Today the shared employee editor still
|
|
177
|
+
produces the canonical `_batch` bundle with inner `request.method = DELETE`.
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
import { EmployeeBundleSession } from 'gdc-sdk-core-ts';
|
|
181
|
+
import { EXAMPLE_EMPLOYEE_DOCTOR_ACTIVE } from 'gdc-common-utils-ts/examples';
|
|
182
|
+
|
|
183
|
+
const employeeDisableBatchBundle = new EmployeeBundleSession()
|
|
184
|
+
.setIdentifier(EXAMPLE_EMPLOYEE_DOCTOR_ACTIVE.identifier)
|
|
185
|
+
.toBundleBatch({
|
|
186
|
+
method: 'DELETE',
|
|
187
|
+
resourceId: EXAMPLE_EMPLOYEE_DOCTOR_ACTIVE.identifier,
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
console.log(employeeDisableBatchBundle);
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Current GW CORE contract vs preferred target:
|
|
194
|
+
|
|
195
|
+
- current live contract
|
|
196
|
+
- disable = `_batch` + inner `request.method = DELETE`
|
|
197
|
+
- purge = `POST .../Employee/_purge`
|
|
198
|
+
- preferred target contract
|
|
199
|
+
- disable/enable = semantic state change via `PATCH`
|
|
200
|
+
- purge = final removal operation kept separate from state changes
|
|
201
|
+
|
|
202
|
+
Conceptual `PATCH` example for state change:
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
const employeeDisablePatchBatchBundle = new EmployeeBundleSession()
|
|
206
|
+
.setIdentifier(EXAMPLE_EMPLOYEE_DOCTOR_ACTIVE.identifier)
|
|
207
|
+
.toBundleBatch({
|
|
208
|
+
method: 'PATCH',
|
|
209
|
+
resourceId: EXAMPLE_EMPLOYEE_DOCTOR_ACTIVE.identifier,
|
|
210
|
+
});
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Business meaning:
|
|
214
|
+
|
|
215
|
+
- `PATCH` should mean state transition such as enable/disable
|
|
216
|
+
- `DELETE` should be reserved for final removal semantics such as purge
|
|
217
|
+
- future operations like merge/split/destroy should be modeled first as named
|
|
218
|
+
business operations, then mapped to transport
|
|
219
|
+
|
|
220
|
+
### Purge
|
|
221
|
+
|
|
222
|
+
Purge is not the same contract as create/disable. The portal backend or runtime
|
|
223
|
+
calls the explicit `Employee/_purge` flow and normally identifies the employee
|
|
224
|
+
with `identifier`.
|
|
225
|
+
|
|
226
|
+
```ts
|
|
227
|
+
import { EmployeeBundleSession } from 'gdc-sdk-core-ts';
|
|
228
|
+
import { EXAMPLE_EMPLOYEE_DOCTOR_ACTIVE } from 'gdc-common-utils-ts/examples';
|
|
229
|
+
|
|
230
|
+
const employeePurgeSelector = new EmployeeBundleSession()
|
|
231
|
+
.setIdentifier(EXAMPLE_EMPLOYEE_DOCTOR_ACTIVE.identifier)
|
|
232
|
+
.toClaims();
|
|
233
|
+
|
|
234
|
+
console.log(employeePurgeSelector);
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Primary references for those employee flows:
|
|
238
|
+
|
|
239
|
+
- [gdc-sdk-core-ts/docs/101-EMPLOYEES.md](https://github.com/Global-DataCare/gdc-sdk-core-ts/blob/main/docs/101-EMPLOYEES.md)
|
|
240
|
+
- [gdc-sdk-core-ts/tests/101-employees.test.mjs](https://github.com/Global-DataCare/gdc-sdk-core-ts/blob/main/tests/101-employees.test.mjs)
|
|
241
|
+
|
|
242
|
+
Non-controller frontend references:
|
|
243
|
+
|
|
244
|
+
- professional / individual flow map:
|
|
245
|
+
- [gdc-sdk-core-ts/docs/101-SDK_FLOWS.md](https://github.com/Global-DataCare/gdc-sdk-core-ts/blob/main/docs/101-SDK_FLOWS.md)
|
|
246
|
+
- consent editing:
|
|
247
|
+
- [gdc-common-utils-ts/docs/101-CONSENT_ACCESS.md](https://github.com/Global-DataCare/gdc-common-utils-ts/blob/main/docs/101-CONSENT_ACCESS.md)
|
|
248
|
+
- consent + communication handoff:
|
|
249
|
+
- [gdc-sdk-core-ts/docs/101-CONSENT_COMMUNICATION.md](https://github.com/Global-DataCare/gdc-sdk-core-ts/blob/main/docs/101-CONSENT_COMMUNICATION.md)
|
|
250
|
+
|
|
251
|
+
### 2. Confidential app / direct client runtime
|
|
252
|
+
|
|
253
|
+
Use this mode when:
|
|
254
|
+
|
|
255
|
+
- the app stores transport keys locally
|
|
256
|
+
- the app can talk directly to GW CORE
|
|
257
|
+
- there is no portal backend doing KMS and DIDComm on behalf of the app
|
|
258
|
+
|
|
259
|
+
Recommended entry point:
|
|
260
|
+
|
|
261
|
+
- start from `ClientSDK`
|
|
262
|
+
- initialize runtime/session state
|
|
263
|
+
- use the same shared editors/builders from `sdk-core` when a flow needs them
|
|
264
|
+
|
|
265
|
+
Main references:
|
|
266
|
+
|
|
267
|
+
- [docs/101-SDK_INTEGRATION.md](./docs/101-SDK_INTEGRATION.md)
|
|
268
|
+
- [gdc-sdk-node-ts/docs/101-LIVE_GW_LOCAL.md](https://github.com/Global-DataCare/gdc-sdk-node-ts/blob/main/docs/101-LIVE_GW_LOCAL.md)
|
|
269
|
+
|
|
270
|
+
Decision rule:
|
|
271
|
+
|
|
272
|
+
- no local key custody: start from `sdk-core` editors and send to your backend
|
|
273
|
+
- local key custody: start from `ClientSDK` runtime/session and use `sdk-core` editors as shared modeling helpers
|
|
274
|
+
|
|
275
|
+
Minimal confidential-app example:
|
|
276
|
+
|
|
277
|
+
```ts
|
|
278
|
+
import { ClientSDK } from 'gdc-sdk-front-ts';
|
|
279
|
+
import { EmployeeBundleSession } from 'gdc-sdk-core-ts';
|
|
280
|
+
import {
|
|
281
|
+
EXAMPLE_EMPLOYEE_DOCTOR_ACTIVE,
|
|
282
|
+
EXAMPLE_PROFILE_SESSION_INPUT,
|
|
283
|
+
} from 'gdc-common-utils-ts/examples';
|
|
284
|
+
|
|
285
|
+
const appId = frontendAppConfig.appId;
|
|
286
|
+
const client = new ClientSDK({ appId });
|
|
287
|
+
|
|
288
|
+
// `initializeSession(...)` creates the authenticated frontend runtime session.
|
|
289
|
+
// In a confidential app this session owns the actor-facing runtime surface and
|
|
290
|
+
// can later expose organization-controller/professional capabilities.
|
|
291
|
+
const session = await client.initializeSession(EXAMPLE_PROFILE_SESSION_INPUT);
|
|
292
|
+
|
|
293
|
+
// The shared editor from sdk-core is still used to model the employee bundle.
|
|
294
|
+
const employeeSearchBundle = new EmployeeBundleSession()
|
|
295
|
+
.setEmail(EXAMPLE_EMPLOYEE_DOCTOR_ACTIVE.email)
|
|
296
|
+
.setRole(EXAMPLE_EMPLOYEE_DOCTOR_ACTIVE.role)
|
|
297
|
+
.toBundleSearch();
|
|
298
|
+
|
|
299
|
+
console.log(session, employeeSearchBundle);
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Runtime note:
|
|
303
|
+
|
|
304
|
+
- a confidential app still must choose the correct actor surface before using
|
|
305
|
+
an employee flow
|
|
306
|
+
- employee management belongs only to the organization-controller/admin side
|
|
307
|
+
- professional or individual apps should start from their own actor flow, not
|
|
308
|
+
from the employee examples above
|
|
309
|
+
|
|
310
|
+
Primary references for that flow:
|
|
311
|
+
|
|
312
|
+
- [docs/101-SDK_INTEGRATION.md](./docs/101-SDK_INTEGRATION.md)
|
|
313
|
+
- [gdc-sdk-node-ts/docs/101-LIVE_GW_LOCAL.md](https://github.com/Global-DataCare/gdc-sdk-node-ts/blob/main/docs/101-LIVE_GW_LOCAL.md)
|
|
46
314
|
|
|
47
315
|
## Executable Usage Examples
|
|
48
316
|
|
|
@@ -289,7 +557,7 @@ const communication = buildPermissionRequestCommunication({
|
|
|
289
557
|
## Shared Contract Sources
|
|
290
558
|
|
|
291
559
|
- [gdc-sdk-core-ts/README.md](https://github.com/Global-DataCare/gdc-sdk-core-ts/blob/main/README.md)
|
|
292
|
-
- [gdc-common-utils-ts/docs/
|
|
560
|
+
- [gdc-common-utils-ts/docs/101-CONSENT_ACCESS.md](https://github.com/Global-DataCare/gdc-common-utils-ts/blob/main/docs/101-CONSENT_ACCESS.md)
|
|
293
561
|
|
|
294
562
|
Reusable payload examples:
|
|
295
563
|
|
package/dist/ProfileManager.d.ts
CHANGED
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
import type { DeviceAppType, DeviceUserClass } from 'gdc-common-utils-ts/constants';
|
|
2
2
|
import type { Profile } from './types.js';
|
|
3
3
|
import type { CommonServices, FamilyAdminServices, IndividualServices, OrgAdminServices, ProfessionalServices } from './roleRegistry.js';
|
|
4
|
+
import { HostOnboardingSdk } from './orchestration/host-onboarding-sdk.js';
|
|
5
|
+
import { IndividualControllerSdk } from './orchestration/individual-controller-sdk.js';
|
|
6
|
+
import { IndividualMemberSdk } from './orchestration/individual-member-sdk.js';
|
|
7
|
+
import { OrganizationControllerSdk } from './orchestration/organization-controller-sdk.js';
|
|
8
|
+
import { OrganizationEmployeeSdk } from './orchestration/organization-employee-sdk.js';
|
|
9
|
+
import { PersonalSdk } from './orchestration/personal-sdk.js';
|
|
10
|
+
import { ProfessionalSdk } from './orchestration/professional-sdk.js';
|
|
4
11
|
/**
|
|
5
12
|
* Role-scoped session object returned by `ClientSDK.initializeSession(...)`.
|
|
6
13
|
*
|
|
7
14
|
* It exposes the common/auth surface plus the services allowed by the current
|
|
8
15
|
* profile capabilities.
|
|
16
|
+
*
|
|
17
|
+
* Architectural note:
|
|
18
|
+
* `ProfileManager` remains the frontend session/composition entry point, but it
|
|
19
|
+
* also materializes actor-scoped facades that mirror `gdc-sdk-node-ts`.
|
|
20
|
+
*
|
|
21
|
+
* The goal is to preserve the legacy/frontend-friendly session API while
|
|
22
|
+
* keeping the same actor boundaries as the backend runtime.
|
|
9
23
|
*/
|
|
10
24
|
export declare class ProfileManager {
|
|
11
25
|
readonly profile: Profile;
|
|
@@ -17,6 +31,7 @@ export declare class ProfileManager {
|
|
|
17
31
|
readonly familyAdmin?: FamilyAdminServices;
|
|
18
32
|
readonly individual?: IndividualServices;
|
|
19
33
|
readonly professional?: ProfessionalServices;
|
|
34
|
+
private readonly runtimeClient;
|
|
20
35
|
/**
|
|
21
36
|
* @param profile Current logical profile.
|
|
22
37
|
* @param orgDid DID of the provider/organization used as the session anchor.
|
|
@@ -131,6 +146,13 @@ export declare class ProfileManager {
|
|
|
131
146
|
}): Promise<{
|
|
132
147
|
thid: string;
|
|
133
148
|
}>;
|
|
149
|
+
asHostOnboarding(): HostOnboardingSdk;
|
|
150
|
+
asOrganizationController(): OrganizationControllerSdk;
|
|
151
|
+
asOrganizationEmployee(): OrganizationEmployeeSdk;
|
|
152
|
+
asIndividualController(): IndividualControllerSdk;
|
|
153
|
+
asIndividualMember(): IndividualMemberSdk;
|
|
154
|
+
asPersonal(): PersonalSdk;
|
|
155
|
+
asProfessional(): ProfessionalSdk;
|
|
134
156
|
}
|
|
135
157
|
/**
|
|
136
158
|
* Preferred neutral frontend actor-session surface.
|
package/dist/ProfileManager.js
CHANGED
|
@@ -1,11 +1,26 @@
|
|
|
1
1
|
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
2
|
import { CommonAuthService } from './services.js';
|
|
3
3
|
import { mapCapabilitiesToServices } from './capabilityMapper.js';
|
|
4
|
+
import { HostOnboardingSdk, } from './orchestration/host-onboarding-sdk.js';
|
|
5
|
+
import { IndividualControllerSdk } from './orchestration/individual-controller-sdk.js';
|
|
6
|
+
import { IndividualMemberSdk } from './orchestration/individual-member-sdk.js';
|
|
7
|
+
import { OrganizationControllerSdk } from './orchestration/organization-controller-sdk.js';
|
|
8
|
+
import { OrganizationEmployeeSdk } from './orchestration/organization-employee-sdk.js';
|
|
9
|
+
import { PersonalSdk } from './orchestration/personal-sdk.js';
|
|
10
|
+
import { ProfessionalSdk } from './orchestration/professional-sdk.js';
|
|
11
|
+
import { createSyntheticSubmitAndPollResult } from './orchestration/client-port.js';
|
|
4
12
|
/**
|
|
5
13
|
* Role-scoped session object returned by `ClientSDK.initializeSession(...)`.
|
|
6
14
|
*
|
|
7
15
|
* It exposes the common/auth surface plus the services allowed by the current
|
|
8
16
|
* profile capabilities.
|
|
17
|
+
*
|
|
18
|
+
* Architectural note:
|
|
19
|
+
* `ProfileManager` remains the frontend session/composition entry point, but it
|
|
20
|
+
* also materializes actor-scoped facades that mirror `gdc-sdk-node-ts`.
|
|
21
|
+
*
|
|
22
|
+
* The goal is to preserve the legacy/frontend-friendly session API while
|
|
23
|
+
* keeping the same actor boundaries as the backend runtime.
|
|
9
24
|
*/
|
|
10
25
|
export class ProfileManager {
|
|
11
26
|
/**
|
|
@@ -21,6 +36,111 @@ export class ProfileManager {
|
|
|
21
36
|
this.familyAdmin = mapped.familyAdmin;
|
|
22
37
|
this.individual = mapped.individual;
|
|
23
38
|
this.professional = mapped.professional;
|
|
39
|
+
this.runtimeClient = {
|
|
40
|
+
activateOrganizationInGatewayFromIcaProof: (input) => {
|
|
41
|
+
if (!this.orgAdmin?.admin)
|
|
42
|
+
throw new Error('orgAdmin.admin service is not available for this profile.');
|
|
43
|
+
return this.orgAdmin.admin.activateOrganizationInGatewayFromIcaProof(input);
|
|
44
|
+
},
|
|
45
|
+
confirmLegalOrganizationOrder: (input) => {
|
|
46
|
+
if (!this.orgAdmin?.admin)
|
|
47
|
+
throw new Error('orgAdmin.admin service is not available for this profile.');
|
|
48
|
+
return this.orgAdmin.admin.confirmLegalOrganizationOrder(input);
|
|
49
|
+
},
|
|
50
|
+
createOrganizationEmployee: (ctx, input) => {
|
|
51
|
+
if (!this.orgAdmin?.admin)
|
|
52
|
+
throw new Error('orgAdmin.admin service is not available for this profile.');
|
|
53
|
+
return this.orgAdmin.admin.createOrganizationEmployee(ctx.providerDid, ctx.idToken, input)
|
|
54
|
+
.then((result) => createSyntheticSubmitAndPollResult(result.thid));
|
|
55
|
+
},
|
|
56
|
+
disableEmployee: (ctx, input) => {
|
|
57
|
+
if (!this.orgAdmin?.admin)
|
|
58
|
+
throw new Error('orgAdmin.admin service is not available for this profile.');
|
|
59
|
+
return this.orgAdmin.admin.disableEmployee(ctx.providerDid, ctx.idToken, input);
|
|
60
|
+
},
|
|
61
|
+
purgeEmployee: (ctx, input) => {
|
|
62
|
+
if (!this.orgAdmin?.admin)
|
|
63
|
+
throw new Error('orgAdmin.admin service is not available for this profile.');
|
|
64
|
+
return this.orgAdmin.admin.purgeEmployee(ctx.providerDid, ctx.idToken, input);
|
|
65
|
+
},
|
|
66
|
+
activateEmployeeDeviceWithActivationRequest: (ctx, input) => this.common.auth.activateEmployeeDeviceWithActivationRequest(input.activationCode, ctx.providerDid, ctx.idToken, input.dcrPayload),
|
|
67
|
+
requestSmartToken: (input) => this.common.auth.requestSmartToken(input),
|
|
68
|
+
startIndividualOrganization: (ctx, input) => {
|
|
69
|
+
if (!this.familyAdmin?.admin)
|
|
70
|
+
throw new Error('familyAdmin.admin service is not available for this profile.');
|
|
71
|
+
return this.familyAdmin.admin.startIndividualOrganization(ctx.providerDid, ctx.idToken, input);
|
|
72
|
+
},
|
|
73
|
+
confirmIndividualOrganizationOrder: (ctx, input) => {
|
|
74
|
+
if (!this.familyAdmin?.admin)
|
|
75
|
+
throw new Error('familyAdmin.admin service is not available for this profile.');
|
|
76
|
+
return this.familyAdmin.admin.confirmIndividualOrganizationOrder(ctx.providerDid, ctx.idToken, input);
|
|
77
|
+
},
|
|
78
|
+
disableIndividual: (ctx, input) => {
|
|
79
|
+
if (!this.familyAdmin?.admin)
|
|
80
|
+
throw new Error('familyAdmin.admin service is not available for this profile.');
|
|
81
|
+
return this.familyAdmin.admin.disableIndividual(ctx.providerDid, ctx.idToken, input);
|
|
82
|
+
},
|
|
83
|
+
purgeIndividual: (ctx, input) => {
|
|
84
|
+
if (!this.familyAdmin?.admin)
|
|
85
|
+
throw new Error('familyAdmin.admin service is not available for this profile.');
|
|
86
|
+
return this.familyAdmin.admin.purgeIndividual(ctx.providerDid, ctx.idToken, input);
|
|
87
|
+
},
|
|
88
|
+
disableIndividualMember: (ctx, input) => {
|
|
89
|
+
if (!this.familyAdmin?.admin)
|
|
90
|
+
throw new Error('familyAdmin.admin service is not available for this profile.');
|
|
91
|
+
return this.familyAdmin.admin.disableIndividualMember(ctx.providerDid, ctx.idToken, input);
|
|
92
|
+
},
|
|
93
|
+
purgeIndividualMember: (ctx, input) => {
|
|
94
|
+
if (!this.familyAdmin?.admin)
|
|
95
|
+
throw new Error('familyAdmin.admin service is not available for this profile.');
|
|
96
|
+
return this.familyAdmin.admin.purgeIndividualMember(ctx.providerDid, ctx.idToken, input);
|
|
97
|
+
},
|
|
98
|
+
grantProfessionalAccess: (ctx, input) => {
|
|
99
|
+
if (this.professional?.physician) {
|
|
100
|
+
return this.professional.physician.grantProfessionalAccess({ ...input, providerDid: ctx.providerDid, requiredScope: ctx.requiredScope, idToken: ctx.idToken });
|
|
101
|
+
}
|
|
102
|
+
if (!this.individual?.service)
|
|
103
|
+
throw new Error('individual.service is not available for this profile.');
|
|
104
|
+
return this.individual.service.grantProfessionalAccess({ ...input, providerDid: ctx.providerDid, requiredScope: ctx.requiredScope || '', idToken: ctx.idToken });
|
|
105
|
+
},
|
|
106
|
+
importIpsOrFhirAndUpdateIndex: (ctx, input) => {
|
|
107
|
+
if (!this.individual?.service)
|
|
108
|
+
throw new Error('individual.service is not available for this profile.');
|
|
109
|
+
return this.individual.service.importIpsOrFhirAndUpdateIndex(input.compositionPayload, ctx.providerDid, ctx.requiredScope || '', ctx.idToken, input.format).then((result) => createSyntheticSubmitAndPollResult(result.thid));
|
|
110
|
+
},
|
|
111
|
+
upsertRelatedPersonAndPoll: (ctx, input) => {
|
|
112
|
+
if (!this.individual?.service)
|
|
113
|
+
throw new Error('individual.service is not available for this profile.');
|
|
114
|
+
return this.individual.service.upsertRelatedPersonAndPoll(input.relatedPersonPayload, ctx.providerDid, ctx.requiredScope || '', ctx.idToken);
|
|
115
|
+
},
|
|
116
|
+
ingestCommunicationAndUpdateIndex: (ctx, input) => {
|
|
117
|
+
if (this.professional?.physician) {
|
|
118
|
+
return this.professional.physician.ingestCommunicationAndUpdateIndex(input.communicationPayload, ctx.providerDid, ctx.requiredScope || '', ctx.idToken, input.pathFormatSegment);
|
|
119
|
+
}
|
|
120
|
+
if (this.professional?.paramedic) {
|
|
121
|
+
return this.professional.paramedic.ingestCommunicationAndUpdateIndex(input.communicationPayload, ctx.providerDid, ctx.requiredScope || '', ctx.idToken, input.pathFormatSegment);
|
|
122
|
+
}
|
|
123
|
+
if (!this.individual?.service)
|
|
124
|
+
throw new Error('individual.service is not available for this profile.');
|
|
125
|
+
return this.individual.service.ingestCommunicationAndUpdateIndex(input.communicationPayload, ctx.providerDid, ctx.requiredScope || '', ctx.idToken, input.pathFormatSegment);
|
|
126
|
+
},
|
|
127
|
+
generateDigitalTwinFromSubjectData: (ctx, input) => {
|
|
128
|
+
if (!this.individual?.service)
|
|
129
|
+
throw new Error('individual.service is not available for this profile.');
|
|
130
|
+
return this.individual.service.generateDigitalTwinFromSubjectData(input.compositionPayload, ctx.providerDid, ctx.requiredScope || '', ctx.idToken, input.format).then((result) => createSyntheticSubmitAndPollResult(result.thid));
|
|
131
|
+
},
|
|
132
|
+
searchClinicalBundle: (ctx, input) => {
|
|
133
|
+
if (!this.individual?.service)
|
|
134
|
+
throw new Error('individual.service is not available for this profile.');
|
|
135
|
+
return this.individual.service.searchClinicalBundle(input, ctx.providerDid, ctx.requiredScope || '', ctx.idToken);
|
|
136
|
+
},
|
|
137
|
+
getLatestIps: (ctx, subject) => {
|
|
138
|
+
if (!this.individual?.service)
|
|
139
|
+
throw new Error('individual.service is not available for this profile.');
|
|
140
|
+
return this.individual.service.getLatestIps(subject, ctx.providerDid, ctx.requiredScope || '', ctx.idToken);
|
|
141
|
+
},
|
|
142
|
+
submitAndPoll: async (_submitPath, _pollPath, payload) => createSyntheticSubmitAndPollResult(String(payload.thid || `front-${Date.now()}`)),
|
|
143
|
+
};
|
|
24
144
|
}
|
|
25
145
|
/**
|
|
26
146
|
* Organization-admin helper for employee/professional creation.
|
|
@@ -67,6 +187,41 @@ export class ProfileManager {
|
|
|
67
187
|
}
|
|
68
188
|
return this.individual.service.generateDigitalTwinFromSubjectData(params.compositionPayload, params.providerDid, params.requiredScope, params.idToken, params.format);
|
|
69
189
|
}
|
|
190
|
+
asHostOnboarding() {
|
|
191
|
+
if (!this.orgAdmin?.admin)
|
|
192
|
+
throw new Error('HostOnboardingSdk is not available for this profile.');
|
|
193
|
+
return new HostOnboardingSdk(this.runtimeClient);
|
|
194
|
+
}
|
|
195
|
+
asOrganizationController() {
|
|
196
|
+
if (!this.orgAdmin?.admin)
|
|
197
|
+
throw new Error('OrganizationControllerSdk is not available for this profile.');
|
|
198
|
+
return new OrganizationControllerSdk(this.runtimeClient);
|
|
199
|
+
}
|
|
200
|
+
asOrganizationEmployee() {
|
|
201
|
+
return new OrganizationEmployeeSdk(this.runtimeClient);
|
|
202
|
+
}
|
|
203
|
+
asIndividualController() {
|
|
204
|
+
if (!this.familyAdmin?.admin)
|
|
205
|
+
throw new Error('IndividualControllerSdk is not available for this profile.');
|
|
206
|
+
return new IndividualControllerSdk(this.runtimeClient);
|
|
207
|
+
}
|
|
208
|
+
asIndividualMember() {
|
|
209
|
+
if (!this.individual?.service)
|
|
210
|
+
throw new Error('IndividualMemberSdk is not available for this profile.');
|
|
211
|
+
return new IndividualMemberSdk(this.runtimeClient);
|
|
212
|
+
}
|
|
213
|
+
asPersonal() {
|
|
214
|
+
if (!this.familyAdmin?.admin && !this.individual?.service) {
|
|
215
|
+
throw new Error('PersonalSdk is not available for this profile.');
|
|
216
|
+
}
|
|
217
|
+
return new PersonalSdk(this.runtimeClient);
|
|
218
|
+
}
|
|
219
|
+
asProfessional() {
|
|
220
|
+
if (!this.professional?.physician && !this.professional?.paramedic && !this.individual?.service) {
|
|
221
|
+
throw new Error('ProfessionalSdk is not available for this profile.');
|
|
222
|
+
}
|
|
223
|
+
return new ProfessionalSdk(this.runtimeClient);
|
|
224
|
+
}
|
|
70
225
|
}
|
|
71
226
|
/**
|
|
72
227
|
* Preferred neutral frontend actor-session surface.
|
package/dist/index.d.ts
CHANGED
|
@@ -12,3 +12,11 @@ export * from './ProfileManager.js';
|
|
|
12
12
|
export * from './ProfileRegistry.js';
|
|
13
13
|
export * from './ClientSDK.js';
|
|
14
14
|
export * from './discovery/index.js';
|
|
15
|
+
export * from './orchestration/client-port.js';
|
|
16
|
+
export * from './orchestration/host-onboarding-sdk.js';
|
|
17
|
+
export * from './orchestration/organization-controller-sdk.js';
|
|
18
|
+
export * from './orchestration/organization-employee-sdk.js';
|
|
19
|
+
export * from './orchestration/individual-controller-sdk.js';
|
|
20
|
+
export * from './orchestration/individual-member-sdk.js';
|
|
21
|
+
export * from './orchestration/personal-sdk.js';
|
|
22
|
+
export * from './orchestration/professional-sdk.js';
|
package/dist/index.js
CHANGED
|
@@ -13,3 +13,11 @@ export * from './ProfileManager.js';
|
|
|
13
13
|
export * from './ProfileRegistry.js';
|
|
14
14
|
export * from './ClientSDK.js';
|
|
15
15
|
export * from './discovery/index.js';
|
|
16
|
+
export * from './orchestration/client-port.js';
|
|
17
|
+
export * from './orchestration/host-onboarding-sdk.js';
|
|
18
|
+
export * from './orchestration/organization-controller-sdk.js';
|
|
19
|
+
export * from './orchestration/organization-employee-sdk.js';
|
|
20
|
+
export * from './orchestration/individual-controller-sdk.js';
|
|
21
|
+
export * from './orchestration/individual-member-sdk.js';
|
|
22
|
+
export * from './orchestration/personal-sdk.js';
|
|
23
|
+
export * from './orchestration/professional-sdk.js';
|