vet-data-utils-ts 0.5.15 → 0.5.17

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
@@ -30,6 +30,12 @@ shows FHIR `Immunization.occurrenceDateTime`, `vaccineCode` and
30
30
  `protocolApplied.targetDisease`. Its issuer-supplied validity interval is not
31
31
  FHIR `Immunization.expirationDate`, which means vaccine-batch expiry.
32
32
 
33
+ `buildSmartHealthCardJwsProofReference(...)` serves a different purpose: it
34
+ hashes the exact compact SHC JWS, including its ES256 signature, with a domain
35
+ separator. A product ledger/resolver may use that key to retrieve the existing
36
+ detached `pqc:/` proofs when only the SHC QR is printed and internet access is
37
+ available. Offline PQC verification still requires the companion QR labels.
38
+
33
39
  Development and releases follow the mandatory
34
40
  [`local-first TDD and release contract`](docs/LOCAL_FIRST_RELEASE_CONTRACT.md).
35
41
 
@@ -29,7 +29,7 @@ const nativeFieldsByResource = Object.freeze({
29
29
  Location: new Set(['identifier', 'status', 'mode', 'name', 'description', 'type', 'telecom', 'address', 'physicalType', 'position', 'managingOrganization', 'characteristic', 'contained']),
30
30
  Schedule: new Set(['identifier', 'active', 'serviceCategory', 'serviceType', 'specialty', 'name', 'actor', 'planningHorizon', 'comment']),
31
31
  Slot: new Set(['identifier', 'serviceCategory', 'serviceType', 'specialty', 'appointmentType', 'schedule', 'status', 'start', 'end', 'overbooked', 'comment']),
32
- Appointment: new Set(['identifier', 'status', 'serviceCategory', 'serviceType', 'specialty', 'appointmentType', 'reason', 'description', 'start', 'end', 'slot', 'participant', 'subject', 'note', 'supportingInformation']),
32
+ Appointment: new Set(['identifier', 'status', 'serviceCategory', 'serviceType', 'specialty', 'appointmentType', 'reason', 'description', 'start', 'end', 'slot', 'participant', 'subject', 'note', 'supportingInformation', 'contained']),
33
33
  AppointmentResponse: new Set(['identifier', 'appointment', 'proposedNewTime', 'start', 'end', 'participantType', 'actor', 'participantStatus', 'comment', 'recurring', 'occurrenceDate', 'recurrenceId', 'contained']),
34
34
  });
35
35
  /** Validates native FHIR scheduling data and normalizes indexed SearchParameter claims to strings. */
@@ -295,6 +295,11 @@ export function buildAppointmentResource(input) {
295
295
  const startInstant = new Date(start).toISOString();
296
296
  const endInstant = new Date(end).toISOString();
297
297
  const organization = hasOrganization ? organizationReference.trim() : undefined;
298
+ const emailEndpoint = hasNotificationEmail ? {
299
+ resourceType: 'Endpoint', id: 'clinic-notification-email', status: 'active',
300
+ connectionType: [{ coding: [{ code: 'email' }] }],
301
+ address: `mailto:${notificationEmail.trim().toLowerCase()}`,
302
+ } : undefined;
298
303
  return claimsResource('Appointment', input.id, {
299
304
  'Appointment.identifier': input.id, 'Appointment.status': input.status, 'Appointment.date': startInstant,
300
305
  ...(input.slotReferences.length ? { 'Appointment.slot': Object.freeze([...input.slotReferences]) } : {}),
@@ -306,7 +311,8 @@ export function buildAppointmentResource(input) {
306
311
  identifier: [{ value: input.id }], status: input.status, start: startInstant, end: endInstant,
307
312
  ...(input.slotReferences.length ? { slot: input.slotReferences.map(reference => ({ reference })) } : {}),
308
313
  participant: input.actorReferences.map(reference => ({ actor: { reference }, status: 'needs-action' })),
309
- ...(organization ? { supportingInformation: [{ reference: organization }] } : {}),
314
+ ...(organization ? { supportingInformation: [{ reference: organization }, { reference: '#clinic-notification-email' }] } : {}),
315
+ ...(emailEndpoint ? { contained: [emailEndpoint] } : {}),
310
316
  });
311
317
  }
312
318
  /** Builds the durable web inbox notification when a schedule change displaces an appointment. */
package/dist/shc.d.ts CHANGED
@@ -55,6 +55,13 @@ export declare function assembleSmartHealthCardJws(prepared: Pick<PreparedSmartH
55
55
  * content identifier. They are deliberately not aliases.
56
56
  */
57
57
  export declare function buildSmartHealthCardPayloadReferences(payloadBytes: Uint8Array): SmartHealthCardPayloadReferences;
58
+ /**
59
+ * Builds the optional online lookup key for a PQC companion proof from the
60
+ * exact compact SHC JWS printed by `shc:/`. This is intentionally distinct
61
+ * from the canonical payload references above: it includes the ES256
62
+ * signature and uses a domain separator so the two namespaces cannot collide.
63
+ */
64
+ export declare function buildSmartHealthCardJwsProofReference(compactJws: string): string;
58
65
  /** Encodes one compact SHC JWS into one or more standard numeric QR payloads. */
59
66
  export declare function encodeSmartHealthCardQr(compactJws: string): readonly string[];
60
67
  /** Reassembles standard SHC QR payloads regardless of scan order. */
package/dist/shc.js CHANGED
@@ -156,6 +156,19 @@ export function buildSmartHealthCardPayloadReferences(payloadBytes) {
156
156
  cidV1: buildRawCidV1FromUtf8String(payloadText),
157
157
  };
158
158
  }
159
+ /**
160
+ * Builds the optional online lookup key for a PQC companion proof from the
161
+ * exact compact SHC JWS printed by `shc:/`. This is intentionally distinct
162
+ * from the canonical payload references above: it includes the ES256
163
+ * signature and uses a domain separator so the two namespaces cannot collide.
164
+ */
165
+ export function buildSmartHealthCardJwsProofReference(compactJws) {
166
+ const jws = nonEmptyString(compactJws, 'shc_compact_jws_required');
167
+ if (jws.split('.').length !== 3)
168
+ throw new TypeError('shc_compact_jws_required');
169
+ const lookupBytes = Content.stringToBytesUTF8(`vetchain:shc-jws-pqc-proof:v1\0${jws}`);
170
+ return `urn:multibase:${encodeMultibaseSha3(lookupBytes, 384)}`;
171
+ }
159
172
  /** Encodes one compact SHC JWS into one or more standard numeric QR payloads. */
160
173
  export function encodeSmartHealthCardQr(compactJws) {
161
174
  const jws = nonEmptyString(compactJws, 'shc_compact_jws_required');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vet-data-utils-ts",
3
- "version": "0.5.15",
3
+ "version": "0.5.17",
4
4
  "description": "Browser-safe governed VetChain data contracts",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Connecting Solution & Applications Ltd",