gdc-common-utils-ts 1.14.14 → 1.15.0

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 CHANGED
@@ -27,7 +27,15 @@ boundaries used in `gdc-common-utils-ts`.
27
27
  - FHIR SearchParameter names must use canonical FHIR naming (lowercase, with `-` when defined by FHIR).
28
28
  - Never use invented camelCase parameter names for FHIR claims/search keys (example: `Communication.part-of` is valid, `Communication.partOf` is not).
29
29
  - Only define custom names when no canonical FHIR SearchParameter exists.
30
- - `resource.meta.claims` is the canonical claims container and must be preserved across conversions/transports.
30
+ - `resource.meta.claims` is the canonical project-specific claims container and must be preserved across conversions/transports.
31
+ - `resource.meta.claims` is not part of base FHIR; it is a claims-first extension carried by FHIR-like resources in GDC contracts.
32
+
33
+ If you need the canonical explanation of how DIDComm envelope, batch body,
34
+ entry types, FHIR-like resources, and `resource.meta.claims` fit together,
35
+ read first:
36
+
37
+ - [`docs/101-COMMUNICATION_LAYERING.md`](docs/101-COMMUNICATION_LAYERING.md)
38
+ - [`docs/101-BUNDLE_EDITOR_READER.md`](docs/101-BUNDLE_EDITOR_READER.md)
31
39
 
32
40
  ## Install
33
41
 
@@ -148,12 +156,12 @@ import { JweObject, JwtCompactParts } from 'gdc-common-utils-ts/models';
148
156
  - [docs/DATASPACE_DISCOVERY_ROADMAP.md](docs/DATASPACE_DISCOVERY_ROADMAP.md)
149
157
  - cross-repo contract for dataspace discovery semantics, EU coverage
150
158
  inference, shared DTOs, and parameterized examples
151
- - [docs/DATASPACE_DISCOVERY_DEFAULTS_101.md](docs/DATASPACE_DISCOVERY_DEFAULTS_101.md)
159
+ - [docs/101-DATASPACE_DISCOVERY_DEFAULTS.md](docs/101-DATASPACE_DISCOVERY_DEFAULTS.md)
152
160
  - portal/backend bootstrap guide for `defaults-only`, `default-first`, and
153
161
  `internet-first` discovery seeding by `jurisdiction + version + networkType`
154
162
  - [docs/consent-access-matrix-task.md](docs/consent-access-matrix-task.md)
155
163
  - next-step design/task document for active consent aggregation, explicit deny precedence, controller views, permission-request communications, and SMART access evaluation
156
- - [docs/IPS_BUNDLE_101.md](docs/IPS_BUNDLE_101.md)
164
+ - [docs/101-IPS_BUNDLE.md](docs/101-IPS_BUNDLE.md)
157
165
  - canonical 101 for requesting IPS, editing IPS-style bundles in `Communication.content-attachment-data`, and reading resources by section
158
166
 
159
167
  ## Dataspace Protocol And Discovery
@@ -177,7 +185,7 @@ Main entry points:
177
185
  - [`src/examples/dataspace-discovery.ts`](src/examples/dataspace-discovery.ts)
178
186
  - synthetic provider/operator examples that distinguish discovery URL from
179
187
  derived catalog artifact URL
180
- - [`docs/DATASPACE_DISCOVERY_DEFAULTS_101.md`](docs/DATASPACE_DISCOVERY_DEFAULTS_101.md)
188
+ - [`docs/101-DATASPACE_DISCOVERY_DEFAULTS.md`](docs/101-DATASPACE_DISCOVERY_DEFAULTS.md)
181
189
  - copy/paste backend bootstrap guide for portal `default-first` rollout
182
190
  - [`__tests__/dataspace-discovery-defaults.101.test.ts`](__tests__/dataspace-discovery-defaults.101.test.ts)
183
191
  - executable defaults-registry examples for ICAs, hosting operators, and
@@ -267,7 +275,7 @@ The canonical API contract should live in JSDoc on exported code. The README act
267
275
  - This is the preferred first scope to teach when the backend only needs subject-scoped read access.
