@blackcode_sa/metaestetics-api 1.8.1 → 1.8.3

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/index.js CHANGED
@@ -43,6 +43,7 @@ __export(index_exports, {
43
43
  CLINIC_GROUPS_COLLECTION: () => CLINIC_GROUPS_COLLECTION,
44
44
  CalendarEventStatus: () => CalendarEventStatus,
45
45
  CalendarEventType: () => CalendarEventType,
46
+ CalendarServiceV2: () => CalendarServiceV2,
46
47
  CalendarServiceV3: () => CalendarServiceV3,
47
48
  CalendarSyncStatus: () => CalendarSyncStatus,
48
49
  ClinicAdminService: () => ClinicAdminService,
@@ -111,6 +112,7 @@ __export(index_exports, {
111
112
  USERS_COLLECTION: () => USERS_COLLECTION,
112
113
  USER_FORMS_SUBCOLLECTION: () => USER_FORMS_SUBCOLLECTION,
113
114
  UserRole: () => UserRole,
115
+ UserService: () => UserService,
114
116
  addAllergySchema: () => addAllergySchema,
115
117
  addBlockingConditionSchema: () => addBlockingConditionSchema,
116
118
  addContraindicationSchema: () => addContraindicationSchema,
@@ -843,20 +845,20 @@ var rescheduleAppointmentSchema = import_zod3.z.object({
843
845
  var import_firestore = require("firebase/firestore");
844
846
 
845
847
  // src/types/calendar/index.ts
846
- var CalendarEventStatus = /* @__PURE__ */ ((CalendarEventStatus3) => {
847
- CalendarEventStatus3["PENDING"] = "pending";
848
- CalendarEventStatus3["CONFIRMED"] = "confirmed";
849
- CalendarEventStatus3["REJECTED"] = "rejected";
850
- CalendarEventStatus3["CANCELED"] = "canceled";
851
- CalendarEventStatus3["RESCHEDULED"] = "rescheduled";
852
- CalendarEventStatus3["COMPLETED"] = "completed";
853
- CalendarEventStatus3["NO_SHOW"] = "no_show";
854
- return CalendarEventStatus3;
848
+ var CalendarEventStatus = /* @__PURE__ */ ((CalendarEventStatus4) => {
849
+ CalendarEventStatus4["PENDING"] = "pending";
850
+ CalendarEventStatus4["CONFIRMED"] = "confirmed";
851
+ CalendarEventStatus4["REJECTED"] = "rejected";
852
+ CalendarEventStatus4["CANCELED"] = "canceled";
853
+ CalendarEventStatus4["RESCHEDULED"] = "rescheduled";
854
+ CalendarEventStatus4["COMPLETED"] = "completed";
855
+ CalendarEventStatus4["NO_SHOW"] = "no_show";
856
+ return CalendarEventStatus4;
855
857
  })(CalendarEventStatus || {});
856
- var CalendarSyncStatus = /* @__PURE__ */ ((CalendarSyncStatus3) => {
857
- CalendarSyncStatus3["INTERNAL"] = "internal";
858
- CalendarSyncStatus3["EXTERNAL"] = "external";
859
- return CalendarSyncStatus3;
858
+ var CalendarSyncStatus = /* @__PURE__ */ ((CalendarSyncStatus4) => {
859
+ CalendarSyncStatus4["INTERNAL"] = "internal";
860
+ CalendarSyncStatus4["EXTERNAL"] = "external";
861
+ return CalendarSyncStatus4;
860
862
  })(CalendarSyncStatus || {});
861
863
  var CalendarEventType = /* @__PURE__ */ ((CalendarEventType3) => {
862
864
  CalendarEventType3["APPOINTMENT"] = "appointment";
@@ -1228,7 +1230,7 @@ async function searchAppointmentsUtil(db, params) {
1228
1230
  const q = (0, import_firestore.query)((0, import_firestore.collection)(db, APPOINTMENTS_COLLECTION), ...constraints);
1229
1231
  const querySnapshot = await (0, import_firestore.getDocs)(q);
1230
1232
  const appointments = querySnapshot.docs.map(
1231
- (doc26) => doc26.data()
1233
+ (doc32) => doc32.data()
1232
1234
  );
1233
1235
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
1234
1236
  return { appointments, lastDoc };
@@ -2035,7 +2037,7 @@ var AppointmentService = class extends BaseService {
2035
2037
  );
2036
2038
  const querySnapshot = await (0, import_firestore2.getDocs)(q);
2037
2039
  const appointments = querySnapshot.docs.map(
2038
- (doc26) => doc26.data()
2040
+ (doc32) => doc32.data()
2039
2041
  );
2040
2042
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
2041
2043
  console.log(
@@ -2108,7 +2110,7 @@ var AppointmentService = class extends BaseService {
2108
2110
  );
2109
2111
  const querySnapshot = await (0, import_firestore2.getDocs)(q);
2110
2112
  const appointments = querySnapshot.docs.map(
2111
- (doc26) => doc26.data()
2113
+ (doc32) => doc32.data()
2112
2114
  );
2113
2115
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
2114
2116
  console.log(
@@ -2819,11 +2821,11 @@ var UserRole = /* @__PURE__ */ ((UserRole2) => {
2819
2821
  var USERS_COLLECTION = "users";
2820
2822
 
2821
2823
  // src/types/calendar/synced-calendar.types.ts
2822
- var SyncedCalendarProvider = /* @__PURE__ */ ((SyncedCalendarProvider2) => {
2823
- SyncedCalendarProvider2["GOOGLE"] = "google";
2824
- SyncedCalendarProvider2["OUTLOOK"] = "outlook";
2825
- SyncedCalendarProvider2["APPLE"] = "apple";
2826
- return SyncedCalendarProvider2;
2824
+ var SyncedCalendarProvider = /* @__PURE__ */ ((SyncedCalendarProvider3) => {
2825
+ SyncedCalendarProvider3["GOOGLE"] = "google";
2826
+ SyncedCalendarProvider3["OUTLOOK"] = "outlook";
2827
+ SyncedCalendarProvider3["APPLE"] = "apple";
2828
+ return SyncedCalendarProvider3;
2827
2829
  })(SyncedCalendarProvider || {});
2828
2830
  var SYNCED_CALENDARS_COLLECTION = "syncedCalendars";
2829
2831
 
@@ -3361,7 +3363,7 @@ var MediaService = class extends BaseService {
3361
3363
  try {
3362
3364
  const querySnapshot = await (0, import_firestore5.getDocs)(finalQuery);
3363
3365
  const mediaList = querySnapshot.docs.map(
3364
- (doc26) => doc26.data()
3366
+ (doc32) => doc32.data()
3365
3367
  );
3366
3368
  console.log(`[MediaService] Found ${mediaList.length} media items.`);
3367
3369
  return mediaList;
@@ -3415,8 +3417,8 @@ var getPatientsByClinicUtil = async (db, clinicId, options) => {
3415
3417
  }
3416
3418
  const patientsSnapshot = await (0, import_firestore6.getDocs)(q);
3417
3419
  const patients = [];
3418
- patientsSnapshot.forEach((doc26) => {
3419
- patients.push(doc26.data());
3420
+ patientsSnapshot.forEach((doc32) => {
3421
+ patients.push(doc32.data());
3420
3422
  });
3421
3423
  console.log(
3422
3424
  `[getPatientsByClinicUtil] Found ${patients.length} patients for clinic ID: ${clinicId}`
@@ -3769,8 +3771,8 @@ var getPatientsByPractitionerUtil = async (db, practitionerId, options) => {
3769
3771
  }
3770
3772
  const patientsSnapshot = await (0, import_firestore9.getDocs)(q);
3771
3773
  const patients = [];
3772
- patientsSnapshot.forEach((doc26) => {
3773
- patients.push(doc26.data());
3774
+ patientsSnapshot.forEach((doc32) => {
3775
+ patients.push(doc32.data());
3774
3776
  });
3775
3777
  console.log(
3776
3778
  `[getPatientsByPractitionerUtil] Found ${patients.length} patients for practitioner ID: ${practitionerId}`
@@ -4338,7 +4340,7 @@ async function getClinicAdminsByGroup(db, clinicGroupId) {
4338
4340
  (0, import_firestore11.where)("clinicGroupId", "==", clinicGroupId)
4339
4341
  );
4340
4342
  const querySnapshot = await (0, import_firestore11.getDocs)(q);
4341
- return querySnapshot.docs.map((doc26) => doc26.data());
4343
+ return querySnapshot.docs.map((doc32) => doc32.data());
4342
4344
  }
4343
4345
  async function updateClinicAdmin(db, adminId, data) {
4344
4346
  const admin2 = await getClinicAdmin(db, adminId);
@@ -5001,9 +5003,9 @@ var updateAllergyUtil = async (db, patientId, data, requesterId, requesterRoles)
5001
5003
  };
5002
5004
  var removeAllergyUtil = async (db, patientId, allergyIndex, requesterId, requesterRoles) => {
5003
5005
  await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
5004
- const doc26 = await (0, import_firestore16.getDoc)(getMedicalInfoDocRef(db, patientId));
5005
- if (!doc26.exists()) throw new Error("Medical info not found");
5006
- const medicalInfo = doc26.data();
5006
+ const doc32 = await (0, import_firestore16.getDoc)(getMedicalInfoDocRef(db, patientId));
5007
+ if (!doc32.exists()) throw new Error("Medical info not found");
5008
+ const medicalInfo = doc32.data();
5007
5009
  if (allergyIndex >= medicalInfo.allergies.length) {
5008
5010
  throw new Error("Invalid allergy index");
5009
5011
  }
@@ -5030,9 +5032,9 @@ var updateBlockingConditionUtil = async (db, patientId, data, requesterId, reque
5030
5032
  await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
5031
5033
  const validatedData = updateBlockingConditionSchema.parse(data);
5032
5034
  const { conditionIndex, ...updateData } = validatedData;
5033
- const doc26 = await (0, import_firestore16.getDoc)(getMedicalInfoDocRef(db, patientId));
5034
- if (!doc26.exists()) throw new Error("Medical info not found");
5035
- const medicalInfo = doc26.data();
5035
+ const doc32 = await (0, import_firestore16.getDoc)(getMedicalInfoDocRef(db, patientId));
5036
+ if (!doc32.exists()) throw new Error("Medical info not found");
5037
+ const medicalInfo = doc32.data();
5036
5038
  if (conditionIndex >= medicalInfo.blockingConditions.length) {
5037
5039
  throw new Error("Invalid blocking condition index");
5038
5040
  }
@@ -5049,9 +5051,9 @@ var updateBlockingConditionUtil = async (db, patientId, data, requesterId, reque
5049
5051
  };
5050
5052
  var removeBlockingConditionUtil = async (db, patientId, conditionIndex, requesterId, requesterRoles) => {
5051
5053
  await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
5052
- const doc26 = await (0, import_firestore16.getDoc)(getMedicalInfoDocRef(db, patientId));
5053
- if (!doc26.exists()) throw new Error("Medical info not found");
5054
- const medicalInfo = doc26.data();
5054
+ const doc32 = await (0, import_firestore16.getDoc)(getMedicalInfoDocRef(db, patientId));
5055
+ if (!doc32.exists()) throw new Error("Medical info not found");
5056
+ const medicalInfo = doc32.data();
5055
5057
  if (conditionIndex >= medicalInfo.blockingConditions.length) {
5056
5058
  throw new Error("Invalid blocking condition index");
5057
5059
  }
@@ -5078,9 +5080,9 @@ var updateContraindicationUtil = async (db, patientId, data, requesterId, reques
5078
5080
  await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
5079
5081
  const validatedData = updateContraindicationSchema.parse(data);
5080
5082
  const { contraindicationIndex, ...updateData } = validatedData;
5081
- const doc26 = await (0, import_firestore16.getDoc)(getMedicalInfoDocRef(db, patientId));
5082
- if (!doc26.exists()) throw new Error("Medical info not found");
5083
- const medicalInfo = doc26.data();
5083
+ const doc32 = await (0, import_firestore16.getDoc)(getMedicalInfoDocRef(db, patientId));
5084
+ if (!doc32.exists()) throw new Error("Medical info not found");
5085
+ const medicalInfo = doc32.data();
5084
5086
  if (contraindicationIndex >= medicalInfo.contraindications.length) {
5085
5087
  throw new Error("Invalid contraindication index");
5086
5088
  }
@@ -5097,9 +5099,9 @@ var updateContraindicationUtil = async (db, patientId, data, requesterId, reques
5097
5099
  };
5098
5100
  var removeContraindicationUtil = async (db, patientId, contraindicationIndex, requesterId, requesterRoles) => {
5099
5101
  await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
5100
- const doc26 = await (0, import_firestore16.getDoc)(getMedicalInfoDocRef(db, patientId));
5101
- if (!doc26.exists()) throw new Error("Medical info not found");
5102
- const medicalInfo = doc26.data();
5102
+ const doc32 = await (0, import_firestore16.getDoc)(getMedicalInfoDocRef(db, patientId));
5103
+ if (!doc32.exists()) throw new Error("Medical info not found");
5104
+ const medicalInfo = doc32.data();
5103
5105
  if (contraindicationIndex >= medicalInfo.contraindications.length) {
5104
5106
  throw new Error("Invalid contraindication index");
5105
5107
  }
@@ -5126,9 +5128,9 @@ var updateMedicationUtil = async (db, patientId, data, requesterId, requesterRol
5126
5128
  await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
5127
5129
  const validatedData = updateMedicationSchema.parse(data);
5128
5130
  const { medicationIndex, ...updateData } = validatedData;
5129
- const doc26 = await (0, import_firestore16.getDoc)(getMedicalInfoDocRef(db, patientId));
5130
- if (!doc26.exists()) throw new Error("Medical info not found");
5131
- const medicalInfo = doc26.data();
5131
+ const doc32 = await (0, import_firestore16.getDoc)(getMedicalInfoDocRef(db, patientId));
5132
+ if (!doc32.exists()) throw new Error("Medical info not found");
5133
+ const medicalInfo = doc32.data();
5132
5134
  if (medicationIndex >= medicalInfo.currentMedications.length) {
5133
5135
  throw new Error("Invalid medication index");
5134
5136
  }
@@ -5145,9 +5147,9 @@ var updateMedicationUtil = async (db, patientId, data, requesterId, requesterRol
5145
5147
  };
5146
5148
  var removeMedicationUtil = async (db, patientId, medicationIndex, requesterId, requesterRoles) => {
5147
5149
  await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
5148
- const doc26 = await (0, import_firestore16.getDoc)(getMedicalInfoDocRef(db, patientId));
5149
- if (!doc26.exists()) throw new Error("Medical info not found");
5150
- const medicalInfo = doc26.data();
5150
+ const doc32 = await (0, import_firestore16.getDoc)(getMedicalInfoDocRef(db, patientId));
5151
+ if (!doc32.exists()) throw new Error("Medical info not found");
5152
+ const medicalInfo = doc32.data();
5151
5153
  if (medicationIndex >= medicalInfo.currentMedications.length) {
5152
5154
  throw new Error("Invalid medication index");
5153
5155
  }
@@ -5434,7 +5436,7 @@ var searchPatientsUtil = async (db, params, requester) => {
5434
5436
  const finalQuery = (0, import_firestore17.query)(patientsCollectionRef, ...constraints);
5435
5437
  const querySnapshot = await (0, import_firestore17.getDocs)(finalQuery);
5436
5438
  const patients = querySnapshot.docs.map(
5437
- (doc26) => doc26.data()
5439
+ (doc32) => doc32.data()
5438
5440
  );
5439
5441
  console.log(
5440
5442
  `[searchPatientsUtil] Found ${patients.length} patients matching criteria.`
@@ -5466,8 +5468,8 @@ var getAllPatientsUtil = async (db, options) => {
5466
5468
  }
5467
5469
  const patientsSnapshot = await (0, import_firestore17.getDocs)(q);
5468
5470
  const patients = [];
5469
- patientsSnapshot.forEach((doc26) => {
5470
- patients.push(doc26.data());
5471
+ patientsSnapshot.forEach((doc32) => {
5472
+ patients.push(doc32.data());
5471
5473
  });
5472
5474
  console.log(`[getAllPatientsUtil] Found ${patients.length} patients`);
5473
5475
  return patients;
@@ -5589,7 +5591,7 @@ var getActiveInviteTokensByClinicUtil = async (db, clinicId) => {
5589
5591
  if (querySnapshot.empty) {
5590
5592
  return [];
5591
5593
  }
5592
- return querySnapshot.docs.map((doc26) => doc26.data());
5594
+ return querySnapshot.docs.map((doc32) => doc32.data());
5593
5595
  };
5594
5596
  var getActiveInviteTokensByPatientUtil = async (db, patientId) => {
5595
5597
  const tokensRef = (0, import_firestore18.collection)(
@@ -5607,7 +5609,7 @@ var getActiveInviteTokensByPatientUtil = async (db, patientId) => {
5607
5609
  if (querySnapshot.empty) {
5608
5610
  return [];
5609
5611
  }
5610
- return querySnapshot.docs.map((doc26) => doc26.data());
5612
+ return querySnapshot.docs.map((doc32) => doc32.data());
5611
5613
  };
5612
5614
 
5613
5615
  // src/services/patient/patient.service.ts
@@ -6713,7 +6715,7 @@ var PractitionerService = class extends BaseService {
6713
6715
  (0, import_firestore21.where)("expiresAt", ">", import_firestore21.Timestamp.now())
6714
6716
  );
6715
6717
  const querySnapshot = await (0, import_firestore21.getDocs)(q);
6716
- return querySnapshot.docs.map((doc26) => doc26.data());
6718
+ return querySnapshot.docs.map((doc32) => doc32.data());
6717
6719
  }
6718
6720
  /**
6719
6721
  * Gets a token by its string value and validates it
@@ -6823,7 +6825,7 @@ var PractitionerService = class extends BaseService {
6823
6825
  (0, import_firestore21.where)("status", "==", "active" /* ACTIVE */)
6824
6826
  );
6825
6827
  const querySnapshot = await (0, import_firestore21.getDocs)(q);
6826
- return querySnapshot.docs.map((doc26) => doc26.data());
6828
+ return querySnapshot.docs.map((doc32) => doc32.data());
6827
6829
  }
6828
6830
  /**
6829
6831
  * Dohvata sve zdravstvene radnike za određenu kliniku
@@ -6835,7 +6837,7 @@ var PractitionerService = class extends BaseService {
6835
6837
  (0, import_firestore21.where)("isActive", "==", true)
6836
6838
  );
6837
6839
  const querySnapshot = await (0, import_firestore21.getDocs)(q);
6838
- return querySnapshot.docs.map((doc26) => doc26.data());
6840
+ return querySnapshot.docs.map((doc32) => doc32.data());
6839
6841
  }
6840
6842
  /**
6841
6843
  * Dohvata sve draft zdravstvene radnike za određenu kliniku sa statusom DRAFT
@@ -6847,7 +6849,7 @@ var PractitionerService = class extends BaseService {
6847
6849
  (0, import_firestore21.where)("status", "==", "draft" /* DRAFT */)
6848
6850
  );
6849
6851
  const querySnapshot = await (0, import_firestore21.getDocs)(q);
6850
- return querySnapshot.docs.map((doc26) => doc26.data());
6852
+ return querySnapshot.docs.map((doc32) => doc32.data());
6851
6853
  }
6852
6854
  /**
6853
6855
  * Updates a practitioner
@@ -7061,7 +7063,7 @@ var PractitionerService = class extends BaseService {
7061
7063
  );
7062
7064
  const querySnapshot = await (0, import_firestore21.getDocs)(q);
7063
7065
  const practitioners = querySnapshot.docs.map(
7064
- (doc26) => doc26.data()
7066
+ (doc32) => doc32.data()
7065
7067
  );
7066
7068
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
7067
7069
  return {
@@ -7132,8 +7134,8 @@ var PractitionerService = class extends BaseService {
7132
7134
  console.log(
7133
7135
  `[PRACTITIONER_SERVICE] Found ${querySnapshot.docs.length} practitioners with base query`
7134
7136
  );
7135
- let practitioners = querySnapshot.docs.map((doc26) => {
7136
- return { ...doc26.data(), id: doc26.id };
7137
+ let practitioners = querySnapshot.docs.map((doc32) => {
7138
+ return { ...doc32.data(), id: doc32.id };
7137
7139
  });
7138
7140
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
7139
7141
  if (filters.nameSearch && filters.nameSearch.trim() !== "") {
@@ -7617,7 +7619,7 @@ var UserService = class extends BaseService {
7617
7619
  ];
7618
7620
  const q = (0, import_firestore22.query)((0, import_firestore22.collection)(this.db, USERS_COLLECTION), ...constraints);
7619
7621
  const querySnapshot = await (0, import_firestore22.getDocs)(q);
7620
- const users = querySnapshot.docs.map((doc26) => doc26.data());
7622
+ const users = querySnapshot.docs.map((doc32) => doc32.data());
7621
7623
  return users.map((userData) => userSchema.parse(userData));
7622
7624
  }
7623
7625
  /**
@@ -7981,7 +7983,7 @@ async function getAllActiveGroups(db) {
7981
7983
  (0, import_firestore23.where)("isActive", "==", true)
7982
7984
  );
7983
7985
  const querySnapshot = await (0, import_firestore23.getDocs)(q);
7984
- return querySnapshot.docs.map((doc26) => doc26.data());
7986
+ return querySnapshot.docs.map((doc32) => doc32.data());
7985
7987
  }
7986
7988
  async function updateClinicGroup(db, groupId, data, app) {
7987
7989
  console.log("[CLINIC_GROUP] Updating clinic group", { groupId });
@@ -8421,7 +8423,7 @@ async function getClinicsByGroup(db, groupId) {
8421
8423
  (0, import_firestore24.where)("isActive", "==", true)
8422
8424
  );
8423
8425
  const querySnapshot = await (0, import_firestore24.getDocs)(q);
8424
- return querySnapshot.docs.map((doc26) => doc26.data());
8426
+ return querySnapshot.docs.map((doc32) => doc32.data());
8425
8427
  }
8426
8428
  async function updateClinic(db, clinicId, data, adminId, clinicAdminService, app) {
8427
8429
  console.log("[CLINIC] Starting clinic update", { clinicId, adminId });
@@ -8615,7 +8617,7 @@ async function getClinicsByAdmin(db, adminId, options = {}, clinicAdminService,
8615
8617
  }
8616
8618
  const q = (0, import_firestore24.query)((0, import_firestore24.collection)(db, CLINICS_COLLECTION), ...constraints);
8617
8619
  const querySnapshot = await (0, import_firestore24.getDocs)(q);
8618
- return querySnapshot.docs.map((doc26) => doc26.data());
8620
+ return querySnapshot.docs.map((doc32) => doc32.data());
8619
8621
  }
8620
8622
  async function getActiveClinicsByAdmin(db, adminId, clinicAdminService, clinicGroupService) {
8621
8623
  return getClinicsByAdmin(
@@ -8660,11 +8662,11 @@ async function getAllClinics(db, pagination, lastDoc) {
8660
8662
  }
8661
8663
  const clinicsSnapshot = await (0, import_firestore24.getDocs)(clinicsQuery);
8662
8664
  const lastVisible = clinicsSnapshot.docs[clinicsSnapshot.docs.length - 1];
8663
- const clinics = clinicsSnapshot.docs.map((doc26) => {
8664
- const data = doc26.data();
8665
+ const clinics = clinicsSnapshot.docs.map((doc32) => {
8666
+ const data = doc32.data();
8665
8667
  return {
8666
8668
  ...data,
8667
- id: doc26.id
8669
+ id: doc32.id
8668
8670
  };
8669
8671
  });
8670
8672
  return {
@@ -8691,8 +8693,8 @@ async function getAllClinicsInRange(db, center, rangeInKm, pagination, lastDoc)
8691
8693
  ];
8692
8694
  const q = (0, import_firestore24.query)((0, import_firestore24.collection)(db, CLINICS_COLLECTION), ...constraints);
8693
8695
  const querySnapshot = await (0, import_firestore24.getDocs)(q);
8694
- for (const doc26 of querySnapshot.docs) {
8695
- const clinic = doc26.data();
8696
+ for (const doc32 of querySnapshot.docs) {
8697
+ const clinic = doc32.data();
8696
8698
  const distance = (0, import_geofire_common4.distanceBetween)(
8697
8699
  [center.latitude, center.longitude],
8698
8700
  [clinic.location.latitude, clinic.location.longitude]
@@ -8809,8 +8811,8 @@ async function findClinicsInRadius(db, center, radiusInKm, filters) {
8809
8811
  }
8810
8812
  const q = (0, import_firestore25.query)((0, import_firestore25.collection)(db, CLINICS_COLLECTION), ...constraints);
8811
8813
  const querySnapshot = await (0, import_firestore25.getDocs)(q);
8812
- for (const doc26 of querySnapshot.docs) {
8813
- const clinic = doc26.data();
8814
+ for (const doc32 of querySnapshot.docs) {
8815
+ const clinic = doc32.data();
8814
8816
  const distance = (0, import_geofire_common5.distanceBetween)(
8815
8817
  [center.latitude, center.longitude],
8816
8818
  [clinic.location.latitude, clinic.location.longitude]
@@ -8898,8 +8900,8 @@ async function getClinicsByFilters(db, filters) {
8898
8900
  console.log(
8899
8901
  `[FILTER_UTILS] Found ${querySnapshot.docs.length} clinics in geo bound`
8900
8902
  );
8901
- for (const doc26 of querySnapshot.docs) {
8902
- const clinic = { ...doc26.data(), id: doc26.id };
8903
+ for (const doc32 of querySnapshot.docs) {
8904
+ const clinic = { ...doc32.data(), id: doc32.id };
8903
8905
  const distance = (0, import_geofire_common6.distanceBetween)(
8904
8906
  [center.latitude, center.longitude],
8905
8907
  [clinic.location.latitude, clinic.location.longitude]
@@ -8955,8 +8957,8 @@ async function getClinicsByFilters(db, filters) {
8955
8957
  console.log(
8956
8958
  `[FILTER_UTILS] Found ${querySnapshot.docs.length} clinics with regular query`
8957
8959
  );
8958
- const clinics = querySnapshot.docs.map((doc26) => {
8959
- return { ...doc26.data(), id: doc26.id };
8960
+ const clinics = querySnapshot.docs.map((doc32) => {
8961
+ return { ...doc32.data(), id: doc32.id };
8960
8962
  });
8961
8963
  let filteredClinics = clinics;
8962
8964
  if (filters.center) {
@@ -10274,12 +10276,226 @@ var AuthService = class extends BaseService {
10274
10276
  }
10275
10277
  };
10276
10278
 
10277
- // src/services/calendar/calendar.v3.service.ts
10279
+ // src/services/calendar/calendar.v2.service.ts
10280
+ var import_firestore36 = require("firebase/firestore");
10281
+ var import_firestore37 = require("firebase/firestore");
10282
+
10283
+ // src/services/calendar/utils/clinic.utils.ts
10278
10284
  var import_firestore30 = require("firebase/firestore");
10285
+
10286
+ // src/services/calendar/utils/docs.utils.ts
10287
+ var import_firestore29 = require("firebase/firestore");
10288
+ function getPractitionerCalendarEventDocRef(db, practitionerId, eventId) {
10289
+ return (0, import_firestore29.doc)(
10290
+ db,
10291
+ `${PRACTITIONERS_COLLECTION}/${practitionerId}/${CALENDAR_COLLECTION}/${eventId}`
10292
+ );
10293
+ }
10294
+ function getPatientCalendarEventDocRef(db, patientId, eventId) {
10295
+ return (0, import_firestore29.doc)(
10296
+ db,
10297
+ `${PATIENTS_COLLECTION}/${patientId}/${CALENDAR_COLLECTION}/${eventId}`
10298
+ );
10299
+ }
10300
+ function getClinicCalendarEventDocRef(db, clinicId, eventId) {
10301
+ return (0, import_firestore29.doc)(
10302
+ db,
10303
+ `${CLINICS_COLLECTION}/${clinicId}/${CALENDAR_COLLECTION}/${eventId}`
10304
+ );
10305
+ }
10306
+ function getPractitionerSyncedCalendarDocRef(db, practitionerId, syncedCalendarId) {
10307
+ return (0, import_firestore29.doc)(
10308
+ db,
10309
+ `${PRACTITIONERS_COLLECTION}/${practitionerId}/syncedCalendars/${syncedCalendarId}`
10310
+ );
10311
+ }
10312
+ function getPatientSyncedCalendarDocRef(db, patientId, syncedCalendarId) {
10313
+ return (0, import_firestore29.doc)(
10314
+ db,
10315
+ `${PATIENTS_COLLECTION}/${patientId}/syncedCalendars/${syncedCalendarId}`
10316
+ );
10317
+ }
10318
+ function getClinicSyncedCalendarDocRef(db, clinicId, syncedCalendarId) {
10319
+ return (0, import_firestore29.doc)(
10320
+ db,
10321
+ `${CLINICS_COLLECTION}/${clinicId}/syncedCalendars/${syncedCalendarId}`
10322
+ );
10323
+ }
10324
+
10325
+ // src/services/calendar/utils/clinic.utils.ts
10326
+ async function createClinicCalendarEventUtil(db, clinicId, eventData, generateId2) {
10327
+ const eventId = generateId2();
10328
+ const eventRef = getClinicCalendarEventDocRef(db, clinicId, eventId);
10329
+ const newEvent = {
10330
+ id: eventId,
10331
+ ...eventData,
10332
+ createdAt: (0, import_firestore30.serverTimestamp)(),
10333
+ updatedAt: (0, import_firestore30.serverTimestamp)()
10334
+ };
10335
+ await (0, import_firestore30.setDoc)(eventRef, newEvent);
10336
+ return {
10337
+ ...newEvent,
10338
+ createdAt: import_firestore30.Timestamp.now(),
10339
+ updatedAt: import_firestore30.Timestamp.now()
10340
+ };
10341
+ }
10342
+ async function updateClinicCalendarEventUtil(db, clinicId, eventId, updateData) {
10343
+ const eventRef = getClinicCalendarEventDocRef(db, clinicId, eventId);
10344
+ const updates = {
10345
+ ...updateData,
10346
+ updatedAt: (0, import_firestore30.serverTimestamp)()
10347
+ };
10348
+ await (0, import_firestore30.updateDoc)(eventRef, updates);
10349
+ const updatedDoc = await (0, import_firestore30.getDoc)(eventRef);
10350
+ if (!updatedDoc.exists()) {
10351
+ throw new Error("Event not found after update");
10352
+ }
10353
+ return updatedDoc.data();
10354
+ }
10355
+ async function checkAutoConfirmAppointmentsUtil(db, clinicId) {
10356
+ const clinicDoc = await (0, import_firestore30.getDoc)((0, import_firestore30.doc)(db, `clinics/${clinicId}`));
10357
+ if (!clinicDoc.exists()) {
10358
+ throw new Error(`Clinic with ID ${clinicId} not found`);
10359
+ }
10360
+ const clinicData = clinicDoc.data();
10361
+ const clinicGroupId = clinicData.clinicGroupId;
10362
+ if (!clinicGroupId) {
10363
+ return false;
10364
+ }
10365
+ const clinicGroupDoc = await (0, import_firestore30.getDoc)(
10366
+ (0, import_firestore30.doc)(db, `${CLINIC_GROUPS_COLLECTION}/${clinicGroupId}`)
10367
+ );
10368
+ if (!clinicGroupDoc.exists()) {
10369
+ return false;
10370
+ }
10371
+ const clinicGroupData = clinicGroupDoc.data();
10372
+ return !!clinicGroupData.autoConfirmAppointments;
10373
+ }
10374
+
10375
+ // src/services/calendar/utils/patient.utils.ts
10279
10376
  var import_firestore31 = require("firebase/firestore");
10377
+ async function createPatientCalendarEventUtil(db, patientId, eventData, generateId2) {
10378
+ const eventId = generateId2();
10379
+ const eventRef = getPatientCalendarEventDocRef(db, patientId, eventId);
10380
+ const newEvent = {
10381
+ id: eventId,
10382
+ ...eventData,
10383
+ createdAt: (0, import_firestore31.serverTimestamp)(),
10384
+ updatedAt: (0, import_firestore31.serverTimestamp)()
10385
+ };
10386
+ await (0, import_firestore31.setDoc)(eventRef, newEvent);
10387
+ return {
10388
+ ...newEvent,
10389
+ createdAt: import_firestore31.Timestamp.now(),
10390
+ updatedAt: import_firestore31.Timestamp.now()
10391
+ };
10392
+ }
10393
+ async function updatePatientCalendarEventUtil(db, patientId, eventId, updateData) {
10394
+ const eventRef = getPatientCalendarEventDocRef(db, patientId, eventId);
10395
+ const updates = {
10396
+ ...updateData,
10397
+ updatedAt: (0, import_firestore31.serverTimestamp)()
10398
+ };
10399
+ await (0, import_firestore31.updateDoc)(eventRef, updates);
10400
+ const updatedDoc = await (0, import_firestore31.getDoc)(eventRef);
10401
+ if (!updatedDoc.exists()) {
10402
+ throw new Error("Event not found after update");
10403
+ }
10404
+ return updatedDoc.data();
10405
+ }
10406
+
10407
+ // src/services/calendar/utils/practitioner.utils.ts
10408
+ var import_firestore32 = require("firebase/firestore");
10409
+ async function createPractitionerCalendarEventUtil(db, practitionerId, eventData, generateId2) {
10410
+ const eventId = generateId2();
10411
+ const eventRef = getPractitionerCalendarEventDocRef(
10412
+ db,
10413
+ practitionerId,
10414
+ eventId
10415
+ );
10416
+ const newEvent = {
10417
+ id: eventId,
10418
+ ...eventData,
10419
+ createdAt: (0, import_firestore32.serverTimestamp)(),
10420
+ updatedAt: (0, import_firestore32.serverTimestamp)()
10421
+ };
10422
+ await (0, import_firestore32.setDoc)(eventRef, newEvent);
10423
+ return {
10424
+ ...newEvent,
10425
+ createdAt: import_firestore32.Timestamp.now(),
10426
+ updatedAt: import_firestore32.Timestamp.now()
10427
+ };
10428
+ }
10429
+ async function updatePractitionerCalendarEventUtil(db, practitionerId, eventId, updateData) {
10430
+ const eventRef = getPractitionerCalendarEventDocRef(
10431
+ db,
10432
+ practitionerId,
10433
+ eventId
10434
+ );
10435
+ const updates = {
10436
+ ...updateData,
10437
+ updatedAt: (0, import_firestore32.serverTimestamp)()
10438
+ };
10439
+ await (0, import_firestore32.updateDoc)(eventRef, updates);
10440
+ const updatedDoc = await (0, import_firestore32.getDoc)(eventRef);
10441
+ if (!updatedDoc.exists()) {
10442
+ throw new Error("Event not found after update");
10443
+ }
10444
+ return updatedDoc.data();
10445
+ }
10446
+
10447
+ // src/services/calendar/utils/appointment.utils.ts
10448
+ async function createAppointmentUtil2(db, clinicId, practitionerId, patientId, eventData, generateId2) {
10449
+ const eventId = generateId2();
10450
+ const autoConfirm = await checkAutoConfirmAppointmentsUtil(db, clinicId);
10451
+ const initialStatus = autoConfirm ? "confirmed" /* CONFIRMED */ : "pending" /* PENDING */;
10452
+ const appointmentData = {
10453
+ ...eventData,
10454
+ clinicBranchId: clinicId,
10455
+ practitionerProfileId: practitionerId,
10456
+ patientProfileId: patientId,
10457
+ eventType: "appointment" /* APPOINTMENT */,
10458
+ status: eventData.status || initialStatus
10459
+ };
10460
+ const clinicPromise = createClinicCalendarEventUtil(
10461
+ db,
10462
+ clinicId,
10463
+ appointmentData,
10464
+ () => eventId
10465
+ // Use the same ID for all calendars
10466
+ );
10467
+ const practitionerPromise = createPractitionerCalendarEventUtil(
10468
+ db,
10469
+ practitionerId,
10470
+ appointmentData,
10471
+ () => eventId
10472
+ // Use the same ID for all calendars
10473
+ );
10474
+ const patientPromise = createPatientCalendarEventUtil(
10475
+ db,
10476
+ patientId,
10477
+ appointmentData,
10478
+ () => eventId
10479
+ // Use the same ID for all calendars
10480
+ );
10481
+ const [clinicEvent] = await Promise.all([clinicPromise, practitionerPromise, patientPromise]);
10482
+ return clinicEvent;
10483
+ }
10484
+ async function updateAppointmentUtil2(db, clinicId, practitionerId, patientId, eventId, updateData) {
10485
+ const clinicPromise = updateClinicCalendarEventUtil(db, clinicId, eventId, updateData);
10486
+ const practitionerPromise = updatePractitionerCalendarEventUtil(
10487
+ db,
10488
+ practitionerId,
10489
+ eventId,
10490
+ updateData
10491
+ );
10492
+ const patientPromise = updatePatientCalendarEventUtil(db, patientId, eventId, updateData);
10493
+ const [clinicEvent] = await Promise.all([clinicPromise, practitionerPromise, patientPromise]);
10494
+ return clinicEvent;
10495
+ }
10280
10496
 
10281
10497
  // src/services/calendar/utils/calendar-event.utils.ts
10282
- var import_firestore29 = require("firebase/firestore");
10498
+ var import_firestore33 = require("firebase/firestore");
10283
10499
  async function searchCalendarEventsUtil(db, params) {
10284
10500
  const { searchLocation, entityId, ...filters } = params;
10285
10501
  let baseCollectionPath;
@@ -10291,88 +10507,2312 @@ async function searchCalendarEventsUtil(db, params) {
10291
10507
  "Practitioner ID (entityId) is required when searching practitioner calendar."
10292
10508
  );
10293
10509
  }
10294
- baseCollectionPath = `${PRACTITIONERS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}`;
10295
- if (filters.practitionerId && filters.practitionerId !== entityId) {
10296
- console.warn(
10297
- `Provided practitionerId filter (${filters.practitionerId}) does not match search entityId (${entityId}). Returning empty results.`
10298
- );
10299
- return [];
10510
+ baseCollectionPath = `${PRACTITIONERS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}`;
10511
+ if (filters.practitionerId && filters.practitionerId !== entityId) {
10512
+ console.warn(
10513
+ `Provided practitionerId filter (${filters.practitionerId}) does not match search entityId (${entityId}). Returning empty results.`
10514
+ );
10515
+ return [];
10516
+ }
10517
+ filters.practitionerId = void 0;
10518
+ break;
10519
+ case "patient" /* PATIENT */:
10520
+ if (!entityId) {
10521
+ throw new Error(
10522
+ "Patient ID (entityId) is required when searching patient calendar."
10523
+ );
10524
+ }
10525
+ baseCollectionPath = `${PATIENTS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}`;
10526
+ if (filters.patientId && filters.patientId !== entityId) {
10527
+ console.warn(
10528
+ `Provided patientId filter (${filters.patientId}) does not match search entityId (${entityId}). Returning empty results.`
10529
+ );
10530
+ return [];
10531
+ }
10532
+ filters.patientId = void 0;
10533
+ break;
10534
+ case "clinic" /* CLINIC */:
10535
+ if (!entityId) {
10536
+ throw new Error(
10537
+ "Clinic ID (entityId) is required when searching clinic-related events."
10538
+ );
10539
+ }
10540
+ baseCollectionPath = `${CLINICS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}`;
10541
+ constraints.push((0, import_firestore33.where)("clinicBranchId", "==", entityId));
10542
+ if (filters.clinicId && filters.clinicId !== entityId) {
10543
+ console.warn(
10544
+ `Provided clinicId filter (${filters.clinicId}) does not match search entityId (${entityId}). Returning empty results.`
10545
+ );
10546
+ return [];
10547
+ }
10548
+ filters.clinicId = void 0;
10549
+ break;
10550
+ default:
10551
+ throw new Error(`Invalid search location: ${searchLocation}`);
10552
+ }
10553
+ const collectionRef = (0, import_firestore33.collection)(db, baseCollectionPath);
10554
+ if (filters.clinicId) {
10555
+ constraints.push((0, import_firestore33.where)("clinicBranchId", "==", filters.clinicId));
10556
+ }
10557
+ if (filters.practitionerId) {
10558
+ constraints.push(
10559
+ (0, import_firestore33.where)("practitionerProfileId", "==", filters.practitionerId)
10560
+ );
10561
+ }
10562
+ if (filters.patientId) {
10563
+ constraints.push((0, import_firestore33.where)("patientProfileId", "==", filters.patientId));
10564
+ }
10565
+ if (filters.procedureId) {
10566
+ constraints.push((0, import_firestore33.where)("procedureId", "==", filters.procedureId));
10567
+ }
10568
+ if (filters.eventStatus) {
10569
+ constraints.push((0, import_firestore33.where)("status", "==", filters.eventStatus));
10570
+ }
10571
+ if (filters.eventType) {
10572
+ constraints.push((0, import_firestore33.where)("eventType", "==", filters.eventType));
10573
+ }
10574
+ if (filters.dateRange) {
10575
+ constraints.push((0, import_firestore33.where)("eventTime.start", ">=", filters.dateRange.start));
10576
+ constraints.push((0, import_firestore33.where)("eventTime.start", "<=", filters.dateRange.end));
10577
+ }
10578
+ try {
10579
+ const finalQuery = (0, import_firestore33.query)(collectionRef, ...constraints);
10580
+ const querySnapshot = await (0, import_firestore33.getDocs)(finalQuery);
10581
+ const events = querySnapshot.docs.map(
10582
+ (doc32) => ({ id: doc32.id, ...doc32.data() })
10583
+ );
10584
+ return events;
10585
+ } catch (error) {
10586
+ console.error("Error searching calendar events:", error);
10587
+ return [];
10588
+ }
10589
+ }
10590
+
10591
+ // src/services/calendar/utils/synced-calendar.utils.ts
10592
+ var import_firestore34 = require("firebase/firestore");
10593
+ async function createPractitionerSyncedCalendarUtil(db, practitionerId, calendarData, generateId2) {
10594
+ const calendarId = generateId2();
10595
+ const calendarRef = getPractitionerSyncedCalendarDocRef(
10596
+ db,
10597
+ practitionerId,
10598
+ calendarId
10599
+ );
10600
+ const newCalendar = {
10601
+ id: calendarId,
10602
+ ...calendarData,
10603
+ createdAt: (0, import_firestore34.serverTimestamp)(),
10604
+ updatedAt: (0, import_firestore34.serverTimestamp)()
10605
+ };
10606
+ await (0, import_firestore34.setDoc)(calendarRef, newCalendar);
10607
+ return {
10608
+ ...newCalendar,
10609
+ createdAt: import_firestore34.Timestamp.now(),
10610
+ updatedAt: import_firestore34.Timestamp.now()
10611
+ };
10612
+ }
10613
+ async function createPatientSyncedCalendarUtil(db, patientId, calendarData, generateId2) {
10614
+ const calendarId = generateId2();
10615
+ const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
10616
+ const newCalendar = {
10617
+ id: calendarId,
10618
+ ...calendarData,
10619
+ createdAt: (0, import_firestore34.serverTimestamp)(),
10620
+ updatedAt: (0, import_firestore34.serverTimestamp)()
10621
+ };
10622
+ await (0, import_firestore34.setDoc)(calendarRef, newCalendar);
10623
+ return {
10624
+ ...newCalendar,
10625
+ createdAt: import_firestore34.Timestamp.now(),
10626
+ updatedAt: import_firestore34.Timestamp.now()
10627
+ };
10628
+ }
10629
+ async function createClinicSyncedCalendarUtil(db, clinicId, calendarData, generateId2) {
10630
+ const calendarId = generateId2();
10631
+ const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
10632
+ const newCalendar = {
10633
+ id: calendarId,
10634
+ ...calendarData,
10635
+ createdAt: (0, import_firestore34.serverTimestamp)(),
10636
+ updatedAt: (0, import_firestore34.serverTimestamp)()
10637
+ };
10638
+ await (0, import_firestore34.setDoc)(calendarRef, newCalendar);
10639
+ return {
10640
+ ...newCalendar,
10641
+ createdAt: import_firestore34.Timestamp.now(),
10642
+ updatedAt: import_firestore34.Timestamp.now()
10643
+ };
10644
+ }
10645
+ async function getPractitionerSyncedCalendarUtil(db, practitionerId, calendarId) {
10646
+ const calendarRef = getPractitionerSyncedCalendarDocRef(
10647
+ db,
10648
+ practitionerId,
10649
+ calendarId
10650
+ );
10651
+ const calendarDoc = await (0, import_firestore34.getDoc)(calendarRef);
10652
+ if (!calendarDoc.exists()) {
10653
+ return null;
10654
+ }
10655
+ return calendarDoc.data();
10656
+ }
10657
+ async function getPractitionerSyncedCalendarsUtil(db, practitionerId) {
10658
+ const calendarsRef = (0, import_firestore34.collection)(
10659
+ db,
10660
+ `practitioners/${practitionerId}/${SYNCED_CALENDARS_COLLECTION}`
10661
+ );
10662
+ const q = (0, import_firestore34.query)(calendarsRef, (0, import_firestore34.orderBy)("createdAt", "desc"));
10663
+ const querySnapshot = await (0, import_firestore34.getDocs)(q);
10664
+ return querySnapshot.docs.map((doc32) => doc32.data());
10665
+ }
10666
+ async function getPatientSyncedCalendarUtil(db, patientId, calendarId) {
10667
+ const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
10668
+ const calendarDoc = await (0, import_firestore34.getDoc)(calendarRef);
10669
+ if (!calendarDoc.exists()) {
10670
+ return null;
10671
+ }
10672
+ return calendarDoc.data();
10673
+ }
10674
+ async function getPatientSyncedCalendarsUtil(db, patientId) {
10675
+ const calendarsRef = (0, import_firestore34.collection)(
10676
+ db,
10677
+ `patients/${patientId}/${SYNCED_CALENDARS_COLLECTION}`
10678
+ );
10679
+ const q = (0, import_firestore34.query)(calendarsRef, (0, import_firestore34.orderBy)("createdAt", "desc"));
10680
+ const querySnapshot = await (0, import_firestore34.getDocs)(q);
10681
+ return querySnapshot.docs.map((doc32) => doc32.data());
10682
+ }
10683
+ async function getClinicSyncedCalendarUtil(db, clinicId, calendarId) {
10684
+ const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
10685
+ const calendarDoc = await (0, import_firestore34.getDoc)(calendarRef);
10686
+ if (!calendarDoc.exists()) {
10687
+ return null;
10688
+ }
10689
+ return calendarDoc.data();
10690
+ }
10691
+ async function getClinicSyncedCalendarsUtil(db, clinicId) {
10692
+ const calendarsRef = (0, import_firestore34.collection)(
10693
+ db,
10694
+ `clinics/${clinicId}/${SYNCED_CALENDARS_COLLECTION}`
10695
+ );
10696
+ const q = (0, import_firestore34.query)(calendarsRef, (0, import_firestore34.orderBy)("createdAt", "desc"));
10697
+ const querySnapshot = await (0, import_firestore34.getDocs)(q);
10698
+ return querySnapshot.docs.map((doc32) => doc32.data());
10699
+ }
10700
+ async function updatePractitionerSyncedCalendarUtil(db, practitionerId, calendarId, updateData) {
10701
+ const calendarRef = getPractitionerSyncedCalendarDocRef(
10702
+ db,
10703
+ practitionerId,
10704
+ calendarId
10705
+ );
10706
+ const updates = {
10707
+ ...updateData,
10708
+ updatedAt: (0, import_firestore34.serverTimestamp)()
10709
+ };
10710
+ await (0, import_firestore34.updateDoc)(calendarRef, updates);
10711
+ const updatedDoc = await (0, import_firestore34.getDoc)(calendarRef);
10712
+ if (!updatedDoc.exists()) {
10713
+ throw new Error("Synced calendar not found after update");
10714
+ }
10715
+ return updatedDoc.data();
10716
+ }
10717
+ async function updatePatientSyncedCalendarUtil(db, patientId, calendarId, updateData) {
10718
+ const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
10719
+ const updates = {
10720
+ ...updateData,
10721
+ updatedAt: (0, import_firestore34.serverTimestamp)()
10722
+ };
10723
+ await (0, import_firestore34.updateDoc)(calendarRef, updates);
10724
+ const updatedDoc = await (0, import_firestore34.getDoc)(calendarRef);
10725
+ if (!updatedDoc.exists()) {
10726
+ throw new Error("Synced calendar not found after update");
10727
+ }
10728
+ return updatedDoc.data();
10729
+ }
10730
+ async function updateClinicSyncedCalendarUtil(db, clinicId, calendarId, updateData) {
10731
+ const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
10732
+ const updates = {
10733
+ ...updateData,
10734
+ updatedAt: (0, import_firestore34.serverTimestamp)()
10735
+ };
10736
+ await (0, import_firestore34.updateDoc)(calendarRef, updates);
10737
+ const updatedDoc = await (0, import_firestore34.getDoc)(calendarRef);
10738
+ if (!updatedDoc.exists()) {
10739
+ throw new Error("Synced calendar not found after update");
10740
+ }
10741
+ return updatedDoc.data();
10742
+ }
10743
+ async function deletePractitionerSyncedCalendarUtil(db, practitionerId, calendarId) {
10744
+ const calendarRef = getPractitionerSyncedCalendarDocRef(
10745
+ db,
10746
+ practitionerId,
10747
+ calendarId
10748
+ );
10749
+ await (0, import_firestore34.deleteDoc)(calendarRef);
10750
+ }
10751
+ async function deletePatientSyncedCalendarUtil(db, patientId, calendarId) {
10752
+ const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
10753
+ await (0, import_firestore34.deleteDoc)(calendarRef);
10754
+ }
10755
+ async function deleteClinicSyncedCalendarUtil(db, clinicId, calendarId) {
10756
+ const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
10757
+ await (0, import_firestore34.deleteDoc)(calendarRef);
10758
+ }
10759
+ async function updateLastSyncedTimestampUtil(db, entityType, entityId, calendarId) {
10760
+ const updateData = {
10761
+ lastSyncedAt: import_firestore34.Timestamp.now()
10762
+ };
10763
+ switch (entityType) {
10764
+ case "practitioner":
10765
+ return updatePractitionerSyncedCalendarUtil(
10766
+ db,
10767
+ entityId,
10768
+ calendarId,
10769
+ updateData
10770
+ );
10771
+ case "patient":
10772
+ return updatePatientSyncedCalendarUtil(
10773
+ db,
10774
+ entityId,
10775
+ calendarId,
10776
+ updateData
10777
+ );
10778
+ case "clinic":
10779
+ return updateClinicSyncedCalendarUtil(
10780
+ db,
10781
+ entityId,
10782
+ calendarId,
10783
+ updateData
10784
+ );
10785
+ default:
10786
+ throw new Error(`Invalid entity type: ${entityType}`);
10787
+ }
10788
+ }
10789
+
10790
+ // src/services/calendar/utils/google-calendar.utils.ts
10791
+ var import_firestore35 = require("firebase/firestore");
10792
+ var GOOGLE_CALENDAR_API_URL = "https://www.googleapis.com/calendar/v3";
10793
+ var GOOGLE_OAUTH_URL = "https://oauth2.googleapis.com/token";
10794
+ var CLIENT_ID = "your-client-id";
10795
+ var CLIENT_SECRET = "your-client-secret";
10796
+ var REDIRECT_URI = "your-redirect-uri";
10797
+ async function makeRequest(method, url, headers, data, params) {
10798
+ const queryParams = params ? "?" + Object.entries(params).map(
10799
+ ([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`
10800
+ ).join("&") : "";
10801
+ const finalUrl = url + queryParams;
10802
+ const options = {
10803
+ method,
10804
+ headers,
10805
+ body: data ? JSON.stringify(data) : void 0
10806
+ };
10807
+ const response = await fetch(finalUrl, options);
10808
+ if (!response.ok) {
10809
+ const error = new Error(
10810
+ `Request failed with status ${response.status}`
10811
+ );
10812
+ error.response = response;
10813
+ throw error;
10814
+ }
10815
+ return response.json();
10816
+ }
10817
+ async function authenticateWithGoogleCalendarUtil(authCode) {
10818
+ try {
10819
+ const data = {
10820
+ code: authCode,
10821
+ client_id: CLIENT_ID,
10822
+ client_secret: CLIENT_SECRET,
10823
+ redirect_uri: REDIRECT_URI,
10824
+ grant_type: "authorization_code"
10825
+ };
10826
+ const response = await makeRequest(
10827
+ "post",
10828
+ GOOGLE_OAUTH_URL,
10829
+ { "Content-Type": "application/json" },
10830
+ data
10831
+ );
10832
+ return {
10833
+ accessToken: response.access_token,
10834
+ refreshToken: response.refresh_token,
10835
+ expiresIn: response.expires_in
10836
+ };
10837
+ } catch (error) {
10838
+ const apiError = error;
10839
+ console.error(
10840
+ "Error authenticating with Google Calendar:",
10841
+ apiError.message || "Unknown error"
10842
+ );
10843
+ throw new Error(
10844
+ `Failed to authenticate with Google Calendar: ${apiError.message || "Unknown error"}`
10845
+ );
10846
+ }
10847
+ }
10848
+ async function refreshGoogleCalendarTokenUtil(refreshToken) {
10849
+ try {
10850
+ const data = {
10851
+ refresh_token: refreshToken,
10852
+ client_id: CLIENT_ID,
10853
+ client_secret: CLIENT_SECRET,
10854
+ grant_type: "refresh_token"
10855
+ };
10856
+ const response = await makeRequest(
10857
+ "post",
10858
+ GOOGLE_OAUTH_URL,
10859
+ { "Content-Type": "application/json" },
10860
+ data
10861
+ );
10862
+ return {
10863
+ accessToken: response.access_token,
10864
+ expiresIn: response.expires_in
10865
+ };
10866
+ } catch (error) {
10867
+ const apiError = error;
10868
+ console.error(
10869
+ "Error refreshing Google Calendar token:",
10870
+ apiError.message || "Unknown error"
10871
+ );
10872
+ throw new Error(
10873
+ `Failed to refresh Google Calendar token: ${apiError.message || "Unknown error"}`
10874
+ );
10875
+ }
10876
+ }
10877
+ async function listGoogleCalendarsUtil(accessToken) {
10878
+ try {
10879
+ const response = await makeRequest(
10880
+ "get",
10881
+ `${GOOGLE_CALENDAR_API_URL}/users/me/calendarList`,
10882
+ { Authorization: `Bearer ${accessToken}` }
10883
+ );
10884
+ return response.items.map((calendar) => ({
10885
+ id: calendar.id,
10886
+ name: calendar.summary
10887
+ }));
10888
+ } catch (error) {
10889
+ const apiError = error;
10890
+ console.error(
10891
+ "Error listing Google Calendars:",
10892
+ apiError.message || "Unknown error"
10893
+ );
10894
+ throw new Error(
10895
+ `Failed to list Google Calendars: ${apiError.message || "Unknown error"}`
10896
+ );
10897
+ }
10898
+ }
10899
+ async function ensureValidToken(db, entityType, entityId, syncedCalendar) {
10900
+ const expiryTime = syncedCalendar.tokenExpiry.toDate();
10901
+ const now = /* @__PURE__ */ new Date();
10902
+ const fiveMinutesFromNow = new Date(now.getTime() + 5 * 60 * 1e3);
10903
+ if (expiryTime < fiveMinutesFromNow) {
10904
+ const { accessToken, expiresIn } = await refreshGoogleCalendarTokenUtil(
10905
+ syncedCalendar.refreshToken
10906
+ );
10907
+ const tokenExpiry = /* @__PURE__ */ new Date();
10908
+ tokenExpiry.setSeconds(tokenExpiry.getSeconds() + expiresIn);
10909
+ const updateData = {
10910
+ accessToken,
10911
+ tokenExpiry: import_firestore35.Timestamp.fromDate(tokenExpiry)
10912
+ };
10913
+ switch (entityType) {
10914
+ case "practitioner":
10915
+ await updatePractitionerSyncedCalendarUtil(
10916
+ db,
10917
+ entityId,
10918
+ syncedCalendar.id,
10919
+ updateData
10920
+ );
10921
+ break;
10922
+ case "patient":
10923
+ await updatePatientSyncedCalendarUtil(
10924
+ db,
10925
+ entityId,
10926
+ syncedCalendar.id,
10927
+ updateData
10928
+ );
10929
+ break;
10930
+ case "clinic":
10931
+ await updateClinicSyncedCalendarUtil(
10932
+ db,
10933
+ entityId,
10934
+ syncedCalendar.id,
10935
+ updateData
10936
+ );
10937
+ break;
10938
+ }
10939
+ return accessToken;
10940
+ }
10941
+ return syncedCalendar.accessToken;
10942
+ }
10943
+ async function syncEventsToGoogleCalendarUtil(db, entityType, entityId, syncedCalendar, events, existingSyncId) {
10944
+ var _a, _b;
10945
+ try {
10946
+ const { accessToken } = await refreshGoogleCalendarTokenUtil(
10947
+ syncedCalendar.refreshToken
10948
+ );
10949
+ let syncedCount = 0;
10950
+ const errors = [];
10951
+ const eventIds = [];
10952
+ for (const event of events) {
10953
+ try {
10954
+ if (event.syncStatus === "external" /* EXTERNAL */) {
10955
+ continue;
10956
+ }
10957
+ if (entityType === "practitioner" && event.status !== "confirmed" /* CONFIRMED */) {
10958
+ continue;
10959
+ }
10960
+ if (entityType === "patient" && (event.status === "canceled" /* CANCELED */ || event.status === "rejected" /* REJECTED */)) {
10961
+ continue;
10962
+ }
10963
+ if (entityType === "clinic") {
10964
+ continue;
10965
+ }
10966
+ const googleEvent = convertCalendarEventToGoogleEventUtil(event);
10967
+ const headers = {
10968
+ Authorization: `Bearer ${accessToken}`,
10969
+ "Content-Type": "application/json"
10970
+ };
10971
+ let responseId = "";
10972
+ if (existingSyncId) {
10973
+ const response = await makeRequest(
10974
+ "put",
10975
+ `${GOOGLE_CALENDAR_API_URL}/calendars/${syncedCalendar.calendarId}/events/${existingSyncId}`,
10976
+ headers,
10977
+ googleEvent
10978
+ );
10979
+ responseId = response.id;
10980
+ } else {
10981
+ const existingSync = (_a = event.syncedCalendarEventId) == null ? void 0 : _a.find(
10982
+ (sync) => sync.syncedCalendarProvider === "google" /* GOOGLE */ && // We should check if this is the same calendar we're syncing with, but that information isn't stored
10983
+ // For now, we'll just use the first Google Calendar sync ID
10984
+ sync.syncedCalendarProvider === syncedCalendar.provider
10985
+ );
10986
+ if (existingSync) {
10987
+ const response = await makeRequest(
10988
+ "put",
10989
+ `${GOOGLE_CALENDAR_API_URL}/calendars/${syncedCalendar.calendarId}/events/${existingSync.eventId}`,
10990
+ headers,
10991
+ googleEvent
10992
+ );
10993
+ responseId = response.id;
10994
+ } else {
10995
+ const response = await makeRequest(
10996
+ "post",
10997
+ `${GOOGLE_CALENDAR_API_URL}/calendars/${syncedCalendar.calendarId}/events`,
10998
+ headers,
10999
+ googleEvent
11000
+ );
11001
+ responseId = response.id;
11002
+ }
11003
+ }
11004
+ if (responseId) {
11005
+ eventIds.push(responseId);
11006
+ syncedCount++;
11007
+ }
11008
+ } catch (error) {
11009
+ const apiError = error;
11010
+ errors.push({
11011
+ eventId: event.id,
11012
+ error: apiError.message || "Unknown error",
11013
+ status: (_b = apiError.response) == null ? void 0 : _b.status
11014
+ });
11015
+ }
11016
+ }
11017
+ await updateLastSyncedTimestampUtil(
11018
+ db,
11019
+ entityType,
11020
+ entityId,
11021
+ syncedCalendar.id
11022
+ );
11023
+ return {
11024
+ success: errors.length === 0,
11025
+ syncedEvents: syncedCount,
11026
+ errors,
11027
+ eventIds
11028
+ };
11029
+ } catch (error) {
11030
+ console.error("Error syncing with Google Calendar:", error);
11031
+ return {
11032
+ success: false,
11033
+ syncedEvents: 0,
11034
+ errors: [{ error: error.message || "Unknown error" }],
11035
+ eventIds: []
11036
+ };
11037
+ }
11038
+ }
11039
+ async function fetchEventsFromGoogleCalendarUtil(db, entityType, entityId, syncedCalendar, startDate, endDate) {
11040
+ try {
11041
+ const accessToken = await ensureValidToken(
11042
+ db,
11043
+ entityType,
11044
+ entityId,
11045
+ syncedCalendar
11046
+ );
11047
+ const timeMin = startDate.toISOString();
11048
+ const timeMax = endDate.toISOString();
11049
+ const response = await makeRequest(
11050
+ "get",
11051
+ `${GOOGLE_CALENDAR_API_URL}/calendars/${syncedCalendar.calendarId}/events`,
11052
+ { Authorization: `Bearer ${accessToken}` },
11053
+ void 0,
11054
+ {
11055
+ timeMin,
11056
+ timeMax,
11057
+ singleEvents: "true",
11058
+ orderBy: "startTime"
11059
+ }
11060
+ );
11061
+ await updateLastSyncedTimestampUtil(
11062
+ db,
11063
+ entityType,
11064
+ entityId,
11065
+ syncedCalendar.id
11066
+ );
11067
+ return response.items;
11068
+ } catch (error) {
11069
+ const apiError = error;
11070
+ console.error(
11071
+ "Error fetching events from Google Calendar:",
11072
+ apiError.message || "Unknown error"
11073
+ );
11074
+ throw new Error(
11075
+ `Failed to fetch events from Google Calendar: ${apiError.message || "Unknown error"}`
11076
+ );
11077
+ }
11078
+ }
11079
+ function convertGoogleEventToCalendarEventUtil(googleEvent, entityId, entityType) {
11080
+ const start = googleEvent.start.dateTime ? new Date(googleEvent.start.dateTime) : new Date(googleEvent.start.date);
11081
+ const end = googleEvent.end.dateTime ? new Date(googleEvent.end.dateTime) : new Date(googleEvent.end.date);
11082
+ const calendarEvent = {
11083
+ eventName: googleEvent.summary || "External Event",
11084
+ eventLocation: googleEvent.location,
11085
+ eventTime: {
11086
+ start: import_firestore35.Timestamp.fromDate(start),
11087
+ end: import_firestore35.Timestamp.fromDate(end)
11088
+ },
11089
+ description: googleEvent.description || "",
11090
+ // External events are always set as CONFIRMED - status updates will happen externally
11091
+ status: "confirmed" /* CONFIRMED */,
11092
+ // All external events are marked as EXTERNAL to indicate they originated outside our system
11093
+ syncStatus: "external" /* EXTERNAL */,
11094
+ // All external events are treated as BLOCKING events
11095
+ eventType: "blocking" /* BLOCKING */,
11096
+ // Store the original Google Calendar event ID
11097
+ syncedCalendarEventId: [
11098
+ {
11099
+ eventId: googleEvent.id,
11100
+ syncedCalendarProvider: "google" /* GOOGLE */,
11101
+ syncedAt: import_firestore35.Timestamp.now()
11102
+ }
11103
+ ]
11104
+ };
11105
+ switch (entityType) {
11106
+ case "practitioner":
11107
+ calendarEvent.practitionerProfileId = entityId;
11108
+ break;
11109
+ case "patient":
11110
+ calendarEvent.patientProfileId = entityId;
11111
+ break;
11112
+ case "clinic":
11113
+ calendarEvent.clinicBranchId = entityId;
11114
+ break;
11115
+ }
11116
+ return calendarEvent;
11117
+ }
11118
+ function convertCalendarEventToGoogleEventUtil(calendarEvent) {
11119
+ const googleEvent = {
11120
+ summary: calendarEvent.eventName,
11121
+ location: calendarEvent.eventLocation,
11122
+ description: calendarEvent.description,
11123
+ start: {
11124
+ dateTime: calendarEvent.eventTime.start.toDate().toISOString(),
11125
+ timeZone: "UTC"
11126
+ },
11127
+ end: {
11128
+ dateTime: calendarEvent.eventTime.end.toDate().toISOString(),
11129
+ timeZone: "UTC"
11130
+ },
11131
+ // Add reminders
11132
+ reminders: {
11133
+ useDefault: false,
11134
+ overrides: [
11135
+ { method: "email", minutes: 24 * 60 },
11136
+ // 1 day before
11137
+ { method: "popup", minutes: 30 }
11138
+ // 30 minutes before
11139
+ ]
11140
+ }
11141
+ };
11142
+ switch (calendarEvent.status) {
11143
+ case "confirmed" /* CONFIRMED */:
11144
+ googleEvent.status = "confirmed";
11145
+ break;
11146
+ case "canceled" /* CANCELED */:
11147
+ googleEvent.status = "cancelled";
11148
+ break;
11149
+ case "pending" /* PENDING */:
11150
+ googleEvent.status = "tentative";
11151
+ break;
11152
+ default:
11153
+ googleEvent.status = "confirmed";
11154
+ }
11155
+ if (calendarEvent.eventType === "appointment" /* APPOINTMENT */) {
11156
+ googleEvent.attendees = [];
11157
+ if (calendarEvent.practitionerProfileId) {
11158
+ googleEvent.attendees.push({
11159
+ email: "practitioner@example.com",
11160
+ // This would be fetched from the practitioner profile
11161
+ displayName: "Dr. Practitioner",
11162
+ // This would be fetched from the practitioner profile
11163
+ responseStatus: "accepted"
11164
+ });
11165
+ }
11166
+ if (calendarEvent.patientProfileId) {
11167
+ googleEvent.attendees.push({
11168
+ email: "patient@example.com",
11169
+ // This would be fetched from the patient profile
11170
+ displayName: "Patient",
11171
+ // This would be fetched from the patient profile
11172
+ responseStatus: "needsAction"
11173
+ });
11174
+ }
11175
+ }
11176
+ return googleEvent;
11177
+ }
11178
+ async function deleteGoogleCalendarEventUtil(db, entityType, entityId, syncedCalendar, eventId) {
11179
+ try {
11180
+ const accessToken = await ensureValidToken(
11181
+ db,
11182
+ entityType,
11183
+ entityId,
11184
+ syncedCalendar
11185
+ );
11186
+ await makeRequest(
11187
+ "delete",
11188
+ `${GOOGLE_CALENDAR_API_URL}/calendars/${syncedCalendar.calendarId}/events/${eventId}`,
11189
+ { Authorization: `Bearer ${accessToken}` }
11190
+ );
11191
+ return true;
11192
+ } catch (error) {
11193
+ const apiError = error;
11194
+ console.error(
11195
+ "Error deleting event from Google Calendar:",
11196
+ apiError.message || "Unknown error"
11197
+ );
11198
+ throw new Error(
11199
+ `Failed to delete event from Google Calendar: ${apiError.message || "Unknown error"}`
11200
+ );
11201
+ }
11202
+ }
11203
+ function getGoogleCalendarOAuthUrlUtil(scopes = ["https://www.googleapis.com/auth/calendar"]) {
11204
+ const scopeString = encodeURIComponent(scopes.join(" "));
11205
+ return `https://accounts.google.com/o/oauth2/v2/auth?client_id=${CLIENT_ID}&redirect_uri=${encodeURIComponent(
11206
+ REDIRECT_URI
11207
+ )}&response_type=code&scope=${scopeString}&access_type=offline&prompt=consent`;
11208
+ }
11209
+
11210
+ // src/services/calendar/synced-calendars.service.ts
11211
+ var SyncedCalendarsService = class extends BaseService {
11212
+ /**
11213
+ * Creates a new SyncedCalendarsService instance
11214
+ * @param db - Firestore instance
11215
+ * @param auth - Firebase Auth instance
11216
+ * @param app - Firebase App instance
11217
+ */
11218
+ constructor(db, auth, app) {
11219
+ super(db, auth, app);
11220
+ }
11221
+ // ===== Practitioner Synced Calendars =====
11222
+ /**
11223
+ * Creates a synced calendar for a practitioner
11224
+ * @param practitionerId - ID of the practitioner
11225
+ * @param calendarData - Synced calendar data
11226
+ * @returns Created synced calendar
11227
+ */
11228
+ async createPractitionerSyncedCalendar(practitionerId, calendarData) {
11229
+ return createPractitionerSyncedCalendarUtil(
11230
+ this.db,
11231
+ practitionerId,
11232
+ calendarData,
11233
+ this.generateId.bind(this)
11234
+ );
11235
+ }
11236
+ /**
11237
+ * Gets a synced calendar for a practitioner
11238
+ * @param practitionerId - ID of the practitioner
11239
+ * @param calendarId - ID of the synced calendar
11240
+ * @returns Synced calendar or null if not found
11241
+ */
11242
+ async getPractitionerSyncedCalendar(practitionerId, calendarId) {
11243
+ return getPractitionerSyncedCalendarUtil(
11244
+ this.db,
11245
+ practitionerId,
11246
+ calendarId
11247
+ );
11248
+ }
11249
+ /**
11250
+ * Gets all synced calendars for a practitioner
11251
+ * @param practitionerId - ID of the practitioner
11252
+ * @returns Array of synced calendars
11253
+ */
11254
+ async getPractitionerSyncedCalendars(practitionerId) {
11255
+ return getPractitionerSyncedCalendarsUtil(this.db, practitionerId);
11256
+ }
11257
+ /**
11258
+ * Updates a synced calendar for a practitioner
11259
+ * @param practitionerId - ID of the practitioner
11260
+ * @param calendarId - ID of the synced calendar
11261
+ * @param updateData - Data to update
11262
+ * @returns Updated synced calendar
11263
+ */
11264
+ async updatePractitionerSyncedCalendar(practitionerId, calendarId, updateData) {
11265
+ return updatePractitionerSyncedCalendarUtil(
11266
+ this.db,
11267
+ practitionerId,
11268
+ calendarId,
11269
+ updateData
11270
+ );
11271
+ }
11272
+ /**
11273
+ * Deletes a synced calendar for a practitioner
11274
+ * @param practitionerId - ID of the practitioner
11275
+ * @param calendarId - ID of the synced calendar
11276
+ */
11277
+ async deletePractitionerSyncedCalendar(practitionerId, calendarId) {
11278
+ return deletePractitionerSyncedCalendarUtil(
11279
+ this.db,
11280
+ practitionerId,
11281
+ calendarId
11282
+ );
11283
+ }
11284
+ // ===== Patient Synced Calendars =====
11285
+ /**
11286
+ * Creates a synced calendar for a patient
11287
+ * @param patientId - ID of the patient
11288
+ * @param calendarData - Synced calendar data
11289
+ * @returns Created synced calendar
11290
+ */
11291
+ async createPatientSyncedCalendar(patientId, calendarData) {
11292
+ return createPatientSyncedCalendarUtil(
11293
+ this.db,
11294
+ patientId,
11295
+ calendarData,
11296
+ this.generateId.bind(this)
11297
+ );
11298
+ }
11299
+ /**
11300
+ * Gets a synced calendar for a patient
11301
+ * @param patientId - ID of the patient
11302
+ * @param calendarId - ID of the synced calendar
11303
+ * @returns Synced calendar or null if not found
11304
+ */
11305
+ async getPatientSyncedCalendar(patientId, calendarId) {
11306
+ return getPatientSyncedCalendarUtil(this.db, patientId, calendarId);
11307
+ }
11308
+ /**
11309
+ * Gets all synced calendars for a patient
11310
+ * @param patientId - ID of the patient
11311
+ * @returns Array of synced calendars
11312
+ */
11313
+ async getPatientSyncedCalendars(patientId) {
11314
+ return getPatientSyncedCalendarsUtil(this.db, patientId);
11315
+ }
11316
+ /**
11317
+ * Updates a synced calendar for a patient
11318
+ * @param patientId - ID of the patient
11319
+ * @param calendarId - ID of the synced calendar
11320
+ * @param updateData - Data to update
11321
+ * @returns Updated synced calendar
11322
+ */
11323
+ async updatePatientSyncedCalendar(patientId, calendarId, updateData) {
11324
+ return updatePatientSyncedCalendarUtil(
11325
+ this.db,
11326
+ patientId,
11327
+ calendarId,
11328
+ updateData
11329
+ );
11330
+ }
11331
+ /**
11332
+ * Deletes a synced calendar for a patient
11333
+ * @param patientId - ID of the patient
11334
+ * @param calendarId - ID of the synced calendar
11335
+ */
11336
+ async deletePatientSyncedCalendar(patientId, calendarId) {
11337
+ return deletePatientSyncedCalendarUtil(this.db, patientId, calendarId);
11338
+ }
11339
+ // ===== Clinic Synced Calendars =====
11340
+ /**
11341
+ * Creates a synced calendar for a clinic
11342
+ * @param clinicId - ID of the clinic
11343
+ * @param calendarData - Synced calendar data
11344
+ * @returns Created synced calendar
11345
+ */
11346
+ async createClinicSyncedCalendar(clinicId, calendarData) {
11347
+ return createClinicSyncedCalendarUtil(
11348
+ this.db,
11349
+ clinicId,
11350
+ calendarData,
11351
+ this.generateId.bind(this)
11352
+ );
11353
+ }
11354
+ /**
11355
+ * Gets a synced calendar for a clinic
11356
+ * @param clinicId - ID of the clinic
11357
+ * @param calendarId - ID of the synced calendar
11358
+ * @returns Synced calendar or null if not found
11359
+ */
11360
+ async getClinicSyncedCalendar(clinicId, calendarId) {
11361
+ return getClinicSyncedCalendarUtil(this.db, clinicId, calendarId);
11362
+ }
11363
+ /**
11364
+ * Gets all synced calendars for a clinic
11365
+ * @param clinicId - ID of the clinic
11366
+ * @returns Array of synced calendars
11367
+ */
11368
+ async getClinicSyncedCalendars(clinicId) {
11369
+ return getClinicSyncedCalendarsUtil(this.db, clinicId);
11370
+ }
11371
+ /**
11372
+ * Updates a synced calendar for a clinic
11373
+ * @param clinicId - ID of the clinic
11374
+ * @param calendarId - ID of the synced calendar
11375
+ * @param updateData - Data to update
11376
+ * @returns Updated synced calendar
11377
+ */
11378
+ async updateClinicSyncedCalendar(clinicId, calendarId, updateData) {
11379
+ return updateClinicSyncedCalendarUtil(
11380
+ this.db,
11381
+ clinicId,
11382
+ calendarId,
11383
+ updateData
11384
+ );
11385
+ }
11386
+ /**
11387
+ * Deletes a synced calendar for a clinic
11388
+ * @param clinicId - ID of the clinic
11389
+ * @param calendarId - ID of the synced calendar
11390
+ */
11391
+ async deleteClinicSyncedCalendar(clinicId, calendarId) {
11392
+ return deleteClinicSyncedCalendarUtil(this.db, clinicId, calendarId);
11393
+ }
11394
+ // ===== Google Calendar Integration =====
11395
+ /**
11396
+ * Gets the OAuth URL for Google Calendar
11397
+ * @param scopes - OAuth scopes to request
11398
+ * @returns OAuth URL
11399
+ */
11400
+ getGoogleCalendarOAuthUrl(scopes = ["https://www.googleapis.com/auth/calendar"]) {
11401
+ return getGoogleCalendarOAuthUrlUtil(scopes);
11402
+ }
11403
+ /**
11404
+ * Authenticates with Google Calendar using an authorization code
11405
+ * @param authCode - Authorization code from Google OAuth
11406
+ * @returns Access token, refresh token, and expiration time
11407
+ */
11408
+ async authenticateWithGoogleCalendar(authCode) {
11409
+ return authenticateWithGoogleCalendarUtil(authCode);
11410
+ }
11411
+ /**
11412
+ * Lists available Google Calendars for a user
11413
+ * @param accessToken - Google API access token
11414
+ * @returns List of available calendars
11415
+ */
11416
+ async listGoogleCalendars(accessToken) {
11417
+ return listGoogleCalendarsUtil(accessToken);
11418
+ }
11419
+ /**
11420
+ * Syncs events from our system to Google Calendar for a practitioner
11421
+ * @param practitionerId - ID of the practitioner
11422
+ * @param calendarId - ID of the synced calendar
11423
+ * @param events - Events to sync
11424
+ * @param existingSyncId - Optional existing sync ID for updating an event
11425
+ * @returns Result of the sync operation
11426
+ */
11427
+ async syncPractitionerEventsToGoogleCalendar(practitionerId, calendarId, events, existingSyncId) {
11428
+ const syncedCalendar = await this.getPractitionerSyncedCalendar(
11429
+ practitionerId,
11430
+ calendarId
11431
+ );
11432
+ if (!syncedCalendar) {
11433
+ throw new Error("Synced calendar not found");
11434
+ }
11435
+ return syncEventsToGoogleCalendarUtil(
11436
+ this.db,
11437
+ "practitioner",
11438
+ practitionerId,
11439
+ syncedCalendar,
11440
+ events,
11441
+ existingSyncId
11442
+ );
11443
+ }
11444
+ /**
11445
+ * Syncs events from our system to Google Calendar for a patient
11446
+ * @param patientId - ID of the patient
11447
+ * @param calendarId - ID of the synced calendar
11448
+ * @param events - Events to sync
11449
+ * @param existingSyncId - Optional existing sync ID for updating an event
11450
+ * @returns Result of the sync operation
11451
+ */
11452
+ async syncPatientEventsToGoogleCalendar(patientId, calendarId, events, existingSyncId) {
11453
+ const syncedCalendar = await this.getPatientSyncedCalendar(
11454
+ patientId,
11455
+ calendarId
11456
+ );
11457
+ if (!syncedCalendar) {
11458
+ throw new Error("Synced calendar not found");
11459
+ }
11460
+ return syncEventsToGoogleCalendarUtil(
11461
+ this.db,
11462
+ "patient",
11463
+ patientId,
11464
+ syncedCalendar,
11465
+ events,
11466
+ existingSyncId
11467
+ );
11468
+ }
11469
+ /**
11470
+ * Syncs events from our system to Google Calendar for a clinic
11471
+ * @param clinicId - ID of the clinic
11472
+ * @param calendarId - ID of the synced calendar
11473
+ * @param events - Events to sync
11474
+ * @returns Result of the sync operation
11475
+ */
11476
+ async syncClinicEventsToGoogleCalendar(clinicId, calendarId, events) {
11477
+ const syncedCalendar = await this.getClinicSyncedCalendar(
11478
+ clinicId,
11479
+ calendarId
11480
+ );
11481
+ if (!syncedCalendar) {
11482
+ throw new Error("Synced calendar not found");
11483
+ }
11484
+ return syncEventsToGoogleCalendarUtil(
11485
+ this.db,
11486
+ "clinic",
11487
+ clinicId,
11488
+ syncedCalendar,
11489
+ events
11490
+ );
11491
+ }
11492
+ /**
11493
+ * Fetches events from Google Calendar for a practitioner
11494
+ * @param practitionerId - ID of the practitioner
11495
+ * @param calendarId - ID of the synced calendar
11496
+ * @param startDate - Start date for fetching events
11497
+ * @param endDate - End date for fetching events
11498
+ * @returns Events fetched from Google Calendar
11499
+ */
11500
+ async fetchEventsFromPractitionerGoogleCalendar(practitionerId, calendarId, startDate, endDate) {
11501
+ const syncedCalendar = await this.getPractitionerSyncedCalendar(
11502
+ practitionerId,
11503
+ calendarId
11504
+ );
11505
+ if (!syncedCalendar) {
11506
+ throw new Error("Synced calendar not found");
11507
+ }
11508
+ return fetchEventsFromGoogleCalendarUtil(
11509
+ this.db,
11510
+ "practitioner",
11511
+ practitionerId,
11512
+ syncedCalendar,
11513
+ startDate,
11514
+ endDate
11515
+ );
11516
+ }
11517
+ /**
11518
+ * Fetches events from Google Calendar for a patient
11519
+ * @param patientId - ID of the patient
11520
+ * @param calendarId - ID of the synced calendar
11521
+ * @param startDate - Start date for fetching events
11522
+ * @param endDate - End date for fetching events
11523
+ * @returns Events fetched from Google Calendar
11524
+ */
11525
+ async fetchEventsFromPatientGoogleCalendar(patientId, calendarId, startDate, endDate) {
11526
+ const syncedCalendar = await this.getPatientSyncedCalendar(
11527
+ patientId,
11528
+ calendarId
11529
+ );
11530
+ if (!syncedCalendar) {
11531
+ throw new Error("Synced calendar not found");
11532
+ }
11533
+ return fetchEventsFromGoogleCalendarUtil(
11534
+ this.db,
11535
+ "patient",
11536
+ patientId,
11537
+ syncedCalendar,
11538
+ startDate,
11539
+ endDate
11540
+ );
11541
+ }
11542
+ /**
11543
+ * Fetches events from Google Calendar for a clinic
11544
+ * @param clinicId - ID of the clinic
11545
+ * @param calendarId - ID of the synced calendar
11546
+ * @param startDate - Start date for fetching events
11547
+ * @param endDate - End date for fetching events
11548
+ * @returns Events fetched from Google Calendar
11549
+ */
11550
+ async fetchEventsFromClinicGoogleCalendar(clinicId, calendarId, startDate, endDate) {
11551
+ const syncedCalendar = await this.getClinicSyncedCalendar(
11552
+ clinicId,
11553
+ calendarId
11554
+ );
11555
+ if (!syncedCalendar) {
11556
+ throw new Error("Synced calendar not found");
11557
+ }
11558
+ return fetchEventsFromGoogleCalendarUtil(
11559
+ this.db,
11560
+ "clinic",
11561
+ clinicId,
11562
+ syncedCalendar,
11563
+ startDate,
11564
+ endDate
11565
+ );
11566
+ }
11567
+ /**
11568
+ * Deletes an event from Google Calendar for a practitioner
11569
+ * @param practitionerId - ID of the practitioner
11570
+ * @param calendarId - ID of the synced calendar
11571
+ * @param eventId - ID of the event in Google Calendar
11572
+ * @returns Success status
11573
+ */
11574
+ async deletePractitionerGoogleCalendarEvent(practitionerId, calendarId, eventId) {
11575
+ const syncedCalendar = await this.getPractitionerSyncedCalendar(
11576
+ practitionerId,
11577
+ calendarId
11578
+ );
11579
+ if (!syncedCalendar) {
11580
+ throw new Error("Synced calendar not found");
11581
+ }
11582
+ return deleteGoogleCalendarEventUtil(
11583
+ this.db,
11584
+ "practitioner",
11585
+ practitionerId,
11586
+ syncedCalendar,
11587
+ eventId
11588
+ );
11589
+ }
11590
+ /**
11591
+ * Deletes an event from Google Calendar for a patient
11592
+ * @param patientId - ID of the patient
11593
+ * @param calendarId - ID of the synced calendar
11594
+ * @param eventId - ID of the event in Google Calendar
11595
+ * @returns Success status
11596
+ */
11597
+ async deletePatientGoogleCalendarEvent(patientId, calendarId, eventId) {
11598
+ const syncedCalendar = await this.getPatientSyncedCalendar(
11599
+ patientId,
11600
+ calendarId
11601
+ );
11602
+ if (!syncedCalendar) {
11603
+ throw new Error("Synced calendar not found");
11604
+ }
11605
+ return deleteGoogleCalendarEventUtil(
11606
+ this.db,
11607
+ "patient",
11608
+ patientId,
11609
+ syncedCalendar,
11610
+ eventId
11611
+ );
11612
+ }
11613
+ /**
11614
+ * Deletes an event from Google Calendar for a clinic
11615
+ * @param clinicId - ID of the clinic
11616
+ * @param calendarId - ID of the synced calendar
11617
+ * @param eventId - ID of the event in Google Calendar
11618
+ * @returns Success status
11619
+ */
11620
+ async deleteClinicGoogleCalendarEvent(clinicId, calendarId, eventId) {
11621
+ const syncedCalendar = await this.getClinicSyncedCalendar(
11622
+ clinicId,
11623
+ calendarId
11624
+ );
11625
+ if (!syncedCalendar) {
11626
+ throw new Error("Synced calendar not found");
11627
+ }
11628
+ return deleteGoogleCalendarEventUtil(
11629
+ this.db,
11630
+ "clinic",
11631
+ clinicId,
11632
+ syncedCalendar,
11633
+ eventId
11634
+ );
11635
+ }
11636
+ /**
11637
+ * Converts Google Calendar events to our system's format for a practitioner
11638
+ * @param practitionerId - ID of the practitioner
11639
+ * @param googleEvents - Google Calendar events
11640
+ * @returns Converted calendar events
11641
+ */
11642
+ convertGoogleEventsToPractitionerEvents(practitionerId, googleEvents) {
11643
+ return googleEvents.map(
11644
+ (event) => convertGoogleEventToCalendarEventUtil(
11645
+ event,
11646
+ practitionerId,
11647
+ "practitioner"
11648
+ )
11649
+ );
11650
+ }
11651
+ /**
11652
+ * Converts Google Calendar events to our system's format for a patient
11653
+ * @param patientId - ID of the patient
11654
+ * @param googleEvents - Google Calendar events
11655
+ * @returns Converted calendar events
11656
+ */
11657
+ convertGoogleEventsToPatientEvents(patientId, googleEvents) {
11658
+ return googleEvents.map(
11659
+ (event) => convertGoogleEventToCalendarEventUtil(event, patientId, "patient")
11660
+ );
11661
+ }
11662
+ /**
11663
+ * Converts Google Calendar events to our system's format for a clinic
11664
+ * @param clinicId - ID of the clinic
11665
+ * @param googleEvents - Google Calendar events
11666
+ * @returns Converted calendar events
11667
+ */
11668
+ convertGoogleEventsToClinicEvents(clinicId, googleEvents) {
11669
+ return googleEvents.map(
11670
+ (event) => convertGoogleEventToCalendarEventUtil(event, clinicId, "clinic")
11671
+ );
11672
+ }
11673
+ /**
11674
+ * Fetches a single event from Google Calendar for a practitioner
11675
+ * @param practitionerId - ID of the practitioner
11676
+ * @param calendarId - ID of the synced calendar
11677
+ * @param eventId - ID of the event in Google Calendar
11678
+ * @returns The event data or null if not found
11679
+ */
11680
+ async fetchEventFromPractitionerGoogleCalendar(practitionerId, calendarId, eventId) {
11681
+ var _a;
11682
+ const syncedCalendar = await this.getPractitionerSyncedCalendar(
11683
+ practitionerId,
11684
+ calendarId
11685
+ );
11686
+ if (!syncedCalendar) {
11687
+ throw new Error("Synced calendar not found");
11688
+ }
11689
+ try {
11690
+ const { accessToken } = await refreshGoogleCalendarTokenUtil(
11691
+ syncedCalendar.refreshToken
11692
+ );
11693
+ const response = await makeRequest(
11694
+ "get",
11695
+ `${GOOGLE_CALENDAR_API_URL}/calendars/${syncedCalendar.calendarId}/events/${eventId}`,
11696
+ { Authorization: `Bearer ${accessToken}` }
11697
+ );
11698
+ await updateLastSyncedTimestampUtil(
11699
+ this.db,
11700
+ "practitioner",
11701
+ practitionerId,
11702
+ syncedCalendar.id
11703
+ );
11704
+ return response;
11705
+ } catch (error) {
11706
+ if (((_a = error.response) == null ? void 0 : _a.status) === 404) {
11707
+ return null;
11708
+ }
11709
+ console.error(
11710
+ `Error fetching event from Google Calendar: ${error.message}`
11711
+ );
11712
+ throw error;
11713
+ }
11714
+ }
11715
+ };
11716
+
11717
+ // src/services/calendar/calendar.v2.service.ts
11718
+ var MIN_APPOINTMENT_DURATION = 15;
11719
+ var CalendarServiceV2 = class extends BaseService {
11720
+ /**
11721
+ * Creates a new CalendarService instance
11722
+ * @param db - Firestore instance
11723
+ * @param auth - Firebase Auth instance
11724
+ * @param app - Firebase App instance
11725
+ */
11726
+ constructor(db, auth, app) {
11727
+ super(db, auth, app);
11728
+ this.syncedCalendarsService = new SyncedCalendarsService(db, auth, app);
11729
+ }
11730
+ // #region Public API Methods
11731
+ /**
11732
+ * Creates a new appointment with proper validation and scheduling rules
11733
+ * @param params - Appointment creation parameters
11734
+ * @returns Created calendar event
11735
+ */
11736
+ async createAppointment(params) {
11737
+ await this.validateAppointmentParams(params);
11738
+ await this.validateClinicWorkingHours(params.clinicId, params.eventTime);
11739
+ await this.validateDoctorAvailability(
11740
+ params.doctorId,
11741
+ params.eventTime,
11742
+ params.clinicId
11743
+ );
11744
+ const { clinicInfo, practitionerInfo, patientInfo } = await this.fetchProfileInfoCards(
11745
+ params.clinicId,
11746
+ params.doctorId,
11747
+ params.patientId
11748
+ );
11749
+ const appointmentData = {
11750
+ clinicBranchId: params.clinicId,
11751
+ clinicBranchInfo: clinicInfo,
11752
+ practitionerProfileId: params.doctorId,
11753
+ practitionerProfileInfo: practitionerInfo,
11754
+ patientProfileId: params.patientId,
11755
+ patientProfileInfo: patientInfo,
11756
+ procedureId: params.procedureId,
11757
+ eventLocation: params.eventLocation,
11758
+ eventName: "Appointment",
11759
+ // TODO: Add procedure name when procedure model is available
11760
+ eventTime: params.eventTime,
11761
+ description: params.description || "",
11762
+ status: "pending" /* PENDING */,
11763
+ syncStatus: "internal" /* INTERNAL */,
11764
+ eventType: "appointment" /* APPOINTMENT */
11765
+ };
11766
+ const appointment = await createAppointmentUtil2(
11767
+ this.db,
11768
+ params.clinicId,
11769
+ params.doctorId,
11770
+ params.patientId,
11771
+ appointmentData,
11772
+ this.generateId.bind(this)
11773
+ );
11774
+ await this.syncAppointmentWithExternalCalendars(appointment);
11775
+ return appointment;
11776
+ }
11777
+ /**
11778
+ * Updates an existing appointment
11779
+ * @param params - Appointment update parameters
11780
+ * @returns Updated calendar event
11781
+ */
11782
+ async updateAppointment(params) {
11783
+ await this.validateUpdatePermissions(params);
11784
+ const updateData = {
11785
+ eventTime: params.eventTime,
11786
+ description: params.description,
11787
+ status: params.status
11788
+ };
11789
+ const appointment = await updateAppointmentUtil2(
11790
+ this.db,
11791
+ params.clinicId,
11792
+ params.doctorId,
11793
+ params.patientId,
11794
+ params.appointmentId,
11795
+ updateData
11796
+ );
11797
+ await this.syncAppointmentWithExternalCalendars(appointment);
11798
+ return appointment;
11799
+ }
11800
+ /**
11801
+ * Gets available appointment slots for a doctor at a clinic
11802
+ * @param clinicId - ID of the clinic
11803
+ * @param doctorId - ID of the doctor
11804
+ * @param date - Date to check availability for
11805
+ * @returns Array of available time slots
11806
+ */
11807
+ async getAvailableSlots(clinicId, doctorId, date) {
11808
+ const workingHours = await this.getClinicWorkingHours(clinicId, date);
11809
+ const doctorSchedule = await this.getDoctorSchedule(doctorId, date);
11810
+ const existingAppointments = await this.getDoctorAppointments(
11811
+ doctorId,
11812
+ date
11813
+ );
11814
+ return this.calculateAvailableSlots(
11815
+ workingHours,
11816
+ doctorSchedule,
11817
+ existingAppointments
11818
+ );
11819
+ }
11820
+ /**
11821
+ * Confirms an appointment
11822
+ * @param appointmentId - ID of the appointment
11823
+ * @param clinicId - ID of the clinic
11824
+ * @returns Confirmed calendar event
11825
+ */
11826
+ async confirmAppointment(appointmentId, clinicId) {
11827
+ return this.updateAppointmentStatus(
11828
+ appointmentId,
11829
+ clinicId,
11830
+ "confirmed" /* CONFIRMED */
11831
+ );
11832
+ }
11833
+ /**
11834
+ * Rejects an appointment
11835
+ * @param appointmentId - ID of the appointment
11836
+ * @param clinicId - ID of the clinic
11837
+ * @returns Rejected calendar event
11838
+ */
11839
+ async rejectAppointment(appointmentId, clinicId) {
11840
+ return this.updateAppointmentStatus(
11841
+ appointmentId,
11842
+ clinicId,
11843
+ "rejected" /* REJECTED */
11844
+ );
11845
+ }
11846
+ /**
11847
+ * Cancels an appointment
11848
+ * @param appointmentId - ID of the appointment
11849
+ * @param clinicId - ID of the clinic
11850
+ * @returns Canceled calendar event
11851
+ */
11852
+ async cancelAppointment(appointmentId, clinicId) {
11853
+ return this.updateAppointmentStatus(
11854
+ appointmentId,
11855
+ clinicId,
11856
+ "canceled" /* CANCELED */
11857
+ );
11858
+ }
11859
+ /**
11860
+ * Imports events from external calendars
11861
+ * @param entityType - Type of entity (practitioner or patient)
11862
+ * @param entityId - ID of the entity
11863
+ * @param startDate - Start date for fetching events
11864
+ * @param endDate - End date for fetching events
11865
+ * @returns Number of events imported
11866
+ */
11867
+ async importEventsFromExternalCalendars(entityType, entityId, startDate, endDate) {
11868
+ if (entityType === "patient") {
11869
+ return 0;
11870
+ }
11871
+ const syncedCalendars = await this.syncedCalendarsService.getPractitionerSyncedCalendars(
11872
+ entityId
11873
+ );
11874
+ const activeCalendars = syncedCalendars.filter((cal) => cal.isActive);
11875
+ if (activeCalendars.length === 0) {
11876
+ return 0;
11877
+ }
11878
+ let importedEventsCount = 0;
11879
+ const currentTime = import_firestore36.Timestamp.now();
11880
+ for (const calendar of activeCalendars) {
11881
+ try {
11882
+ let externalEvents = [];
11883
+ if (calendar.provider === "google" /* GOOGLE */) {
11884
+ externalEvents = await this.syncedCalendarsService.fetchEventsFromPractitionerGoogleCalendar(
11885
+ entityId,
11886
+ calendar.id,
11887
+ startDate,
11888
+ endDate
11889
+ );
11890
+ }
11891
+ for (const externalEvent of externalEvents) {
11892
+ try {
11893
+ const convertedEvent = this.syncedCalendarsService.convertGoogleEventsToPractitionerEvents(
11894
+ entityId,
11895
+ [externalEvent]
11896
+ )[0];
11897
+ if (!convertedEvent.eventTime) {
11898
+ continue;
11899
+ }
11900
+ const eventData = {
11901
+ // Ensure all required fields are set
11902
+ eventName: convertedEvent.eventName || "External Event",
11903
+ eventTime: convertedEvent.eventTime,
11904
+ description: convertedEvent.description || "",
11905
+ status: "confirmed" /* CONFIRMED */,
11906
+ syncStatus: "external" /* EXTERNAL */,
11907
+ eventType: "blocking" /* BLOCKING */,
11908
+ practitionerProfileId: entityId,
11909
+ syncedCalendarEventId: [
11910
+ {
11911
+ eventId: externalEvent.id,
11912
+ syncedCalendarProvider: calendar.provider,
11913
+ syncedAt: currentTime
11914
+ }
11915
+ ]
11916
+ };
11917
+ const doctorEvent = await this.createDoctorBlockingEvent(
11918
+ entityId,
11919
+ eventData
11920
+ );
11921
+ if (doctorEvent) {
11922
+ importedEventsCount++;
11923
+ }
11924
+ } catch (eventError) {
11925
+ console.error("Error importing event:", eventError);
11926
+ }
11927
+ }
11928
+ } catch (calendarError) {
11929
+ console.error(
11930
+ `Error fetching events from calendar ${calendar.id}:`,
11931
+ calendarError
11932
+ );
11933
+ }
11934
+ }
11935
+ return importedEventsCount;
11936
+ }
11937
+ /**
11938
+ * Creates a blocking event in a doctor's calendar
11939
+ * @param doctorId - ID of the doctor
11940
+ * @param eventData - Calendar event data
11941
+ * @returns Created calendar event
11942
+ */
11943
+ async createDoctorBlockingEvent(doctorId, eventData) {
11944
+ try {
11945
+ const eventId = this.generateId();
11946
+ const eventRef = (0, import_firestore37.doc)(
11947
+ this.db,
11948
+ PRACTITIONERS_COLLECTION,
11949
+ doctorId,
11950
+ CALENDAR_COLLECTION,
11951
+ eventId
11952
+ );
11953
+ const newEvent = {
11954
+ id: eventId,
11955
+ ...eventData,
11956
+ createdAt: (0, import_firestore36.serverTimestamp)(),
11957
+ updatedAt: (0, import_firestore36.serverTimestamp)()
11958
+ };
11959
+ await (0, import_firestore37.setDoc)(eventRef, newEvent);
11960
+ return {
11961
+ ...newEvent,
11962
+ createdAt: import_firestore36.Timestamp.now(),
11963
+ updatedAt: import_firestore36.Timestamp.now()
11964
+ };
11965
+ } catch (error) {
11966
+ console.error(
11967
+ `Error creating blocking event for doctor ${doctorId}:`,
11968
+ error
11969
+ );
11970
+ return null;
11971
+ }
11972
+ }
11973
+ /**
11974
+ * Periodically syncs events from external calendars for doctors
11975
+ * This would be called via a scheduled Cloud Function
11976
+ * @param lookbackDays - Number of days to look back for events
11977
+ * @param lookforwardDays - Number of days to look forward for events
11978
+ */
11979
+ async synchronizeExternalCalendars(lookbackDays = 7, lookforwardDays = 30) {
11980
+ try {
11981
+ const practitionersRef = (0, import_firestore37.collection)(this.db, PRACTITIONERS_COLLECTION);
11982
+ const practitionersSnapshot = await (0, import_firestore37.getDocs)(practitionersRef);
11983
+ const startDate = /* @__PURE__ */ new Date();
11984
+ startDate.setDate(startDate.getDate() - lookbackDays);
11985
+ const endDate = /* @__PURE__ */ new Date();
11986
+ endDate.setDate(endDate.getDate() + lookforwardDays);
11987
+ const syncPromises = [];
11988
+ for (const docSnapshot of practitionersSnapshot.docs) {
11989
+ const practitionerId = docSnapshot.id;
11990
+ syncPromises.push(
11991
+ this.importEventsFromExternalCalendars(
11992
+ "doctor",
11993
+ practitionerId,
11994
+ startDate,
11995
+ endDate
11996
+ ).then((count) => {
11997
+ console.log(
11998
+ `Imported ${count} events for doctor ${practitionerId}`
11999
+ );
12000
+ }).catch((error) => {
12001
+ console.error(
12002
+ `Error importing events for doctor ${practitionerId}:`,
12003
+ error
12004
+ );
12005
+ })
12006
+ );
12007
+ syncPromises.push(
12008
+ this.updateExistingEventsFromExternalCalendars(
12009
+ practitionerId,
12010
+ startDate,
12011
+ endDate
12012
+ ).then((count) => {
12013
+ console.log(
12014
+ `Updated ${count} events for doctor ${practitionerId}`
12015
+ );
12016
+ }).catch((error) => {
12017
+ console.error(
12018
+ `Error updating events for doctor ${practitionerId}:`,
12019
+ error
12020
+ );
12021
+ })
12022
+ );
12023
+ }
12024
+ await Promise.all(syncPromises);
12025
+ console.log("Completed external calendar synchronization");
12026
+ } catch (error) {
12027
+ console.error("Error synchronizing external calendars:", error);
12028
+ }
12029
+ }
12030
+ /**
12031
+ * Updates existing events that were synced from external calendars
12032
+ * @param doctorId - ID of the doctor
12033
+ * @param startDate - Start date for fetching events
12034
+ * @param endDate - End date for fetching events
12035
+ * @returns Number of events updated
12036
+ */
12037
+ async updateExistingEventsFromExternalCalendars(doctorId, startDate, endDate) {
12038
+ var _a;
12039
+ try {
12040
+ const eventsRef = (0, import_firestore37.collection)(
12041
+ this.db,
12042
+ PRACTITIONERS_COLLECTION,
12043
+ doctorId,
12044
+ CALENDAR_COLLECTION
12045
+ );
12046
+ const q = (0, import_firestore37.query)(
12047
+ eventsRef,
12048
+ (0, import_firestore37.where)("syncStatus", "==", "external" /* EXTERNAL */),
12049
+ (0, import_firestore37.where)("eventTime.start", ">=", import_firestore36.Timestamp.fromDate(startDate)),
12050
+ (0, import_firestore37.where)("eventTime.start", "<=", import_firestore36.Timestamp.fromDate(endDate))
12051
+ );
12052
+ const eventsSnapshot = await (0, import_firestore37.getDocs)(q);
12053
+ const events = eventsSnapshot.docs.map((doc32) => ({
12054
+ id: doc32.id,
12055
+ ...doc32.data()
12056
+ }));
12057
+ const calendars = await this.syncedCalendarsService.getPractitionerSyncedCalendars(
12058
+ doctorId
12059
+ );
12060
+ const activeCalendars = calendars.filter((cal) => cal.isActive);
12061
+ if (activeCalendars.length === 0 || events.length === 0) {
12062
+ return 0;
12063
+ }
12064
+ let updatedCount = 0;
12065
+ for (const event of events) {
12066
+ if (!((_a = event.syncedCalendarEventId) == null ? void 0 : _a.length)) continue;
12067
+ for (const syncId of event.syncedCalendarEventId) {
12068
+ const calendar = activeCalendars.find(
12069
+ (cal) => cal.provider === syncId.syncedCalendarProvider
12070
+ );
12071
+ if (!calendar) continue;
12072
+ if (syncId.syncedCalendarProvider === "google" /* GOOGLE */) {
12073
+ try {
12074
+ const externalEvent = await this.fetchExternalEvent(
12075
+ doctorId,
12076
+ calendar,
12077
+ syncId.eventId
12078
+ );
12079
+ if (externalEvent) {
12080
+ const externalStartTime = new Date(
12081
+ externalEvent.start.dateTime || externalEvent.start.date
12082
+ ).getTime();
12083
+ const externalEndTime = new Date(
12084
+ externalEvent.end.dateTime || externalEvent.end.date
12085
+ ).getTime();
12086
+ const localStartTime = event.eventTime.start.toDate().getTime();
12087
+ const localEndTime = event.eventTime.end.toDate().getTime();
12088
+ if (externalStartTime !== localStartTime || externalEndTime !== localEndTime || externalEvent.summary !== event.eventName || externalEvent.description !== event.description) {
12089
+ await this.updateLocalEventFromExternal(
12090
+ doctorId,
12091
+ event.id,
12092
+ externalEvent
12093
+ );
12094
+ updatedCount++;
12095
+ }
12096
+ } else {
12097
+ await this.updateEventStatus(
12098
+ doctorId,
12099
+ event.id,
12100
+ "canceled" /* CANCELED */
12101
+ );
12102
+ updatedCount++;
12103
+ }
12104
+ } catch (error) {
12105
+ console.error(
12106
+ `Error updating external event ${event.id}:`,
12107
+ error
12108
+ );
12109
+ }
12110
+ }
12111
+ }
12112
+ }
12113
+ return updatedCount;
12114
+ } catch (error) {
12115
+ console.error(
12116
+ "Error updating existing events from external calendars:",
12117
+ error
12118
+ );
12119
+ return 0;
12120
+ }
12121
+ }
12122
+ /**
12123
+ * Fetches a single external event from Google Calendar
12124
+ * @param doctorId - ID of the doctor
12125
+ * @param calendar - Calendar information
12126
+ * @param externalEventId - ID of the external event
12127
+ * @returns External event data or null if not found
12128
+ */
12129
+ async fetchExternalEvent(doctorId, calendar, externalEventId) {
12130
+ try {
12131
+ if (calendar.provider === "google" /* GOOGLE */) {
12132
+ const result = await this.syncedCalendarsService.fetchEventFromPractitionerGoogleCalendar(
12133
+ doctorId,
12134
+ calendar.id,
12135
+ externalEventId
12136
+ );
12137
+ return result;
12138
+ }
12139
+ return null;
12140
+ } catch (error) {
12141
+ console.error(`Error fetching external event ${externalEventId}:`, error);
12142
+ return null;
12143
+ }
12144
+ }
12145
+ /**
12146
+ * Updates a local event with data from an external event
12147
+ * @param doctorId - ID of the doctor
12148
+ * @param eventId - ID of the local event
12149
+ * @param externalEvent - External event data
12150
+ */
12151
+ async updateLocalEventFromExternal(doctorId, eventId, externalEvent) {
12152
+ try {
12153
+ const startTime = new Date(
12154
+ externalEvent.start.dateTime || externalEvent.start.date
12155
+ );
12156
+ const endTime = new Date(
12157
+ externalEvent.end.dateTime || externalEvent.end.date
12158
+ );
12159
+ const eventRef = (0, import_firestore37.doc)(
12160
+ this.db,
12161
+ PRACTITIONERS_COLLECTION,
12162
+ doctorId,
12163
+ CALENDAR_COLLECTION,
12164
+ eventId
12165
+ );
12166
+ await (0, import_firestore37.updateDoc)(eventRef, {
12167
+ eventName: externalEvent.summary || "External Event",
12168
+ eventTime: {
12169
+ start: import_firestore36.Timestamp.fromDate(startTime),
12170
+ end: import_firestore36.Timestamp.fromDate(endTime)
12171
+ },
12172
+ description: externalEvent.description || "",
12173
+ updatedAt: (0, import_firestore36.serverTimestamp)()
12174
+ });
12175
+ console.log(`Updated local event ${eventId} from external event`);
12176
+ } catch (error) {
12177
+ console.error(
12178
+ `Error updating local event ${eventId} from external:`,
12179
+ error
12180
+ );
12181
+ }
12182
+ }
12183
+ /**
12184
+ * Updates an event's status
12185
+ * @param doctorId - ID of the doctor
12186
+ * @param eventId - ID of the event
12187
+ * @param status - New status
12188
+ */
12189
+ async updateEventStatus(doctorId, eventId, status) {
12190
+ try {
12191
+ const eventRef = (0, import_firestore37.doc)(
12192
+ this.db,
12193
+ PRACTITIONERS_COLLECTION,
12194
+ doctorId,
12195
+ CALENDAR_COLLECTION,
12196
+ eventId
12197
+ );
12198
+ await (0, import_firestore37.updateDoc)(eventRef, {
12199
+ status,
12200
+ updatedAt: (0, import_firestore36.serverTimestamp)()
12201
+ });
12202
+ console.log(`Updated event ${eventId} status to ${status}`);
12203
+ } catch (error) {
12204
+ console.error(`Error updating event ${eventId} status:`, error);
12205
+ }
12206
+ }
12207
+ /**
12208
+ * Creates a scheduled job to periodically sync external calendars
12209
+ * Note: This would be implemented using Cloud Functions in a real application
12210
+ * This is a sample implementation to show how it could be set up
12211
+ * @param interval - Interval in hours
12212
+ */
12213
+ createScheduledSyncJob(interval = 3) {
12214
+ console.log(
12215
+ `Setting up scheduled calendar sync job every ${interval} hours`
12216
+ );
12217
+ }
12218
+ /**
12219
+ * Searches for calendar events based on specified criteria.
12220
+ *
12221
+ * @param {SearchCalendarEventsParams} params - The search parameters.
12222
+ * @param {SearchLocationEnum} params.searchLocation - The primary location to search (practitioner, patient, or clinic).
12223
+ * @param {string} params.entityId - The ID of the entity (practitioner, patient, or clinic) to search within/for.
12224
+ * @param {string} [params.clinicId] - Optional clinic ID to filter by.
12225
+ * @param {string} [params.practitionerId] - Optional practitioner ID to filter by.
12226
+ * @param {string} [params.patientId] - Optional patient ID to filter by.
12227
+ * @param {string} [params.procedureId] - Optional procedure ID to filter by.
12228
+ * @param {DateRange} [params.dateRange] - Optional date range to filter by (event start time).
12229
+ * @param {CalendarEventStatus} [params.eventStatus] - Optional event status to filter by.
12230
+ * @param {CalendarEventType} [params.eventType] - Optional event type to filter by.
12231
+ * @returns {Promise<CalendarEvent[]>} A promise that resolves to an array of matching calendar events.
12232
+ * @throws {Error} If the search location requires an entity ID that is not provided.
12233
+ */
12234
+ async searchCalendarEvents(params) {
12235
+ return searchCalendarEventsUtil(this.db, params);
12236
+ }
12237
+ /**
12238
+ * Gets a doctor's upcoming appointments for a specific date range
12239
+ *
12240
+ * @param {string} doctorId - ID of the practitioner
12241
+ * @param {Date} startDate - Start date of the range
12242
+ * @param {Date} endDate - End date of the range
12243
+ * @param {CalendarEventStatus} [status] - Optional status filter (defaults to CONFIRMED)
12244
+ * @returns {Promise<CalendarEvent[]>} A promise that resolves to an array of appointments
12245
+ */
12246
+ async getPractitionerUpcomingAppointments(doctorId, startDate, endDate, status = "confirmed" /* CONFIRMED */) {
12247
+ const dateRange = {
12248
+ start: import_firestore36.Timestamp.fromDate(startDate),
12249
+ end: import_firestore36.Timestamp.fromDate(endDate)
12250
+ };
12251
+ const searchParams = {
12252
+ searchLocation: "practitioner" /* PRACTITIONER */,
12253
+ entityId: doctorId,
12254
+ dateRange,
12255
+ eventStatus: status,
12256
+ eventType: "appointment" /* APPOINTMENT */
12257
+ };
12258
+ return this.searchCalendarEvents(searchParams);
12259
+ }
12260
+ /**
12261
+ * Gets a patient's appointments for a specific date range
12262
+ *
12263
+ * @param {string} patientId - ID of the patient
12264
+ * @param {Date} startDate - Start date of the range
12265
+ * @param {Date} endDate - End date of the range
12266
+ * @param {CalendarEventStatus} [status] - Optional status filter (defaults to all non-canceled appointments)
12267
+ * @returns {Promise<CalendarEvent[]>} A promise that resolves to an array of appointments
12268
+ */
12269
+ async getPatientAppointments(patientId, startDate, endDate, status) {
12270
+ const dateRange = {
12271
+ start: import_firestore36.Timestamp.fromDate(startDate),
12272
+ end: import_firestore36.Timestamp.fromDate(endDate)
12273
+ };
12274
+ const searchParams = {
12275
+ searchLocation: "patient" /* PATIENT */,
12276
+ entityId: patientId,
12277
+ dateRange,
12278
+ eventType: "appointment" /* APPOINTMENT */
12279
+ };
12280
+ if (status) {
12281
+ searchParams.eventStatus = status;
12282
+ }
12283
+ return this.searchCalendarEvents(searchParams);
12284
+ }
12285
+ /**
12286
+ * Gets all appointments for a clinic within a specific date range
12287
+ *
12288
+ * @param {string} clinicId - ID of the clinic
12289
+ * @param {Date} startDate - Start date of the range
12290
+ * @param {Date} endDate - End date of the range
12291
+ * @param {string} [doctorId] - Optional doctor ID to filter by
12292
+ * @param {CalendarEventStatus} [status] - Optional status filter
12293
+ * @returns {Promise<CalendarEvent[]>} A promise that resolves to an array of appointments
12294
+ */
12295
+ async getClinicAppointments(clinicId, startDate, endDate, doctorId, status) {
12296
+ const dateRange = {
12297
+ start: import_firestore36.Timestamp.fromDate(startDate),
12298
+ end: import_firestore36.Timestamp.fromDate(endDate)
12299
+ };
12300
+ const searchParams = {
12301
+ searchLocation: "clinic" /* CLINIC */,
12302
+ entityId: clinicId,
12303
+ dateRange,
12304
+ eventType: "appointment" /* APPOINTMENT */
12305
+ };
12306
+ if (doctorId) {
12307
+ searchParams.practitionerId = doctorId;
12308
+ }
12309
+ if (status) {
12310
+ searchParams.eventStatus = status;
12311
+ }
12312
+ return this.searchCalendarEvents(searchParams);
12313
+ }
12314
+ // #endregion
12315
+ // #region Private Helper Methods
12316
+ /**
12317
+ * Validates appointment creation parameters
12318
+ * @param params - Appointment parameters to validate
12319
+ * @throws Error if validation fails
12320
+ */
12321
+ async validateAppointmentParams(params) {
12322
+ await createAppointmentSchema.parseAsync(params);
12323
+ }
12324
+ /**
12325
+ * Validates if the event time falls within clinic working hours
12326
+ * @param clinicId - ID of the clinic
12327
+ * @param eventTime - Event time to validate
12328
+ * @throws Error if validation fails
12329
+ */
12330
+ async validateClinicWorkingHours(clinicId, eventTime) {
12331
+ const startDate = eventTime.start.toDate();
12332
+ const workingHours = await this.getClinicWorkingHours(clinicId, startDate);
12333
+ if (workingHours.length === 0) {
12334
+ throw new Error("Clinic is not open on this day");
12335
+ }
12336
+ const startTime = startDate;
12337
+ const endTime = eventTime.end.toDate();
12338
+ const isWithinWorkingHours = workingHours.some((slot) => {
12339
+ return slot.start <= startTime && slot.end >= endTime && slot.isAvailable;
12340
+ });
12341
+ if (!isWithinWorkingHours) {
12342
+ throw new Error("Appointment time is outside clinic working hours");
12343
+ }
12344
+ }
12345
+ /**
12346
+ * Validates if the doctor is available during the event time
12347
+ * @param doctorId - ID of the doctor
12348
+ * @param eventTime - Event time to validate
12349
+ * @param clinicId - ID of the clinic where the appointment is being booked
12350
+ * @throws Error if validation fails
12351
+ */
12352
+ async validateDoctorAvailability(doctorId, eventTime, clinicId) {
12353
+ var _a;
12354
+ const startDate = eventTime.start.toDate();
12355
+ const startTime = startDate;
12356
+ const endTime = eventTime.end.toDate();
12357
+ const practitionerRef = (0, import_firestore37.doc)(this.db, PRACTITIONERS_COLLECTION, doctorId);
12358
+ const practitionerDoc = await (0, import_firestore37.getDoc)(practitionerRef);
12359
+ if (!practitionerDoc.exists()) {
12360
+ throw new Error(`Doctor with ID ${doctorId} not found`);
12361
+ }
12362
+ const practitioner = practitionerDoc.data();
12363
+ if (!practitioner.clinics.includes(clinicId)) {
12364
+ throw new Error("Doctor does not work at this clinic");
12365
+ }
12366
+ const clinicWorkingHours = (_a = practitioner.clinicWorkingHours) == null ? void 0 : _a.find(
12367
+ (hours) => hours.clinicId === clinicId && hours.isActive
12368
+ );
12369
+ if (!clinicWorkingHours) {
12370
+ throw new Error("Doctor does not have working hours set for this clinic");
12371
+ }
12372
+ const dayOfWeek = startDate.getDay();
12373
+ const dayKey = [
12374
+ "sunday",
12375
+ "monday",
12376
+ "tuesday",
12377
+ "wednesday",
12378
+ "thursday",
12379
+ "friday",
12380
+ "saturday"
12381
+ ][dayOfWeek];
12382
+ const daySchedule = clinicWorkingHours.workingHours[dayKey];
12383
+ if (!daySchedule) {
12384
+ throw new Error("Doctor is not working on this day at this clinic");
12385
+ }
12386
+ const [startHour, startMinute] = daySchedule.start.split(":").map(Number);
12387
+ const [endHour, endMinute] = daySchedule.end.split(":").map(Number);
12388
+ const scheduleStart = new Date(startDate);
12389
+ scheduleStart.setHours(startHour, startMinute, 0, 0);
12390
+ const scheduleEnd = new Date(startDate);
12391
+ scheduleEnd.setHours(endHour, endMinute, 0, 0);
12392
+ if (startTime < scheduleStart || endTime > scheduleEnd) {
12393
+ throw new Error(
12394
+ "Appointment time is outside doctor's working hours at this clinic"
12395
+ );
12396
+ }
12397
+ const appointments = await this.getDoctorAppointments(doctorId, startDate);
12398
+ const hasOverlap = appointments.some((appointment) => {
12399
+ const appointmentStart = appointment.eventTime.start.toDate();
12400
+ const appointmentEnd = appointment.eventTime.end.toDate();
12401
+ return startTime >= appointmentStart && startTime < appointmentEnd || endTime > appointmentStart && endTime <= appointmentEnd || startTime <= appointmentStart && endTime >= appointmentEnd;
12402
+ });
12403
+ if (hasOverlap) {
12404
+ throw new Error("Doctor has another appointment during this time");
12405
+ }
12406
+ }
12407
+ /**
12408
+ * Updates appointment status
12409
+ * @param appointmentId - ID of the appointment
12410
+ * @param clinicId - ID of the clinic
12411
+ * @param status - New status
12412
+ * @returns Updated calendar event
12413
+ */
12414
+ async updateAppointmentStatus(appointmentId, clinicId, status) {
12415
+ const baseCollectionPath = `${CLINICS_COLLECTION}/${clinicId}/${CALENDAR_COLLECTION}`;
12416
+ const appointmentRef = (0, import_firestore37.doc)(this.db, baseCollectionPath, appointmentId);
12417
+ const appointmentDoc = await (0, import_firestore37.getDoc)(appointmentRef);
12418
+ if (!appointmentDoc.exists()) {
12419
+ throw new Error(`Appointment with ID ${appointmentId} not found`);
12420
+ }
12421
+ const appointment = appointmentDoc.data();
12422
+ if (appointment.clinicBranchId !== clinicId) {
12423
+ throw new Error("Appointment does not belong to the specified clinic");
12424
+ }
12425
+ this.validateStatusTransition(appointment.status, status);
12426
+ const updateParams = {
12427
+ appointmentId,
12428
+ clinicId,
12429
+ eventTime: appointment.eventTime,
12430
+ description: appointment.description || "",
12431
+ doctorId: appointment.practitionerProfileId || "",
12432
+ patientId: appointment.patientProfileId || "",
12433
+ status
12434
+ };
12435
+ await this.validateUpdatePermissions(updateParams);
12436
+ return this.updateAppointment(updateParams);
12437
+ }
12438
+ /**
12439
+ * Validates status transition
12440
+ * @param currentStatus - Current status
12441
+ * @param newStatus - New status
12442
+ * @throws Error if transition is invalid
12443
+ */
12444
+ validateStatusTransition(currentStatus, newStatus) {
12445
+ const validTransitions = {
12446
+ ["pending" /* PENDING */]: [
12447
+ "confirmed" /* CONFIRMED */,
12448
+ "rejected" /* REJECTED */,
12449
+ "canceled" /* CANCELED */
12450
+ ],
12451
+ ["confirmed" /* CONFIRMED */]: [
12452
+ "canceled" /* CANCELED */,
12453
+ "completed" /* COMPLETED */,
12454
+ "rescheduled" /* RESCHEDULED */,
12455
+ "no_show" /* NO_SHOW */
12456
+ ],
12457
+ ["rejected" /* REJECTED */]: [],
12458
+ ["canceled" /* CANCELED */]: [],
12459
+ ["rescheduled" /* RESCHEDULED */]: [
12460
+ "confirmed" /* CONFIRMED */,
12461
+ "canceled" /* CANCELED */
12462
+ ],
12463
+ ["completed" /* COMPLETED */]: [],
12464
+ ["no_show" /* NO_SHOW */]: []
12465
+ };
12466
+ if (!validTransitions[currentStatus].includes(newStatus)) {
12467
+ throw new Error(
12468
+ `Invalid status transition from ${currentStatus} to ${newStatus}`
12469
+ );
12470
+ }
12471
+ }
12472
+ /**
12473
+ * Syncs appointment with external calendars based on entity type and status
12474
+ * @param appointment - Calendar event to sync
12475
+ */
12476
+ async syncAppointmentWithExternalCalendars(appointment) {
12477
+ if (!appointment.practitionerProfileId || !appointment.patientProfileId) {
12478
+ return;
12479
+ }
12480
+ try {
12481
+ const [doctorCalendars, patientCalendars] = await Promise.all([
12482
+ this.syncedCalendarsService.getPractitionerSyncedCalendars(
12483
+ appointment.practitionerProfileId
12484
+ ),
12485
+ this.syncedCalendarsService.getPatientSyncedCalendars(
12486
+ appointment.patientProfileId
12487
+ )
12488
+ ]);
12489
+ const activeDoctorCalendars = doctorCalendars.filter(
12490
+ (cal) => cal.isActive
12491
+ );
12492
+ const activePatientCalendars = patientCalendars.filter(
12493
+ (cal) => cal.isActive
12494
+ );
12495
+ if (activeDoctorCalendars.length === 0 && activePatientCalendars.length === 0) {
12496
+ return;
12497
+ }
12498
+ if (appointment.syncStatus !== "internal" /* INTERNAL */) {
12499
+ return;
10300
12500
  }
10301
- filters.practitionerId = void 0;
10302
- break;
10303
- case "patient" /* PATIENT */:
10304
- if (!entityId) {
10305
- throw new Error(
10306
- "Patient ID (entityId) is required when searching patient calendar."
12501
+ if (appointment.status === "confirmed" /* CONFIRMED */ && activeDoctorCalendars.length > 0) {
12502
+ await Promise.all(
12503
+ activeDoctorCalendars.map(
12504
+ (calendar) => this.syncEventToExternalCalendar(appointment, calendar, "doctor")
12505
+ )
10307
12506
  );
10308
12507
  }
10309
- baseCollectionPath = `${PATIENTS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}`;
10310
- if (filters.patientId && filters.patientId !== entityId) {
10311
- console.warn(
10312
- `Provided patientId filter (${filters.patientId}) does not match search entityId (${entityId}). Returning empty results.`
12508
+ if (appointment.status !== "canceled" /* CANCELED */ && appointment.status !== "rejected" /* REJECTED */ && activePatientCalendars.length > 0) {
12509
+ await Promise.all(
12510
+ activePatientCalendars.map(
12511
+ (calendar) => this.syncEventToExternalCalendar(appointment, calendar, "patient")
12512
+ )
10313
12513
  );
10314
- return [];
10315
12514
  }
10316
- filters.patientId = void 0;
10317
- break;
10318
- case "clinic" /* CLINIC */:
10319
- if (!entityId) {
10320
- throw new Error(
10321
- "Clinic ID (entityId) is required when searching clinic-related events."
10322
- );
12515
+ } catch (error) {
12516
+ console.error("Error syncing with external calendars:", error);
12517
+ }
12518
+ }
12519
+ /**
12520
+ * Syncs a single event to an external calendar
12521
+ * @param appointment - Calendar event to sync
12522
+ * @param calendar - External calendar to sync with
12523
+ * @param entityType - Type of entity owning the calendar
12524
+ */
12525
+ async syncEventToExternalCalendar(appointment, calendar, entityType) {
12526
+ var _a, _b, _c, _d, _e;
12527
+ try {
12528
+ const eventToSync = { ...appointment };
12529
+ let eventTitle = appointment.eventName;
12530
+ const clinicName = ((_a = appointment.clinicBranchInfo) == null ? void 0 : _a.name) || "Clinic";
12531
+ if (entityType === "patient") {
12532
+ eventTitle = `[${appointment.status}] ${eventTitle} @ ${clinicName}`;
12533
+ } else {
12534
+ eventTitle = `${eventTitle} - Patient: ${((_b = appointment.patientProfileInfo) == null ? void 0 : _b.fullName) || "Unknown"} @ ${clinicName}`;
10323
12535
  }
10324
- baseCollectionPath = `${CLINICS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}`;
10325
- constraints.push((0, import_firestore29.where)("clinicBranchId", "==", entityId));
10326
- if (filters.clinicId && filters.clinicId !== entityId) {
10327
- console.warn(
10328
- `Provided clinicId filter (${filters.clinicId}) does not match search entityId (${entityId}). Returning empty results.`
12536
+ eventToSync.eventName = eventTitle;
12537
+ const existingSyncId = (_d = (_c = appointment.syncedCalendarEventId) == null ? void 0 : _c.find(
12538
+ (sync) => sync.syncedCalendarProvider === calendar.provider
12539
+ )) == null ? void 0 : _d.eventId;
12540
+ if (calendar.provider === "google" /* GOOGLE */) {
12541
+ const result = await this.syncedCalendarsService.syncPractitionerEventsToGoogleCalendar(
12542
+ entityType === "doctor" ? appointment.practitionerProfileId : appointment.patientProfileId,
12543
+ calendar.id,
12544
+ [eventToSync],
12545
+ existingSyncId
12546
+ // Pass existing sync ID if we have one
10329
12547
  );
10330
- return [];
12548
+ if (result.success && ((_e = result.eventIds) == null ? void 0 : _e.length) && !existingSyncId) {
12549
+ const newSyncEvent = {
12550
+ eventId: result.eventIds[0],
12551
+ syncedCalendarProvider: calendar.provider,
12552
+ syncedAt: import_firestore36.Timestamp.now()
12553
+ };
12554
+ await this.updateEventWithSyncId(
12555
+ entityType === "doctor" ? appointment.practitionerProfileId : appointment.patientProfileId,
12556
+ entityType,
12557
+ appointment.id,
12558
+ newSyncEvent
12559
+ );
12560
+ }
10331
12561
  }
10332
- filters.clinicId = void 0;
10333
- break;
10334
- default:
10335
- throw new Error(`Invalid search location: ${searchLocation}`);
10336
- }
10337
- const collectionRef = (0, import_firestore29.collection)(db, baseCollectionPath);
10338
- if (filters.clinicId) {
10339
- constraints.push((0, import_firestore29.where)("clinicBranchId", "==", filters.clinicId));
12562
+ } catch (error) {
12563
+ console.error(`Error syncing with ${entityType}'s calendar:`, error);
12564
+ }
10340
12565
  }
10341
- if (filters.practitionerId) {
10342
- constraints.push(
10343
- (0, import_firestore29.where)("practitionerProfileId", "==", filters.practitionerId)
10344
- );
12566
+ /**
12567
+ * Updates an event with a new sync ID
12568
+ * @param entityId - ID of the entity (doctor or patient)
12569
+ * @param entityType - Type of entity
12570
+ * @param eventId - ID of the event
12571
+ * @param syncEvent - Sync event information
12572
+ */
12573
+ async updateEventWithSyncId(entityId, entityType, eventId, syncEvent) {
12574
+ try {
12575
+ const collectionPath = entityType === "doctor" ? `${PRACTITIONERS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}` : `${PATIENTS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}`;
12576
+ const eventRef = (0, import_firestore37.doc)(this.db, collectionPath, eventId);
12577
+ const eventDoc = await (0, import_firestore37.getDoc)(eventRef);
12578
+ if (eventDoc.exists()) {
12579
+ const event = eventDoc.data();
12580
+ const syncIds = [...event.syncedCalendarEventId || []];
12581
+ const existingSyncIndex = syncIds.findIndex(
12582
+ (sync) => sync.syncedCalendarProvider === syncEvent.syncedCalendarProvider
12583
+ );
12584
+ if (existingSyncIndex >= 0) {
12585
+ syncIds[existingSyncIndex] = syncEvent;
12586
+ } else {
12587
+ syncIds.push(syncEvent);
12588
+ }
12589
+ await (0, import_firestore37.updateDoc)(eventRef, {
12590
+ syncedCalendarEventId: syncIds,
12591
+ updatedAt: (0, import_firestore36.serverTimestamp)()
12592
+ });
12593
+ console.log(
12594
+ `Updated event ${eventId} with sync ID ${syncEvent.eventId}`
12595
+ );
12596
+ }
12597
+ } catch (error) {
12598
+ console.error("Error updating event with sync ID:", error);
12599
+ }
10345
12600
  }
10346
- if (filters.patientId) {
10347
- constraints.push((0, import_firestore29.where)("patientProfileId", "==", filters.patientId));
12601
+ /**
12602
+ * Validates update permissions and parameters
12603
+ * @param params - Update parameters to validate
12604
+ */
12605
+ async validateUpdatePermissions(params) {
12606
+ await updateAppointmentSchema.parseAsync(params);
10348
12607
  }
10349
- if (filters.procedureId) {
10350
- constraints.push((0, import_firestore29.where)("procedureId", "==", filters.procedureId));
12608
+ /**
12609
+ * Gets clinic working hours for a specific date
12610
+ * @param clinicId - ID of the clinic
12611
+ * @param date - Date to get working hours for
12612
+ * @returns Working hours for the clinic
12613
+ */
12614
+ async getClinicWorkingHours(clinicId, date) {
12615
+ const clinicRef = (0, import_firestore37.doc)(this.db, CLINICS_COLLECTION, clinicId);
12616
+ const clinicDoc = await (0, import_firestore37.getDoc)(clinicRef);
12617
+ if (!clinicDoc.exists()) {
12618
+ throw new Error(`Clinic with ID ${clinicId} not found`);
12619
+ }
12620
+ const workingHours = [];
12621
+ const dayOfWeek = date.getDay();
12622
+ if (dayOfWeek === 0 || dayOfWeek === 6) {
12623
+ return workingHours;
12624
+ }
12625
+ const workingDate = new Date(date);
12626
+ workingDate.setHours(9, 0, 0, 0);
12627
+ const startTime = new Date(workingDate);
12628
+ workingDate.setHours(17, 0, 0, 0);
12629
+ const endTime = new Date(workingDate);
12630
+ workingHours.push({
12631
+ start: startTime,
12632
+ end: endTime,
12633
+ isAvailable: true
12634
+ });
12635
+ return workingHours;
10351
12636
  }
10352
- if (filters.eventStatus) {
10353
- constraints.push((0, import_firestore29.where)("status", "==", filters.eventStatus));
12637
+ /**
12638
+ * Gets doctor's schedule for a specific date
12639
+ * @param doctorId - ID of the doctor
12640
+ * @param date - Date to get schedule for
12641
+ * @returns Doctor's schedule
12642
+ */
12643
+ async getDoctorSchedule(doctorId, date) {
12644
+ const practitionerRef = (0, import_firestore37.doc)(this.db, PRACTITIONERS_COLLECTION, doctorId);
12645
+ const practitionerDoc = await (0, import_firestore37.getDoc)(practitionerRef);
12646
+ if (!practitionerDoc.exists()) {
12647
+ throw new Error(`Doctor with ID ${doctorId} not found`);
12648
+ }
12649
+ const schedule = [];
12650
+ const dayOfWeek = date.getDay();
12651
+ if (dayOfWeek === 0 || dayOfWeek === 6) {
12652
+ return schedule;
12653
+ }
12654
+ const scheduleDate = new Date(date);
12655
+ scheduleDate.setHours(9, 0, 0, 0);
12656
+ const startTime = new Date(scheduleDate);
12657
+ scheduleDate.setHours(17, 0, 0, 0);
12658
+ const endTime = new Date(scheduleDate);
12659
+ schedule.push({
12660
+ start: startTime,
12661
+ end: endTime,
12662
+ isAvailable: true
12663
+ });
12664
+ return schedule;
10354
12665
  }
10355
- if (filters.eventType) {
10356
- constraints.push((0, import_firestore29.where)("eventType", "==", filters.eventType));
12666
+ /**
12667
+ * Gets doctor's appointments for a specific date
12668
+ * @param doctorId - ID of the doctor
12669
+ * @param date - Date to get appointments for
12670
+ * @returns Array of calendar events
12671
+ */
12672
+ async getDoctorAppointments(doctorId, date) {
12673
+ const startOfDay = new Date(date);
12674
+ startOfDay.setHours(0, 0, 0, 0);
12675
+ const endOfDay = new Date(date);
12676
+ endOfDay.setHours(23, 59, 59, 999);
12677
+ const appointmentsRef = (0, import_firestore37.collection)(this.db, CALENDAR_COLLECTION);
12678
+ const q = (0, import_firestore37.query)(
12679
+ appointmentsRef,
12680
+ (0, import_firestore37.where)("practitionerProfileId", "==", doctorId),
12681
+ (0, import_firestore37.where)("eventTime.start", ">=", import_firestore36.Timestamp.fromDate(startOfDay)),
12682
+ (0, import_firestore37.where)("eventTime.start", "<=", import_firestore36.Timestamp.fromDate(endOfDay)),
12683
+ (0, import_firestore37.where)("status", "in", [
12684
+ "confirmed" /* CONFIRMED */,
12685
+ "pending" /* PENDING */
12686
+ ])
12687
+ );
12688
+ const querySnapshot = await (0, import_firestore37.getDocs)(q);
12689
+ return querySnapshot.docs.map((doc32) => doc32.data());
10357
12690
  }
10358
- if (filters.dateRange) {
10359
- constraints.push((0, import_firestore29.where)("eventTime.start", ">=", filters.dateRange.start));
10360
- constraints.push((0, import_firestore29.where)("eventTime.start", "<=", filters.dateRange.end));
12691
+ /**
12692
+ * Calculates available time slots based on working hours, schedule and existing appointments
12693
+ * @param workingHours - Clinic working hours
12694
+ * @param doctorSchedule - Doctor's schedule
12695
+ * @param existingAppointments - Existing appointments
12696
+ * @returns Array of available time slots
12697
+ */
12698
+ calculateAvailableSlots(workingHours, doctorSchedule, existingAppointments) {
12699
+ const availableSlots = [];
12700
+ for (const workingHour of workingHours) {
12701
+ for (const scheduleSlot of doctorSchedule) {
12702
+ const overlapStart = new Date(
12703
+ Math.max(workingHour.start.getTime(), scheduleSlot.start.getTime())
12704
+ );
12705
+ const overlapEnd = new Date(
12706
+ Math.min(workingHour.end.getTime(), scheduleSlot.end.getTime())
12707
+ );
12708
+ if (overlapStart < overlapEnd && workingHour.isAvailable && scheduleSlot.isAvailable) {
12709
+ let slotStart = new Date(overlapStart);
12710
+ while (slotStart < overlapEnd) {
12711
+ const slotEnd = new Date(
12712
+ slotStart.getTime() + MIN_APPOINTMENT_DURATION * 60 * 1e3
12713
+ );
12714
+ const hasOverlap = existingAppointments.some((appointment) => {
12715
+ const appointmentStart = appointment.eventTime.start.toDate();
12716
+ const appointmentEnd = appointment.eventTime.end.toDate();
12717
+ return slotStart >= appointmentStart && slotStart < appointmentEnd || slotEnd > appointmentStart && slotEnd <= appointmentEnd;
12718
+ });
12719
+ if (!hasOverlap && slotEnd <= overlapEnd) {
12720
+ availableSlots.push({
12721
+ start: new Date(slotStart),
12722
+ end: new Date(slotEnd),
12723
+ isAvailable: true
12724
+ });
12725
+ }
12726
+ slotStart = new Date(
12727
+ slotStart.getTime() + MIN_APPOINTMENT_DURATION * 60 * 1e3
12728
+ );
12729
+ }
12730
+ }
12731
+ }
12732
+ }
12733
+ return availableSlots;
10361
12734
  }
10362
- try {
10363
- const finalQuery = (0, import_firestore29.query)(collectionRef, ...constraints);
10364
- const querySnapshot = await (0, import_firestore29.getDocs)(finalQuery);
10365
- const events = querySnapshot.docs.map(
10366
- (doc26) => ({ id: doc26.id, ...doc26.data() })
10367
- );
10368
- return events;
10369
- } catch (error) {
10370
- console.error("Error searching calendar events:", error);
10371
- return [];
12735
+ /**
12736
+ * Fetches and creates info cards for clinic, doctor, and patient profiles
12737
+ * @param clinicId - ID of the clinic
12738
+ * @param doctorId - ID of the doctor
12739
+ * @param patientId - ID of the patient
12740
+ * @returns Object containing info cards for all profiles
12741
+ */
12742
+ async fetchProfileInfoCards(clinicId, doctorId, patientId) {
12743
+ var _a;
12744
+ try {
12745
+ const [clinicDoc, practitionerDoc, patientDoc, patientSensitiveInfoDoc] = await Promise.all([
12746
+ (0, import_firestore37.getDoc)((0, import_firestore37.doc)(this.db, CLINICS_COLLECTION, clinicId)),
12747
+ (0, import_firestore37.getDoc)((0, import_firestore37.doc)(this.db, PRACTITIONERS_COLLECTION, doctorId)),
12748
+ (0, import_firestore37.getDoc)((0, import_firestore37.doc)(this.db, PATIENTS_COLLECTION, patientId)),
12749
+ (0, import_firestore37.getDoc)(
12750
+ (0, import_firestore37.doc)(
12751
+ this.db,
12752
+ PATIENTS_COLLECTION,
12753
+ patientId,
12754
+ PATIENT_SENSITIVE_INFO_COLLECTION,
12755
+ patientId
12756
+ )
12757
+ )
12758
+ ]);
12759
+ const clinicInfo = clinicDoc.exists() ? {
12760
+ id: clinicDoc.id,
12761
+ featuredPhoto: clinicDoc.data().featuredPhoto || "",
12762
+ name: clinicDoc.data().name,
12763
+ description: clinicDoc.data().description || "",
12764
+ location: clinicDoc.data().location,
12765
+ contactInfo: clinicDoc.data().contactInfo
12766
+ } : null;
12767
+ const practitionerInfo = practitionerDoc.exists() ? {
12768
+ id: practitionerDoc.id,
12769
+ practitionerPhoto: practitionerDoc.data().basicInfo.profileImageUrl || null,
12770
+ name: `${practitionerDoc.data().basicInfo.firstName} ${practitionerDoc.data().basicInfo.lastName}`,
12771
+ email: practitionerDoc.data().basicInfo.email,
12772
+ phone: practitionerDoc.data().basicInfo.phoneNumber || null,
12773
+ certification: practitionerDoc.data().certification
12774
+ } : null;
12775
+ let patientInfo = null;
12776
+ if (patientSensitiveInfoDoc.exists()) {
12777
+ const sensitiveData = patientSensitiveInfoDoc.data();
12778
+ patientInfo = {
12779
+ id: patientId,
12780
+ fullName: `${sensitiveData.firstName} ${sensitiveData.lastName}`,
12781
+ email: sensitiveData.email || "",
12782
+ phone: sensitiveData.phoneNumber || null,
12783
+ dateOfBirth: sensitiveData.dateOfBirth || import_firestore36.Timestamp.now(),
12784
+ gender: sensitiveData.gender || "other" /* OTHER */
12785
+ };
12786
+ } else if (patientDoc.exists()) {
12787
+ patientInfo = {
12788
+ id: patientDoc.id,
12789
+ fullName: patientDoc.data().displayName,
12790
+ email: ((_a = patientDoc.data().contactInfo) == null ? void 0 : _a.email) || "",
12791
+ phone: patientDoc.data().phoneNumber || null,
12792
+ dateOfBirth: patientDoc.data().dateOfBirth || import_firestore36.Timestamp.now(),
12793
+ gender: patientDoc.data().gender || "other" /* OTHER */
12794
+ };
12795
+ }
12796
+ return {
12797
+ clinicInfo,
12798
+ practitionerInfo,
12799
+ patientInfo
12800
+ };
12801
+ } catch (error) {
12802
+ console.error("Error fetching profile info cards:", error);
12803
+ return {
12804
+ clinicInfo: null,
12805
+ practitionerInfo: null,
12806
+ patientInfo: null
12807
+ };
12808
+ }
10372
12809
  }
10373
- }
12810
+ // #endregion
12811
+ };
10374
12812
 
10375
12813
  // src/services/calendar/calendar.v3.service.ts
12814
+ var import_firestore38 = require("firebase/firestore");
12815
+ var import_firestore39 = require("firebase/firestore");
10376
12816
  var CalendarServiceV3 = class extends BaseService {
10377
12817
  /**
10378
12818
  * Creates a new CalendarServiceV3 instance
@@ -10396,7 +12836,7 @@ var CalendarServiceV3 = class extends BaseService {
10396
12836
  params.entityType,
10397
12837
  params.entityId
10398
12838
  );
10399
- const eventRef = (0, import_firestore31.doc)(this.db, collectionPath, eventId);
12839
+ const eventRef = (0, import_firestore39.doc)(this.db, collectionPath, eventId);
10400
12840
  const eventData = {
10401
12841
  id: eventId,
10402
12842
  eventName: params.eventName,
@@ -10406,19 +12846,19 @@ var CalendarServiceV3 = class extends BaseService {
10406
12846
  status: "confirmed" /* CONFIRMED */,
10407
12847
  // Blocking events are always confirmed
10408
12848
  syncStatus: "internal" /* INTERNAL */,
10409
- createdAt: (0, import_firestore30.serverTimestamp)(),
10410
- updatedAt: (0, import_firestore30.serverTimestamp)()
12849
+ createdAt: (0, import_firestore38.serverTimestamp)(),
12850
+ updatedAt: (0, import_firestore38.serverTimestamp)()
10411
12851
  };
10412
12852
  if (params.entityType === "practitioner") {
10413
12853
  eventData.practitionerProfileId = params.entityId;
10414
12854
  } else {
10415
12855
  eventData.clinicBranchId = params.entityId;
10416
12856
  }
10417
- await (0, import_firestore31.setDoc)(eventRef, eventData);
12857
+ await (0, import_firestore39.setDoc)(eventRef, eventData);
10418
12858
  return {
10419
12859
  ...eventData,
10420
- createdAt: import_firestore30.Timestamp.now(),
10421
- updatedAt: import_firestore30.Timestamp.now()
12860
+ createdAt: import_firestore38.Timestamp.now(),
12861
+ updatedAt: import_firestore38.Timestamp.now()
10422
12862
  };
10423
12863
  }
10424
12864
  /**
@@ -10431,13 +12871,13 @@ var CalendarServiceV3 = class extends BaseService {
10431
12871
  params.entityType,
10432
12872
  params.entityId
10433
12873
  );
10434
- const eventRef = (0, import_firestore31.doc)(this.db, collectionPath, params.eventId);
10435
- const eventDoc = await (0, import_firestore31.getDoc)(eventRef);
12874
+ const eventRef = (0, import_firestore39.doc)(this.db, collectionPath, params.eventId);
12875
+ const eventDoc = await (0, import_firestore39.getDoc)(eventRef);
10436
12876
  if (!eventDoc.exists()) {
10437
12877
  throw new Error(`Blocking event with ID ${params.eventId} not found`);
10438
12878
  }
10439
12879
  const updateData = {
10440
- updatedAt: (0, import_firestore30.serverTimestamp)()
12880
+ updatedAt: (0, import_firestore38.serverTimestamp)()
10441
12881
  };
10442
12882
  if (params.eventName !== void 0) {
10443
12883
  updateData.eventName = params.eventName;
@@ -10451,8 +12891,8 @@ var CalendarServiceV3 = class extends BaseService {
10451
12891
  if (params.status !== void 0) {
10452
12892
  updateData.status = params.status;
10453
12893
  }
10454
- await (0, import_firestore31.updateDoc)(eventRef, updateData);
10455
- const updatedEventDoc = await (0, import_firestore31.getDoc)(eventRef);
12894
+ await (0, import_firestore39.updateDoc)(eventRef, updateData);
12895
+ const updatedEventDoc = await (0, import_firestore39.getDoc)(eventRef);
10456
12896
  return updatedEventDoc.data();
10457
12897
  }
10458
12898
  /**
@@ -10463,12 +12903,12 @@ var CalendarServiceV3 = class extends BaseService {
10463
12903
  */
10464
12904
  async deleteBlockingEvent(entityType, entityId, eventId) {
10465
12905
  const collectionPath = this.getEntityCalendarPath(entityType, entityId);
10466
- const eventRef = (0, import_firestore31.doc)(this.db, collectionPath, eventId);
10467
- const eventDoc = await (0, import_firestore31.getDoc)(eventRef);
12906
+ const eventRef = (0, import_firestore39.doc)(this.db, collectionPath, eventId);
12907
+ const eventDoc = await (0, import_firestore39.getDoc)(eventRef);
10468
12908
  if (!eventDoc.exists()) {
10469
12909
  throw new Error(`Blocking event with ID ${eventId} not found`);
10470
12910
  }
10471
- await (0, import_firestore31.deleteDoc)(eventRef);
12911
+ await (0, import_firestore39.deleteDoc)(eventRef);
10472
12912
  }
10473
12913
  /**
10474
12914
  * Gets a specific blocking event
@@ -10479,8 +12919,8 @@ var CalendarServiceV3 = class extends BaseService {
10479
12919
  */
10480
12920
  async getBlockingEvent(entityType, entityId, eventId) {
10481
12921
  const collectionPath = this.getEntityCalendarPath(entityType, entityId);
10482
- const eventRef = (0, import_firestore31.doc)(this.db, collectionPath, eventId);
10483
- const eventDoc = await (0, import_firestore31.getDoc)(eventRef);
12922
+ const eventRef = (0, import_firestore39.doc)(this.db, collectionPath, eventId);
12923
+ const eventDoc = await (0, import_firestore39.getDoc)(eventRef);
10484
12924
  if (!eventDoc.exists()) {
10485
12925
  return null;
10486
12926
  }
@@ -10673,7 +13113,7 @@ var ExternalCalendarService = class extends BaseService {
10673
13113
  };
10674
13114
 
10675
13115
  // src/services/clinic/practitioner-invite.service.ts
10676
- var import_firestore32 = require("firebase/firestore");
13116
+ var import_firestore40 = require("firebase/firestore");
10677
13117
  var PractitionerInviteService = class extends BaseService {
10678
13118
  constructor(db, auth, app) {
10679
13119
  super(db, auth, app);
@@ -10735,7 +13175,7 @@ var PractitionerInviteService = class extends BaseService {
10735
13175
  message: message || null,
10736
13176
  status: "pending" /* PENDING */
10737
13177
  };
10738
- const now = import_firestore32.Timestamp.now();
13178
+ const now = import_firestore40.Timestamp.now();
10739
13179
  const invite = {
10740
13180
  id: inviteId,
10741
13181
  ...inviteData,
@@ -10746,8 +13186,8 @@ var PractitionerInviteService = class extends BaseService {
10746
13186
  rejectedAt: null,
10747
13187
  cancelledAt: null
10748
13188
  };
10749
- const docRef = (0, import_firestore32.doc)(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
10750
- await (0, import_firestore32.setDoc)(docRef, invite);
13189
+ const docRef = (0, import_firestore40.doc)(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
13190
+ await (0, import_firestore40.setDoc)(docRef, invite);
10751
13191
  return invite;
10752
13192
  } catch (error) {
10753
13193
  console.error(
@@ -10766,18 +13206,18 @@ var PractitionerInviteService = class extends BaseService {
10766
13206
  async getAllInvitesDoctor(practitionerId, statusFilter) {
10767
13207
  try {
10768
13208
  const constraints = [
10769
- (0, import_firestore32.where)("practitionerId", "==", practitionerId),
10770
- (0, import_firestore32.orderBy)("createdAt", "desc")
13209
+ (0, import_firestore40.where)("practitionerId", "==", practitionerId),
13210
+ (0, import_firestore40.orderBy)("createdAt", "desc")
10771
13211
  ];
10772
13212
  if (statusFilter && statusFilter.length > 0) {
10773
- constraints.push((0, import_firestore32.where)("status", "in", statusFilter));
13213
+ constraints.push((0, import_firestore40.where)("status", "in", statusFilter));
10774
13214
  }
10775
- const q = (0, import_firestore32.query)(
10776
- (0, import_firestore32.collection)(this.db, PRACTITIONER_INVITES_COLLECTION),
13215
+ const q = (0, import_firestore40.query)(
13216
+ (0, import_firestore40.collection)(this.db, PRACTITIONER_INVITES_COLLECTION),
10777
13217
  ...constraints
10778
13218
  );
10779
- const querySnapshot = await (0, import_firestore32.getDocs)(q);
10780
- return querySnapshot.docs.map((doc26) => doc26.data());
13219
+ const querySnapshot = await (0, import_firestore40.getDocs)(q);
13220
+ return querySnapshot.docs.map((doc32) => doc32.data());
10781
13221
  } catch (error) {
10782
13222
  console.error(
10783
13223
  "[PractitionerInviteService] Error getting doctor invites:",
@@ -10795,18 +13235,18 @@ var PractitionerInviteService = class extends BaseService {
10795
13235
  async getAllInvitesClinic(clinicId, statusFilter) {
10796
13236
  try {
10797
13237
  const constraints = [
10798
- (0, import_firestore32.where)("clinicId", "==", clinicId),
10799
- (0, import_firestore32.orderBy)("createdAt", "desc")
13238
+ (0, import_firestore40.where)("clinicId", "==", clinicId),
13239
+ (0, import_firestore40.orderBy)("createdAt", "desc")
10800
13240
  ];
10801
13241
  if (statusFilter && statusFilter.length > 0) {
10802
- constraints.push((0, import_firestore32.where)("status", "in", statusFilter));
13242
+ constraints.push((0, import_firestore40.where)("status", "in", statusFilter));
10803
13243
  }
10804
- const q = (0, import_firestore32.query)(
10805
- (0, import_firestore32.collection)(this.db, PRACTITIONER_INVITES_COLLECTION),
13244
+ const q = (0, import_firestore40.query)(
13245
+ (0, import_firestore40.collection)(this.db, PRACTITIONER_INVITES_COLLECTION),
10806
13246
  ...constraints
10807
13247
  );
10808
- const querySnapshot = await (0, import_firestore32.getDocs)(q);
10809
- return querySnapshot.docs.map((doc26) => doc26.data());
13248
+ const querySnapshot = await (0, import_firestore40.getDocs)(q);
13249
+ return querySnapshot.docs.map((doc32) => doc32.data());
10810
13250
  } catch (error) {
10811
13251
  console.error(
10812
13252
  "[PractitionerInviteService] Error getting clinic invites:",
@@ -10831,11 +13271,11 @@ var PractitionerInviteService = class extends BaseService {
10831
13271
  }
10832
13272
  const updateData = {
10833
13273
  status: "accepted" /* ACCEPTED */,
10834
- acceptedAt: import_firestore32.Timestamp.now(),
10835
- updatedAt: (0, import_firestore32.serverTimestamp)()
13274
+ acceptedAt: import_firestore40.Timestamp.now(),
13275
+ updatedAt: (0, import_firestore40.serverTimestamp)()
10836
13276
  };
10837
- const docRef = (0, import_firestore32.doc)(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
10838
- await (0, import_firestore32.updateDoc)(docRef, updateData);
13277
+ const docRef = (0, import_firestore40.doc)(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
13278
+ await (0, import_firestore40.updateDoc)(docRef, updateData);
10839
13279
  return await this.getInviteById(inviteId);
10840
13280
  } catch (error) {
10841
13281
  console.error(
@@ -10863,11 +13303,11 @@ var PractitionerInviteService = class extends BaseService {
10863
13303
  const updateData = {
10864
13304
  status: "rejected" /* REJECTED */,
10865
13305
  rejectionReason: rejectionReason || null,
10866
- rejectedAt: import_firestore32.Timestamp.now(),
10867
- updatedAt: (0, import_firestore32.serverTimestamp)()
13306
+ rejectedAt: import_firestore40.Timestamp.now(),
13307
+ updatedAt: (0, import_firestore40.serverTimestamp)()
10868
13308
  };
10869
- const docRef = (0, import_firestore32.doc)(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
10870
- await (0, import_firestore32.updateDoc)(docRef, updateData);
13309
+ const docRef = (0, import_firestore40.doc)(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
13310
+ await (0, import_firestore40.updateDoc)(docRef, updateData);
10871
13311
  return await this.getInviteById(inviteId);
10872
13312
  } catch (error) {
10873
13313
  console.error(
@@ -10895,11 +13335,11 @@ var PractitionerInviteService = class extends BaseService {
10895
13335
  const updateData = {
10896
13336
  status: "cancelled" /* CANCELLED */,
10897
13337
  cancelReason: cancelReason || null,
10898
- cancelledAt: import_firestore32.Timestamp.now(),
10899
- updatedAt: (0, import_firestore32.serverTimestamp)()
13338
+ cancelledAt: import_firestore40.Timestamp.now(),
13339
+ updatedAt: (0, import_firestore40.serverTimestamp)()
10900
13340
  };
10901
- const docRef = (0, import_firestore32.doc)(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
10902
- await (0, import_firestore32.updateDoc)(docRef, updateData);
13341
+ const docRef = (0, import_firestore40.doc)(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
13342
+ await (0, import_firestore40.updateDoc)(docRef, updateData);
10903
13343
  return await this.getInviteById(inviteId);
10904
13344
  } catch (error) {
10905
13345
  console.error(
@@ -10916,8 +13356,8 @@ var PractitionerInviteService = class extends BaseService {
10916
13356
  */
10917
13357
  async getInviteById(inviteId) {
10918
13358
  try {
10919
- const docRef = (0, import_firestore32.doc)(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
10920
- const docSnap = await (0, import_firestore32.getDoc)(docRef);
13359
+ const docRef = (0, import_firestore40.doc)(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
13360
+ const docSnap = await (0, import_firestore40.getDoc)(docRef);
10921
13361
  if (docSnap.exists()) {
10922
13362
  return docSnap.data();
10923
13363
  }
@@ -10939,30 +13379,30 @@ var PractitionerInviteService = class extends BaseService {
10939
13379
  try {
10940
13380
  const constraints = [];
10941
13381
  if (filters.practitionerId) {
10942
- constraints.push((0, import_firestore32.where)("practitionerId", "==", filters.practitionerId));
13382
+ constraints.push((0, import_firestore40.where)("practitionerId", "==", filters.practitionerId));
10943
13383
  }
10944
13384
  if (filters.clinicId) {
10945
- constraints.push((0, import_firestore32.where)("clinicId", "==", filters.clinicId));
13385
+ constraints.push((0, import_firestore40.where)("clinicId", "==", filters.clinicId));
10946
13386
  }
10947
13387
  if (filters.invitedBy) {
10948
- constraints.push((0, import_firestore32.where)("invitedBy", "==", filters.invitedBy));
13388
+ constraints.push((0, import_firestore40.where)("invitedBy", "==", filters.invitedBy));
10949
13389
  }
10950
13390
  if (filters.status && filters.status.length > 0) {
10951
- constraints.push((0, import_firestore32.where)("status", "in", filters.status));
13391
+ constraints.push((0, import_firestore40.where)("status", "in", filters.status));
10952
13392
  }
10953
13393
  const orderField = filters.orderBy || "createdAt";
10954
13394
  const orderDirection = filters.orderDirection || "desc";
10955
- constraints.push((0, import_firestore32.orderBy)(orderField, orderDirection));
13395
+ constraints.push((0, import_firestore40.orderBy)(orderField, orderDirection));
10956
13396
  if (filters.limit) {
10957
- constraints.push((0, import_firestore32.limit)(filters.limit));
13397
+ constraints.push((0, import_firestore40.limit)(filters.limit));
10958
13398
  }
10959
- const q = (0, import_firestore32.query)(
10960
- (0, import_firestore32.collection)(this.db, PRACTITIONER_INVITES_COLLECTION),
13399
+ const q = (0, import_firestore40.query)(
13400
+ (0, import_firestore40.collection)(this.db, PRACTITIONER_INVITES_COLLECTION),
10961
13401
  ...constraints
10962
13402
  );
10963
- const querySnapshot = await (0, import_firestore32.getDocs)(q);
13403
+ const querySnapshot = await (0, import_firestore40.getDocs)(q);
10964
13404
  let invites = querySnapshot.docs.map(
10965
- (doc26) => doc26.data()
13405
+ (doc32) => doc32.data()
10966
13406
  );
10967
13407
  if (filters.fromDate) {
10968
13408
  invites = invites.filter(
@@ -10989,8 +13429,8 @@ var PractitionerInviteService = class extends BaseService {
10989
13429
  */
10990
13430
  async deleteInvite(inviteId) {
10991
13431
  try {
10992
- const docRef = (0, import_firestore32.doc)(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
10993
- await (0, import_firestore32.deleteDoc)(docRef);
13432
+ const docRef = (0, import_firestore40.doc)(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
13433
+ await (0, import_firestore40.deleteDoc)(docRef);
10994
13434
  } catch (error) {
10995
13435
  console.error(
10996
13436
  "[PractitionerInviteService] Error deleting invite:",
@@ -11007,8 +13447,8 @@ var PractitionerInviteService = class extends BaseService {
11007
13447
  */
11008
13448
  async getPractitionerById(practitionerId) {
11009
13449
  try {
11010
- const docRef = (0, import_firestore32.doc)(this.db, PRACTITIONERS_COLLECTION, practitionerId);
11011
- const docSnap = await (0, import_firestore32.getDoc)(docRef);
13450
+ const docRef = (0, import_firestore40.doc)(this.db, PRACTITIONERS_COLLECTION, practitionerId);
13451
+ const docSnap = await (0, import_firestore40.getDoc)(docRef);
11012
13452
  return docSnap.exists() ? docSnap.data() : null;
11013
13453
  } catch (error) {
11014
13454
  console.error(
@@ -11025,8 +13465,8 @@ var PractitionerInviteService = class extends BaseService {
11025
13465
  */
11026
13466
  async getClinicById(clinicId) {
11027
13467
  try {
11028
- const docRef = (0, import_firestore32.doc)(this.db, CLINICS_COLLECTION, clinicId);
11029
- const docSnap = await (0, import_firestore32.getDoc)(docRef);
13468
+ const docRef = (0, import_firestore40.doc)(this.db, CLINICS_COLLECTION, clinicId);
13469
+ const docSnap = await (0, import_firestore40.getDoc)(docRef);
11030
13470
  return docSnap.exists() ? docSnap.data() : null;
11031
13471
  } catch (error) {
11032
13472
  console.error("[PractitionerInviteService] Error getting clinic:", error);
@@ -11041,14 +13481,14 @@ var PractitionerInviteService = class extends BaseService {
11041
13481
  */
11042
13482
  async findExistingInvite(practitionerId, clinicId) {
11043
13483
  try {
11044
- const q = (0, import_firestore32.query)(
11045
- (0, import_firestore32.collection)(this.db, PRACTITIONER_INVITES_COLLECTION),
11046
- (0, import_firestore32.where)("practitionerId", "==", practitionerId),
11047
- (0, import_firestore32.where)("clinicId", "==", clinicId),
11048
- (0, import_firestore32.orderBy)("createdAt", "desc"),
11049
- (0, import_firestore32.limit)(1)
11050
- );
11051
- const querySnapshot = await (0, import_firestore32.getDocs)(q);
13484
+ const q = (0, import_firestore40.query)(
13485
+ (0, import_firestore40.collection)(this.db, PRACTITIONER_INVITES_COLLECTION),
13486
+ (0, import_firestore40.where)("practitionerId", "==", practitionerId),
13487
+ (0, import_firestore40.where)("clinicId", "==", clinicId),
13488
+ (0, import_firestore40.orderBy)("createdAt", "desc"),
13489
+ (0, import_firestore40.limit)(1)
13490
+ );
13491
+ const querySnapshot = await (0, import_firestore40.getDocs)(q);
11052
13492
  if (querySnapshot.empty) {
11053
13493
  return null;
11054
13494
  }
@@ -11064,11 +13504,11 @@ var PractitionerInviteService = class extends BaseService {
11064
13504
  };
11065
13505
 
11066
13506
  // src/services/documentation-templates/documentation-template.service.ts
11067
- var import_firestore33 = require("firebase/firestore");
13507
+ var import_firestore41 = require("firebase/firestore");
11068
13508
  var DocumentationTemplateService = class extends BaseService {
11069
13509
  constructor() {
11070
13510
  super(...arguments);
11071
- this.collectionRef = (0, import_firestore33.collection)(
13511
+ this.collectionRef = (0, import_firestore41.collection)(
11072
13512
  this.db,
11073
13513
  DOCUMENTATION_TEMPLATES_COLLECTION
11074
13514
  );
@@ -11102,8 +13542,8 @@ var DocumentationTemplateService = class extends BaseService {
11102
13542
  isRequired: validatedData.isRequired || false,
11103
13543
  sortingOrder: validatedData.sortingOrder || 0
11104
13544
  };
11105
- const docRef = (0, import_firestore33.doc)(this.collectionRef, templateId);
11106
- await (0, import_firestore33.setDoc)(docRef, template);
13545
+ const docRef = (0, import_firestore41.doc)(this.collectionRef, templateId);
13546
+ await (0, import_firestore41.setDoc)(docRef, template);
11107
13547
  return template;
11108
13548
  }
11109
13549
  /**
@@ -11113,8 +13553,8 @@ var DocumentationTemplateService = class extends BaseService {
11113
13553
  * @returns The template or null if not found
11114
13554
  */
11115
13555
  async getTemplateById(templateId, version) {
11116
- const docRef = (0, import_firestore33.doc)(this.collectionRef, templateId);
11117
- const docSnap = await (0, import_firestore33.getDoc)(docRef);
13556
+ const docRef = (0, import_firestore41.doc)(this.collectionRef, templateId);
13557
+ const docSnap = await (0, import_firestore41.getDoc)(docRef);
11118
13558
  if (!docSnap.exists()) {
11119
13559
  return null;
11120
13560
  }
@@ -11152,15 +13592,15 @@ var DocumentationTemplateService = class extends BaseService {
11152
13592
  if (!template) {
11153
13593
  throw new Error(`Template with ID ${templateId} not found`);
11154
13594
  }
11155
- const versionsCollectionRef = (0, import_firestore33.collection)(
13595
+ const versionsCollectionRef = (0, import_firestore41.collection)(
11156
13596
  this.db,
11157
13597
  `${DOCUMENTATION_TEMPLATES_COLLECTION}/${templateId}/versions`
11158
13598
  );
11159
- const versionDocRef = (0, import_firestore33.doc)(
13599
+ const versionDocRef = (0, import_firestore41.doc)(
11160
13600
  versionsCollectionRef,
11161
13601
  template.version.toString()
11162
13602
  );
11163
- await (0, import_firestore33.setDoc)(versionDocRef, template);
13603
+ await (0, import_firestore41.setDoc)(versionDocRef, template);
11164
13604
  let updatedElements = template.elements;
11165
13605
  if (validatedData.elements) {
11166
13606
  updatedElements = validatedData.elements.map((element) => ({
@@ -11184,9 +13624,9 @@ var DocumentationTemplateService = class extends BaseService {
11184
13624
  updatePayload.isUserForm = (_a = validatedData.isUserForm) != null ? _a : false;
11185
13625
  updatePayload.isRequired = (_b = validatedData.isRequired) != null ? _b : false;
11186
13626
  updatePayload.sortingOrder = (_c = validatedData.sortingOrder) != null ? _c : 0;
11187
- const docRef = (0, import_firestore33.doc)(this.collectionRef, templateId);
13627
+ const docRef = (0, import_firestore41.doc)(this.collectionRef, templateId);
11188
13628
  console.log("Update payload", updatePayload);
11189
- await (0, import_firestore33.updateDoc)(docRef, updatePayload);
13629
+ await (0, import_firestore41.updateDoc)(docRef, updatePayload);
11190
13630
  return { ...template, ...updatePayload };
11191
13631
  }
11192
13632
  /**
@@ -11196,11 +13636,11 @@ var DocumentationTemplateService = class extends BaseService {
11196
13636
  * @returns The template version or null if not found
11197
13637
  */
11198
13638
  async getTemplateVersion(templateId, versionNumber) {
11199
- const versionDocRef = (0, import_firestore33.doc)(
13639
+ const versionDocRef = (0, import_firestore41.doc)(
11200
13640
  this.db,
11201
13641
  `${DOCUMENTATION_TEMPLATES_COLLECTION}/${templateId}/versions/${versionNumber}`
11202
13642
  );
11203
- const versionDocSnap = await (0, import_firestore33.getDoc)(versionDocRef);
13643
+ const versionDocSnap = await (0, import_firestore41.getDoc)(versionDocRef);
11204
13644
  if (!versionDocSnap.exists()) {
11205
13645
  return null;
11206
13646
  }
@@ -11212,15 +13652,15 @@ var DocumentationTemplateService = class extends BaseService {
11212
13652
  * @returns Array of template versions
11213
13653
  */
11214
13654
  async getTemplateOldVersions(templateId) {
11215
- const versionsCollectionRef = (0, import_firestore33.collection)(
13655
+ const versionsCollectionRef = (0, import_firestore41.collection)(
11216
13656
  this.db,
11217
13657
  `${DOCUMENTATION_TEMPLATES_COLLECTION}/${templateId}/versions`
11218
13658
  );
11219
- const q = (0, import_firestore33.query)(versionsCollectionRef, (0, import_firestore33.orderBy)("version", "desc"));
11220
- const querySnapshot = await (0, import_firestore33.getDocs)(q);
13659
+ const q = (0, import_firestore41.query)(versionsCollectionRef, (0, import_firestore41.orderBy)("version", "desc"));
13660
+ const querySnapshot = await (0, import_firestore41.getDocs)(q);
11221
13661
  const versions = [];
11222
- querySnapshot.forEach((doc26) => {
11223
- versions.push(doc26.data());
13662
+ querySnapshot.forEach((doc32) => {
13663
+ versions.push(doc32.data());
11224
13664
  });
11225
13665
  return versions;
11226
13666
  }
@@ -11229,8 +13669,8 @@ var DocumentationTemplateService = class extends BaseService {
11229
13669
  * @param templateId - ID of the template to delete
11230
13670
  */
11231
13671
  async deleteTemplate(templateId) {
11232
- const docRef = (0, import_firestore33.doc)(this.collectionRef, templateId);
11233
- await (0, import_firestore33.deleteDoc)(docRef);
13672
+ const docRef = (0, import_firestore41.doc)(this.collectionRef, templateId);
13673
+ await (0, import_firestore41.deleteDoc)(docRef);
11234
13674
  }
11235
13675
  /**
11236
13676
  * Get all active templates
@@ -11239,21 +13679,21 @@ var DocumentationTemplateService = class extends BaseService {
11239
13679
  * @returns Array of templates and the last document for pagination
11240
13680
  */
11241
13681
  async getActiveTemplates(pageSize = 20, lastDoc) {
11242
- let q = (0, import_firestore33.query)(
13682
+ let q = (0, import_firestore41.query)(
11243
13683
  this.collectionRef,
11244
- (0, import_firestore33.where)("isActive", "==", true),
11245
- (0, import_firestore33.orderBy)("updatedAt", "desc"),
11246
- (0, import_firestore33.limit)(pageSize)
13684
+ (0, import_firestore41.where)("isActive", "==", true),
13685
+ (0, import_firestore41.orderBy)("updatedAt", "desc"),
13686
+ (0, import_firestore41.limit)(pageSize)
11247
13687
  );
11248
13688
  if (lastDoc) {
11249
- q = (0, import_firestore33.query)(q, (0, import_firestore33.startAfter)(lastDoc));
13689
+ q = (0, import_firestore41.query)(q, (0, import_firestore41.startAfter)(lastDoc));
11250
13690
  }
11251
- const querySnapshot = await (0, import_firestore33.getDocs)(q);
13691
+ const querySnapshot = await (0, import_firestore41.getDocs)(q);
11252
13692
  const templates = [];
11253
13693
  let lastVisible = null;
11254
- querySnapshot.forEach((doc26) => {
11255
- templates.push(doc26.data());
11256
- lastVisible = doc26;
13694
+ querySnapshot.forEach((doc32) => {
13695
+ templates.push(doc32.data());
13696
+ lastVisible = doc32;
11257
13697
  });
11258
13698
  return {
11259
13699
  templates,
@@ -11268,22 +13708,22 @@ var DocumentationTemplateService = class extends BaseService {
11268
13708
  * @returns Array of templates and the last document for pagination
11269
13709
  */
11270
13710
  async getTemplatesByTags(tags, pageSize = 20, lastDoc) {
11271
- let q = (0, import_firestore33.query)(
13711
+ let q = (0, import_firestore41.query)(
11272
13712
  this.collectionRef,
11273
- (0, import_firestore33.where)("isActive", "==", true),
11274
- (0, import_firestore33.where)("tags", "array-contains-any", tags),
11275
- (0, import_firestore33.orderBy)("updatedAt", "desc"),
11276
- (0, import_firestore33.limit)(pageSize)
13713
+ (0, import_firestore41.where)("isActive", "==", true),
13714
+ (0, import_firestore41.where)("tags", "array-contains-any", tags),
13715
+ (0, import_firestore41.orderBy)("updatedAt", "desc"),
13716
+ (0, import_firestore41.limit)(pageSize)
11277
13717
  );
11278
13718
  if (lastDoc) {
11279
- q = (0, import_firestore33.query)(q, (0, import_firestore33.startAfter)(lastDoc));
13719
+ q = (0, import_firestore41.query)(q, (0, import_firestore41.startAfter)(lastDoc));
11280
13720
  }
11281
- const querySnapshot = await (0, import_firestore33.getDocs)(q);
13721
+ const querySnapshot = await (0, import_firestore41.getDocs)(q);
11282
13722
  const templates = [];
11283
13723
  let lastVisible = null;
11284
- querySnapshot.forEach((doc26) => {
11285
- templates.push(doc26.data());
11286
- lastVisible = doc26;
13724
+ querySnapshot.forEach((doc32) => {
13725
+ templates.push(doc32.data());
13726
+ lastVisible = doc32;
11287
13727
  });
11288
13728
  return {
11289
13729
  templates,
@@ -11298,21 +13738,21 @@ var DocumentationTemplateService = class extends BaseService {
11298
13738
  * @returns Array of templates and the last document for pagination
11299
13739
  */
11300
13740
  async getTemplatesByCreator(userId, pageSize = 20, lastDoc) {
11301
- let q = (0, import_firestore33.query)(
13741
+ let q = (0, import_firestore41.query)(
11302
13742
  this.collectionRef,
11303
- (0, import_firestore33.where)("createdBy", "==", userId),
11304
- (0, import_firestore33.orderBy)("updatedAt", "desc"),
11305
- (0, import_firestore33.limit)(pageSize)
13743
+ (0, import_firestore41.where)("createdBy", "==", userId),
13744
+ (0, import_firestore41.orderBy)("updatedAt", "desc"),
13745
+ (0, import_firestore41.limit)(pageSize)
11306
13746
  );
11307
13747
  if (lastDoc) {
11308
- q = (0, import_firestore33.query)(q, (0, import_firestore33.startAfter)(lastDoc));
13748
+ q = (0, import_firestore41.query)(q, (0, import_firestore41.startAfter)(lastDoc));
11309
13749
  }
11310
- const querySnapshot = await (0, import_firestore33.getDocs)(q);
13750
+ const querySnapshot = await (0, import_firestore41.getDocs)(q);
11311
13751
  const templates = [];
11312
13752
  let lastVisible = null;
11313
- querySnapshot.forEach((doc26) => {
11314
- templates.push(doc26.data());
11315
- lastVisible = doc26;
13753
+ querySnapshot.forEach((doc32) => {
13754
+ templates.push(doc32.data());
13755
+ lastVisible = doc32;
11316
13756
  });
11317
13757
  return {
11318
13758
  templates,
@@ -11325,28 +13765,28 @@ var DocumentationTemplateService = class extends BaseService {
11325
13765
  * @returns Array of templates
11326
13766
  */
11327
13767
  async getAllTemplatesForSelection(options) {
11328
- let q = (0, import_firestore33.query)(
13768
+ let q = (0, import_firestore41.query)(
11329
13769
  this.collectionRef,
11330
- (0, import_firestore33.where)("isActive", "==", true),
11331
- (0, import_firestore33.orderBy)("updatedAt", "desc")
13770
+ (0, import_firestore41.where)("isActive", "==", true),
13771
+ (0, import_firestore41.orderBy)("updatedAt", "desc")
11332
13772
  );
11333
13773
  if ((options == null ? void 0 : options.isUserForm) !== void 0) {
11334
- q = (0, import_firestore33.query)(q, (0, import_firestore33.where)("isUserForm", "==", options.isUserForm));
13774
+ q = (0, import_firestore41.query)(q, (0, import_firestore41.where)("isUserForm", "==", options.isUserForm));
11335
13775
  }
11336
13776
  if ((options == null ? void 0 : options.isRequired) !== void 0) {
11337
- q = (0, import_firestore33.query)(q, (0, import_firestore33.where)("isRequired", "==", options.isRequired));
13777
+ q = (0, import_firestore41.query)(q, (0, import_firestore41.where)("isRequired", "==", options.isRequired));
11338
13778
  }
11339
- const querySnapshot = await (0, import_firestore33.getDocs)(q);
13779
+ const querySnapshot = await (0, import_firestore41.getDocs)(q);
11340
13780
  const templates = [];
11341
- querySnapshot.forEach((doc26) => {
11342
- templates.push(doc26.data());
13781
+ querySnapshot.forEach((doc32) => {
13782
+ templates.push(doc32.data());
11343
13783
  });
11344
13784
  return templates;
11345
13785
  }
11346
13786
  };
11347
13787
 
11348
13788
  // src/services/documentation-templates/filled-document.service.ts
11349
- var import_firestore34 = require("firebase/firestore");
13789
+ var import_firestore42 = require("firebase/firestore");
11350
13790
  var FilledDocumentService = class extends BaseService {
11351
13791
  constructor(...args) {
11352
13792
  super(...args);
@@ -11401,7 +13841,7 @@ var FilledDocumentService = class extends BaseService {
11401
13841
  values: initialValues,
11402
13842
  status: initialStatus
11403
13843
  };
11404
- const docRef = (0, import_firestore34.doc)(
13844
+ const docRef = (0, import_firestore42.doc)(
11405
13845
  this.db,
11406
13846
  APPOINTMENTS_COLLECTION,
11407
13847
  // Replaced "appointments"
@@ -11409,7 +13849,7 @@ var FilledDocumentService = class extends BaseService {
11409
13849
  formSubcollection,
11410
13850
  documentId3
11411
13851
  );
11412
- await (0, import_firestore34.setDoc)(docRef, filledDocument);
13852
+ await (0, import_firestore42.setDoc)(docRef, filledDocument);
11413
13853
  return filledDocument;
11414
13854
  }
11415
13855
  /**
@@ -11421,7 +13861,7 @@ var FilledDocumentService = class extends BaseService {
11421
13861
  */
11422
13862
  async getFilledDocumentFromAppointmentById(appointmentId, formId, isUserForm) {
11423
13863
  const formSubcollection = this.getFormSubcollectionPath(isUserForm);
11424
- const docRef = (0, import_firestore34.doc)(
13864
+ const docRef = (0, import_firestore42.doc)(
11425
13865
  this.db,
11426
13866
  APPOINTMENTS_COLLECTION,
11427
13867
  // Replaced "appointments"
@@ -11429,7 +13869,7 @@ var FilledDocumentService = class extends BaseService {
11429
13869
  formSubcollection,
11430
13870
  formId
11431
13871
  );
11432
- const docSnap = await (0, import_firestore34.getDoc)(docRef);
13872
+ const docSnap = await (0, import_firestore42.getDoc)(docRef);
11433
13873
  if (!docSnap.exists()) {
11434
13874
  return null;
11435
13875
  }
@@ -11446,7 +13886,7 @@ var FilledDocumentService = class extends BaseService {
11446
13886
  */
11447
13887
  async updateFilledDocumentInAppointment(appointmentId, formId, isUserForm, values, status) {
11448
13888
  const formSubcollection = this.getFormSubcollectionPath(isUserForm);
11449
- const docRef = (0, import_firestore34.doc)(
13889
+ const docRef = (0, import_firestore42.doc)(
11450
13890
  this.db,
11451
13891
  APPOINTMENTS_COLLECTION,
11452
13892
  // Replaced "appointments"
@@ -11478,7 +13918,7 @@ var FilledDocumentService = class extends BaseService {
11478
13918
  }
11479
13919
  if (Object.keys(updatePayload).length === 1 && "updatedAt" in updatePayload) {
11480
13920
  }
11481
- await (0, import_firestore34.updateDoc)(docRef, updatePayload);
13921
+ await (0, import_firestore42.updateDoc)(docRef, updatePayload);
11482
13922
  return { ...existingDoc, ...updatePayload };
11483
13923
  }
11484
13924
  /**
@@ -11488,20 +13928,20 @@ var FilledDocumentService = class extends BaseService {
11488
13928
  * @param lastDoc Last document from previous page for pagination.
11489
13929
  */
11490
13930
  async getFilledUserFormsForAppointment(appointmentId, pageSize = 20, lastDoc) {
11491
- const subcollectionRef = (0, import_firestore34.collection)(
13931
+ const subcollectionRef = (0, import_firestore42.collection)(
11492
13932
  this.db,
11493
13933
  APPOINTMENTS_COLLECTION,
11494
13934
  // Replaced "appointments"
11495
13935
  appointmentId,
11496
13936
  USER_FORMS_SUBCOLLECTION
11497
13937
  );
11498
- let q = (0, import_firestore34.query)(
13938
+ let q = (0, import_firestore42.query)(
11499
13939
  subcollectionRef,
11500
- (0, import_firestore34.orderBy)("updatedAt", "desc"),
11501
- (0, import_firestore34.limit)(pageSize)
13940
+ (0, import_firestore42.orderBy)("updatedAt", "desc"),
13941
+ (0, import_firestore42.limit)(pageSize)
11502
13942
  );
11503
13943
  if (lastDoc) {
11504
- q = (0, import_firestore34.query)(q, (0, import_firestore34.startAfter)(lastDoc));
13944
+ q = (0, import_firestore42.query)(q, (0, import_firestore42.startAfter)(lastDoc));
11505
13945
  }
11506
13946
  return this.executeQuery(q);
11507
13947
  }
@@ -11512,31 +13952,31 @@ var FilledDocumentService = class extends BaseService {
11512
13952
  * @param lastDoc Last document from previous page for pagination.
11513
13953
  */
11514
13954
  async getFilledDoctorFormsForAppointment(appointmentId, pageSize = 20, lastDoc) {
11515
- const subcollectionRef = (0, import_firestore34.collection)(
13955
+ const subcollectionRef = (0, import_firestore42.collection)(
11516
13956
  this.db,
11517
13957
  APPOINTMENTS_COLLECTION,
11518
13958
  // Replaced "appointments"
11519
13959
  appointmentId,
11520
13960
  DOCTOR_FORMS_SUBCOLLECTION
11521
13961
  );
11522
- let q = (0, import_firestore34.query)(
13962
+ let q = (0, import_firestore42.query)(
11523
13963
  subcollectionRef,
11524
- (0, import_firestore34.orderBy)("updatedAt", "desc"),
11525
- (0, import_firestore34.limit)(pageSize)
13964
+ (0, import_firestore42.orderBy)("updatedAt", "desc"),
13965
+ (0, import_firestore42.limit)(pageSize)
11526
13966
  );
11527
13967
  if (lastDoc) {
11528
- q = (0, import_firestore34.query)(q, (0, import_firestore34.startAfter)(lastDoc));
13968
+ q = (0, import_firestore42.query)(q, (0, import_firestore42.startAfter)(lastDoc));
11529
13969
  }
11530
13970
  return this.executeQuery(q);
11531
13971
  }
11532
13972
  // Helper to execute query and return documents + lastDoc
11533
13973
  async executeQuery(q) {
11534
- const querySnapshot = await (0, import_firestore34.getDocs)(q);
13974
+ const querySnapshot = await (0, import_firestore42.getDocs)(q);
11535
13975
  const documents = [];
11536
13976
  let lastVisible = null;
11537
- querySnapshot.forEach((doc26) => {
11538
- documents.push(doc26.data());
11539
- lastVisible = doc26;
13977
+ querySnapshot.forEach((doc32) => {
13978
+ documents.push(doc32.data());
13979
+ lastVisible = doc32;
11540
13980
  });
11541
13981
  return {
11542
13982
  documents,
@@ -11695,14 +14135,14 @@ var FilledDocumentService = class extends BaseService {
11695
14135
  };
11696
14136
 
11697
14137
  // src/services/notifications/notification.service.ts
11698
- var import_firestore35 = require("firebase/firestore");
14138
+ var import_firestore43 = require("firebase/firestore");
11699
14139
  var NotificationService = class extends BaseService {
11700
14140
  /**
11701
14141
  * Kreira novu notifikaciju
11702
14142
  */
11703
14143
  async createNotification(notification) {
11704
- const notificationsRef = (0, import_firestore35.collection)(this.db, NOTIFICATIONS_COLLECTION);
11705
- const now = import_firestore35.Timestamp.now();
14144
+ const notificationsRef = (0, import_firestore43.collection)(this.db, NOTIFICATIONS_COLLECTION);
14145
+ const now = import_firestore43.Timestamp.now();
11706
14146
  const notificationData = {
11707
14147
  ...notification,
11708
14148
  createdAt: now,
@@ -11711,7 +14151,7 @@ var NotificationService = class extends BaseService {
11711
14151
  isRead: false,
11712
14152
  userRole: notification.userRole || "patient" /* PATIENT */
11713
14153
  };
11714
- const docRef = await (0, import_firestore35.addDoc)(notificationsRef, notificationData);
14154
+ const docRef = await (0, import_firestore43.addDoc)(notificationsRef, notificationData);
11715
14155
  return {
11716
14156
  ...notificationData,
11717
14157
  id: docRef.id
@@ -11721,12 +14161,12 @@ var NotificationService = class extends BaseService {
11721
14161
  * Dohvata notifikaciju po ID-u
11722
14162
  */
11723
14163
  async getNotification(notificationId) {
11724
- const notificationRef = (0, import_firestore35.doc)(
14164
+ const notificationRef = (0, import_firestore43.doc)(
11725
14165
  this.db,
11726
14166
  NOTIFICATIONS_COLLECTION,
11727
14167
  notificationId
11728
14168
  );
11729
- const notificationDoc = await (0, import_firestore35.getDoc)(notificationRef);
14169
+ const notificationDoc = await (0, import_firestore43.getDoc)(notificationRef);
11730
14170
  if (!notificationDoc.exists()) {
11731
14171
  return null;
11732
14172
  }
@@ -11739,45 +14179,45 @@ var NotificationService = class extends BaseService {
11739
14179
  * Dohvata sve notifikacije za korisnika
11740
14180
  */
11741
14181
  async getUserNotifications(userId) {
11742
- const q = (0, import_firestore35.query)(
11743
- (0, import_firestore35.collection)(this.db, NOTIFICATIONS_COLLECTION),
11744
- (0, import_firestore35.where)("userId", "==", userId),
11745
- (0, import_firestore35.orderBy)("notificationTime", "desc")
11746
- );
11747
- const querySnapshot = await (0, import_firestore35.getDocs)(q);
11748
- return querySnapshot.docs.map((doc26) => ({
11749
- id: doc26.id,
11750
- ...doc26.data()
14182
+ const q = (0, import_firestore43.query)(
14183
+ (0, import_firestore43.collection)(this.db, NOTIFICATIONS_COLLECTION),
14184
+ (0, import_firestore43.where)("userId", "==", userId),
14185
+ (0, import_firestore43.orderBy)("notificationTime", "desc")
14186
+ );
14187
+ const querySnapshot = await (0, import_firestore43.getDocs)(q);
14188
+ return querySnapshot.docs.map((doc32) => ({
14189
+ id: doc32.id,
14190
+ ...doc32.data()
11751
14191
  }));
11752
14192
  }
11753
14193
  /**
11754
14194
  * Dohvata nepročitane notifikacije za korisnika
11755
14195
  */
11756
14196
  async getUnreadNotifications(userId) {
11757
- const q = (0, import_firestore35.query)(
11758
- (0, import_firestore35.collection)(this.db, NOTIFICATIONS_COLLECTION),
11759
- (0, import_firestore35.where)("userId", "==", userId),
11760
- (0, import_firestore35.where)("isRead", "==", false),
11761
- (0, import_firestore35.orderBy)("notificationTime", "desc")
11762
- );
11763
- const querySnapshot = await (0, import_firestore35.getDocs)(q);
11764
- return querySnapshot.docs.map((doc26) => ({
11765
- id: doc26.id,
11766
- ...doc26.data()
14197
+ const q = (0, import_firestore43.query)(
14198
+ (0, import_firestore43.collection)(this.db, NOTIFICATIONS_COLLECTION),
14199
+ (0, import_firestore43.where)("userId", "==", userId),
14200
+ (0, import_firestore43.where)("isRead", "==", false),
14201
+ (0, import_firestore43.orderBy)("notificationTime", "desc")
14202
+ );
14203
+ const querySnapshot = await (0, import_firestore43.getDocs)(q);
14204
+ return querySnapshot.docs.map((doc32) => ({
14205
+ id: doc32.id,
14206
+ ...doc32.data()
11767
14207
  }));
11768
14208
  }
11769
14209
  /**
11770
14210
  * Označava notifikaciju kao pročitanu
11771
14211
  */
11772
14212
  async markAsRead(notificationId) {
11773
- const notificationRef = (0, import_firestore35.doc)(
14213
+ const notificationRef = (0, import_firestore43.doc)(
11774
14214
  this.db,
11775
14215
  NOTIFICATIONS_COLLECTION,
11776
14216
  notificationId
11777
14217
  );
11778
- await (0, import_firestore35.updateDoc)(notificationRef, {
14218
+ await (0, import_firestore43.updateDoc)(notificationRef, {
11779
14219
  isRead: true,
11780
- updatedAt: import_firestore35.Timestamp.now()
14220
+ updatedAt: import_firestore43.Timestamp.now()
11781
14221
  });
11782
14222
  }
11783
14223
  /**
@@ -11785,16 +14225,16 @@ var NotificationService = class extends BaseService {
11785
14225
  */
11786
14226
  async markAllAsRead(userId) {
11787
14227
  const notifications = await this.getUnreadNotifications(userId);
11788
- const batch = (0, import_firestore35.writeBatch)(this.db);
14228
+ const batch = (0, import_firestore43.writeBatch)(this.db);
11789
14229
  notifications.forEach((notification) => {
11790
- const notificationRef = (0, import_firestore35.doc)(
14230
+ const notificationRef = (0, import_firestore43.doc)(
11791
14231
  this.db,
11792
14232
  NOTIFICATIONS_COLLECTION,
11793
14233
  notification.id
11794
14234
  );
11795
14235
  batch.update(notificationRef, {
11796
14236
  isRead: true,
11797
- updatedAt: import_firestore35.Timestamp.now()
14237
+ updatedAt: import_firestore43.Timestamp.now()
11798
14238
  });
11799
14239
  });
11800
14240
  await batch.commit();
@@ -11803,74 +14243,74 @@ var NotificationService = class extends BaseService {
11803
14243
  * Ažurira status notifikacije
11804
14244
  */
11805
14245
  async updateNotificationStatus(notificationId, status) {
11806
- const notificationRef = (0, import_firestore35.doc)(
14246
+ const notificationRef = (0, import_firestore43.doc)(
11807
14247
  this.db,
11808
14248
  NOTIFICATIONS_COLLECTION,
11809
14249
  notificationId
11810
14250
  );
11811
- await (0, import_firestore35.updateDoc)(notificationRef, {
14251
+ await (0, import_firestore43.updateDoc)(notificationRef, {
11812
14252
  status,
11813
- updatedAt: import_firestore35.Timestamp.now()
14253
+ updatedAt: import_firestore43.Timestamp.now()
11814
14254
  });
11815
14255
  }
11816
14256
  /**
11817
14257
  * Briše notifikaciju
11818
14258
  */
11819
14259
  async deleteNotification(notificationId) {
11820
- const notificationRef = (0, import_firestore35.doc)(
14260
+ const notificationRef = (0, import_firestore43.doc)(
11821
14261
  this.db,
11822
14262
  NOTIFICATIONS_COLLECTION,
11823
14263
  notificationId
11824
14264
  );
11825
- await (0, import_firestore35.deleteDoc)(notificationRef);
14265
+ await (0, import_firestore43.deleteDoc)(notificationRef);
11826
14266
  }
11827
14267
  /**
11828
14268
  * Dohvata notifikacije po tipu
11829
14269
  */
11830
14270
  async getNotificationsByType(userId, type) {
11831
- const q = (0, import_firestore35.query)(
11832
- (0, import_firestore35.collection)(this.db, NOTIFICATIONS_COLLECTION),
11833
- (0, import_firestore35.where)("userId", "==", userId),
11834
- (0, import_firestore35.where)("notificationType", "==", type),
11835
- (0, import_firestore35.orderBy)("notificationTime", "desc")
11836
- );
11837
- const querySnapshot = await (0, import_firestore35.getDocs)(q);
11838
- return querySnapshot.docs.map((doc26) => ({
11839
- id: doc26.id,
11840
- ...doc26.data()
14271
+ const q = (0, import_firestore43.query)(
14272
+ (0, import_firestore43.collection)(this.db, NOTIFICATIONS_COLLECTION),
14273
+ (0, import_firestore43.where)("userId", "==", userId),
14274
+ (0, import_firestore43.where)("notificationType", "==", type),
14275
+ (0, import_firestore43.orderBy)("notificationTime", "desc")
14276
+ );
14277
+ const querySnapshot = await (0, import_firestore43.getDocs)(q);
14278
+ return querySnapshot.docs.map((doc32) => ({
14279
+ id: doc32.id,
14280
+ ...doc32.data()
11841
14281
  }));
11842
14282
  }
11843
14283
  /**
11844
14284
  * Dohvata notifikacije za određeni termin
11845
14285
  */
11846
14286
  async getAppointmentNotifications(appointmentId) {
11847
- const q = (0, import_firestore35.query)(
11848
- (0, import_firestore35.collection)(this.db, NOTIFICATIONS_COLLECTION),
11849
- (0, import_firestore35.where)("appointmentId", "==", appointmentId),
11850
- (0, import_firestore35.orderBy)("notificationTime", "desc")
11851
- );
11852
- const querySnapshot = await (0, import_firestore35.getDocs)(q);
11853
- return querySnapshot.docs.map((doc26) => ({
11854
- id: doc26.id,
11855
- ...doc26.data()
14287
+ const q = (0, import_firestore43.query)(
14288
+ (0, import_firestore43.collection)(this.db, NOTIFICATIONS_COLLECTION),
14289
+ (0, import_firestore43.where)("appointmentId", "==", appointmentId),
14290
+ (0, import_firestore43.orderBy)("notificationTime", "desc")
14291
+ );
14292
+ const querySnapshot = await (0, import_firestore43.getDocs)(q);
14293
+ return querySnapshot.docs.map((doc32) => ({
14294
+ id: doc32.id,
14295
+ ...doc32.data()
11856
14296
  }));
11857
14297
  }
11858
14298
  };
11859
14299
 
11860
14300
  // src/services/patient/patientRequirements.service.ts
11861
- var import_firestore36 = require("firebase/firestore");
14301
+ var import_firestore44 = require("firebase/firestore");
11862
14302
  var PatientRequirementsService = class extends BaseService {
11863
14303
  constructor(db, auth, app) {
11864
14304
  super(db, auth, app);
11865
14305
  }
11866
14306
  getPatientRequirementsCollectionRef(patientId) {
11867
- return (0, import_firestore36.collection)(
14307
+ return (0, import_firestore44.collection)(
11868
14308
  this.db,
11869
14309
  `patients/${patientId}/${PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME}`
11870
14310
  );
11871
14311
  }
11872
14312
  getPatientRequirementDocRef(patientId, instanceId) {
11873
- return (0, import_firestore36.doc)(
14313
+ return (0, import_firestore44.doc)(
11874
14314
  this.getPatientRequirementsCollectionRef(patientId),
11875
14315
  instanceId
11876
14316
  );
@@ -11883,7 +14323,7 @@ var PatientRequirementsService = class extends BaseService {
11883
14323
  */
11884
14324
  async getPatientRequirementInstance(patientId, instanceId) {
11885
14325
  const docRef = this.getPatientRequirementDocRef(patientId, instanceId);
11886
- const docSnap = await (0, import_firestore36.getDoc)(docRef);
14326
+ const docSnap = await (0, import_firestore44.getDoc)(docRef);
11887
14327
  if (!docSnap.exists()) {
11888
14328
  return null;
11889
14329
  }
@@ -11902,22 +14342,22 @@ var PatientRequirementsService = class extends BaseService {
11902
14342
  */
11903
14343
  async getAllPatientRequirementInstances(patientId, filters, pageLimit = 20, lastVisible) {
11904
14344
  const collRef = this.getPatientRequirementsCollectionRef(patientId);
11905
- let q = (0, import_firestore36.query)(collRef, (0, import_firestore36.orderBy)("createdAt", "desc"));
14345
+ let q = (0, import_firestore44.query)(collRef, (0, import_firestore44.orderBy)("createdAt", "desc"));
11906
14346
  const queryConstraints = [];
11907
14347
  if ((filters == null ? void 0 : filters.appointmentId) && filters.appointmentId !== "all") {
11908
14348
  queryConstraints.push(
11909
- (0, import_firestore36.where)("appointmentId", "==", filters.appointmentId)
14349
+ (0, import_firestore44.where)("appointmentId", "==", filters.appointmentId)
11910
14350
  );
11911
14351
  }
11912
14352
  if ((filters == null ? void 0 : filters.statuses) && filters.statuses.length > 0) {
11913
- queryConstraints.push((0, import_firestore36.where)("overallStatus", "in", filters.statuses));
14353
+ queryConstraints.push((0, import_firestore44.where)("overallStatus", "in", filters.statuses));
11914
14354
  }
11915
14355
  if (lastVisible) {
11916
- queryConstraints.push((0, import_firestore36.startAfter)(lastVisible));
14356
+ queryConstraints.push((0, import_firestore44.startAfter)(lastVisible));
11917
14357
  }
11918
- queryConstraints.push((0, import_firestore36.limit)(pageLimit));
11919
- q = (0, import_firestore36.query)(collRef, ...queryConstraints);
11920
- const snapshot = await (0, import_firestore36.getDocs)(q);
14358
+ queryConstraints.push((0, import_firestore44.limit)(pageLimit));
14359
+ q = (0, import_firestore44.query)(collRef, ...queryConstraints);
14360
+ const snapshot = await (0, import_firestore44.getDocs)(q);
11921
14361
  let requirements = snapshot.docs.map((docSnap) => {
11922
14362
  const data = docSnap.data();
11923
14363
  return { id: docSnap.id, ...data };
@@ -11960,7 +14400,7 @@ var PatientRequirementsService = class extends BaseService {
11960
14400
  */
11961
14401
  async completeInstruction(patientId, instanceId, instructionId) {
11962
14402
  const instanceRef = this.getPatientRequirementDocRef(patientId, instanceId);
11963
- const instanceSnap = await (0, import_firestore36.getDoc)(instanceRef);
14403
+ const instanceSnap = await (0, import_firestore44.getDoc)(instanceRef);
11964
14404
  if (!instanceSnap.exists()) {
11965
14405
  throw new Error(
11966
14406
  `PatientRequirementInstance ${instanceId} not found for patient ${patientId}.`
@@ -11988,7 +14428,7 @@ var PatientRequirementsService = class extends BaseService {
11988
14428
  `Instruction ${instructionId} is in status ${instructionToUpdate.status} and cannot be marked as completed.`
11989
14429
  );
11990
14430
  }
11991
- const now = import_firestore36.Timestamp.now();
14431
+ const now = import_firestore44.Timestamp.now();
11992
14432
  const updatedInstructions = [...instance.instructions];
11993
14433
  updatedInstructions[instructionIndex] = {
11994
14434
  ...instructionToUpdate,
@@ -12015,7 +14455,7 @@ var PatientRequirementsService = class extends BaseService {
12015
14455
  if (newOverallStatus !== instance.overallStatus) {
12016
14456
  updatePayload.overallStatus = newOverallStatus;
12017
14457
  }
12018
- await (0, import_firestore36.updateDoc)(instanceRef, updatePayload);
14458
+ await (0, import_firestore44.updateDoc)(instanceRef, updatePayload);
12019
14459
  return {
12020
14460
  ...instance,
12021
14461
  instructions: updatedInstructions,
@@ -12028,7 +14468,7 @@ var PatientRequirementsService = class extends BaseService {
12028
14468
  };
12029
14469
 
12030
14470
  // src/services/procedure/procedure.service.ts
12031
- var import_firestore37 = require("firebase/firestore");
14471
+ var import_firestore45 = require("firebase/firestore");
12032
14472
 
12033
14473
  // src/validations/procedure.schema.ts
12034
14474
  var import_zod24 = require("zod");
@@ -12183,24 +14623,24 @@ var ProcedureService = class extends BaseService {
12183
14623
  if (!category || !subcategory || !technology || !product) {
12184
14624
  throw new Error("One or more required base entities not found");
12185
14625
  }
12186
- const clinicRef = (0, import_firestore37.doc)(
14626
+ const clinicRef = (0, import_firestore45.doc)(
12187
14627
  this.db,
12188
14628
  CLINICS_COLLECTION,
12189
14629
  validatedData.clinicBranchId
12190
14630
  );
12191
- const clinicSnapshot = await (0, import_firestore37.getDoc)(clinicRef);
14631
+ const clinicSnapshot = await (0, import_firestore45.getDoc)(clinicRef);
12192
14632
  if (!clinicSnapshot.exists()) {
12193
14633
  throw new Error(
12194
14634
  `Clinic with ID ${validatedData.clinicBranchId} not found`
12195
14635
  );
12196
14636
  }
12197
14637
  const clinic = clinicSnapshot.data();
12198
- const practitionerRef = (0, import_firestore37.doc)(
14638
+ const practitionerRef = (0, import_firestore45.doc)(
12199
14639
  this.db,
12200
14640
  PRACTITIONERS_COLLECTION,
12201
14641
  validatedData.practitionerId
12202
14642
  );
12203
- const practitionerSnapshot = await (0, import_firestore37.getDoc)(practitionerRef);
14643
+ const practitionerSnapshot = await (0, import_firestore45.getDoc)(practitionerRef);
12204
14644
  if (!practitionerSnapshot.exists()) {
12205
14645
  throw new Error(
12206
14646
  `Practitioner with ID ${validatedData.practitionerId} not found`
@@ -12266,13 +14706,13 @@ var ProcedureService = class extends BaseService {
12266
14706
  isActive: true
12267
14707
  // Default to active
12268
14708
  };
12269
- const procedureRef = (0, import_firestore37.doc)(this.db, PROCEDURES_COLLECTION, procedureId);
12270
- await (0, import_firestore37.setDoc)(procedureRef, {
14709
+ const procedureRef = (0, import_firestore45.doc)(this.db, PROCEDURES_COLLECTION, procedureId);
14710
+ await (0, import_firestore45.setDoc)(procedureRef, {
12271
14711
  ...newProcedure,
12272
- createdAt: (0, import_firestore37.serverTimestamp)(),
12273
- updatedAt: (0, import_firestore37.serverTimestamp)()
14712
+ createdAt: (0, import_firestore45.serverTimestamp)(),
14713
+ updatedAt: (0, import_firestore45.serverTimestamp)()
12274
14714
  });
12275
- const savedDoc = await (0, import_firestore37.getDoc)(procedureRef);
14715
+ const savedDoc = await (0, import_firestore45.getDoc)(procedureRef);
12276
14716
  return savedDoc.data();
12277
14717
  }
12278
14718
  /**
@@ -12301,7 +14741,7 @@ var ProcedureService = class extends BaseService {
12301
14741
  validatedData.technologyId,
12302
14742
  validatedData.productId
12303
14743
  ),
12304
- (0, import_firestore37.getDoc)((0, import_firestore37.doc)(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId))
14744
+ (0, import_firestore45.getDoc)((0, import_firestore45.doc)(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId))
12305
14745
  ]);
12306
14746
  if (!category || !subcategory || !technology || !product) {
12307
14747
  throw new Error("One or more required base entities not found");
@@ -12324,13 +14764,13 @@ var ProcedureService = class extends BaseService {
12324
14764
  const practitionersMap = /* @__PURE__ */ new Map();
12325
14765
  for (let i = 0; i < practitionerIds.length; i += 30) {
12326
14766
  const chunk = practitionerIds.slice(i, i + 30);
12327
- const practitionersQuery = (0, import_firestore37.query)(
12328
- (0, import_firestore37.collection)(this.db, PRACTITIONERS_COLLECTION),
12329
- (0, import_firestore37.where)((0, import_firestore37.documentId)(), "in", chunk)
14767
+ const practitionersQuery = (0, import_firestore45.query)(
14768
+ (0, import_firestore45.collection)(this.db, PRACTITIONERS_COLLECTION),
14769
+ (0, import_firestore45.where)((0, import_firestore45.documentId)(), "in", chunk)
12330
14770
  );
12331
- const practitionersSnapshot = await (0, import_firestore37.getDocs)(practitionersQuery);
12332
- practitionersSnapshot.docs.forEach((doc26) => {
12333
- practitionersMap.set(doc26.id, doc26.data());
14771
+ const practitionersSnapshot = await (0, import_firestore45.getDocs)(practitionersQuery);
14772
+ practitionersSnapshot.docs.forEach((doc32) => {
14773
+ practitionersMap.set(doc32.id, doc32.data());
12334
14774
  });
12335
14775
  }
12336
14776
  if (practitionersMap.size !== practitionerIds.length) {
@@ -12342,7 +14782,7 @@ var ProcedureService = class extends BaseService {
12342
14782
  `The following practitioners were not found: ${notFoundIds.join(", ")}`
12343
14783
  );
12344
14784
  }
12345
- const batch = (0, import_firestore37.writeBatch)(this.db);
14785
+ const batch = (0, import_firestore45.writeBatch)(this.db);
12346
14786
  const createdProcedureIds = [];
12347
14787
  const clinicInfo = {
12348
14788
  id: clinicSnapshot.id,
@@ -12364,7 +14804,7 @@ var ProcedureService = class extends BaseService {
12364
14804
  };
12365
14805
  const procedureId = this.generateId();
12366
14806
  createdProcedureIds.push(procedureId);
12367
- const procedureRef = (0, import_firestore37.doc)(this.db, PROCEDURES_COLLECTION, procedureId);
14807
+ const procedureRef = (0, import_firestore45.doc)(this.db, PROCEDURES_COLLECTION, procedureId);
12368
14808
  const newProcedure = {
12369
14809
  id: procedureId,
12370
14810
  ...validatedData,
@@ -12399,21 +14839,21 @@ var ProcedureService = class extends BaseService {
12399
14839
  };
12400
14840
  batch.set(procedureRef, {
12401
14841
  ...newProcedure,
12402
- createdAt: (0, import_firestore37.serverTimestamp)(),
12403
- updatedAt: (0, import_firestore37.serverTimestamp)()
14842
+ createdAt: (0, import_firestore45.serverTimestamp)(),
14843
+ updatedAt: (0, import_firestore45.serverTimestamp)()
12404
14844
  });
12405
14845
  }
12406
14846
  await batch.commit();
12407
14847
  const fetchedProcedures = [];
12408
14848
  for (let i = 0; i < createdProcedureIds.length; i += 30) {
12409
14849
  const chunk = createdProcedureIds.slice(i, i + 30);
12410
- const q = (0, import_firestore37.query)(
12411
- (0, import_firestore37.collection)(this.db, PROCEDURES_COLLECTION),
12412
- (0, import_firestore37.where)((0, import_firestore37.documentId)(), "in", chunk)
14850
+ const q = (0, import_firestore45.query)(
14851
+ (0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION),
14852
+ (0, import_firestore45.where)((0, import_firestore45.documentId)(), "in", chunk)
12413
14853
  );
12414
- const snapshot = await (0, import_firestore37.getDocs)(q);
12415
- snapshot.forEach((doc26) => {
12416
- fetchedProcedures.push(doc26.data());
14854
+ const snapshot = await (0, import_firestore45.getDocs)(q);
14855
+ snapshot.forEach((doc32) => {
14856
+ fetchedProcedures.push(doc32.data());
12417
14857
  });
12418
14858
  }
12419
14859
  return fetchedProcedures;
@@ -12424,8 +14864,8 @@ var ProcedureService = class extends BaseService {
12424
14864
  * @returns The procedure if found, null otherwise
12425
14865
  */
12426
14866
  async getProcedure(id) {
12427
- const docRef = (0, import_firestore37.doc)(this.db, PROCEDURES_COLLECTION, id);
12428
- const docSnap = await (0, import_firestore37.getDoc)(docRef);
14867
+ const docRef = (0, import_firestore45.doc)(this.db, PROCEDURES_COLLECTION, id);
14868
+ const docSnap = await (0, import_firestore45.getDoc)(docRef);
12429
14869
  if (!docSnap.exists()) {
12430
14870
  return null;
12431
14871
  }
@@ -12437,13 +14877,13 @@ var ProcedureService = class extends BaseService {
12437
14877
  * @returns List of procedures
12438
14878
  */
12439
14879
  async getProceduresByClinicBranch(clinicBranchId) {
12440
- const q = (0, import_firestore37.query)(
12441
- (0, import_firestore37.collection)(this.db, PROCEDURES_COLLECTION),
12442
- (0, import_firestore37.where)("clinicBranchId", "==", clinicBranchId),
12443
- (0, import_firestore37.where)("isActive", "==", true)
14880
+ const q = (0, import_firestore45.query)(
14881
+ (0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION),
14882
+ (0, import_firestore45.where)("clinicBranchId", "==", clinicBranchId),
14883
+ (0, import_firestore45.where)("isActive", "==", true)
12444
14884
  );
12445
- const snapshot = await (0, import_firestore37.getDocs)(q);
12446
- return snapshot.docs.map((doc26) => doc26.data());
14885
+ const snapshot = await (0, import_firestore45.getDocs)(q);
14886
+ return snapshot.docs.map((doc32) => doc32.data());
12447
14887
  }
12448
14888
  /**
12449
14889
  * Gets all procedures for a practitioner
@@ -12451,13 +14891,13 @@ var ProcedureService = class extends BaseService {
12451
14891
  * @returns List of procedures
12452
14892
  */
12453
14893
  async getProceduresByPractitioner(practitionerId) {
12454
- const q = (0, import_firestore37.query)(
12455
- (0, import_firestore37.collection)(this.db, PROCEDURES_COLLECTION),
12456
- (0, import_firestore37.where)("practitionerId", "==", practitionerId),
12457
- (0, import_firestore37.where)("isActive", "==", true)
14894
+ const q = (0, import_firestore45.query)(
14895
+ (0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION),
14896
+ (0, import_firestore45.where)("practitionerId", "==", practitionerId),
14897
+ (0, import_firestore45.where)("isActive", "==", true)
12458
14898
  );
12459
- const snapshot = await (0, import_firestore37.getDocs)(q);
12460
- return snapshot.docs.map((doc26) => doc26.data());
14899
+ const snapshot = await (0, import_firestore45.getDocs)(q);
14900
+ return snapshot.docs.map((doc32) => doc32.data());
12461
14901
  }
12462
14902
  /**
12463
14903
  * Gets all inactive procedures for a practitioner
@@ -12465,13 +14905,13 @@ var ProcedureService = class extends BaseService {
12465
14905
  * @returns List of inactive procedures
12466
14906
  */
12467
14907
  async getInactiveProceduresByPractitioner(practitionerId) {
12468
- const q = (0, import_firestore37.query)(
12469
- (0, import_firestore37.collection)(this.db, PROCEDURES_COLLECTION),
12470
- (0, import_firestore37.where)("practitionerId", "==", practitionerId),
12471
- (0, import_firestore37.where)("isActive", "==", false)
14908
+ const q = (0, import_firestore45.query)(
14909
+ (0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION),
14910
+ (0, import_firestore45.where)("practitionerId", "==", practitionerId),
14911
+ (0, import_firestore45.where)("isActive", "==", false)
12472
14912
  );
12473
- const snapshot = await (0, import_firestore37.getDocs)(q);
12474
- return snapshot.docs.map((doc26) => doc26.data());
14913
+ const snapshot = await (0, import_firestore45.getDocs)(q);
14914
+ return snapshot.docs.map((doc32) => doc32.data());
12475
14915
  }
12476
14916
  /**
12477
14917
  * Updates a procedure
@@ -12482,8 +14922,8 @@ var ProcedureService = class extends BaseService {
12482
14922
  async updateProcedure(id, data) {
12483
14923
  var _a;
12484
14924
  const validatedData = updateProcedureSchema.parse(data);
12485
- const procedureRef = (0, import_firestore37.doc)(this.db, PROCEDURES_COLLECTION, id);
12486
- const procedureSnapshot = await (0, import_firestore37.getDoc)(procedureRef);
14925
+ const procedureRef = (0, import_firestore45.doc)(this.db, PROCEDURES_COLLECTION, id);
14926
+ const procedureSnapshot = await (0, import_firestore45.getDoc)(procedureRef);
12487
14927
  if (!procedureSnapshot.exists()) {
12488
14928
  throw new Error(`Procedure with ID ${id} not found`);
12489
14929
  }
@@ -12504,12 +14944,12 @@ var ProcedureService = class extends BaseService {
12504
14944
  }
12505
14945
  if (validatedData.practitionerId && validatedData.practitionerId !== oldPractitionerId) {
12506
14946
  practitionerChanged = true;
12507
- const newPractitionerRef = (0, import_firestore37.doc)(
14947
+ const newPractitionerRef = (0, import_firestore45.doc)(
12508
14948
  this.db,
12509
14949
  PRACTITIONERS_COLLECTION,
12510
14950
  validatedData.practitionerId
12511
14951
  );
12512
- const newPractitionerSnap = await (0, import_firestore37.getDoc)(newPractitionerRef);
14952
+ const newPractitionerSnap = await (0, import_firestore45.getDoc)(newPractitionerRef);
12513
14953
  if (!newPractitionerSnap.exists())
12514
14954
  throw new Error(
12515
14955
  `New Practitioner ${validatedData.practitionerId} not found`
@@ -12527,12 +14967,12 @@ var ProcedureService = class extends BaseService {
12527
14967
  }
12528
14968
  if (validatedData.clinicBranchId && validatedData.clinicBranchId !== oldClinicId) {
12529
14969
  clinicChanged = true;
12530
- const newClinicRef = (0, import_firestore37.doc)(
14970
+ const newClinicRef = (0, import_firestore45.doc)(
12531
14971
  this.db,
12532
14972
  CLINICS_COLLECTION,
12533
14973
  validatedData.clinicBranchId
12534
14974
  );
12535
- const newClinicSnap = await (0, import_firestore37.getDoc)(newClinicRef);
14975
+ const newClinicSnap = await (0, import_firestore45.getDoc)(newClinicRef);
12536
14976
  if (!newClinicSnap.exists())
12537
14977
  throw new Error(`New Clinic ${validatedData.clinicBranchId} not found`);
12538
14978
  newClinic = newClinicSnap.data();
@@ -12599,11 +15039,11 @@ var ProcedureService = class extends BaseService {
12599
15039
  } else if (validatedData.productId) {
12600
15040
  console.warn("Attempted to update product without a valid technologyId");
12601
15041
  }
12602
- await (0, import_firestore37.updateDoc)(procedureRef, {
15042
+ await (0, import_firestore45.updateDoc)(procedureRef, {
12603
15043
  ...updatedProcedureData,
12604
- updatedAt: (0, import_firestore37.serverTimestamp)()
15044
+ updatedAt: (0, import_firestore45.serverTimestamp)()
12605
15045
  });
12606
- const updatedSnapshot = await (0, import_firestore37.getDoc)(procedureRef);
15046
+ const updatedSnapshot = await (0, import_firestore45.getDoc)(procedureRef);
12607
15047
  return updatedSnapshot.data();
12608
15048
  }
12609
15049
  /**
@@ -12611,15 +15051,15 @@ var ProcedureService = class extends BaseService {
12611
15051
  * @param id - The ID of the procedure to deactivate
12612
15052
  */
12613
15053
  async deactivateProcedure(id) {
12614
- const procedureRef = (0, import_firestore37.doc)(this.db, PROCEDURES_COLLECTION, id);
12615
- const procedureSnap = await (0, import_firestore37.getDoc)(procedureRef);
15054
+ const procedureRef = (0, import_firestore45.doc)(this.db, PROCEDURES_COLLECTION, id);
15055
+ const procedureSnap = await (0, import_firestore45.getDoc)(procedureRef);
12616
15056
  if (!procedureSnap.exists()) {
12617
15057
  console.warn(`Procedure ${id} not found for deactivation.`);
12618
15058
  return;
12619
15059
  }
12620
- await (0, import_firestore37.updateDoc)(procedureRef, {
15060
+ await (0, import_firestore45.updateDoc)(procedureRef, {
12621
15061
  isActive: false,
12622
- updatedAt: (0, import_firestore37.serverTimestamp)()
15062
+ updatedAt: (0, import_firestore45.serverTimestamp)()
12623
15063
  });
12624
15064
  }
12625
15065
  /**
@@ -12628,12 +15068,12 @@ var ProcedureService = class extends BaseService {
12628
15068
  * @returns A boolean indicating if the deletion was successful
12629
15069
  */
12630
15070
  async deleteProcedure(id) {
12631
- const procedureRef = (0, import_firestore37.doc)(this.db, PROCEDURES_COLLECTION, id);
12632
- const procedureSnapshot = await (0, import_firestore37.getDoc)(procedureRef);
15071
+ const procedureRef = (0, import_firestore45.doc)(this.db, PROCEDURES_COLLECTION, id);
15072
+ const procedureSnapshot = await (0, import_firestore45.getDoc)(procedureRef);
12633
15073
  if (!procedureSnapshot.exists()) {
12634
15074
  return false;
12635
15075
  }
12636
- await (0, import_firestore37.deleteDoc)(procedureRef);
15076
+ await (0, import_firestore45.deleteDoc)(procedureRef);
12637
15077
  return true;
12638
15078
  }
12639
15079
  /**
@@ -12659,35 +15099,35 @@ var ProcedureService = class extends BaseService {
12659
15099
  */
12660
15100
  async getAllProcedures(pagination, lastDoc) {
12661
15101
  try {
12662
- const proceduresCollection = (0, import_firestore37.collection)(this.db, PROCEDURES_COLLECTION);
12663
- let proceduresQuery = (0, import_firestore37.query)(proceduresCollection);
15102
+ const proceduresCollection = (0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION);
15103
+ let proceduresQuery = (0, import_firestore45.query)(proceduresCollection);
12664
15104
  if (pagination && pagination > 0) {
12665
15105
  const { limit: limit16, startAfter: startAfter14 } = await import("firebase/firestore");
12666
15106
  if (lastDoc) {
12667
- proceduresQuery = (0, import_firestore37.query)(
15107
+ proceduresQuery = (0, import_firestore45.query)(
12668
15108
  proceduresCollection,
12669
- (0, import_firestore37.orderBy)("name"),
15109
+ (0, import_firestore45.orderBy)("name"),
12670
15110
  // Use imported orderBy
12671
15111
  startAfter14(lastDoc),
12672
15112
  limit16(pagination)
12673
15113
  );
12674
15114
  } else {
12675
- proceduresQuery = (0, import_firestore37.query)(
15115
+ proceduresQuery = (0, import_firestore45.query)(
12676
15116
  proceduresCollection,
12677
- (0, import_firestore37.orderBy)("name"),
15117
+ (0, import_firestore45.orderBy)("name"),
12678
15118
  limit16(pagination)
12679
15119
  );
12680
15120
  }
12681
15121
  } else {
12682
- proceduresQuery = (0, import_firestore37.query)(proceduresCollection, (0, import_firestore37.orderBy)("name"));
15122
+ proceduresQuery = (0, import_firestore45.query)(proceduresCollection, (0, import_firestore45.orderBy)("name"));
12683
15123
  }
12684
- const proceduresSnapshot = await (0, import_firestore37.getDocs)(proceduresQuery);
15124
+ const proceduresSnapshot = await (0, import_firestore45.getDocs)(proceduresQuery);
12685
15125
  const lastVisible = proceduresSnapshot.docs[proceduresSnapshot.docs.length - 1];
12686
- const procedures = proceduresSnapshot.docs.map((doc26) => {
12687
- const data = doc26.data();
15126
+ const procedures = proceduresSnapshot.docs.map((doc32) => {
15127
+ const data = doc32.data();
12688
15128
  return {
12689
15129
  ...data,
12690
- id: doc26.id
15130
+ id: doc32.id
12691
15131
  // Ensure ID is present
12692
15132
  };
12693
15133
  });
@@ -12730,19 +15170,19 @@ var ProcedureService = class extends BaseService {
12730
15170
  const isGeoQuery = filters.location && filters.radiusInKm && filters.radiusInKm > 0;
12731
15171
  const constraints = [];
12732
15172
  if (filters.isActive !== void 0) {
12733
- constraints.push((0, import_firestore37.where)("isActive", "==", filters.isActive));
15173
+ constraints.push((0, import_firestore45.where)("isActive", "==", filters.isActive));
12734
15174
  } else {
12735
- constraints.push((0, import_firestore37.where)("isActive", "==", true));
15175
+ constraints.push((0, import_firestore45.where)("isActive", "==", true));
12736
15176
  }
12737
15177
  if (filters.procedureFamily) {
12738
- constraints.push((0, import_firestore37.where)("family", "==", filters.procedureFamily));
15178
+ constraints.push((0, import_firestore45.where)("family", "==", filters.procedureFamily));
12739
15179
  }
12740
- constraints.push((0, import_firestore37.orderBy)("clinicInfo.location.geohash"));
15180
+ constraints.push((0, import_firestore45.orderBy)("clinicInfo.location.geohash"));
12741
15181
  if (filters.pagination && filters.pagination > 0 && filters.lastDoc) {
12742
- constraints.push((0, import_firestore37.startAfter)(filters.lastDoc));
12743
- constraints.push((0, import_firestore37.limit)(filters.pagination));
15182
+ constraints.push((0, import_firestore45.startAfter)(filters.lastDoc));
15183
+ constraints.push((0, import_firestore45.limit)(filters.pagination));
12744
15184
  } else if (filters.pagination && filters.pagination > 0) {
12745
- constraints.push((0, import_firestore37.limit)(filters.pagination));
15185
+ constraints.push((0, import_firestore45.limit)(filters.pagination));
12746
15186
  }
12747
15187
  let proceduresResult = [];
12748
15188
  let lastVisibleDoc = null;
@@ -12758,19 +15198,19 @@ var ProcedureService = class extends BaseService {
12758
15198
  for (const bound of bounds) {
12759
15199
  const geoConstraints = [
12760
15200
  ...constraints,
12761
- (0, import_firestore37.where)("clinicInfo.location.geohash", ">=", bound[0]),
12762
- (0, import_firestore37.where)("clinicInfo.location.geohash", "<=", bound[1])
15201
+ (0, import_firestore45.where)("clinicInfo.location.geohash", ">=", bound[0]),
15202
+ (0, import_firestore45.where)("clinicInfo.location.geohash", "<=", bound[1])
12763
15203
  ];
12764
- const q = (0, import_firestore37.query)(
12765
- (0, import_firestore37.collection)(this.db, PROCEDURES_COLLECTION),
15204
+ const q = (0, import_firestore45.query)(
15205
+ (0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION),
12766
15206
  ...geoConstraints
12767
15207
  );
12768
- const querySnapshot = await (0, import_firestore37.getDocs)(q);
15208
+ const querySnapshot = await (0, import_firestore45.getDocs)(q);
12769
15209
  console.log(
12770
15210
  `[PROCEDURE_SERVICE] Found ${querySnapshot.docs.length} procedures in geo bound`
12771
15211
  );
12772
- for (const doc26 of querySnapshot.docs) {
12773
- const procedure = { ...doc26.data(), id: doc26.id };
15212
+ for (const doc32 of querySnapshot.docs) {
15213
+ const procedure = { ...doc32.data(), id: doc32.id };
12774
15214
  const distance = (0, import_geofire_common8.distanceBetween)(
12775
15215
  [center.latitude, center.longitude],
12776
15216
  [
@@ -12813,16 +15253,16 @@ var ProcedureService = class extends BaseService {
12813
15253
  proceduresResult = filteredProcedures;
12814
15254
  }
12815
15255
  } else {
12816
- const q = (0, import_firestore37.query)(
12817
- (0, import_firestore37.collection)(this.db, PROCEDURES_COLLECTION),
15256
+ const q = (0, import_firestore45.query)(
15257
+ (0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION),
12818
15258
  ...constraints
12819
15259
  );
12820
- const querySnapshot = await (0, import_firestore37.getDocs)(q);
15260
+ const querySnapshot = await (0, import_firestore45.getDocs)(q);
12821
15261
  console.log(
12822
15262
  `[PROCEDURE_SERVICE] Found ${querySnapshot.docs.length} procedures with regular query`
12823
15263
  );
12824
- const procedures = querySnapshot.docs.map((doc26) => {
12825
- return { ...doc26.data(), id: doc26.id };
15264
+ const procedures = querySnapshot.docs.map((doc32) => {
15265
+ return { ...doc32.data(), id: doc32.id };
12826
15266
  });
12827
15267
  if (filters.location) {
12828
15268
  const center = filters.location;
@@ -12943,18 +15383,18 @@ var ProcedureService = class extends BaseService {
12943
15383
  if (!category || !subcategory || !technology) {
12944
15384
  throw new Error("One or more required base entities not found");
12945
15385
  }
12946
- const clinicRef = (0, import_firestore37.doc)(this.db, CLINICS_COLLECTION, data.clinicBranchId);
12947
- const clinicSnapshot = await (0, import_firestore37.getDoc)(clinicRef);
15386
+ const clinicRef = (0, import_firestore45.doc)(this.db, CLINICS_COLLECTION, data.clinicBranchId);
15387
+ const clinicSnapshot = await (0, import_firestore45.getDoc)(clinicRef);
12948
15388
  if (!clinicSnapshot.exists()) {
12949
15389
  throw new Error(`Clinic with ID ${data.clinicBranchId} not found`);
12950
15390
  }
12951
15391
  const clinic = clinicSnapshot.data();
12952
- const practitionerRef = (0, import_firestore37.doc)(
15392
+ const practitionerRef = (0, import_firestore45.doc)(
12953
15393
  this.db,
12954
15394
  PRACTITIONERS_COLLECTION,
12955
15395
  data.practitionerId
12956
15396
  );
12957
- const practitionerSnapshot = await (0, import_firestore37.getDoc)(practitionerRef);
15397
+ const practitionerSnapshot = await (0, import_firestore45.getDoc)(practitionerRef);
12958
15398
  if (!practitionerSnapshot.exists()) {
12959
15399
  throw new Error(`Practitioner with ID ${data.practitionerId} not found`);
12960
15400
  }
@@ -13025,19 +15465,19 @@ var ProcedureService = class extends BaseService {
13025
15465
  },
13026
15466
  isActive: true
13027
15467
  };
13028
- const procedureRef = (0, import_firestore37.doc)(this.db, PROCEDURES_COLLECTION, procedureId);
13029
- await (0, import_firestore37.setDoc)(procedureRef, {
15468
+ const procedureRef = (0, import_firestore45.doc)(this.db, PROCEDURES_COLLECTION, procedureId);
15469
+ await (0, import_firestore45.setDoc)(procedureRef, {
13030
15470
  ...newProcedure,
13031
- createdAt: (0, import_firestore37.serverTimestamp)(),
13032
- updatedAt: (0, import_firestore37.serverTimestamp)()
15471
+ createdAt: (0, import_firestore45.serverTimestamp)(),
15472
+ updatedAt: (0, import_firestore45.serverTimestamp)()
13033
15473
  });
13034
- const savedDoc = await (0, import_firestore37.getDoc)(procedureRef);
15474
+ const savedDoc = await (0, import_firestore45.getDoc)(procedureRef);
13035
15475
  return savedDoc.data();
13036
15476
  }
13037
15477
  };
13038
15478
 
13039
15479
  // src/services/reviews/reviews.service.ts
13040
- var import_firestore38 = require("firebase/firestore");
15480
+ var import_firestore46 = require("firebase/firestore");
13041
15481
  var import_zod25 = require("zod");
13042
15482
  var ReviewService = class extends BaseService {
13043
15483
  constructor(db, auth, app) {
@@ -13117,11 +15557,11 @@ var ReviewService = class extends BaseService {
13117
15557
  updatedAt: now
13118
15558
  };
13119
15559
  reviewSchema.parse(review);
13120
- const docRef = (0, import_firestore38.doc)(this.db, REVIEWS_COLLECTION, reviewId);
13121
- await (0, import_firestore38.setDoc)(docRef, {
15560
+ const docRef = (0, import_firestore46.doc)(this.db, REVIEWS_COLLECTION, reviewId);
15561
+ await (0, import_firestore46.setDoc)(docRef, {
13122
15562
  ...review,
13123
- createdAt: (0, import_firestore38.serverTimestamp)(),
13124
- updatedAt: (0, import_firestore38.serverTimestamp)()
15563
+ createdAt: (0, import_firestore46.serverTimestamp)(),
15564
+ updatedAt: (0, import_firestore46.serverTimestamp)()
13125
15565
  });
13126
15566
  return review;
13127
15567
  } catch (error) {
@@ -13137,8 +15577,8 @@ var ReviewService = class extends BaseService {
13137
15577
  * @returns The review if found, null otherwise
13138
15578
  */
13139
15579
  async getReview(reviewId) {
13140
- const docRef = (0, import_firestore38.doc)(this.db, REVIEWS_COLLECTION, reviewId);
13141
- const docSnap = await (0, import_firestore38.getDoc)(docRef);
15580
+ const docRef = (0, import_firestore46.doc)(this.db, REVIEWS_COLLECTION, reviewId);
15581
+ const docSnap = await (0, import_firestore46.getDoc)(docRef);
13142
15582
  if (!docSnap.exists()) {
13143
15583
  return null;
13144
15584
  }
@@ -13150,12 +15590,12 @@ var ReviewService = class extends BaseService {
13150
15590
  * @returns Array of reviews for the patient
13151
15591
  */
13152
15592
  async getReviewsByPatient(patientId) {
13153
- const q = (0, import_firestore38.query)(
13154
- (0, import_firestore38.collection)(this.db, REVIEWS_COLLECTION),
13155
- (0, import_firestore38.where)("patientId", "==", patientId)
15593
+ const q = (0, import_firestore46.query)(
15594
+ (0, import_firestore46.collection)(this.db, REVIEWS_COLLECTION),
15595
+ (0, import_firestore46.where)("patientId", "==", patientId)
13156
15596
  );
13157
- const snapshot = await (0, import_firestore38.getDocs)(q);
13158
- return snapshot.docs.map((doc26) => doc26.data());
15597
+ const snapshot = await (0, import_firestore46.getDocs)(q);
15598
+ return snapshot.docs.map((doc32) => doc32.data());
13159
15599
  }
13160
15600
  /**
13161
15601
  * Gets all reviews for a specific clinic
@@ -13163,12 +15603,12 @@ var ReviewService = class extends BaseService {
13163
15603
  * @returns Array of reviews containing clinic reviews
13164
15604
  */
13165
15605
  async getReviewsByClinic(clinicId) {
13166
- const q = (0, import_firestore38.query)(
13167
- (0, import_firestore38.collection)(this.db, REVIEWS_COLLECTION),
13168
- (0, import_firestore38.where)("clinicReview.clinicId", "==", clinicId)
15606
+ const q = (0, import_firestore46.query)(
15607
+ (0, import_firestore46.collection)(this.db, REVIEWS_COLLECTION),
15608
+ (0, import_firestore46.where)("clinicReview.clinicId", "==", clinicId)
13169
15609
  );
13170
- const snapshot = await (0, import_firestore38.getDocs)(q);
13171
- return snapshot.docs.map((doc26) => doc26.data());
15610
+ const snapshot = await (0, import_firestore46.getDocs)(q);
15611
+ return snapshot.docs.map((doc32) => doc32.data());
13172
15612
  }
13173
15613
  /**
13174
15614
  * Gets all reviews for a specific practitioner
@@ -13176,12 +15616,12 @@ var ReviewService = class extends BaseService {
13176
15616
  * @returns Array of reviews containing practitioner reviews
13177
15617
  */
13178
15618
  async getReviewsByPractitioner(practitionerId) {
13179
- const q = (0, import_firestore38.query)(
13180
- (0, import_firestore38.collection)(this.db, REVIEWS_COLLECTION),
13181
- (0, import_firestore38.where)("practitionerReview.practitionerId", "==", practitionerId)
15619
+ const q = (0, import_firestore46.query)(
15620
+ (0, import_firestore46.collection)(this.db, REVIEWS_COLLECTION),
15621
+ (0, import_firestore46.where)("practitionerReview.practitionerId", "==", practitionerId)
13182
15622
  );
13183
- const snapshot = await (0, import_firestore38.getDocs)(q);
13184
- return snapshot.docs.map((doc26) => doc26.data());
15623
+ const snapshot = await (0, import_firestore46.getDocs)(q);
15624
+ return snapshot.docs.map((doc32) => doc32.data());
13185
15625
  }
13186
15626
  /**
13187
15627
  * Gets all reviews for a specific procedure
@@ -13189,12 +15629,12 @@ var ReviewService = class extends BaseService {
13189
15629
  * @returns Array of reviews containing procedure reviews
13190
15630
  */
13191
15631
  async getReviewsByProcedure(procedureId) {
13192
- const q = (0, import_firestore38.query)(
13193
- (0, import_firestore38.collection)(this.db, REVIEWS_COLLECTION),
13194
- (0, import_firestore38.where)("procedureReview.procedureId", "==", procedureId)
15632
+ const q = (0, import_firestore46.query)(
15633
+ (0, import_firestore46.collection)(this.db, REVIEWS_COLLECTION),
15634
+ (0, import_firestore46.where)("procedureReview.procedureId", "==", procedureId)
13195
15635
  );
13196
- const snapshot = await (0, import_firestore38.getDocs)(q);
13197
- return snapshot.docs.map((doc26) => doc26.data());
15636
+ const snapshot = await (0, import_firestore46.getDocs)(q);
15637
+ return snapshot.docs.map((doc32) => doc32.data());
13198
15638
  }
13199
15639
  /**
13200
15640
  * Gets all reviews for a specific appointment
@@ -13202,11 +15642,11 @@ var ReviewService = class extends BaseService {
13202
15642
  * @returns The review for the appointment if found, null otherwise
13203
15643
  */
13204
15644
  async getReviewByAppointment(appointmentId) {
13205
- const q = (0, import_firestore38.query)(
13206
- (0, import_firestore38.collection)(this.db, REVIEWS_COLLECTION),
13207
- (0, import_firestore38.where)("appointmentId", "==", appointmentId)
15645
+ const q = (0, import_firestore46.query)(
15646
+ (0, import_firestore46.collection)(this.db, REVIEWS_COLLECTION),
15647
+ (0, import_firestore46.where)("appointmentId", "==", appointmentId)
13208
15648
  );
13209
- const snapshot = await (0, import_firestore38.getDocs)(q);
15649
+ const snapshot = await (0, import_firestore46.getDocs)(q);
13210
15650
  if (snapshot.empty) {
13211
15651
  return null;
13212
15652
  }
@@ -13221,7 +15661,7 @@ var ReviewService = class extends BaseService {
13221
15661
  if (!review) {
13222
15662
  throw new Error(`Review with ID ${reviewId} not found`);
13223
15663
  }
13224
- await (0, import_firestore38.deleteDoc)((0, import_firestore38.doc)(this.db, REVIEWS_COLLECTION, reviewId));
15664
+ await (0, import_firestore46.deleteDoc)((0, import_firestore46.doc)(this.db, REVIEWS_COLLECTION, reviewId));
13225
15665
  }
13226
15666
  /**
13227
15667
  * Calculates the average of an array of numbers
@@ -13240,11 +15680,11 @@ var ReviewService = class extends BaseService {
13240
15680
 
13241
15681
  // src/validations/calendar.schema.ts
13242
15682
  var import_zod27 = require("zod");
13243
- var import_firestore40 = require("firebase/firestore");
15683
+ var import_firestore48 = require("firebase/firestore");
13244
15684
 
13245
15685
  // src/validations/profile-info.schema.ts
13246
15686
  var import_zod26 = require("zod");
13247
- var import_firestore39 = require("firebase/firestore");
15687
+ var import_firestore47 = require("firebase/firestore");
13248
15688
  var clinicBranchInfoSchema = import_zod26.z.object({
13249
15689
  id: import_zod26.z.string(),
13250
15690
  featuredPhoto: import_zod26.z.string(),
@@ -13266,19 +15706,19 @@ var patientProfileInfoSchema = import_zod26.z.object({
13266
15706
  fullName: import_zod26.z.string(),
13267
15707
  email: import_zod26.z.string().email(),
13268
15708
  phone: import_zod26.z.string().nullable(),
13269
- dateOfBirth: import_zod26.z.instanceof(import_firestore39.Timestamp),
15709
+ dateOfBirth: import_zod26.z.instanceof(import_firestore47.Timestamp),
13270
15710
  gender: import_zod26.z.nativeEnum(Gender)
13271
15711
  });
13272
15712
 
13273
15713
  // src/validations/calendar.schema.ts
13274
- var MIN_APPOINTMENT_DURATION = 15;
15714
+ var MIN_APPOINTMENT_DURATION2 = 15;
13275
15715
  var calendarEventTimeSchema = import_zod27.z.object({
13276
- start: import_zod27.z.instanceof(Date).or(import_zod27.z.instanceof(import_firestore40.Timestamp)),
13277
- end: import_zod27.z.instanceof(Date).or(import_zod27.z.instanceof(import_firestore40.Timestamp))
15716
+ start: import_zod27.z.instanceof(Date).or(import_zod27.z.instanceof(import_firestore48.Timestamp)),
15717
+ end: import_zod27.z.instanceof(Date).or(import_zod27.z.instanceof(import_firestore48.Timestamp))
13278
15718
  }).refine(
13279
15719
  (data) => {
13280
- const startDate = data.start instanceof import_firestore40.Timestamp ? data.start.toDate() : data.start;
13281
- const endDate = data.end instanceof import_firestore40.Timestamp ? data.end.toDate() : data.end;
15720
+ const startDate = data.start instanceof import_firestore48.Timestamp ? data.start.toDate() : data.start;
15721
+ const endDate = data.end instanceof import_firestore48.Timestamp ? data.end.toDate() : data.end;
13282
15722
  return startDate < endDate;
13283
15723
  },
13284
15724
  {
@@ -13287,7 +15727,7 @@ var calendarEventTimeSchema = import_zod27.z.object({
13287
15727
  }
13288
15728
  ).refine(
13289
15729
  (data) => {
13290
- const startDate = data.start instanceof import_firestore40.Timestamp ? data.start.toDate() : data.start;
15730
+ const startDate = data.start instanceof import_firestore48.Timestamp ? data.start.toDate() : data.start;
13291
15731
  return startDate > /* @__PURE__ */ new Date();
13292
15732
  },
13293
15733
  {
@@ -13306,12 +15746,12 @@ var timeSlotSchema2 = import_zod27.z.object({
13306
15746
  var syncedCalendarEventSchema = import_zod27.z.object({
13307
15747
  eventId: import_zod27.z.string(),
13308
15748
  syncedCalendarProvider: import_zod27.z.nativeEnum(SyncedCalendarProvider),
13309
- syncedAt: import_zod27.z.instanceof(Date).or(import_zod27.z.instanceof(import_firestore40.Timestamp))
15749
+ syncedAt: import_zod27.z.instanceof(Date).or(import_zod27.z.instanceof(import_firestore48.Timestamp))
13310
15750
  });
13311
15751
  var procedureInfoSchema = import_zod27.z.object({
13312
15752
  name: import_zod27.z.string(),
13313
15753
  description: import_zod27.z.string(),
13314
- duration: import_zod27.z.number().min(MIN_APPOINTMENT_DURATION),
15754
+ duration: import_zod27.z.number().min(MIN_APPOINTMENT_DURATION2),
13315
15755
  price: import_zod27.z.number().min(0),
13316
15756
  currency: import_zod27.z.nativeEnum(Currency)
13317
15757
  });
@@ -13385,8 +15825,8 @@ var calendarEventSchema = import_zod27.z.object({
13385
15825
  status: import_zod27.z.nativeEnum(CalendarEventStatus),
13386
15826
  syncStatus: import_zod27.z.nativeEnum(CalendarSyncStatus),
13387
15827
  eventType: import_zod27.z.nativeEnum(CalendarEventType),
13388
- createdAt: import_zod27.z.instanceof(Date).or(import_zod27.z.instanceof(import_firestore40.Timestamp)),
13389
- updatedAt: import_zod27.z.instanceof(Date).or(import_zod27.z.instanceof(import_firestore40.Timestamp))
15828
+ createdAt: import_zod27.z.instanceof(Date).or(import_zod27.z.instanceof(import_firestore48.Timestamp)),
15829
+ updatedAt: import_zod27.z.instanceof(Date).or(import_zod27.z.instanceof(import_firestore48.Timestamp))
13390
15830
  });
13391
15831
  var createBlockingEventSchema = import_zod27.z.object({
13392
15832
  entityType: import_zod27.z.enum(["practitioner", "clinic"]),
@@ -13514,11 +15954,11 @@ var RequirementType = /* @__PURE__ */ ((RequirementType2) => {
13514
15954
  })(RequirementType || {});
13515
15955
 
13516
15956
  // src/backoffice/validations/schemas.ts
13517
- var blockingConditionSchema2 = import_zod29.z.nativeEnum(BlockingCondition);
13518
- var contraindicationSchema2 = import_zod29.z.nativeEnum(Contraindication);
13519
- var treatmentBenefitSchema = import_zod29.z.nativeEnum(TreatmentBenefit);
13520
- var procedureFamilySchema = import_zod29.z.nativeEnum(ProcedureFamily);
13521
- var timeUnitSchema = import_zod29.z.nativeEnum(TimeUnit);
15957
+ var blockingConditionSchemaBackoffice = import_zod29.z.nativeEnum(BlockingCondition);
15958
+ var contraindicationSchemaBackoffice = import_zod29.z.nativeEnum(Contraindication);
15959
+ var treatmentBenefitSchemaBackoffice = import_zod29.z.nativeEnum(TreatmentBenefit);
15960
+ var procedureFamilySchemaBackoffice = import_zod29.z.nativeEnum(ProcedureFamily);
15961
+ var timeUnitSchemaBackoffice = import_zod29.z.nativeEnum(TimeUnit);
13522
15962
  var requirementTypeSchema = import_zod29.z.nativeEnum(RequirementType);
13523
15963
  var certificationLevelSchema = import_zod29.z.nativeEnum(CertificationLevel);
13524
15964
  var certificationSpecialtySchema = import_zod29.z.nativeEnum(
@@ -13530,7 +15970,7 @@ var certificationRequirementSchema = import_zod29.z.object({
13530
15970
  });
13531
15971
  var timeframeSchema = import_zod29.z.object({
13532
15972
  duration: import_zod29.z.number().min(1, "Duration must be positive"),
13533
- unit: timeUnitSchema,
15973
+ unit: timeUnitSchemaBackoffice,
13534
15974
  notifyAt: import_zod29.z.array(import_zod29.z.number()).min(1, "At least one notification point is required")
13535
15975
  });
13536
15976
  var requirementSchema = import_zod29.z.object({
@@ -13549,24 +15989,24 @@ var technologySchema = import_zod29.z.object({
13549
15989
  name: import_zod29.z.string().min(1, "Name is required").max(100, "Name is too long"),
13550
15990
  description: import_zod29.z.string().max(1e3, "Description is too long").optional(),
13551
15991
  technicalDetails: import_zod29.z.string().max(2e3, "Technical details are too long").optional(),
13552
- family: procedureFamilySchema,
15992
+ family: procedureFamilySchemaBackoffice,
13553
15993
  categoryId: import_zod29.z.string().min(1, "Category ID is required"),
13554
15994
  subcategoryId: import_zod29.z.string().min(1, "Subcategory ID is required"),
13555
15995
  requirements: technologyRequirementsSchema.default({
13556
15996
  pre: [],
13557
15997
  post: []
13558
15998
  }),
13559
- blockingConditions: import_zod29.z.array(blockingConditionSchema2),
13560
- contraindications: import_zod29.z.array(contraindicationSchema2),
15999
+ blockingConditions: import_zod29.z.array(blockingConditionSchemaBackoffice),
16000
+ contraindications: import_zod29.z.array(contraindicationSchemaBackoffice),
13561
16001
  documentationTemplates: import_zod29.z.array(documentTemplateSchema),
13562
- benefits: import_zod29.z.array(treatmentBenefitSchema),
16002
+ benefits: import_zod29.z.array(treatmentBenefitSchemaBackoffice),
13563
16003
  certificationRequirement: certificationRequirementSchema,
13564
16004
  isActive: import_zod29.z.boolean().default(true)
13565
16005
  });
13566
16006
  var categorySchema = import_zod29.z.object({
13567
16007
  name: import_zod29.z.string().min(1, "Name is required").max(100, "Name is too long"),
13568
16008
  description: import_zod29.z.string().optional(),
13569
- family: procedureFamilySchema,
16009
+ family: procedureFamilySchemaBackoffice,
13570
16010
  isActive: import_zod29.z.boolean().default(true)
13571
16011
  });
13572
16012
  var subcategorySchema = import_zod29.z.object({
@@ -13592,7 +16032,7 @@ var patientRequirementInstructionSchema = import_zod30.z.object({
13592
16032
  actionableWindow: import_zod30.z.number().default(1),
13593
16033
  status: patientInstructionStatusSchema,
13594
16034
  originalNotifyAtValue: import_zod30.z.number(),
13595
- originalTimeframeUnit: timeUnitSchema,
16035
+ originalTimeframeUnit: timeUnitSchemaBackoffice,
13596
16036
  // Use the correctly imported timeUnitSchema
13597
16037
  notificationId: import_zod30.z.string().optional(),
13598
16038
  actionTakenAt: import_zod30.z.any().optional().nullable(),
@@ -13629,7 +16069,7 @@ var updatePatientInstructionStatusSchema = import_zod30.z.object({
13629
16069
 
13630
16070
  // src/utils/TimestampUtils.ts
13631
16071
  var admin = __toESM(require("firebase-admin"));
13632
- var import_firestore41 = require("firebase/firestore");
16072
+ var import_firestore49 = require("firebase/firestore");
13633
16073
  var IS_SERVER_ENV = process.env.NODE_ENV === "production" || process.env.FUNCTIONS_EMULATOR === "true" || process.env.FIREBASE_CONFIG !== void 0;
13634
16074
  var TimestampUtils = class {
13635
16075
  /**
@@ -13659,7 +16099,7 @@ var TimestampUtils = class {
13659
16099
  if (this.serverMode) {
13660
16100
  return adminTimestamp;
13661
16101
  }
13662
- return new import_firestore41.Timestamp(
16102
+ return new import_firestore49.Timestamp(
13663
16103
  adminTimestamp.seconds,
13664
16104
  adminTimestamp.nanoseconds
13665
16105
  );
@@ -13704,14 +16144,14 @@ var TimestampUtils = class {
13704
16144
  if (this.serverMode) {
13705
16145
  return admin.firestore.Timestamp.fromDate(date);
13706
16146
  }
13707
- return import_firestore41.Timestamp.fromDate(date);
16147
+ return import_firestore49.Timestamp.fromDate(date);
13708
16148
  }
13709
16149
  /**
13710
16150
  * @deprecated Use dateToTimestamp() instead for better cross-environment compatibility
13711
16151
  */
13712
16152
  static dateToClientTimestamp(date) {
13713
16153
  if (!date) return null;
13714
- return import_firestore41.Timestamp.fromDate(date);
16154
+ return import_firestore49.Timestamp.fromDate(date);
13715
16155
  }
13716
16156
  /**
13717
16157
  * @deprecated Use dateToTimestamp() instead for better cross-environment compatibility
@@ -13741,7 +16181,7 @@ var TimestampUtils = class {
13741
16181
  if (obj instanceof admin.firestore.Timestamp) {
13742
16182
  return this.serverMode ? obj : this.adminToClient(obj);
13743
16183
  }
13744
- if (obj instanceof import_firestore41.Timestamp && this.serverMode) {
16184
+ if (obj instanceof import_firestore49.Timestamp && this.serverMode) {
13745
16185
  return this.clientToAdmin(obj);
13746
16186
  }
13747
16187
  if (Array.isArray(obj)) {
@@ -13785,7 +16225,7 @@ var TimestampUtils = class {
13785
16225
  if (!obj || typeof obj !== "object") {
13786
16226
  return obj;
13787
16227
  }
13788
- if (obj instanceof import_firestore41.Timestamp) {
16228
+ if (obj instanceof import_firestore49.Timestamp) {
13789
16229
  return this.clientToAdmin(obj);
13790
16230
  }
13791
16231
  if (Array.isArray(obj)) {
@@ -13810,7 +16250,7 @@ TimestampUtils.serverMode = IS_SERVER_ENV;
13810
16250
 
13811
16251
  // src/config/firebase.ts
13812
16252
  var import_app = require("firebase/app");
13813
- var import_firestore42 = require("firebase/firestore");
16253
+ var import_firestore50 = require("firebase/firestore");
13814
16254
  var import_auth9 = require("firebase/auth");
13815
16255
  var import_analytics = require("firebase/analytics");
13816
16256
  var import_react_native = require("react-native");
@@ -13820,7 +16260,7 @@ var firebaseInstance = null;
13820
16260
  var initializeFirebase = (config) => {
13821
16261
  if (!firebaseInstance) {
13822
16262
  const app = (0, import_app.initializeApp)(config);
13823
- const db = (0, import_firestore42.getFirestore)(app);
16263
+ const db = (0, import_firestore50.getFirestore)(app);
13824
16264
  const auth = (0, import_auth9.getAuth)(app);
13825
16265
  const storage = (0, import_storage4.getStorage)(app);
13826
16266
  const functions = (0, import_functions2.getFunctions)(app);
@@ -13875,6 +16315,7 @@ var getFirebaseFunctions = async () => {
13875
16315
  CLINIC_GROUPS_COLLECTION,
13876
16316
  CalendarEventStatus,
13877
16317
  CalendarEventType,
16318
+ CalendarServiceV2,
13878
16319
  CalendarServiceV3,
13879
16320
  CalendarSyncStatus,
13880
16321
  ClinicAdminService,
@@ -13943,6 +16384,7 @@ var getFirebaseFunctions = async () => {
13943
16384
  USERS_COLLECTION,
13944
16385
  USER_FORMS_SUBCOLLECTION,
13945
16386
  UserRole,
16387
+ UserService,
13946
16388
  addAllergySchema,
13947
16389
  addBlockingConditionSchema,
13948
16390
  addContraindicationSchema,