vet-sdk-core-ts 0.4.24 → 0.4.26
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/dist/scheduling.d.ts +48 -28
- package/dist/scheduling.js +37 -25
- package/package.json +2 -2
package/dist/scheduling.d.ts
CHANGED
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
export type
|
|
3
|
-
export type
|
|
1
|
+
import { type SchedulingFlatClaimsResource, type SchedulingResourceType } from 'vet-data-utils-ts/scheduling';
|
|
2
|
+
export type SchedulingBatchMethod = 'POST' | 'PUT';
|
|
3
|
+
export type SchedulingBatch = Readonly<{
|
|
4
4
|
data: readonly Readonly<{
|
|
5
|
-
type: `${
|
|
6
|
-
resource:
|
|
5
|
+
type: `${SchedulingResourceType}-v5.0.0`;
|
|
6
|
+
resource: SchedulingFlatClaimsResource;
|
|
7
7
|
request: Readonly<{
|
|
8
|
-
method:
|
|
8
|
+
method: SchedulingBatchMethod;
|
|
9
9
|
url: string;
|
|
10
10
|
}>;
|
|
11
11
|
}>[];
|
|
12
12
|
}>;
|
|
13
13
|
/**
|
|
14
|
-
* Extends the generic GW JSON:API batch boundary for
|
|
15
|
-
* Resources are revalidated at this product boundary
|
|
14
|
+
* Extends the generic GW JSON:API batch boundary for reusable scheduling.
|
|
15
|
+
* Resources are revalidated at this product boundary; only SearchParameters are indexed.
|
|
16
16
|
*/
|
|
17
|
-
export declare function
|
|
18
|
-
/** Builds the governed claims-first search envelope accepted by GW
|
|
19
|
-
export declare function
|
|
17
|
+
export declare function buildSchedulingBatch(resources: readonly unknown[], method?: SchedulingBatchMethod): SchedulingBatch;
|
|
18
|
+
/** Builds the governed claims-first search envelope accepted by a GW. */
|
|
19
|
+
export declare function buildSchedulingSearch(resourceType: SchedulingResourceType, claims: Readonly<Record<string, unknown>>): Readonly<{
|
|
20
20
|
data: readonly Readonly<{
|
|
21
|
-
resource: Readonly<{
|
|
22
|
-
resourceType:
|
|
21
|
+
resource: Readonly<Record<string, unknown> & {
|
|
22
|
+
resourceType: SchedulingResourceType;
|
|
23
23
|
id: string;
|
|
24
|
-
meta: Readonly<{
|
|
24
|
+
meta: Readonly<Record<string, unknown> & {
|
|
25
25
|
claims: Readonly<Record<string, readonly string[]>>;
|
|
26
26
|
}>;
|
|
27
27
|
}>;
|
|
28
28
|
}>[];
|
|
29
29
|
}>;
|
|
30
|
-
/** Builds the
|
|
31
|
-
export declare function
|
|
30
|
+
/** Builds the organization-wide `_search` envelope for responses recorded inside an inclusive time period. */
|
|
31
|
+
export declare function buildAppointmentResponseSearchPeriod(input: Readonly<{
|
|
32
32
|
from: string;
|
|
33
33
|
to: string;
|
|
34
34
|
}>): Readonly<{
|
|
35
35
|
data: readonly Readonly<{
|
|
36
|
-
resource: Readonly<{
|
|
37
|
-
resourceType:
|
|
36
|
+
resource: Readonly<Record<string, unknown> & {
|
|
37
|
+
resourceType: SchedulingResourceType;
|
|
38
38
|
id: string;
|
|
39
|
-
meta: Readonly<{
|
|
39
|
+
meta: Readonly<Record<string, unknown> & {
|
|
40
40
|
claims: Readonly<Record<string, readonly string[]>>;
|
|
41
41
|
}>;
|
|
42
42
|
}>;
|
|
43
43
|
}>[];
|
|
44
44
|
}>;
|
|
45
|
-
export type
|
|
45
|
+
export type AppointmentResponseEmailPayload = Readonly<{
|
|
46
46
|
to: string;
|
|
47
47
|
subject: string;
|
|
48
48
|
text: string;
|
|
49
49
|
metadata: Readonly<Record<string, string>>;
|
|
50
50
|
}>;
|
|
51
51
|
/** Converts the governed English AppointmentResponse Communication projection into an email-adapter payload. */
|
|
52
|
-
export declare function
|
|
52
|
+
export declare function convertAppointmentResponseCommunicationToEnglishEmail(input: Readonly<{
|
|
53
53
|
recipientEmail: string;
|
|
54
54
|
communication: unknown;
|
|
55
|
-
}>):
|
|
55
|
+
}>): AppointmentResponseEmailPayload;
|
|
56
56
|
/** Reads canonical GW search matches from `body.data[].resource`. */
|
|
57
|
-
export declare function
|
|
58
|
-
export type
|
|
59
|
-
appointments: readonly
|
|
57
|
+
export declare function readSchedulingSearch(body: unknown, expectedResourceType: SchedulingResourceType): readonly SchedulingFlatClaimsResource[];
|
|
58
|
+
export type ScheduleReconciliation = Readonly<{
|
|
59
|
+
appointments: readonly SchedulingFlatClaimsResource[];
|
|
60
60
|
notifications: readonly Readonly<{
|
|
61
61
|
resourceType: 'Communication';
|
|
62
62
|
id: string;
|
|
@@ -70,9 +70,29 @@ export type VeterinaryScheduleReconciliation = Readonly<{
|
|
|
70
70
|
* It deliberately does not cancel: the patient receives a durable
|
|
71
71
|
* Communication and may choose another slot before a final decline.
|
|
72
72
|
*/
|
|
73
|
-
export declare function
|
|
73
|
+
export declare function reconcileAppointmentsAfterSlotChange(input: Readonly<{
|
|
74
74
|
appointments: readonly unknown[];
|
|
75
75
|
availableSlotReferences: ReadonlySet<string>;
|
|
76
|
-
subjectReferenceFor: (appointment:
|
|
76
|
+
subjectReferenceFor: (appointment: SchedulingFlatClaimsResource) => string;
|
|
77
77
|
reason: string;
|
|
78
|
-
}>):
|
|
78
|
+
}>): ScheduleReconciliation;
|
|
79
|
+
/** @deprecated Use {@link SchedulingBatchMethod}. */
|
|
80
|
+
export type VeterinarySchedulingBatchMethod = SchedulingBatchMethod;
|
|
81
|
+
/** @deprecated Use {@link SchedulingBatch}. */
|
|
82
|
+
export type VeterinarySchedulingBatch = SchedulingBatch;
|
|
83
|
+
/** @deprecated Use {@link buildSchedulingBatch}. */
|
|
84
|
+
export declare const buildVeterinarySchedulingBatch: typeof buildSchedulingBatch;
|
|
85
|
+
/** @deprecated Use {@link buildSchedulingSearch}. */
|
|
86
|
+
export declare const buildVeterinarySchedulingSearch: typeof buildSchedulingSearch;
|
|
87
|
+
/** @deprecated Use {@link buildAppointmentResponseSearchPeriod}. */
|
|
88
|
+
export declare const buildVeterinaryAppointmentResponseSearchPeriod: typeof buildAppointmentResponseSearchPeriod;
|
|
89
|
+
/** @deprecated Use {@link AppointmentResponseEmailPayload}. */
|
|
90
|
+
export type VeterinaryAppointmentResponseEmailPayload = AppointmentResponseEmailPayload;
|
|
91
|
+
/** @deprecated Use {@link convertAppointmentResponseCommunicationToEnglishEmail}. */
|
|
92
|
+
export declare const convertVeterinaryAppointmentResponseCommunicationToEnglishEmail: typeof convertAppointmentResponseCommunicationToEnglishEmail;
|
|
93
|
+
/** @deprecated Use {@link readSchedulingSearch}. */
|
|
94
|
+
export declare const readVeterinarySchedulingSearch: typeof readSchedulingSearch;
|
|
95
|
+
/** @deprecated Use {@link ScheduleReconciliation}. */
|
|
96
|
+
export type VeterinaryScheduleReconciliation = ScheduleReconciliation;
|
|
97
|
+
/** @deprecated Use {@link reconcileAppointmentsAfterSlotChange}. */
|
|
98
|
+
export declare const reconcileVeterinaryAppointmentsAfterSlotChange: typeof reconcileAppointmentsAfterSlotChange;
|
package/dist/scheduling.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { buildAppointmentNotificationResource, normalizeSchedulingFlatClaimsResource, } from 'vet-data-utils-ts/scheduling';
|
|
2
2
|
const asArrayClaims = (claims) => Object.freeze(Object.fromEntries(Object.entries(claims).map(([name, raw]) => [
|
|
3
3
|
name,
|
|
4
4
|
Object.freeze((Array.isArray(raw) ? raw : [raw]).map(value => String(value))),
|
|
5
5
|
])));
|
|
6
6
|
/**
|
|
7
|
-
* Extends the generic GW JSON:API batch boundary for
|
|
8
|
-
* Resources are revalidated at this product boundary
|
|
7
|
+
* Extends the generic GW JSON:API batch boundary for reusable scheduling.
|
|
8
|
+
* Resources are revalidated at this product boundary; only SearchParameters are indexed.
|
|
9
9
|
*/
|
|
10
|
-
export function
|
|
10
|
+
export function buildSchedulingBatch(resources, method = 'POST') {
|
|
11
11
|
return Object.freeze({
|
|
12
12
|
data: Object.freeze(resources.map(candidate => {
|
|
13
|
-
const resource =
|
|
13
|
+
const resource = normalizeSchedulingFlatClaimsResource(candidate);
|
|
14
14
|
return Object.freeze({
|
|
15
15
|
type: `${resource.resourceType}-v5.0.0`,
|
|
16
16
|
resource,
|
|
@@ -19,27 +19,27 @@ export function buildVeterinarySchedulingBatch(resources, method = 'POST') {
|
|
|
19
19
|
})),
|
|
20
20
|
});
|
|
21
21
|
}
|
|
22
|
-
/** Builds the governed claims-first search envelope accepted by GW
|
|
23
|
-
export function
|
|
24
|
-
const resource =
|
|
22
|
+
/** Builds the governed claims-first search envelope accepted by a GW. */
|
|
23
|
+
export function buildSchedulingSearch(resourceType, claims) {
|
|
24
|
+
const resource = normalizeSchedulingFlatClaimsResource({
|
|
25
25
|
resourceType,
|
|
26
26
|
id: 'search',
|
|
27
27
|
meta: { claims },
|
|
28
28
|
});
|
|
29
29
|
return Object.freeze({ data: Object.freeze([Object.freeze({ resource })]) });
|
|
30
30
|
}
|
|
31
|
-
/** Builds the
|
|
32
|
-
export function
|
|
31
|
+
/** Builds the organization-wide `_search` envelope for responses recorded inside an inclusive time period. */
|
|
32
|
+
export function buildAppointmentResponseSearchPeriod(input) {
|
|
33
33
|
const from = Date.parse(input.from);
|
|
34
34
|
const to = Date.parse(input.to);
|
|
35
35
|
if (!Number.isFinite(from) || !Number.isFinite(to) || from > to)
|
|
36
36
|
throw new Error('appointment_response_search_period_invalid');
|
|
37
|
-
return
|
|
38
|
-
'
|
|
37
|
+
return buildSchedulingSearch('AppointmentResponse', {
|
|
38
|
+
'AppointmentResponse._lastUpdated': [`ge${new Date(from).toISOString()}`, `le${new Date(to).toISOString()}`],
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
41
|
/** Converts the governed English AppointmentResponse Communication projection into an email-adapter payload. */
|
|
42
|
-
export function
|
|
42
|
+
export function convertAppointmentResponseCommunicationToEnglishEmail(input) {
|
|
43
43
|
const email = String(input.recipientEmail || '').trim().toLowerCase();
|
|
44
44
|
const resource = input.communication;
|
|
45
45
|
const claims = resource?.resourceType === 'Communication' ? resource?.meta?.claims : undefined;
|
|
@@ -53,22 +53,22 @@ export function convertVeterinaryAppointmentResponseCommunicationToEnglishEmail(
|
|
|
53
53
|
return Object.freeze({ to: email, subject: 'Appointment response', text, metadata: Object.freeze({ appointmentResponse, appointment, recipient, language: 'en' }) });
|
|
54
54
|
}
|
|
55
55
|
/** Reads canonical GW search matches from `body.data[].resource`. */
|
|
56
|
-
export function
|
|
56
|
+
export function readSchedulingSearch(body, expectedResourceType) {
|
|
57
57
|
if (!body || typeof body !== 'object' || !Array.isArray(body.data)) {
|
|
58
|
-
throw new TypeError('
|
|
58
|
+
throw new TypeError('scheduling_search_invalid');
|
|
59
59
|
}
|
|
60
60
|
return Object.freeze(body.data.map(entry => {
|
|
61
61
|
if (!entry || typeof entry !== 'object' || !('resource' in entry)) {
|
|
62
|
-
throw new TypeError('
|
|
62
|
+
throw new TypeError('scheduling_search_resource_invalid');
|
|
63
63
|
}
|
|
64
64
|
try {
|
|
65
|
-
const resource =
|
|
65
|
+
const resource = normalizeSchedulingFlatClaimsResource(entry.resource);
|
|
66
66
|
if (resource.resourceType !== expectedResourceType)
|
|
67
67
|
throw new Error('wrong type');
|
|
68
68
|
return resource;
|
|
69
69
|
}
|
|
70
70
|
catch {
|
|
71
|
-
throw new TypeError('
|
|
71
|
+
throw new TypeError('scheduling_search_resource_invalid');
|
|
72
72
|
}
|
|
73
73
|
}));
|
|
74
74
|
}
|
|
@@ -77,26 +77,26 @@ export function readVeterinarySchedulingSearch(body, expectedResourceType) {
|
|
|
77
77
|
* It deliberately does not cancel: the patient receives a durable
|
|
78
78
|
* Communication and may choose another slot before a final decline.
|
|
79
79
|
*/
|
|
80
|
-
export function
|
|
80
|
+
export function reconcileAppointmentsAfterSlotChange(input) {
|
|
81
81
|
const appointments = [];
|
|
82
82
|
const notifications = [];
|
|
83
83
|
for (const candidate of input.appointments) {
|
|
84
|
-
const appointment =
|
|
84
|
+
const appointment = normalizeSchedulingFlatClaimsResource(candidate);
|
|
85
85
|
if (appointment.resourceType !== 'Appointment')
|
|
86
|
-
throw new TypeError('
|
|
86
|
+
throw new TypeError('scheduling_appointment_required');
|
|
87
87
|
const slots = appointment.meta.claims['Appointment.slot'] ?? [];
|
|
88
88
|
if (slots.length > 0 && slots.every(slot => input.availableSlotReferences.has(slot)))
|
|
89
89
|
continue;
|
|
90
|
-
const updated =
|
|
90
|
+
const updated = normalizeSchedulingFlatClaimsResource({
|
|
91
91
|
...appointment,
|
|
92
|
-
|
|
92
|
+
description: input.reason,
|
|
93
|
+
meta: { ...appointment.meta, claims: {
|
|
93
94
|
...appointment.meta.claims,
|
|
94
95
|
'Appointment.status': ['pending'],
|
|
95
|
-
'VeterinaryAppointment.reschedulingReason': [input.reason],
|
|
96
96
|
} },
|
|
97
97
|
});
|
|
98
98
|
appointments.push(updated);
|
|
99
|
-
const notification =
|
|
99
|
+
const notification = buildAppointmentNotificationResource({
|
|
100
100
|
id: `${appointment.id}-schedule-change`,
|
|
101
101
|
appointmentReference: `Appointment/${appointment.id}`,
|
|
102
102
|
subjectReference: input.subjectReferenceFor(appointment),
|
|
@@ -110,3 +110,15 @@ export function reconcileVeterinaryAppointmentsAfterSlotChange(input) {
|
|
|
110
110
|
}
|
|
111
111
|
return Object.freeze({ appointments: Object.freeze(appointments), notifications: Object.freeze(notifications) });
|
|
112
112
|
}
|
|
113
|
+
/** @deprecated Use {@link buildSchedulingBatch}. */
|
|
114
|
+
export const buildVeterinarySchedulingBatch = buildSchedulingBatch;
|
|
115
|
+
/** @deprecated Use {@link buildSchedulingSearch}. */
|
|
116
|
+
export const buildVeterinarySchedulingSearch = buildSchedulingSearch;
|
|
117
|
+
/** @deprecated Use {@link buildAppointmentResponseSearchPeriod}. */
|
|
118
|
+
export const buildVeterinaryAppointmentResponseSearchPeriod = buildAppointmentResponseSearchPeriod;
|
|
119
|
+
/** @deprecated Use {@link convertAppointmentResponseCommunicationToEnglishEmail}. */
|
|
120
|
+
export const convertVeterinaryAppointmentResponseCommunicationToEnglishEmail = convertAppointmentResponseCommunicationToEnglishEmail;
|
|
121
|
+
/** @deprecated Use {@link readSchedulingSearch}. */
|
|
122
|
+
export const readVeterinarySchedulingSearch = readSchedulingSearch;
|
|
123
|
+
/** @deprecated Use {@link reconcileAppointmentsAfterSlotChange}. */
|
|
124
|
+
export const reconcileVeterinaryAppointmentsAfterSlotChange = reconcileAppointmentsAfterSlotChange;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vet-sdk-core-ts",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.26",
|
|
4
4
|
"description": "Browser-safe VetChain core contracts and governed animal species identifiers",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Connecting Solution & Applications Ltd",
|
|
@@ -76,6 +76,6 @@
|
|
|
76
76
|
"dependencies": {
|
|
77
77
|
"@noble/hashes": "^2.2.0",
|
|
78
78
|
"gdc-common-utils-ts": "2.9.10",
|
|
79
|
-
"vet-data-utils-ts": "0.5.
|
|
79
|
+
"vet-data-utils-ts": "0.5.16"
|
|
80
80
|
}
|
|
81
81
|
}
|