268
276
  - [`getOrganizationCredentialFromVpToken(...)`, `getLegalRepresentativeCredentialFromVpToken(...)`](src/utils/vp-token.ts)
269
277
  - Extract typed VC objects from a VP token when GW/SDK flows carry canonical proof only in `vp_token`.
270
- - [`docs/VP_TOKEN_101.md`](docs/VP_TOKEN_101.md)
278
+ - [`docs/101-VP_TOKEN.md`](docs/101-VP_TOKEN.md)
271
279
  - Step-by-step guide for building the canonical compact `vp_token` string from organization and representative VCs.
272
280
  - [`validateCommunicationResourceFhirR4(...)`](src/utils/communication-fhir-r4.ts)
273
281
  - Validates FHIR R4 `Communication` resources.
@@ -336,9 +344,9 @@ The canonical API contract should live in JSDoc on exported code. The README act
336
344
  - [`src/examples/shared.ts`](src/examples/shared.ts)
337
345
  - Shared route contexts, controller binding fragments, and reusable helper builders.
338
346
  - `tenantId` is modeled as an identifier-like route token (`acme-id`), not as a friendly alternate name.
339
- - [`docs/LIFECYCLE_101.md`](docs/LIFECYCLE_101.md)
347
+ - [`docs/101-LIFECYCLE.md`](docs/101-LIFECYCLE.md)
340
348
  - Copy/paste lifecycle `101` guide with semantic rules and reusable placeholders.
341
- - [`docs/HEALTHCARE_ROLES_I18N_101.md`](docs/HEALTHCARE_ROLES_I18N_101.md)
349
+ - [`docs/101-HEALTHCARE_ROLES_I18N.md`](docs/101-HEALTHCARE_ROLES_I18N.md)
342
350
  - Sector-aware healthcare role catalog and i18n `101` (ISCO-08 + HL7) for FE/BE onboarding.
343
351
 
344
352
  ## Documentation Naming Rules
