@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.mjs CHANGED
@@ -593,20 +593,20 @@ import {
593
593
  } from "firebase/firestore";
594
594
 
595
595
  // src/types/calendar/index.ts
596
- var CalendarEventStatus = /* @__PURE__ */ ((CalendarEventStatus3) => {
597
- CalendarEventStatus3["PENDING"] = "pending";
598
- CalendarEventStatus3["CONFIRMED"] = "confirmed";
599
- CalendarEventStatus3["REJECTED"] = "rejected";
600
- CalendarEventStatus3["CANCELED"] = "canceled";
601
- CalendarEventStatus3["RESCHEDULED"] = "rescheduled";
602
- CalendarEventStatus3["COMPLETED"] = "completed";
603
- CalendarEventStatus3["NO_SHOW"] = "no_show";
604
- return CalendarEventStatus3;
596
+ var CalendarEventStatus = /* @__PURE__ */ ((CalendarEventStatus4) => {
597
+ CalendarEventStatus4["PENDING"] = "pending";
598
+ CalendarEventStatus4["CONFIRMED"] = "confirmed";
599
+ CalendarEventStatus4["REJECTED"] = "rejected";
600
+ CalendarEventStatus4["CANCELED"] = "canceled";
601
+ CalendarEventStatus4["RESCHEDULED"] = "rescheduled";
602
+ CalendarEventStatus4["COMPLETED"] = "completed";
603
+ CalendarEventStatus4["NO_SHOW"] = "no_show";
604
+ return CalendarEventStatus4;
605
605
  })(CalendarEventStatus || {});
606
- var CalendarSyncStatus = /* @__PURE__ */ ((CalendarSyncStatus3) => {
607
- CalendarSyncStatus3["INTERNAL"] = "internal";
608
- CalendarSyncStatus3["EXTERNAL"] = "external";
609
- return CalendarSyncStatus3;
606
+ var CalendarSyncStatus = /* @__PURE__ */ ((CalendarSyncStatus4) => {
607
+ CalendarSyncStatus4["INTERNAL"] = "internal";
608
+ CalendarSyncStatus4["EXTERNAL"] = "external";
609
+ return CalendarSyncStatus4;
610
610
  })(CalendarSyncStatus || {});
611
611
  var CalendarEventType = /* @__PURE__ */ ((CalendarEventType3) => {
612
612
  CalendarEventType3["APPOINTMENT"] = "appointment";
@@ -978,7 +978,7 @@ async function searchAppointmentsUtil(db, params) {
978
978
  const q = query(collection(db, APPOINTMENTS_COLLECTION), ...constraints);
979
979
  const querySnapshot = await getDocs(q);
980
980
  const appointments = querySnapshot.docs.map(
981
- (doc26) => doc26.data()
981
+ (doc32) => doc32.data()
982
982
  );
983
983
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
984
984
  return { appointments, lastDoc };
@@ -1785,7 +1785,7 @@ var AppointmentService = class extends BaseService {
1785
1785
  );
1786
1786
  const querySnapshot = await getDocs2(q);
1787
1787
  const appointments = querySnapshot.docs.map(
1788
- (doc26) => doc26.data()
1788
+ (doc32) => doc32.data()
1789
1789
  );
1790
1790
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
1791
1791
  console.log(
@@ -1858,7 +1858,7 @@ var AppointmentService = class extends BaseService {
1858
1858
  );
1859
1859
  const querySnapshot = await getDocs2(q);
1860
1860
  const appointments = querySnapshot.docs.map(
1861
- (doc26) => doc26.data()
1861
+ (doc32) => doc32.data()
1862
1862
  );
1863
1863
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
1864
1864
  console.log(
@@ -2589,11 +2589,11 @@ var UserRole = /* @__PURE__ */ ((UserRole2) => {
2589
2589
  var USERS_COLLECTION = "users";
2590
2590
 
2591
2591
  // src/types/calendar/synced-calendar.types.ts
2592
- var SyncedCalendarProvider = /* @__PURE__ */ ((SyncedCalendarProvider2) => {
2593
- SyncedCalendarProvider2["GOOGLE"] = "google";
2594
- SyncedCalendarProvider2["OUTLOOK"] = "outlook";
2595
- SyncedCalendarProvider2["APPLE"] = "apple";
2596
- return SyncedCalendarProvider2;
2592
+ var SyncedCalendarProvider = /* @__PURE__ */ ((SyncedCalendarProvider3) => {
2593
+ SyncedCalendarProvider3["GOOGLE"] = "google";
2594
+ SyncedCalendarProvider3["OUTLOOK"] = "outlook";
2595
+ SyncedCalendarProvider3["APPLE"] = "apple";
2596
+ return SyncedCalendarProvider3;
2597
2597
  })(SyncedCalendarProvider || {});
2598
2598
  var SYNCED_CALENDARS_COLLECTION = "syncedCalendars";
2599
2599
 
@@ -3167,7 +3167,7 @@ var MediaService = class extends BaseService {
3167
3167
  try {
3168
3168
  const querySnapshot = await getDocs3(finalQuery);
3169
3169
  const mediaList = querySnapshot.docs.map(
3170
- (doc26) => doc26.data()
3170
+ (doc32) => doc32.data()
3171
3171
  );
3172
3172
  console.log(`[MediaService] Found ${mediaList.length} media items.`);
3173
3173
  return mediaList;
@@ -3230,8 +3230,8 @@ var getPatientsByClinicUtil = async (db, clinicId, options) => {
3230
3230
  }
3231
3231
  const patientsSnapshot = await getDocs4(q);
3232
3232
  const patients = [];
3233
- patientsSnapshot.forEach((doc26) => {
3234
- patients.push(doc26.data());
3233
+ patientsSnapshot.forEach((doc32) => {
3234
+ patients.push(doc32.data());
3235
3235
  });
3236
3236
  console.log(
3237
3237
  `[getPatientsByClinicUtil] Found ${patients.length} patients for clinic ID: ${clinicId}`
@@ -3605,8 +3605,8 @@ var getPatientsByPractitionerUtil = async (db, practitionerId, options) => {
3605
3605
  }
3606
3606
  const patientsSnapshot = await getDocs5(q);
3607
3607
  const patients = [];
3608
- patientsSnapshot.forEach((doc26) => {
3609
- patients.push(doc26.data());
3608
+ patientsSnapshot.forEach((doc32) => {
3609
+ patients.push(doc32.data());
3610
3610
  });
3611
3611
  console.log(
3612
3612
  `[getPatientsByPractitionerUtil] Found ${patients.length} patients for practitioner ID: ${practitionerId}`
@@ -4186,7 +4186,7 @@ async function getClinicAdminsByGroup(db, clinicGroupId) {
4186
4186
  where6("clinicGroupId", "==", clinicGroupId)
4187
4187
  );
4188
4188
  const querySnapshot = await getDocs6(q);
4189
- return querySnapshot.docs.map((doc26) => doc26.data());
4189
+ return querySnapshot.docs.map((doc32) => doc32.data());
4190
4190
  }
4191
4191
  async function updateClinicAdmin(db, adminId, data) {
4192
4192
  const admin2 = await getClinicAdmin(db, adminId);
@@ -4867,9 +4867,9 @@ var updateAllergyUtil = async (db, patientId, data, requesterId, requesterRoles)
4867
4867
  };
4868
4868
  var removeAllergyUtil = async (db, patientId, allergyIndex, requesterId, requesterRoles) => {
4869
4869
  await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
4870
- const doc26 = await getDoc10(getMedicalInfoDocRef(db, patientId));
4871
- if (!doc26.exists()) throw new Error("Medical info not found");
4872
- const medicalInfo = doc26.data();
4870
+ const doc32 = await getDoc10(getMedicalInfoDocRef(db, patientId));
4871
+ if (!doc32.exists()) throw new Error("Medical info not found");
4872
+ const medicalInfo = doc32.data();
4873
4873
  if (allergyIndex >= medicalInfo.allergies.length) {
4874
4874
  throw new Error("Invalid allergy index");
4875
4875
  }
@@ -4896,9 +4896,9 @@ var updateBlockingConditionUtil = async (db, patientId, data, requesterId, reque
4896
4896
  await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
4897
4897
  const validatedData = updateBlockingConditionSchema.parse(data);
4898
4898
  const { conditionIndex, ...updateData } = validatedData;
4899
- const doc26 = await getDoc10(getMedicalInfoDocRef(db, patientId));
4900
- if (!doc26.exists()) throw new Error("Medical info not found");
4901
- const medicalInfo = doc26.data();
4899
+ const doc32 = await getDoc10(getMedicalInfoDocRef(db, patientId));
4900
+ if (!doc32.exists()) throw new Error("Medical info not found");
4901
+ const medicalInfo = doc32.data();
4902
4902
  if (conditionIndex >= medicalInfo.blockingConditions.length) {
4903
4903
  throw new Error("Invalid blocking condition index");
4904
4904
  }
@@ -4915,9 +4915,9 @@ var updateBlockingConditionUtil = async (db, patientId, data, requesterId, reque
4915
4915
  };
4916
4916
  var removeBlockingConditionUtil = async (db, patientId, conditionIndex, requesterId, requesterRoles) => {
4917
4917
  await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
4918
- const doc26 = await getDoc10(getMedicalInfoDocRef(db, patientId));
4919
- if (!doc26.exists()) throw new Error("Medical info not found");
4920
- const medicalInfo = doc26.data();
4918
+ const doc32 = await getDoc10(getMedicalInfoDocRef(db, patientId));
4919
+ if (!doc32.exists()) throw new Error("Medical info not found");
4920
+ const medicalInfo = doc32.data();
4921
4921
  if (conditionIndex >= medicalInfo.blockingConditions.length) {
4922
4922
  throw new Error("Invalid blocking condition index");
4923
4923
  }
@@ -4944,9 +4944,9 @@ var updateContraindicationUtil = async (db, patientId, data, requesterId, reques
4944
4944
  await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
4945
4945
  const validatedData = updateContraindicationSchema.parse(data);
4946
4946
  const { contraindicationIndex, ...updateData } = validatedData;
4947
- const doc26 = await getDoc10(getMedicalInfoDocRef(db, patientId));
4948
- if (!doc26.exists()) throw new Error("Medical info not found");
4949
- const medicalInfo = doc26.data();
4947
+ const doc32 = await getDoc10(getMedicalInfoDocRef(db, patientId));
4948
+ if (!doc32.exists()) throw new Error("Medical info not found");
4949
+ const medicalInfo = doc32.data();
4950
4950
  if (contraindicationIndex >= medicalInfo.contraindications.length) {
4951
4951
  throw new Error("Invalid contraindication index");
4952
4952
  }
@@ -4963,9 +4963,9 @@ var updateContraindicationUtil = async (db, patientId, data, requesterId, reques
4963
4963
  };
4964
4964
  var removeContraindicationUtil = async (db, patientId, contraindicationIndex, requesterId, requesterRoles) => {
4965
4965
  await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
4966
- const doc26 = await getDoc10(getMedicalInfoDocRef(db, patientId));
4967
- if (!doc26.exists()) throw new Error("Medical info not found");
4968
- const medicalInfo = doc26.data();
4966
+ const doc32 = await getDoc10(getMedicalInfoDocRef(db, patientId));
4967
+ if (!doc32.exists()) throw new Error("Medical info not found");
4968
+ const medicalInfo = doc32.data();
4969
4969
  if (contraindicationIndex >= medicalInfo.contraindications.length) {
4970
4970
  throw new Error("Invalid contraindication index");
4971
4971
  }
@@ -4992,9 +4992,9 @@ var updateMedicationUtil = async (db, patientId, data, requesterId, requesterRol
4992
4992
  await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
4993
4993
  const validatedData = updateMedicationSchema.parse(data);
4994
4994
  const { medicationIndex, ...updateData } = validatedData;
4995
- const doc26 = await getDoc10(getMedicalInfoDocRef(db, patientId));
4996
- if (!doc26.exists()) throw new Error("Medical info not found");
4997
- const medicalInfo = doc26.data();
4995
+ const doc32 = await getDoc10(getMedicalInfoDocRef(db, patientId));
4996
+ if (!doc32.exists()) throw new Error("Medical info not found");
4997
+ const medicalInfo = doc32.data();
4998
4998
  if (medicationIndex >= medicalInfo.currentMedications.length) {
4999
4999
  throw new Error("Invalid medication index");
5000
5000
  }
@@ -5011,9 +5011,9 @@ var updateMedicationUtil = async (db, patientId, data, requesterId, requesterRol
5011
5011
  };
5012
5012
  var removeMedicationUtil = async (db, patientId, medicationIndex, requesterId, requesterRoles) => {
5013
5013
  await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
5014
- const doc26 = await getDoc10(getMedicalInfoDocRef(db, patientId));
5015
- if (!doc26.exists()) throw new Error("Medical info not found");
5016
- const medicalInfo = doc26.data();
5014
+ const doc32 = await getDoc10(getMedicalInfoDocRef(db, patientId));
5015
+ if (!doc32.exists()) throw new Error("Medical info not found");
5016
+ const medicalInfo = doc32.data();
5017
5017
  if (medicationIndex >= medicalInfo.currentMedications.length) {
5018
5018
  throw new Error("Invalid medication index");
5019
5019
  }
@@ -5316,7 +5316,7 @@ var searchPatientsUtil = async (db, params, requester) => {
5316
5316
  const finalQuery = query8(patientsCollectionRef, ...constraints);
5317
5317
  const querySnapshot = await getDocs8(finalQuery);
5318
5318
  const patients = querySnapshot.docs.map(
5319
- (doc26) => doc26.data()
5319
+ (doc32) => doc32.data()
5320
5320
  );
5321
5321
  console.log(
5322
5322
  `[searchPatientsUtil] Found ${patients.length} patients matching criteria.`
@@ -5348,8 +5348,8 @@ var getAllPatientsUtil = async (db, options) => {
5348
5348
  }
5349
5349
  const patientsSnapshot = await getDocs8(q);
5350
5350
  const patients = [];
5351
- patientsSnapshot.forEach((doc26) => {
5352
- patients.push(doc26.data());
5351
+ patientsSnapshot.forEach((doc32) => {
5352
+ patients.push(doc32.data());
5353
5353
  });
5354
5354
  console.log(`[getAllPatientsUtil] Found ${patients.length} patients`);
5355
5355
  return patients;
@@ -5482,7 +5482,7 @@ var getActiveInviteTokensByClinicUtil = async (db, clinicId) => {
5482
5482
  if (querySnapshot.empty) {
5483
5483
  return [];
5484
5484
  }
5485
- return querySnapshot.docs.map((doc26) => doc26.data());
5485
+ return querySnapshot.docs.map((doc32) => doc32.data());
5486
5486
  };
5487
5487
  var getActiveInviteTokensByPatientUtil = async (db, patientId) => {
5488
5488
  const tokensRef = collection9(
@@ -5500,7 +5500,7 @@ var getActiveInviteTokensByPatientUtil = async (db, patientId) => {
5500
5500
  if (querySnapshot.empty) {
5501
5501
  return [];
5502
5502
  }
5503
- return querySnapshot.docs.map((doc26) => doc26.data());
5503
+ return querySnapshot.docs.map((doc32) => doc32.data());
5504
5504
  };
5505
5505
 
5506
5506
  // src/services/patient/patient.service.ts
@@ -6623,7 +6623,7 @@ var PractitionerService = class extends BaseService {
6623
6623
  where10("expiresAt", ">", Timestamp14.now())
6624
6624
  );
6625
6625
  const querySnapshot = await getDocs10(q);
6626
- return querySnapshot.docs.map((doc26) => doc26.data());
6626
+ return querySnapshot.docs.map((doc32) => doc32.data());
6627
6627
  }
6628
6628
  /**
6629
6629
  * Gets a token by its string value and validates it
@@ -6733,7 +6733,7 @@ var PractitionerService = class extends BaseService {
6733
6733
  where10("status", "==", "active" /* ACTIVE */)
6734
6734
  );
6735
6735
  const querySnapshot = await getDocs10(q);
6736
- return querySnapshot.docs.map((doc26) => doc26.data());
6736
+ return querySnapshot.docs.map((doc32) => doc32.data());
6737
6737
  }
6738
6738
  /**
6739
6739
  * Dohvata sve zdravstvene radnike za određenu kliniku
@@ -6745,7 +6745,7 @@ var PractitionerService = class extends BaseService {
6745
6745
  where10("isActive", "==", true)
6746
6746
  );
6747
6747
  const querySnapshot = await getDocs10(q);
6748
- return querySnapshot.docs.map((doc26) => doc26.data());
6748
+ return querySnapshot.docs.map((doc32) => doc32.data());
6749
6749
  }
6750
6750
  /**
6751
6751
  * Dohvata sve draft zdravstvene radnike za određenu kliniku sa statusom DRAFT
@@ -6757,7 +6757,7 @@ var PractitionerService = class extends BaseService {
6757
6757
  where10("status", "==", "draft" /* DRAFT */)
6758
6758
  );
6759
6759
  const querySnapshot = await getDocs10(q);
6760
- return querySnapshot.docs.map((doc26) => doc26.data());
6760
+ return querySnapshot.docs.map((doc32) => doc32.data());
6761
6761
  }
6762
6762
  /**
6763
6763
  * Updates a practitioner
@@ -6971,7 +6971,7 @@ var PractitionerService = class extends BaseService {
6971
6971
  );
6972
6972
  const querySnapshot = await getDocs10(q);
6973
6973
  const practitioners = querySnapshot.docs.map(
6974
- (doc26) => doc26.data()
6974
+ (doc32) => doc32.data()
6975
6975
  );
6976
6976
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
6977
6977
  return {
@@ -7042,8 +7042,8 @@ var PractitionerService = class extends BaseService {
7042
7042
  console.log(
7043
7043
  `[PRACTITIONER_SERVICE] Found ${querySnapshot.docs.length} practitioners with base query`
7044
7044
  );
7045
- let practitioners = querySnapshot.docs.map((doc26) => {
7046
- return { ...doc26.data(), id: doc26.id };
7045
+ let practitioners = querySnapshot.docs.map((doc32) => {
7046
+ return { ...doc32.data(), id: doc32.id };
7047
7047
  });
7048
7048
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
7049
7049
  if (filters.nameSearch && filters.nameSearch.trim() !== "") {
@@ -7527,7 +7527,7 @@ var UserService = class extends BaseService {
7527
7527
  ];
7528
7528
  const q = query11(collection11(this.db, USERS_COLLECTION), ...constraints);
7529
7529
  const querySnapshot = await getDocs11(q);
7530
- const users = querySnapshot.docs.map((doc26) => doc26.data());
7530
+ const users = querySnapshot.docs.map((doc32) => doc32.data());
7531
7531
  return users.map((userData) => userSchema.parse(userData));
7532
7532
  }
7533
7533
  /**
@@ -7907,7 +7907,7 @@ async function getAllActiveGroups(db) {
7907
7907
  where12("isActive", "==", true)
7908
7908
  );
7909
7909
  const querySnapshot = await getDocs12(q);
7910
- return querySnapshot.docs.map((doc26) => doc26.data());
7910
+ return querySnapshot.docs.map((doc32) => doc32.data());
7911
7911
  }
7912
7912
  async function updateClinicGroup(db, groupId, data, app) {
7913
7913
  console.log("[CLINIC_GROUP] Updating clinic group", { groupId });
@@ -8372,7 +8372,7 @@ async function getClinicsByGroup(db, groupId) {
8372
8372
  where13("isActive", "==", true)
8373
8373
  );
8374
8374
  const querySnapshot = await getDocs13(q);
8375
- return querySnapshot.docs.map((doc26) => doc26.data());
8375
+ return querySnapshot.docs.map((doc32) => doc32.data());
8376
8376
  }
8377
8377
  async function updateClinic(db, clinicId, data, adminId, clinicAdminService, app) {
8378
8378
  console.log("[CLINIC] Starting clinic update", { clinicId, adminId });
@@ -8566,7 +8566,7 @@ async function getClinicsByAdmin(db, adminId, options = {}, clinicAdminService,
8566
8566
  }
8567
8567
  const q = query13(collection13(db, CLINICS_COLLECTION), ...constraints);
8568
8568
  const querySnapshot = await getDocs13(q);
8569
- return querySnapshot.docs.map((doc26) => doc26.data());
8569
+ return querySnapshot.docs.map((doc32) => doc32.data());
8570
8570
  }
8571
8571
  async function getActiveClinicsByAdmin(db, adminId, clinicAdminService, clinicGroupService) {
8572
8572
  return getClinicsByAdmin(
@@ -8611,11 +8611,11 @@ async function getAllClinics(db, pagination, lastDoc) {
8611
8611
  }
8612
8612
  const clinicsSnapshot = await getDocs13(clinicsQuery);
8613
8613
  const lastVisible = clinicsSnapshot.docs[clinicsSnapshot.docs.length - 1];
8614
- const clinics = clinicsSnapshot.docs.map((doc26) => {
8615
- const data = doc26.data();
8614
+ const clinics = clinicsSnapshot.docs.map((doc32) => {
8615
+ const data = doc32.data();
8616
8616
  return {
8617
8617
  ...data,
8618
- id: doc26.id
8618
+ id: doc32.id
8619
8619
  };
8620
8620
  });
8621
8621
  return {
@@ -8642,8 +8642,8 @@ async function getAllClinicsInRange(db, center, rangeInKm, pagination, lastDoc)
8642
8642
  ];
8643
8643
  const q = query13(collection13(db, CLINICS_COLLECTION), ...constraints);
8644
8644
  const querySnapshot = await getDocs13(q);
8645
- for (const doc26 of querySnapshot.docs) {
8646
- const clinic = doc26.data();
8645
+ for (const doc32 of querySnapshot.docs) {
8646
+ const clinic = doc32.data();
8647
8647
  const distance = distanceBetween2(
8648
8648
  [center.latitude, center.longitude],
8649
8649
  [clinic.location.latitude, clinic.location.longitude]
@@ -8765,8 +8765,8 @@ async function findClinicsInRadius(db, center, radiusInKm, filters) {
8765
8765
  }
8766
8766
  const q = query14(collection14(db, CLINICS_COLLECTION), ...constraints);
8767
8767
  const querySnapshot = await getDocs14(q);
8768
- for (const doc26 of querySnapshot.docs) {
8769
- const clinic = doc26.data();
8768
+ for (const doc32 of querySnapshot.docs) {
8769
+ const clinic = doc32.data();
8770
8770
  const distance = distanceBetween3(
8771
8771
  [center.latitude, center.longitude],
8772
8772
  [clinic.location.latitude, clinic.location.longitude]
@@ -8862,8 +8862,8 @@ async function getClinicsByFilters(db, filters) {
8862
8862
  console.log(
8863
8863
  `[FILTER_UTILS] Found ${querySnapshot.docs.length} clinics in geo bound`
8864
8864
  );
8865
- for (const doc26 of querySnapshot.docs) {
8866
- const clinic = { ...doc26.data(), id: doc26.id };
8865
+ for (const doc32 of querySnapshot.docs) {
8866
+ const clinic = { ...doc32.data(), id: doc32.id };
8867
8867
  const distance = distanceBetween4(
8868
8868
  [center.latitude, center.longitude],
8869
8869
  [clinic.location.latitude, clinic.location.longitude]
@@ -8919,8 +8919,8 @@ async function getClinicsByFilters(db, filters) {
8919
8919
  console.log(
8920
8920
  `[FILTER_UTILS] Found ${querySnapshot.docs.length} clinics with regular query`
8921
8921
  );
8922
- const clinics = querySnapshot.docs.map((doc26) => {
8923
- return { ...doc26.data(), id: doc26.id };
8922
+ const clinics = querySnapshot.docs.map((doc32) => {
8923
+ return { ...doc32.data(), id: doc32.id };
8924
8924
  });
8925
8925
  let filteredClinics = clinics;
8926
8926
  if (filters.center) {
@@ -10238,14 +10238,23 @@ var AuthService = class extends BaseService {
10238
10238
  }
10239
10239
  };
10240
10240
 
10241
- // src/services/calendar/calendar.v3.service.ts
10242
- import { Timestamp as Timestamp21, serverTimestamp as serverTimestamp16 } from "firebase/firestore";
10243
- import { doc as doc18, getDoc as getDoc21, setDoc as setDoc17, updateDoc as updateDoc18, deleteDoc as deleteDoc10 } from "firebase/firestore";
10241
+ // src/services/calendar/calendar.v2.service.ts
10242
+ import { Timestamp as Timestamp26, serverTimestamp as serverTimestamp20 } from "firebase/firestore";
10243
+ import {
10244
+ doc as doc23,
10245
+ getDoc as getDoc25,
10246
+ collection as collection23,
10247
+ query as query23,
10248
+ where as where23,
10249
+ getDocs as getDocs23,
10250
+ setDoc as setDoc21,
10251
+ updateDoc as updateDoc22
10252
+ } from "firebase/firestore";
10244
10253
 
10245
- // src/services/calendar/utils/calendar-event.utils.ts
10254
+ // src/services/calendar/utils/clinic.utils.ts
10246
10255
  import {
10247
10256
  collection as collection18,
10248
- doc as doc17,
10257
+ doc as doc18,
10249
10258
  getDoc as getDoc20,
10250
10259
  getDocs as getDocs18,
10251
10260
  setDoc as setDoc16,
@@ -10257,6 +10266,257 @@ import {
10257
10266
  Timestamp as Timestamp20,
10258
10267
  serverTimestamp as serverTimestamp15
10259
10268
  } from "firebase/firestore";
10269
+
10270
+ // src/services/calendar/utils/docs.utils.ts
10271
+ import { doc as doc17 } from "firebase/firestore";
10272
+ function getPractitionerCalendarEventDocRef(db, practitionerId, eventId) {
10273
+ return doc17(
10274
+ db,
10275
+ `${PRACTITIONERS_COLLECTION}/${practitionerId}/${CALENDAR_COLLECTION}/${eventId}`
10276
+ );
10277
+ }
10278
+ function getPatientCalendarEventDocRef(db, patientId, eventId) {
10279
+ return doc17(
10280
+ db,
10281
+ `${PATIENTS_COLLECTION}/${patientId}/${CALENDAR_COLLECTION}/${eventId}`
10282
+ );
10283
+ }
10284
+ function getClinicCalendarEventDocRef(db, clinicId, eventId) {
10285
+ return doc17(
10286
+ db,
10287
+ `${CLINICS_COLLECTION}/${clinicId}/${CALENDAR_COLLECTION}/${eventId}`
10288
+ );
10289
+ }
10290
+ function getPractitionerSyncedCalendarDocRef(db, practitionerId, syncedCalendarId) {
10291
+ return doc17(
10292
+ db,
10293
+ `${PRACTITIONERS_COLLECTION}/${practitionerId}/syncedCalendars/${syncedCalendarId}`
10294
+ );
10295
+ }
10296
+ function getPatientSyncedCalendarDocRef(db, patientId, syncedCalendarId) {
10297
+ return doc17(
10298
+ db,
10299
+ `${PATIENTS_COLLECTION}/${patientId}/syncedCalendars/${syncedCalendarId}`
10300
+ );
10301
+ }
10302
+ function getClinicSyncedCalendarDocRef(db, clinicId, syncedCalendarId) {
10303
+ return doc17(
10304
+ db,
10305
+ `${CLINICS_COLLECTION}/${clinicId}/syncedCalendars/${syncedCalendarId}`
10306
+ );
10307
+ }
10308
+
10309
+ // src/services/calendar/utils/clinic.utils.ts
10310
+ async function createClinicCalendarEventUtil(db, clinicId, eventData, generateId2) {
10311
+ const eventId = generateId2();
10312
+ const eventRef = getClinicCalendarEventDocRef(db, clinicId, eventId);
10313
+ const newEvent = {
10314
+ id: eventId,
10315
+ ...eventData,
10316
+ createdAt: serverTimestamp15(),
10317
+ updatedAt: serverTimestamp15()
10318
+ };
10319
+ await setDoc16(eventRef, newEvent);
10320
+ return {
10321
+ ...newEvent,
10322
+ createdAt: Timestamp20.now(),
10323
+ updatedAt: Timestamp20.now()
10324
+ };
10325
+ }
10326
+ async function updateClinicCalendarEventUtil(db, clinicId, eventId, updateData) {
10327
+ const eventRef = getClinicCalendarEventDocRef(db, clinicId, eventId);
10328
+ const updates = {
10329
+ ...updateData,
10330
+ updatedAt: serverTimestamp15()
10331
+ };
10332
+ await updateDoc17(eventRef, updates);
10333
+ const updatedDoc = await getDoc20(eventRef);
10334
+ if (!updatedDoc.exists()) {
10335
+ throw new Error("Event not found after update");
10336
+ }
10337
+ return updatedDoc.data();
10338
+ }
10339
+ async function checkAutoConfirmAppointmentsUtil(db, clinicId) {
10340
+ const clinicDoc = await getDoc20(doc18(db, `clinics/${clinicId}`));
10341
+ if (!clinicDoc.exists()) {
10342
+ throw new Error(`Clinic with ID ${clinicId} not found`);
10343
+ }
10344
+ const clinicData = clinicDoc.data();
10345
+ const clinicGroupId = clinicData.clinicGroupId;
10346
+ if (!clinicGroupId) {
10347
+ return false;
10348
+ }
10349
+ const clinicGroupDoc = await getDoc20(
10350
+ doc18(db, `${CLINIC_GROUPS_COLLECTION}/${clinicGroupId}`)
10351
+ );
10352
+ if (!clinicGroupDoc.exists()) {
10353
+ return false;
10354
+ }
10355
+ const clinicGroupData = clinicGroupDoc.data();
10356
+ return !!clinicGroupData.autoConfirmAppointments;
10357
+ }
10358
+
10359
+ // src/services/calendar/utils/patient.utils.ts
10360
+ import {
10361
+ collection as collection19,
10362
+ getDoc as getDoc21,
10363
+ getDocs as getDocs19,
10364
+ setDoc as setDoc17,
10365
+ updateDoc as updateDoc18,
10366
+ deleteDoc as deleteDoc10,
10367
+ query as query19,
10368
+ where as where19,
10369
+ orderBy as orderBy8,
10370
+ Timestamp as Timestamp21,
10371
+ serverTimestamp as serverTimestamp16
10372
+ } from "firebase/firestore";
10373
+ async function createPatientCalendarEventUtil(db, patientId, eventData, generateId2) {
10374
+ const eventId = generateId2();
10375
+ const eventRef = getPatientCalendarEventDocRef(db, patientId, eventId);
10376
+ const newEvent = {
10377
+ id: eventId,
10378
+ ...eventData,
10379
+ createdAt: serverTimestamp16(),
10380
+ updatedAt: serverTimestamp16()
10381
+ };
10382
+ await setDoc17(eventRef, newEvent);
10383
+ return {
10384
+ ...newEvent,
10385
+ createdAt: Timestamp21.now(),
10386
+ updatedAt: Timestamp21.now()
10387
+ };
10388
+ }
10389
+ async function updatePatientCalendarEventUtil(db, patientId, eventId, updateData) {
10390
+ const eventRef = getPatientCalendarEventDocRef(db, patientId, eventId);
10391
+ const updates = {
10392
+ ...updateData,
10393
+ updatedAt: serverTimestamp16()
10394
+ };
10395
+ await updateDoc18(eventRef, updates);
10396
+ const updatedDoc = await getDoc21(eventRef);
10397
+ if (!updatedDoc.exists()) {
10398
+ throw new Error("Event not found after update");
10399
+ }
10400
+ return updatedDoc.data();
10401
+ }
10402
+
10403
+ // src/services/calendar/utils/practitioner.utils.ts
10404
+ import {
10405
+ collection as collection20,
10406
+ getDoc as getDoc22,
10407
+ getDocs as getDocs20,
10408
+ setDoc as setDoc18,
10409
+ updateDoc as updateDoc19,
10410
+ deleteDoc as deleteDoc11,
10411
+ query as query20,
10412
+ where as where20,
10413
+ orderBy as orderBy9,
10414
+ Timestamp as Timestamp22,
10415
+ serverTimestamp as serverTimestamp17
10416
+ } from "firebase/firestore";
10417
+ async function createPractitionerCalendarEventUtil(db, practitionerId, eventData, generateId2) {
10418
+ const eventId = generateId2();
10419
+ const eventRef = getPractitionerCalendarEventDocRef(
10420
+ db,
10421
+ practitionerId,
10422
+ eventId
10423
+ );
10424
+ const newEvent = {
10425
+ id: eventId,
10426
+ ...eventData,
10427
+ createdAt: serverTimestamp17(),
10428
+ updatedAt: serverTimestamp17()
10429
+ };
10430
+ await setDoc18(eventRef, newEvent);
10431
+ return {
10432
+ ...newEvent,
10433
+ createdAt: Timestamp22.now(),
10434
+ updatedAt: Timestamp22.now()
10435
+ };
10436
+ }
10437
+ async function updatePractitionerCalendarEventUtil(db, practitionerId, eventId, updateData) {
10438
+ const eventRef = getPractitionerCalendarEventDocRef(
10439
+ db,
10440
+ practitionerId,
10441
+ eventId
10442
+ );
10443
+ const updates = {
10444
+ ...updateData,
10445
+ updatedAt: serverTimestamp17()
10446
+ };
10447
+ await updateDoc19(eventRef, updates);
10448
+ const updatedDoc = await getDoc22(eventRef);
10449
+ if (!updatedDoc.exists()) {
10450
+ throw new Error("Event not found after update");
10451
+ }
10452
+ return updatedDoc.data();
10453
+ }
10454
+
10455
+ // src/services/calendar/utils/appointment.utils.ts
10456
+ async function createAppointmentUtil2(db, clinicId, practitionerId, patientId, eventData, generateId2) {
10457
+ const eventId = generateId2();
10458
+ const autoConfirm = await checkAutoConfirmAppointmentsUtil(db, clinicId);
10459
+ const initialStatus = autoConfirm ? "confirmed" /* CONFIRMED */ : "pending" /* PENDING */;
10460
+ const appointmentData = {
10461
+ ...eventData,
10462
+ clinicBranchId: clinicId,
10463
+ practitionerProfileId: practitionerId,
10464
+ patientProfileId: patientId,
10465
+ eventType: "appointment" /* APPOINTMENT */,
10466
+ status: eventData.status || initialStatus
10467
+ };
10468
+ const clinicPromise = createClinicCalendarEventUtil(
10469
+ db,
10470
+ clinicId,
10471
+ appointmentData,
10472
+ () => eventId
10473
+ // Use the same ID for all calendars
10474
+ );
10475
+ const practitionerPromise = createPractitionerCalendarEventUtil(
10476
+ db,
10477
+ practitionerId,
10478
+ appointmentData,
10479
+ () => eventId
10480
+ // Use the same ID for all calendars
10481
+ );
10482
+ const patientPromise = createPatientCalendarEventUtil(
10483
+ db,
10484
+ patientId,
10485
+ appointmentData,
10486
+ () => eventId
10487
+ // Use the same ID for all calendars
10488
+ );
10489
+ const [clinicEvent] = await Promise.all([clinicPromise, practitionerPromise, patientPromise]);
10490
+ return clinicEvent;
10491
+ }
10492
+ async function updateAppointmentUtil2(db, clinicId, practitionerId, patientId, eventId, updateData) {
10493
+ const clinicPromise = updateClinicCalendarEventUtil(db, clinicId, eventId, updateData);
10494
+ const practitionerPromise = updatePractitionerCalendarEventUtil(
10495
+ db,
10496
+ practitionerId,
10497
+ eventId,
10498
+ updateData
10499
+ );
10500
+ const patientPromise = updatePatientCalendarEventUtil(db, patientId, eventId, updateData);
10501
+ const [clinicEvent] = await Promise.all([clinicPromise, practitionerPromise, patientPromise]);
10502
+ return clinicEvent;
10503
+ }
10504
+
10505
+ // src/services/calendar/utils/calendar-event.utils.ts
10506
+ import {
10507
+ collection as collection21,
10508
+ doc as doc21,
10509
+ getDoc as getDoc23,
10510
+ getDocs as getDocs21,
10511
+ setDoc as setDoc19,
10512
+ updateDoc as updateDoc20,
10513
+ deleteDoc as deleteDoc12,
10514
+ query as query21,
10515
+ where as where21,
10516
+ orderBy as orderBy10,
10517
+ Timestamp as Timestamp23,
10518
+ serverTimestamp as serverTimestamp18
10519
+ } from "firebase/firestore";
10260
10520
  async function searchCalendarEventsUtil(db, params) {
10261
10521
  const { searchLocation, entityId, ...filters } = params;
10262
10522
  let baseCollectionPath;
@@ -10268,88 +10528,2323 @@ async function searchCalendarEventsUtil(db, params) {
10268
10528
  "Practitioner ID (entityId) is required when searching practitioner calendar."
10269
10529
  );
10270
10530
  }
10271
- baseCollectionPath = `${PRACTITIONERS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}`;
10272
- if (filters.practitionerId && filters.practitionerId !== entityId) {
10273
- console.warn(
10274
- `Provided practitionerId filter (${filters.practitionerId}) does not match search entityId (${entityId}). Returning empty results.`
10275
- );
10276
- return [];
10531
+ baseCollectionPath = `${PRACTITIONERS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}`;
10532
+ if (filters.practitionerId && filters.practitionerId !== entityId) {
10533
+ console.warn(
10534
+ `Provided practitionerId filter (${filters.practitionerId}) does not match search entityId (${entityId}). Returning empty results.`
10535
+ );
10536
+ return [];
10537
+ }
10538
+ filters.practitionerId = void 0;
10539
+ break;
10540
+ case "patient" /* PATIENT */:
10541
+ if (!entityId) {
10542
+ throw new Error(
10543
+ "Patient ID (entityId) is required when searching patient calendar."
10544
+ );
10545
+ }
10546
+ baseCollectionPath = `${PATIENTS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}`;
10547
+ if (filters.patientId && filters.patientId !== entityId) {
10548
+ console.warn(
10549
+ `Provided patientId filter (${filters.patientId}) does not match search entityId (${entityId}). Returning empty results.`
10550
+ );
10551
+ return [];
10552
+ }
10553
+ filters.patientId = void 0;
10554
+ break;
10555
+ case "clinic" /* CLINIC */:
10556
+ if (!entityId) {
10557
+ throw new Error(
10558
+ "Clinic ID (entityId) is required when searching clinic-related events."
10559
+ );
10560
+ }
10561
+ baseCollectionPath = `${CLINICS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}`;
10562
+ constraints.push(where21("clinicBranchId", "==", entityId));
10563
+ if (filters.clinicId && filters.clinicId !== entityId) {
10564
+ console.warn(
10565
+ `Provided clinicId filter (${filters.clinicId}) does not match search entityId (${entityId}). Returning empty results.`
10566
+ );
10567
+ return [];
10568
+ }
10569
+ filters.clinicId = void 0;
10570
+ break;
10571
+ default:
10572
+ throw new Error(`Invalid search location: ${searchLocation}`);
10573
+ }
10574
+ const collectionRef = collection21(db, baseCollectionPath);
10575
+ if (filters.clinicId) {
10576
+ constraints.push(where21("clinicBranchId", "==", filters.clinicId));
10577
+ }
10578
+ if (filters.practitionerId) {
10579
+ constraints.push(
10580
+ where21("practitionerProfileId", "==", filters.practitionerId)
10581
+ );
10582
+ }
10583
+ if (filters.patientId) {
10584
+ constraints.push(where21("patientProfileId", "==", filters.patientId));
10585
+ }
10586
+ if (filters.procedureId) {
10587
+ constraints.push(where21("procedureId", "==", filters.procedureId));
10588
+ }
10589
+ if (filters.eventStatus) {
10590
+ constraints.push(where21("status", "==", filters.eventStatus));
10591
+ }
10592
+ if (filters.eventType) {
10593
+ constraints.push(where21("eventType", "==", filters.eventType));
10594
+ }
10595
+ if (filters.dateRange) {
10596
+ constraints.push(where21("eventTime.start", ">=", filters.dateRange.start));
10597
+ constraints.push(where21("eventTime.start", "<=", filters.dateRange.end));
10598
+ }
10599
+ try {
10600
+ const finalQuery = query21(collectionRef, ...constraints);
10601
+ const querySnapshot = await getDocs21(finalQuery);
10602
+ const events = querySnapshot.docs.map(
10603
+ (doc32) => ({ id: doc32.id, ...doc32.data() })
10604
+ );
10605
+ return events;
10606
+ } catch (error) {
10607
+ console.error("Error searching calendar events:", error);
10608
+ return [];
10609
+ }
10610
+ }
10611
+
10612
+ // src/services/calendar/utils/synced-calendar.utils.ts
10613
+ import {
10614
+ collection as collection22,
10615
+ getDoc as getDoc24,
10616
+ getDocs as getDocs22,
10617
+ setDoc as setDoc20,
10618
+ updateDoc as updateDoc21,
10619
+ deleteDoc as deleteDoc13,
10620
+ query as query22,
10621
+ orderBy as orderBy11,
10622
+ Timestamp as Timestamp24,
10623
+ serverTimestamp as serverTimestamp19
10624
+ } from "firebase/firestore";
10625
+ async function createPractitionerSyncedCalendarUtil(db, practitionerId, calendarData, generateId2) {
10626
+ const calendarId = generateId2();
10627
+ const calendarRef = getPractitionerSyncedCalendarDocRef(
10628
+ db,
10629
+ practitionerId,
10630
+ calendarId
10631
+ );
10632
+ const newCalendar = {
10633
+ id: calendarId,
10634
+ ...calendarData,
10635
+ createdAt: serverTimestamp19(),
10636
+ updatedAt: serverTimestamp19()
10637
+ };
10638
+ await setDoc20(calendarRef, newCalendar);
10639
+ return {
10640
+ ...newCalendar,
10641
+ createdAt: Timestamp24.now(),
10642
+ updatedAt: Timestamp24.now()
10643
+ };
10644
+ }
10645
+ async function createPatientSyncedCalendarUtil(db, patientId, calendarData, generateId2) {
10646
+ const calendarId = generateId2();
10647
+ const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
10648
+ const newCalendar = {
10649
+ id: calendarId,
10650
+ ...calendarData,
10651
+ createdAt: serverTimestamp19(),
10652
+ updatedAt: serverTimestamp19()
10653
+ };
10654
+ await setDoc20(calendarRef, newCalendar);
10655
+ return {
10656
+ ...newCalendar,
10657
+ createdAt: Timestamp24.now(),
10658
+ updatedAt: Timestamp24.now()
10659
+ };
10660
+ }
10661
+ async function createClinicSyncedCalendarUtil(db, clinicId, calendarData, generateId2) {
10662
+ const calendarId = generateId2();
10663
+ const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
10664
+ const newCalendar = {
10665
+ id: calendarId,
10666
+ ...calendarData,
10667
+ createdAt: serverTimestamp19(),
10668
+ updatedAt: serverTimestamp19()
10669
+ };
10670
+ await setDoc20(calendarRef, newCalendar);
10671
+ return {
10672
+ ...newCalendar,
10673
+ createdAt: Timestamp24.now(),
10674
+ updatedAt: Timestamp24.now()
10675
+ };
10676
+ }
10677
+ async function getPractitionerSyncedCalendarUtil(db, practitionerId, calendarId) {
10678
+ const calendarRef = getPractitionerSyncedCalendarDocRef(
10679
+ db,
10680
+ practitionerId,
10681
+ calendarId
10682
+ );
10683
+ const calendarDoc = await getDoc24(calendarRef);
10684
+ if (!calendarDoc.exists()) {
10685
+ return null;
10686
+ }
10687
+ return calendarDoc.data();
10688
+ }
10689
+ async function getPractitionerSyncedCalendarsUtil(db, practitionerId) {
10690
+ const calendarsRef = collection22(
10691
+ db,
10692
+ `practitioners/${practitionerId}/${SYNCED_CALENDARS_COLLECTION}`
10693
+ );
10694
+ const q = query22(calendarsRef, orderBy11("createdAt", "desc"));
10695
+ const querySnapshot = await getDocs22(q);
10696
+ return querySnapshot.docs.map((doc32) => doc32.data());
10697
+ }
10698
+ async function getPatientSyncedCalendarUtil(db, patientId, calendarId) {
10699
+ const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
10700
+ const calendarDoc = await getDoc24(calendarRef);
10701
+ if (!calendarDoc.exists()) {
10702
+ return null;
10703
+ }
10704
+ return calendarDoc.data();
10705
+ }
10706
+ async function getPatientSyncedCalendarsUtil(db, patientId) {
10707
+ const calendarsRef = collection22(
10708
+ db,
10709
+ `patients/${patientId}/${SYNCED_CALENDARS_COLLECTION}`
10710
+ );
10711
+ const q = query22(calendarsRef, orderBy11("createdAt", "desc"));
10712
+ const querySnapshot = await getDocs22(q);
10713
+ return querySnapshot.docs.map((doc32) => doc32.data());
10714
+ }
10715
+ async function getClinicSyncedCalendarUtil(db, clinicId, calendarId) {
10716
+ const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
10717
+ const calendarDoc = await getDoc24(calendarRef);
10718
+ if (!calendarDoc.exists()) {
10719
+ return null;
10720
+ }
10721
+ return calendarDoc.data();
10722
+ }
10723
+ async function getClinicSyncedCalendarsUtil(db, clinicId) {
10724
+ const calendarsRef = collection22(
10725
+ db,
10726
+ `clinics/${clinicId}/${SYNCED_CALENDARS_COLLECTION}`
10727
+ );
10728
+ const q = query22(calendarsRef, orderBy11("createdAt", "desc"));
10729
+ const querySnapshot = await getDocs22(q);
10730
+ return querySnapshot.docs.map((doc32) => doc32.data());
10731
+ }
10732
+ async function updatePractitionerSyncedCalendarUtil(db, practitionerId, calendarId, updateData) {
10733
+ const calendarRef = getPractitionerSyncedCalendarDocRef(
10734
+ db,
10735
+ practitionerId,
10736
+ calendarId
10737
+ );
10738
+ const updates = {
10739
+ ...updateData,
10740
+ updatedAt: serverTimestamp19()
10741
+ };
10742
+ await updateDoc21(calendarRef, updates);
10743
+ const updatedDoc = await getDoc24(calendarRef);
10744
+ if (!updatedDoc.exists()) {
10745
+ throw new Error("Synced calendar not found after update");
10746
+ }
10747
+ return updatedDoc.data();
10748
+ }
10749
+ async function updatePatientSyncedCalendarUtil(db, patientId, calendarId, updateData) {
10750
+ const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
10751
+ const updates = {
10752
+ ...updateData,
10753
+ updatedAt: serverTimestamp19()
10754
+ };
10755
+ await updateDoc21(calendarRef, updates);
10756
+ const updatedDoc = await getDoc24(calendarRef);
10757
+ if (!updatedDoc.exists()) {
10758
+ throw new Error("Synced calendar not found after update");
10759
+ }
10760
+ return updatedDoc.data();
10761
+ }
10762
+ async function updateClinicSyncedCalendarUtil(db, clinicId, calendarId, updateData) {
10763
+ const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
10764
+ const updates = {
10765
+ ...updateData,
10766
+ updatedAt: serverTimestamp19()
10767
+ };
10768
+ await updateDoc21(calendarRef, updates);
10769
+ const updatedDoc = await getDoc24(calendarRef);
10770
+ if (!updatedDoc.exists()) {
10771
+ throw new Error("Synced calendar not found after update");
10772
+ }
10773
+ return updatedDoc.data();
10774
+ }
10775
+ async function deletePractitionerSyncedCalendarUtil(db, practitionerId, calendarId) {
10776
+ const calendarRef = getPractitionerSyncedCalendarDocRef(
10777
+ db,
10778
+ practitionerId,
10779
+ calendarId
10780
+ );
10781
+ await deleteDoc13(calendarRef);
10782
+ }
10783
+ async function deletePatientSyncedCalendarUtil(db, patientId, calendarId) {
10784
+ const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
10785
+ await deleteDoc13(calendarRef);
10786
+ }
10787
+ async function deleteClinicSyncedCalendarUtil(db, clinicId, calendarId) {
10788
+ const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
10789
+ await deleteDoc13(calendarRef);
10790
+ }
10791
+ async function updateLastSyncedTimestampUtil(db, entityType, entityId, calendarId) {
10792
+ const updateData = {
10793
+ lastSyncedAt: Timestamp24.now()
10794
+ };
10795
+ switch (entityType) {
10796
+ case "practitioner":
10797
+ return updatePractitionerSyncedCalendarUtil(
10798
+ db,
10799
+ entityId,
10800
+ calendarId,
10801
+ updateData
10802
+ );
10803
+ case "patient":
10804
+ return updatePatientSyncedCalendarUtil(
10805
+ db,
10806
+ entityId,
10807
+ calendarId,
10808
+ updateData
10809
+ );
10810
+ case "clinic":
10811
+ return updateClinicSyncedCalendarUtil(
10812
+ db,
10813
+ entityId,
10814
+ calendarId,
10815
+ updateData
10816
+ );
10817
+ default:
10818
+ throw new Error(`Invalid entity type: ${entityType}`);
10819
+ }
10820
+ }
10821
+
10822
+ // src/services/calendar/utils/google-calendar.utils.ts
10823
+ import { Timestamp as Timestamp25 } from "firebase/firestore";
10824
+ var GOOGLE_CALENDAR_API_URL = "https://www.googleapis.com/calendar/v3";
10825
+ var GOOGLE_OAUTH_URL = "https://oauth2.googleapis.com/token";
10826
+ var CLIENT_ID = "your-client-id";
10827
+ var CLIENT_SECRET = "your-client-secret";
10828
+ var REDIRECT_URI = "your-redirect-uri";
10829
+ async function makeRequest(method, url, headers, data, params) {
10830
+ const queryParams = params ? "?" + Object.entries(params).map(
10831
+ ([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`
10832
+ ).join("&") : "";
10833
+ const finalUrl = url + queryParams;
10834
+ const options = {
10835
+ method,
10836
+ headers,
10837
+ body: data ? JSON.stringify(data) : void 0
10838
+ };
10839
+ const response = await fetch(finalUrl, options);
10840
+ if (!response.ok) {
10841
+ const error = new Error(
10842
+ `Request failed with status ${response.status}`
10843
+ );
10844
+ error.response = response;
10845
+ throw error;
10846
+ }
10847
+ return response.json();
10848
+ }
10849
+ async function authenticateWithGoogleCalendarUtil(authCode) {
10850
+ try {
10851
+ const data = {
10852
+ code: authCode,
10853
+ client_id: CLIENT_ID,
10854
+ client_secret: CLIENT_SECRET,
10855
+ redirect_uri: REDIRECT_URI,
10856
+ grant_type: "authorization_code"
10857
+ };
10858
+ const response = await makeRequest(
10859
+ "post",
10860
+ GOOGLE_OAUTH_URL,
10861
+ { "Content-Type": "application/json" },
10862
+ data
10863
+ );
10864
+ return {
10865
+ accessToken: response.access_token,
10866
+ refreshToken: response.refresh_token,
10867
+ expiresIn: response.expires_in
10868
+ };
10869
+ } catch (error) {
10870
+ const apiError = error;
10871
+ console.error(
10872
+ "Error authenticating with Google Calendar:",
10873
+ apiError.message || "Unknown error"
10874
+ );
10875
+ throw new Error(
10876
+ `Failed to authenticate with Google Calendar: ${apiError.message || "Unknown error"}`
10877
+ );
10878
+ }
10879
+ }
10880
+ async function refreshGoogleCalendarTokenUtil(refreshToken) {
10881
+ try {
10882
+ const data = {
10883
+ refresh_token: refreshToken,
10884
+ client_id: CLIENT_ID,
10885
+ client_secret: CLIENT_SECRET,
10886
+ grant_type: "refresh_token"
10887
+ };
10888
+ const response = await makeRequest(
10889
+ "post",
10890
+ GOOGLE_OAUTH_URL,
10891
+ { "Content-Type": "application/json" },
10892
+ data
10893
+ );
10894
+ return {
10895
+ accessToken: response.access_token,
10896
+ expiresIn: response.expires_in
10897
+ };
10898
+ } catch (error) {
10899
+ const apiError = error;
10900
+ console.error(
10901
+ "Error refreshing Google Calendar token:",
10902
+ apiError.message || "Unknown error"
10903
+ );
10904
+ throw new Error(
10905
+ `Failed to refresh Google Calendar token: ${apiError.message || "Unknown error"}`
10906
+ );
10907
+ }
10908
+ }
10909
+ async function listGoogleCalendarsUtil(accessToken) {
10910
+ try {
10911
+ const response = await makeRequest(
10912
+ "get",
10913
+ `${GOOGLE_CALENDAR_API_URL}/users/me/calendarList`,
10914
+ { Authorization: `Bearer ${accessToken}` }
10915
+ );
10916
+ return response.items.map((calendar) => ({
10917
+ id: calendar.id,
10918
+ name: calendar.summary
10919
+ }));
10920
+ } catch (error) {
10921
+ const apiError = error;
10922
+ console.error(
10923
+ "Error listing Google Calendars:",
10924
+ apiError.message || "Unknown error"
10925
+ );
10926
+ throw new Error(
10927
+ `Failed to list Google Calendars: ${apiError.message || "Unknown error"}`
10928
+ );
10929
+ }
10930
+ }
10931
+ async function ensureValidToken(db, entityType, entityId, syncedCalendar) {
10932
+ const expiryTime = syncedCalendar.tokenExpiry.toDate();
10933
+ const now = /* @__PURE__ */ new Date();
10934
+ const fiveMinutesFromNow = new Date(now.getTime() + 5 * 60 * 1e3);
10935
+ if (expiryTime < fiveMinutesFromNow) {
10936
+ const { accessToken, expiresIn } = await refreshGoogleCalendarTokenUtil(
10937
+ syncedCalendar.refreshToken
10938
+ );
10939
+ const tokenExpiry = /* @__PURE__ */ new Date();
10940
+ tokenExpiry.setSeconds(tokenExpiry.getSeconds() + expiresIn);
10941
+ const updateData = {
10942
+ accessToken,
10943
+ tokenExpiry: Timestamp25.fromDate(tokenExpiry)
10944
+ };
10945
+ switch (entityType) {
10946
+ case "practitioner":
10947
+ await updatePractitionerSyncedCalendarUtil(
10948
+ db,
10949
+ entityId,
10950
+ syncedCalendar.id,
10951
+ updateData
10952
+ );
10953
+ break;
10954
+ case "patient":
10955
+ await updatePatientSyncedCalendarUtil(
10956
+ db,
10957
+ entityId,
10958
+ syncedCalendar.id,
10959
+ updateData
10960
+ );
10961
+ break;
10962
+ case "clinic":
10963
+ await updateClinicSyncedCalendarUtil(
10964
+ db,
10965
+ entityId,
10966
+ syncedCalendar.id,
10967
+ updateData
10968
+ );
10969
+ break;
10970
+ }
10971
+ return accessToken;
10972
+ }
10973
+ return syncedCalendar.accessToken;
10974
+ }
10975
+ async function syncEventsToGoogleCalendarUtil(db, entityType, entityId, syncedCalendar, events, existingSyncId) {
10976
+ var _a, _b;
10977
+ try {
10978
+ const { accessToken } = await refreshGoogleCalendarTokenUtil(
10979
+ syncedCalendar.refreshToken
10980
+ );
10981
+ let syncedCount = 0;
10982
+ const errors = [];
10983
+ const eventIds = [];
10984
+ for (const event of events) {
10985
+ try {
10986
+ if (event.syncStatus === "external" /* EXTERNAL */) {
10987
+ continue;
10988
+ }
10989
+ if (entityType === "practitioner" && event.status !== "confirmed" /* CONFIRMED */) {
10990
+ continue;
10991
+ }
10992
+ if (entityType === "patient" && (event.status === "canceled" /* CANCELED */ || event.status === "rejected" /* REJECTED */)) {
10993
+ continue;
10994
+ }
10995
+ if (entityType === "clinic") {
10996
+ continue;
10997
+ }
10998
+ const googleEvent = convertCalendarEventToGoogleEventUtil(event);
10999
+ const headers = {
11000
+ Authorization: `Bearer ${accessToken}`,
11001
+ "Content-Type": "application/json"
11002
+ };
11003
+ let responseId = "";
11004
+ if (existingSyncId) {
11005
+ const response = await makeRequest(
11006
+ "put",
11007
+ `${GOOGLE_CALENDAR_API_URL}/calendars/${syncedCalendar.calendarId}/events/${existingSyncId}`,
11008
+ headers,
11009
+ googleEvent
11010
+ );
11011
+ responseId = response.id;
11012
+ } else {
11013
+ const existingSync = (_a = event.syncedCalendarEventId) == null ? void 0 : _a.find(
11014
+ (sync) => sync.syncedCalendarProvider === "google" /* GOOGLE */ && // We should check if this is the same calendar we're syncing with, but that information isn't stored
11015
+ // For now, we'll just use the first Google Calendar sync ID
11016
+ sync.syncedCalendarProvider === syncedCalendar.provider
11017
+ );
11018
+ if (existingSync) {
11019
+ const response = await makeRequest(
11020
+ "put",
11021
+ `${GOOGLE_CALENDAR_API_URL}/calendars/${syncedCalendar.calendarId}/events/${existingSync.eventId}`,
11022
+ headers,
11023
+ googleEvent
11024
+ );
11025
+ responseId = response.id;
11026
+ } else {
11027
+ const response = await makeRequest(
11028
+ "post",
11029
+ `${GOOGLE_CALENDAR_API_URL}/calendars/${syncedCalendar.calendarId}/events`,
11030
+ headers,
11031
+ googleEvent
11032
+ );
11033
+ responseId = response.id;
11034
+ }
11035
+ }
11036
+ if (responseId) {
11037
+ eventIds.push(responseId);
11038
+ syncedCount++;
11039
+ }
11040
+ } catch (error) {
11041
+ const apiError = error;
11042
+ errors.push({
11043
+ eventId: event.id,
11044
+ error: apiError.message || "Unknown error",
11045
+ status: (_b = apiError.response) == null ? void 0 : _b.status
11046
+ });
11047
+ }
11048
+ }
11049
+ await updateLastSyncedTimestampUtil(
11050
+ db,
11051
+ entityType,
11052
+ entityId,
11053
+ syncedCalendar.id
11054
+ );
11055
+ return {
11056
+ success: errors.length === 0,
11057
+ syncedEvents: syncedCount,
11058
+ errors,
11059
+ eventIds
11060
+ };
11061
+ } catch (error) {
11062
+ console.error("Error syncing with Google Calendar:", error);
11063
+ return {
11064
+ success: false,
11065
+ syncedEvents: 0,
11066
+ errors: [{ error: error.message || "Unknown error" }],
11067
+ eventIds: []
11068
+ };
11069
+ }
11070
+ }
11071
+ async function fetchEventsFromGoogleCalendarUtil(db, entityType, entityId, syncedCalendar, startDate, endDate) {
11072
+ try {
11073
+ const accessToken = await ensureValidToken(
11074
+ db,
11075
+ entityType,
11076
+ entityId,
11077
+ syncedCalendar
11078
+ );
11079
+ const timeMin = startDate.toISOString();
11080
+ const timeMax = endDate.toISOString();
11081
+ const response = await makeRequest(
11082
+ "get",
11083
+ `${GOOGLE_CALENDAR_API_URL}/calendars/${syncedCalendar.calendarId}/events`,
11084
+ { Authorization: `Bearer ${accessToken}` },
11085
+ void 0,
11086
+ {
11087
+ timeMin,
11088
+ timeMax,
11089
+ singleEvents: "true",
11090
+ orderBy: "startTime"
11091
+ }
11092
+ );
11093
+ await updateLastSyncedTimestampUtil(
11094
+ db,
11095
+ entityType,
11096
+ entityId,
11097
+ syncedCalendar.id
11098
+ );
11099
+ return response.items;
11100
+ } catch (error) {
11101
+ const apiError = error;
11102
+ console.error(
11103
+ "Error fetching events from Google Calendar:",
11104
+ apiError.message || "Unknown error"
11105
+ );
11106
+ throw new Error(
11107
+ `Failed to fetch events from Google Calendar: ${apiError.message || "Unknown error"}`
11108
+ );
11109
+ }
11110
+ }
11111
+ function convertGoogleEventToCalendarEventUtil(googleEvent, entityId, entityType) {
11112
+ const start = googleEvent.start.dateTime ? new Date(googleEvent.start.dateTime) : new Date(googleEvent.start.date);
11113
+ const end = googleEvent.end.dateTime ? new Date(googleEvent.end.dateTime) : new Date(googleEvent.end.date);
11114
+ const calendarEvent = {
11115
+ eventName: googleEvent.summary || "External Event",
11116
+ eventLocation: googleEvent.location,
11117
+ eventTime: {
11118
+ start: Timestamp25.fromDate(start),
11119
+ end: Timestamp25.fromDate(end)
11120
+ },
11121
+ description: googleEvent.description || "",
11122
+ // External events are always set as CONFIRMED - status updates will happen externally
11123
+ status: "confirmed" /* CONFIRMED */,
11124
+ // All external events are marked as EXTERNAL to indicate they originated outside our system
11125
+ syncStatus: "external" /* EXTERNAL */,
11126
+ // All external events are treated as BLOCKING events
11127
+ eventType: "blocking" /* BLOCKING */,
11128
+ // Store the original Google Calendar event ID
11129
+ syncedCalendarEventId: [
11130
+ {
11131
+ eventId: googleEvent.id,
11132
+ syncedCalendarProvider: "google" /* GOOGLE */,
11133
+ syncedAt: Timestamp25.now()
11134
+ }
11135
+ ]
11136
+ };
11137
+ switch (entityType) {
11138
+ case "practitioner":
11139
+ calendarEvent.practitionerProfileId = entityId;
11140
+ break;
11141
+ case "patient":
11142
+ calendarEvent.patientProfileId = entityId;
11143
+ break;
11144
+ case "clinic":
11145
+ calendarEvent.clinicBranchId = entityId;
11146
+ break;
11147
+ }
11148
+ return calendarEvent;
11149
+ }
11150
+ function convertCalendarEventToGoogleEventUtil(calendarEvent) {
11151
+ const googleEvent = {
11152
+ summary: calendarEvent.eventName,
11153
+ location: calendarEvent.eventLocation,
11154
+ description: calendarEvent.description,
11155
+ start: {
11156
+ dateTime: calendarEvent.eventTime.start.toDate().toISOString(),
11157
+ timeZone: "UTC"
11158
+ },
11159
+ end: {
11160
+ dateTime: calendarEvent.eventTime.end.toDate().toISOString(),
11161
+ timeZone: "UTC"
11162
+ },
11163
+ // Add reminders
11164
+ reminders: {
11165
+ useDefault: false,
11166
+ overrides: [
11167
+ { method: "email", minutes: 24 * 60 },
11168
+ // 1 day before
11169
+ { method: "popup", minutes: 30 }
11170
+ // 30 minutes before
11171
+ ]
11172
+ }
11173
+ };
11174
+ switch (calendarEvent.status) {
11175
+ case "confirmed" /* CONFIRMED */:
11176
+ googleEvent.status = "confirmed";
11177
+ break;
11178
+ case "canceled" /* CANCELED */:
11179
+ googleEvent.status = "cancelled";
11180
+ break;
11181
+ case "pending" /* PENDING */:
11182
+ googleEvent.status = "tentative";
11183
+ break;
11184
+ default:
11185
+ googleEvent.status = "confirmed";
11186
+ }
11187
+ if (calendarEvent.eventType === "appointment" /* APPOINTMENT */) {
11188
+ googleEvent.attendees = [];
11189
+ if (calendarEvent.practitionerProfileId) {
11190
+ googleEvent.attendees.push({
11191
+ email: "practitioner@example.com",
11192
+ // This would be fetched from the practitioner profile
11193
+ displayName: "Dr. Practitioner",
11194
+ // This would be fetched from the practitioner profile
11195
+ responseStatus: "accepted"
11196
+ });
11197
+ }
11198
+ if (calendarEvent.patientProfileId) {
11199
+ googleEvent.attendees.push({
11200
+ email: "patient@example.com",
11201
+ // This would be fetched from the patient profile
11202
+ displayName: "Patient",
11203
+ // This would be fetched from the patient profile
11204
+ responseStatus: "needsAction"
11205
+ });
11206
+ }
11207
+ }
11208
+ return googleEvent;
11209
+ }
11210
+ async function deleteGoogleCalendarEventUtil(db, entityType, entityId, syncedCalendar, eventId) {
11211
+ try {
11212
+ const accessToken = await ensureValidToken(
11213
+ db,
11214
+ entityType,
11215
+ entityId,
11216
+ syncedCalendar
11217
+ );
11218
+ await makeRequest(
11219
+ "delete",
11220
+ `${GOOGLE_CALENDAR_API_URL}/calendars/${syncedCalendar.calendarId}/events/${eventId}`,
11221
+ { Authorization: `Bearer ${accessToken}` }
11222
+ );
11223
+ return true;
11224
+ } catch (error) {
11225
+ const apiError = error;
11226
+ console.error(
11227
+ "Error deleting event from Google Calendar:",
11228
+ apiError.message || "Unknown error"
11229
+ );
11230
+ throw new Error(
11231
+ `Failed to delete event from Google Calendar: ${apiError.message || "Unknown error"}`
11232
+ );
11233
+ }
11234
+ }
11235
+ function getGoogleCalendarOAuthUrlUtil(scopes = ["https://www.googleapis.com/auth/calendar"]) {
11236
+ const scopeString = encodeURIComponent(scopes.join(" "));
11237
+ return `https://accounts.google.com/o/oauth2/v2/auth?client_id=${CLIENT_ID}&redirect_uri=${encodeURIComponent(
11238
+ REDIRECT_URI
11239
+ )}&response_type=code&scope=${scopeString}&access_type=offline&prompt=consent`;
11240
+ }
11241
+
11242
+ // src/services/calendar/synced-calendars.service.ts
11243
+ var SyncedCalendarsService = class extends BaseService {
11244
+ /**
11245
+ * Creates a new SyncedCalendarsService instance
11246
+ * @param db - Firestore instance
11247
+ * @param auth - Firebase Auth instance
11248
+ * @param app - Firebase App instance
11249
+ */
11250
+ constructor(db, auth, app) {
11251
+ super(db, auth, app);
11252
+ }
11253
+ // ===== Practitioner Synced Calendars =====
11254
+ /**
11255
+ * Creates a synced calendar for a practitioner
11256
+ * @param practitionerId - ID of the practitioner
11257
+ * @param calendarData - Synced calendar data
11258
+ * @returns Created synced calendar
11259
+ */
11260
+ async createPractitionerSyncedCalendar(practitionerId, calendarData) {
11261
+ return createPractitionerSyncedCalendarUtil(
11262
+ this.db,
11263
+ practitionerId,
11264
+ calendarData,
11265
+ this.generateId.bind(this)
11266
+ );
11267
+ }
11268
+ /**
11269
+ * Gets a synced calendar for a practitioner
11270
+ * @param practitionerId - ID of the practitioner
11271
+ * @param calendarId - ID of the synced calendar
11272
+ * @returns Synced calendar or null if not found
11273
+ */
11274
+ async getPractitionerSyncedCalendar(practitionerId, calendarId) {
11275
+ return getPractitionerSyncedCalendarUtil(
11276
+ this.db,
11277
+ practitionerId,
11278
+ calendarId
11279
+ );
11280
+ }
11281
+ /**
11282
+ * Gets all synced calendars for a practitioner
11283
+ * @param practitionerId - ID of the practitioner
11284
+ * @returns Array of synced calendars
11285
+ */
11286
+ async getPractitionerSyncedCalendars(practitionerId) {
11287
+ return getPractitionerSyncedCalendarsUtil(this.db, practitionerId);
11288
+ }
11289
+ /**
11290
+ * Updates a synced calendar for a practitioner
11291
+ * @param practitionerId - ID of the practitioner
11292
+ * @param calendarId - ID of the synced calendar
11293
+ * @param updateData - Data to update
11294
+ * @returns Updated synced calendar
11295
+ */
11296
+ async updatePractitionerSyncedCalendar(practitionerId, calendarId, updateData) {
11297
+ return updatePractitionerSyncedCalendarUtil(
11298
+ this.db,
11299
+ practitionerId,
11300
+ calendarId,
11301
+ updateData
11302
+ );
11303
+ }
11304
+ /**
11305
+ * Deletes a synced calendar for a practitioner
11306
+ * @param practitionerId - ID of the practitioner
11307
+ * @param calendarId - ID of the synced calendar
11308
+ */
11309
+ async deletePractitionerSyncedCalendar(practitionerId, calendarId) {
11310
+ return deletePractitionerSyncedCalendarUtil(
11311
+ this.db,
11312
+ practitionerId,
11313
+ calendarId
11314
+ );
11315
+ }
11316
+ // ===== Patient Synced Calendars =====
11317
+ /**
11318
+ * Creates a synced calendar for a patient
11319
+ * @param patientId - ID of the patient
11320
+ * @param calendarData - Synced calendar data
11321
+ * @returns Created synced calendar
11322
+ */
11323
+ async createPatientSyncedCalendar(patientId, calendarData) {
11324
+ return createPatientSyncedCalendarUtil(
11325
+ this.db,
11326
+ patientId,
11327
+ calendarData,
11328
+ this.generateId.bind(this)
11329
+ );
11330
+ }
11331
+ /**
11332
+ * Gets a synced calendar for a patient
11333
+ * @param patientId - ID of the patient
11334
+ * @param calendarId - ID of the synced calendar
11335
+ * @returns Synced calendar or null if not found
11336
+ */
11337
+ async getPatientSyncedCalendar(patientId, calendarId) {
11338
+ return getPatientSyncedCalendarUtil(this.db, patientId, calendarId);
11339
+ }
11340
+ /**
11341
+ * Gets all synced calendars for a patient
11342
+ * @param patientId - ID of the patient
11343
+ * @returns Array of synced calendars
11344
+ */
11345
+ async getPatientSyncedCalendars(patientId) {
11346
+ return getPatientSyncedCalendarsUtil(this.db, patientId);
11347
+ }
11348
+ /**
11349
+ * Updates a synced calendar for a patient
11350
+ * @param patientId - ID of the patient
11351
+ * @param calendarId - ID of the synced calendar
11352
+ * @param updateData - Data to update
11353
+ * @returns Updated synced calendar
11354
+ */
11355
+ async updatePatientSyncedCalendar(patientId, calendarId, updateData) {
11356
+ return updatePatientSyncedCalendarUtil(
11357
+ this.db,
11358
+ patientId,
11359
+ calendarId,
11360
+ updateData
11361
+ );
11362
+ }
11363
+ /**
11364
+ * Deletes a synced calendar for a patient
11365
+ * @param patientId - ID of the patient
11366
+ * @param calendarId - ID of the synced calendar
11367
+ */
11368
+ async deletePatientSyncedCalendar(patientId, calendarId) {
11369
+ return deletePatientSyncedCalendarUtil(this.db, patientId, calendarId);
11370
+ }
11371
+ // ===== Clinic Synced Calendars =====
11372
+ /**
11373
+ * Creates a synced calendar for a clinic
11374
+ * @param clinicId - ID of the clinic
11375
+ * @param calendarData - Synced calendar data
11376
+ * @returns Created synced calendar
11377
+ */
11378
+ async createClinicSyncedCalendar(clinicId, calendarData) {
11379
+ return createClinicSyncedCalendarUtil(
11380
+ this.db,
11381
+ clinicId,
11382
+ calendarData,
11383
+ this.generateId.bind(this)
11384
+ );
11385
+ }
11386
+ /**
11387
+ * Gets a synced calendar for a clinic
11388
+ * @param clinicId - ID of the clinic
11389
+ * @param calendarId - ID of the synced calendar
11390
+ * @returns Synced calendar or null if not found
11391
+ */
11392
+ async getClinicSyncedCalendar(clinicId, calendarId) {
11393
+ return getClinicSyncedCalendarUtil(this.db, clinicId, calendarId);
11394
+ }
11395
+ /**
11396
+ * Gets all synced calendars for a clinic
11397
+ * @param clinicId - ID of the clinic
11398
+ * @returns Array of synced calendars
11399
+ */
11400
+ async getClinicSyncedCalendars(clinicId) {
11401
+ return getClinicSyncedCalendarsUtil(this.db, clinicId);
11402
+ }
11403
+ /**
11404
+ * Updates a synced calendar for a clinic
11405
+ * @param clinicId - ID of the clinic
11406
+ * @param calendarId - ID of the synced calendar
11407
+ * @param updateData - Data to update
11408
+ * @returns Updated synced calendar
11409
+ */
11410
+ async updateClinicSyncedCalendar(clinicId, calendarId, updateData) {
11411
+ return updateClinicSyncedCalendarUtil(
11412
+ this.db,
11413
+ clinicId,
11414
+ calendarId,
11415
+ updateData
11416
+ );
11417
+ }
11418
+ /**
11419
+ * Deletes a synced calendar for a clinic
11420
+ * @param clinicId - ID of the clinic
11421
+ * @param calendarId - ID of the synced calendar
11422
+ */
11423
+ async deleteClinicSyncedCalendar(clinicId, calendarId) {
11424
+ return deleteClinicSyncedCalendarUtil(this.db, clinicId, calendarId);
11425
+ }
11426
+ // ===== Google Calendar Integration =====
11427
+ /**
11428
+ * Gets the OAuth URL for Google Calendar
11429
+ * @param scopes - OAuth scopes to request
11430
+ * @returns OAuth URL
11431
+ */
11432
+ getGoogleCalendarOAuthUrl(scopes = ["https://www.googleapis.com/auth/calendar"]) {
11433
+ return getGoogleCalendarOAuthUrlUtil(scopes);
11434
+ }
11435
+ /**
11436
+ * Authenticates with Google Calendar using an authorization code
11437
+ * @param authCode - Authorization code from Google OAuth
11438
+ * @returns Access token, refresh token, and expiration time
11439
+ */
11440
+ async authenticateWithGoogleCalendar(authCode) {
11441
+ return authenticateWithGoogleCalendarUtil(authCode);
11442
+ }
11443
+ /**
11444
+ * Lists available Google Calendars for a user
11445
+ * @param accessToken - Google API access token
11446
+ * @returns List of available calendars
11447
+ */
11448
+ async listGoogleCalendars(accessToken) {
11449
+ return listGoogleCalendarsUtil(accessToken);
11450
+ }
11451
+ /**
11452
+ * Syncs events from our system to Google Calendar for a practitioner
11453
+ * @param practitionerId - ID of the practitioner
11454
+ * @param calendarId - ID of the synced calendar
11455
+ * @param events - Events to sync
11456
+ * @param existingSyncId - Optional existing sync ID for updating an event
11457
+ * @returns Result of the sync operation
11458
+ */
11459
+ async syncPractitionerEventsToGoogleCalendar(practitionerId, calendarId, events, existingSyncId) {
11460
+ const syncedCalendar = await this.getPractitionerSyncedCalendar(
11461
+ practitionerId,
11462
+ calendarId
11463
+ );
11464
+ if (!syncedCalendar) {
11465
+ throw new Error("Synced calendar not found");
11466
+ }
11467
+ return syncEventsToGoogleCalendarUtil(
11468
+ this.db,
11469
+ "practitioner",
11470
+ practitionerId,
11471
+ syncedCalendar,
11472
+ events,
11473
+ existingSyncId
11474
+ );
11475
+ }
11476
+ /**
11477
+ * Syncs events from our system to Google Calendar for a patient
11478
+ * @param patientId - ID of the patient
11479
+ * @param calendarId - ID of the synced calendar
11480
+ * @param events - Events to sync
11481
+ * @param existingSyncId - Optional existing sync ID for updating an event
11482
+ * @returns Result of the sync operation
11483
+ */
11484
+ async syncPatientEventsToGoogleCalendar(patientId, calendarId, events, existingSyncId) {
11485
+ const syncedCalendar = await this.getPatientSyncedCalendar(
11486
+ patientId,
11487
+ calendarId
11488
+ );
11489
+ if (!syncedCalendar) {
11490
+ throw new Error("Synced calendar not found");
11491
+ }
11492
+ return syncEventsToGoogleCalendarUtil(
11493
+ this.db,
11494
+ "patient",
11495
+ patientId,
11496
+ syncedCalendar,
11497
+ events,
11498
+ existingSyncId
11499
+ );
11500
+ }
11501
+ /**
11502
+ * Syncs events from our system to Google Calendar for a clinic
11503
+ * @param clinicId - ID of the clinic
11504
+ * @param calendarId - ID of the synced calendar
11505
+ * @param events - Events to sync
11506
+ * @returns Result of the sync operation
11507
+ */
11508
+ async syncClinicEventsToGoogleCalendar(clinicId, calendarId, events) {
11509
+ const syncedCalendar = await this.getClinicSyncedCalendar(
11510
+ clinicId,
11511
+ calendarId
11512
+ );
11513
+ if (!syncedCalendar) {
11514
+ throw new Error("Synced calendar not found");
11515
+ }
11516
+ return syncEventsToGoogleCalendarUtil(
11517
+ this.db,
11518
+ "clinic",
11519
+ clinicId,
11520
+ syncedCalendar,
11521
+ events
11522
+ );
11523
+ }
11524
+ /**
11525
+ * Fetches events from Google Calendar for a practitioner
11526
+ * @param practitionerId - ID of the practitioner
11527
+ * @param calendarId - ID of the synced calendar
11528
+ * @param startDate - Start date for fetching events
11529
+ * @param endDate - End date for fetching events
11530
+ * @returns Events fetched from Google Calendar
11531
+ */
11532
+ async fetchEventsFromPractitionerGoogleCalendar(practitionerId, calendarId, startDate, endDate) {
11533
+ const syncedCalendar = await this.getPractitionerSyncedCalendar(
11534
+ practitionerId,
11535
+ calendarId
11536
+ );
11537
+ if (!syncedCalendar) {
11538
+ throw new Error("Synced calendar not found");
11539
+ }
11540
+ return fetchEventsFromGoogleCalendarUtil(
11541
+ this.db,
11542
+ "practitioner",
11543
+ practitionerId,
11544
+ syncedCalendar,
11545
+ startDate,
11546
+ endDate
11547
+ );
11548
+ }
11549
+ /**
11550
+ * Fetches events from Google Calendar for a patient
11551
+ * @param patientId - ID of the patient
11552
+ * @param calendarId - ID of the synced calendar
11553
+ * @param startDate - Start date for fetching events
11554
+ * @param endDate - End date for fetching events
11555
+ * @returns Events fetched from Google Calendar
11556
+ */
11557
+ async fetchEventsFromPatientGoogleCalendar(patientId, calendarId, startDate, endDate) {
11558
+ const syncedCalendar = await this.getPatientSyncedCalendar(
11559
+ patientId,
11560
+ calendarId
11561
+ );
11562
+ if (!syncedCalendar) {
11563
+ throw new Error("Synced calendar not found");
11564
+ }
11565
+ return fetchEventsFromGoogleCalendarUtil(
11566
+ this.db,
11567
+ "patient",
11568
+ patientId,
11569
+ syncedCalendar,
11570
+ startDate,
11571
+ endDate
11572
+ );
11573
+ }
11574
+ /**
11575
+ * Fetches events from Google Calendar for a clinic
11576
+ * @param clinicId - ID of the clinic
11577
+ * @param calendarId - ID of the synced calendar
11578
+ * @param startDate - Start date for fetching events
11579
+ * @param endDate - End date for fetching events
11580
+ * @returns Events fetched from Google Calendar
11581
+ */
11582
+ async fetchEventsFromClinicGoogleCalendar(clinicId, calendarId, startDate, endDate) {
11583
+ const syncedCalendar = await this.getClinicSyncedCalendar(
11584
+ clinicId,
11585
+ calendarId
11586
+ );
11587
+ if (!syncedCalendar) {
11588
+ throw new Error("Synced calendar not found");
11589
+ }
11590
+ return fetchEventsFromGoogleCalendarUtil(
11591
+ this.db,
11592
+ "clinic",
11593
+ clinicId,
11594
+ syncedCalendar,
11595
+ startDate,
11596
+ endDate
11597
+ );
11598
+ }
11599
+ /**
11600
+ * Deletes an event from Google Calendar for a practitioner
11601
+ * @param practitionerId - ID of the practitioner
11602
+ * @param calendarId - ID of the synced calendar
11603
+ * @param eventId - ID of the event in Google Calendar
11604
+ * @returns Success status
11605
+ */
11606
+ async deletePractitionerGoogleCalendarEvent(practitionerId, calendarId, eventId) {
11607
+ const syncedCalendar = await this.getPractitionerSyncedCalendar(
11608
+ practitionerId,
11609
+ calendarId
11610
+ );
11611
+ if (!syncedCalendar) {
11612
+ throw new Error("Synced calendar not found");
11613
+ }
11614
+ return deleteGoogleCalendarEventUtil(
11615
+ this.db,
11616
+ "practitioner",
11617
+ practitionerId,
11618
+ syncedCalendar,
11619
+ eventId
11620
+ );
11621
+ }
11622
+ /**
11623
+ * Deletes an event from Google Calendar for a patient
11624
+ * @param patientId - ID of the patient
11625
+ * @param calendarId - ID of the synced calendar
11626
+ * @param eventId - ID of the event in Google Calendar
11627
+ * @returns Success status
11628
+ */
11629
+ async deletePatientGoogleCalendarEvent(patientId, calendarId, eventId) {
11630
+ const syncedCalendar = await this.getPatientSyncedCalendar(
11631
+ patientId,
11632
+ calendarId
11633
+ );
11634
+ if (!syncedCalendar) {
11635
+ throw new Error("Synced calendar not found");
11636
+ }
11637
+ return deleteGoogleCalendarEventUtil(
11638
+ this.db,
11639
+ "patient",
11640
+ patientId,
11641
+ syncedCalendar,
11642
+ eventId
11643
+ );
11644
+ }
11645
+ /**
11646
+ * Deletes an event from Google Calendar for a clinic
11647
+ * @param clinicId - ID of the clinic
11648
+ * @param calendarId - ID of the synced calendar
11649
+ * @param eventId - ID of the event in Google Calendar
11650
+ * @returns Success status
11651
+ */
11652
+ async deleteClinicGoogleCalendarEvent(clinicId, calendarId, eventId) {
11653
+ const syncedCalendar = await this.getClinicSyncedCalendar(
11654
+ clinicId,
11655
+ calendarId
11656
+ );
11657
+ if (!syncedCalendar) {
11658
+ throw new Error("Synced calendar not found");
11659
+ }
11660
+ return deleteGoogleCalendarEventUtil(
11661
+ this.db,
11662
+ "clinic",
11663
+ clinicId,
11664
+ syncedCalendar,
11665
+ eventId
11666
+ );
11667
+ }
11668
+ /**
11669
+ * Converts Google Calendar events to our system's format for a practitioner
11670
+ * @param practitionerId - ID of the practitioner
11671
+ * @param googleEvents - Google Calendar events
11672
+ * @returns Converted calendar events
11673
+ */
11674
+ convertGoogleEventsToPractitionerEvents(practitionerId, googleEvents) {
11675
+ return googleEvents.map(
11676
+ (event) => convertGoogleEventToCalendarEventUtil(
11677
+ event,
11678
+ practitionerId,
11679
+ "practitioner"
11680
+ )
11681
+ );
11682
+ }
11683
+ /**
11684
+ * Converts Google Calendar events to our system's format for a patient
11685
+ * @param patientId - ID of the patient
11686
+ * @param googleEvents - Google Calendar events
11687
+ * @returns Converted calendar events
11688
+ */
11689
+ convertGoogleEventsToPatientEvents(patientId, googleEvents) {
11690
+ return googleEvents.map(
11691
+ (event) => convertGoogleEventToCalendarEventUtil(event, patientId, "patient")
11692
+ );
11693
+ }
11694
+ /**
11695
+ * Converts Google Calendar events to our system's format for a clinic
11696
+ * @param clinicId - ID of the clinic
11697
+ * @param googleEvents - Google Calendar events
11698
+ * @returns Converted calendar events
11699
+ */
11700
+ convertGoogleEventsToClinicEvents(clinicId, googleEvents) {
11701
+ return googleEvents.map(
11702
+ (event) => convertGoogleEventToCalendarEventUtil(event, clinicId, "clinic")
11703
+ );
11704
+ }
11705
+ /**
11706
+ * Fetches a single event from Google Calendar for a practitioner
11707
+ * @param practitionerId - ID of the practitioner
11708
+ * @param calendarId - ID of the synced calendar
11709
+ * @param eventId - ID of the event in Google Calendar
11710
+ * @returns The event data or null if not found
11711
+ */
11712
+ async fetchEventFromPractitionerGoogleCalendar(practitionerId, calendarId, eventId) {
11713
+ var _a;
11714
+ const syncedCalendar = await this.getPractitionerSyncedCalendar(
11715
+ practitionerId,
11716
+ calendarId
11717
+ );
11718
+ if (!syncedCalendar) {
11719
+ throw new Error("Synced calendar not found");
11720
+ }
11721
+ try {
11722
+ const { accessToken } = await refreshGoogleCalendarTokenUtil(
11723
+ syncedCalendar.refreshToken
11724
+ );
11725
+ const response = await makeRequest(
11726
+ "get",
11727
+ `${GOOGLE_CALENDAR_API_URL}/calendars/${syncedCalendar.calendarId}/events/${eventId}`,
11728
+ { Authorization: `Bearer ${accessToken}` }
11729
+ );
11730
+ await updateLastSyncedTimestampUtil(
11731
+ this.db,
11732
+ "practitioner",
11733
+ practitionerId,
11734
+ syncedCalendar.id
11735
+ );
11736
+ return response;
11737
+ } catch (error) {
11738
+ if (((_a = error.response) == null ? void 0 : _a.status) === 404) {
11739
+ return null;
11740
+ }
11741
+ console.error(
11742
+ `Error fetching event from Google Calendar: ${error.message}`
11743
+ );
11744
+ throw error;
11745
+ }
11746
+ }
11747
+ };
11748
+
11749
+ // src/services/calendar/calendar.v2.service.ts
11750
+ var MIN_APPOINTMENT_DURATION = 15;
11751
+ var CalendarServiceV2 = class extends BaseService {
11752
+ /**
11753
+ * Creates a new CalendarService instance
11754
+ * @param db - Firestore instance
11755
+ * @param auth - Firebase Auth instance
11756
+ * @param app - Firebase App instance
11757
+ */
11758
+ constructor(db, auth, app) {
11759
+ super(db, auth, app);
11760
+ this.syncedCalendarsService = new SyncedCalendarsService(db, auth, app);
11761
+ }
11762
+ // #region Public API Methods
11763
+ /**
11764
+ * Creates a new appointment with proper validation and scheduling rules
11765
+ * @param params - Appointment creation parameters
11766
+ * @returns Created calendar event
11767
+ */
11768
+ async createAppointment(params) {
11769
+ await this.validateAppointmentParams(params);
11770
+ await this.validateClinicWorkingHours(params.clinicId, params.eventTime);
11771
+ await this.validateDoctorAvailability(
11772
+ params.doctorId,
11773
+ params.eventTime,
11774
+ params.clinicId
11775
+ );
11776
+ const { clinicInfo, practitionerInfo, patientInfo } = await this.fetchProfileInfoCards(
11777
+ params.clinicId,
11778
+ params.doctorId,
11779
+ params.patientId
11780
+ );
11781
+ const appointmentData = {
11782
+ clinicBranchId: params.clinicId,
11783
+ clinicBranchInfo: clinicInfo,
11784
+ practitionerProfileId: params.doctorId,
11785
+ practitionerProfileInfo: practitionerInfo,
11786
+ patientProfileId: params.patientId,
11787
+ patientProfileInfo: patientInfo,
11788
+ procedureId: params.procedureId,
11789
+ eventLocation: params.eventLocation,
11790
+ eventName: "Appointment",
11791
+ // TODO: Add procedure name when procedure model is available
11792
+ eventTime: params.eventTime,
11793
+ description: params.description || "",
11794
+ status: "pending" /* PENDING */,
11795
+ syncStatus: "internal" /* INTERNAL */,
11796
+ eventType: "appointment" /* APPOINTMENT */
11797
+ };
11798
+ const appointment = await createAppointmentUtil2(
11799
+ this.db,
11800
+ params.clinicId,
11801
+ params.doctorId,
11802
+ params.patientId,
11803
+ appointmentData,
11804
+ this.generateId.bind(this)
11805
+ );
11806
+ await this.syncAppointmentWithExternalCalendars(appointment);
11807
+ return appointment;
11808
+ }
11809
+ /**
11810
+ * Updates an existing appointment
11811
+ * @param params - Appointment update parameters
11812
+ * @returns Updated calendar event
11813
+ */
11814
+ async updateAppointment(params) {
11815
+ await this.validateUpdatePermissions(params);
11816
+ const updateData = {
11817
+ eventTime: params.eventTime,
11818
+ description: params.description,
11819
+ status: params.status
11820
+ };
11821
+ const appointment = await updateAppointmentUtil2(
11822
+ this.db,
11823
+ params.clinicId,
11824
+ params.doctorId,
11825
+ params.patientId,
11826
+ params.appointmentId,
11827
+ updateData
11828
+ );
11829
+ await this.syncAppointmentWithExternalCalendars(appointment);
11830
+ return appointment;
11831
+ }
11832
+ /**
11833
+ * Gets available appointment slots for a doctor at a clinic
11834
+ * @param clinicId - ID of the clinic
11835
+ * @param doctorId - ID of the doctor
11836
+ * @param date - Date to check availability for
11837
+ * @returns Array of available time slots
11838
+ */
11839
+ async getAvailableSlots(clinicId, doctorId, date) {
11840
+ const workingHours = await this.getClinicWorkingHours(clinicId, date);
11841
+ const doctorSchedule = await this.getDoctorSchedule(doctorId, date);
11842
+ const existingAppointments = await this.getDoctorAppointments(
11843
+ doctorId,
11844
+ date
11845
+ );
11846
+ return this.calculateAvailableSlots(
11847
+ workingHours,
11848
+ doctorSchedule,
11849
+ existingAppointments
11850
+ );
11851
+ }
11852
+ /**
11853
+ * Confirms an appointment
11854
+ * @param appointmentId - ID of the appointment
11855
+ * @param clinicId - ID of the clinic
11856
+ * @returns Confirmed calendar event
11857
+ */
11858
+ async confirmAppointment(appointmentId, clinicId) {
11859
+ return this.updateAppointmentStatus(
11860
+ appointmentId,
11861
+ clinicId,
11862
+ "confirmed" /* CONFIRMED */
11863
+ );
11864
+ }
11865
+ /**
11866
+ * Rejects an appointment
11867
+ * @param appointmentId - ID of the appointment
11868
+ * @param clinicId - ID of the clinic
11869
+ * @returns Rejected calendar event
11870
+ */
11871
+ async rejectAppointment(appointmentId, clinicId) {
11872
+ return this.updateAppointmentStatus(
11873
+ appointmentId,
11874
+ clinicId,
11875
+ "rejected" /* REJECTED */
11876
+ );
11877
+ }
11878
+ /**
11879
+ * Cancels an appointment
11880
+ * @param appointmentId - ID of the appointment
11881
+ * @param clinicId - ID of the clinic
11882
+ * @returns Canceled calendar event
11883
+ */
11884
+ async cancelAppointment(appointmentId, clinicId) {
11885
+ return this.updateAppointmentStatus(
11886
+ appointmentId,
11887
+ clinicId,
11888
+ "canceled" /* CANCELED */
11889
+ );
11890
+ }
11891
+ /**
11892
+ * Imports events from external calendars
11893
+ * @param entityType - Type of entity (practitioner or patient)
11894
+ * @param entityId - ID of the entity
11895
+ * @param startDate - Start date for fetching events
11896
+ * @param endDate - End date for fetching events
11897
+ * @returns Number of events imported
11898
+ */
11899
+ async importEventsFromExternalCalendars(entityType, entityId, startDate, endDate) {
11900
+ if (entityType === "patient") {
11901
+ return 0;
11902
+ }
11903
+ const syncedCalendars = await this.syncedCalendarsService.getPractitionerSyncedCalendars(
11904
+ entityId
11905
+ );
11906
+ const activeCalendars = syncedCalendars.filter((cal) => cal.isActive);
11907
+ if (activeCalendars.length === 0) {
11908
+ return 0;
11909
+ }
11910
+ let importedEventsCount = 0;
11911
+ const currentTime = Timestamp26.now();
11912
+ for (const calendar of activeCalendars) {
11913
+ try {
11914
+ let externalEvents = [];
11915
+ if (calendar.provider === "google" /* GOOGLE */) {
11916
+ externalEvents = await this.syncedCalendarsService.fetchEventsFromPractitionerGoogleCalendar(
11917
+ entityId,
11918
+ calendar.id,
11919
+ startDate,
11920
+ endDate
11921
+ );
11922
+ }
11923
+ for (const externalEvent of externalEvents) {
11924
+ try {
11925
+ const convertedEvent = this.syncedCalendarsService.convertGoogleEventsToPractitionerEvents(
11926
+ entityId,
11927
+ [externalEvent]
11928
+ )[0];
11929
+ if (!convertedEvent.eventTime) {
11930
+ continue;
11931
+ }
11932
+ const eventData = {
11933
+ // Ensure all required fields are set
11934
+ eventName: convertedEvent.eventName || "External Event",
11935
+ eventTime: convertedEvent.eventTime,
11936
+ description: convertedEvent.description || "",
11937
+ status: "confirmed" /* CONFIRMED */,
11938
+ syncStatus: "external" /* EXTERNAL */,
11939
+ eventType: "blocking" /* BLOCKING */,
11940
+ practitionerProfileId: entityId,
11941
+ syncedCalendarEventId: [
11942
+ {
11943
+ eventId: externalEvent.id,
11944
+ syncedCalendarProvider: calendar.provider,
11945
+ syncedAt: currentTime
11946
+ }
11947
+ ]
11948
+ };
11949
+ const doctorEvent = await this.createDoctorBlockingEvent(
11950
+ entityId,
11951
+ eventData
11952
+ );
11953
+ if (doctorEvent) {
11954
+ importedEventsCount++;
11955
+ }
11956
+ } catch (eventError) {
11957
+ console.error("Error importing event:", eventError);
11958
+ }
11959
+ }
11960
+ } catch (calendarError) {
11961
+ console.error(
11962
+ `Error fetching events from calendar ${calendar.id}:`,
11963
+ calendarError
11964
+ );
11965
+ }
11966
+ }
11967
+ return importedEventsCount;
11968
+ }
11969
+ /**
11970
+ * Creates a blocking event in a doctor's calendar
11971
+ * @param doctorId - ID of the doctor
11972
+ * @param eventData - Calendar event data
11973
+ * @returns Created calendar event
11974
+ */
11975
+ async createDoctorBlockingEvent(doctorId, eventData) {
11976
+ try {
11977
+ const eventId = this.generateId();
11978
+ const eventRef = doc23(
11979
+ this.db,
11980
+ PRACTITIONERS_COLLECTION,
11981
+ doctorId,
11982
+ CALENDAR_COLLECTION,
11983
+ eventId
11984
+ );
11985
+ const newEvent = {
11986
+ id: eventId,
11987
+ ...eventData,
11988
+ createdAt: serverTimestamp20(),
11989
+ updatedAt: serverTimestamp20()
11990
+ };
11991
+ await setDoc21(eventRef, newEvent);
11992
+ return {
11993
+ ...newEvent,
11994
+ createdAt: Timestamp26.now(),
11995
+ updatedAt: Timestamp26.now()
11996
+ };
11997
+ } catch (error) {
11998
+ console.error(
11999
+ `Error creating blocking event for doctor ${doctorId}:`,
12000
+ error
12001
+ );
12002
+ return null;
12003
+ }
12004
+ }
12005
+ /**
12006
+ * Periodically syncs events from external calendars for doctors
12007
+ * This would be called via a scheduled Cloud Function
12008
+ * @param lookbackDays - Number of days to look back for events
12009
+ * @param lookforwardDays - Number of days to look forward for events
12010
+ */
12011
+ async synchronizeExternalCalendars(lookbackDays = 7, lookforwardDays = 30) {
12012
+ try {
12013
+ const practitionersRef = collection23(this.db, PRACTITIONERS_COLLECTION);
12014
+ const practitionersSnapshot = await getDocs23(practitionersRef);
12015
+ const startDate = /* @__PURE__ */ new Date();
12016
+ startDate.setDate(startDate.getDate() - lookbackDays);
12017
+ const endDate = /* @__PURE__ */ new Date();
12018
+ endDate.setDate(endDate.getDate() + lookforwardDays);
12019
+ const syncPromises = [];
12020
+ for (const docSnapshot of practitionersSnapshot.docs) {
12021
+ const practitionerId = docSnapshot.id;
12022
+ syncPromises.push(
12023
+ this.importEventsFromExternalCalendars(
12024
+ "doctor",
12025
+ practitionerId,
12026
+ startDate,
12027
+ endDate
12028
+ ).then((count) => {
12029
+ console.log(
12030
+ `Imported ${count} events for doctor ${practitionerId}`
12031
+ );
12032
+ }).catch((error) => {
12033
+ console.error(
12034
+ `Error importing events for doctor ${practitionerId}:`,
12035
+ error
12036
+ );
12037
+ })
12038
+ );
12039
+ syncPromises.push(
12040
+ this.updateExistingEventsFromExternalCalendars(
12041
+ practitionerId,
12042
+ startDate,
12043
+ endDate
12044
+ ).then((count) => {
12045
+ console.log(
12046
+ `Updated ${count} events for doctor ${practitionerId}`
12047
+ );
12048
+ }).catch((error) => {
12049
+ console.error(
12050
+ `Error updating events for doctor ${practitionerId}:`,
12051
+ error
12052
+ );
12053
+ })
12054
+ );
12055
+ }
12056
+ await Promise.all(syncPromises);
12057
+ console.log("Completed external calendar synchronization");
12058
+ } catch (error) {
12059
+ console.error("Error synchronizing external calendars:", error);
12060
+ }
12061
+ }
12062
+ /**
12063
+ * Updates existing events that were synced from external calendars
12064
+ * @param doctorId - ID of the doctor
12065
+ * @param startDate - Start date for fetching events
12066
+ * @param endDate - End date for fetching events
12067
+ * @returns Number of events updated
12068
+ */
12069
+ async updateExistingEventsFromExternalCalendars(doctorId, startDate, endDate) {
12070
+ var _a;
12071
+ try {
12072
+ const eventsRef = collection23(
12073
+ this.db,
12074
+ PRACTITIONERS_COLLECTION,
12075
+ doctorId,
12076
+ CALENDAR_COLLECTION
12077
+ );
12078
+ const q = query23(
12079
+ eventsRef,
12080
+ where23("syncStatus", "==", "external" /* EXTERNAL */),
12081
+ where23("eventTime.start", ">=", Timestamp26.fromDate(startDate)),
12082
+ where23("eventTime.start", "<=", Timestamp26.fromDate(endDate))
12083
+ );
12084
+ const eventsSnapshot = await getDocs23(q);
12085
+ const events = eventsSnapshot.docs.map((doc32) => ({
12086
+ id: doc32.id,
12087
+ ...doc32.data()
12088
+ }));
12089
+ const calendars = await this.syncedCalendarsService.getPractitionerSyncedCalendars(
12090
+ doctorId
12091
+ );
12092
+ const activeCalendars = calendars.filter((cal) => cal.isActive);
12093
+ if (activeCalendars.length === 0 || events.length === 0) {
12094
+ return 0;
12095
+ }
12096
+ let updatedCount = 0;
12097
+ for (const event of events) {
12098
+ if (!((_a = event.syncedCalendarEventId) == null ? void 0 : _a.length)) continue;
12099
+ for (const syncId of event.syncedCalendarEventId) {
12100
+ const calendar = activeCalendars.find(
12101
+ (cal) => cal.provider === syncId.syncedCalendarProvider
12102
+ );
12103
+ if (!calendar) continue;
12104
+ if (syncId.syncedCalendarProvider === "google" /* GOOGLE */) {
12105
+ try {
12106
+ const externalEvent = await this.fetchExternalEvent(
12107
+ doctorId,
12108
+ calendar,
12109
+ syncId.eventId
12110
+ );
12111
+ if (externalEvent) {
12112
+ const externalStartTime = new Date(
12113
+ externalEvent.start.dateTime || externalEvent.start.date
12114
+ ).getTime();
12115
+ const externalEndTime = new Date(
12116
+ externalEvent.end.dateTime || externalEvent.end.date
12117
+ ).getTime();
12118
+ const localStartTime = event.eventTime.start.toDate().getTime();
12119
+ const localEndTime = event.eventTime.end.toDate().getTime();
12120
+ if (externalStartTime !== localStartTime || externalEndTime !== localEndTime || externalEvent.summary !== event.eventName || externalEvent.description !== event.description) {
12121
+ await this.updateLocalEventFromExternal(
12122
+ doctorId,
12123
+ event.id,
12124
+ externalEvent
12125
+ );
12126
+ updatedCount++;
12127
+ }
12128
+ } else {
12129
+ await this.updateEventStatus(
12130
+ doctorId,
12131
+ event.id,
12132
+ "canceled" /* CANCELED */
12133
+ );
12134
+ updatedCount++;
12135
+ }
12136
+ } catch (error) {
12137
+ console.error(
12138
+ `Error updating external event ${event.id}:`,
12139
+ error
12140
+ );
12141
+ }
12142
+ }
12143
+ }
12144
+ }
12145
+ return updatedCount;
12146
+ } catch (error) {
12147
+ console.error(
12148
+ "Error updating existing events from external calendars:",
12149
+ error
12150
+ );
12151
+ return 0;
12152
+ }
12153
+ }
12154
+ /**
12155
+ * Fetches a single external event from Google Calendar
12156
+ * @param doctorId - ID of the doctor
12157
+ * @param calendar - Calendar information
12158
+ * @param externalEventId - ID of the external event
12159
+ * @returns External event data or null if not found
12160
+ */
12161
+ async fetchExternalEvent(doctorId, calendar, externalEventId) {
12162
+ try {
12163
+ if (calendar.provider === "google" /* GOOGLE */) {
12164
+ const result = await this.syncedCalendarsService.fetchEventFromPractitionerGoogleCalendar(
12165
+ doctorId,
12166
+ calendar.id,
12167
+ externalEventId
12168
+ );
12169
+ return result;
12170
+ }
12171
+ return null;
12172
+ } catch (error) {
12173
+ console.error(`Error fetching external event ${externalEventId}:`, error);
12174
+ return null;
12175
+ }
12176
+ }
12177
+ /**
12178
+ * Updates a local event with data from an external event
12179
+ * @param doctorId - ID of the doctor
12180
+ * @param eventId - ID of the local event
12181
+ * @param externalEvent - External event data
12182
+ */
12183
+ async updateLocalEventFromExternal(doctorId, eventId, externalEvent) {
12184
+ try {
12185
+ const startTime = new Date(
12186
+ externalEvent.start.dateTime || externalEvent.start.date
12187
+ );
12188
+ const endTime = new Date(
12189
+ externalEvent.end.dateTime || externalEvent.end.date
12190
+ );
12191
+ const eventRef = doc23(
12192
+ this.db,
12193
+ PRACTITIONERS_COLLECTION,
12194
+ doctorId,
12195
+ CALENDAR_COLLECTION,
12196
+ eventId
12197
+ );
12198
+ await updateDoc22(eventRef, {
12199
+ eventName: externalEvent.summary || "External Event",
12200
+ eventTime: {
12201
+ start: Timestamp26.fromDate(startTime),
12202
+ end: Timestamp26.fromDate(endTime)
12203
+ },
12204
+ description: externalEvent.description || "",
12205
+ updatedAt: serverTimestamp20()
12206
+ });
12207
+ console.log(`Updated local event ${eventId} from external event`);
12208
+ } catch (error) {
12209
+ console.error(
12210
+ `Error updating local event ${eventId} from external:`,
12211
+ error
12212
+ );
12213
+ }
12214
+ }
12215
+ /**
12216
+ * Updates an event's status
12217
+ * @param doctorId - ID of the doctor
12218
+ * @param eventId - ID of the event
12219
+ * @param status - New status
12220
+ */
12221
+ async updateEventStatus(doctorId, eventId, status) {
12222
+ try {
12223
+ const eventRef = doc23(
12224
+ this.db,
12225
+ PRACTITIONERS_COLLECTION,
12226
+ doctorId,
12227
+ CALENDAR_COLLECTION,
12228
+ eventId
12229
+ );
12230
+ await updateDoc22(eventRef, {
12231
+ status,
12232
+ updatedAt: serverTimestamp20()
12233
+ });
12234
+ console.log(`Updated event ${eventId} status to ${status}`);
12235
+ } catch (error) {
12236
+ console.error(`Error updating event ${eventId} status:`, error);
12237
+ }
12238
+ }
12239
+ /**
12240
+ * Creates a scheduled job to periodically sync external calendars
12241
+ * Note: This would be implemented using Cloud Functions in a real application
12242
+ * This is a sample implementation to show how it could be set up
12243
+ * @param interval - Interval in hours
12244
+ */
12245
+ createScheduledSyncJob(interval = 3) {
12246
+ console.log(
12247
+ `Setting up scheduled calendar sync job every ${interval} hours`
12248
+ );
12249
+ }
12250
+ /**
12251
+ * Searches for calendar events based on specified criteria.
12252
+ *
12253
+ * @param {SearchCalendarEventsParams} params - The search parameters.
12254
+ * @param {SearchLocationEnum} params.searchLocation - The primary location to search (practitioner, patient, or clinic).
12255
+ * @param {string} params.entityId - The ID of the entity (practitioner, patient, or clinic) to search within/for.
12256
+ * @param {string} [params.clinicId] - Optional clinic ID to filter by.
12257
+ * @param {string} [params.practitionerId] - Optional practitioner ID to filter by.
12258
+ * @param {string} [params.patientId] - Optional patient ID to filter by.
12259
+ * @param {string} [params.procedureId] - Optional procedure ID to filter by.
12260
+ * @param {DateRange} [params.dateRange] - Optional date range to filter by (event start time).
12261
+ * @param {CalendarEventStatus} [params.eventStatus] - Optional event status to filter by.
12262
+ * @param {CalendarEventType} [params.eventType] - Optional event type to filter by.
12263
+ * @returns {Promise<CalendarEvent[]>} A promise that resolves to an array of matching calendar events.
12264
+ * @throws {Error} If the search location requires an entity ID that is not provided.
12265
+ */
12266
+ async searchCalendarEvents(params) {
12267
+ return searchCalendarEventsUtil(this.db, params);
12268
+ }
12269
+ /**
12270
+ * Gets a doctor's upcoming appointments for a specific date range
12271
+ *
12272
+ * @param {string} doctorId - ID of the practitioner
12273
+ * @param {Date} startDate - Start date of the range
12274
+ * @param {Date} endDate - End date of the range
12275
+ * @param {CalendarEventStatus} [status] - Optional status filter (defaults to CONFIRMED)
12276
+ * @returns {Promise<CalendarEvent[]>} A promise that resolves to an array of appointments
12277
+ */
12278
+ async getPractitionerUpcomingAppointments(doctorId, startDate, endDate, status = "confirmed" /* CONFIRMED */) {
12279
+ const dateRange = {
12280
+ start: Timestamp26.fromDate(startDate),
12281
+ end: Timestamp26.fromDate(endDate)
12282
+ };
12283
+ const searchParams = {
12284
+ searchLocation: "practitioner" /* PRACTITIONER */,
12285
+ entityId: doctorId,
12286
+ dateRange,
12287
+ eventStatus: status,
12288
+ eventType: "appointment" /* APPOINTMENT */
12289
+ };
12290
+ return this.searchCalendarEvents(searchParams);
12291
+ }
12292
+ /**
12293
+ * Gets a patient's appointments for a specific date range
12294
+ *
12295
+ * @param {string} patientId - ID of the patient
12296
+ * @param {Date} startDate - Start date of the range
12297
+ * @param {Date} endDate - End date of the range
12298
+ * @param {CalendarEventStatus} [status] - Optional status filter (defaults to all non-canceled appointments)
12299
+ * @returns {Promise<CalendarEvent[]>} A promise that resolves to an array of appointments
12300
+ */
12301
+ async getPatientAppointments(patientId, startDate, endDate, status) {
12302
+ const dateRange = {
12303
+ start: Timestamp26.fromDate(startDate),
12304
+ end: Timestamp26.fromDate(endDate)
12305
+ };
12306
+ const searchParams = {
12307
+ searchLocation: "patient" /* PATIENT */,
12308
+ entityId: patientId,
12309
+ dateRange,
12310
+ eventType: "appointment" /* APPOINTMENT */
12311
+ };
12312
+ if (status) {
12313
+ searchParams.eventStatus = status;
12314
+ }
12315
+ return this.searchCalendarEvents(searchParams);
12316
+ }
12317
+ /**
12318
+ * Gets all appointments for a clinic within a specific date range
12319
+ *
12320
+ * @param {string} clinicId - ID of the clinic
12321
+ * @param {Date} startDate - Start date of the range
12322
+ * @param {Date} endDate - End date of the range
12323
+ * @param {string} [doctorId] - Optional doctor ID to filter by
12324
+ * @param {CalendarEventStatus} [status] - Optional status filter
12325
+ * @returns {Promise<CalendarEvent[]>} A promise that resolves to an array of appointments
12326
+ */
12327
+ async getClinicAppointments(clinicId, startDate, endDate, doctorId, status) {
12328
+ const dateRange = {
12329
+ start: Timestamp26.fromDate(startDate),
12330
+ end: Timestamp26.fromDate(endDate)
12331
+ };
12332
+ const searchParams = {
12333
+ searchLocation: "clinic" /* CLINIC */,
12334
+ entityId: clinicId,
12335
+ dateRange,
12336
+ eventType: "appointment" /* APPOINTMENT */
12337
+ };
12338
+ if (doctorId) {
12339
+ searchParams.practitionerId = doctorId;
12340
+ }
12341
+ if (status) {
12342
+ searchParams.eventStatus = status;
12343
+ }
12344
+ return this.searchCalendarEvents(searchParams);
12345
+ }
12346
+ // #endregion
12347
+ // #region Private Helper Methods
12348
+ /**
12349
+ * Validates appointment creation parameters
12350
+ * @param params - Appointment parameters to validate
12351
+ * @throws Error if validation fails
12352
+ */
12353
+ async validateAppointmentParams(params) {
12354
+ await createAppointmentSchema.parseAsync(params);
12355
+ }
12356
+ /**
12357
+ * Validates if the event time falls within clinic working hours
12358
+ * @param clinicId - ID of the clinic
12359
+ * @param eventTime - Event time to validate
12360
+ * @throws Error if validation fails
12361
+ */
12362
+ async validateClinicWorkingHours(clinicId, eventTime) {
12363
+ const startDate = eventTime.start.toDate();
12364
+ const workingHours = await this.getClinicWorkingHours(clinicId, startDate);
12365
+ if (workingHours.length === 0) {
12366
+ throw new Error("Clinic is not open on this day");
12367
+ }
12368
+ const startTime = startDate;
12369
+ const endTime = eventTime.end.toDate();
12370
+ const isWithinWorkingHours = workingHours.some((slot) => {
12371
+ return slot.start <= startTime && slot.end >= endTime && slot.isAvailable;
12372
+ });
12373
+ if (!isWithinWorkingHours) {
12374
+ throw new Error("Appointment time is outside clinic working hours");
12375
+ }
12376
+ }
12377
+ /**
12378
+ * Validates if the doctor is available during the event time
12379
+ * @param doctorId - ID of the doctor
12380
+ * @param eventTime - Event time to validate
12381
+ * @param clinicId - ID of the clinic where the appointment is being booked
12382
+ * @throws Error if validation fails
12383
+ */
12384
+ async validateDoctorAvailability(doctorId, eventTime, clinicId) {
12385
+ var _a;
12386
+ const startDate = eventTime.start.toDate();
12387
+ const startTime = startDate;
12388
+ const endTime = eventTime.end.toDate();
12389
+ const practitionerRef = doc23(this.db, PRACTITIONERS_COLLECTION, doctorId);
12390
+ const practitionerDoc = await getDoc25(practitionerRef);
12391
+ if (!practitionerDoc.exists()) {
12392
+ throw new Error(`Doctor with ID ${doctorId} not found`);
12393
+ }
12394
+ const practitioner = practitionerDoc.data();
12395
+ if (!practitioner.clinics.includes(clinicId)) {
12396
+ throw new Error("Doctor does not work at this clinic");
12397
+ }
12398
+ const clinicWorkingHours = (_a = practitioner.clinicWorkingHours) == null ? void 0 : _a.find(
12399
+ (hours) => hours.clinicId === clinicId && hours.isActive
12400
+ );
12401
+ if (!clinicWorkingHours) {
12402
+ throw new Error("Doctor does not have working hours set for this clinic");
12403
+ }
12404
+ const dayOfWeek = startDate.getDay();
12405
+ const dayKey = [
12406
+ "sunday",
12407
+ "monday",
12408
+ "tuesday",
12409
+ "wednesday",
12410
+ "thursday",
12411
+ "friday",
12412
+ "saturday"
12413
+ ][dayOfWeek];
12414
+ const daySchedule = clinicWorkingHours.workingHours[dayKey];
12415
+ if (!daySchedule) {
12416
+ throw new Error("Doctor is not working on this day at this clinic");
12417
+ }
12418
+ const [startHour, startMinute] = daySchedule.start.split(":").map(Number);
12419
+ const [endHour, endMinute] = daySchedule.end.split(":").map(Number);
12420
+ const scheduleStart = new Date(startDate);
12421
+ scheduleStart.setHours(startHour, startMinute, 0, 0);
12422
+ const scheduleEnd = new Date(startDate);
12423
+ scheduleEnd.setHours(endHour, endMinute, 0, 0);
12424
+ if (startTime < scheduleStart || endTime > scheduleEnd) {
12425
+ throw new Error(
12426
+ "Appointment time is outside doctor's working hours at this clinic"
12427
+ );
12428
+ }
12429
+ const appointments = await this.getDoctorAppointments(doctorId, startDate);
12430
+ const hasOverlap = appointments.some((appointment) => {
12431
+ const appointmentStart = appointment.eventTime.start.toDate();
12432
+ const appointmentEnd = appointment.eventTime.end.toDate();
12433
+ return startTime >= appointmentStart && startTime < appointmentEnd || endTime > appointmentStart && endTime <= appointmentEnd || startTime <= appointmentStart && endTime >= appointmentEnd;
12434
+ });
12435
+ if (hasOverlap) {
12436
+ throw new Error("Doctor has another appointment during this time");
12437
+ }
12438
+ }
12439
+ /**
12440
+ * Updates appointment status
12441
+ * @param appointmentId - ID of the appointment
12442
+ * @param clinicId - ID of the clinic
12443
+ * @param status - New status
12444
+ * @returns Updated calendar event
12445
+ */
12446
+ async updateAppointmentStatus(appointmentId, clinicId, status) {
12447
+ const baseCollectionPath = `${CLINICS_COLLECTION}/${clinicId}/${CALENDAR_COLLECTION}`;
12448
+ const appointmentRef = doc23(this.db, baseCollectionPath, appointmentId);
12449
+ const appointmentDoc = await getDoc25(appointmentRef);
12450
+ if (!appointmentDoc.exists()) {
12451
+ throw new Error(`Appointment with ID ${appointmentId} not found`);
12452
+ }
12453
+ const appointment = appointmentDoc.data();
12454
+ if (appointment.clinicBranchId !== clinicId) {
12455
+ throw new Error("Appointment does not belong to the specified clinic");
12456
+ }
12457
+ this.validateStatusTransition(appointment.status, status);
12458
+ const updateParams = {
12459
+ appointmentId,
12460
+ clinicId,
12461
+ eventTime: appointment.eventTime,
12462
+ description: appointment.description || "",
12463
+ doctorId: appointment.practitionerProfileId || "",
12464
+ patientId: appointment.patientProfileId || "",
12465
+ status
12466
+ };
12467
+ await this.validateUpdatePermissions(updateParams);
12468
+ return this.updateAppointment(updateParams);
12469
+ }
12470
+ /**
12471
+ * Validates status transition
12472
+ * @param currentStatus - Current status
12473
+ * @param newStatus - New status
12474
+ * @throws Error if transition is invalid
12475
+ */
12476
+ validateStatusTransition(currentStatus, newStatus) {
12477
+ const validTransitions = {
12478
+ ["pending" /* PENDING */]: [
12479
+ "confirmed" /* CONFIRMED */,
12480
+ "rejected" /* REJECTED */,
12481
+ "canceled" /* CANCELED */
12482
+ ],
12483
+ ["confirmed" /* CONFIRMED */]: [
12484
+ "canceled" /* CANCELED */,
12485
+ "completed" /* COMPLETED */,
12486
+ "rescheduled" /* RESCHEDULED */,
12487
+ "no_show" /* NO_SHOW */
12488
+ ],
12489
+ ["rejected" /* REJECTED */]: [],
12490
+ ["canceled" /* CANCELED */]: [],
12491
+ ["rescheduled" /* RESCHEDULED */]: [
12492
+ "confirmed" /* CONFIRMED */,
12493
+ "canceled" /* CANCELED */
12494
+ ],
12495
+ ["completed" /* COMPLETED */]: [],
12496
+ ["no_show" /* NO_SHOW */]: []
12497
+ };
12498
+ if (!validTransitions[currentStatus].includes(newStatus)) {
12499
+ throw new Error(
12500
+ `Invalid status transition from ${currentStatus} to ${newStatus}`
12501
+ );
12502
+ }
12503
+ }
12504
+ /**
12505
+ * Syncs appointment with external calendars based on entity type and status
12506
+ * @param appointment - Calendar event to sync
12507
+ */
12508
+ async syncAppointmentWithExternalCalendars(appointment) {
12509
+ if (!appointment.practitionerProfileId || !appointment.patientProfileId) {
12510
+ return;
12511
+ }
12512
+ try {
12513
+ const [doctorCalendars, patientCalendars] = await Promise.all([
12514
+ this.syncedCalendarsService.getPractitionerSyncedCalendars(
12515
+ appointment.practitionerProfileId
12516
+ ),
12517
+ this.syncedCalendarsService.getPatientSyncedCalendars(
12518
+ appointment.patientProfileId
12519
+ )
12520
+ ]);
12521
+ const activeDoctorCalendars = doctorCalendars.filter(
12522
+ (cal) => cal.isActive
12523
+ );
12524
+ const activePatientCalendars = patientCalendars.filter(
12525
+ (cal) => cal.isActive
12526
+ );
12527
+ if (activeDoctorCalendars.length === 0 && activePatientCalendars.length === 0) {
12528
+ return;
12529
+ }
12530
+ if (appointment.syncStatus !== "internal" /* INTERNAL */) {
12531
+ return;
10277
12532
  }
10278
- filters.practitionerId = void 0;
10279
- break;
10280
- case "patient" /* PATIENT */:
10281
- if (!entityId) {
10282
- throw new Error(
10283
- "Patient ID (entityId) is required when searching patient calendar."
12533
+ if (appointment.status === "confirmed" /* CONFIRMED */ && activeDoctorCalendars.length > 0) {
12534
+ await Promise.all(
12535
+ activeDoctorCalendars.map(
12536
+ (calendar) => this.syncEventToExternalCalendar(appointment, calendar, "doctor")
12537
+ )
10284
12538
  );
10285
12539
  }
10286
- baseCollectionPath = `${PATIENTS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}`;
10287
- if (filters.patientId && filters.patientId !== entityId) {
10288
- console.warn(
10289
- `Provided patientId filter (${filters.patientId}) does not match search entityId (${entityId}). Returning empty results.`
12540
+ if (appointment.status !== "canceled" /* CANCELED */ && appointment.status !== "rejected" /* REJECTED */ && activePatientCalendars.length > 0) {
12541
+ await Promise.all(
12542
+ activePatientCalendars.map(
12543
+ (calendar) => this.syncEventToExternalCalendar(appointment, calendar, "patient")
12544
+ )
10290
12545
  );
10291
- return [];
10292
12546
  }
10293
- filters.patientId = void 0;
10294
- break;
10295
- case "clinic" /* CLINIC */:
10296
- if (!entityId) {
10297
- throw new Error(
10298
- "Clinic ID (entityId) is required when searching clinic-related events."
10299
- );
12547
+ } catch (error) {
12548
+ console.error("Error syncing with external calendars:", error);
12549
+ }
12550
+ }
12551
+ /**
12552
+ * Syncs a single event to an external calendar
12553
+ * @param appointment - Calendar event to sync
12554
+ * @param calendar - External calendar to sync with
12555
+ * @param entityType - Type of entity owning the calendar
12556
+ */
12557
+ async syncEventToExternalCalendar(appointment, calendar, entityType) {
12558
+ var _a, _b, _c, _d, _e;
12559
+ try {
12560
+ const eventToSync = { ...appointment };
12561
+ let eventTitle = appointment.eventName;
12562
+ const clinicName = ((_a = appointment.clinicBranchInfo) == null ? void 0 : _a.name) || "Clinic";
12563
+ if (entityType === "patient") {
12564
+ eventTitle = `[${appointment.status}] ${eventTitle} @ ${clinicName}`;
12565
+ } else {
12566
+ eventTitle = `${eventTitle} - Patient: ${((_b = appointment.patientProfileInfo) == null ? void 0 : _b.fullName) || "Unknown"} @ ${clinicName}`;
10300
12567
  }
10301
- baseCollectionPath = `${CLINICS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}`;
10302
- constraints.push(where18("clinicBranchId", "==", entityId));
10303
- if (filters.clinicId && filters.clinicId !== entityId) {
10304
- console.warn(
10305
- `Provided clinicId filter (${filters.clinicId}) does not match search entityId (${entityId}). Returning empty results.`
12568
+ eventToSync.eventName = eventTitle;
12569
+ const existingSyncId = (_d = (_c = appointment.syncedCalendarEventId) == null ? void 0 : _c.find(
12570
+ (sync) => sync.syncedCalendarProvider === calendar.provider
12571
+ )) == null ? void 0 : _d.eventId;
12572
+ if (calendar.provider === "google" /* GOOGLE */) {
12573
+ const result = await this.syncedCalendarsService.syncPractitionerEventsToGoogleCalendar(
12574
+ entityType === "doctor" ? appointment.practitionerProfileId : appointment.patientProfileId,
12575
+ calendar.id,
12576
+ [eventToSync],
12577
+ existingSyncId
12578
+ // Pass existing sync ID if we have one
10306
12579
  );
10307
- return [];
12580
+ if (result.success && ((_e = result.eventIds) == null ? void 0 : _e.length) && !existingSyncId) {
12581
+ const newSyncEvent = {
12582
+ eventId: result.eventIds[0],
12583
+ syncedCalendarProvider: calendar.provider,
12584
+ syncedAt: Timestamp26.now()
12585
+ };
12586
+ await this.updateEventWithSyncId(
12587
+ entityType === "doctor" ? appointment.practitionerProfileId : appointment.patientProfileId,
12588
+ entityType,
12589
+ appointment.id,
12590
+ newSyncEvent
12591
+ );
12592
+ }
10308
12593
  }
10309
- filters.clinicId = void 0;
10310
- break;
10311
- default:
10312
- throw new Error(`Invalid search location: ${searchLocation}`);
10313
- }
10314
- const collectionRef = collection18(db, baseCollectionPath);
10315
- if (filters.clinicId) {
10316
- constraints.push(where18("clinicBranchId", "==", filters.clinicId));
12594
+ } catch (error) {
12595
+ console.error(`Error syncing with ${entityType}'s calendar:`, error);
12596
+ }
10317
12597
  }
10318
- if (filters.practitionerId) {
10319
- constraints.push(
10320
- where18("practitionerProfileId", "==", filters.practitionerId)
10321
- );
12598
+ /**
12599
+ * Updates an event with a new sync ID
12600
+ * @param entityId - ID of the entity (doctor or patient)
12601
+ * @param entityType - Type of entity
12602
+ * @param eventId - ID of the event
12603
+ * @param syncEvent - Sync event information
12604
+ */
12605
+ async updateEventWithSyncId(entityId, entityType, eventId, syncEvent) {
12606
+ try {
12607
+ const collectionPath = entityType === "doctor" ? `${PRACTITIONERS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}` : `${PATIENTS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}`;
12608
+ const eventRef = doc23(this.db, collectionPath, eventId);
12609
+ const eventDoc = await getDoc25(eventRef);
12610
+ if (eventDoc.exists()) {
12611
+ const event = eventDoc.data();
12612
+ const syncIds = [...event.syncedCalendarEventId || []];
12613
+ const existingSyncIndex = syncIds.findIndex(
12614
+ (sync) => sync.syncedCalendarProvider === syncEvent.syncedCalendarProvider
12615
+ );
12616
+ if (existingSyncIndex >= 0) {
12617
+ syncIds[existingSyncIndex] = syncEvent;
12618
+ } else {
12619
+ syncIds.push(syncEvent);
12620
+ }
12621
+ await updateDoc22(eventRef, {
12622
+ syncedCalendarEventId: syncIds,
12623
+ updatedAt: serverTimestamp20()
12624
+ });
12625
+ console.log(
12626
+ `Updated event ${eventId} with sync ID ${syncEvent.eventId}`
12627
+ );
12628
+ }
12629
+ } catch (error) {
12630
+ console.error("Error updating event with sync ID:", error);
12631
+ }
10322
12632
  }
10323
- if (filters.patientId) {
10324
- constraints.push(where18("patientProfileId", "==", filters.patientId));
12633
+ /**
12634
+ * Validates update permissions and parameters
12635
+ * @param params - Update parameters to validate
12636
+ */
12637
+ async validateUpdatePermissions(params) {
12638
+ await updateAppointmentSchema.parseAsync(params);
10325
12639
  }
10326
- if (filters.procedureId) {
10327
- constraints.push(where18("procedureId", "==", filters.procedureId));
12640
+ /**
12641
+ * Gets clinic working hours for a specific date
12642
+ * @param clinicId - ID of the clinic
12643
+ * @param date - Date to get working hours for
12644
+ * @returns Working hours for the clinic
12645
+ */
12646
+ async getClinicWorkingHours(clinicId, date) {
12647
+ const clinicRef = doc23(this.db, CLINICS_COLLECTION, clinicId);
12648
+ const clinicDoc = await getDoc25(clinicRef);
12649
+ if (!clinicDoc.exists()) {
12650
+ throw new Error(`Clinic with ID ${clinicId} not found`);
12651
+ }
12652
+ const workingHours = [];
12653
+ const dayOfWeek = date.getDay();
12654
+ if (dayOfWeek === 0 || dayOfWeek === 6) {
12655
+ return workingHours;
12656
+ }
12657
+ const workingDate = new Date(date);
12658
+ workingDate.setHours(9, 0, 0, 0);
12659
+ const startTime = new Date(workingDate);
12660
+ workingDate.setHours(17, 0, 0, 0);
12661
+ const endTime = new Date(workingDate);
12662
+ workingHours.push({
12663
+ start: startTime,
12664
+ end: endTime,
12665
+ isAvailable: true
12666
+ });
12667
+ return workingHours;
10328
12668
  }
10329
- if (filters.eventStatus) {
10330
- constraints.push(where18("status", "==", filters.eventStatus));
12669
+ /**
12670
+ * Gets doctor's schedule for a specific date
12671
+ * @param doctorId - ID of the doctor
12672
+ * @param date - Date to get schedule for
12673
+ * @returns Doctor's schedule
12674
+ */
12675
+ async getDoctorSchedule(doctorId, date) {
12676
+ const practitionerRef = doc23(this.db, PRACTITIONERS_COLLECTION, doctorId);
12677
+ const practitionerDoc = await getDoc25(practitionerRef);
12678
+ if (!practitionerDoc.exists()) {
12679
+ throw new Error(`Doctor with ID ${doctorId} not found`);
12680
+ }
12681
+ const schedule = [];
12682
+ const dayOfWeek = date.getDay();
12683
+ if (dayOfWeek === 0 || dayOfWeek === 6) {
12684
+ return schedule;
12685
+ }
12686
+ const scheduleDate = new Date(date);
12687
+ scheduleDate.setHours(9, 0, 0, 0);
12688
+ const startTime = new Date(scheduleDate);
12689
+ scheduleDate.setHours(17, 0, 0, 0);
12690
+ const endTime = new Date(scheduleDate);
12691
+ schedule.push({
12692
+ start: startTime,
12693
+ end: endTime,
12694
+ isAvailable: true
12695
+ });
12696
+ return schedule;
10331
12697
  }
10332
- if (filters.eventType) {
10333
- constraints.push(where18("eventType", "==", filters.eventType));
12698
+ /**
12699
+ * Gets doctor's appointments for a specific date
12700
+ * @param doctorId - ID of the doctor
12701
+ * @param date - Date to get appointments for
12702
+ * @returns Array of calendar events
12703
+ */
12704
+ async getDoctorAppointments(doctorId, date) {
12705
+ const startOfDay = new Date(date);
12706
+ startOfDay.setHours(0, 0, 0, 0);
12707
+ const endOfDay = new Date(date);
12708
+ endOfDay.setHours(23, 59, 59, 999);
12709
+ const appointmentsRef = collection23(this.db, CALENDAR_COLLECTION);
12710
+ const q = query23(
12711
+ appointmentsRef,
12712
+ where23("practitionerProfileId", "==", doctorId),
12713
+ where23("eventTime.start", ">=", Timestamp26.fromDate(startOfDay)),
12714
+ where23("eventTime.start", "<=", Timestamp26.fromDate(endOfDay)),
12715
+ where23("status", "in", [
12716
+ "confirmed" /* CONFIRMED */,
12717
+ "pending" /* PENDING */
12718
+ ])
12719
+ );
12720
+ const querySnapshot = await getDocs23(q);
12721
+ return querySnapshot.docs.map((doc32) => doc32.data());
10334
12722
  }
10335
- if (filters.dateRange) {
10336
- constraints.push(where18("eventTime.start", ">=", filters.dateRange.start));
10337
- constraints.push(where18("eventTime.start", "<=", filters.dateRange.end));
12723
+ /**
12724
+ * Calculates available time slots based on working hours, schedule and existing appointments
12725
+ * @param workingHours - Clinic working hours
12726
+ * @param doctorSchedule - Doctor's schedule
12727
+ * @param existingAppointments - Existing appointments
12728
+ * @returns Array of available time slots
12729
+ */
12730
+ calculateAvailableSlots(workingHours, doctorSchedule, existingAppointments) {
12731
+ const availableSlots = [];
12732
+ for (const workingHour of workingHours) {
12733
+ for (const scheduleSlot of doctorSchedule) {
12734
+ const overlapStart = new Date(
12735
+ Math.max(workingHour.start.getTime(), scheduleSlot.start.getTime())
12736
+ );
12737
+ const overlapEnd = new Date(
12738
+ Math.min(workingHour.end.getTime(), scheduleSlot.end.getTime())
12739
+ );
12740
+ if (overlapStart < overlapEnd && workingHour.isAvailable && scheduleSlot.isAvailable) {
12741
+ let slotStart = new Date(overlapStart);
12742
+ while (slotStart < overlapEnd) {
12743
+ const slotEnd = new Date(
12744
+ slotStart.getTime() + MIN_APPOINTMENT_DURATION * 60 * 1e3
12745
+ );
12746
+ const hasOverlap = existingAppointments.some((appointment) => {
12747
+ const appointmentStart = appointment.eventTime.start.toDate();
12748
+ const appointmentEnd = appointment.eventTime.end.toDate();
12749
+ return slotStart >= appointmentStart && slotStart < appointmentEnd || slotEnd > appointmentStart && slotEnd <= appointmentEnd;
12750
+ });
12751
+ if (!hasOverlap && slotEnd <= overlapEnd) {
12752
+ availableSlots.push({
12753
+ start: new Date(slotStart),
12754
+ end: new Date(slotEnd),
12755
+ isAvailable: true
12756
+ });
12757
+ }
12758
+ slotStart = new Date(
12759
+ slotStart.getTime() + MIN_APPOINTMENT_DURATION * 60 * 1e3
12760
+ );
12761
+ }
12762
+ }
12763
+ }
12764
+ }
12765
+ return availableSlots;
10338
12766
  }
10339
- try {
10340
- const finalQuery = query18(collectionRef, ...constraints);
10341
- const querySnapshot = await getDocs18(finalQuery);
10342
- const events = querySnapshot.docs.map(
10343
- (doc26) => ({ id: doc26.id, ...doc26.data() })
10344
- );
10345
- return events;
10346
- } catch (error) {
10347
- console.error("Error searching calendar events:", error);
10348
- return [];
12767
+ /**
12768
+ * Fetches and creates info cards for clinic, doctor, and patient profiles
12769
+ * @param clinicId - ID of the clinic
12770
+ * @param doctorId - ID of the doctor
12771
+ * @param patientId - ID of the patient
12772
+ * @returns Object containing info cards for all profiles
12773
+ */
12774
+ async fetchProfileInfoCards(clinicId, doctorId, patientId) {
12775
+ var _a;
12776
+ try {
12777
+ const [clinicDoc, practitionerDoc, patientDoc, patientSensitiveInfoDoc] = await Promise.all([
12778
+ getDoc25(doc23(this.db, CLINICS_COLLECTION, clinicId)),
12779
+ getDoc25(doc23(this.db, PRACTITIONERS_COLLECTION, doctorId)),
12780
+ getDoc25(doc23(this.db, PATIENTS_COLLECTION, patientId)),
12781
+ getDoc25(
12782
+ doc23(
12783
+ this.db,
12784
+ PATIENTS_COLLECTION,
12785
+ patientId,
12786
+ PATIENT_SENSITIVE_INFO_COLLECTION,
12787
+ patientId
12788
+ )
12789
+ )
12790
+ ]);
12791
+ const clinicInfo = clinicDoc.exists() ? {
12792
+ id: clinicDoc.id,
12793
+ featuredPhoto: clinicDoc.data().featuredPhoto || "",
12794
+ name: clinicDoc.data().name,
12795
+ description: clinicDoc.data().description || "",
12796
+ location: clinicDoc.data().location,
12797
+ contactInfo: clinicDoc.data().contactInfo
12798
+ } : null;
12799
+ const practitionerInfo = practitionerDoc.exists() ? {
12800
+ id: practitionerDoc.id,
12801
+ practitionerPhoto: practitionerDoc.data().basicInfo.profileImageUrl || null,
12802
+ name: `${practitionerDoc.data().basicInfo.firstName} ${practitionerDoc.data().basicInfo.lastName}`,
12803
+ email: practitionerDoc.data().basicInfo.email,
12804
+ phone: practitionerDoc.data().basicInfo.phoneNumber || null,
12805
+ certification: practitionerDoc.data().certification
12806
+ } : null;
12807
+ let patientInfo = null;
12808
+ if (patientSensitiveInfoDoc.exists()) {
12809
+ const sensitiveData = patientSensitiveInfoDoc.data();
12810
+ patientInfo = {
12811
+ id: patientId,
12812
+ fullName: `${sensitiveData.firstName} ${sensitiveData.lastName}`,
12813
+ email: sensitiveData.email || "",
12814
+ phone: sensitiveData.phoneNumber || null,
12815
+ dateOfBirth: sensitiveData.dateOfBirth || Timestamp26.now(),
12816
+ gender: sensitiveData.gender || "other" /* OTHER */
12817
+ };
12818
+ } else if (patientDoc.exists()) {
12819
+ patientInfo = {
12820
+ id: patientDoc.id,
12821
+ fullName: patientDoc.data().displayName,
12822
+ email: ((_a = patientDoc.data().contactInfo) == null ? void 0 : _a.email) || "",
12823
+ phone: patientDoc.data().phoneNumber || null,
12824
+ dateOfBirth: patientDoc.data().dateOfBirth || Timestamp26.now(),
12825
+ gender: patientDoc.data().gender || "other" /* OTHER */
12826
+ };
12827
+ }
12828
+ return {
12829
+ clinicInfo,
12830
+ practitionerInfo,
12831
+ patientInfo
12832
+ };
12833
+ } catch (error) {
12834
+ console.error("Error fetching profile info cards:", error);
12835
+ return {
12836
+ clinicInfo: null,
12837
+ practitionerInfo: null,
12838
+ patientInfo: null
12839
+ };
12840
+ }
10349
12841
  }
10350
- }
12842
+ // #endregion
12843
+ };
10351
12844
 
10352
12845
  // src/services/calendar/calendar.v3.service.ts
12846
+ import { Timestamp as Timestamp27, serverTimestamp as serverTimestamp21 } from "firebase/firestore";
12847
+ import { doc as doc24, getDoc as getDoc26, setDoc as setDoc22, updateDoc as updateDoc23, deleteDoc as deleteDoc14 } from "firebase/firestore";
10353
12848
  var CalendarServiceV3 = class extends BaseService {
10354
12849
  /**
10355
12850
  * Creates a new CalendarServiceV3 instance
@@ -10373,7 +12868,7 @@ var CalendarServiceV3 = class extends BaseService {
10373
12868
  params.entityType,
10374
12869
  params.entityId
10375
12870
  );
10376
- const eventRef = doc18(this.db, collectionPath, eventId);
12871
+ const eventRef = doc24(this.db, collectionPath, eventId);
10377
12872
  const eventData = {
10378
12873
  id: eventId,
10379
12874
  eventName: params.eventName,
@@ -10383,19 +12878,19 @@ var CalendarServiceV3 = class extends BaseService {
10383
12878
  status: "confirmed" /* CONFIRMED */,
10384
12879
  // Blocking events are always confirmed
10385
12880
  syncStatus: "internal" /* INTERNAL */,
10386
- createdAt: serverTimestamp16(),
10387
- updatedAt: serverTimestamp16()
12881
+ createdAt: serverTimestamp21(),
12882
+ updatedAt: serverTimestamp21()
10388
12883
  };
10389
12884
  if (params.entityType === "practitioner") {
10390
12885
  eventData.practitionerProfileId = params.entityId;
10391
12886
  } else {
10392
12887
  eventData.clinicBranchId = params.entityId;
10393
12888
  }
10394
- await setDoc17(eventRef, eventData);
12889
+ await setDoc22(eventRef, eventData);
10395
12890
  return {
10396
12891
  ...eventData,
10397
- createdAt: Timestamp21.now(),
10398
- updatedAt: Timestamp21.now()
12892
+ createdAt: Timestamp27.now(),
12893
+ updatedAt: Timestamp27.now()
10399
12894
  };
10400
12895
  }
10401
12896
  /**
@@ -10408,13 +12903,13 @@ var CalendarServiceV3 = class extends BaseService {
10408
12903
  params.entityType,
10409
12904
  params.entityId
10410
12905
  );
10411
- const eventRef = doc18(this.db, collectionPath, params.eventId);
10412
- const eventDoc = await getDoc21(eventRef);
12906
+ const eventRef = doc24(this.db, collectionPath, params.eventId);
12907
+ const eventDoc = await getDoc26(eventRef);
10413
12908
  if (!eventDoc.exists()) {
10414
12909
  throw new Error(`Blocking event with ID ${params.eventId} not found`);
10415
12910
  }
10416
12911
  const updateData = {
10417
- updatedAt: serverTimestamp16()
12912
+ updatedAt: serverTimestamp21()
10418
12913
  };
10419
12914
  if (params.eventName !== void 0) {
10420
12915
  updateData.eventName = params.eventName;
@@ -10428,8 +12923,8 @@ var CalendarServiceV3 = class extends BaseService {
10428
12923
  if (params.status !== void 0) {
10429
12924
  updateData.status = params.status;
10430
12925
  }
10431
- await updateDoc18(eventRef, updateData);
10432
- const updatedEventDoc = await getDoc21(eventRef);
12926
+ await updateDoc23(eventRef, updateData);
12927
+ const updatedEventDoc = await getDoc26(eventRef);
10433
12928
  return updatedEventDoc.data();
10434
12929
  }
10435
12930
  /**
@@ -10440,12 +12935,12 @@ var CalendarServiceV3 = class extends BaseService {
10440
12935
  */
10441
12936
  async deleteBlockingEvent(entityType, entityId, eventId) {
10442
12937
  const collectionPath = this.getEntityCalendarPath(entityType, entityId);
10443
- const eventRef = doc18(this.db, collectionPath, eventId);
10444
- const eventDoc = await getDoc21(eventRef);
12938
+ const eventRef = doc24(this.db, collectionPath, eventId);
12939
+ const eventDoc = await getDoc26(eventRef);
10445
12940
  if (!eventDoc.exists()) {
10446
12941
  throw new Error(`Blocking event with ID ${eventId} not found`);
10447
12942
  }
10448
- await deleteDoc10(eventRef);
12943
+ await deleteDoc14(eventRef);
10449
12944
  }
10450
12945
  /**
10451
12946
  * Gets a specific blocking event
@@ -10456,8 +12951,8 @@ var CalendarServiceV3 = class extends BaseService {
10456
12951
  */
10457
12952
  async getBlockingEvent(entityType, entityId, eventId) {
10458
12953
  const collectionPath = this.getEntityCalendarPath(entityType, entityId);
10459
- const eventRef = doc18(this.db, collectionPath, eventId);
10460
- const eventDoc = await getDoc21(eventRef);
12954
+ const eventRef = doc24(this.db, collectionPath, eventId);
12955
+ const eventDoc = await getDoc26(eventRef);
10461
12956
  if (!eventDoc.exists()) {
10462
12957
  return null;
10463
12958
  }
@@ -10651,18 +13146,18 @@ var ExternalCalendarService = class extends BaseService {
10651
13146
 
10652
13147
  // src/services/clinic/practitioner-invite.service.ts
10653
13148
  import {
10654
- collection as collection19,
10655
- doc as doc19,
10656
- getDoc as getDoc22,
10657
- getDocs as getDocs19,
10658
- query as query19,
10659
- where as where19,
10660
- updateDoc as updateDoc19,
10661
- setDoc as setDoc18,
10662
- deleteDoc as deleteDoc11,
10663
- Timestamp as Timestamp22,
10664
- serverTimestamp as serverTimestamp17,
10665
- orderBy as orderBy8,
13149
+ collection as collection24,
13150
+ doc as doc25,
13151
+ getDoc as getDoc27,
13152
+ getDocs as getDocs24,
13153
+ query as query24,
13154
+ where as where24,
13155
+ updateDoc as updateDoc24,
13156
+ setDoc as setDoc23,
13157
+ deleteDoc as deleteDoc15,
13158
+ Timestamp as Timestamp28,
13159
+ serverTimestamp as serverTimestamp22,
13160
+ orderBy as orderBy12,
10666
13161
  limit as limit11
10667
13162
  } from "firebase/firestore";
10668
13163
  var PractitionerInviteService = class extends BaseService {
@@ -10726,7 +13221,7 @@ var PractitionerInviteService = class extends BaseService {
10726
13221
  message: message || null,
10727
13222
  status: "pending" /* PENDING */
10728
13223
  };
10729
- const now = Timestamp22.now();
13224
+ const now = Timestamp28.now();
10730
13225
  const invite = {
10731
13226
  id: inviteId,
10732
13227
  ...inviteData,
@@ -10737,8 +13232,8 @@ var PractitionerInviteService = class extends BaseService {
10737
13232
  rejectedAt: null,
10738
13233
  cancelledAt: null
10739
13234
  };
10740
- const docRef = doc19(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
10741
- await setDoc18(docRef, invite);
13235
+ const docRef = doc25(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
13236
+ await setDoc23(docRef, invite);
10742
13237
  return invite;
10743
13238
  } catch (error) {
10744
13239
  console.error(
@@ -10757,18 +13252,18 @@ var PractitionerInviteService = class extends BaseService {
10757
13252
  async getAllInvitesDoctor(practitionerId, statusFilter) {
10758
13253
  try {
10759
13254
  const constraints = [
10760
- where19("practitionerId", "==", practitionerId),
10761
- orderBy8("createdAt", "desc")
13255
+ where24("practitionerId", "==", practitionerId),
13256
+ orderBy12("createdAt", "desc")
10762
13257
  ];
10763
13258
  if (statusFilter && statusFilter.length > 0) {
10764
- constraints.push(where19("status", "in", statusFilter));
13259
+ constraints.push(where24("status", "in", statusFilter));
10765
13260
  }
10766
- const q = query19(
10767
- collection19(this.db, PRACTITIONER_INVITES_COLLECTION),
13261
+ const q = query24(
13262
+ collection24(this.db, PRACTITIONER_INVITES_COLLECTION),
10768
13263
  ...constraints
10769
13264
  );
10770
- const querySnapshot = await getDocs19(q);
10771
- return querySnapshot.docs.map((doc26) => doc26.data());
13265
+ const querySnapshot = await getDocs24(q);
13266
+ return querySnapshot.docs.map((doc32) => doc32.data());
10772
13267
  } catch (error) {
10773
13268
  console.error(
10774
13269
  "[PractitionerInviteService] Error getting doctor invites:",
@@ -10786,18 +13281,18 @@ var PractitionerInviteService = class extends BaseService {
10786
13281
  async getAllInvitesClinic(clinicId, statusFilter) {
10787
13282
  try {
10788
13283
  const constraints = [
10789
- where19("clinicId", "==", clinicId),
10790
- orderBy8("createdAt", "desc")
13284
+ where24("clinicId", "==", clinicId),
13285
+ orderBy12("createdAt", "desc")
10791
13286
  ];
10792
13287
  if (statusFilter && statusFilter.length > 0) {
10793
- constraints.push(where19("status", "in", statusFilter));
13288
+ constraints.push(where24("status", "in", statusFilter));
10794
13289
  }
10795
- const q = query19(
10796
- collection19(this.db, PRACTITIONER_INVITES_COLLECTION),
13290
+ const q = query24(
13291
+ collection24(this.db, PRACTITIONER_INVITES_COLLECTION),
10797
13292
  ...constraints
10798
13293
  );
10799
- const querySnapshot = await getDocs19(q);
10800
- return querySnapshot.docs.map((doc26) => doc26.data());
13294
+ const querySnapshot = await getDocs24(q);
13295
+ return querySnapshot.docs.map((doc32) => doc32.data());
10801
13296
  } catch (error) {
10802
13297
  console.error(
10803
13298
  "[PractitionerInviteService] Error getting clinic invites:",
@@ -10822,11 +13317,11 @@ var PractitionerInviteService = class extends BaseService {
10822
13317
  }
10823
13318
  const updateData = {
10824
13319
  status: "accepted" /* ACCEPTED */,
10825
- acceptedAt: Timestamp22.now(),
10826
- updatedAt: serverTimestamp17()
13320
+ acceptedAt: Timestamp28.now(),
13321
+ updatedAt: serverTimestamp22()
10827
13322
  };
10828
- const docRef = doc19(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
10829
- await updateDoc19(docRef, updateData);
13323
+ const docRef = doc25(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
13324
+ await updateDoc24(docRef, updateData);
10830
13325
  return await this.getInviteById(inviteId);
10831
13326
  } catch (error) {
10832
13327
  console.error(
@@ -10854,11 +13349,11 @@ var PractitionerInviteService = class extends BaseService {
10854
13349
  const updateData = {
10855
13350
  status: "rejected" /* REJECTED */,
10856
13351
  rejectionReason: rejectionReason || null,
10857
- rejectedAt: Timestamp22.now(),
10858
- updatedAt: serverTimestamp17()
13352
+ rejectedAt: Timestamp28.now(),
13353
+ updatedAt: serverTimestamp22()
10859
13354
  };
10860
- const docRef = doc19(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
10861
- await updateDoc19(docRef, updateData);
13355
+ const docRef = doc25(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
13356
+ await updateDoc24(docRef, updateData);
10862
13357
  return await this.getInviteById(inviteId);
10863
13358
  } catch (error) {
10864
13359
  console.error(
@@ -10886,11 +13381,11 @@ var PractitionerInviteService = class extends BaseService {
10886
13381
  const updateData = {
10887
13382
  status: "cancelled" /* CANCELLED */,
10888
13383
  cancelReason: cancelReason || null,
10889
- cancelledAt: Timestamp22.now(),
10890
- updatedAt: serverTimestamp17()
13384
+ cancelledAt: Timestamp28.now(),
13385
+ updatedAt: serverTimestamp22()
10891
13386
  };
10892
- const docRef = doc19(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
10893
- await updateDoc19(docRef, updateData);
13387
+ const docRef = doc25(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
13388
+ await updateDoc24(docRef, updateData);
10894
13389
  return await this.getInviteById(inviteId);
10895
13390
  } catch (error) {
10896
13391
  console.error(
@@ -10907,8 +13402,8 @@ var PractitionerInviteService = class extends BaseService {
10907
13402
  */
10908
13403
  async getInviteById(inviteId) {
10909
13404
  try {
10910
- const docRef = doc19(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
10911
- const docSnap = await getDoc22(docRef);
13405
+ const docRef = doc25(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
13406
+ const docSnap = await getDoc27(docRef);
10912
13407
  if (docSnap.exists()) {
10913
13408
  return docSnap.data();
10914
13409
  }
@@ -10930,30 +13425,30 @@ var PractitionerInviteService = class extends BaseService {
10930
13425
  try {
10931
13426
  const constraints = [];
10932
13427
  if (filters.practitionerId) {
10933
- constraints.push(where19("practitionerId", "==", filters.practitionerId));
13428
+ constraints.push(where24("practitionerId", "==", filters.practitionerId));
10934
13429
  }
10935
13430
  if (filters.clinicId) {
10936
- constraints.push(where19("clinicId", "==", filters.clinicId));
13431
+ constraints.push(where24("clinicId", "==", filters.clinicId));
10937
13432
  }
10938
13433
  if (filters.invitedBy) {
10939
- constraints.push(where19("invitedBy", "==", filters.invitedBy));
13434
+ constraints.push(where24("invitedBy", "==", filters.invitedBy));
10940
13435
  }
10941
13436
  if (filters.status && filters.status.length > 0) {
10942
- constraints.push(where19("status", "in", filters.status));
13437
+ constraints.push(where24("status", "in", filters.status));
10943
13438
  }
10944
13439
  const orderField = filters.orderBy || "createdAt";
10945
13440
  const orderDirection = filters.orderDirection || "desc";
10946
- constraints.push(orderBy8(orderField, orderDirection));
13441
+ constraints.push(orderBy12(orderField, orderDirection));
10947
13442
  if (filters.limit) {
10948
13443
  constraints.push(limit11(filters.limit));
10949
13444
  }
10950
- const q = query19(
10951
- collection19(this.db, PRACTITIONER_INVITES_COLLECTION),
13445
+ const q = query24(
13446
+ collection24(this.db, PRACTITIONER_INVITES_COLLECTION),
10952
13447
  ...constraints
10953
13448
  );
10954
- const querySnapshot = await getDocs19(q);
13449
+ const querySnapshot = await getDocs24(q);
10955
13450
  let invites = querySnapshot.docs.map(
10956
- (doc26) => doc26.data()
13451
+ (doc32) => doc32.data()
10957
13452
  );
10958
13453
  if (filters.fromDate) {
10959
13454
  invites = invites.filter(
@@ -10980,8 +13475,8 @@ var PractitionerInviteService = class extends BaseService {
10980
13475
  */
10981
13476
  async deleteInvite(inviteId) {
10982
13477
  try {
10983
- const docRef = doc19(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
10984
- await deleteDoc11(docRef);
13478
+ const docRef = doc25(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
13479
+ await deleteDoc15(docRef);
10985
13480
  } catch (error) {
10986
13481
  console.error(
10987
13482
  "[PractitionerInviteService] Error deleting invite:",
@@ -10998,8 +13493,8 @@ var PractitionerInviteService = class extends BaseService {
10998
13493
  */
10999
13494
  async getPractitionerById(practitionerId) {
11000
13495
  try {
11001
- const docRef = doc19(this.db, PRACTITIONERS_COLLECTION, practitionerId);
11002
- const docSnap = await getDoc22(docRef);
13496
+ const docRef = doc25(this.db, PRACTITIONERS_COLLECTION, practitionerId);
13497
+ const docSnap = await getDoc27(docRef);
11003
13498
  return docSnap.exists() ? docSnap.data() : null;
11004
13499
  } catch (error) {
11005
13500
  console.error(
@@ -11016,8 +13511,8 @@ var PractitionerInviteService = class extends BaseService {
11016
13511
  */
11017
13512
  async getClinicById(clinicId) {
11018
13513
  try {
11019
- const docRef = doc19(this.db, CLINICS_COLLECTION, clinicId);
11020
- const docSnap = await getDoc22(docRef);
13514
+ const docRef = doc25(this.db, CLINICS_COLLECTION, clinicId);
13515
+ const docSnap = await getDoc27(docRef);
11021
13516
  return docSnap.exists() ? docSnap.data() : null;
11022
13517
  } catch (error) {
11023
13518
  console.error("[PractitionerInviteService] Error getting clinic:", error);
@@ -11032,14 +13527,14 @@ var PractitionerInviteService = class extends BaseService {
11032
13527
  */
11033
13528
  async findExistingInvite(practitionerId, clinicId) {
11034
13529
  try {
11035
- const q = query19(
11036
- collection19(this.db, PRACTITIONER_INVITES_COLLECTION),
11037
- where19("practitionerId", "==", practitionerId),
11038
- where19("clinicId", "==", clinicId),
11039
- orderBy8("createdAt", "desc"),
13530
+ const q = query24(
13531
+ collection24(this.db, PRACTITIONER_INVITES_COLLECTION),
13532
+ where24("practitionerId", "==", practitionerId),
13533
+ where24("clinicId", "==", clinicId),
13534
+ orderBy12("createdAt", "desc"),
11040
13535
  limit11(1)
11041
13536
  );
11042
- const querySnapshot = await getDocs19(q);
13537
+ const querySnapshot = await getDocs24(q);
11043
13538
  if (querySnapshot.empty) {
11044
13539
  return null;
11045
13540
  }
@@ -11056,23 +13551,23 @@ var PractitionerInviteService = class extends BaseService {
11056
13551
 
11057
13552
  // src/services/documentation-templates/documentation-template.service.ts
11058
13553
  import {
11059
- collection as collection20,
11060
- doc as doc20,
11061
- getDoc as getDoc23,
11062
- getDocs as getDocs20,
11063
- setDoc as setDoc19,
11064
- updateDoc as updateDoc20,
11065
- deleteDoc as deleteDoc12,
11066
- query as query20,
11067
- where as where20,
11068
- orderBy as orderBy9,
13554
+ collection as collection25,
13555
+ doc as doc26,
13556
+ getDoc as getDoc28,
13557
+ getDocs as getDocs25,
13558
+ setDoc as setDoc24,
13559
+ updateDoc as updateDoc25,
13560
+ deleteDoc as deleteDoc16,
13561
+ query as query25,
13562
+ where as where25,
13563
+ orderBy as orderBy13,
11069
13564
  limit as limit12,
11070
13565
  startAfter as startAfter10
11071
13566
  } from "firebase/firestore";
11072
13567
  var DocumentationTemplateService = class extends BaseService {
11073
13568
  constructor() {
11074
13569
  super(...arguments);
11075
- this.collectionRef = collection20(
13570
+ this.collectionRef = collection25(
11076
13571
  this.db,
11077
13572
  DOCUMENTATION_TEMPLATES_COLLECTION
11078
13573
  );
@@ -11106,8 +13601,8 @@ var DocumentationTemplateService = class extends BaseService {
11106
13601
  isRequired: validatedData.isRequired || false,
11107
13602
  sortingOrder: validatedData.sortingOrder || 0
11108
13603
  };
11109
- const docRef = doc20(this.collectionRef, templateId);
11110
- await setDoc19(docRef, template);
13604
+ const docRef = doc26(this.collectionRef, templateId);
13605
+ await setDoc24(docRef, template);
11111
13606
  return template;
11112
13607
  }
11113
13608
  /**
@@ -11117,8 +13612,8 @@ var DocumentationTemplateService = class extends BaseService {
11117
13612
  * @returns The template or null if not found
11118
13613
  */
11119
13614
  async getTemplateById(templateId, version) {
11120
- const docRef = doc20(this.collectionRef, templateId);
11121
- const docSnap = await getDoc23(docRef);
13615
+ const docRef = doc26(this.collectionRef, templateId);
13616
+ const docSnap = await getDoc28(docRef);
11122
13617
  if (!docSnap.exists()) {
11123
13618
  return null;
11124
13619
  }
@@ -11156,15 +13651,15 @@ var DocumentationTemplateService = class extends BaseService {
11156
13651
  if (!template) {
11157
13652
  throw new Error(`Template with ID ${templateId} not found`);
11158
13653
  }
11159
- const versionsCollectionRef = collection20(
13654
+ const versionsCollectionRef = collection25(
11160
13655
  this.db,
11161
13656
  `${DOCUMENTATION_TEMPLATES_COLLECTION}/${templateId}/versions`
11162
13657
  );
11163
- const versionDocRef = doc20(
13658
+ const versionDocRef = doc26(
11164
13659
  versionsCollectionRef,
11165
13660
  template.version.toString()
11166
13661
  );
11167
- await setDoc19(versionDocRef, template);
13662
+ await setDoc24(versionDocRef, template);
11168
13663
  let updatedElements = template.elements;
11169
13664
  if (validatedData.elements) {
11170
13665
  updatedElements = validatedData.elements.map((element) => ({
@@ -11188,9 +13683,9 @@ var DocumentationTemplateService = class extends BaseService {
11188
13683
  updatePayload.isUserForm = (_a = validatedData.isUserForm) != null ? _a : false;
11189
13684
  updatePayload.isRequired = (_b = validatedData.isRequired) != null ? _b : false;
11190
13685
  updatePayload.sortingOrder = (_c = validatedData.sortingOrder) != null ? _c : 0;
11191
- const docRef = doc20(this.collectionRef, templateId);
13686
+ const docRef = doc26(this.collectionRef, templateId);
11192
13687
  console.log("Update payload", updatePayload);
11193
- await updateDoc20(docRef, updatePayload);
13688
+ await updateDoc25(docRef, updatePayload);
11194
13689
  return { ...template, ...updatePayload };
11195
13690
  }
11196
13691
  /**
@@ -11200,11 +13695,11 @@ var DocumentationTemplateService = class extends BaseService {
11200
13695
  * @returns The template version or null if not found
11201
13696
  */
11202
13697
  async getTemplateVersion(templateId, versionNumber) {
11203
- const versionDocRef = doc20(
13698
+ const versionDocRef = doc26(
11204
13699
  this.db,
11205
13700
  `${DOCUMENTATION_TEMPLATES_COLLECTION}/${templateId}/versions/${versionNumber}`
11206
13701
  );
11207
- const versionDocSnap = await getDoc23(versionDocRef);
13702
+ const versionDocSnap = await getDoc28(versionDocRef);
11208
13703
  if (!versionDocSnap.exists()) {
11209
13704
  return null;
11210
13705
  }
@@ -11216,15 +13711,15 @@ var DocumentationTemplateService = class extends BaseService {
11216
13711
  * @returns Array of template versions
11217
13712
  */
11218
13713
  async getTemplateOldVersions(templateId) {
11219
- const versionsCollectionRef = collection20(
13714
+ const versionsCollectionRef = collection25(
11220
13715
  this.db,
11221
13716
  `${DOCUMENTATION_TEMPLATES_COLLECTION}/${templateId}/versions`
11222
13717
  );
11223
- const q = query20(versionsCollectionRef, orderBy9("version", "desc"));
11224
- const querySnapshot = await getDocs20(q);
13718
+ const q = query25(versionsCollectionRef, orderBy13("version", "desc"));
13719
+ const querySnapshot = await getDocs25(q);
11225
13720
  const versions = [];
11226
- querySnapshot.forEach((doc26) => {
11227
- versions.push(doc26.data());
13721
+ querySnapshot.forEach((doc32) => {
13722
+ versions.push(doc32.data());
11228
13723
  });
11229
13724
  return versions;
11230
13725
  }
@@ -11233,8 +13728,8 @@ var DocumentationTemplateService = class extends BaseService {
11233
13728
  * @param templateId - ID of the template to delete
11234
13729
  */
11235
13730
  async deleteTemplate(templateId) {
11236
- const docRef = doc20(this.collectionRef, templateId);
11237
- await deleteDoc12(docRef);
13731
+ const docRef = doc26(this.collectionRef, templateId);
13732
+ await deleteDoc16(docRef);
11238
13733
  }
11239
13734
  /**
11240
13735
  * Get all active templates
@@ -11243,21 +13738,21 @@ var DocumentationTemplateService = class extends BaseService {
11243
13738
  * @returns Array of templates and the last document for pagination
11244
13739
  */
11245
13740
  async getActiveTemplates(pageSize = 20, lastDoc) {
11246
- let q = query20(
13741
+ let q = query25(
11247
13742
  this.collectionRef,
11248
- where20("isActive", "==", true),
11249
- orderBy9("updatedAt", "desc"),
13743
+ where25("isActive", "==", true),
13744
+ orderBy13("updatedAt", "desc"),
11250
13745
  limit12(pageSize)
11251
13746
  );
11252
13747
  if (lastDoc) {
11253
- q = query20(q, startAfter10(lastDoc));
13748
+ q = query25(q, startAfter10(lastDoc));
11254
13749
  }
11255
- const querySnapshot = await getDocs20(q);
13750
+ const querySnapshot = await getDocs25(q);
11256
13751
  const templates = [];
11257
13752
  let lastVisible = null;
11258
- querySnapshot.forEach((doc26) => {
11259
- templates.push(doc26.data());
11260
- lastVisible = doc26;
13753
+ querySnapshot.forEach((doc32) => {
13754
+ templates.push(doc32.data());
13755
+ lastVisible = doc32;
11261
13756
  });
11262
13757
  return {
11263
13758
  templates,
@@ -11272,22 +13767,22 @@ var DocumentationTemplateService = class extends BaseService {
11272
13767
  * @returns Array of templates and the last document for pagination
11273
13768
  */
11274
13769
  async getTemplatesByTags(tags, pageSize = 20, lastDoc) {
11275
- let q = query20(
13770
+ let q = query25(
11276
13771
  this.collectionRef,
11277
- where20("isActive", "==", true),
11278
- where20("tags", "array-contains-any", tags),
11279
- orderBy9("updatedAt", "desc"),
13772
+ where25("isActive", "==", true),
13773
+ where25("tags", "array-contains-any", tags),
13774
+ orderBy13("updatedAt", "desc"),
11280
13775
  limit12(pageSize)
11281
13776
  );
11282
13777
  if (lastDoc) {
11283
- q = query20(q, startAfter10(lastDoc));
13778
+ q = query25(q, startAfter10(lastDoc));
11284
13779
  }
11285
- const querySnapshot = await getDocs20(q);
13780
+ const querySnapshot = await getDocs25(q);
11286
13781
  const templates = [];
11287
13782
  let lastVisible = null;
11288
- querySnapshot.forEach((doc26) => {
11289
- templates.push(doc26.data());
11290
- lastVisible = doc26;
13783
+ querySnapshot.forEach((doc32) => {
13784
+ templates.push(doc32.data());
13785
+ lastVisible = doc32;
11291
13786
  });
11292
13787
  return {
11293
13788
  templates,
@@ -11302,21 +13797,21 @@ var DocumentationTemplateService = class extends BaseService {
11302
13797
  * @returns Array of templates and the last document for pagination
11303
13798
  */
11304
13799
  async getTemplatesByCreator(userId, pageSize = 20, lastDoc) {
11305
- let q = query20(
13800
+ let q = query25(
11306
13801
  this.collectionRef,
11307
- where20("createdBy", "==", userId),
11308
- orderBy9("updatedAt", "desc"),
13802
+ where25("createdBy", "==", userId),
13803
+ orderBy13("updatedAt", "desc"),
11309
13804
  limit12(pageSize)
11310
13805
  );
11311
13806
  if (lastDoc) {
11312
- q = query20(q, startAfter10(lastDoc));
13807
+ q = query25(q, startAfter10(lastDoc));
11313
13808
  }
11314
- const querySnapshot = await getDocs20(q);
13809
+ const querySnapshot = await getDocs25(q);
11315
13810
  const templates = [];
11316
13811
  let lastVisible = null;
11317
- querySnapshot.forEach((doc26) => {
11318
- templates.push(doc26.data());
11319
- lastVisible = doc26;
13812
+ querySnapshot.forEach((doc32) => {
13813
+ templates.push(doc32.data());
13814
+ lastVisible = doc32;
11320
13815
  });
11321
13816
  return {
11322
13817
  templates,
@@ -11329,21 +13824,21 @@ var DocumentationTemplateService = class extends BaseService {
11329
13824
  * @returns Array of templates
11330
13825
  */
11331
13826
  async getAllTemplatesForSelection(options) {
11332
- let q = query20(
13827
+ let q = query25(
11333
13828
  this.collectionRef,
11334
- where20("isActive", "==", true),
11335
- orderBy9("updatedAt", "desc")
13829
+ where25("isActive", "==", true),
13830
+ orderBy13("updatedAt", "desc")
11336
13831
  );
11337
13832
  if ((options == null ? void 0 : options.isUserForm) !== void 0) {
11338
- q = query20(q, where20("isUserForm", "==", options.isUserForm));
13833
+ q = query25(q, where25("isUserForm", "==", options.isUserForm));
11339
13834
  }
11340
13835
  if ((options == null ? void 0 : options.isRequired) !== void 0) {
11341
- q = query20(q, where20("isRequired", "==", options.isRequired));
13836
+ q = query25(q, where25("isRequired", "==", options.isRequired));
11342
13837
  }
11343
- const querySnapshot = await getDocs20(q);
13838
+ const querySnapshot = await getDocs25(q);
11344
13839
  const templates = [];
11345
- querySnapshot.forEach((doc26) => {
11346
- templates.push(doc26.data());
13840
+ querySnapshot.forEach((doc32) => {
13841
+ templates.push(doc32.data());
11347
13842
  });
11348
13843
  return templates;
11349
13844
  }
@@ -11351,14 +13846,14 @@ var DocumentationTemplateService = class extends BaseService {
11351
13846
 
11352
13847
  // src/services/documentation-templates/filled-document.service.ts
11353
13848
  import {
11354
- collection as collection21,
11355
- doc as doc21,
11356
- getDoc as getDoc24,
11357
- getDocs as getDocs21,
11358
- setDoc as setDoc20,
11359
- updateDoc as updateDoc21,
11360
- query as query21,
11361
- orderBy as orderBy10,
13849
+ collection as collection26,
13850
+ doc as doc27,
13851
+ getDoc as getDoc29,
13852
+ getDocs as getDocs26,
13853
+ setDoc as setDoc25,
13854
+ updateDoc as updateDoc26,
13855
+ query as query26,
13856
+ orderBy as orderBy14,
11362
13857
  limit as limit13,
11363
13858
  startAfter as startAfter11
11364
13859
  } from "firebase/firestore";
@@ -11416,7 +13911,7 @@ var FilledDocumentService = class extends BaseService {
11416
13911
  values: initialValues,
11417
13912
  status: initialStatus
11418
13913
  };
11419
- const docRef = doc21(
13914
+ const docRef = doc27(
11420
13915
  this.db,
11421
13916
  APPOINTMENTS_COLLECTION,
11422
13917
  // Replaced "appointments"
@@ -11424,7 +13919,7 @@ var FilledDocumentService = class extends BaseService {
11424
13919
  formSubcollection,
11425
13920
  documentId3
11426
13921
  );
11427
- await setDoc20(docRef, filledDocument);
13922
+ await setDoc25(docRef, filledDocument);
11428
13923
  return filledDocument;
11429
13924
  }
11430
13925
  /**
@@ -11436,7 +13931,7 @@ var FilledDocumentService = class extends BaseService {
11436
13931
  */
11437
13932
  async getFilledDocumentFromAppointmentById(appointmentId, formId, isUserForm) {
11438
13933
  const formSubcollection = this.getFormSubcollectionPath(isUserForm);
11439
- const docRef = doc21(
13934
+ const docRef = doc27(
11440
13935
  this.db,
11441
13936
  APPOINTMENTS_COLLECTION,
11442
13937
  // Replaced "appointments"
@@ -11444,7 +13939,7 @@ var FilledDocumentService = class extends BaseService {
11444
13939
  formSubcollection,
11445
13940
  formId
11446
13941
  );
11447
- const docSnap = await getDoc24(docRef);
13942
+ const docSnap = await getDoc29(docRef);
11448
13943
  if (!docSnap.exists()) {
11449
13944
  return null;
11450
13945
  }
@@ -11461,7 +13956,7 @@ var FilledDocumentService = class extends BaseService {
11461
13956
  */
11462
13957
  async updateFilledDocumentInAppointment(appointmentId, formId, isUserForm, values, status) {
11463
13958
  const formSubcollection = this.getFormSubcollectionPath(isUserForm);
11464
- const docRef = doc21(
13959
+ const docRef = doc27(
11465
13960
  this.db,
11466
13961
  APPOINTMENTS_COLLECTION,
11467
13962
  // Replaced "appointments"
@@ -11493,7 +13988,7 @@ var FilledDocumentService = class extends BaseService {
11493
13988
  }
11494
13989
  if (Object.keys(updatePayload).length === 1 && "updatedAt" in updatePayload) {
11495
13990
  }
11496
- await updateDoc21(docRef, updatePayload);
13991
+ await updateDoc26(docRef, updatePayload);
11497
13992
  return { ...existingDoc, ...updatePayload };
11498
13993
  }
11499
13994
  /**
@@ -11503,20 +13998,20 @@ var FilledDocumentService = class extends BaseService {
11503
13998
  * @param lastDoc Last document from previous page for pagination.
11504
13999
  */
11505
14000
  async getFilledUserFormsForAppointment(appointmentId, pageSize = 20, lastDoc) {
11506
- const subcollectionRef = collection21(
14001
+ const subcollectionRef = collection26(
11507
14002
  this.db,
11508
14003
  APPOINTMENTS_COLLECTION,
11509
14004
  // Replaced "appointments"
11510
14005
  appointmentId,
11511
14006
  USER_FORMS_SUBCOLLECTION
11512
14007
  );
11513
- let q = query21(
14008
+ let q = query26(
11514
14009
  subcollectionRef,
11515
- orderBy10("updatedAt", "desc"),
14010
+ orderBy14("updatedAt", "desc"),
11516
14011
  limit13(pageSize)
11517
14012
  );
11518
14013
  if (lastDoc) {
11519
- q = query21(q, startAfter11(lastDoc));
14014
+ q = query26(q, startAfter11(lastDoc));
11520
14015
  }
11521
14016
  return this.executeQuery(q);
11522
14017
  }
@@ -11527,31 +14022,31 @@ var FilledDocumentService = class extends BaseService {
11527
14022
  * @param lastDoc Last document from previous page for pagination.
11528
14023
  */
11529
14024
  async getFilledDoctorFormsForAppointment(appointmentId, pageSize = 20, lastDoc) {
11530
- const subcollectionRef = collection21(
14025
+ const subcollectionRef = collection26(
11531
14026
  this.db,
11532
14027
  APPOINTMENTS_COLLECTION,
11533
14028
  // Replaced "appointments"
11534
14029
  appointmentId,
11535
14030
  DOCTOR_FORMS_SUBCOLLECTION
11536
14031
  );
11537
- let q = query21(
14032
+ let q = query26(
11538
14033
  subcollectionRef,
11539
- orderBy10("updatedAt", "desc"),
14034
+ orderBy14("updatedAt", "desc"),
11540
14035
  limit13(pageSize)
11541
14036
  );
11542
14037
  if (lastDoc) {
11543
- q = query21(q, startAfter11(lastDoc));
14038
+ q = query26(q, startAfter11(lastDoc));
11544
14039
  }
11545
14040
  return this.executeQuery(q);
11546
14041
  }
11547
14042
  // Helper to execute query and return documents + lastDoc
11548
14043
  async executeQuery(q) {
11549
- const querySnapshot = await getDocs21(q);
14044
+ const querySnapshot = await getDocs26(q);
11550
14045
  const documents = [];
11551
14046
  let lastVisible = null;
11552
- querySnapshot.forEach((doc26) => {
11553
- documents.push(doc26.data());
11554
- lastVisible = doc26;
14047
+ querySnapshot.forEach((doc32) => {
14048
+ documents.push(doc32.data());
14049
+ lastVisible = doc32;
11555
14050
  });
11556
14051
  return {
11557
14052
  documents,
@@ -11711,16 +14206,16 @@ var FilledDocumentService = class extends BaseService {
11711
14206
 
11712
14207
  // src/services/notifications/notification.service.ts
11713
14208
  import {
11714
- collection as collection22,
11715
- doc as doc22,
11716
- getDoc as getDoc25,
11717
- getDocs as getDocs22,
11718
- query as query22,
11719
- where as where22,
11720
- updateDoc as updateDoc22,
11721
- deleteDoc as deleteDoc13,
11722
- orderBy as orderBy11,
11723
- Timestamp as Timestamp24,
14209
+ collection as collection27,
14210
+ doc as doc28,
14211
+ getDoc as getDoc30,
14212
+ getDocs as getDocs27,
14213
+ query as query27,
14214
+ where as where27,
14215
+ updateDoc as updateDoc27,
14216
+ deleteDoc as deleteDoc17,
14217
+ orderBy as orderBy15,
14218
+ Timestamp as Timestamp30,
11724
14219
  addDoc as addDoc2,
11725
14220
  writeBatch as writeBatch5
11726
14221
  } from "firebase/firestore";
@@ -11729,8 +14224,8 @@ var NotificationService = class extends BaseService {
11729
14224
  * Kreira novu notifikaciju
11730
14225
  */
11731
14226
  async createNotification(notification) {
11732
- const notificationsRef = collection22(this.db, NOTIFICATIONS_COLLECTION);
11733
- const now = Timestamp24.now();
14227
+ const notificationsRef = collection27(this.db, NOTIFICATIONS_COLLECTION);
14228
+ const now = Timestamp30.now();
11734
14229
  const notificationData = {
11735
14230
  ...notification,
11736
14231
  createdAt: now,
@@ -11749,12 +14244,12 @@ var NotificationService = class extends BaseService {
11749
14244
  * Dohvata notifikaciju po ID-u
11750
14245
  */
11751
14246
  async getNotification(notificationId) {
11752
- const notificationRef = doc22(
14247
+ const notificationRef = doc28(
11753
14248
  this.db,
11754
14249
  NOTIFICATIONS_COLLECTION,
11755
14250
  notificationId
11756
14251
  );
11757
- const notificationDoc = await getDoc25(notificationRef);
14252
+ const notificationDoc = await getDoc30(notificationRef);
11758
14253
  if (!notificationDoc.exists()) {
11759
14254
  return null;
11760
14255
  }
@@ -11767,45 +14262,45 @@ var NotificationService = class extends BaseService {
11767
14262
  * Dohvata sve notifikacije za korisnika
11768
14263
  */
11769
14264
  async getUserNotifications(userId) {
11770
- const q = query22(
11771
- collection22(this.db, NOTIFICATIONS_COLLECTION),
11772
- where22("userId", "==", userId),
11773
- orderBy11("notificationTime", "desc")
11774
- );
11775
- const querySnapshot = await getDocs22(q);
11776
- return querySnapshot.docs.map((doc26) => ({
11777
- id: doc26.id,
11778
- ...doc26.data()
14265
+ const q = query27(
14266
+ collection27(this.db, NOTIFICATIONS_COLLECTION),
14267
+ where27("userId", "==", userId),
14268
+ orderBy15("notificationTime", "desc")
14269
+ );
14270
+ const querySnapshot = await getDocs27(q);
14271
+ return querySnapshot.docs.map((doc32) => ({
14272
+ id: doc32.id,
14273
+ ...doc32.data()
11779
14274
  }));
11780
14275
  }
11781
14276
  /**
11782
14277
  * Dohvata nepročitane notifikacije za korisnika
11783
14278
  */
11784
14279
  async getUnreadNotifications(userId) {
11785
- const q = query22(
11786
- collection22(this.db, NOTIFICATIONS_COLLECTION),
11787
- where22("userId", "==", userId),
11788
- where22("isRead", "==", false),
11789
- orderBy11("notificationTime", "desc")
11790
- );
11791
- const querySnapshot = await getDocs22(q);
11792
- return querySnapshot.docs.map((doc26) => ({
11793
- id: doc26.id,
11794
- ...doc26.data()
14280
+ const q = query27(
14281
+ collection27(this.db, NOTIFICATIONS_COLLECTION),
14282
+ where27("userId", "==", userId),
14283
+ where27("isRead", "==", false),
14284
+ orderBy15("notificationTime", "desc")
14285
+ );
14286
+ const querySnapshot = await getDocs27(q);
14287
+ return querySnapshot.docs.map((doc32) => ({
14288
+ id: doc32.id,
14289
+ ...doc32.data()
11795
14290
  }));
11796
14291
  }
11797
14292
  /**
11798
14293
  * Označava notifikaciju kao pročitanu
11799
14294
  */
11800
14295
  async markAsRead(notificationId) {
11801
- const notificationRef = doc22(
14296
+ const notificationRef = doc28(
11802
14297
  this.db,
11803
14298
  NOTIFICATIONS_COLLECTION,
11804
14299
  notificationId
11805
14300
  );
11806
- await updateDoc22(notificationRef, {
14301
+ await updateDoc27(notificationRef, {
11807
14302
  isRead: true,
11808
- updatedAt: Timestamp24.now()
14303
+ updatedAt: Timestamp30.now()
11809
14304
  });
11810
14305
  }
11811
14306
  /**
@@ -11815,14 +14310,14 @@ var NotificationService = class extends BaseService {
11815
14310
  const notifications = await this.getUnreadNotifications(userId);
11816
14311
  const batch = writeBatch5(this.db);
11817
14312
  notifications.forEach((notification) => {
11818
- const notificationRef = doc22(
14313
+ const notificationRef = doc28(
11819
14314
  this.db,
11820
14315
  NOTIFICATIONS_COLLECTION,
11821
14316
  notification.id
11822
14317
  );
11823
14318
  batch.update(notificationRef, {
11824
14319
  isRead: true,
11825
- updatedAt: Timestamp24.now()
14320
+ updatedAt: Timestamp30.now()
11826
14321
  });
11827
14322
  });
11828
14323
  await batch.commit();
@@ -11831,86 +14326,86 @@ var NotificationService = class extends BaseService {
11831
14326
  * Ažurira status notifikacije
11832
14327
  */
11833
14328
  async updateNotificationStatus(notificationId, status) {
11834
- const notificationRef = doc22(
14329
+ const notificationRef = doc28(
11835
14330
  this.db,
11836
14331
  NOTIFICATIONS_COLLECTION,
11837
14332
  notificationId
11838
14333
  );
11839
- await updateDoc22(notificationRef, {
14334
+ await updateDoc27(notificationRef, {
11840
14335
  status,
11841
- updatedAt: Timestamp24.now()
14336
+ updatedAt: Timestamp30.now()
11842
14337
  });
11843
14338
  }
11844
14339
  /**
11845
14340
  * Briše notifikaciju
11846
14341
  */
11847
14342
  async deleteNotification(notificationId) {
11848
- const notificationRef = doc22(
14343
+ const notificationRef = doc28(
11849
14344
  this.db,
11850
14345
  NOTIFICATIONS_COLLECTION,
11851
14346
  notificationId
11852
14347
  );
11853
- await deleteDoc13(notificationRef);
14348
+ await deleteDoc17(notificationRef);
11854
14349
  }
11855
14350
  /**
11856
14351
  * Dohvata notifikacije po tipu
11857
14352
  */
11858
14353
  async getNotificationsByType(userId, type) {
11859
- const q = query22(
11860
- collection22(this.db, NOTIFICATIONS_COLLECTION),
11861
- where22("userId", "==", userId),
11862
- where22("notificationType", "==", type),
11863
- orderBy11("notificationTime", "desc")
11864
- );
11865
- const querySnapshot = await getDocs22(q);
11866
- return querySnapshot.docs.map((doc26) => ({
11867
- id: doc26.id,
11868
- ...doc26.data()
14354
+ const q = query27(
14355
+ collection27(this.db, NOTIFICATIONS_COLLECTION),
14356
+ where27("userId", "==", userId),
14357
+ where27("notificationType", "==", type),
14358
+ orderBy15("notificationTime", "desc")
14359
+ );
14360
+ const querySnapshot = await getDocs27(q);
14361
+ return querySnapshot.docs.map((doc32) => ({
14362
+ id: doc32.id,
14363
+ ...doc32.data()
11869
14364
  }));
11870
14365
  }
11871
14366
  /**
11872
14367
  * Dohvata notifikacije za određeni termin
11873
14368
  */
11874
14369
  async getAppointmentNotifications(appointmentId) {
11875
- const q = query22(
11876
- collection22(this.db, NOTIFICATIONS_COLLECTION),
11877
- where22("appointmentId", "==", appointmentId),
11878
- orderBy11("notificationTime", "desc")
11879
- );
11880
- const querySnapshot = await getDocs22(q);
11881
- return querySnapshot.docs.map((doc26) => ({
11882
- id: doc26.id,
11883
- ...doc26.data()
14370
+ const q = query27(
14371
+ collection27(this.db, NOTIFICATIONS_COLLECTION),
14372
+ where27("appointmentId", "==", appointmentId),
14373
+ orderBy15("notificationTime", "desc")
14374
+ );
14375
+ const querySnapshot = await getDocs27(q);
14376
+ return querySnapshot.docs.map((doc32) => ({
14377
+ id: doc32.id,
14378
+ ...doc32.data()
11884
14379
  }));
11885
14380
  }
11886
14381
  };
11887
14382
 
11888
14383
  // src/services/patient/patientRequirements.service.ts
11889
14384
  import {
11890
- collection as collection23,
11891
- getDocs as getDocs23,
11892
- query as query23,
11893
- where as where23,
11894
- doc as doc23,
11895
- updateDoc as updateDoc23,
11896
- Timestamp as Timestamp25,
11897
- orderBy as orderBy12,
14385
+ collection as collection28,
14386
+ getDocs as getDocs28,
14387
+ query as query28,
14388
+ where as where28,
14389
+ doc as doc29,
14390
+ updateDoc as updateDoc28,
14391
+ Timestamp as Timestamp31,
14392
+ orderBy as orderBy16,
11898
14393
  limit as limit14,
11899
14394
  startAfter as startAfter12,
11900
- getDoc as getDoc26
14395
+ getDoc as getDoc31
11901
14396
  } from "firebase/firestore";
11902
14397
  var PatientRequirementsService = class extends BaseService {
11903
14398
  constructor(db, auth, app) {
11904
14399
  super(db, auth, app);
11905
14400
  }
11906
14401
  getPatientRequirementsCollectionRef(patientId) {
11907
- return collection23(
14402
+ return collection28(
11908
14403
  this.db,
11909
14404
  `patients/${patientId}/${PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME}`
11910
14405
  );
11911
14406
  }
11912
14407
  getPatientRequirementDocRef(patientId, instanceId) {
11913
- return doc23(
14408
+ return doc29(
11914
14409
  this.getPatientRequirementsCollectionRef(patientId),
11915
14410
  instanceId
11916
14411
  );
@@ -11923,7 +14418,7 @@ var PatientRequirementsService = class extends BaseService {
11923
14418
  */
11924
14419
  async getPatientRequirementInstance(patientId, instanceId) {
11925
14420
  const docRef = this.getPatientRequirementDocRef(patientId, instanceId);
11926
- const docSnap = await getDoc26(docRef);
14421
+ const docSnap = await getDoc31(docRef);
11927
14422
  if (!docSnap.exists()) {
11928
14423
  return null;
11929
14424
  }
@@ -11942,22 +14437,22 @@ var PatientRequirementsService = class extends BaseService {
11942
14437
  */
11943
14438
  async getAllPatientRequirementInstances(patientId, filters, pageLimit = 20, lastVisible) {
11944
14439
  const collRef = this.getPatientRequirementsCollectionRef(patientId);
11945
- let q = query23(collRef, orderBy12("createdAt", "desc"));
14440
+ let q = query28(collRef, orderBy16("createdAt", "desc"));
11946
14441
  const queryConstraints = [];
11947
14442
  if ((filters == null ? void 0 : filters.appointmentId) && filters.appointmentId !== "all") {
11948
14443
  queryConstraints.push(
11949
- where23("appointmentId", "==", filters.appointmentId)
14444
+ where28("appointmentId", "==", filters.appointmentId)
11950
14445
  );
11951
14446
  }
11952
14447
  if ((filters == null ? void 0 : filters.statuses) && filters.statuses.length > 0) {
11953
- queryConstraints.push(where23("overallStatus", "in", filters.statuses));
14448
+ queryConstraints.push(where28("overallStatus", "in", filters.statuses));
11954
14449
  }
11955
14450
  if (lastVisible) {
11956
14451
  queryConstraints.push(startAfter12(lastVisible));
11957
14452
  }
11958
14453
  queryConstraints.push(limit14(pageLimit));
11959
- q = query23(collRef, ...queryConstraints);
11960
- const snapshot = await getDocs23(q);
14454
+ q = query28(collRef, ...queryConstraints);
14455
+ const snapshot = await getDocs28(q);
11961
14456
  let requirements = snapshot.docs.map((docSnap) => {
11962
14457
  const data = docSnap.data();
11963
14458
  return { id: docSnap.id, ...data };
@@ -12000,7 +14495,7 @@ var PatientRequirementsService = class extends BaseService {
12000
14495
  */
12001
14496
  async completeInstruction(patientId, instanceId, instructionId) {
12002
14497
  const instanceRef = this.getPatientRequirementDocRef(patientId, instanceId);
12003
- const instanceSnap = await getDoc26(instanceRef);
14498
+ const instanceSnap = await getDoc31(instanceRef);
12004
14499
  if (!instanceSnap.exists()) {
12005
14500
  throw new Error(
12006
14501
  `PatientRequirementInstance ${instanceId} not found for patient ${patientId}.`
@@ -12028,7 +14523,7 @@ var PatientRequirementsService = class extends BaseService {
12028
14523
  `Instruction ${instructionId} is in status ${instructionToUpdate.status} and cannot be marked as completed.`
12029
14524
  );
12030
14525
  }
12031
- const now = Timestamp25.now();
14526
+ const now = Timestamp31.now();
12032
14527
  const updatedInstructions = [...instance.instructions];
12033
14528
  updatedInstructions[instructionIndex] = {
12034
14529
  ...instructionToUpdate,
@@ -12055,7 +14550,7 @@ var PatientRequirementsService = class extends BaseService {
12055
14550
  if (newOverallStatus !== instance.overallStatus) {
12056
14551
  updatePayload.overallStatus = newOverallStatus;
12057
14552
  }
12058
- await updateDoc23(instanceRef, updatePayload);
14553
+ await updateDoc28(instanceRef, updatePayload);
12059
14554
  return {
12060
14555
  ...instance,
12061
14556
  instructions: updatedInstructions,
@@ -12069,18 +14564,18 @@ var PatientRequirementsService = class extends BaseService {
12069
14564
 
12070
14565
  // src/services/procedure/procedure.service.ts
12071
14566
  import {
12072
- collection as collection24,
12073
- doc as doc24,
12074
- getDoc as getDoc27,
12075
- getDocs as getDocs24,
12076
- query as query24,
12077
- where as where24,
12078
- updateDoc as updateDoc24,
12079
- setDoc as setDoc21,
12080
- deleteDoc as deleteDoc14,
12081
- serverTimestamp as serverTimestamp20,
14567
+ collection as collection29,
14568
+ doc as doc30,
14569
+ getDoc as getDoc32,
14570
+ getDocs as getDocs29,
14571
+ query as query29,
14572
+ where as where29,
14573
+ updateDoc as updateDoc29,
14574
+ setDoc as setDoc26,
14575
+ deleteDoc as deleteDoc18,
14576
+ serverTimestamp as serverTimestamp25,
12082
14577
  writeBatch as writeBatch6,
12083
- orderBy as orderBy13,
14578
+ orderBy as orderBy17,
12084
14579
  limit as limit15,
12085
14580
  startAfter as startAfter13,
12086
14581
  documentId as documentId2
@@ -12239,24 +14734,24 @@ var ProcedureService = class extends BaseService {
12239
14734
  if (!category || !subcategory || !technology || !product) {
12240
14735
  throw new Error("One or more required base entities not found");
12241
14736
  }
12242
- const clinicRef = doc24(
14737
+ const clinicRef = doc30(
12243
14738
  this.db,
12244
14739
  CLINICS_COLLECTION,
12245
14740
  validatedData.clinicBranchId
12246
14741
  );
12247
- const clinicSnapshot = await getDoc27(clinicRef);
14742
+ const clinicSnapshot = await getDoc32(clinicRef);
12248
14743
  if (!clinicSnapshot.exists()) {
12249
14744
  throw new Error(
12250
14745
  `Clinic with ID ${validatedData.clinicBranchId} not found`
12251
14746
  );
12252
14747
  }
12253
14748
  const clinic = clinicSnapshot.data();
12254
- const practitionerRef = doc24(
14749
+ const practitionerRef = doc30(
12255
14750
  this.db,
12256
14751
  PRACTITIONERS_COLLECTION,
12257
14752
  validatedData.practitionerId
12258
14753
  );
12259
- const practitionerSnapshot = await getDoc27(practitionerRef);
14754
+ const practitionerSnapshot = await getDoc32(practitionerRef);
12260
14755
  if (!practitionerSnapshot.exists()) {
12261
14756
  throw new Error(
12262
14757
  `Practitioner with ID ${validatedData.practitionerId} not found`
@@ -12322,13 +14817,13 @@ var ProcedureService = class extends BaseService {
12322
14817
  isActive: true
12323
14818
  // Default to active
12324
14819
  };
12325
- const procedureRef = doc24(this.db, PROCEDURES_COLLECTION, procedureId);
12326
- await setDoc21(procedureRef, {
14820
+ const procedureRef = doc30(this.db, PROCEDURES_COLLECTION, procedureId);
14821
+ await setDoc26(procedureRef, {
12327
14822
  ...newProcedure,
12328
- createdAt: serverTimestamp20(),
12329
- updatedAt: serverTimestamp20()
14823
+ createdAt: serverTimestamp25(),
14824
+ updatedAt: serverTimestamp25()
12330
14825
  });
12331
- const savedDoc = await getDoc27(procedureRef);
14826
+ const savedDoc = await getDoc32(procedureRef);
12332
14827
  return savedDoc.data();
12333
14828
  }
12334
14829
  /**
@@ -12357,7 +14852,7 @@ var ProcedureService = class extends BaseService {
12357
14852
  validatedData.technologyId,
12358
14853
  validatedData.productId
12359
14854
  ),
12360
- getDoc27(doc24(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId))
14855
+ getDoc32(doc30(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId))
12361
14856
  ]);
12362
14857
  if (!category || !subcategory || !technology || !product) {
12363
14858
  throw new Error("One or more required base entities not found");
@@ -12380,13 +14875,13 @@ var ProcedureService = class extends BaseService {
12380
14875
  const practitionersMap = /* @__PURE__ */ new Map();
12381
14876
  for (let i = 0; i < practitionerIds.length; i += 30) {
12382
14877
  const chunk = practitionerIds.slice(i, i + 30);
12383
- const practitionersQuery = query24(
12384
- collection24(this.db, PRACTITIONERS_COLLECTION),
12385
- where24(documentId2(), "in", chunk)
14878
+ const practitionersQuery = query29(
14879
+ collection29(this.db, PRACTITIONERS_COLLECTION),
14880
+ where29(documentId2(), "in", chunk)
12386
14881
  );
12387
- const practitionersSnapshot = await getDocs24(practitionersQuery);
12388
- practitionersSnapshot.docs.forEach((doc26) => {
12389
- practitionersMap.set(doc26.id, doc26.data());
14882
+ const practitionersSnapshot = await getDocs29(practitionersQuery);
14883
+ practitionersSnapshot.docs.forEach((doc32) => {
14884
+ practitionersMap.set(doc32.id, doc32.data());
12390
14885
  });
12391
14886
  }
12392
14887
  if (practitionersMap.size !== practitionerIds.length) {
@@ -12420,7 +14915,7 @@ var ProcedureService = class extends BaseService {
12420
14915
  };
12421
14916
  const procedureId = this.generateId();
12422
14917
  createdProcedureIds.push(procedureId);
12423
- const procedureRef = doc24(this.db, PROCEDURES_COLLECTION, procedureId);
14918
+ const procedureRef = doc30(this.db, PROCEDURES_COLLECTION, procedureId);
12424
14919
  const newProcedure = {
12425
14920
  id: procedureId,
12426
14921
  ...validatedData,
@@ -12455,21 +14950,21 @@ var ProcedureService = class extends BaseService {
12455
14950
  };
12456
14951
  batch.set(procedureRef, {
12457
14952
  ...newProcedure,
12458
- createdAt: serverTimestamp20(),
12459
- updatedAt: serverTimestamp20()
14953
+ createdAt: serverTimestamp25(),
14954
+ updatedAt: serverTimestamp25()
12460
14955
  });
12461
14956
  }
12462
14957
  await batch.commit();
12463
14958
  const fetchedProcedures = [];
12464
14959
  for (let i = 0; i < createdProcedureIds.length; i += 30) {
12465
14960
  const chunk = createdProcedureIds.slice(i, i + 30);
12466
- const q = query24(
12467
- collection24(this.db, PROCEDURES_COLLECTION),
12468
- where24(documentId2(), "in", chunk)
14961
+ const q = query29(
14962
+ collection29(this.db, PROCEDURES_COLLECTION),
14963
+ where29(documentId2(), "in", chunk)
12469
14964
  );
12470
- const snapshot = await getDocs24(q);
12471
- snapshot.forEach((doc26) => {
12472
- fetchedProcedures.push(doc26.data());
14965
+ const snapshot = await getDocs29(q);
14966
+ snapshot.forEach((doc32) => {
14967
+ fetchedProcedures.push(doc32.data());
12473
14968
  });
12474
14969
  }
12475
14970
  return fetchedProcedures;
@@ -12480,8 +14975,8 @@ var ProcedureService = class extends BaseService {
12480
14975
  * @returns The procedure if found, null otherwise
12481
14976
  */
12482
14977
  async getProcedure(id) {
12483
- const docRef = doc24(this.db, PROCEDURES_COLLECTION, id);
12484
- const docSnap = await getDoc27(docRef);
14978
+ const docRef = doc30(this.db, PROCEDURES_COLLECTION, id);
14979
+ const docSnap = await getDoc32(docRef);
12485
14980
  if (!docSnap.exists()) {
12486
14981
  return null;
12487
14982
  }
@@ -12493,13 +14988,13 @@ var ProcedureService = class extends BaseService {
12493
14988
  * @returns List of procedures
12494
14989
  */
12495
14990
  async getProceduresByClinicBranch(clinicBranchId) {
12496
- const q = query24(
12497
- collection24(this.db, PROCEDURES_COLLECTION),
12498
- where24("clinicBranchId", "==", clinicBranchId),
12499
- where24("isActive", "==", true)
14991
+ const q = query29(
14992
+ collection29(this.db, PROCEDURES_COLLECTION),
14993
+ where29("clinicBranchId", "==", clinicBranchId),
14994
+ where29("isActive", "==", true)
12500
14995
  );
12501
- const snapshot = await getDocs24(q);
12502
- return snapshot.docs.map((doc26) => doc26.data());
14996
+ const snapshot = await getDocs29(q);
14997
+ return snapshot.docs.map((doc32) => doc32.data());
12503
14998
  }
12504
14999
  /**
12505
15000
  * Gets all procedures for a practitioner
@@ -12507,13 +15002,13 @@ var ProcedureService = class extends BaseService {
12507
15002
  * @returns List of procedures
12508
15003
  */
12509
15004
  async getProceduresByPractitioner(practitionerId) {
12510
- const q = query24(
12511
- collection24(this.db, PROCEDURES_COLLECTION),
12512
- where24("practitionerId", "==", practitionerId),
12513
- where24("isActive", "==", true)
15005
+ const q = query29(
15006
+ collection29(this.db, PROCEDURES_COLLECTION),
15007
+ where29("practitionerId", "==", practitionerId),
15008
+ where29("isActive", "==", true)
12514
15009
  );
12515
- const snapshot = await getDocs24(q);
12516
- return snapshot.docs.map((doc26) => doc26.data());
15010
+ const snapshot = await getDocs29(q);
15011
+ return snapshot.docs.map((doc32) => doc32.data());
12517
15012
  }
12518
15013
  /**
12519
15014
  * Gets all inactive procedures for a practitioner
@@ -12521,13 +15016,13 @@ var ProcedureService = class extends BaseService {
12521
15016
  * @returns List of inactive procedures
12522
15017
  */
12523
15018
  async getInactiveProceduresByPractitioner(practitionerId) {
12524
- const q = query24(
12525
- collection24(this.db, PROCEDURES_COLLECTION),
12526
- where24("practitionerId", "==", practitionerId),
12527
- where24("isActive", "==", false)
15019
+ const q = query29(
15020
+ collection29(this.db, PROCEDURES_COLLECTION),
15021
+ where29("practitionerId", "==", practitionerId),
15022
+ where29("isActive", "==", false)
12528
15023
  );
12529
- const snapshot = await getDocs24(q);
12530
- return snapshot.docs.map((doc26) => doc26.data());
15024
+ const snapshot = await getDocs29(q);
15025
+ return snapshot.docs.map((doc32) => doc32.data());
12531
15026
  }
12532
15027
  /**
12533
15028
  * Updates a procedure
@@ -12538,8 +15033,8 @@ var ProcedureService = class extends BaseService {
12538
15033
  async updateProcedure(id, data) {
12539
15034
  var _a;
12540
15035
  const validatedData = updateProcedureSchema.parse(data);
12541
- const procedureRef = doc24(this.db, PROCEDURES_COLLECTION, id);
12542
- const procedureSnapshot = await getDoc27(procedureRef);
15036
+ const procedureRef = doc30(this.db, PROCEDURES_COLLECTION, id);
15037
+ const procedureSnapshot = await getDoc32(procedureRef);
12543
15038
  if (!procedureSnapshot.exists()) {
12544
15039
  throw new Error(`Procedure with ID ${id} not found`);
12545
15040
  }
@@ -12560,12 +15055,12 @@ var ProcedureService = class extends BaseService {
12560
15055
  }
12561
15056
  if (validatedData.practitionerId && validatedData.practitionerId !== oldPractitionerId) {
12562
15057
  practitionerChanged = true;
12563
- const newPractitionerRef = doc24(
15058
+ const newPractitionerRef = doc30(
12564
15059
  this.db,
12565
15060
  PRACTITIONERS_COLLECTION,
12566
15061
  validatedData.practitionerId
12567
15062
  );
12568
- const newPractitionerSnap = await getDoc27(newPractitionerRef);
15063
+ const newPractitionerSnap = await getDoc32(newPractitionerRef);
12569
15064
  if (!newPractitionerSnap.exists())
12570
15065
  throw new Error(
12571
15066
  `New Practitioner ${validatedData.practitionerId} not found`
@@ -12583,12 +15078,12 @@ var ProcedureService = class extends BaseService {
12583
15078
  }
12584
15079
  if (validatedData.clinicBranchId && validatedData.clinicBranchId !== oldClinicId) {
12585
15080
  clinicChanged = true;
12586
- const newClinicRef = doc24(
15081
+ const newClinicRef = doc30(
12587
15082
  this.db,
12588
15083
  CLINICS_COLLECTION,
12589
15084
  validatedData.clinicBranchId
12590
15085
  );
12591
- const newClinicSnap = await getDoc27(newClinicRef);
15086
+ const newClinicSnap = await getDoc32(newClinicRef);
12592
15087
  if (!newClinicSnap.exists())
12593
15088
  throw new Error(`New Clinic ${validatedData.clinicBranchId} not found`);
12594
15089
  newClinic = newClinicSnap.data();
@@ -12655,11 +15150,11 @@ var ProcedureService = class extends BaseService {
12655
15150
  } else if (validatedData.productId) {
12656
15151
  console.warn("Attempted to update product without a valid technologyId");
12657
15152
  }
12658
- await updateDoc24(procedureRef, {
15153
+ await updateDoc29(procedureRef, {
12659
15154
  ...updatedProcedureData,
12660
- updatedAt: serverTimestamp20()
15155
+ updatedAt: serverTimestamp25()
12661
15156
  });
12662
- const updatedSnapshot = await getDoc27(procedureRef);
15157
+ const updatedSnapshot = await getDoc32(procedureRef);
12663
15158
  return updatedSnapshot.data();
12664
15159
  }
12665
15160
  /**
@@ -12667,15 +15162,15 @@ var ProcedureService = class extends BaseService {
12667
15162
  * @param id - The ID of the procedure to deactivate
12668
15163
  */
12669
15164
  async deactivateProcedure(id) {
12670
- const procedureRef = doc24(this.db, PROCEDURES_COLLECTION, id);
12671
- const procedureSnap = await getDoc27(procedureRef);
15165
+ const procedureRef = doc30(this.db, PROCEDURES_COLLECTION, id);
15166
+ const procedureSnap = await getDoc32(procedureRef);
12672
15167
  if (!procedureSnap.exists()) {
12673
15168
  console.warn(`Procedure ${id} not found for deactivation.`);
12674
15169
  return;
12675
15170
  }
12676
- await updateDoc24(procedureRef, {
15171
+ await updateDoc29(procedureRef, {
12677
15172
  isActive: false,
12678
- updatedAt: serverTimestamp20()
15173
+ updatedAt: serverTimestamp25()
12679
15174
  });
12680
15175
  }
12681
15176
  /**
@@ -12684,12 +15179,12 @@ var ProcedureService = class extends BaseService {
12684
15179
  * @returns A boolean indicating if the deletion was successful
12685
15180
  */
12686
15181
  async deleteProcedure(id) {
12687
- const procedureRef = doc24(this.db, PROCEDURES_COLLECTION, id);
12688
- const procedureSnapshot = await getDoc27(procedureRef);
15182
+ const procedureRef = doc30(this.db, PROCEDURES_COLLECTION, id);
15183
+ const procedureSnapshot = await getDoc32(procedureRef);
12689
15184
  if (!procedureSnapshot.exists()) {
12690
15185
  return false;
12691
15186
  }
12692
- await deleteDoc14(procedureRef);
15187
+ await deleteDoc18(procedureRef);
12693
15188
  return true;
12694
15189
  }
12695
15190
  /**
@@ -12715,35 +15210,35 @@ var ProcedureService = class extends BaseService {
12715
15210
  */
12716
15211
  async getAllProcedures(pagination, lastDoc) {
12717
15212
  try {
12718
- const proceduresCollection = collection24(this.db, PROCEDURES_COLLECTION);
12719
- let proceduresQuery = query24(proceduresCollection);
15213
+ const proceduresCollection = collection29(this.db, PROCEDURES_COLLECTION);
15214
+ let proceduresQuery = query29(proceduresCollection);
12720
15215
  if (pagination && pagination > 0) {
12721
15216
  const { limit: limit16, startAfter: startAfter14 } = await import("firebase/firestore");
12722
15217
  if (lastDoc) {
12723
- proceduresQuery = query24(
15218
+ proceduresQuery = query29(
12724
15219
  proceduresCollection,
12725
- orderBy13("name"),
15220
+ orderBy17("name"),
12726
15221
  // Use imported orderBy
12727
15222
  startAfter14(lastDoc),
12728
15223
  limit16(pagination)
12729
15224
  );
12730
15225
  } else {
12731
- proceduresQuery = query24(
15226
+ proceduresQuery = query29(
12732
15227
  proceduresCollection,
12733
- orderBy13("name"),
15228
+ orderBy17("name"),
12734
15229
  limit16(pagination)
12735
15230
  );
12736
15231
  }
12737
15232
  } else {
12738
- proceduresQuery = query24(proceduresCollection, orderBy13("name"));
15233
+ proceduresQuery = query29(proceduresCollection, orderBy17("name"));
12739
15234
  }
12740
- const proceduresSnapshot = await getDocs24(proceduresQuery);
15235
+ const proceduresSnapshot = await getDocs29(proceduresQuery);
12741
15236
  const lastVisible = proceduresSnapshot.docs[proceduresSnapshot.docs.length - 1];
12742
- const procedures = proceduresSnapshot.docs.map((doc26) => {
12743
- const data = doc26.data();
15237
+ const procedures = proceduresSnapshot.docs.map((doc32) => {
15238
+ const data = doc32.data();
12744
15239
  return {
12745
15240
  ...data,
12746
- id: doc26.id
15241
+ id: doc32.id
12747
15242
  // Ensure ID is present
12748
15243
  };
12749
15244
  });
@@ -12786,14 +15281,14 @@ var ProcedureService = class extends BaseService {
12786
15281
  const isGeoQuery = filters.location && filters.radiusInKm && filters.radiusInKm > 0;
12787
15282
  const constraints = [];
12788
15283
  if (filters.isActive !== void 0) {
12789
- constraints.push(where24("isActive", "==", filters.isActive));
15284
+ constraints.push(where29("isActive", "==", filters.isActive));
12790
15285
  } else {
12791
- constraints.push(where24("isActive", "==", true));
15286
+ constraints.push(where29("isActive", "==", true));
12792
15287
  }
12793
15288
  if (filters.procedureFamily) {
12794
- constraints.push(where24("family", "==", filters.procedureFamily));
15289
+ constraints.push(where29("family", "==", filters.procedureFamily));
12795
15290
  }
12796
- constraints.push(orderBy13("clinicInfo.location.geohash"));
15291
+ constraints.push(orderBy17("clinicInfo.location.geohash"));
12797
15292
  if (filters.pagination && filters.pagination > 0 && filters.lastDoc) {
12798
15293
  constraints.push(startAfter13(filters.lastDoc));
12799
15294
  constraints.push(limit15(filters.pagination));
@@ -12814,19 +15309,19 @@ var ProcedureService = class extends BaseService {
12814
15309
  for (const bound of bounds) {
12815
15310
  const geoConstraints = [
12816
15311
  ...constraints,
12817
- where24("clinicInfo.location.geohash", ">=", bound[0]),
12818
- where24("clinicInfo.location.geohash", "<=", bound[1])
15312
+ where29("clinicInfo.location.geohash", ">=", bound[0]),
15313
+ where29("clinicInfo.location.geohash", "<=", bound[1])
12819
15314
  ];
12820
- const q = query24(
12821
- collection24(this.db, PROCEDURES_COLLECTION),
15315
+ const q = query29(
15316
+ collection29(this.db, PROCEDURES_COLLECTION),
12822
15317
  ...geoConstraints
12823
15318
  );
12824
- const querySnapshot = await getDocs24(q);
15319
+ const querySnapshot = await getDocs29(q);
12825
15320
  console.log(
12826
15321
  `[PROCEDURE_SERVICE] Found ${querySnapshot.docs.length} procedures in geo bound`
12827
15322
  );
12828
- for (const doc26 of querySnapshot.docs) {
12829
- const procedure = { ...doc26.data(), id: doc26.id };
15323
+ for (const doc32 of querySnapshot.docs) {
15324
+ const procedure = { ...doc32.data(), id: doc32.id };
12830
15325
  const distance = distanceBetween6(
12831
15326
  [center.latitude, center.longitude],
12832
15327
  [
@@ -12869,16 +15364,16 @@ var ProcedureService = class extends BaseService {
12869
15364
  proceduresResult = filteredProcedures;
12870
15365
  }
12871
15366
  } else {
12872
- const q = query24(
12873
- collection24(this.db, PROCEDURES_COLLECTION),
15367
+ const q = query29(
15368
+ collection29(this.db, PROCEDURES_COLLECTION),
12874
15369
  ...constraints
12875
15370
  );
12876
- const querySnapshot = await getDocs24(q);
15371
+ const querySnapshot = await getDocs29(q);
12877
15372
  console.log(
12878
15373
  `[PROCEDURE_SERVICE] Found ${querySnapshot.docs.length} procedures with regular query`
12879
15374
  );
12880
- const procedures = querySnapshot.docs.map((doc26) => {
12881
- return { ...doc26.data(), id: doc26.id };
15375
+ const procedures = querySnapshot.docs.map((doc32) => {
15376
+ return { ...doc32.data(), id: doc32.id };
12882
15377
  });
12883
15378
  if (filters.location) {
12884
15379
  const center = filters.location;
@@ -12999,18 +15494,18 @@ var ProcedureService = class extends BaseService {
12999
15494
  if (!category || !subcategory || !technology) {
13000
15495
  throw new Error("One or more required base entities not found");
13001
15496
  }
13002
- const clinicRef = doc24(this.db, CLINICS_COLLECTION, data.clinicBranchId);
13003
- const clinicSnapshot = await getDoc27(clinicRef);
15497
+ const clinicRef = doc30(this.db, CLINICS_COLLECTION, data.clinicBranchId);
15498
+ const clinicSnapshot = await getDoc32(clinicRef);
13004
15499
  if (!clinicSnapshot.exists()) {
13005
15500
  throw new Error(`Clinic with ID ${data.clinicBranchId} not found`);
13006
15501
  }
13007
15502
  const clinic = clinicSnapshot.data();
13008
- const practitionerRef = doc24(
15503
+ const practitionerRef = doc30(
13009
15504
  this.db,
13010
15505
  PRACTITIONERS_COLLECTION,
13011
15506
  data.practitionerId
13012
15507
  );
13013
- const practitionerSnapshot = await getDoc27(practitionerRef);
15508
+ const practitionerSnapshot = await getDoc32(practitionerRef);
13014
15509
  if (!practitionerSnapshot.exists()) {
13015
15510
  throw new Error(`Practitioner with ID ${data.practitionerId} not found`);
13016
15511
  }
@@ -13081,28 +15576,28 @@ var ProcedureService = class extends BaseService {
13081
15576
  },
13082
15577
  isActive: true
13083
15578
  };
13084
- const procedureRef = doc24(this.db, PROCEDURES_COLLECTION, procedureId);
13085
- await setDoc21(procedureRef, {
15579
+ const procedureRef = doc30(this.db, PROCEDURES_COLLECTION, procedureId);
15580
+ await setDoc26(procedureRef, {
13086
15581
  ...newProcedure,
13087
- createdAt: serverTimestamp20(),
13088
- updatedAt: serverTimestamp20()
15582
+ createdAt: serverTimestamp25(),
15583
+ updatedAt: serverTimestamp25()
13089
15584
  });
13090
- const savedDoc = await getDoc27(procedureRef);
15585
+ const savedDoc = await getDoc32(procedureRef);
13091
15586
  return savedDoc.data();
13092
15587
  }
13093
15588
  };
13094
15589
 
13095
15590
  // src/services/reviews/reviews.service.ts
13096
15591
  import {
13097
- collection as collection25,
13098
- doc as doc25,
13099
- getDoc as getDoc28,
13100
- getDocs as getDocs25,
13101
- query as query25,
13102
- where as where25,
13103
- setDoc as setDoc22,
13104
- deleteDoc as deleteDoc15,
13105
- serverTimestamp as serverTimestamp21
15592
+ collection as collection30,
15593
+ doc as doc31,
15594
+ getDoc as getDoc33,
15595
+ getDocs as getDocs30,
15596
+ query as query30,
15597
+ where as where30,
15598
+ setDoc as setDoc27,
15599
+ deleteDoc as deleteDoc19,
15600
+ serverTimestamp as serverTimestamp26
13106
15601
  } from "firebase/firestore";
13107
15602
  import { z as z25 } from "zod";
13108
15603
  var ReviewService = class extends BaseService {
@@ -13183,11 +15678,11 @@ var ReviewService = class extends BaseService {
13183
15678
  updatedAt: now
13184
15679
  };
13185
15680
  reviewSchema.parse(review);
13186
- const docRef = doc25(this.db, REVIEWS_COLLECTION, reviewId);
13187
- await setDoc22(docRef, {
15681
+ const docRef = doc31(this.db, REVIEWS_COLLECTION, reviewId);
15682
+ await setDoc27(docRef, {
13188
15683
  ...review,
13189
- createdAt: serverTimestamp21(),
13190
- updatedAt: serverTimestamp21()
15684
+ createdAt: serverTimestamp26(),
15685
+ updatedAt: serverTimestamp26()
13191
15686
  });
13192
15687
  return review;
13193
15688
  } catch (error) {
@@ -13203,8 +15698,8 @@ var ReviewService = class extends BaseService {
13203
15698
  * @returns The review if found, null otherwise
13204
15699
  */
13205
15700
  async getReview(reviewId) {
13206
- const docRef = doc25(this.db, REVIEWS_COLLECTION, reviewId);
13207
- const docSnap = await getDoc28(docRef);
15701
+ const docRef = doc31(this.db, REVIEWS_COLLECTION, reviewId);
15702
+ const docSnap = await getDoc33(docRef);
13208
15703
  if (!docSnap.exists()) {
13209
15704
  return null;
13210
15705
  }
@@ -13216,12 +15711,12 @@ var ReviewService = class extends BaseService {
13216
15711
  * @returns Array of reviews for the patient
13217
15712
  */
13218
15713
  async getReviewsByPatient(patientId) {
13219
- const q = query25(
13220
- collection25(this.db, REVIEWS_COLLECTION),
13221
- where25("patientId", "==", patientId)
15714
+ const q = query30(
15715
+ collection30(this.db, REVIEWS_COLLECTION),
15716
+ where30("patientId", "==", patientId)
13222
15717
  );
13223
- const snapshot = await getDocs25(q);
13224
- return snapshot.docs.map((doc26) => doc26.data());
15718
+ const snapshot = await getDocs30(q);
15719
+ return snapshot.docs.map((doc32) => doc32.data());
13225
15720
  }
13226
15721
  /**
13227
15722
  * Gets all reviews for a specific clinic
@@ -13229,12 +15724,12 @@ var ReviewService = class extends BaseService {
13229
15724
  * @returns Array of reviews containing clinic reviews
13230
15725
  */
13231
15726
  async getReviewsByClinic(clinicId) {
13232
- const q = query25(
13233
- collection25(this.db, REVIEWS_COLLECTION),
13234
- where25("clinicReview.clinicId", "==", clinicId)
15727
+ const q = query30(
15728
+ collection30(this.db, REVIEWS_COLLECTION),
15729
+ where30("clinicReview.clinicId", "==", clinicId)
13235
15730
  );
13236
- const snapshot = await getDocs25(q);
13237
- return snapshot.docs.map((doc26) => doc26.data());
15731
+ const snapshot = await getDocs30(q);
15732
+ return snapshot.docs.map((doc32) => doc32.data());
13238
15733
  }
13239
15734
  /**
13240
15735
  * Gets all reviews for a specific practitioner
@@ -13242,12 +15737,12 @@ var ReviewService = class extends BaseService {
13242
15737
  * @returns Array of reviews containing practitioner reviews
13243
15738
  */
13244
15739
  async getReviewsByPractitioner(practitionerId) {
13245
- const q = query25(
13246
- collection25(this.db, REVIEWS_COLLECTION),
13247
- where25("practitionerReview.practitionerId", "==", practitionerId)
15740
+ const q = query30(
15741
+ collection30(this.db, REVIEWS_COLLECTION),
15742
+ where30("practitionerReview.practitionerId", "==", practitionerId)
13248
15743
  );
13249
- const snapshot = await getDocs25(q);
13250
- return snapshot.docs.map((doc26) => doc26.data());
15744
+ const snapshot = await getDocs30(q);
15745
+ return snapshot.docs.map((doc32) => doc32.data());
13251
15746
  }
13252
15747
  /**
13253
15748
  * Gets all reviews for a specific procedure
@@ -13255,12 +15750,12 @@ var ReviewService = class extends BaseService {
13255
15750
  * @returns Array of reviews containing procedure reviews
13256
15751
  */
13257
15752
  async getReviewsByProcedure(procedureId) {
13258
- const q = query25(
13259
- collection25(this.db, REVIEWS_COLLECTION),
13260
- where25("procedureReview.procedureId", "==", procedureId)
15753
+ const q = query30(
15754
+ collection30(this.db, REVIEWS_COLLECTION),
15755
+ where30("procedureReview.procedureId", "==", procedureId)
13261
15756
  );
13262
- const snapshot = await getDocs25(q);
13263
- return snapshot.docs.map((doc26) => doc26.data());
15757
+ const snapshot = await getDocs30(q);
15758
+ return snapshot.docs.map((doc32) => doc32.data());
13264
15759
  }
13265
15760
  /**
13266
15761
  * Gets all reviews for a specific appointment
@@ -13268,11 +15763,11 @@ var ReviewService = class extends BaseService {
13268
15763
  * @returns The review for the appointment if found, null otherwise
13269
15764
  */
13270
15765
  async getReviewByAppointment(appointmentId) {
13271
- const q = query25(
13272
- collection25(this.db, REVIEWS_COLLECTION),
13273
- where25("appointmentId", "==", appointmentId)
15766
+ const q = query30(
15767
+ collection30(this.db, REVIEWS_COLLECTION),
15768
+ where30("appointmentId", "==", appointmentId)
13274
15769
  );
13275
- const snapshot = await getDocs25(q);
15770
+ const snapshot = await getDocs30(q);
13276
15771
  if (snapshot.empty) {
13277
15772
  return null;
13278
15773
  }
@@ -13287,7 +15782,7 @@ var ReviewService = class extends BaseService {
13287
15782
  if (!review) {
13288
15783
  throw new Error(`Review with ID ${reviewId} not found`);
13289
15784
  }
13290
- await deleteDoc15(doc25(this.db, REVIEWS_COLLECTION, reviewId));
15785
+ await deleteDoc19(doc31(this.db, REVIEWS_COLLECTION, reviewId));
13291
15786
  }
13292
15787
  /**
13293
15788
  * Calculates the average of an array of numbers
@@ -13306,11 +15801,11 @@ var ReviewService = class extends BaseService {
13306
15801
 
13307
15802
  // src/validations/calendar.schema.ts
13308
15803
  import { z as z27 } from "zod";
13309
- import { Timestamp as Timestamp28 } from "firebase/firestore";
15804
+ import { Timestamp as Timestamp34 } from "firebase/firestore";
13310
15805
 
13311
15806
  // src/validations/profile-info.schema.ts
13312
15807
  import { z as z26 } from "zod";
13313
- import { Timestamp as Timestamp27 } from "firebase/firestore";
15808
+ import { Timestamp as Timestamp33 } from "firebase/firestore";
13314
15809
  var clinicBranchInfoSchema = z26.object({
13315
15810
  id: z26.string(),
13316
15811
  featuredPhoto: z26.string(),
@@ -13332,19 +15827,19 @@ var patientProfileInfoSchema = z26.object({
13332
15827
  fullName: z26.string(),
13333
15828
  email: z26.string().email(),
13334
15829
  phone: z26.string().nullable(),
13335
- dateOfBirth: z26.instanceof(Timestamp27),
15830
+ dateOfBirth: z26.instanceof(Timestamp33),
13336
15831
  gender: z26.nativeEnum(Gender)
13337
15832
  });
13338
15833
 
13339
15834
  // src/validations/calendar.schema.ts
13340
- var MIN_APPOINTMENT_DURATION = 15;
15835
+ var MIN_APPOINTMENT_DURATION2 = 15;
13341
15836
  var calendarEventTimeSchema = z27.object({
13342
- start: z27.instanceof(Date).or(z27.instanceof(Timestamp28)),
13343
- end: z27.instanceof(Date).or(z27.instanceof(Timestamp28))
15837
+ start: z27.instanceof(Date).or(z27.instanceof(Timestamp34)),
15838
+ end: z27.instanceof(Date).or(z27.instanceof(Timestamp34))
13344
15839
  }).refine(
13345
15840
  (data) => {
13346
- const startDate = data.start instanceof Timestamp28 ? data.start.toDate() : data.start;
13347
- const endDate = data.end instanceof Timestamp28 ? data.end.toDate() : data.end;
15841
+ const startDate = data.start instanceof Timestamp34 ? data.start.toDate() : data.start;
15842
+ const endDate = data.end instanceof Timestamp34 ? data.end.toDate() : data.end;
13348
15843
  return startDate < endDate;
13349
15844
  },
13350
15845
  {
@@ -13353,7 +15848,7 @@ var calendarEventTimeSchema = z27.object({
13353
15848
  }
13354
15849
  ).refine(
13355
15850
  (data) => {
13356
- const startDate = data.start instanceof Timestamp28 ? data.start.toDate() : data.start;
15851
+ const startDate = data.start instanceof Timestamp34 ? data.start.toDate() : data.start;
13357
15852
  return startDate > /* @__PURE__ */ new Date();
13358
15853
  },
13359
15854
  {
@@ -13372,12 +15867,12 @@ var timeSlotSchema2 = z27.object({
13372
15867
  var syncedCalendarEventSchema = z27.object({
13373
15868
  eventId: z27.string(),
13374
15869
  syncedCalendarProvider: z27.nativeEnum(SyncedCalendarProvider),
13375
- syncedAt: z27.instanceof(Date).or(z27.instanceof(Timestamp28))
15870
+ syncedAt: z27.instanceof(Date).or(z27.instanceof(Timestamp34))
13376
15871
  });
13377
15872
  var procedureInfoSchema = z27.object({
13378
15873
  name: z27.string(),
13379
15874
  description: z27.string(),
13380
- duration: z27.number().min(MIN_APPOINTMENT_DURATION),
15875
+ duration: z27.number().min(MIN_APPOINTMENT_DURATION2),
13381
15876
  price: z27.number().min(0),
13382
15877
  currency: z27.nativeEnum(Currency)
13383
15878
  });
@@ -13451,8 +15946,8 @@ var calendarEventSchema = z27.object({
13451
15946
  status: z27.nativeEnum(CalendarEventStatus),
13452
15947
  syncStatus: z27.nativeEnum(CalendarSyncStatus),
13453
15948
  eventType: z27.nativeEnum(CalendarEventType),
13454
- createdAt: z27.instanceof(Date).or(z27.instanceof(Timestamp28)),
13455
- updatedAt: z27.instanceof(Date).or(z27.instanceof(Timestamp28))
15949
+ createdAt: z27.instanceof(Date).or(z27.instanceof(Timestamp34)),
15950
+ updatedAt: z27.instanceof(Date).or(z27.instanceof(Timestamp34))
13456
15951
  });
13457
15952
  var createBlockingEventSchema = z27.object({
13458
15953
  entityType: z27.enum(["practitioner", "clinic"]),
@@ -13580,11 +16075,11 @@ var RequirementType = /* @__PURE__ */ ((RequirementType2) => {
13580
16075
  })(RequirementType || {});
13581
16076
 
13582
16077
  // src/backoffice/validations/schemas.ts
13583
- var blockingConditionSchema2 = z29.nativeEnum(BlockingCondition);
13584
- var contraindicationSchema2 = z29.nativeEnum(Contraindication);
13585
- var treatmentBenefitSchema = z29.nativeEnum(TreatmentBenefit);
13586
- var procedureFamilySchema = z29.nativeEnum(ProcedureFamily);
13587
- var timeUnitSchema = z29.nativeEnum(TimeUnit);
16078
+ var blockingConditionSchemaBackoffice = z29.nativeEnum(BlockingCondition);
16079
+ var contraindicationSchemaBackoffice = z29.nativeEnum(Contraindication);
16080
+ var treatmentBenefitSchemaBackoffice = z29.nativeEnum(TreatmentBenefit);
16081
+ var procedureFamilySchemaBackoffice = z29.nativeEnum(ProcedureFamily);
16082
+ var timeUnitSchemaBackoffice = z29.nativeEnum(TimeUnit);
13588
16083
  var requirementTypeSchema = z29.nativeEnum(RequirementType);
13589
16084
  var certificationLevelSchema = z29.nativeEnum(CertificationLevel);
13590
16085
  var certificationSpecialtySchema = z29.nativeEnum(
@@ -13596,7 +16091,7 @@ var certificationRequirementSchema = z29.object({
13596
16091
  });
13597
16092
  var timeframeSchema = z29.object({
13598
16093
  duration: z29.number().min(1, "Duration must be positive"),
13599
- unit: timeUnitSchema,
16094
+ unit: timeUnitSchemaBackoffice,
13600
16095
  notifyAt: z29.array(z29.number()).min(1, "At least one notification point is required")
13601
16096
  });
13602
16097
  var requirementSchema = z29.object({
@@ -13615,24 +16110,24 @@ var technologySchema = z29.object({
13615
16110
  name: z29.string().min(1, "Name is required").max(100, "Name is too long"),
13616
16111
  description: z29.string().max(1e3, "Description is too long").optional(),
13617
16112
  technicalDetails: z29.string().max(2e3, "Technical details are too long").optional(),
13618
- family: procedureFamilySchema,
16113
+ family: procedureFamilySchemaBackoffice,
13619
16114
  categoryId: z29.string().min(1, "Category ID is required"),
13620
16115
  subcategoryId: z29.string().min(1, "Subcategory ID is required"),
13621
16116
  requirements: technologyRequirementsSchema.default({
13622
16117
  pre: [],
13623
16118
  post: []
13624
16119
  }),
13625
- blockingConditions: z29.array(blockingConditionSchema2),
13626
- contraindications: z29.array(contraindicationSchema2),
16120
+ blockingConditions: z29.array(blockingConditionSchemaBackoffice),
16121
+ contraindications: z29.array(contraindicationSchemaBackoffice),
13627
16122
  documentationTemplates: z29.array(documentTemplateSchema),
13628
- benefits: z29.array(treatmentBenefitSchema),
16123
+ benefits: z29.array(treatmentBenefitSchemaBackoffice),
13629
16124
  certificationRequirement: certificationRequirementSchema,
13630
16125
  isActive: z29.boolean().default(true)
13631
16126
  });
13632
16127
  var categorySchema = z29.object({
13633
16128
  name: z29.string().min(1, "Name is required").max(100, "Name is too long"),
13634
16129
  description: z29.string().optional(),
13635
- family: procedureFamilySchema,
16130
+ family: procedureFamilySchemaBackoffice,
13636
16131
  isActive: z29.boolean().default(true)
13637
16132
  });
13638
16133
  var subcategorySchema = z29.object({
@@ -13658,7 +16153,7 @@ var patientRequirementInstructionSchema = z30.object({
13658
16153
  actionableWindow: z30.number().default(1),
13659
16154
  status: patientInstructionStatusSchema,
13660
16155
  originalNotifyAtValue: z30.number(),
13661
- originalTimeframeUnit: timeUnitSchema,
16156
+ originalTimeframeUnit: timeUnitSchemaBackoffice,
13662
16157
  // Use the correctly imported timeUnitSchema
13663
16158
  notificationId: z30.string().optional(),
13664
16159
  actionTakenAt: z30.any().optional().nullable(),
@@ -13940,6 +16435,7 @@ export {
13940
16435
  CLINIC_GROUPS_COLLECTION,
13941
16436
  CalendarEventStatus,
13942
16437
  CalendarEventType,
16438
+ CalendarServiceV2,
13943
16439
  CalendarServiceV3,
13944
16440
  CalendarSyncStatus,
13945
16441
  ClinicAdminService,
@@ -14008,6 +16504,7 @@ export {
14008
16504
  USERS_COLLECTION,
14009
16505
  USER_FORMS_SUBCOLLECTION,
14010
16506
  UserRole,
16507
+ UserService,
14011
16508
  addAllergySchema,
14012
16509
  addBlockingConditionSchema,
14013
16510
  addContraindicationSchema,