vet-data-utils-ts 0.5.13 → 0.5.14

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.
@@ -144,6 +144,8 @@ export declare function buildVeterinaryAppointmentResource(input: Readonly<{
144
144
  locationReference?: string;
145
145
  confirmationDueAt?: string;
146
146
  userSelected?: boolean;
147
+ clinicRecipientReference?: string;
148
+ clinicRecipientEmail?: string;
147
149
  }>): ClaimsFirstResource;
148
150
  /** Builds the durable web inbox notification when a schedule change displaces an appointment. */
149
151
  export declare function buildVeterinaryAppointmentNotificationResource(input: Readonly<{
@@ -14,7 +14,7 @@ export const VeterinarySchedulingFlatClaimCatalog = Object.freeze({
14
14
  Location: Object.freeze(['Location.identifier', 'Location.status', 'Location.mode', 'Location.name', 'Location.description', 'Location.position.latitude', 'Location.position.longitude', 'Location.position.altitude', 'Location.managingOrganization', 'Location.characteristic', 'VeterinaryLocation.photoUrl']),
15
15
  Schedule: Object.freeze(['Schedule.identifier', 'Schedule.active', 'Schedule.name', 'Schedule.actor', 'Schedule.planningHorizon.start', 'Schedule.planningHorizon.end']),
16
16
  Slot: Object.freeze(['Slot.identifier', 'Slot.schedule', 'Slot.status', 'Slot.start', 'Slot.end', 'Slot.service-category', 'Slot.service-type', 'Slot.specialty', 'VeterinarySlot.location', 'VeterinarySlot.timeZone']),
17
- Appointment: Object.freeze(['Appointment.identifier', 'Appointment.status', 'Appointment.description', 'Appointment.note', 'Appointment.start', 'Appointment.end', 'Appointment.slot', 'Appointment.actor', 'Appointment.location', 'Appointment.user-selected', 'VeterinaryAppointment.confirmationDueAt', 'VeterinaryAppointment.reschedulingReason']),
17
+ Appointment: Object.freeze(['Appointment.identifier', 'Appointment.status', 'Appointment.description', 'Appointment.note', 'Appointment.start', 'Appointment.end', 'Appointment.slot', 'Appointment.actor', 'Appointment.location', 'Appointment.user-selected', 'VeterinaryAppointment.confirmationDueAt', 'VeterinaryAppointment.reschedulingReason', 'VeterinaryAppointment.clinicRecipient', 'VeterinaryAppointment.clinicEmail']),
18
18
  AppointmentResponse: Object.freeze(['AppointmentResponse.identifier', 'AppointmentResponse.appointment', 'AppointmentResponse.actor', 'AppointmentResponse.participantStatus', 'AppointmentResponse.proposedNewTime', 'AppointmentResponse.start', 'AppointmentResponse.end', 'VeterinaryAppointmentResponse.respondedAt', 'VeterinaryAppointmentResponse.recipient', 'VeterinaryAppointmentResponse.recipientEmail']),
19
19
  });
20
20
  /** Validates the claims-only wire shape and normalizes scalar builder values to indexed strings. */
@@ -225,6 +225,12 @@ export function buildVeterinaryAppointmentResource(input) {
225
225
  const confirmationDueAt = input.confirmationDueAt || new Date(start - 7 * 24 * 60 * 60 * 1000).toISOString();
226
226
  if (!Number.isFinite(Date.parse(confirmationDueAt)) || Date.parse(confirmationDueAt) >= start)
227
227
  throw new Error('appointment_confirmation_due_invalid');
228
+ const hasClinicRecipient = Boolean(input.clinicRecipientReference?.trim());
229
+ const hasClinicEmail = Boolean(input.clinicRecipientEmail?.trim());
230
+ if (hasClinicRecipient !== hasClinicEmail)
231
+ throw new Error('appointment_clinic_notification_recipient_incomplete');
232
+ if (hasClinicEmail && !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(input.clinicRecipientEmail.trim()))
233
+ throw new Error('appointment_clinic_email_invalid');
228
234
  return claimsResource('Appointment', input.id, {
229
235
  'Appointment.status': input.status,
230
236
  'Appointment.start': new Date(start).toISOString(),
@@ -232,6 +238,7 @@ export function buildVeterinaryAppointmentResource(input) {
232
238
  ...(input.slotReferences.length ? { 'Appointment.slot': Object.freeze([...input.slotReferences]) } : {}),
233
239
  'Appointment.actor': Object.freeze([...input.actorReferences]),
234
240
  'Appointment.user-selected': userSelected,
241
+ ...(hasClinicRecipient ? { 'VeterinaryAppointment.clinicRecipient': input.clinicRecipientReference.trim(), 'VeterinaryAppointment.clinicEmail': input.clinicRecipientEmail.trim().toLowerCase() } : {}),
235
242
  ...(input.locationReference ? { 'Appointment.location': required(input.locationReference, 'appointment_location_required') } : {}),
236
243
  'VeterinaryAppointment.confirmationDueAt': new Date(confirmationDueAt).toISOString(),
237
244
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vet-data-utils-ts",
3
- "version": "0.5.13",
3
+ "version": "0.5.14",
4
4
  "description": "Browser-safe governed VetChain data contracts",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Connecting Solution & Applications Ltd",