@@ -0,0 +1,22 @@
1
+ import { BundleEntry, BundleJsonApi } from '../models/bundle';
2
+ /**
3
+ * First developer use case:
4
+ * - edit a Consent entry inside a Communication-attached Bundle
5
+ * - keep active entry in memory
6
+ * - serialize full Bundle to Communication.content-attachment-data on save
7
+ * - release active entry memory when finished
8
+ */
9
+ export declare function buildConsentEditingCommunicationSessionExample(): {
10
+ communicationClaims: Record<string, unknown>;
11
+ bundleInMemory: BundleJsonApi<BundleEntry>;
12
+ };
13
+ /**
14
+ * Second developer use case:
15
+ * - edit MedicationStatement claims to drive a health view
16
+ * - keep bundle attached to Communication as base64 payload
17
+ * - apply save/release lifecycle consistently
18
+ */
19
+ export declare function buildMedicationEditingCommunicationSessionExample(): {
20
+ communicationClaims: Record<string, unknown>;
21
+ bundleInMemory: BundleJsonApi<BundleEntry>;
22
+ };
@@ -0,0 +1,79 @@
1
+ // Copyright 2026 Conectate Soluciones y Aplicaciones SL under the Apache License, Version 2.0.
2
+ // Always create JSDoc, do not use strings inline in keys nor values, use types instead, and reuse the data test examples.
3
+ import { HealthcareBasicSections } from '../constants/healthcare.js';
4
+ import { CommunicationCategoryCodes } from '../constants/communication.js';
5
+ import { MedicationStatementClaim } from '../models/interoperable-claims/medication-statement-claims.js';
6
+ import { EXAMPLE_COMMUNICATION_IDENTIFIER, EXAMPLE_CONSENT_DATE, EXAMPLE_CONSENT_IDENTIFIER, EXAMPLE_CONSENT_PERIOD_END, EXAMPLE_CONSENT_PERIOD_START, EXAMPLE_CONSENT_PURPOSE_TREATMENT, EXAMPLE_EMAIL_PROFESSIONAL, EXAMPLE_HEALTHCARE_ACTOR_ROLE_PHYSICIAN, EXAMPLE_IPS_BUNDLE_NOTE_TEXT, EXAMPLE_MEDICATION_STATEMENT_IDENTIFIER, EXAMPLE_MEDICATION_STATEMENT_STATUS, EXAMPLE_MEDICATION_STATEMENT_TEXT, EXAMPLE_SUBJECT_DID, } from './shared.js';
7
+ import { CommunicationAttachedBundleSession } from '../utils/communication-attached-bundle-session.js';
8
+ import { setCommunicationCategory, setCommunicationIdentifier, setCommunicationSubject, setCommunicationText, } from '../claims/claims-helpers-communication.js';
9
+ import { setActorIdentifierList, setActorRoleList, setConsentDate, setConsentDecision, setConsentIdentifier, setConsentPeriodEnd, setConsentPeriodStart, setConsentSubject, setPurposeList, setSectionList, } from '../claims/claims-helpers-consent.js';
10
+ /**
11
+ * First developer use case:
12
+ * - edit a Consent entry inside a Communication-attached Bundle
13
+ * - keep active entry in memory
14
+ * - serialize full Bundle to Communication.content-attachment-data on save
15
+ * - release active entry memory when finished
16
+ */
17
+ export function buildConsentEditingCommunicationSessionExample() {
18
+ let communicationClaims = { '@context': 'org.hl7.fhir.r4' };
19
+ communicationClaims = setCommunicationIdentifier(communicationClaims, EXAMPLE_COMMUNICATION_IDENTIFIER);
20
+ communicationClaims = setCommunicationSubject(communicationClaims, EXAMPLE_SUBJECT_DID);
21
+ communicationClaims = setCommunicationCategory(communicationClaims, CommunicationCategoryCodes.Notification.attributeValue);
22
+ communicationClaims = setCommunicationText(communicationClaims, EXAMPLE_IPS_BUNDLE_NOTE_TEXT);
23
+ const bundleEditor = new CommunicationAttachedBundleSession({
24
+ communicationClaims,
25
+ });
26
+ let consentClaims = { '@context': 'org.hl7.fhir.api' };
27
+ consentClaims = setConsentDecision(consentClaims, 'permit');
28
+ consentClaims = setConsentSubject(consentClaims, EXAMPLE_SUBJECT_DID);
29
+ consentClaims = setConsentIdentifier(consentClaims, EXAMPLE_CONSENT_IDENTIFIER);
30
+ consentClaims = setConsentDate(consentClaims, EXAMPLE_CONSENT_DATE);
31
+ consentClaims = setConsentPeriodStart(consentClaims, EXAMPLE_CONSENT_PERIOD_START);
32
+ consentClaims = setConsentPeriodEnd(consentClaims, EXAMPLE_CONSENT_PERIOD_END);
33
+ consentClaims = setPurposeList(consentClaims, [EXAMPLE_CONSENT_PURPOSE_TREATMENT]);
34
+ consentClaims = setSectionList(consentClaims, [
35
+ HealthcareBasicSections.AllergiesAndIntolerances.attributeValue,
36
+ ]);
37
+ consentClaims = setActorIdentifierList(consentClaims, [EXAMPLE_EMAIL_PROFESSIONAL]);
38
+ consentClaims = setActorRoleList(consentClaims, [EXAMPLE_HEALTHCARE_ACTOR_ROLE_PHYSICIAN]);
39
+ bundleEditor.upsertActiveConsentEntry({
40
+ claims: consentClaims,
41
+ fullUrl: `urn:uuid:${EXAMPLE_CONSENT_IDENTIFIER}`,
42
+ });
43
+ bundleEditor.saveAndReleaseActiveEntry();
44
+ return {
45
+ communicationClaims: bundleEditor.getCommunicationClaims(),
46
+ bundleInMemory: bundleEditor.getBundleInMemory(),
47
+ };
48
+ }
49
+ /**
50
+ * Second developer use case:
51
+ * - edit MedicationStatement claims to drive a health view
52
+ * - keep bundle attached to Communication as base64 payload
53
+ * - apply save/release lifecycle consistently
54
+ */
55
+ export function buildMedicationEditingCommunicationSessionExample() {
56
+ let communicationClaims = { '@context': 'org.hl7.fhir.r4' };
57
+ communicationClaims = setCommunicationIdentifier(communicationClaims, EXAMPLE_COMMUNICATION_IDENTIFIER);
58
+ communicationClaims = setCommunicationSubject(communicationClaims, EXAMPLE_SUBJECT_DID);
59
+ communicationClaims = setCommunicationCategory(communicationClaims, CommunicationCategoryCodes.Reminder.attributeValue);
60
+ communicationClaims = setCommunicationText(communicationClaims, EXAMPLE_IPS_BUNDLE_NOTE_TEXT);
61
+ const bundleEditor = new CommunicationAttachedBundleSession({
62
+ communicationClaims,
63
+ });
64
+ bundleEditor.upsertActiveMedicationStatementEntry({
65
+ claims: {
66
+ '@context': 'org.hl7.fhir.api',
67
+ [MedicationStatementClaim.Identifier]: EXAMPLE_MEDICATION_STATEMENT_IDENTIFIER,
68
+ [MedicationStatementClaim.Subject]: EXAMPLE_SUBJECT_DID,
69
+ [MedicationStatementClaim.Status]: EXAMPLE_MEDICATION_STATEMENT_STATUS,
70
+ [MedicationStatementClaim.MedicationText]: EXAMPLE_MEDICATION_STATEMENT_TEXT,
71
+ },
72
+ fullUrl: `urn:uuid:${EXAMPLE_MEDICATION_STATEMENT_IDENTIFIER}`,
73
+ });
74
+ bundleEditor.saveAndReleaseActiveEntry();
75
+ return {
76
+ communicationClaims: bundleEditor.getCommunicationClaims(),
77
+ bundleInMemory: bundleEditor.getBundleInMemory(),
78
+ };
79
+ }
@@ -12,6 +12,6 @@ export * from './frontend-session';
12
12
  export * from './lifecycle';
