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
package/dist/index.d.ts
CHANGED
|
@@ -2,15 +2,22 @@ export * from 'gdc-sdk-core-ts';
|
|
|
2
2
|
export * from './runtime-contracts.js';
|
|
3
3
|
export * from './identity-bootstrap.js';
|
|
4
4
|
export * from './async-polling.js';
|
|
5
|
+
export * from './backend-profile-runtime.js';
|
|
6
|
+
export * from './individual-controller-backend-runtime.js';
|
|
7
|
+
export * from './organization-controller-backend-runtime.js';
|
|
8
|
+
export * from './professional-backend-runtime.js';
|
|
5
9
|
export * from './poll-options.js';
|
|
6
10
|
export * from './host-onboarding.js';
|
|
7
11
|
export * from './individual-start.js';
|
|
12
|
+
export * from './family-organization-search.js';
|
|
13
|
+
export * from './family-organization-registration.js';
|
|
8
14
|
export * from './individual-onboarding.js';
|
|
9
15
|
export * from './device-activation.js';
|
|
10
16
|
export * from './smart-token.js';
|
|
11
17
|
export * from './order-offer-summary.js';
|
|
12
18
|
export * from './organization-license-order.js';
|
|
13
19
|
export * from './resource-operations.js';
|
|
20
|
+
export * from './profile-workspace.js';
|
|
14
21
|
export * from './constants/lifecycle.js';
|
|
15
22
|
export * from './consent-claim-helpers.js';
|
|
16
23
|
export * from './session.js';
|
package/dist/index.js
CHANGED
|
@@ -3,15 +3,22 @@ export * from 'gdc-sdk-core-ts';
|
|
|
3
3
|
export * from './runtime-contracts.js';
|
|
4
4
|
export * from './identity-bootstrap.js';
|
|
5
5
|
export * from './async-polling.js';
|
|
6
|
+
export * from './backend-profile-runtime.js';
|
|
7
|
+
export * from './individual-controller-backend-runtime.js';
|
|
8
|
+
export * from './organization-controller-backend-runtime.js';
|
|
9
|
+
export * from './professional-backend-runtime.js';
|
|
6
10
|
export * from './poll-options.js';
|
|
7
11
|
export * from './host-onboarding.js';
|
|
8
12
|
export * from './individual-start.js';
|
|
13
|
+
export * from './family-organization-search.js';
|
|
14
|
+
export * from './family-organization-registration.js';
|
|
9
15
|
export * from './individual-onboarding.js';
|
|
10
16
|
export * from './device-activation.js';
|
|
11
17
|
export * from './smart-token.js';
|
|
12
18
|
export * from './order-offer-summary.js';
|
|
13
19
|
export * from './organization-license-order.js';
|
|
14
20
|
export * from './resource-operations.js';
|
|
21
|
+
export * from './profile-workspace.js';
|
|
15
22
|
export * from './constants/lifecycle.js';
|
|
16
23
|
export * from './consent-claim-helpers.js';
|
|
17
24
|
export * from './session.js';
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { SubmitAndPollResult } from 'gdc-sdk-core-ts';
|
|
2
|
+
import type { FamilyOrganizationSummary } from 'gdc-common-utils-ts/utils/family-organization-summary';
|
|
3
|
+
import type { IndividualOrganizationConfirmOrderInput, RouteContext } from './individual-onboarding.js';
|
|
4
|
+
import type { IndividualOrganizationBootstrapInput, IndividualOrganizationStartResult } from './individual-start.js';
|
|
5
|
+
import type { EnsureFamilyOrganizationRegistrationInput, EnsureFamilyOrganizationRegistrationResult } from './family-organization-registration.js';
|
|
6
|
+
import type { FamilyOrganizationSearchInput } from './family-organization-search.js';
|
|
7
|
+
import type { ClinicalBundleSearchInput } from './resource-operations.js';
|
|
8
|
+
import { type BackendIndividualControllerProfile, type BackendProfileRuntimeClient } from './backend-profile-runtime.js';
|
|
9
|
+
import type { ProfileLoadRequest } from 'gdc-sdk-core-ts';
|
|
10
|
+
/**
|
|
11
|
+
* Backend use-case facade for the current individual-controller baseline.
|
|
12
|
+
*
|
|
13
|
+
* This class does not redefine the generic backend profile runtime. It wraps
|
|
14
|
+
* that runtime with the current stable CORE-facing actions that backend
|
|
15
|
+
* consumers need first:
|
|
16
|
+
*
|
|
17
|
+
* - load an individual-controller profile
|
|
18
|
+
* - start individual registration/bootstrap
|
|
19
|
+
* - confirm the returned order/offer
|
|
20
|
+
* - search the subject clinical index
|
|
21
|
+
* - request the latest IPS-oriented bundle
|
|
22
|
+
*/
|
|
23
|
+
export declare class IndividualControllerBackendRuntime {
|
|
24
|
+
private readonly profileRuntime;
|
|
25
|
+
constructor(profileRuntime: BackendProfileRuntimeClient);
|
|
26
|
+
/**
|
|
27
|
+
* Loads one individual-controller backend profile and materializes its actor
|
|
28
|
+
* facade in one step.
|
|
29
|
+
*/
|
|
30
|
+
loadProfile(input: ProfileLoadRequest): Promise<BackendIndividualControllerProfile>;
|
|
31
|
+
/**
|
|
32
|
+
* Starts the current CORE individual/family bootstrap flow.
|
|
33
|
+
*/
|
|
34
|
+
startIndividualOrganization(profile: BackendIndividualControllerProfile, input: IndividualOrganizationBootstrapInput): Promise<IndividualOrganizationStartResult>;
|
|
35
|
+
/**
|
|
36
|
+
* Searches one existing family/individual registration before deciding
|
|
37
|
+
* whether the backend should create or resume it.
|
|
38
|
+
*/
|
|
39
|
+
searchFamilyOrganization(profile: BackendIndividualControllerProfile, ctx: RouteContext, input: FamilyOrganizationSearchInput): Promise<FamilyOrganizationSummary | null>;
|
|
40
|
+
/**
|
|
41
|
+
* High-level onboarding gate for channel apps:
|
|
42
|
+
* search the registration first and only bootstrap when still missing.
|
|
43
|
+
*/
|
|
44
|
+
ensureFamilyOrganizationRegistration(profile: BackendIndividualControllerProfile, ctx: RouteContext, input: EnsureFamilyOrganizationRegistrationInput): Promise<EnsureFamilyOrganizationRegistrationResult>;
|
|
45
|
+
/**
|
|
46
|
+
* Confirms the order returned by the individual bootstrap flow.
|
|
47
|
+
*/
|
|
48
|
+
confirmIndividualOrganizationOrder(profile: BackendIndividualControllerProfile, input: IndividualOrganizationConfirmOrderInput): Promise<SubmitAndPollResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Searches the current subject clinical bundle index through the loaded
|
|
51
|
+
* individual-controller facade.
|
|
52
|
+
*/
|
|
53
|
+
searchClinicalBundle(profile: BackendIndividualControllerProfile, ctx: RouteContext, input: ClinicalBundleSearchInput): Promise<SubmitAndPollResult>;
|
|
54
|
+
/**
|
|
55
|
+
* Reads the latest IPS-oriented bundle through the loaded
|
|
56
|
+
* individual-controller facade.
|
|
57
|
+
*/
|
|
58
|
+
getLatestIps(profile: BackendIndividualControllerProfile, ctx: RouteContext, input: Omit<ClinicalBundleSearchInput, 'includedTypes'>): Promise<SubmitAndPollResult>;
|
|
59
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
+
import { loadBackendIndividualControllerProfile, } from './backend-profile-runtime.js';
|
|
3
|
+
/**
|
|
4
|
+
* Backend use-case facade for the current individual-controller baseline.
|
|
5
|
+
*
|
|
6
|
+
* This class does not redefine the generic backend profile runtime. It wraps
|
|
7
|
+
* that runtime with the current stable CORE-facing actions that backend
|
|
8
|
+
* consumers need first:
|
|
9
|
+
*
|
|
10
|
+
* - load an individual-controller profile
|
|
11
|
+
* - start individual registration/bootstrap
|
|
12
|
+
* - confirm the returned order/offer
|
|
13
|
+
* - search the subject clinical index
|
|
14
|
+
* - request the latest IPS-oriented bundle
|
|
15
|
+
*/
|
|
16
|
+
export class IndividualControllerBackendRuntime {
|
|
17
|
+
constructor(profileRuntime) {
|
|
18
|
+
this.profileRuntime = profileRuntime;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Loads one individual-controller backend profile and materializes its actor
|
|
22
|
+
* facade in one step.
|
|
23
|
+
*/
|
|
24
|
+
loadProfile(input) {
|
|
25
|
+
return loadBackendIndividualControllerProfile(this.profileRuntime, input);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Starts the current CORE individual/family bootstrap flow.
|
|
29
|
+
*/
|
|
30
|
+
startIndividualOrganization(profile, input) {
|
|
31
|
+
return profile.sdk.startIndividualOrganization(input);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Searches one existing family/individual registration before deciding
|
|
35
|
+
* whether the backend should create or resume it.
|
|
36
|
+
*/
|
|
37
|
+
searchFamilyOrganization(profile, ctx, input) {
|
|
38
|
+
return profile.sdk.searchFamilyOrganization(ctx, input);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* High-level onboarding gate for channel apps:
|
|
42
|
+
* search the registration first and only bootstrap when still missing.
|
|
43
|
+
*/
|
|
44
|
+
ensureFamilyOrganizationRegistration(profile, ctx, input) {
|
|
45
|
+
return profile.sdk.ensureFamilyOrganizationRegistration(ctx, input);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Confirms the order returned by the individual bootstrap flow.
|
|
49
|
+
*/
|
|
50
|
+
confirmIndividualOrganizationOrder(profile, input) {
|
|
51
|
+
return profile.sdk.confirmIndividualOrganizationOrder(input);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Searches the current subject clinical bundle index through the loaded
|
|
55
|
+
* individual-controller facade.
|
|
56
|
+
*/
|
|
57
|
+
searchClinicalBundle(profile, ctx, input) {
|
|
58
|
+
return profile.sdk.searchClinicalBundle(ctx, input);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Reads the latest IPS-oriented bundle through the loaded
|
|
62
|
+
* individual-controller facade.
|
|
63
|
+
*/
|
|
64
|
+
getLatestIps(profile, ctx, input) {
|
|
65
|
+
return profile.sdk.getLatestIps(ctx, input);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { LegalOrganizationVerificationRouting, LegalOrganizationVerificationTransactionController, LegalOrganizationVerificationTransactionInput, LegalOrganizationVerificationTransactionOrganization, LegalOrganizationVerificationRepresentativePayload } from 'gdc-common-utils-ts/utils/legal-organization-verification-transaction';
|
|
2
|
+
import type { NodeOrganizationActivationInput } from './orchestration/client-port.js';
|
|
3
|
+
export type LegalOrganizationFormFields = Readonly<{
|
|
4
|
+
legalName?: string;
|
|
5
|
+
legalIdentifierType?: string;
|
|
6
|
+
legalIdentifierValue?: string;
|
|
7
|
+
taxId?: string;
|
|
8
|
+
addressCountry?: string;
|
|
9
|
+
controllerEmail?: string;
|
|
10
|
+
controllerRole?: string;
|
|
11
|
+
serviceCategory?: string;
|
|
12
|
+
serviceIdentifier?: string;
|
|
13
|
+
serviceUrl?: string;
|
|
14
|
+
}>;
|
|
15
|
+
export type LegalOrganizationOnboardingValidationIssue = Readonly<{
|
|
16
|
+
severity: 'error' | 'warning';
|
|
17
|
+
code: string;
|
|
18
|
+
message: string;
|
|
19
|
+
field?: keyof LegalOrganizationFormFields | 'claims' | string;
|
|
20
|
+
}>;
|
|
21
|
+
export type LegalOrganizationOnboardingValidationResult = Readonly<{
|
|
22
|
+
ok: boolean;
|
|
23
|
+
errors: LegalOrganizationOnboardingValidationIssue[];
|
|
24
|
+
warnings: LegalOrganizationOnboardingValidationIssue[];
|
|
25
|
+
normalizedClaims: Record<string, unknown>;
|
|
26
|
+
}>;
|
|
27
|
+
export interface LegalOrganizationOnboardingEditor {
|
|
28
|
+
setLegalName(value: string): LegalOrganizationOnboardingEditor;
|
|
29
|
+
setLegalIdentifierType(value: string): LegalOrganizationOnboardingEditor;
|
|
30
|
+
setLegalIdentifierValue(value: string): LegalOrganizationOnboardingEditor;
|
|
31
|
+
setTaxId(value: string): LegalOrganizationOnboardingEditor;
|
|
32
|
+
setAddressCountry(value: string): LegalOrganizationOnboardingEditor;
|
|
33
|
+
setControllerEmail(value: string): LegalOrganizationOnboardingEditor;
|
|
34
|
+
setControllerRole(value: string): LegalOrganizationOnboardingEditor;
|
|
35
|
+
setServiceCategory(value: string): LegalOrganizationOnboardingEditor;
|
|
36
|
+
setServiceIdentifier(value: string): LegalOrganizationOnboardingEditor;
|
|
37
|
+
setServiceUrl(value: string): LegalOrganizationOnboardingEditor;
|
|
38
|
+
getFormFields(): LegalOrganizationFormFields;
|
|
39
|
+
buildClaims(): Record<string, unknown>;
|
|
40
|
+
validate(): LegalOrganizationOnboardingValidationResult;
|
|
41
|
+
buildVerificationTransactionInput(input: Readonly<{
|
|
42
|
+
controller: LegalOrganizationVerificationTransactionController;
|
|
43
|
+
organization?: LegalOrganizationVerificationTransactionOrganization;
|
|
44
|
+
legalRepresentativePayload?: LegalOrganizationVerificationRepresentativePayload;
|
|
45
|
+
verification?: LegalOrganizationVerificationRouting;
|
|
46
|
+
attachments?: unknown[];
|
|
47
|
+
}>): LegalOrganizationVerificationTransactionInput;
|
|
48
|
+
buildActivationInput(input: Readonly<{
|
|
49
|
+
vpToken: string;
|
|
50
|
+
controller: LegalOrganizationVerificationTransactionController;
|
|
51
|
+
capabilities?: readonly string[];
|
|
52
|
+
}>): NodeOrganizationActivationInput;
|
|
53
|
+
}
|
|
54
|
+
export interface LegalOrganizationOnboardingFacade {
|
|
55
|
+
createDraft(initial?: LegalOrganizationFormFields): LegalOrganizationFormFields;
|
|
56
|
+
createEditor(initial?: LegalOrganizationFormFields): LegalOrganizationOnboardingEditor;
|
|
57
|
+
setLegalName(fields: LegalOrganizationFormFields, value: string): LegalOrganizationFormFields;
|
|
58
|
+
setLegalIdentifierType(fields: LegalOrganizationFormFields, value: string): LegalOrganizationFormFields;
|
|
59
|
+
setLegalIdentifierValue(fields: LegalOrganizationFormFields, value: string): LegalOrganizationFormFields;
|
|
60
|
+
setTaxId(fields: LegalOrganizationFormFields, value: string): LegalOrganizationFormFields;
|
|
61
|
+
setAddressCountry(fields: LegalOrganizationFormFields, value: string): LegalOrganizationFormFields;
|
|
62
|
+
setControllerEmail(fields: LegalOrganizationFormFields, value: string): LegalOrganizationFormFields;
|
|
63
|
+
setControllerRole(fields: LegalOrganizationFormFields, value: string): LegalOrganizationFormFields;
|
|
64
|
+
setServiceCategory(fields: LegalOrganizationFormFields, value: string): LegalOrganizationFormFields;
|
|
65
|
+
setServiceIdentifier(fields: LegalOrganizationFormFields, value: string): LegalOrganizationFormFields;
|
|
66
|
+
setServiceUrl(fields: LegalOrganizationFormFields, value: string): LegalOrganizationFormFields;
|
|
67
|
+
buildClaims(fields: LegalOrganizationFormFields): Record<string, unknown>;
|
|
68
|
+
validate(fields: LegalOrganizationFormFields): LegalOrganizationOnboardingValidationResult;
|
|
69
|
+
}
|
|
70
|
+
export declare function createLegalOrganizationOnboardingFacade(): LegalOrganizationOnboardingFacade;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
+
import { ClaimsOrganizationSchemaorg, ClaimsPersonSchemaorg, ClaimsServiceSchemaorg, } from 'gdc-common-utils-ts/constants/schemaorg';
|
|
3
|
+
import { ServiceCapability } from 'gdc-common-utils-ts/constants/service-capabilities';
|
|
4
|
+
import { validateLegalOrganizationOnboardingClaims, } from 'gdc-common-utils-ts/utils/legal-organization-onboarding';
|
|
5
|
+
function normalizeText(value) {
|
|
6
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
7
|
+
}
|
|
8
|
+
function normalizeOptionalText(value) {
|
|
9
|
+
const normalized = normalizeText(value);
|
|
10
|
+
return normalized || undefined;
|
|
11
|
+
}
|
|
12
|
+
function cloneFields(fields) {
|
|
13
|
+
return { ...(fields || {}) };
|
|
14
|
+
}
|
|
15
|
+
function patchFields(fields, patch) {
|
|
16
|
+
return {
|
|
17
|
+
...cloneFields(fields),
|
|
18
|
+
...patch,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function createIssues(fields) {
|
|
22
|
+
const issues = [];
|
|
23
|
+
if (!normalizeOptionalText(fields.legalName)) {
|
|
24
|
+
issues.push({ severity: 'error', code: 'missing-legal-name', message: 'Legal organization name is required.', field: 'legalName' });
|
|
25
|
+
}
|
|
26
|
+
if (!normalizeOptionalText(fields.legalIdentifierType)) {
|
|
27
|
+
issues.push({ severity: 'error', code: 'missing-legal-identifier-type', message: 'Legal identifier type is required.', field: 'legalIdentifierType' });
|
|
28
|
+
}
|
|
29
|
+
if (!normalizeOptionalText(fields.addressCountry)) {
|
|
30
|
+
issues.push({ severity: 'error', code: 'missing-address-country', message: 'Address country is required.', field: 'addressCountry' });
|
|
31
|
+
}
|
|
32
|
+
if (!normalizeOptionalText(fields.controllerEmail)) {
|
|
33
|
+
issues.push({ severity: 'error', code: 'missing-controller-email', message: 'Controller email is required.', field: 'controllerEmail' });
|
|
34
|
+
}
|
|
35
|
+
if (!normalizeOptionalText(fields.serviceCategory)) {
|
|
36
|
+
issues.push({ severity: 'error', code: 'missing-service-category', message: 'Service category is required.', field: 'serviceCategory' });
|
|
37
|
+
}
|
|
38
|
+
return issues;
|
|
39
|
+
}
|
|
40
|
+
function createEditorFromFacade(facade, initial) {
|
|
41
|
+
let formFields = facade.createDraft(initial);
|
|
42
|
+
const editor = {
|
|
43
|
+
setLegalName(value) { formFields = facade.setLegalName(formFields, value); return editor; },
|
|
44
|
+
setLegalIdentifierType(value) { formFields = facade.setLegalIdentifierType(formFields, value); return editor; },
|
|
45
|
+
setLegalIdentifierValue(value) { formFields = facade.setLegalIdentifierValue(formFields, value); return editor; },
|
|
46
|
+
setTaxId(value) { formFields = facade.setTaxId(formFields, value); return editor; },
|
|
47
|
+
setAddressCountry(value) { formFields = facade.setAddressCountry(formFields, value); return editor; },
|
|
48
|
+
setControllerEmail(value) { formFields = facade.setControllerEmail(formFields, value); return editor; },
|
|
49
|
+
setControllerRole(value) { formFields = facade.setControllerRole(formFields, value); return editor; },
|
|
50
|
+
setServiceCategory(value) { formFields = facade.setServiceCategory(formFields, value); return editor; },
|
|
51
|
+
setServiceIdentifier(value) { formFields = facade.setServiceIdentifier(formFields, value); return editor; },
|
|
52
|
+
setServiceUrl(value) { formFields = facade.setServiceUrl(formFields, value); return editor; },
|
|
53
|
+
getFormFields() { return cloneFields(formFields); },
|
|
54
|
+
buildClaims() { return facade.buildClaims(formFields); },
|
|
55
|
+
validate() { return facade.validate(formFields); },
|
|
56
|
+
buildVerificationTransactionInput(input) {
|
|
57
|
+
return {
|
|
58
|
+
claims: facade.buildClaims(formFields),
|
|
59
|
+
controller: input.controller,
|
|
60
|
+
...(input.organization ? { organization: input.organization } : {}),
|
|
61
|
+
...(input.legalRepresentativePayload ? { legalRepresentativePayload: input.legalRepresentativePayload } : {}),
|
|
62
|
+
...(input.verification ? { verification: input.verification } : {}),
|
|
63
|
+
...(input.attachments ? { attachments: input.attachments } : {}),
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
buildActivationInput(input) {
|
|
67
|
+
const claims = facade.buildClaims(formFields);
|
|
68
|
+
const service = {
|
|
69
|
+
url: String(claims[ClaimsServiceSchemaorg.url] || '').trim() || undefined,
|
|
70
|
+
capabilities: [...new Set((input.capabilities || [ServiceCapability.IndexProvider, ServiceCapability.DigitalTwinReader])
|
|
71
|
+
.map((item) => String(item || '').trim())
|
|
72
|
+
.filter(Boolean))],
|
|
73
|
+
};
|
|
74
|
+
return {
|
|
75
|
+
vpToken: input.vpToken,
|
|
76
|
+
controller: input.controller,
|
|
77
|
+
service,
|
|
78
|
+
additionalClaims: claims,
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
return editor;
|
|
83
|
+
}
|
|
84
|
+
export function createLegalOrganizationOnboardingFacade() {
|
|
85
|
+
return {
|
|
86
|
+
createDraft(initial = {}) {
|
|
87
|
+
return cloneFields(initial);
|
|
88
|
+
},
|
|
89
|
+
createEditor(initial = {}) {
|
|
90
|
+
return createEditorFromFacade(this, initial);
|
|
91
|
+
},
|
|
92
|
+
setLegalName(fields, value) {
|
|
93
|
+
return patchFields(fields, { legalName: normalizeOptionalText(value) });
|
|
94
|
+
},
|
|
95
|
+
setLegalIdentifierType(fields, value) {
|
|
96
|
+
return patchFields(fields, { legalIdentifierType: normalizeOptionalText(value) });
|
|
97
|
+
},
|
|
98
|
+
setLegalIdentifierValue(fields, value) {
|
|
99
|
+
return patchFields(fields, { legalIdentifierValue: normalizeOptionalText(value) });
|
|
100
|
+
},
|
|
101
|
+
setTaxId(fields, value) {
|
|
102
|
+
return patchFields(fields, { taxId: normalizeOptionalText(value) });
|
|
103
|
+
},
|
|
104
|
+
setAddressCountry(fields, value) {
|
|
105
|
+
return patchFields(fields, { addressCountry: normalizeOptionalText(value) });
|
|
106
|
+
},
|
|
107
|
+
setControllerEmail(fields, value) {
|
|
108
|
+
const normalized = normalizeOptionalText(value);
|
|
109
|
+
return patchFields(fields, { controllerEmail: normalized?.toLowerCase() });
|
|
110
|
+
},
|
|
111
|
+
setControllerRole(fields, value) {
|
|
112
|
+
return patchFields(fields, { controllerRole: normalizeOptionalText(value) });
|
|
113
|
+
},
|
|
114
|
+
setServiceCategory(fields, value) {
|
|
115
|
+
return patchFields(fields, { serviceCategory: normalizeOptionalText(value) });
|
|
116
|
+
},
|
|
117
|
+
setServiceIdentifier(fields, value) {
|
|
118
|
+
return patchFields(fields, { serviceIdentifier: normalizeOptionalText(value) });
|
|
119
|
+
},
|
|
120
|
+
setServiceUrl(fields, value) {
|
|
121
|
+
return patchFields(fields, { serviceUrl: normalizeOptionalText(value) });
|
|
122
|
+
},
|
|
123
|
+
buildClaims(fields) {
|
|
124
|
+
const claims = {
|
|
125
|
+
'@context': 'org.schema',
|
|
126
|
+
};
|
|
127
|
+
if (normalizeOptionalText(fields.legalName))
|
|
128
|
+
claims[ClaimsOrganizationSchemaorg.legalName] = normalizeText(fields.legalName);
|
|
129
|
+
if (normalizeOptionalText(fields.legalIdentifierType))
|
|
130
|
+
claims[ClaimsOrganizationSchemaorg.identifierType] = normalizeText(fields.legalIdentifierType);
|
|
131
|
+
if (normalizeOptionalText(fields.legalIdentifierValue))
|
|
132
|
+
claims[ClaimsOrganizationSchemaorg.identifierValue] = normalizeText(fields.legalIdentifierValue);
|
|
133
|
+
if (normalizeOptionalText(fields.taxId))
|
|
134
|
+
claims[ClaimsOrganizationSchemaorg.taxId] = normalizeText(fields.taxId);
|
|
135
|
+
if (normalizeOptionalText(fields.addressCountry))
|
|
136
|
+
claims[ClaimsOrganizationSchemaorg.addressCountry] = normalizeText(fields.addressCountry);
|
|
137
|
+
if (normalizeOptionalText(fields.controllerEmail))
|
|
138
|
+
claims[ClaimsPersonSchemaorg.email] = normalizeText(fields.controllerEmail).toLowerCase();
|
|
139
|
+
if (normalizeOptionalText(fields.controllerRole))
|
|
140
|
+
claims[ClaimsPersonSchemaorg.hasOccupationalRoleValue] = normalizeText(fields.controllerRole);
|
|
141
|
+
if (normalizeOptionalText(fields.serviceCategory))
|
|
142
|
+
claims[ClaimsServiceSchemaorg.category] = normalizeText(fields.serviceCategory);
|
|
143
|
+
if (normalizeOptionalText(fields.serviceIdentifier))
|
|
144
|
+
claims[ClaimsServiceSchemaorg.identifier] = normalizeText(fields.serviceIdentifier);
|
|
145
|
+
if (normalizeOptionalText(fields.serviceUrl))
|
|
146
|
+
claims[ClaimsServiceSchemaorg.url] = normalizeText(fields.serviceUrl);
|
|
147
|
+
return validateLegalOrganizationOnboardingClaims(claims).normalizedClaims;
|
|
148
|
+
},
|
|
149
|
+
validate(fields) {
|
|
150
|
+
const normalizedClaims = this.buildClaims(fields);
|
|
151
|
+
const issues = createIssues(fields);
|
|
152
|
+
const sharedValidation = validateLegalOrganizationOnboardingClaims(normalizedClaims);
|
|
153
|
+
for (const error of sharedValidation.errors) {
|
|
154
|
+
issues.push({
|
|
155
|
+
severity: 'error',
|
|
156
|
+
code: error.code.toLowerCase(),
|
|
157
|
+
message: error.message,
|
|
158
|
+
field: error.claimPaths[0] || 'claims',
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
ok: !issues.some((issue) => issue.severity === 'error'),
|
|
163
|
+
errors: issues.filter((issue) => issue.severity === 'error'),
|
|
164
|
+
warnings: issues.filter((issue) => issue.severity === 'warning'),
|
|
165
|
+
normalizedClaims,
|
|
166
|
+
};
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
import type { OrganizationDidBindingInput } from 'gdc-sdk-core-ts';
|
|
1
2
|
import type { AppInfo } from 'gdc-sdk-core-ts';
|
|
2
3
|
import { type ResolvedAppInfo } from 'gdc-sdk-core-ts';
|
|
3
4
|
import { type HostRouteContext, type HostedTenantLifecycleInput } from './host-onboarding.js';
|
|
4
|
-
import type { NodeOrganizationActivationInput } from './orchestration/client-port.js';
|
|
5
|
+
import type { NodeLegalOrganizationVerificationTransactionInput, NodeOrganizationDidBindingInput, NodeOrganizationActivationInput } from './orchestration/client-port.js';
|
|
5
6
|
import { type IndividualOrganizationConfirmOrderInput, type RouteContext } from './individual-onboarding.js';
|
|
7
|
+
import { type EnsureFamilyOrganizationRegistrationInput } from './family-organization-registration.js';
|
|
8
|
+
import { type FamilyOrganizationSearchInput } from './family-organization-search.js';
|
|
6
9
|
import { type SmartTokenRequestInput } from './smart-token.js';
|
|
7
10
|
import { type OrganizationLicenseOrderConfirmInput } from './organization-license-order.js';
|
|
8
11
|
import { type IndividualOrganizationBootstrapInput, type IndividualOrganizationStartResult } from './individual-start.js';
|
|
9
|
-
import { type CommunicationIngestionInput, type ClinicalBundleSearchInput, type GrantProfessionalAccessInput, type GrantProfessionalAccessResult, type IndividualMemberLifecycleInput, type IndividualOrganizationLifecycleInput, type LicenseListRuntimeSearchInput, type LicenseOfferRuntimeSearchInput, type LicenseOrderRuntimeSearchInput, type OrganizationEmployeeCreationInput, type OrganizationEmployeeLifecycleInput, type OrganizationEmployeeSearchInput, type RelatedPersonUpsertInput } from './resource-operations.js';
|
|
12
|
+
import { type CommunicationIngestionInput, type CommunicationParticipantRuntimeSearchInput, type ClinicalBundleSearchInput, type GrantProfessionalAccessInput, type GrantProfessionalAccessResult, type IndividualMemberLifecycleInput, type IndividualOrganizationLifecycleInput, type LicenseListRuntimeSearchInput, type LicenseOfferRuntimeSearchInput, type LicenseOrderRuntimeSearchInput, type OrganizationEmployeeCreationInput, type OrganizationEmployeeLifecycleInput, type OrganizationEmployeeSearchInput, type RevokeProfessionalAccessInput, type RevokeProfessionalAccessResult, type RelatedPersonUpsertInput } from './resource-operations.js';
|
|
10
13
|
import type { LegalOrganizationOrderInput } from './host-onboarding.js';
|
|
11
14
|
import type { SmartTokenExchangeResult } from './smart-token.js';
|
|
12
15
|
import type { NodeRuntimeClient, PollOptions, PollResult, SubmitAndPollResult, SubmitPayload, SubmitResponse } from './orchestration/client-port.js';
|
|
@@ -109,9 +112,46 @@ export declare class HttpRuntimeClient implements NodeRuntimeClient {
|
|
|
109
112
|
* Convenience wrapper that performs submit and poll in sequence.
|
|
110
113
|
*/
|
|
111
114
|
submitAndPoll(submitPath: string, pollPath: string, payload: SubmitPayload, pollOptions?: PollOptions): Promise<SubmitAndPollResult>;
|
|
115
|
+
/**
|
|
116
|
+
* Starts the host-side legal-organization verification transaction that GW
|
|
117
|
+
* CORE forwards to ICA `_verify`.
|
|
118
|
+
*
|
|
119
|
+
* Runtime ownership:
|
|
120
|
+
* - builds the canonical shared business bundle from `sdk-core/common-utils`
|
|
121
|
+
* - keeps communication/runtime transport concerns at the outer message layer
|
|
122
|
+
* - keeps the controller business key inside the submitted bundle payload
|
|
123
|
+
*
|
|
124
|
+
* Flow separation:
|
|
125
|
+
* - `_transaction` is the new host onboarding step
|
|
126
|
+
* - this runtime does not chain `_activate` after `_transaction`
|
|
127
|
+
* - `_activate` remains available only for the older ICA `_verify` based flow
|
|
128
|
+
*/
|
|
129
|
+
submitLegalOrganizationVerificationTransaction(hostCtx: HostRouteContext, input: NodeLegalOrganizationVerificationTransactionInput, pollOptions?: PollOptions): Promise<SubmitAndPollResult>;
|
|
130
|
+
/**
|
|
131
|
+
* Submits one tenant-scoped DID document binding request.
|
|
132
|
+
*
|
|
133
|
+
* Binding semantics:
|
|
134
|
+
* - the tenant path identifies the existing organization
|
|
135
|
+
* - `organization.url` carries the public alias/domain list
|
|
136
|
+
* - `controller.sameAs` is optional corroborating identity material
|
|
137
|
+
* - the flow does not rotate or replace organization public keys
|
|
138
|
+
*/
|
|
139
|
+
submitOrganizationDidBinding(ctx: RouteContext, input: NodeOrganizationDidBindingInput | OrganizationDidBindingInput, pollOptions?: PollOptions): Promise<SubmitAndPollResult>;
|
|
112
140
|
/**
|
|
113
141
|
* Activates a legal organization in the gateway host registry using an ICA
|
|
114
142
|
* proof token already obtained by the caller.
|
|
143
|
+
*
|
|
144
|
+
* Plaintext transport note:
|
|
145
|
+
* - this Node runtime currently submits `_activate` as
|
|
146
|
+
* `application/didcomm-plain+json`
|
|
147
|
+
* - because there is no real outer JWS/JWE envelope in that mode, the
|
|
148
|
+
* runtime mirrors the technical communication metadata derived from
|
|
149
|
+
* `controller.publicKeyJwk` / `controller.jwks` into `meta.jws.protected`
|
|
150
|
+
* and `meta.jwe.header`
|
|
151
|
+
* - secure JOSE transports should carry those values in the real protected
|
|
152
|
+
* headers instead of plaintext `meta`
|
|
153
|
+
* - this mirrored metadata is transport fallback only; the canonical
|
|
154
|
+
* activation contract remains `body.vp_token` plus `body.controller.*`
|
|
115
155
|
*/
|
|
116
156
|
activateOrganizationInGatewayFromIcaProof(hostCtx: HostRouteContext, input: NodeOrganizationActivationInput, pollOptions?: PollOptions): Promise<SubmitAndPollResult>;
|
|
117
157
|
/**
|
|
@@ -196,6 +236,27 @@ export declare class HttpRuntimeClient implements NodeRuntimeClient {
|
|
|
196
236
|
* Starts the onboarding flow for an individual-oriented tenant or index.
|
|
197
237
|
*/
|
|
198
238
|
startIndividualOrganization(input: IndividualOrganizationBootstrapInput): Promise<IndividualOrganizationStartResult>;
|
|
239
|
+
/**
|
|
240
|
+
* Searches one existing family/individual registration by controller phone +
|
|
241
|
+
* usualname, with optional birth-date disambiguation.
|
|
242
|
+
*/
|
|
243
|
+
searchFamilyOrganization(ctx: RouteContext, input: FamilyOrganizationSearchInput): Promise<Readonly<{
|
|
244
|
+
status: import("gdc-common-utils-ts").FamilyRegistrationStatus;
|
|
245
|
+
offerId?: string;
|
|
246
|
+
organizationId?: string;
|
|
247
|
+
subjectInfo?: import("gdc-common-utils-ts").FamilyOrganizationSubjectInfo;
|
|
248
|
+
missingFields?: string[];
|
|
249
|
+
updatedAt?: string;
|
|
250
|
+
}> | null>;
|
|
251
|
+
/**
|
|
252
|
+
* Searches one existing family/individual registration and starts the
|
|
253
|
+
* bootstrap flow only when the registration does not already exist.
|
|
254
|
+
*/
|
|
255
|
+
ensureFamilyOrganizationRegistration(ctx: RouteContext, input: EnsureFamilyOrganizationRegistrationInput): Promise<Readonly<{
|
|
256
|
+
status: "already_exists" | "resume_required" | "new_created";
|
|
257
|
+
summary?: import("gdc-common-utils-ts").FamilyOrganizationSummary;
|
|
258
|
+
started?: IndividualOrganizationStartResult;
|
|
259
|
+
}>>;
|
|
199
260
|
/**
|
|
200
261
|
* Confirms the order returned by `startIndividualOrganization(...)`.
|
|
201
262
|
*/
|
|
@@ -252,6 +313,11 @@ export declare class HttpRuntimeClient implements NodeRuntimeClient {
|
|
|
252
313
|
* Creates and submits a consent-oriented access grant for a professional actor.
|
|
253
314
|
*/
|
|
254
315
|
grantProfessionalAccess(ctx: RouteContext, input: GrantProfessionalAccessInput): Promise<GrantProfessionalAccessResult>;
|
|
316
|
+
/**
|
|
317
|
+
* Closes an existing professional consent by setting its period end and
|
|
318
|
+
* resubmitting the updated consent resource.
|
|
319
|
+
*/
|
|
320
|
+
revokeProfessionalAccess(ctx: RouteContext, input: RevokeProfessionalAccessInput): Promise<RevokeProfessionalAccessResult>;
|
|
255
321
|
/**
|
|
256
322
|
* Requests SMART/OpenID token material through the gateway.
|
|
257
323
|
*
|
|
@@ -274,6 +340,11 @@ export declare class HttpRuntimeClient implements NodeRuntimeClient {
|
|
|
274
340
|
* @param input Communication payload plus route/format options.
|
|
275
341
|
*/
|
|
276
342
|
ingestCommunicationAndUpdateIndex(ctx: RouteContext, input: CommunicationIngestionInput): Promise<SubmitAndPollResult>;
|
|
343
|
+
/**
|
|
344
|
+
* Searches communication channel records by subject and participant
|
|
345
|
+
* identifiers through `Communication/_search`.
|
|
346
|
+
*/
|
|
347
|
+
searchCommunicationParticipants(ctx: RouteContext, input: CommunicationParticipantRuntimeSearchInput): Promise<SubmitAndPollResult>;
|
|
277
348
|
/**
|
|
278
349
|
* Alias for `ingestCommunicationAndUpdateIndex(...)`.
|
|
279
350
|
*
|
|
@@ -319,8 +390,27 @@ export declare class HttpRuntimeClient implements NodeRuntimeClient {
|
|
|
319
390
|
private parseResponseBody;
|
|
320
391
|
private requireRouteContext;
|
|
321
392
|
private routeCtxFromInput;
|
|
393
|
+
/**
|
|
394
|
+
* Reuses the shared bundle business contract while keeping attachment
|
|
395
|
+
* transport fields at the DIDComm/plaintext message layer expected by GW.
|
|
396
|
+
*/
|
|
397
|
+
private wrapBundleAsGatewayTransactionMessage;
|
|
322
398
|
private hostRegistryPath;
|
|
399
|
+
/**
|
|
400
|
+
* Resolves the host route segment without forcing callers to remember whether
|
|
401
|
+
* the same raw string is named `hostNetwork` or `sector` in a given layer.
|
|
402
|
+
*
|
|
403
|
+
* Step by step:
|
|
404
|
+
* - host routes use `/host/cds-{jurisdiction}/v1/{host-network}`
|
|
405
|
+
* - tenant routes use `/{tenantId}/cds-{jurisdiction}/v1/{tenant-sector}`
|
|
406
|
+
* - older live tests and adapters sometimes passed the host segment under
|
|
407
|
+
* `sector`, which is semantically wrong for host routes
|
|
408
|
+
* - new code should prefer `hostNetwork`
|
|
409
|
+
* - compatibility code may pass `hostNetworkOrTenantSector`
|
|
410
|
+
*/
|
|
323
411
|
private requireHostRouteContext;
|
|
412
|
+
hostRegistryOrganizationTransactionPath(ctx?: HostRouteContext): string;
|
|
413
|
+
hostRegistryOrganizationTransactionPollPath(ctx?: HostRouteContext): string;
|
|
324
414
|
hostRegistryOrganizationActivatePath(ctx?: HostRouteContext): string;
|
|
325
415
|
hostRegistryOrganizationActivatePollPath(ctx?: HostRouteContext): string;
|
|
326
416
|
hostRegistryOrganizationDisablePath(ctx?: HostRouteContext): string;
|
|
@@ -335,6 +425,8 @@ export declare class HttpRuntimeClient implements NodeRuntimeClient {
|
|
|
335
425
|
employeeSearchPollPath(ctx?: RouteContext): string;
|
|
336
426
|
organizationLicenseSearchPath(ctx?: RouteContext): string;
|
|
337
427
|
organizationLicenseSearchPollPath(ctx?: RouteContext): string;
|
|
428
|
+
organizationDidBindingPath(ctx?: RouteContext): string;
|
|
429
|
+
organizationDidBindingPollPath(ctx?: RouteContext): string;
|
|
338
430
|
organizationLicenseOfferSearchPath(ctx?: RouteContext): string;
|
|
339
431
|
organizationLicenseOfferSearchPollPath(ctx?: RouteContext): string;
|
|
340
432
|
organizationLicenseOrderSearchPath(ctx?: RouteContext): string;
|
|
@@ -343,6 +435,8 @@ export declare class HttpRuntimeClient implements NodeRuntimeClient {
|
|
|
343
435
|
employeePurgePollPath(ctx?: RouteContext): string;
|
|
344
436
|
individualFamilyOrganizationBatchPath(ctx?: RouteContext): string;
|
|
345
437
|
individualFamilyOrganizationPollPath(ctx?: RouteContext): string;
|
|
438
|
+
individualFamilyOrganizationSearchPath(ctx?: RouteContext): string;
|
|
439
|
+
individualFamilyOrganizationSearchPollPath(ctx?: RouteContext): string;
|
|
346
440
|
individualFamilyOrganizationTransactionPath(ctx?: RouteContext): string;
|
|
347
441
|
individualFamilyOrganizationTransactionPollPath(ctx?: RouteContext): string;
|
|
348
442
|
individualFamilyOrganizationDisablePath(ctx?: RouteContext): string;
|
|
@@ -365,6 +459,8 @@ export declare class HttpRuntimeClient implements NodeRuntimeClient {
|
|
|
365
459
|
individualConsentR4PollPath(ctx: RouteContext): string;
|
|
366
460
|
individualCommunicationBatchPath(ctx: RouteContext, format: 'org.hl7.fhir.api' | 'org.hl7.fhir.r4'): string;
|
|
367
461
|
individualCommunicationPollPath(ctx: RouteContext, format: 'org.hl7.fhir.api' | 'org.hl7.fhir.r4'): string;
|
|
462
|
+
individualCommunicationSearchPath(ctx: RouteContext): string;
|
|
463
|
+
individualCommunicationSearchPollPath(ctx: RouteContext): string;
|
|
368
464
|
individualBundleSearchPath(ctx: RouteContext): string;
|
|
369
465
|
individualBundleSearchPollPath(ctx: RouteContext): string;
|
|
370
466
|
identityTokenExchangePath(ctx: RouteContext): string;
|