@blackcode_sa/metaestetics-api 1.4.18 → 1.5.1

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.
@@ -0,0 +1,510 @@
1
+ import {
2
+ collection,
3
+ doc,
4
+ getDoc,
5
+ getDocs,
6
+ setDoc,
7
+ updateDoc,
8
+ deleteDoc,
9
+ query,
10
+ where,
11
+ orderBy,
12
+ Timestamp,
13
+ serverTimestamp,
14
+ Firestore,
15
+ DocumentReference,
16
+ QueryConstraint,
17
+ } from "firebase/firestore";
18
+ import {
19
+ CalendarEvent,
20
+ CalendarEventStatus,
21
+ CalendarEventTime,
22
+ CalendarEventType,
23
+ CalendarSyncStatus,
24
+ CreateCalendarEventData,
25
+ UpdateCalendarEventData,
26
+ CALENDAR_COLLECTION,
27
+ } from "../../../types/calendar";
28
+ import { PRACTITIONERS_COLLECTION } from "../../../types/practitioner";
29
+ import { PATIENTS_COLLECTION } from "../../../types/patient";
30
+ import { CLINICS_COLLECTION } from "../../../types/clinic";
31
+
32
+ /**
33
+ * Creates a calendar event for a practitioner
34
+ * @param db - Firestore instance
35
+ * @param practitionerId - ID of the practitioner
36
+ * @param eventData - Calendar event data
37
+ * @param generateId - Function to generate a unique ID
38
+ * @returns Created calendar event
39
+ */
40
+ export async function createPractitionerCalendarEventUtil(
41
+ db: Firestore,
42
+ practitionerId: string,
43
+ eventData: Omit<CreateCalendarEventData, "id" | "createdAt" | "updatedAt">,
44
+ generateId: () => string
45
+ ): Promise<CalendarEvent> {
46
+ // TODO: Add validation for event data
47
+ // - Check if practitioner exists
48
+ // - Validate event time (start < end)
49
+ // - Check for overlapping events
50
+ // - Validate required fields
51
+
52
+ const eventId = generateId();
53
+ const eventRef = doc(
54
+ db,
55
+ `${PRACTITIONERS_COLLECTION}/${practitionerId}/${CALENDAR_COLLECTION}/${eventId}`
56
+ );
57
+
58
+ const newEvent: CreateCalendarEventData = {
59
+ id: eventId,
60
+ ...eventData,
61
+ createdAt: serverTimestamp(),
62
+ updatedAt: serverTimestamp(),
63
+ };
64
+
65
+ await setDoc(eventRef, newEvent);
66
+
67
+ // Convert server timestamp to Timestamp for return value
68
+ return {
69
+ ...newEvent,
70
+ createdAt: Timestamp.now(),
71
+ updatedAt: Timestamp.now(),
72
+ } as CalendarEvent;
73
+ }
74
+
75
+ /**
76
+ * Creates a calendar event for a patient
77
+ * @param db - Firestore instance
78
+ * @param patientId - ID of the patient
79
+ * @param eventData - Calendar event data
80
+ * @param generateId - Function to generate a unique ID
81
+ * @returns Created calendar event
82
+ */
83
+ export async function createPatientCalendarEventUtil(
84
+ db: Firestore,
85
+ patientId: string,
86
+ eventData: Omit<CreateCalendarEventData, "id" | "createdAt" | "updatedAt">,
87
+ generateId: () => string
88
+ ): Promise<CalendarEvent> {
89
+ // TODO: Add validation for event data
90
+ // - Check if patient exists
91
+ // - Validate event time (start < end)
92
+ // - Check for overlapping events
93
+ // - Validate required fields
94
+
95
+ const eventId = generateId();
96
+ const eventRef = doc(
97
+ db,
98
+ `${PATIENTS_COLLECTION}/${patientId}/${CALENDAR_COLLECTION}/${eventId}`
99
+ );
100
+
101
+ const newEvent: CreateCalendarEventData = {
102
+ id: eventId,
103
+ ...eventData,
104
+ createdAt: serverTimestamp(),
105
+ updatedAt: serverTimestamp(),
106
+ };
107
+
108
+ await setDoc(eventRef, newEvent);
109
+
110
+ // Convert server timestamp to Timestamp for return value
111
+ return {
112
+ ...newEvent,
113
+ createdAt: Timestamp.now(),
114
+ updatedAt: Timestamp.now(),
115
+ } as CalendarEvent;
116
+ }
117
+
118
+ /**
119
+ * Creates a calendar event for a clinic
120
+ * @param db - Firestore instance
121
+ * @param clinicId - ID of the clinic
122
+ * @param eventData - Calendar event data
123
+ * @param generateId - Function to generate a unique ID
124
+ * @returns Created calendar event
125
+ */
126
+ export async function createClinicCalendarEventUtil(
127
+ db: Firestore,
128
+ clinicId: string,
129
+ eventData: Omit<CreateCalendarEventData, "id" | "createdAt" | "updatedAt">,
130
+ generateId: () => string
131
+ ): Promise<CalendarEvent> {
132
+ // TODO: Add validation for event data
133
+ // - Check if clinic exists
134
+ // - Validate event time (start < end)
135
+ // - Check for overlapping events
136
+ // - Validate required fields
137
+
138
+ const eventId = generateId();
139
+ const eventRef = doc(
140
+ db,
141
+ `${CLINICS_COLLECTION}/${clinicId}/${CALENDAR_COLLECTION}/${eventId}`
142
+ );
143
+
144
+ const newEvent: CreateCalendarEventData = {
145
+ id: eventId,
146
+ ...eventData,
147
+ createdAt: serverTimestamp(),
148
+ updatedAt: serverTimestamp(),
149
+ };
150
+
151
+ await setDoc(eventRef, newEvent);
152
+
153
+ // Convert server timestamp to Timestamp for return value
154
+ return {
155
+ ...newEvent,
156
+ createdAt: Timestamp.now(),
157
+ updatedAt: Timestamp.now(),
158
+ } as CalendarEvent;
159
+ }
160
+
161
+ /**
162
+ * Gets a calendar event for a practitioner
163
+ * @param db - Firestore instance
164
+ * @param practitionerId - ID of the practitioner
165
+ * @param eventId - ID of the event
166
+ * @returns Calendar event or null if not found
167
+ */
168
+ export async function getPractitionerCalendarEventUtil(
169
+ db: Firestore,
170
+ practitionerId: string,
171
+ eventId: string
172
+ ): Promise<CalendarEvent | null> {
173
+ const eventRef = doc(
174
+ db,
175
+ `${PRACTITIONERS_COLLECTION}/${practitionerId}/${CALENDAR_COLLECTION}/${eventId}`
176
+ );
177
+ const eventDoc = await getDoc(eventRef);
178
+
179
+ if (!eventDoc.exists()) {
180
+ return null;
181
+ }
182
+
183
+ return eventDoc.data() as CalendarEvent;
184
+ }
185
+
186
+ /**
187
+ * Gets a calendar event for a patient
188
+ * @param db - Firestore instance
189
+ * @param patientId - ID of the patient
190
+ * @param eventId - ID of the event
191
+ * @returns Calendar event or null if not found
192
+ */
193
+ export async function getPatientCalendarEventUtil(
194
+ db: Firestore,
195
+ patientId: string,
196
+ eventId: string
197
+ ): Promise<CalendarEvent | null> {
198
+ const eventRef = doc(
199
+ db,
200
+ `${PATIENTS_COLLECTION}/${patientId}/${CALENDAR_COLLECTION}/${eventId}`
201
+ );
202
+ const eventDoc = await getDoc(eventRef);
203
+
204
+ if (!eventDoc.exists()) {
205
+ return null;
206
+ }
207
+
208
+ return eventDoc.data() as CalendarEvent;
209
+ }
210
+
211
+ /**
212
+ * Gets a calendar event for a clinic
213
+ * @param db - Firestore instance
214
+ * @param clinicId - ID of the clinic
215
+ * @param eventId - ID of the event
216
+ * @returns Calendar event or null if not found
217
+ */
218
+ export async function getClinicCalendarEventUtil(
219
+ db: Firestore,
220
+ clinicId: string,
221
+ eventId: string
222
+ ): Promise<CalendarEvent | null> {
223
+ const eventRef = doc(
224
+ db,
225
+ `${CLINICS_COLLECTION}/${clinicId}/${CALENDAR_COLLECTION}/${eventId}`
226
+ );
227
+ const eventDoc = await getDoc(eventRef);
228
+
229
+ if (!eventDoc.exists()) {
230
+ return null;
231
+ }
232
+
233
+ return eventDoc.data() as CalendarEvent;
234
+ }
235
+
236
+ /**
237
+ * Gets calendar events for a practitioner within a date range
238
+ * @param db - Firestore instance
239
+ * @param practitionerId - ID of the practitioner
240
+ * @param startDate - Start date of the range
241
+ * @param endDate - End date of the range
242
+ * @returns Array of calendar events
243
+ */
244
+ export async function getPractitionerCalendarEventsUtil(
245
+ db: Firestore,
246
+ practitionerId: string,
247
+ startDate: Date,
248
+ endDate: Date
249
+ ): Promise<CalendarEvent[]> {
250
+ const startTimestamp = Timestamp.fromDate(startDate);
251
+ const endTimestamp = Timestamp.fromDate(endDate);
252
+
253
+ const eventsRef = collection(
254
+ db,
255
+ `${PRACTITIONERS_COLLECTION}/${practitionerId}/${CALENDAR_COLLECTION}`
256
+ );
257
+
258
+ const q = query(
259
+ eventsRef,
260
+ where("eventTime.start", ">=", startTimestamp),
261
+ where("eventTime.end", "<=", endTimestamp),
262
+ orderBy("eventTime.start", "asc")
263
+ );
264
+
265
+ const querySnapshot = await getDocs(q);
266
+ return querySnapshot.docs.map((doc) => doc.data() as CalendarEvent);
267
+ }
268
+
269
+ /**
270
+ * Gets calendar events for a patient within a date range
271
+ * @param db - Firestore instance
272
+ * @param patientId - ID of the patient
273
+ * @param startDate - Start date of the range
274
+ * @param endDate - End date of the range
275
+ * @returns Array of calendar events
276
+ */
277
+ export async function getPatientCalendarEventsUtil(
278
+ db: Firestore,
279
+ patientId: string,
280
+ startDate: Date,
281
+ endDate: Date
282
+ ): Promise<CalendarEvent[]> {
283
+ const startTimestamp = Timestamp.fromDate(startDate);
284
+ const endTimestamp = Timestamp.fromDate(endDate);
285
+
286
+ const eventsRef = collection(
287
+ db,
288
+ `${PATIENTS_COLLECTION}/${patientId}/${CALENDAR_COLLECTION}`
289
+ );
290
+
291
+ const q = query(
292
+ eventsRef,
293
+ where("eventTime.start", ">=", startTimestamp),
294
+ where("eventTime.end", "<=", endTimestamp),
295
+ orderBy("eventTime.start", "asc")
296
+ );
297
+
298
+ const querySnapshot = await getDocs(q);
299
+ return querySnapshot.docs.map((doc) => doc.data() as CalendarEvent);
300
+ }
301
+
302
+ /**
303
+ * Gets calendar events for a clinic within a date range
304
+ * @param db - Firestore instance
305
+ * @param clinicId - ID of the clinic
306
+ * @param startDate - Start date of the range
307
+ * @param endDate - End date of the range
308
+ * @returns Array of calendar events
309
+ */
310
+ export async function getClinicCalendarEventsUtil(
311
+ db: Firestore,
312
+ clinicId: string,
313
+ startDate: Date,
314
+ endDate: Date
315
+ ): Promise<CalendarEvent[]> {
316
+ const startTimestamp = Timestamp.fromDate(startDate);
317
+ const endTimestamp = Timestamp.fromDate(endDate);
318
+
319
+ const eventsRef = collection(
320
+ db,
321
+ `${CLINICS_COLLECTION}/${clinicId}/${CALENDAR_COLLECTION}`
322
+ );
323
+
324
+ const q = query(
325
+ eventsRef,
326
+ where("eventTime.start", ">=", startTimestamp),
327
+ where("eventTime.end", "<=", endTimestamp),
328
+ orderBy("eventTime.start", "asc")
329
+ );
330
+
331
+ const querySnapshot = await getDocs(q);
332
+ return querySnapshot.docs.map((doc) => doc.data() as CalendarEvent);
333
+ }
334
+
335
+ /**
336
+ * Updates a calendar event for a practitioner
337
+ * @param db - Firestore instance
338
+ * @param practitionerId - ID of the practitioner
339
+ * @param eventId - ID of the event
340
+ * @param updateData - Data to update
341
+ * @returns Updated calendar event
342
+ */
343
+ export async function updatePractitionerCalendarEventUtil(
344
+ db: Firestore,
345
+ practitionerId: string,
346
+ eventId: string,
347
+ updateData: Omit<UpdateCalendarEventData, "updatedAt">
348
+ ): Promise<CalendarEvent> {
349
+ // TODO: Add validation for update data
350
+ // - Check if event exists
351
+ // - Validate event time (start < end)
352
+ // - Check for overlapping events
353
+
354
+ const eventRef = doc(
355
+ db,
356
+ `${PRACTITIONERS_COLLECTION}/${practitionerId}/${CALENDAR_COLLECTION}/${eventId}`
357
+ );
358
+
359
+ const updates: UpdateCalendarEventData = {
360
+ ...updateData,
361
+ updatedAt: serverTimestamp(),
362
+ };
363
+
364
+ await updateDoc(eventRef, updates as any);
365
+
366
+ // Get the updated document
367
+ const updatedDoc = await getDoc(eventRef);
368
+
369
+ if (!updatedDoc.exists()) {
370
+ throw new Error("Event not found after update");
371
+ }
372
+
373
+ return updatedDoc.data() as CalendarEvent;
374
+ }
375
+
376
+ /**
377
+ * Updates a calendar event for a patient
378
+ * @param db - Firestore instance
379
+ * @param patientId - ID of the patient
380
+ * @param eventId - ID of the event
381
+ * @param updateData - Data to update
382
+ * @returns Updated calendar event
383
+ */
384
+ export async function updatePatientCalendarEventUtil(
385
+ db: Firestore,
386
+ patientId: string,
387
+ eventId: string,
388
+ updateData: Omit<UpdateCalendarEventData, "updatedAt">
389
+ ): Promise<CalendarEvent> {
390
+ // TODO: Add validation for update data
391
+ // - Check if event exists
392
+ // - Validate event time (start < end)
393
+ // - Check for overlapping events
394
+
395
+ const eventRef = doc(
396
+ db,
397
+ `${PATIENTS_COLLECTION}/${patientId}/${CALENDAR_COLLECTION}/${eventId}`
398
+ );
399
+
400
+ const updates: UpdateCalendarEventData = {
401
+ ...updateData,
402
+ updatedAt: serverTimestamp(),
403
+ };
404
+
405
+ await updateDoc(eventRef, updates as any);
406
+
407
+ // Get the updated document
408
+ const updatedDoc = await getDoc(eventRef);
409
+
410
+ if (!updatedDoc.exists()) {
411
+ throw new Error("Event not found after update");
412
+ }
413
+
414
+ return updatedDoc.data() as CalendarEvent;
415
+ }
416
+
417
+ /**
418
+ * Updates a calendar event for a clinic
419
+ * @param db - Firestore instance
420
+ * @param clinicId - ID of the clinic
421
+ * @param eventId - ID of the event
422
+ * @param updateData - Data to update
423
+ * @returns Updated calendar event
424
+ */
425
+ export async function updateClinicCalendarEventUtil(
426
+ db: Firestore,
427
+ clinicId: string,
428
+ eventId: string,
429
+ updateData: Omit<UpdateCalendarEventData, "updatedAt">
430
+ ): Promise<CalendarEvent> {
431
+ // TODO: Add validation for update data
432
+ // - Check if event exists
433
+ // - Validate event time (start < end)
434
+ // - Check for overlapping events
435
+
436
+ const eventRef = doc(
437
+ db,
438
+ `${CLINICS_COLLECTION}/${clinicId}/${CALENDAR_COLLECTION}/${eventId}`
439
+ );
440
+
441
+ const updates: UpdateCalendarEventData = {
442
+ ...updateData,
443
+ updatedAt: serverTimestamp(),
444
+ };
445
+
446
+ await updateDoc(eventRef, updates as any);
447
+
448
+ // Get the updated document
449
+ const updatedDoc = await getDoc(eventRef);
450
+
451
+ if (!updatedDoc.exists()) {
452
+ throw new Error("Event not found after update");
453
+ }
454
+
455
+ return updatedDoc.data() as CalendarEvent;
456
+ }
457
+
458
+ /**
459
+ * Deletes a calendar event for a practitioner
460
+ * @param db - Firestore instance
461
+ * @param practitionerId - ID of the practitioner
462
+ * @param eventId - ID of the event
463
+ */
464
+ export async function deletePractitionerCalendarEventUtil(
465
+ db: Firestore,
466
+ practitionerId: string,
467
+ eventId: string
468
+ ): Promise<void> {
469
+ const eventRef = doc(
470
+ db,
471
+ `${PRACTITIONERS_COLLECTION}/${practitionerId}/${CALENDAR_COLLECTION}/${eventId}`
472
+ );
473
+ await deleteDoc(eventRef);
474
+ }
475
+
476
+ /**
477
+ * Deletes a calendar event for a patient
478
+ * @param db - Firestore instance
479
+ * @param patientId - ID of the patient
480
+ * @param eventId - ID of the event
481
+ */
482
+ export async function deletePatientCalendarEventUtil(
483
+ db: Firestore,
484
+ patientId: string,
485
+ eventId: string
486
+ ): Promise<void> {
487
+ const eventRef = doc(
488
+ db,
489
+ `${PATIENTS_COLLECTION}/${patientId}/${CALENDAR_COLLECTION}/${eventId}`
490
+ );
491
+ await deleteDoc(eventRef);
492
+ }
493
+
494
+ /**
495
+ * Deletes a calendar event for a clinic
496
+ * @param db - Firestore instance
497
+ * @param clinicId - ID of the clinic
498
+ * @param eventId - ID of the event
499
+ */
500
+ export async function deleteClinicCalendarEventUtil(
501
+ db: Firestore,
502
+ clinicId: string,
503
+ eventId: string
504
+ ): Promise<void> {
505
+ const eventRef = doc(
506
+ db,
507
+ `${CLINICS_COLLECTION}/${clinicId}/${CALENDAR_COLLECTION}/${eventId}`
508
+ );
509
+ await deleteDoc(eventRef);
510
+ }