13
13
  export * from './api-flow-examples';
14
14
  export * from './contract-examples';
15
- export * from './communication-bundle-session';
15
+ export * from './communication-attached-bundle-session';
16
16
  export * from './communication-bundle-document-request';
17
17
  export * from './ips-bundle';
@@ -12,6 +12,6 @@ export * from './frontend-session.js';
12
12
  export * from './lifecycle.js';
13
13
  export * from './api-flow-examples.js';
14
14
  export * from './contract-examples.js';
15
- export * from './communication-bundle-session.js';
15
+ export * from './communication-attached-bundle-session.js';
16
16
  export * from './communication-bundle-document-request.js';
17
17
  export * from './ips-bundle.js';
@@ -8,13 +8,13 @@ import { ConditionClaim } from '../models/interoperable-claims/condition-claims.
8
8
  import { MedicationStatementClaim } from '../models/interoperable-claims/medication-statement-claims.js';
9
9
  import { EXAMPLE_COMMUNICATION_IDENTIFIER, EXAMPLE_DOCUMENT_REFERENCE_CONTENT_TYPE_PDF, EXAMPLE_DOCUMENT_REFERENCE_DATE, EXAMPLE_DOCUMENT_REFERENCE_DESCRIPTION, EXAMPLE_DOCUMENT_REFERENCE_IDENTIFIER, EXAMPLE_DOCUMENT_REFERENCE_URL, EXAMPLE_IPS_BUNDLE_NOTE_TEXT, EXAMPLE_MEDICATION_STATEMENT_IDENTIFIER, EXAMPLE_MEDICATION_STATEMENT_STATUS, EXAMPLE_MEDICATION_STATEMENT_TEXT, EXAMPLE_SUBJECT_DID, } from './shared.js';
