@blackcode_sa/metaestetics-api 1.4.17 → 1.5.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.
Files changed (31) hide show
  1. package/dist/index.d.mts +9633 -7023
  2. package/dist/index.d.ts +9633 -7023
  3. package/dist/index.js +2773 -150
  4. package/dist/index.mjs +2809 -150
  5. package/package.json +4 -3
  6. package/src/index.ts +48 -1
  7. package/src/services/calendar/calendar-refactored.service.ts +1531 -0
  8. package/src/services/calendar/calendar.service.ts +1077 -0
  9. package/src/services/calendar/synced-calendars.service.ts +743 -0
  10. package/src/services/calendar/utils/appointment.utils.ts +314 -0
  11. package/src/services/calendar/utils/calendar-event.utils.ts +510 -0
  12. package/src/services/calendar/utils/clinic.utils.ts +237 -0
  13. package/src/services/calendar/utils/docs.utils.ts +157 -0
  14. package/src/services/calendar/utils/google-calendar.utils.ts +697 -0
  15. package/src/services/calendar/utils/index.ts +8 -0
  16. package/src/services/calendar/utils/patient.utils.ts +198 -0
  17. package/src/services/calendar/utils/practitioner.utils.ts +221 -0
  18. package/src/services/calendar/utils/synced-calendar.utils.ts +472 -0
  19. package/src/services/clinic/clinic.service.ts +2 -2
  20. package/src/services/clinic/utils/clinic.utils.ts +49 -47
  21. package/src/services/practitioner/practitioner.service.ts +1 -0
  22. package/src/types/calendar/index.ts +187 -0
  23. package/src/types/calendar/synced-calendar.types.ts +66 -0
  24. package/src/types/clinic/index.ts +4 -15
  25. package/src/types/index.ts +4 -0
  26. package/src/types/practitioner/index.ts +21 -0
  27. package/src/types/profile/index.ts +39 -0
  28. package/src/validations/calendar.schema.ts +223 -0
  29. package/src/validations/clinic.schema.ts +3 -3
  30. package/src/validations/practitioner.schema.ts +21 -0
  31. package/src/validations/profile-info.schema.ts +41 -0
