@blackcode_sa/metaestetics-api 1.7.3 → 1.7.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/dist/admin/index.d.mts +41 -8
- package/dist/admin/index.d.ts +41 -8
- package/dist/admin/index.js +621 -109
- package/dist/admin/index.mjs +621 -109
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +5 -2
- package/dist/index.mjs +5 -2
- package/package.json +1 -1
- package/src/admin/aggregation/appointment/appointment.aggregation.service.ts +553 -112
- package/src/admin/calendar/calendar.admin.service.ts +230 -65
- package/src/services/calendar/calendar-refactored.service.ts +2 -0
- package/src/types/calendar/index.ts +1 -0
|
@@ -42,47 +42,93 @@ export class CalendarAdminService {
|
|
|
42
42
|
);
|
|
43
43
|
const batch = this.db.batch();
|
|
44
44
|
const serverTimestamp = admin.firestore.FieldValue.serverTimestamp();
|
|
45
|
+
let updatesAdded = 0;
|
|
45
46
|
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
// We need a robust way to find these if they aren't directly on the appointment object.
|
|
49
|
-
// For now, assuming we can query them or they are added to the Appointment type.
|
|
47
|
+
// Get the shared calendar event ID
|
|
48
|
+
const calendarEventId = appointment.calendarEventId;
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const practitionerCalendarEventPath = `${PRACTITIONERS_COLLECTION}/${appointment.practitionerId}/${CALENDAR_COLLECTION}/${appointment.calendarEventId}`;
|
|
59
|
-
// Example paths, these need to be accurate based on your data model:
|
|
60
|
-
// const patientCalendarEventPath = `${PATIENTS_COLLECTION}/${appointment.patientId}/${CALENDAR_COLLECTION}/${appointment.patientCalendarEventId}`;
|
|
61
|
-
// const clinicCalendarEventPath = `${CLINICS_COLLECTION}/${appointment.clinicBranchId}/${CALENDAR_COLLECTION}/${appointment.clinicCalendarEventId}`;
|
|
50
|
+
if (!calendarEventId) {
|
|
51
|
+
Logger.warn(
|
|
52
|
+
`[CalendarAdminService] Missing calendar event ID for appointment ${appointment.id}`
|
|
53
|
+
);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
62
56
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const practitionerEventRef = this.db.doc(
|
|
57
|
+
// Update practitioner calendar event
|
|
58
|
+
if (appointment.practitionerId) {
|
|
59
|
+
const practitionerEventRef = this.db.doc(
|
|
60
|
+
`${PRACTITIONERS_COLLECTION}/${appointment.practitionerId}/${CALENDAR_COLLECTION}/${calendarEventId}`
|
|
61
|
+
);
|
|
66
62
|
batch.update(practitionerEventRef, {
|
|
67
63
|
status: newStatus,
|
|
68
64
|
updatedAt: serverTimestamp,
|
|
69
65
|
});
|
|
66
|
+
updatesAdded++;
|
|
67
|
+
Logger.debug(
|
|
68
|
+
`[CalendarAdminService] Added practitioner calendar event status update to batch`
|
|
69
|
+
);
|
|
70
|
+
} else {
|
|
71
|
+
Logger.warn(
|
|
72
|
+
`[CalendarAdminService] Missing practitioner ID for appointment ${appointment.id}`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Update patient calendar event
|
|
77
|
+
if (appointment.patientId) {
|
|
78
|
+
const patientEventRef = this.db.doc(
|
|
79
|
+
`${PATIENTS_COLLECTION}/${appointment.patientId}/${CALENDAR_COLLECTION}/${calendarEventId}`
|
|
80
|
+
);
|
|
81
|
+
batch.update(patientEventRef, {
|
|
82
|
+
status: newStatus,
|
|
83
|
+
updatedAt: serverTimestamp,
|
|
84
|
+
});
|
|
85
|
+
updatesAdded++;
|
|
86
|
+
Logger.debug(
|
|
87
|
+
`[CalendarAdminService] Added patient calendar event status update to batch`
|
|
88
|
+
);
|
|
89
|
+
} else {
|
|
90
|
+
Logger.warn(
|
|
91
|
+
`[CalendarAdminService] Missing patient ID for appointment ${appointment.id}`
|
|
92
|
+
);
|
|
70
93
|
}
|
|
71
|
-
// Add similar updates for patient and clinic calendar events once their refs are confirmed
|
|
72
|
-
// if (appointment.patientCalendarEventId) { ... }
|
|
73
|
-
// if (appointment.clinicCalendarEventId) { ... }
|
|
74
94
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
95
|
+
// Update clinic calendar event
|
|
96
|
+
if (appointment.clinicBranchId) {
|
|
97
|
+
const clinicEventRef = this.db.doc(
|
|
98
|
+
`${CLINICS_COLLECTION}/${appointment.clinicBranchId}/${CALENDAR_COLLECTION}/${calendarEventId}`
|
|
99
|
+
);
|
|
100
|
+
batch.update(clinicEventRef, {
|
|
101
|
+
status: newStatus,
|
|
102
|
+
updatedAt: serverTimestamp,
|
|
103
|
+
});
|
|
104
|
+
updatesAdded++;
|
|
105
|
+
Logger.debug(
|
|
106
|
+
`[CalendarAdminService] Added clinic calendar event status update to batch`
|
|
107
|
+
);
|
|
108
|
+
} else {
|
|
109
|
+
Logger.warn(
|
|
110
|
+
`[CalendarAdminService] Missing clinic ID for appointment ${appointment.id}`
|
|
79
111
|
);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Only commit if we have updates to make
|
|
115
|
+
if (updatesAdded > 0) {
|
|
116
|
+
try {
|
|
117
|
+
await batch.commit();
|
|
118
|
+
Logger.info(
|
|
119
|
+
`[CalendarAdminService] Successfully updated ${updatesAdded} calendar event statuses for appointment ${appointment.id}.`
|
|
120
|
+
);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
Logger.error(
|
|
123
|
+
`[CalendarAdminService] Error updating calendar event statuses for appointment ${appointment.id}:`,
|
|
124
|
+
error
|
|
125
|
+
);
|
|
126
|
+
throw error; // Re-throw to allow caller to handle
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
Logger.warn(
|
|
130
|
+
`[CalendarAdminService] No calendar event status updates were made for appointment ${appointment.id}`
|
|
84
131
|
);
|
|
85
|
-
// Decide on error handling: re-throw, or log and continue?
|
|
86
132
|
}
|
|
87
133
|
}
|
|
88
134
|
|
|
@@ -91,51 +137,113 @@ export class CalendarAdminService {
|
|
|
91
137
|
* associated with a given appointment.
|
|
92
138
|
*
|
|
93
139
|
* @param appointment - The appointment object.
|
|
94
|
-
* @param newEventTime - The new CalendarEventTime object (using
|
|
140
|
+
* @param newEventTime - The new CalendarEventTime object (using admin.firestore.Timestamp).
|
|
95
141
|
* @returns {Promise<void>} A promise that resolves when all updates are attempted.
|
|
96
142
|
*/
|
|
97
143
|
async updateAppointmentCalendarEventsTime(
|
|
98
144
|
appointment: Appointment,
|
|
99
|
-
newEventTime:
|
|
145
|
+
newEventTime: {
|
|
146
|
+
start: admin.firestore.Timestamp;
|
|
147
|
+
end: admin.firestore.Timestamp;
|
|
148
|
+
}
|
|
100
149
|
): Promise<void> {
|
|
101
150
|
Logger.info(
|
|
102
151
|
`[CalendarAdminService] Updating calendar event times for appointment ${appointment.id}`
|
|
103
152
|
);
|
|
104
153
|
const batch = this.db.batch();
|
|
105
154
|
const serverTimestamp = admin.firestore.FieldValue.serverTimestamp();
|
|
155
|
+
let updatesAdded = 0;
|
|
156
|
+
|
|
157
|
+
// Get the shared calendar event ID
|
|
158
|
+
const calendarEventId = appointment.calendarEventId;
|
|
106
159
|
|
|
107
|
-
|
|
160
|
+
if (!calendarEventId) {
|
|
161
|
+
Logger.warn(
|
|
162
|
+
`[CalendarAdminService] Missing calendar event ID for appointment ${appointment.id}`
|
|
163
|
+
);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Use the timestamps directly since they are already admin.firestore.Timestamp
|
|
108
168
|
const firestoreCompatibleEventTime = {
|
|
109
|
-
start:
|
|
110
|
-
|
|
111
|
-
admin.firestore.Timestamp.now(),
|
|
112
|
-
end:
|
|
113
|
-
TimestampUtils.clientToAdmin(newEventTime.end) ||
|
|
114
|
-
admin.firestore.Timestamp.now(),
|
|
169
|
+
start: newEventTime.start,
|
|
170
|
+
end: newEventTime.end,
|
|
115
171
|
};
|
|
116
172
|
|
|
117
|
-
//
|
|
118
|
-
if (appointment.
|
|
119
|
-
// Practitioner event
|
|
173
|
+
// Update practitioner calendar event
|
|
174
|
+
if (appointment.practitionerId) {
|
|
120
175
|
const practitionerEventRef = this.db.doc(
|
|
121
|
-
`${PRACTITIONERS_COLLECTION}/${appointment.practitionerId}/${CALENDAR_COLLECTION}/${
|
|
176
|
+
`${PRACTITIONERS_COLLECTION}/${appointment.practitionerId}/${CALENDAR_COLLECTION}/${calendarEventId}`
|
|
122
177
|
);
|
|
123
178
|
batch.update(practitionerEventRef, {
|
|
124
179
|
eventTime: firestoreCompatibleEventTime,
|
|
125
180
|
updatedAt: serverTimestamp,
|
|
126
181
|
});
|
|
182
|
+
updatesAdded++;
|
|
183
|
+
Logger.debug(
|
|
184
|
+
`[CalendarAdminService] Added practitioner calendar event time update to batch`
|
|
185
|
+
);
|
|
186
|
+
} else {
|
|
187
|
+
Logger.warn(
|
|
188
|
+
`[CalendarAdminService] Missing practitioner ID for appointment ${appointment.id}`
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Update patient calendar event
|
|
193
|
+
if (appointment.patientId) {
|
|
194
|
+
const patientEventRef = this.db.doc(
|
|
195
|
+
`${PATIENTS_COLLECTION}/${appointment.patientId}/${CALENDAR_COLLECTION}/${calendarEventId}`
|
|
196
|
+
);
|
|
197
|
+
batch.update(patientEventRef, {
|
|
198
|
+
eventTime: firestoreCompatibleEventTime,
|
|
199
|
+
updatedAt: serverTimestamp,
|
|
200
|
+
});
|
|
201
|
+
updatesAdded++;
|
|
202
|
+
Logger.debug(
|
|
203
|
+
`[CalendarAdminService] Added patient calendar event time update to batch`
|
|
204
|
+
);
|
|
205
|
+
} else {
|
|
206
|
+
Logger.warn(
|
|
207
|
+
`[CalendarAdminService] Missing patient ID for appointment ${appointment.id}`
|
|
208
|
+
);
|
|
127
209
|
}
|
|
128
|
-
// Add similar updates for patient and clinic calendar events
|
|
129
210
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
211
|
+
// Update clinic calendar event
|
|
212
|
+
if (appointment.clinicBranchId) {
|
|
213
|
+
const clinicEventRef = this.db.doc(
|
|
214
|
+
`${CLINICS_COLLECTION}/${appointment.clinicBranchId}/${CALENDAR_COLLECTION}/${calendarEventId}`
|
|
134
215
|
);
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
216
|
+
batch.update(clinicEventRef, {
|
|
217
|
+
eventTime: firestoreCompatibleEventTime,
|
|
218
|
+
updatedAt: serverTimestamp,
|
|
219
|
+
});
|
|
220
|
+
updatesAdded++;
|
|
221
|
+
Logger.debug(
|
|
222
|
+
`[CalendarAdminService] Added clinic calendar event time update to batch`
|
|
223
|
+
);
|
|
224
|
+
} else {
|
|
225
|
+
Logger.warn(
|
|
226
|
+
`[CalendarAdminService] Missing clinic ID for appointment ${appointment.id}`
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Only commit if we have updates to make
|
|
231
|
+
if (updatesAdded > 0) {
|
|
232
|
+
try {
|
|
233
|
+
await batch.commit();
|
|
234
|
+
Logger.info(
|
|
235
|
+
`[CalendarAdminService] Successfully updated ${updatesAdded} calendar event times for appointment ${appointment.id}.`
|
|
236
|
+
);
|
|
237
|
+
} catch (error) {
|
|
238
|
+
Logger.error(
|
|
239
|
+
`[CalendarAdminService] Error updating calendar event times for appointment ${appointment.id}:`,
|
|
240
|
+
error
|
|
241
|
+
);
|
|
242
|
+
throw error; // Re-throw to allow caller to handle
|
|
243
|
+
}
|
|
244
|
+
} else {
|
|
245
|
+
Logger.warn(
|
|
246
|
+
`[CalendarAdminService] No calendar event time updates were made for appointment ${appointment.id}`
|
|
139
247
|
);
|
|
140
248
|
}
|
|
141
249
|
}
|
|
@@ -154,26 +262,83 @@ export class CalendarAdminService {
|
|
|
154
262
|
`[CalendarAdminService] Deleting calendar events for appointment ${appointment.id}`
|
|
155
263
|
);
|
|
156
264
|
const batch = this.db.batch();
|
|
265
|
+
let deletesAdded = 0;
|
|
157
266
|
|
|
158
|
-
//
|
|
159
|
-
|
|
160
|
-
|
|
267
|
+
// Get the shared calendar event ID
|
|
268
|
+
const calendarEventId = appointment.calendarEventId;
|
|
269
|
+
|
|
270
|
+
if (!calendarEventId) {
|
|
271
|
+
Logger.warn(
|
|
272
|
+
`[CalendarAdminService] Missing calendar event ID for appointment ${appointment.id}`
|
|
273
|
+
);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Delete practitioner calendar event
|
|
278
|
+
if (appointment.practitionerId) {
|
|
161
279
|
const practitionerEventRef = this.db.doc(
|
|
162
|
-
`${PRACTITIONERS_COLLECTION}/${appointment.practitionerId}/${CALENDAR_COLLECTION}/${
|
|
280
|
+
`${PRACTITIONERS_COLLECTION}/${appointment.practitionerId}/${CALENDAR_COLLECTION}/${calendarEventId}`
|
|
163
281
|
);
|
|
164
282
|
batch.delete(practitionerEventRef);
|
|
283
|
+
deletesAdded++;
|
|
284
|
+
Logger.debug(
|
|
285
|
+
`[CalendarAdminService] Added practitioner calendar event deletion to batch`
|
|
286
|
+
);
|
|
287
|
+
} else {
|
|
288
|
+
Logger.warn(
|
|
289
|
+
`[CalendarAdminService] Missing practitioner ID for appointment ${appointment.id}`
|
|
290
|
+
);
|
|
165
291
|
}
|
|
166
|
-
// Add similar deletes for patient and clinic calendar events
|
|
167
292
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
293
|
+
// Delete patient calendar event
|
|
294
|
+
if (appointment.patientId) {
|
|
295
|
+
const patientEventRef = this.db.doc(
|
|
296
|
+
`${PATIENTS_COLLECTION}/${appointment.patientId}/${CALENDAR_COLLECTION}/${calendarEventId}`
|
|
297
|
+
);
|
|
298
|
+
batch.delete(patientEventRef);
|
|
299
|
+
deletesAdded++;
|
|
300
|
+
Logger.debug(
|
|
301
|
+
`[CalendarAdminService] Added patient calendar event deletion to batch`
|
|
302
|
+
);
|
|
303
|
+
} else {
|
|
304
|
+
Logger.warn(
|
|
305
|
+
`[CalendarAdminService] Missing patient ID for appointment ${appointment.id}`
|
|
172
306
|
);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Delete clinic calendar event
|
|
310
|
+
if (appointment.clinicBranchId) {
|
|
311
|
+
const clinicEventRef = this.db.doc(
|
|
312
|
+
`${CLINICS_COLLECTION}/${appointment.clinicBranchId}/${CALENDAR_COLLECTION}/${calendarEventId}`
|
|
313
|
+
);
|
|
314
|
+
batch.delete(clinicEventRef);
|
|
315
|
+
deletesAdded++;
|
|
316
|
+
Logger.debug(
|
|
317
|
+
`[CalendarAdminService] Added clinic calendar event deletion to batch`
|
|
318
|
+
);
|
|
319
|
+
} else {
|
|
320
|
+
Logger.warn(
|
|
321
|
+
`[CalendarAdminService] Missing clinic ID for appointment ${appointment.id}`
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Only commit if we have deletions to make
|
|
326
|
+
if (deletesAdded > 0) {
|
|
327
|
+
try {
|
|
328
|
+
await batch.commit();
|
|
329
|
+
Logger.info(
|
|
330
|
+
`[CalendarAdminService] Successfully deleted ${deletesAdded} calendar events for appointment ${appointment.id}.`
|
|
331
|
+
);
|
|
332
|
+
} catch (error) {
|
|
333
|
+
Logger.error(
|
|
334
|
+
`[CalendarAdminService] Error deleting calendar events for appointment ${appointment.id}:`,
|
|
335
|
+
error
|
|
336
|
+
);
|
|
337
|
+
throw error; // Re-throw to allow caller to handle
|
|
338
|
+
}
|
|
339
|
+
} else {
|
|
340
|
+
Logger.warn(
|
|
341
|
+
`[CalendarAdminService] No calendar event deletions were made for appointment ${appointment.id}`
|
|
177
342
|
);
|
|
178
343
|
}
|
|
179
344
|
}
|
|
@@ -1142,6 +1142,7 @@ export class CalendarServiceV2 extends BaseService {
|
|
|
1142
1142
|
CalendarEventStatus.CANCELED,
|
|
1143
1143
|
CalendarEventStatus.COMPLETED,
|
|
1144
1144
|
CalendarEventStatus.RESCHEDULED,
|
|
1145
|
+
CalendarEventStatus.NO_SHOW,
|
|
1145
1146
|
],
|
|
1146
1147
|
[CalendarEventStatus.REJECTED]: [],
|
|
1147
1148
|
[CalendarEventStatus.CANCELED]: [],
|
|
@@ -1150,6 +1151,7 @@ export class CalendarServiceV2 extends BaseService {
|
|
|
1150
1151
|
CalendarEventStatus.CANCELED,
|
|
1151
1152
|
],
|
|
1152
1153
|
[CalendarEventStatus.COMPLETED]: [],
|
|
1154
|
+
[CalendarEventStatus.NO_SHOW]: [],
|
|
1153
1155
|
};
|
|
1154
1156
|
|
|
1155
1157
|
// Check if transition is valid
|
|
@@ -27,6 +27,7 @@ export enum CalendarEventStatus {
|
|
|
27
27
|
CANCELED = "canceled", // When event is canceled by the patient
|
|
28
28
|
RESCHEDULED = "rescheduled", // When event is rescheduled by the clinic administrator
|
|
29
29
|
COMPLETED = "completed", // When event is completed
|
|
30
|
+
NO_SHOW = "no_show", // When event is no-show by the patient
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
/**
|