10
10
  import { toClinicalResourceCardViews, toClinicalResourceCommonViews, } from '../utils/clinical-resource-view.js';
11
- import { CommunicationBundleSession } from '../utils/communication-bundle-session.js';
11
+ import { CommunicationAttachedBundleSession } from '../utils/communication-attached-bundle-session.js';
12
12
  /**
13
13
  * Builds a minimal IPS-like history bundle with common clinical resource types
14
14
  * authored as `resource.meta.claims`.
15
15
  */
16
16
  export function buildIpsClinicalHistoryBundleExample() {
17
- const bundleEditor = new CommunicationBundleSession({
17
+ const bundleEditor = new CommunicationAttachedBundleSession({
18
18
  communicationClaims: {
19
19
  '@context': 'org.hl7.fhir.r4',
20
20
  [CommunicationClaim.Identifier]: EXAMPLE_COMMUNICATION_IDENTIFIER,
@@ -81,7 +81,7 @@ export function buildIpsClinicalHistoryBundleExample() {
81
81
  */
82
82
  export function buildIpsBundleFrontCardsExample() {
83
83
  const { communicationClaims, bundleInMemory } = buildIpsClinicalHistoryBundleExample();
84
- const bundleEditor = new CommunicationBundleSession({
84
+ const bundleEditor = new CommunicationAttachedBundleSession({
85
85
  communicationClaims,
86
86
  initialBundle: bundleInMemory,
87
87
  });
@@ -16,16 +16,28 @@
16
16
  * 2. **`BundleEntry`**: The core component of a Bundle. Represents a single unit of work,
17
17
  * such as registering one organization or creating one employee. It has a strict
18
18
  * structure:
19
- * - `type`: A string that defines the business action (e.g., 'Organization-registration-offer-v1.0').
19
+ * - `type`: A string that defines the internal business/message kind
20
+ * (e.g., 'Organization-registration-offer-v1.0').
20
21
  * - `resource.meta.claims`: Canonical location for claims in request entries.
21
22
  * - `meta.claims`: Legacy compatibility location accepted during migration.
22
23
  * - `resource`: A FHIR-like resource object that is the subject of the action.
23
24
  * - `request`/`response`: Contextual objects indicating the operation's details or result.
25
+ *
26
+ * Important distinction:
27
+ * - `BundleEntry.type` is not a FHIR field
28
+ * - `BundleEntry.resource.resourceType` is the actual FHIR-like resource type
29
+ * - `BundleJsonApi.type` is the batch container type
30
+ * - DIDComm envelope `type` is yet another outer field
24
31
  */
25
32
  import { OperationOutcome } from "./operation-outcome";
26
33
  /**
27
34
  * Defines the `request` property for an entry in a request Bundle.
28
35
  * This indicates the intended action for the entry.
36
+ *
37
+ * FHIR note:
38
+ * - this is the closest layer to FHIR batch semantics
39
+ * - `request.method` and `request.url` describe the operation
40
+ * - `BundleEntry.type` remains a separate internal business/message label
29
41
  */
30
42
  export interface BundleRequest {
31
43
  method: 'POST' | 'PUT' | 'DELETE' | 'GET';
@@ -131,7 +143,8 @@ export interface ErrorEntry {
131
143
  * Represents a single, canonical entry within a `BundleJsonApi`.
132
144
  * This structure is used for both requests and successful responses.
133
145
  *
134
- * @property {string} type - A string identifying the business action of the entry.
146
+ * @property {string} type - Internal business/message kind for this entry.
147
+ * This is not the FHIR `resourceType`.
135
148
  * @property {object} resource - The primary FHIR-like resource that is the subject of the action.
136
149
  * Canonical claims location is `resource.meta.claims`.
137
150
  * @property {BundleEntryMeta} [meta] - Legacy top-level claims location for backward compatibility.
@@ -153,6 +166,11 @@ export type BundleEntry = {
153
166
  * The generic type `T` allows for specifying whether the `data` array contains request
154
167
  * entries or response entries, providing strong type safety.
155
168
  *
169
+ * Layering note:
170
+ * - this is the business batch container
171
+ * - it is often placed inside the `body` of a DIDComm/FAPI envelope
172
+ * - entries inside it carry FHIR-like resources plus internal business labels
173
+ *
156
174
  * @example
157
175
  * const requestBundle: BundleJsonApi<BundleEntry> = { ... };
158
176
  * const responseBundle: BundleJsonApi<BundleEntry | ErrorEntry> = { ... };
@@ -16,10 +16,17 @@
16
16
  * 2. **`BundleEntry`**: The core component of a Bundle. Represents a single unit of work,
17
17
  * such as registering one organization or creating one employee. It has a strict
18
18
  * structure:
19
- * - `type`: A string that defines the business action (e.g., 'Organization-registration-offer-v1.0').
19
+ * - `type`: A string that defines the internal business/message kind
20
+ * (e.g., 'Organization-registration-offer-v1.0').
20
21
  * - `resource.meta.claims`: Canonical location for claims in request entries.
21
22
  * - `meta.claims`: Legacy compatibility location accepted during migration.
22
23
  * - `resource`: A FHIR-like resource object that is the subject of the action.
23
24
  * - `request`/`response`: Contextual objects indicating the operation's details or result.
25
+ *
26
+ * Important distinction:
27
+ * - `BundleEntry.type` is not a FHIR field
28
+ * - `BundleEntry.resource.resourceType` is the actual FHIR-like resource type
29
+ * - `BundleJsonApi.type` is the batch container type
30
+ * - DIDComm envelope `type` is yet another outer field
24
31
  */
25
32
  export {};
@@ -1,5 +1,16 @@
1
1
  /**
2
2
  * Represents the standard payload of a DIDComm v2 message.
3
+ *
4
+ * Layering rule:
5
+ * - `type` here is the DIDComm/protocol envelope type
6
+ * - it is not the FHIR `resourceType`
7
+ * - it is not the internal GW batch-entry business type
8
+ * - `body` carries the next business layer (often a `BundleJsonApi`)
9
+ *
10
+ * Read together with:
11
+ * - `docs/101-COMMUNICATION_LAYERING.md`
12
+ * - `src/models/bundle.ts`
13
+ *
3
14
  * @see https://identity.foundation/didcomm-messaging/spec/v2.0/#plaintext-message-structure
4
15
  */
5
16
  export interface DidCommPayload {
@@ -18,6 +29,11 @@ export interface DidCommPayload {
18
29
  /**
19
30
  * Represents a data entry in the `body` of a CommMsgExtended,
20
31
  * following a hybrid JSON:API and FHIR structure.
32
+ *
33
+ * Important:
34
+ * - `type` is an internal entry/data kind such as `Reference` or `Attachment`
35
+ * - it is not the DIDComm envelope type
36
+ * - it is not a FHIR `resourceType`
21
37
  */
22
38
  export interface DataEntry {
23
39
  id: string;
@@ -44,6 +60,19 @@ export interface DidCommAttachment {
44
60
  /**
45
61
  * The canonical, internal representation of a secure message, extending
46
62
  * the standard DIDComm payload with FHIR-specific, flattened metadata.
63
+ *
64
+ * Intended usage:
65
+ * - internal GW/runtime representation
66
+ * - derived from FHIR-like `Communication` payloads when needed
67
+ *
68
+ * Not intended as:
69
+ * - the primary client-facing payload new integrators should author first
70
+ *
71
+ * New client code should usually send:
72
+ * - DIDComm/FAPI-style envelope
73
+ * - carrying a batch body
74
+ * - carrying FHIR-like resources such as `Communication`
75
+ * - with canonical business semantics in `resource.meta.claims`
47
76
  */
48
77
  export interface CommMsgExtended extends DidCommPayload {
49
78
  body: {
@@ -29,6 +29,15 @@ export interface DidCommDecodedMetadata {
29
29
  * Represents the plaintext of a decoded DIDComm message.
30
30
  * This is the core business-level "input" for a job.
31
31
  * For FAPI compliance, this entire object is typically the payload of a signed JWS.
32
+ *
33
+ * Layering rule:
34
+ * - `type` is the outer envelope/protocol type
35
+ * - `body` carries the business payload
36
+ * - that `body` is often a batch container such as `BundleJsonApi`
37
+ * - resources inside that batch may be FHIR-like resources with
38
+ * `resource.meta.claims`
39
+ *
40
+ * This object is not itself a FHIR resource.
32
41
  */
33
42
  export interface IDecodedDidcommPayload {
34
43
  /** Relevant information available through the decryption and verification process */
@@ -66,10 +75,24 @@ export interface IDecodedDidcommPayload {
66
75
  from?: string;
67
76
  /**
68
77
  * The Message Type URI, identifying the type of data in the body or protocol used.
69
- * (e.g. 'application/json')
78
+ *
79
+ * Examples:
80
+ * - DIDComm/business envelope type
81
+ * - transport protocol hint
82
+ *
83
+ * This is not:
84
+ * - a FHIR `resourceType`
85
+ * - a GW batch-entry business type
70
86
  */
71
87
  type: string;
72
- /** The main business payload of the message. The structure is defined by the 'type' protocol. */
88
+ /**
89
+ * The main business payload of the message.
90
+ *
91
+ * In GW/SDK flows this is often:
92
+ * - a hybrid batch container (`BundleJsonApi`)
93
+ * - carrying entries
94
+ * - carrying FHIR-like resources
95
+ */
73
96
  body: any;
74
97
  }
75
98
  /**
@@ -89,6 +112,11 @@ export interface CommDataEntry {
89
112
  /**
90
113
  * The canonical, internal representation of a secure message, extending
91
114
  * the standard DIDComm payload with FHIR-specific, flattened metadata.
115
+ *
116
+ * Internal model note:
117
+ * - this is a gateway/runtime representation
118
+ * - it is not the main payload shape that new SDK/frontend/backend integrators
119
+ * should author directly
92
120
  */
93
121
  export interface ICommPayloadExtended extends IDecodedDidcommPayload {
94
122
  body: {
@@ -91,6 +91,6 @@ export declare const DiagnosticReportSearchParamToClaimKey: Record<DiagnosticRep
91
91
  *
92
92
  * Keep `DiagnosticReport` paused at the typing/mapping layer until:
93
93
  * 1. `claims-helpers-diagnostic-report.ts` exists
94
- * 2. `CommunicationBundleSession.upsertActiveDiagnosticReportEntry(...)` exists
94
+ * 2. `CommunicationAttachedBundleSession.upsertActiveDiagnosticReportEntry(...)` exists
95
95
  * 3. GW Core readers/tests consume the same shared claim keys
96
96
  */
@@ -100,6 +100,6 @@ export const DiagnosticReportSearchParamToClaimKey = {
100
100
  *
101
101
  * Keep `DiagnosticReport` paused at the typing/mapping layer until:
102
102
  * 1. `claims-helpers-diagnostic-report.ts` exists
103
- * 2. `CommunicationBundleSession.upsertActiveDiagnosticReportEntry(...)` exists
103
+ * 2. `CommunicationAttachedBundleSession.upsertActiveDiagnosticReportEntry(...)` exists
104
104
  * 3. GW Core readers/tests consume the same shared claim keys
105
105
  */
@@ -0,0 +1,88 @@
1
+ import { buildEmployeeBatchBundle, buildEmployeeBatchEntry, buildEmployeeSearchBundle, EmployeeBundleOperations } from './employee';
2
+ export type BundleOperation = (typeof EmployeeBundleOperations)[keyof typeof EmployeeBundleOperations];
3
+ export type BuiltEmployeeBatchEntry = ReturnType<typeof buildEmployeeBatchEntry> & {
4
+ fullUrl?: string;
5
+ };
6
+ /**
7
+ * Generic bundle editor with an employee adapter surface.
8
+ *
9
+ * Current scope:
10
+ * - one declared business operation per bundle
11
+ * - active-entry editing through generic claim helpers
12
+ * - employee convenience setters layered on the same active entry
13
+ *
14
+ * This editor lives in `common-utils` because it is runtime-neutral and can be
15
+ * consumed by frontend SDKs, backend SDKs, and backend services.
16
+ */
17
+ export declare class BundleEditor {
18
+ private bundleOperation;
19
+ private readonly entries;
20
+ private activeEntryIndex;
21
+ /** Declares which business operation the bundle is assembling. */
22
+ setBundleOperation(operation: BundleOperation): this;
23
+ /** Returns the operation currently assigned to this bundle. */
24
+ getBundleOperation(): BundleOperation | null;
25
+ /**
26
+ * Opens one new active entry.
27
+ *
28
+ * If the current bundle operation needs an identifier and none is supplied,
29
+ * a canonical `urn:uuid:*` identifier is generated and aligned across
30
+ * `fullUrl`, `resource.id`, and `org.schema.Person.identifier`.
31
+ */
32
+ newEntry(resourceId?: string): this;
33
+ /** Reopens an existing entry by identifier or `fullUrl`. */
34
+ openEntry(resourceId: string): this;
35
+ /** Closes the current active entry while preserving it inside the bundle draft. */
36
+ doneEntry(): this;
37
+ /** Returns a cloned snapshot of the currently staged entries. */
38
+ getEntries(): readonly BuiltEmployeeBatchEntry[];
39
+ /**
40
+ * Builds the final bundle payload for the declared operation.
41
+ *
42
+ * `search` returns one canonical search bundle.
43
+ * `purge` returns a batch bundle whose entries are routed later to
44
+ * `Employee/_purge`.
45
+ * `create` and `disable` return canonical batch bundles.
46
+ */
47
+ build(): ReturnType<typeof buildEmployeeBatchBundle> | ReturnType<typeof buildEmployeeSearchBundle>;
48
+ /** Reads one claim from the active entry. */
49
+ getClaim(key: string): unknown;
50
+ /** Checks whether the active entry contains one claim key. */
51
+ hasClaim(key: string): boolean;
52
+ /** Writes one claim on the active entry. */
53
+ setClaim(key: string, value: unknown): this;
54
+ /** Appends one claim value on the active entry. */
55
+ addClaim(key: string, value: unknown): this;
56
+ /** Removes one claim from the active entry. */
57
+ removeClaim(key: string): this;
58
+ /**
59
+ * Sets the active entry identifier.
60
+ *
61
+ * When informed, the value is synchronized into `fullUrl`, `resource.id`,
62
+ * and the canonical identifier claim.
63
+ * Empty values remove the identifier from all three places.
64
+ */
65
+ setIdentifier(identifier?: string | null): this;
66
+ /** Reads the active entry identifier from claims, resource id, or fullUrl. */
67
+ getIdentifier(): string | undefined;
68
+ /** Ensures the active entry carries one canonical identifier. */
69
+ ensureIdentifier(): string;
70
+ /** Sets the active entry `fullUrl` explicitly. */
71
+ setFullUrl(fullUrl?: string | null): this;
72
+ /** Returns the active entry `fullUrl` when present. */
73
+ getFullUrl(): string | undefined;
74
+ /** Convenience employee setter for email. */
75
+ setEmail(email: string): this;
76
+ /** Convenience employee setter for occupational role. */
77
+ setRole(role: string): this;
78
+ /** Convenience employee setter for `worksFor`. */
79
+ setWorksFor(worksFor: string): this;
80
+ /** Convenience employee setter for `memberOf`. */
81
+ setMemberOf(memberOf: string): this;
82
+ /** Convenience employee setter for `memberOf.taxID`. */
83
+ setMemberOfOrgTaxId(taxId: string): this;
84
+ private requireBundleOperation;
85
+ private getRequiredActiveEntry;
86
+ private getActiveEntryClaims;
87
+ private getActiveOrSingleSearchClaims;
88
+ }