@@ -0,0 +1,314 @@
1
+ import { Firestore, Timestamp } from "firebase/firestore";
2
+ import {
3
+ CalendarEvent,
4
+ CalendarEventStatus,
5
+ CalendarEventTime,
6
+ CalendarEventType,
7
+ CalendarSyncStatus,
8
+ CreateCalendarEventData,
9
+ UpdateCalendarEventData,
10
+ } from "../../../types/calendar";
11
+ import {
12
+ createClinicCalendarEventUtil,
13
+ updateClinicCalendarEventUtil,
14
+ deleteClinicCalendarEventUtil,
15
+ checkAutoConfirmAppointmentsUtil,
16
+ } from "./clinic.utils";
17
+ import {
18
+ createPatientCalendarEventUtil,
19
+ updatePatientCalendarEventUtil,
20
+ deletePatientCalendarEventUtil,
21
+ } from "./patient.utils";
22
+ import {
23
+ createPractitionerCalendarEventUtil,
24
+ updatePractitionerCalendarEventUtil,
25
+ deletePractitionerCalendarEventUtil,
26
+ } from "./practitioner.utils";
27
+
28
+ /**
29
+ * Creates an appointment across all relevant calendars (practitioner, patient, clinic)
30
+ * @param db - Firestore instance
31
+ * @param clinicId - ID of the clinic
32
+ * @param practitionerId - ID of the practitioner
33
+ * @param patientId - ID of the patient
34
+ * @param eventData - Calendar event data
35
+ * @param generateId - Function to generate a unique ID
36
+ * @returns Created calendar event
37
+ */
38
+ export async function createAppointmentUtil(
39
+ db: Firestore,
40
+ clinicId: string,
41
+ practitionerId: string,
42
+ patientId: string,
43
+ eventData: Omit<
44
+ CreateCalendarEventData,
45
+ | "id"
46
+ | "createdAt"
47
+ | "updatedAt"
48
+ | "clinicBranchId"
49
+ | "practitionerProfileId"
50
+ | "patientProfileId"
51
+ >,
52
+ generateId: () => string
53
+ ): Promise<CalendarEvent> {
54
+ // TODO: Add validation for appointment data
55
+ // - Check if all entities exist
56
+ // - Validate event time (start < end)
57
+ // - Check for overlapping events
58
+ // - Validate required fields
59
+
60
+ // Generate a single ID to be used across all calendars
61
+ const eventId = generateId();
62
+
63
+ // Check if the clinic has auto-confirm appointments enabled
64
+ const autoConfirm = await checkAutoConfirmAppointmentsUtil(db, clinicId);
65
+
66
+ // Set the initial status based on auto-confirm setting
67
+ const initialStatus = autoConfirm
68
+ ? CalendarEventStatus.CONFIRMED
69
+ : CalendarEventStatus.PENDING;
70
+
71
+ // Prepare the event data with all required IDs
72
+ const appointmentData: Omit<
73
+ CreateCalendarEventData,
74
+ "id" | "createdAt" | "updatedAt"
75
+ > = {
76
+ ...eventData,
77
+ clinicBranchId: clinicId,
78
+ practitionerProfileId: practitionerId,
79
+ patientProfileId: patientId,
80
+ eventType: CalendarEventType.APPOINTMENT,
81
+ status: eventData.status || initialStatus,
82
+ };
83
+
84
+ // Create the event in all three calendars
85
+ const clinicPromise = createClinicCalendarEventUtil(
86
+ db,
87
+ clinicId,
88
+ appointmentData,
89
+ () => eventId // Use the same ID for all calendars
90
+ );
91
+
92
+ const practitionerPromise = createPractitionerCalendarEventUtil(
93
+ db,
94
+ practitionerId,
95
+ appointmentData,
96
+ () => eventId // Use the same ID for all calendars
97
+ );
98
+
99
+ const patientPromise = createPatientCalendarEventUtil(
100
+ db,
101
+ patientId,
102
+ appointmentData,
103
+ () => eventId // Use the same ID for all calendars
104
+ );
105
+
106
+ // Wait for all operations to complete
107
+ const [clinicEvent] = await Promise.all([
108
+ clinicPromise,
109
+ practitionerPromise,
110
+ patientPromise,
111
+ ]);
112
+
113
+ // Return the event from the clinic calendar
114
+ return clinicEvent;
115
+ }
116
+
117
+ /**
118
+ * Updates an appointment across all relevant calendars (practitioner, patient, clinic)
119
+ * @param db - Firestore instance
120
+ * @param clinicId - ID of the clinic
121
+ * @param practitionerId - ID of the practitioner
122
+ * @param patientId - ID of the patient
123
+ * @param eventId - ID of the event
124
+ * @param updateData - Data to update
125
+ * @returns Updated calendar event
126
+ */
127
+ export async function updateAppointmentUtil(
128
+ db: Firestore,
129
+ clinicId: string,
130
+ practitionerId: string,
131
+ patientId: string,
132
+ eventId: string,
133
+ updateData: Omit<UpdateCalendarEventData, "updatedAt">
134
+ ): Promise<CalendarEvent> {
135
+ // TODO: Add validation for update data
136
+ // - Check if event exists in all calendars
137
+ // - Validate event time (start < end)
138
+ // - Check for overlapping events
139
+
140
+ // Update the event in all three calendars
141
+ const clinicPromise = updateClinicCalendarEventUtil(
142
+ db,
143
+ clinicId,
144
+ eventId,
145
+ updateData
146
+ );
147
+
148
+ const practitionerPromise = updatePractitionerCalendarEventUtil(
149
+ db,
150
+ practitionerId,
151
+ eventId,
152
+ updateData
153
+ );
154
+
155
+ const patientPromise = updatePatientCalendarEventUtil(
156
+ db,
157
+ patientId,
158
+ eventId,
159
+ updateData
160
+ );
161
+
162
+ // Wait for all operations to complete
163
+ const [clinicEvent] = await Promise.all([
164
+ clinicPromise,
165
+ practitionerPromise,
166
+ patientPromise,
167
+ ]);
168
+
169
+ // Return the event from the clinic calendar
170
+ return clinicEvent;
171
+ }
172
+
173
+ /**
174
+ * Deletes an appointment across all relevant calendars (practitioner, patient, clinic)
175
+ * @param db - Firestore instance
176
+ * @param clinicId - ID of the clinic
177
+ * @param practitionerId - ID of the practitioner
178
+ * @param patientId - ID of the patient
179
+ * @param eventId - ID of the event
180
+ */
181
+ export async function deleteAppointmentUtil(
182
+ db: Firestore,
183
+ clinicId: string,
184
+ practitionerId: string,
185
+ patientId: string,
186
+ eventId: string
187
+ ): Promise<void> {
188
+ // Delete the event from all three calendars
189
+ const clinicPromise = deleteClinicCalendarEventUtil(db, clinicId, eventId);
190
+
191
+ const practitionerPromise = deletePractitionerCalendarEventUtil(
192
+ db,
193
+ practitionerId,
194
+ eventId
195
+ );
196
+
197
+ const patientPromise = deletePatientCalendarEventUtil(db, patientId, eventId);
198
+
199
+ // Wait for all operations to complete
200
+ await Promise.all([clinicPromise, practitionerPromise, patientPromise]);
201
+ }
202
+
203
+ /**
204
+ * Confirms an appointment
205
+ * @param db - Firestore instance
206
+ * @param clinicId - ID of the clinic
207
+ * @param practitionerId - ID of the practitioner
208
+ * @param patientId - ID of the patient
209
+ * @param eventId - ID of the event
210
+ * @returns Confirmed calendar event
211
+ */
212
+ export async function confirmAppointmentUtil(
213
+ db: Firestore,
214
+ clinicId: string,
215
+ practitionerId: string,
216
+ patientId: string,
217
+ eventId: string
218
+ ): Promise<CalendarEvent> {
219
+ return updateAppointmentUtil(
220
+ db,
221
+ clinicId,
222
+ practitionerId,
223
+ patientId,
224
+ eventId,
225
+ { status: CalendarEventStatus.CONFIRMED }
226
+ );
227
+ }
228
+
229
+ /**
230
+ * Rejects an appointment
231
+ * @param db - Firestore instance
232
+ * @param clinicId - ID of the clinic
233
+ * @param practitionerId - ID of the practitioner
234
+ * @param patientId - ID of the patient
235
+ * @param eventId - ID of the event
236
+ * @returns Rejected calendar event
237
+ */
238
+ export async function rejectAppointmentUtil(
239
+ db: Firestore,
240
+ clinicId: string,
241
+ practitionerId: string,
242
+ patientId: string,
243
+ eventId: string
244
+ ): Promise<CalendarEvent> {
245
+ return updateAppointmentUtil(
246
+ db,
247
+ clinicId,
248
+ practitionerId,
249
+ patientId,
250
+ eventId,
251
+ { status: CalendarEventStatus.REJECTED }
252
+ );
253
+ }
254
+
255
+ /**
256
+ * Cancels an appointment
257
+ * @param db - Firestore instance
258
+ * @param clinicId - ID of the clinic
259
+ * @param practitionerId - ID of the practitioner
260
+ * @param patientId - ID of the patient
261
+ * @param eventId - ID of the event
262
+ * @returns Canceled calendar event
263
+ */
264
+ export async function cancelAppointmentUtil(
265
+ db: Firestore,
266
+ clinicId: string,
267
+ practitionerId: string,
268
+ patientId: string,
269
+ eventId: string
270
+ ): Promise<CalendarEvent> {
271
+ return updateAppointmentUtil(
272
+ db,
273
+ clinicId,
274
+ practitionerId,
275
+ patientId,
276
+ eventId,
277
+ { status: CalendarEventStatus.CANCELED }
278
+ );
279
+ }
280
+
281
+ /**
282
+ * Reschedules an appointment
283
+ * @param db - Firestore instance
284
+ * @param clinicId - ID of the clinic
285
+ * @param practitionerId - ID of the practitioner
286
+ * @param patientId - ID of the patient
287
+ * @param eventId - ID of the event
288
+ * @param newEventTime - New event time
289
+ * @returns Rescheduled calendar event
290
+ */
291
+ export async function rescheduleAppointmentUtil(
292
+ db: Firestore,
293
+ clinicId: string,
294
+ practitionerId: string,
295
+ patientId: string,
296
+ eventId: string,
297
+ newEventTime: CalendarEventTime
298
+ ): Promise<CalendarEvent> {
299
+ // TODO: Add validation for new event time
300
+ // - Validate event time (start < end)
301
+ // - Check for overlapping events
302
+
303
+ return updateAppointmentUtil(
304
+ db,
305
+ clinicId,
306
+ practitionerId,
307
+ patientId,
308
+ eventId,
309
+ {
310
+ status: CalendarEventStatus.RESCHEDULED,
311
+ eventTime: newEventTime,
312
+ }
313
+ );
314
+ }