@blackcode_sa/metaestetics-api 1.13.18 → 1.13.20

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.
@@ -1882,6 +1882,8 @@ declare enum SyncedCalendarProvider {
1882
1882
  declare enum CalendarEventStatus {
1883
1883
  PENDING = "pending",// When event is created, but not confirmed
1884
1884
  CONFIRMED = "confirmed",// When event is confirmed and ready to be used
1885
+ CHECKED_IN = "checked_in",// Patient has arrived and checked in
1886
+ IN_PROGRESS = "in_progress",// Procedure has started
1885
1887
  REJECTED = "rejected",// When event is rejected by the clinic administrator or patient
1886
1888
  CANCELED = "canceled",// When event is canceled by the patient
1887
1889
  RESCHEDULED = "rescheduled",// When event is rescheduled by the clinic administrator
@@ -1882,6 +1882,8 @@ declare enum SyncedCalendarProvider {
1882
1882
  declare enum CalendarEventStatus {
1883
1883
  PENDING = "pending",// When event is created, but not confirmed
1884
1884
  CONFIRMED = "confirmed",// When event is confirmed and ready to be used
1885
+ CHECKED_IN = "checked_in",// Patient has arrived and checked in
1886
+ IN_PROGRESS = "in_progress",// Procedure has started
1885
1887
  REJECTED = "rejected",// When event is rejected by the clinic administrator or patient
1886
1888
  CANCELED = "canceled",// When event is canceled by the patient
1887
1889
  RESCHEDULED = "rescheduled",// When event is rescheduled by the clinic administrator
package/dist/index.d.mts CHANGED
@@ -2756,6 +2756,8 @@ declare const SYNCED_CALENDARS_COLLECTION = "syncedCalendars";
2756
2756
  declare enum CalendarEventStatus {
2757
2757
  PENDING = "pending",// When event is created, but not confirmed
2758
2758
  CONFIRMED = "confirmed",// When event is confirmed and ready to be used
2759
+ CHECKED_IN = "checked_in",// Patient has arrived and checked in
2760
+ IN_PROGRESS = "in_progress",// Procedure has started
2759
2761
  REJECTED = "rejected",// When event is rejected by the clinic administrator or patient
2760
2762
  CANCELED = "canceled",// When event is canceled by the patient
2761
2763
  RESCHEDULED = "rescheduled",// When event is rescheduled by the clinic administrator
package/dist/index.d.ts CHANGED
@@ -2756,6 +2756,8 @@ declare const SYNCED_CALENDARS_COLLECTION = "syncedCalendars";
2756
2756
  declare enum CalendarEventStatus {
2757
2757
  PENDING = "pending",// When event is created, but not confirmed
2758
2758
  CONFIRMED = "confirmed",// When event is confirmed and ready to be used
2759
+ CHECKED_IN = "checked_in",// Patient has arrived and checked in
2760
+ IN_PROGRESS = "in_progress",// Procedure has started
2759
2761
  REJECTED = "rejected",// When event is rejected by the clinic administrator or patient
2760
2762
  CANCELED = "canceled",// When event is canceled by the patient
2761
2763
  RESCHEDULED = "rescheduled",// When event is rescheduled by the clinic administrator
package/dist/index.js CHANGED
@@ -4473,6 +4473,8 @@ var import_firestore6 = require("firebase/firestore");
4473
4473
  var CalendarEventStatus = /* @__PURE__ */ ((CalendarEventStatus4) => {
4474
4474
  CalendarEventStatus4["PENDING"] = "pending";
4475
4475
  CalendarEventStatus4["CONFIRMED"] = "confirmed";
4476
+ CalendarEventStatus4["CHECKED_IN"] = "checked_in";
4477
+ CalendarEventStatus4["IN_PROGRESS"] = "in_progress";
4476
4478
  CalendarEventStatus4["REJECTED"] = "rejected";
4477
4479
  CalendarEventStatus4["CANCELED"] = "canceled";
4478
4480
  CalendarEventStatus4["RESCHEDULED"] = "rescheduled";
@@ -4604,7 +4606,7 @@ async function updateAppointmentUtil(db, appointmentId, data) {
4604
4606
  updateData.confirmationTime = import_firestore6.Timestamp.now();
4605
4607
  }
4606
4608
  if (currentAppointment.calendarEventId) {
4607
- await updateCalendarEventStatus(db, currentAppointment.calendarEventId, data.status);
4609
+ await updateCalendarEventStatus(db, currentAppointment, data.status);
4608
4610
  }
4609
4611
  }
4610
4612
  await (0, import_firestore6.updateDoc)(appointmentRef, updateData);
@@ -4618,21 +4620,30 @@ async function updateAppointmentUtil(db, appointmentId, data) {
4618
4620
  throw error;
4619
4621
  }
4620
4622
  }
4621
- async function updateCalendarEventStatus(db, calendarEventId, appointmentStatus) {
4623
+ async function updateCalendarEventStatus(db, appointment, appointmentStatus) {
4622
4624
  try {
4623
- const calendarEventRef = (0, import_firestore6.doc)(db, CALENDAR_COLLECTION, calendarEventId);
4624
- const calendarEventDoc = await (0, import_firestore6.getDoc)(calendarEventRef);
4625
- if (!calendarEventDoc.exists()) {
4626
- console.warn(`Calendar event with ID ${calendarEventId} not found`);
4625
+ const calendarEventId = appointment.calendarEventId;
4626
+ if (!calendarEventId) {
4627
+ console.warn(`Appointment ${appointment.id} has no calendarEventId, skipping calendar event update`);
4627
4628
  return;
4628
4629
  }
4629
4630
  let calendarStatus;
4630
4631
  switch (appointmentStatus) {
4632
+ case "pending" /* PENDING */:
4633
+ calendarStatus = "pending";
4634
+ break;
4631
4635
  case "confirmed" /* CONFIRMED */:
4632
4636
  calendarStatus = "confirmed";
4633
4637
  break;
4638
+ case "checked_in" /* CHECKED_IN */:
4639
+ calendarStatus = "checked_in";
4640
+ break;
4641
+ case "in_progress" /* IN_PROGRESS */:
4642
+ calendarStatus = "in_progress";
4643
+ break;
4634
4644
  case "canceled_patient" /* CANCELED_PATIENT */:
4635
4645
  case "canceled_clinic" /* CANCELED_CLINIC */:
4646
+ case "canceled_patient_rescheduled" /* CANCELED_PATIENT_RESCHEDULED */:
4636
4647
  calendarStatus = "canceled";
4637
4648
  break;
4638
4649
  case "rescheduled_by_clinic" /* RESCHEDULED_BY_CLINIC */:
@@ -4641,15 +4652,55 @@ async function updateCalendarEventStatus(db, calendarEventId, appointmentStatus)
4641
4652
  case "completed" /* COMPLETED */:
4642
4653
  calendarStatus = "completed";
4643
4654
  break;
4655
+ case "no_show" /* NO_SHOW */:
4656
+ calendarStatus = "no_show";
4657
+ break;
4644
4658
  default:
4659
+ console.warn(`Unknown appointment status: ${appointmentStatus}, not updating calendar event`);
4645
4660
  return;
4646
4661
  }
4647
- await (0, import_firestore6.updateDoc)(calendarEventRef, {
4662
+ const updateData = {
4648
4663
  status: calendarStatus,
4649
4664
  updatedAt: (0, import_firestore6.serverTimestamp)()
4650
- });
4665
+ };
4666
+ const updatePromises = [];
4667
+ if (appointment.practitionerId) {
4668
+ const practitionerEventRef = (0, import_firestore6.doc)(
4669
+ db,
4670
+ `${PRACTITIONERS_COLLECTION}/${appointment.practitionerId}/${CALENDAR_COLLECTION}/${calendarEventId}`
4671
+ );
4672
+ updatePromises.push(
4673
+ (0, import_firestore6.updateDoc)(practitionerEventRef, updateData).catch((error) => {
4674
+ console.error(`Error updating practitioner calendar event ${calendarEventId}:`, error);
4675
+ })
4676
+ );
4677
+ }
4678
+ if (appointment.patientId) {
4679
+ const patientEventRef = (0, import_firestore6.doc)(
4680
+ db,
4681
+ `${PATIENTS_COLLECTION}/${appointment.patientId}/${CALENDAR_COLLECTION}/${calendarEventId}`
4682
+ );
4683
+ updatePromises.push(
4684
+ (0, import_firestore6.updateDoc)(patientEventRef, updateData).catch((error) => {
4685
+ console.error(`Error updating patient calendar event ${calendarEventId}:`, error);
4686
+ })
4687
+ );
4688
+ }
4689
+ if (appointment.clinicBranchId) {
4690
+ const clinicEventRef = (0, import_firestore6.doc)(
4691
+ db,
4692
+ `${CLINICS_COLLECTION}/${appointment.clinicBranchId}/${CALENDAR_COLLECTION}/${calendarEventId}`
4693
+ );
4694
+ updatePromises.push(
4695
+ (0, import_firestore6.updateDoc)(clinicEventRef, updateData).catch((error) => {
4696
+ console.error(`Error updating clinic calendar event ${calendarEventId}:`, error);
4697
+ })
4698
+ );
4699
+ }
4700
+ await Promise.all(updatePromises);
4701
+ console.log(`Successfully updated calendar event ${calendarEventId} status to ${calendarStatus} across all collections`);
4651
4702
  } catch (error) {
4652
- console.error(`Error updating calendar event ${calendarEventId}:`, error);
4703
+ console.error(`Error updating calendar events for appointment ${appointment.id}:`, error);
4653
4704
  }
4654
4705
  }
4655
4706
  async function getAppointmentByIdUtil(db, appointmentId) {
@@ -17830,10 +17881,20 @@ var CalendarServiceV2 = class extends BaseService {
17830
17881
  ],
17831
17882
  ["confirmed" /* CONFIRMED */]: [
17832
17883
  "canceled" /* CANCELED */,
17884
+ "checked_in" /* CHECKED_IN */,
17833
17885
  "completed" /* COMPLETED */,
17834
17886
  "rescheduled" /* RESCHEDULED */,
17835
17887
  "no_show" /* NO_SHOW */
17836
17888
  ],
17889
+ ["checked_in" /* CHECKED_IN */]: [
17890
+ "in_progress" /* IN_PROGRESS */,
17891
+ "completed" /* COMPLETED */,
17892
+ "canceled" /* CANCELED */
17893
+ ],
17894
+ ["in_progress" /* IN_PROGRESS */]: [
17895
+ "completed" /* COMPLETED */,
17896
+ "canceled" /* CANCELED */
17897
+ ],
17837
17898
  ["rejected" /* REJECTED */]: [],
17838
17899
  ["canceled" /* CANCELED */]: [],
17839
17900
  ["rescheduled" /* RESCHEDULED */]: [
@@ -22002,12 +22063,18 @@ var ReviewService = class extends BaseService {
22002
22063
  updatedAt: now
22003
22064
  };
22004
22065
  reviewSchema.parse(review);
22005
- const docRef = (0, import_firestore59.doc)(this.db, REVIEWS_COLLECTION, reviewId);
22006
- await (0, import_firestore59.setDoc)(docRef, {
22066
+ const firestoreData = {
22007
22067
  ...review,
22008
22068
  createdAt: (0, import_firestore59.serverTimestamp)(),
22009
22069
  updatedAt: (0, import_firestore59.serverTimestamp)()
22070
+ };
22071
+ Object.keys(firestoreData).forEach((key) => {
22072
+ if (firestoreData[key] === void 0) {
22073
+ delete firestoreData[key];
22074
+ }
22010
22075
  });
22076
+ const docRef = (0, import_firestore59.doc)(this.db, REVIEWS_COLLECTION, reviewId);
22077
+ await (0, import_firestore59.setDoc)(docRef, firestoreData);
22011
22078
  console.log("\u2705 ReviewService.createReview - Review saved to Firestore:", {
22012
22079
  reviewId,
22013
22080
  practitionerId: (_e = review.practitionerReview) == null ? void 0 : _e.practitionerId,
package/dist/index.mjs CHANGED
@@ -4360,6 +4360,8 @@ import {
4360
4360
  var CalendarEventStatus = /* @__PURE__ */ ((CalendarEventStatus4) => {
4361
4361
  CalendarEventStatus4["PENDING"] = "pending";
4362
4362
  CalendarEventStatus4["CONFIRMED"] = "confirmed";
4363
+ CalendarEventStatus4["CHECKED_IN"] = "checked_in";
4364
+ CalendarEventStatus4["IN_PROGRESS"] = "in_progress";
4363
4365
  CalendarEventStatus4["REJECTED"] = "rejected";
4364
4366
  CalendarEventStatus4["CANCELED"] = "canceled";
4365
4367
  CalendarEventStatus4["RESCHEDULED"] = "rescheduled";
@@ -4491,7 +4493,7 @@ async function updateAppointmentUtil(db, appointmentId, data) {
4491
4493
  updateData.confirmationTime = Timestamp5.now();
4492
4494
  }
4493
4495
  if (currentAppointment.calendarEventId) {
4494
- await updateCalendarEventStatus(db, currentAppointment.calendarEventId, data.status);
4496
+ await updateCalendarEventStatus(db, currentAppointment, data.status);
4495
4497
  }
4496
4498
  }
4497
4499
  await updateDoc2(appointmentRef, updateData);
@@ -4505,21 +4507,30 @@ async function updateAppointmentUtil(db, appointmentId, data) {
4505
4507
  throw error;
4506
4508
  }
4507
4509
  }
4508
- async function updateCalendarEventStatus(db, calendarEventId, appointmentStatus) {
4510
+ async function updateCalendarEventStatus(db, appointment, appointmentStatus) {
4509
4511
  try {
4510
- const calendarEventRef = doc4(db, CALENDAR_COLLECTION, calendarEventId);
4511
- const calendarEventDoc = await getDoc4(calendarEventRef);
4512
- if (!calendarEventDoc.exists()) {
4513
- console.warn(`Calendar event with ID ${calendarEventId} not found`);
4512
+ const calendarEventId = appointment.calendarEventId;
4513
+ if (!calendarEventId) {
4514
+ console.warn(`Appointment ${appointment.id} has no calendarEventId, skipping calendar event update`);
4514
4515
  return;
4515
4516
  }
4516
4517
  let calendarStatus;
4517
4518
  switch (appointmentStatus) {
4519
+ case "pending" /* PENDING */:
4520
+ calendarStatus = "pending";
4521
+ break;
4518
4522
  case "confirmed" /* CONFIRMED */:
4519
4523
  calendarStatus = "confirmed";
4520
4524
  break;
4525
+ case "checked_in" /* CHECKED_IN */:
4526
+ calendarStatus = "checked_in";
4527
+ break;
4528
+ case "in_progress" /* IN_PROGRESS */:
4529
+ calendarStatus = "in_progress";
4530
+ break;
4521
4531
  case "canceled_patient" /* CANCELED_PATIENT */:
4522
4532
  case "canceled_clinic" /* CANCELED_CLINIC */:
4533
+ case "canceled_patient_rescheduled" /* CANCELED_PATIENT_RESCHEDULED */:
4523
4534
  calendarStatus = "canceled";
4524
4535
  break;
4525
4536
  case "rescheduled_by_clinic" /* RESCHEDULED_BY_CLINIC */:
@@ -4528,15 +4539,55 @@ async function updateCalendarEventStatus(db, calendarEventId, appointmentStatus)
4528
4539
  case "completed" /* COMPLETED */:
4529
4540
  calendarStatus = "completed";
4530
4541
  break;
4542
+ case "no_show" /* NO_SHOW */:
4543
+ calendarStatus = "no_show";
4544
+ break;
4531
4545
  default:
4546
+ console.warn(`Unknown appointment status: ${appointmentStatus}, not updating calendar event`);
4532
4547
  return;
4533
4548
  }
4534
- await updateDoc2(calendarEventRef, {
4549
+ const updateData = {
4535
4550
  status: calendarStatus,
4536
4551
  updatedAt: serverTimestamp()
4537
- });
4552
+ };
4553
+ const updatePromises = [];
4554
+ if (appointment.practitionerId) {
4555
+ const practitionerEventRef = doc4(
4556
+ db,
4557
+ `${PRACTITIONERS_COLLECTION}/${appointment.practitionerId}/${CALENDAR_COLLECTION}/${calendarEventId}`
4558
+ );
4559
+ updatePromises.push(
4560
+ updateDoc2(practitionerEventRef, updateData).catch((error) => {
4561
+ console.error(`Error updating practitioner calendar event ${calendarEventId}:`, error);
4562
+ })
4563
+ );
4564
+ }
4565
+ if (appointment.patientId) {
4566
+ const patientEventRef = doc4(
4567
+ db,
4568
+ `${PATIENTS_COLLECTION}/${appointment.patientId}/${CALENDAR_COLLECTION}/${calendarEventId}`
4569
+ );
4570
+ updatePromises.push(
4571
+ updateDoc2(patientEventRef, updateData).catch((error) => {
4572
+ console.error(`Error updating patient calendar event ${calendarEventId}:`, error);
4573
+ })
4574
+ );
4575
+ }
4576
+ if (appointment.clinicBranchId) {
4577
+ const clinicEventRef = doc4(
4578
+ db,
4579
+ `${CLINICS_COLLECTION}/${appointment.clinicBranchId}/${CALENDAR_COLLECTION}/${calendarEventId}`
4580
+ );
4581
+ updatePromises.push(
4582
+ updateDoc2(clinicEventRef, updateData).catch((error) => {
4583
+ console.error(`Error updating clinic calendar event ${calendarEventId}:`, error);
4584
+ })
4585
+ );
4586
+ }
4587
+ await Promise.all(updatePromises);
4588
+ console.log(`Successfully updated calendar event ${calendarEventId} status to ${calendarStatus} across all collections`);
4538
4589
  } catch (error) {
4539
- console.error(`Error updating calendar event ${calendarEventId}:`, error);
4590
+ console.error(`Error updating calendar events for appointment ${appointment.id}:`, error);
4540
4591
  }
4541
4592
  }
4542
4593
  async function getAppointmentByIdUtil(db, appointmentId) {
@@ -17987,10 +18038,20 @@ var CalendarServiceV2 = class extends BaseService {
17987
18038
  ],
17988
18039
  ["confirmed" /* CONFIRMED */]: [
17989
18040
  "canceled" /* CANCELED */,
18041
+ "checked_in" /* CHECKED_IN */,
17990
18042
  "completed" /* COMPLETED */,
17991
18043
  "rescheduled" /* RESCHEDULED */,
17992
18044
  "no_show" /* NO_SHOW */
17993
18045
  ],
18046
+ ["checked_in" /* CHECKED_IN */]: [
18047
+ "in_progress" /* IN_PROGRESS */,
18048
+ "completed" /* COMPLETED */,
18049
+ "canceled" /* CANCELED */
18050
+ ],
18051
+ ["in_progress" /* IN_PROGRESS */]: [
18052
+ "completed" /* COMPLETED */,
18053
+ "canceled" /* CANCELED */
18054
+ ],
17994
18055
  ["rejected" /* REJECTED */]: [],
17995
18056
  ["canceled" /* CANCELED */]: [],
17996
18057
  ["rescheduled" /* RESCHEDULED */]: [
@@ -22248,12 +22309,18 @@ var ReviewService = class extends BaseService {
22248
22309
  updatedAt: now
22249
22310
  };
22250
22311
  reviewSchema.parse(review);
22251
- const docRef = doc40(this.db, REVIEWS_COLLECTION, reviewId);
22252
- await setDoc28(docRef, {
22312
+ const firestoreData = {
22253
22313
  ...review,
22254
22314
  createdAt: serverTimestamp32(),
22255
22315
  updatedAt: serverTimestamp32()
22316
+ };
22317
+ Object.keys(firestoreData).forEach((key) => {
22318
+ if (firestoreData[key] === void 0) {
22319
+ delete firestoreData[key];
22320
+ }
22256
22321
  });
22322
+ const docRef = doc40(this.db, REVIEWS_COLLECTION, reviewId);
22323
+ await setDoc28(docRef, firestoreData);
22257
22324
  console.log("\u2705 ReviewService.createReview - Review saved to Firestore:", {
22258
22325
  reviewId,
22259
22326
  practitionerId: (_e = review.practitionerReview) == null ? void 0 : _e.practitionerId,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@blackcode_sa/metaestetics-api",
3
3
  "private": false,
4
- "version": "1.13.18",
4
+ "version": "1.13.20",
5
5
  "description": "Firebase authentication service with anonymous upgrade support",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.mjs",
@@ -28,6 +28,9 @@ import {
28
28
  import { CalendarEvent, CALENDAR_COLLECTION } from '../../../types/calendar';
29
29
  import { ProcedureSummaryInfo } from '../../../types/procedure';
30
30
  import { ClinicInfo, PatientProfileInfo, PractitionerProfileInfo } from '../../../types/profile';
31
+ import { PRACTITIONERS_COLLECTION } from '../../../types/practitioner';
32
+ import { PATIENTS_COLLECTION } from '../../../types/patient';
33
+ import { CLINICS_COLLECTION } from '../../../types/clinic';
31
34
  import { BlockingCondition } from '../../../backoffice/types/static/blocking-condition.types';
32
35
  import { Requirement } from '../../../backoffice/types/requirement.types';
33
36
  import { PRACTITIONERS_COLLECTION } from '../../../types/practitioner';
@@ -379,7 +382,7 @@ export async function updateAppointmentUtil(
379
382
 
380
383
  // Update the related calendar event status if needed
381
384
  if (currentAppointment.calendarEventId) {
382
- await updateCalendarEventStatus(db, currentAppointment.calendarEventId, data.status);
385
+ await updateCalendarEventStatus(db, currentAppointment, data.status);
383
386
  }
384
387
  }
385
388
 
@@ -400,34 +403,43 @@ export async function updateAppointmentUtil(
400
403
  }
401
404
 
402
405
  /**
403
- * Updates the status of a calendar event based on appointment status changes.
406
+ * Updates the status of calendar events across all collections (practitioner, patient, clinic)
407
+ * based on appointment status changes.
404
408
  *
405
409
  * @param db Firestore instance
406
- * @param calendarEventId ID of the calendar event
410
+ * @param appointment The appointment object containing calendar event references
407
411
  * @param appointmentStatus New appointment status
408
412
  */
409
413
  async function updateCalendarEventStatus(
410
414
  db: Firestore,
411
- calendarEventId: string,
415
+ appointment: Appointment,
412
416
  appointmentStatus: AppointmentStatus,
413
417
  ): Promise<void> {
414
418
  try {
415
- const calendarEventRef = doc(db, CALENDAR_COLLECTION, calendarEventId);
416
- const calendarEventDoc = await getDoc(calendarEventRef);
417
-
418
- if (!calendarEventDoc.exists()) {
419
- console.warn(`Calendar event with ID ${calendarEventId} not found`);
419
+ const calendarEventId = appointment.calendarEventId;
420
+ if (!calendarEventId) {
421
+ console.warn(`Appointment ${appointment.id} has no calendarEventId, skipping calendar event update`);
420
422
  return;
421
423
  }
422
424
 
423
425
  // Map appointment status to calendar event status
424
- let calendarStatus;
426
+ let calendarStatus: string;
425
427
  switch (appointmentStatus) {
428
+ case AppointmentStatus.PENDING:
429
+ calendarStatus = 'pending';
430
+ break;
426
431
  case AppointmentStatus.CONFIRMED:
427
432
  calendarStatus = 'confirmed';
428
433
  break;
434
+ case AppointmentStatus.CHECKED_IN:
435
+ calendarStatus = 'checked_in';
436
+ break;
437
+ case AppointmentStatus.IN_PROGRESS:
438
+ calendarStatus = 'in_progress';
439
+ break;
429
440
  case AppointmentStatus.CANCELED_PATIENT:
430
441
  case AppointmentStatus.CANCELED_CLINIC:
442
+ case AppointmentStatus.CANCELED_PATIENT_RESCHEDULED:
431
443
  calendarStatus = 'canceled';
432
444
  break;
433
445
  case AppointmentStatus.RESCHEDULED_BY_CLINIC:
@@ -436,17 +448,67 @@ async function updateCalendarEventStatus(
436
448
  case AppointmentStatus.COMPLETED:
437
449
  calendarStatus = 'completed';
438
450
  break;
451
+ case AppointmentStatus.NO_SHOW:
452
+ calendarStatus = 'no_show';
453
+ break;
439
454
  default:
440
- // For other states, don't update the calendar status
455
+ // For unknown states, don't update the calendar status
456
+ console.warn(`Unknown appointment status: ${appointmentStatus}, not updating calendar event`);
441
457
  return;
442
458
  }
443
459
 
444
- await updateDoc(calendarEventRef, {
460
+ const updateData = {
445
461
  status: calendarStatus,
446
462
  updatedAt: serverTimestamp(),
447
- });
463
+ };
464
+
465
+ // Update all three calendar event collections in parallel
466
+ const updatePromises: Promise<void>[] = [];
467
+
468
+ // Update practitioner calendar event
469
+ if (appointment.practitionerId) {
470
+ const practitionerEventRef = doc(
471
+ db,
472
+ `${PRACTITIONERS_COLLECTION}/${appointment.practitionerId}/${CALENDAR_COLLECTION}/${calendarEventId}`
473
+ );
474
+ updatePromises.push(
475
+ updateDoc(practitionerEventRef, updateData).catch(error => {
476
+ console.error(`Error updating practitioner calendar event ${calendarEventId}:`, error);
477
+ })
478
+ );
479
+ }
480
+
481
+ // Update patient calendar event
482
+ if (appointment.patientId) {
483
+ const patientEventRef = doc(
484
+ db,
485
+ `${PATIENTS_COLLECTION}/${appointment.patientId}/${CALENDAR_COLLECTION}/${calendarEventId}`
486
+ );
487
+ updatePromises.push(
488
+ updateDoc(patientEventRef, updateData).catch(error => {
489
+ console.error(`Error updating patient calendar event ${calendarEventId}:`, error);
490
+ })
491
+ );
492
+ }
493
+
494
+ // Update clinic calendar event
495
+ if (appointment.clinicBranchId) {
496
+ const clinicEventRef = doc(
497
+ db,
498
+ `${CLINICS_COLLECTION}/${appointment.clinicBranchId}/${CALENDAR_COLLECTION}/${calendarEventId}`
499
+ );
500
+ updatePromises.push(
501
+ updateDoc(clinicEventRef, updateData).catch(error => {
502
+ console.error(`Error updating clinic calendar event ${calendarEventId}:`, error);
503
+ })
504
+ );
505
+ }
506
+
507
+ // Wait for all updates to complete
508
+ await Promise.all(updatePromises);
509
+ console.log(`Successfully updated calendar event ${calendarEventId} status to ${calendarStatus} across all collections`);
448
510
  } catch (error) {
449
- console.error(`Error updating calendar event ${calendarEventId}:`, error);
511
+ console.error(`Error updating calendar events for appointment ${appointment.id}:`, error);
450
512
  // Don't throw error to avoid failing the appointment update
451
513
  }
452
514
  }
@@ -1140,10 +1140,20 @@ export class CalendarServiceV2 extends BaseService {
1140
1140
  ],
1141
1141
  [CalendarEventStatus.CONFIRMED]: [
1142
1142
  CalendarEventStatus.CANCELED,
1143
+ CalendarEventStatus.CHECKED_IN,
1143
1144
  CalendarEventStatus.COMPLETED,
1144
1145
  CalendarEventStatus.RESCHEDULED,
1145
1146
  CalendarEventStatus.NO_SHOW,
1146
1147
  ],
1148
+ [CalendarEventStatus.CHECKED_IN]: [
1149
+ CalendarEventStatus.IN_PROGRESS,
1150
+ CalendarEventStatus.COMPLETED,
1151
+ CalendarEventStatus.CANCELED,
1152
+ ],
1153
+ [CalendarEventStatus.IN_PROGRESS]: [
1154
+ CalendarEventStatus.COMPLETED,
1155
+ CalendarEventStatus.CANCELED,
1156
+ ],
1147
1157
  [CalendarEventStatus.REJECTED]: [],
1148
1158
  [CalendarEventStatus.CANCELED]: [],
1149
1159
  [CalendarEventStatus.RESCHEDULED]: [
@@ -213,14 +213,25 @@ export class ReviewService extends BaseService {
213
213
  // Validate complete review object
214
214
  reviewSchema.parse(review);
215
215
 
216
- // Save the review to Firestore
217
- const docRef = doc(this.db, REVIEWS_COLLECTION, reviewId);
218
- await setDoc(docRef, {
216
+ // Prepare Firestore document, filtering out undefined values
217
+ // Firebase doesn't accept undefined values, so we omit them
218
+ const firestoreData: any = {
219
219
  ...review,
220
220
  createdAt: serverTimestamp(),
221
221
  updatedAt: serverTimestamp(),
222
+ };
223
+
224
+ // Remove undefined fields to prevent Firebase errors
225
+ Object.keys(firestoreData).forEach((key) => {
226
+ if (firestoreData[key] === undefined) {
227
+ delete firestoreData[key];
228
+ }
222
229
  });
223
230
 
231
+ // Save the review to Firestore
232
+ const docRef = doc(this.db, REVIEWS_COLLECTION, reviewId);
233
+ await setDoc(docRef, firestoreData);
234
+
224
235
  console.log('✅ ReviewService.createReview - Review saved to Firestore:', {
225
236
  reviewId,
226
237
  practitionerId: review.practitionerReview?.practitionerId,
@@ -23,6 +23,8 @@ import type {
23
23
  export enum CalendarEventStatus {
24
24
  PENDING = "pending", // When event is created, but not confirmed
25
25
  CONFIRMED = "confirmed", // When event is confirmed and ready to be used
26
+ CHECKED_IN = "checked_in", // Patient has arrived and checked in
27
+ IN_PROGRESS = "in_progress", // Procedure has started
26
28
  REJECTED = "rejected", // When event is rejected by the clinic administrator or patient
27
29
  CANCELED = "canceled", // When event is canceled by the patient
28
30
  RESCHEDULED = "rescheduled", // When event is rescheduled by the clinic administrator