@blackcode_sa/metaestetics-api 1.5.31 → 1.5.33

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
@@ -1349,9 +1349,9 @@ var addAllergyUtil = async (db, patientId, data, userRef) => {
1349
1349
  var updateAllergyUtil = async (db, patientId, data, userRef) => {
1350
1350
  const validatedData = updateAllergySchema.parse(data);
1351
1351
  const { allergyIndex, ...updateData } = validatedData;
1352
- const doc28 = await getDoc3(getMedicalInfoDocRef(db, patientId));
1353
- if (!doc28.exists()) throw new Error("Medical info not found");
1354
- const medicalInfo = doc28.data();
1352
+ const doc29 = await getDoc3(getMedicalInfoDocRef(db, patientId));
1353
+ if (!doc29.exists()) throw new Error("Medical info not found");
1354
+ const medicalInfo = doc29.data();
1355
1355
  if (allergyIndex >= medicalInfo.allergies.length) {
1356
1356
  throw new Error("Invalid allergy index");
1357
1357
  }
@@ -1367,9 +1367,9 @@ var updateAllergyUtil = async (db, patientId, data, userRef) => {
1367
1367
  });
1368
1368
  };
1369
1369
  var removeAllergyUtil = async (db, patientId, allergyIndex, userRef) => {
1370
- const doc28 = await getDoc3(getMedicalInfoDocRef(db, patientId));
1371
- if (!doc28.exists()) throw new Error("Medical info not found");
1372
- const medicalInfo = doc28.data();
1370
+ const doc29 = await getDoc3(getMedicalInfoDocRef(db, patientId));
1371
+ if (!doc29.exists()) throw new Error("Medical info not found");
1372
+ const medicalInfo = doc29.data();
1373
1373
  if (allergyIndex >= medicalInfo.allergies.length) {
1374
1374
  throw new Error("Invalid allergy index");
1375
1375
  }
@@ -1394,9 +1394,9 @@ var addBlockingConditionUtil = async (db, patientId, data, userRef) => {
1394
1394
  var updateBlockingConditionUtil = async (db, patientId, data, userRef) => {
1395
1395
  const validatedData = updateBlockingConditionSchema.parse(data);
1396
1396
  const { conditionIndex, ...updateData } = validatedData;
1397
- const doc28 = await getDoc3(getMedicalInfoDocRef(db, patientId));
1398
- if (!doc28.exists()) throw new Error("Medical info not found");
1399
- const medicalInfo = doc28.data();
1397
+ const doc29 = await getDoc3(getMedicalInfoDocRef(db, patientId));
1398
+ if (!doc29.exists()) throw new Error("Medical info not found");
1399
+ const medicalInfo = doc29.data();
1400
1400
  if (conditionIndex >= medicalInfo.blockingConditions.length) {
1401
1401
  throw new Error("Invalid blocking condition index");
1402
1402
  }
@@ -1412,9 +1412,9 @@ var updateBlockingConditionUtil = async (db, patientId, data, userRef) => {
1412
1412
  });
1413
1413
  };
1414
1414
  var removeBlockingConditionUtil = async (db, patientId, conditionIndex, userRef) => {
1415
- const doc28 = await getDoc3(getMedicalInfoDocRef(db, patientId));
1416
- if (!doc28.exists()) throw new Error("Medical info not found");
1417
- const medicalInfo = doc28.data();
1415
+ const doc29 = await getDoc3(getMedicalInfoDocRef(db, patientId));
1416
+ if (!doc29.exists()) throw new Error("Medical info not found");
1417
+ const medicalInfo = doc29.data();
1418
1418
  if (conditionIndex >= medicalInfo.blockingConditions.length) {
1419
1419
  throw new Error("Invalid blocking condition index");
1420
1420
  }
@@ -1439,9 +1439,9 @@ var addContraindicationUtil = async (db, patientId, data, userRef) => {
1439
1439
  var updateContraindicationUtil = async (db, patientId, data, userRef) => {
1440
1440
  const validatedData = updateContraindicationSchema.parse(data);
1441
1441
  const { contraindicationIndex, ...updateData } = validatedData;
1442
- const doc28 = await getDoc3(getMedicalInfoDocRef(db, patientId));
1443
- if (!doc28.exists()) throw new Error("Medical info not found");
1444
- const medicalInfo = doc28.data();
1442
+ const doc29 = await getDoc3(getMedicalInfoDocRef(db, patientId));
1443
+ if (!doc29.exists()) throw new Error("Medical info not found");
1444
+ const medicalInfo = doc29.data();
1445
1445
  if (contraindicationIndex >= medicalInfo.contraindications.length) {
1446
1446
  throw new Error("Invalid contraindication index");
1447
1447
  }
@@ -1457,9 +1457,9 @@ var updateContraindicationUtil = async (db, patientId, data, userRef) => {
1457
1457
  });
1458
1458
  };
1459
1459
  var removeContraindicationUtil = async (db, patientId, contraindicationIndex, userRef) => {
1460
- const doc28 = await getDoc3(getMedicalInfoDocRef(db, patientId));
1461
- if (!doc28.exists()) throw new Error("Medical info not found");
1462
- const medicalInfo = doc28.data();
1460
+ const doc29 = await getDoc3(getMedicalInfoDocRef(db, patientId));
1461
+ if (!doc29.exists()) throw new Error("Medical info not found");
1462
+ const medicalInfo = doc29.data();
1463
1463
  if (contraindicationIndex >= medicalInfo.contraindications.length) {
1464
1464
  throw new Error("Invalid contraindication index");
1465
1465
  }
@@ -1484,9 +1484,9 @@ var addMedicationUtil = async (db, patientId, data, userRef) => {
1484
1484
  var updateMedicationUtil = async (db, patientId, data, userRef) => {
1485
1485
  const validatedData = updateMedicationSchema.parse(data);
1486
1486
  const { medicationIndex, ...updateData } = validatedData;
1487
- const doc28 = await getDoc3(getMedicalInfoDocRef(db, patientId));
1488
- if (!doc28.exists()) throw new Error("Medical info not found");
1489
- const medicalInfo = doc28.data();
1487
+ const doc29 = await getDoc3(getMedicalInfoDocRef(db, patientId));
1488
+ if (!doc29.exists()) throw new Error("Medical info not found");
1489
+ const medicalInfo = doc29.data();
1490
1490
  if (medicationIndex >= medicalInfo.currentMedications.length) {
1491
1491
  throw new Error("Invalid medication index");
1492
1492
  }
@@ -1502,9 +1502,9 @@ var updateMedicationUtil = async (db, patientId, data, userRef) => {
1502
1502
  });
1503
1503
  };
1504
1504
  var removeMedicationUtil = async (db, patientId, medicationIndex, userRef) => {
1505
- const doc28 = await getDoc3(getMedicalInfoDocRef(db, patientId));
1506
- if (!doc28.exists()) throw new Error("Medical info not found");
1507
- const medicalInfo = doc28.data();
1505
+ const doc29 = await getDoc3(getMedicalInfoDocRef(db, patientId));
1506
+ if (!doc29.exists()) throw new Error("Medical info not found");
1507
+ const medicalInfo = doc29.data();
1508
1508
  if (medicationIndex >= medicalInfo.currentMedications.length) {
1509
1509
  throw new Error("Invalid medication index");
1510
1510
  }
@@ -1782,7 +1782,7 @@ var searchPatientsUtil = async (db, params, requester) => {
1782
1782
  try {
1783
1783
  const finalQuery = query2(patientsCollectionRef, ...constraints);
1784
1784
  const querySnapshot = await getDocs2(finalQuery);
1785
- const patients = querySnapshot.docs.map((doc28) => doc28.data());
1785
+ const patients = querySnapshot.docs.map((doc29) => doc29.data());
1786
1786
  console.log(`[searchPatientsUtil] Found ${patients.length} patients matching criteria.`);
1787
1787
  return patients;
1788
1788
  } catch (error) {
@@ -1806,8 +1806,8 @@ var getAllPatientsUtil = async (db, options) => {
1806
1806
  }
1807
1807
  const patientsSnapshot = await getDocs2(q);
1808
1808
  const patients = [];
1809
- patientsSnapshot.forEach((doc28) => {
1810
- patients.push(doc28.data());
1809
+ patientsSnapshot.forEach((doc29) => {
1810
+ patients.push(doc29.data());
1811
1811
  });
1812
1812
  console.log(`[getAllPatientsUtil] Found ${patients.length} patients`);
1813
1813
  return patients;
@@ -3165,7 +3165,7 @@ async function getClinicAdminsByGroup(db, clinicGroupId) {
3165
3165
  where3("clinicGroupId", "==", clinicGroupId)
3166
3166
  );
3167
3167
  const querySnapshot = await getDocs3(q);
3168
- return querySnapshot.docs.map((doc28) => doc28.data());
3168
+ return querySnapshot.docs.map((doc29) => doc29.data());
3169
3169
  }
3170
3170
  async function updateClinicAdmin(db, adminId, data) {
3171
3171
  const admin = await getClinicAdmin(db, adminId);
@@ -3687,7 +3687,7 @@ var PractitionerService = class extends BaseService {
3687
3687
  where4("expiresAt", ">", Timestamp8.now())
3688
3688
  );
3689
3689
  const querySnapshot = await getDocs4(q);
3690
- return querySnapshot.docs.map((doc28) => doc28.data());
3690
+ return querySnapshot.docs.map((doc29) => doc29.data());
3691
3691
  }
3692
3692
  /**
3693
3693
  * Gets a token by its string value and validates it
@@ -3770,7 +3770,7 @@ var PractitionerService = class extends BaseService {
3770
3770
  where4("status", "==", "active" /* ACTIVE */)
3771
3771
  );
3772
3772
  const querySnapshot = await getDocs4(q);
3773
- return querySnapshot.docs.map((doc28) => doc28.data());
3773
+ return querySnapshot.docs.map((doc29) => doc29.data());
3774
3774
  }
3775
3775
  /**
3776
3776
  * Dohvata sve zdravstvene radnike za određenu kliniku
@@ -3782,7 +3782,7 @@ var PractitionerService = class extends BaseService {
3782
3782
  where4("isActive", "==", true)
3783
3783
  );
3784
3784
  const querySnapshot = await getDocs4(q);
3785
- return querySnapshot.docs.map((doc28) => doc28.data());
3785
+ return querySnapshot.docs.map((doc29) => doc29.data());
3786
3786
  }
3787
3787
  /**
3788
3788
  * Dohvata sve draft zdravstvene radnike za određenu kliniku sa statusom DRAFT
@@ -3794,7 +3794,7 @@ var PractitionerService = class extends BaseService {
3794
3794
  where4("status", "==", "draft" /* DRAFT */)
3795
3795
  );
3796
3796
  const querySnapshot = await getDocs4(q);
3797
- return querySnapshot.docs.map((doc28) => doc28.data());
3797
+ return querySnapshot.docs.map((doc29) => doc29.data());
3798
3798
  }
3799
3799
  /**
3800
3800
  * Updates a practitioner
@@ -3976,7 +3976,7 @@ var PractitionerService = class extends BaseService {
3976
3976
  );
3977
3977
  const querySnapshot = await getDocs4(q);
3978
3978
  const practitioners = querySnapshot.docs.map(
3979
- (doc28) => doc28.data()
3979
+ (doc29) => doc29.data()
3980
3980
  );
3981
3981
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
3982
3982
  return {
@@ -4047,8 +4047,8 @@ var PractitionerService = class extends BaseService {
4047
4047
  console.log(
4048
4048
  `[PRACTITIONER_SERVICE] Found ${querySnapshot.docs.length} practitioners with base query`
4049
4049
  );
4050
- let practitioners = querySnapshot.docs.map((doc28) => {
4051
- return { ...doc28.data(), id: doc28.id };
4050
+ let practitioners = querySnapshot.docs.map((doc29) => {
4051
+ return { ...doc29.data(), id: doc29.id };
4052
4052
  });
4053
4053
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
4054
4054
  if (filters.nameSearch && filters.nameSearch.trim() !== "") {
@@ -4302,7 +4302,7 @@ var UserService = class extends BaseService {
4302
4302
  ];
4303
4303
  const q = query5(collection5(this.db, USERS_COLLECTION), ...constraints);
4304
4304
  const querySnapshot = await getDocs5(q);
4305
- const users = querySnapshot.docs.map((doc28) => doc28.data());
4305
+ const users = querySnapshot.docs.map((doc29) => doc29.data());
4306
4306
  return Promise.all(users.map((userData) => userSchema.parse(userData)));
4307
4307
  }
4308
4308
  /**
@@ -4682,7 +4682,7 @@ async function getAllActiveGroups(db) {
4682
4682
  where6("isActive", "==", true)
4683
4683
  );
4684
4684
  const querySnapshot = await getDocs6(q);
4685
- return querySnapshot.docs.map((doc28) => doc28.data());
4685
+ return querySnapshot.docs.map((doc29) => doc29.data());
4686
4686
  }
4687
4687
  async function updateClinicGroup(db, groupId, data, app) {
4688
4688
  console.log("[CLINIC_GROUP] Updating clinic group", { groupId });
@@ -5106,7 +5106,7 @@ async function getClinicsByGroup(db, groupId) {
5106
5106
  where7("isActive", "==", true)
5107
5107
  );
5108
5108
  const querySnapshot = await getDocs7(q);
5109
- return querySnapshot.docs.map((doc28) => doc28.data());
5109
+ return querySnapshot.docs.map((doc29) => doc29.data());
5110
5110
  }
5111
5111
  async function updateClinic(db, clinicId, data, adminId, clinicAdminService, app) {
5112
5112
  console.log("[CLINIC] Starting clinic update", { clinicId, adminId });
@@ -5300,7 +5300,7 @@ async function getClinicsByAdmin(db, adminId, options = {}, clinicAdminService,
5300
5300
  }
5301
5301
  const q = query7(collection7(db, CLINICS_COLLECTION), ...constraints);
5302
5302
  const querySnapshot = await getDocs7(q);
5303
- return querySnapshot.docs.map((doc28) => doc28.data());
5303
+ return querySnapshot.docs.map((doc29) => doc29.data());
5304
5304
  }
5305
5305
  async function getActiveClinicsByAdmin(db, adminId, clinicAdminService, clinicGroupService) {
5306
5306
  return getClinicsByAdmin(
@@ -5345,11 +5345,11 @@ async function getAllClinics(db, pagination, lastDoc) {
5345
5345
  }
5346
5346
  const clinicsSnapshot = await getDocs7(clinicsQuery);
5347
5347
  const lastVisible = clinicsSnapshot.docs[clinicsSnapshot.docs.length - 1];
5348
- const clinics = clinicsSnapshot.docs.map((doc28) => {
5349
- const data = doc28.data();
5348
+ const clinics = clinicsSnapshot.docs.map((doc29) => {
5349
+ const data = doc29.data();
5350
5350
  return {
5351
5351
  ...data,
5352
- id: doc28.id
5352
+ id: doc29.id
5353
5353
  };
5354
5354
  });
5355
5355
  return {
@@ -5376,8 +5376,8 @@ async function getAllClinicsInRange(db, center, rangeInKm, pagination, lastDoc)
5376
5376
  ];
5377
5377
  const q = query7(collection7(db, CLINICS_COLLECTION), ...constraints);
5378
5378
  const querySnapshot = await getDocs7(q);
5379
- for (const doc28 of querySnapshot.docs) {
5380
- const clinic = doc28.data();
5379
+ for (const doc29 of querySnapshot.docs) {
5380
+ const clinic = doc29.data();
5381
5381
  const distance = distanceBetween2(
5382
5382
  [center.latitude, center.longitude],
5383
5383
  [clinic.location.latitude, clinic.location.longitude]
@@ -5499,8 +5499,8 @@ async function findClinicsInRadius(db, center, radiusInKm, filters) {
5499
5499
  }
5500
5500
  const q = query8(collection8(db, CLINICS_COLLECTION), ...constraints);
5501
5501
  const querySnapshot = await getDocs8(q);
5502
- for (const doc28 of querySnapshot.docs) {
5503
- const clinic = doc28.data();
5502
+ for (const doc29 of querySnapshot.docs) {
5503
+ const clinic = doc29.data();
5504
5504
  const distance = distanceBetween3(
5505
5505
  [center.latitude, center.longitude],
5506
5506
  [clinic.location.latitude, clinic.location.longitude]
@@ -5532,7 +5532,6 @@ import {
5532
5532
  getDocs as getDocs9,
5533
5533
  startAfter as startAfter4,
5534
5534
  limit as limit4,
5535
- documentId,
5536
5535
  orderBy as orderBy2
5537
5536
  } from "firebase/firestore";
5538
5537
  import { geohashQueryBounds as geohashQueryBounds3, distanceBetween as distanceBetween4 } from "geofire-common";
@@ -5574,7 +5573,7 @@ async function getClinicsByFilters(db, filters) {
5574
5573
  } else if (filters.pagination && filters.pagination > 0) {
5575
5574
  constraints.push(limit4(filters.pagination));
5576
5575
  }
5577
- constraints.push(orderBy2(documentId()));
5576
+ constraints.push(orderBy2("location.geohash"));
5578
5577
  let clinicsResult = [];
5579
5578
  let lastVisibleDoc = null;
5580
5579
  if (isGeoQuery) {
@@ -5597,8 +5596,8 @@ async function getClinicsByFilters(db, filters) {
5597
5596
  console.log(
5598
5597
  `[FILTER_UTILS] Found ${querySnapshot.docs.length} clinics in geo bound`
5599
5598
  );
5600
- for (const doc28 of querySnapshot.docs) {
5601
- const clinic = { ...doc28.data(), id: doc28.id };
5599
+ for (const doc29 of querySnapshot.docs) {
5600
+ const clinic = { ...doc29.data(), id: doc29.id };
5602
5601
  const distance = distanceBetween4(
5603
5602
  [center.latitude, center.longitude],
5604
5603
  [clinic.location.latitude, clinic.location.longitude]
@@ -5654,10 +5653,29 @@ async function getClinicsByFilters(db, filters) {
5654
5653
  console.log(
5655
5654
  `[FILTER_UTILS] Found ${querySnapshot.docs.length} clinics with regular query`
5656
5655
  );
5657
- const clinics = querySnapshot.docs.map((doc28) => {
5658
- return { ...doc28.data(), id: doc28.id };
5656
+ const clinics = querySnapshot.docs.map((doc29) => {
5657
+ return { ...doc29.data(), id: doc29.id };
5659
5658
  });
5660
5659
  let filteredClinics = clinics;
5660
+ if (filters.center) {
5661
+ const center = filters.center;
5662
+ const clinicsWithDistance = [];
5663
+ filteredClinics.forEach((clinic) => {
5664
+ const distance = distanceBetween4(
5665
+ [center.latitude, center.longitude],
5666
+ [clinic.location.latitude, clinic.location.longitude]
5667
+ );
5668
+ clinicsWithDistance.push({
5669
+ ...clinic,
5670
+ distance: distance / 1e3
5671
+ // Convert to kilometers
5672
+ });
5673
+ });
5674
+ filteredClinics = clinicsWithDistance;
5675
+ filteredClinics.sort(
5676
+ (a, b) => a.distance - b.distance
5677
+ );
5678
+ }
5661
5679
  if (filters.tags && filters.tags.length > 1) {
5662
5680
  filteredClinics = filteredClinics.filter((clinic) => {
5663
5681
  return filters.tags.every((tag) => clinic.tags.includes(tag));
@@ -5946,6 +5964,12 @@ var ClinicService = class extends BaseService {
5946
5964
  lastDoc
5947
5965
  );
5948
5966
  }
5967
+ /**
5968
+ * Get clinics based on multiple filtering criteria
5969
+ *
5970
+ * @param filters - Various filters to apply
5971
+ * @returns Filtered clinics and the last document for pagination
5972
+ */
5949
5973
  async getClinicsByFilters(filters) {
5950
5974
  return getClinicsByFilters(this.db, filters);
5951
5975
  }
@@ -6693,9 +6717,9 @@ var NotificationService = class extends BaseService {
6693
6717
  orderBy3("notificationTime", "desc")
6694
6718
  );
6695
6719
  const querySnapshot = await getDocs12(q);
6696
- return querySnapshot.docs.map((doc28) => ({
6697
- id: doc28.id,
6698
- ...doc28.data()
6720
+ return querySnapshot.docs.map((doc29) => ({
6721
+ id: doc29.id,
6722
+ ...doc29.data()
6699
6723
  }));
6700
6724
  }
6701
6725
  /**
@@ -6709,9 +6733,9 @@ var NotificationService = class extends BaseService {
6709
6733
  orderBy3("notificationTime", "desc")
6710
6734
  );
6711
6735
  const querySnapshot = await getDocs12(q);
6712
- return querySnapshot.docs.map((doc28) => ({
6713
- id: doc28.id,
6714
- ...doc28.data()
6736
+ return querySnapshot.docs.map((doc29) => ({
6737
+ id: doc29.id,
6738
+ ...doc29.data()
6715
6739
  }));
6716
6740
  }
6717
6741
  /**
@@ -6783,9 +6807,9 @@ var NotificationService = class extends BaseService {
6783
6807
  orderBy3("notificationTime", "desc")
6784
6808
  );
6785
6809
  const querySnapshot = await getDocs12(q);
6786
- return querySnapshot.docs.map((doc28) => ({
6787
- id: doc28.id,
6788
- ...doc28.data()
6810
+ return querySnapshot.docs.map((doc29) => ({
6811
+ id: doc29.id,
6812
+ ...doc29.data()
6789
6813
  }));
6790
6814
  }
6791
6815
  /**
@@ -6798,9 +6822,9 @@ var NotificationService = class extends BaseService {
6798
6822
  orderBy3("notificationTime", "desc")
6799
6823
  );
6800
6824
  const querySnapshot = await getDocs12(q);
6801
- return querySnapshot.docs.map((doc28) => ({
6802
- id: doc28.id,
6803
- ...doc28.data()
6825
+ return querySnapshot.docs.map((doc29) => ({
6826
+ id: doc29.id,
6827
+ ...doc29.data()
6804
6828
  }));
6805
6829
  }
6806
6830
  };
@@ -6819,8 +6843,7 @@ import {
6819
6843
  serverTimestamp as serverTimestamp14,
6820
6844
  orderBy as orderBy4,
6821
6845
  limit as limit5,
6822
- startAfter as startAfter5,
6823
- documentId as documentId2
6846
+ startAfter as startAfter5
6824
6847
  } from "firebase/firestore";
6825
6848
 
6826
6849
  // src/types/procedure/index.ts
@@ -7032,7 +7055,7 @@ var ProcedureService = class extends BaseService {
7032
7055
  where13("isActive", "==", true)
7033
7056
  );
7034
7057
  const snapshot = await getDocs13(q);
7035
- return snapshot.docs.map((doc28) => doc28.data());
7058
+ return snapshot.docs.map((doc29) => doc29.data());
7036
7059
  }
7037
7060
  /**
7038
7061
  * Gets all procedures for a practitioner
@@ -7046,7 +7069,7 @@ var ProcedureService = class extends BaseService {
7046
7069
  where13("isActive", "==", true)
7047
7070
  );
7048
7071
  const snapshot = await getDocs13(q);
7049
- return snapshot.docs.map((doc28) => doc28.data());
7072
+ return snapshot.docs.map((doc29) => doc29.data());
7050
7073
  }
7051
7074
  /**
7052
7075
  * Updates a procedure
@@ -7250,11 +7273,11 @@ var ProcedureService = class extends BaseService {
7250
7273
  }
7251
7274
  const proceduresSnapshot = await getDocs13(proceduresQuery);
7252
7275
  const lastVisible = proceduresSnapshot.docs[proceduresSnapshot.docs.length - 1];
7253
- const procedures = proceduresSnapshot.docs.map((doc28) => {
7254
- const data = doc28.data();
7276
+ const procedures = proceduresSnapshot.docs.map((doc29) => {
7277
+ const data = doc29.data();
7255
7278
  return {
7256
7279
  ...data,
7257
- id: doc28.id
7280
+ id: doc29.id
7258
7281
  // Ensure ID is present
7259
7282
  };
7260
7283
  });
@@ -7304,7 +7327,7 @@ var ProcedureService = class extends BaseService {
7304
7327
  if (filters.procedureFamily) {
7305
7328
  constraints.push(where13("family", "==", filters.procedureFamily));
7306
7329
  }
7307
- constraints.push(orderBy4(documentId2()));
7330
+ constraints.push(orderBy4("clinicInfo.location.geohash"));
7308
7331
  if (filters.pagination && filters.pagination > 0 && filters.lastDoc) {
7309
7332
  constraints.push(startAfter5(filters.lastDoc));
7310
7333
  constraints.push(limit5(filters.pagination));
@@ -7336,8 +7359,8 @@ var ProcedureService = class extends BaseService {
7336
7359
  console.log(
7337
7360
  `[PROCEDURE_SERVICE] Found ${querySnapshot.docs.length} procedures in geo bound`
7338
7361
  );
7339
- for (const doc28 of querySnapshot.docs) {
7340
- const procedure = { ...doc28.data(), id: doc28.id };
7362
+ for (const doc29 of querySnapshot.docs) {
7363
+ const procedure = { ...doc29.data(), id: doc29.id };
7341
7364
  const distance = distanceBetween6(
7342
7365
  [center.latitude, center.longitude],
7343
7366
  [
@@ -7388,12 +7411,41 @@ var ProcedureService = class extends BaseService {
7388
7411
  console.log(
7389
7412
  `[PROCEDURE_SERVICE] Found ${querySnapshot.docs.length} procedures with regular query`
7390
7413
  );
7391
- const procedures = querySnapshot.docs.map((doc28) => {
7392
- return { ...doc28.data(), id: doc28.id };
7414
+ const procedures = querySnapshot.docs.map((doc29) => {
7415
+ return { ...doc29.data(), id: doc29.id };
7393
7416
  });
7394
- let filteredProcedures = this.applyInMemoryFilters(procedures, filters);
7417
+ if (filters.location) {
7418
+ const center = filters.location;
7419
+ const proceduresWithDistance = [];
7420
+ procedures.forEach((procedure) => {
7421
+ const distance = distanceBetween6(
7422
+ [center.latitude, center.longitude],
7423
+ [
7424
+ procedure.clinicInfo.location.latitude,
7425
+ procedure.clinicInfo.location.longitude
7426
+ ]
7427
+ );
7428
+ proceduresWithDistance.push({
7429
+ ...procedure,
7430
+ distance: distance / 1e3
7431
+ // Convert to kilometers
7432
+ });
7433
+ });
7434
+ let filteredProcedures = proceduresWithDistance;
7435
+ filteredProcedures = this.applyInMemoryFilters(
7436
+ filteredProcedures,
7437
+ filters
7438
+ );
7439
+ filteredProcedures.sort((a, b) => a.distance - b.distance);
7440
+ proceduresResult = filteredProcedures;
7441
+ } else {
7442
+ let filteredProcedures = this.applyInMemoryFilters(
7443
+ procedures,
7444
+ filters
7445
+ );
7446
+ proceduresResult = filteredProcedures;
7447
+ }
7395
7448
  lastVisibleDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
7396
- proceduresResult = filteredProcedures;
7397
7449
  }
7398
7450
  return {
7399
7451
  procedures: proceduresResult,
@@ -7591,9 +7643,9 @@ var DocumentationTemplateService = class extends BaseService {
7591
7643
  const querySnapshot = await getDocs14(q);
7592
7644
  const templates = [];
7593
7645
  let lastVisible = null;
7594
- querySnapshot.forEach((doc28) => {
7595
- templates.push(doc28.data());
7596
- lastVisible = doc28;
7646
+ querySnapshot.forEach((doc29) => {
7647
+ templates.push(doc29.data());
7648
+ lastVisible = doc29;
7597
7649
  });
7598
7650
  return {
7599
7651
  templates,
@@ -7621,9 +7673,9 @@ var DocumentationTemplateService = class extends BaseService {
7621
7673
  const querySnapshot = await getDocs14(q);
7622
7674
  const templates = [];
7623
7675
  let lastVisible = null;
7624
- querySnapshot.forEach((doc28) => {
7625
- templates.push(doc28.data());
7626
- lastVisible = doc28;
7676
+ querySnapshot.forEach((doc29) => {
7677
+ templates.push(doc29.data());
7678
+ lastVisible = doc29;
7627
7679
  });
7628
7680
  return {
7629
7681
  templates,
@@ -7650,9 +7702,9 @@ var DocumentationTemplateService = class extends BaseService {
7650
7702
  const querySnapshot = await getDocs14(q);
7651
7703
  const templates = [];
7652
7704
  let lastVisible = null;
7653
- querySnapshot.forEach((doc28) => {
7654
- templates.push(doc28.data());
7655
- lastVisible = doc28;
7705
+ querySnapshot.forEach((doc29) => {
7706
+ templates.push(doc29.data());
7707
+ lastVisible = doc29;
7656
7708
  });
7657
7709
  return {
7658
7710
  templates,
@@ -7777,9 +7829,9 @@ var FilledDocumentService = class extends BaseService {
7777
7829
  const querySnapshot = await getDocs15(q);
7778
7830
  const documents = [];
7779
7831
  let lastVisible = null;
7780
- querySnapshot.forEach((doc28) => {
7781
- documents.push(doc28.data());
7782
- lastVisible = doc28;
7832
+ querySnapshot.forEach((doc29) => {
7833
+ documents.push(doc29.data());
7834
+ lastVisible = doc29;
7783
7835
  });
7784
7836
  return {
7785
7837
  documents,
@@ -7806,9 +7858,9 @@ var FilledDocumentService = class extends BaseService {
7806
7858
  const querySnapshot = await getDocs15(q);
7807
7859
  const documents = [];
7808
7860
  let lastVisible = null;
7809
- querySnapshot.forEach((doc28) => {
7810
- documents.push(doc28.data());
7811
- lastVisible = doc28;
7861
+ querySnapshot.forEach((doc29) => {
7862
+ documents.push(doc29.data());
7863
+ lastVisible = doc29;
7812
7864
  });
7813
7865
  return {
7814
7866
  documents,
@@ -7835,9 +7887,9 @@ var FilledDocumentService = class extends BaseService {
7835
7887
  const querySnapshot = await getDocs15(q);
7836
7888
  const documents = [];
7837
7889
  let lastVisible = null;
7838
- querySnapshot.forEach((doc28) => {
7839
- documents.push(doc28.data());
7840
- lastVisible = doc28;
7890
+ querySnapshot.forEach((doc29) => {
7891
+ documents.push(doc29.data());
7892
+ lastVisible = doc29;
7841
7893
  });
7842
7894
  return {
7843
7895
  documents,
@@ -7864,9 +7916,9 @@ var FilledDocumentService = class extends BaseService {
7864
7916
  const querySnapshot = await getDocs15(q);
7865
7917
  const documents = [];
7866
7918
  let lastVisible = null;
7867
- querySnapshot.forEach((doc28) => {
7868
- documents.push(doc28.data());
7869
- lastVisible = doc28;
7919
+ querySnapshot.forEach((doc29) => {
7920
+ documents.push(doc29.data());
7921
+ lastVisible = doc29;
7870
7922
  });
7871
7923
  return {
7872
7924
  documents,
@@ -7893,9 +7945,9 @@ var FilledDocumentService = class extends BaseService {
7893
7945
  const querySnapshot = await getDocs15(q);
7894
7946
  const documents = [];
7895
7947
  let lastVisible = null;
7896
- querySnapshot.forEach((doc28) => {
7897
- documents.push(doc28.data());
7898
- lastVisible = doc28;
7948
+ querySnapshot.forEach((doc29) => {
7949
+ documents.push(doc29.data());
7950
+ lastVisible = doc29;
7899
7951
  });
7900
7952
  return {
7901
7953
  documents,
@@ -8451,7 +8503,7 @@ async function searchCalendarEventsUtil(db, params) {
8451
8503
  const finalQuery = query19(collectionRef, ...constraints);
8452
8504
  const querySnapshot = await getDocs19(finalQuery);
8453
8505
  const events = querySnapshot.docs.map(
8454
- (doc28) => ({ id: doc28.id, ...doc28.data() })
8506
+ (doc29) => ({ id: doc29.id, ...doc29.data() })
8455
8507
  );
8456
8508
  return events;
8457
8509
  } catch (error) {
@@ -8544,7 +8596,7 @@ async function getPractitionerSyncedCalendarsUtil(db, practitionerId) {
8544
8596
  );
8545
8597
  const q = query20(calendarsRef, orderBy11("createdAt", "desc"));
8546
8598
  const querySnapshot = await getDocs20(q);
8547
- return querySnapshot.docs.map((doc28) => doc28.data());
8599
+ return querySnapshot.docs.map((doc29) => doc29.data());
8548
8600
  }
8549
8601
  async function getPatientSyncedCalendarUtil(db, patientId, calendarId) {
8550
8602
  const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
@@ -8561,7 +8613,7 @@ async function getPatientSyncedCalendarsUtil(db, patientId) {
8561
8613
  );
8562
8614
  const q = query20(calendarsRef, orderBy11("createdAt", "desc"));
8563
8615
  const querySnapshot = await getDocs20(q);
8564
- return querySnapshot.docs.map((doc28) => doc28.data());
8616
+ return querySnapshot.docs.map((doc29) => doc29.data());
8565
8617
  }
8566
8618
  async function getClinicSyncedCalendarUtil(db, clinicId, calendarId) {
8567
8619
  const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
@@ -8578,7 +8630,7 @@ async function getClinicSyncedCalendarsUtil(db, clinicId) {
8578
8630
  );
8579
8631
  const q = query20(calendarsRef, orderBy11("createdAt", "desc"));
8580
8632
  const querySnapshot = await getDocs20(q);
8581
- return querySnapshot.docs.map((doc28) => doc28.data());
8633
+ return querySnapshot.docs.map((doc29) => doc29.data());
8582
8634
  }
8583
8635
  async function updatePractitionerSyncedCalendarUtil(db, practitionerId, calendarId, updateData) {
8584
8636
  const calendarRef = getPractitionerSyncedCalendarDocRef(
@@ -9933,9 +9985,9 @@ var CalendarServiceV2 = class extends BaseService {
9933
9985
  where21("eventTime.start", "<=", Timestamp25.fromDate(endDate))
9934
9986
  );
9935
9987
  const eventsSnapshot = await getDocs21(q);
9936
- const events = eventsSnapshot.docs.map((doc28) => ({
9937
- id: doc28.id,
9938
- ...doc28.data()
9988
+ const events = eventsSnapshot.docs.map((doc29) => ({
9989
+ id: doc29.id,
9990
+ ...doc29.data()
9939
9991
  }));
9940
9992
  const calendars = await this.syncedCalendarsService.getPractitionerSyncedCalendars(
9941
9993
  doctorId
@@ -10567,7 +10619,7 @@ var CalendarServiceV2 = class extends BaseService {
10567
10619
  ])
10568
10620
  );
10569
10621
  const querySnapshot = await getDocs21(q);
10570
- return querySnapshot.docs.map((doc28) => doc28.data());
10622
+ return querySnapshot.docs.map((doc29) => doc29.data());
10571
10623
  }
10572
10624
  /**
10573
10625
  * Calculates available time slots based on working hours, schedule and existing appointments
@@ -10691,16 +10743,637 @@ var CalendarServiceV2 = class extends BaseService {
10691
10743
  // #endregion
10692
10744
  };
10693
10745
 
10694
- // src/backoffice/services/brand.service.ts
10746
+ // src/services/reviews/reviews.service.ts
10695
10747
  import {
10696
- addDoc as addDoc3,
10697
10748
  collection as collection22,
10698
10749
  doc as doc23,
10699
10750
  getDoc as getDoc25,
10700
10751
  getDocs as getDocs22,
10701
10752
  query as query22,
10753
+ where as where22,
10702
10754
  updateDoc as updateDoc24,
10703
- where as where22
10755
+ setDoc as setDoc22,
10756
+ deleteDoc as deleteDoc15,
10757
+ serverTimestamp as serverTimestamp22,
10758
+ writeBatch as writeBatch7
10759
+ } from "firebase/firestore";
10760
+
10761
+ // src/types/reviews/index.ts
10762
+ var REVIEWS_COLLECTION = "reviews";
10763
+
10764
+ // src/services/reviews/reviews.service.ts
10765
+ import { z as z21 } from "zod";
10766
+ var ReviewService = class extends BaseService {
10767
+ constructor(db, auth, app) {
10768
+ super(db, auth, app);
10769
+ }
10770
+ /**
10771
+ * Creates a new review and updates related entities
10772
+ * @param data - The review data to create
10773
+ * @param appointmentId - ID of the completed appointment
10774
+ * @returns The created review
10775
+ */
10776
+ async createReview(data, appointmentId) {
10777
+ try {
10778
+ const validatedData = createReviewSchema.parse(data);
10779
+ const ratings = [];
10780
+ if (data.clinicReview) {
10781
+ const clinicRatings = [
10782
+ data.clinicReview.cleanliness,
10783
+ data.clinicReview.facilities,
10784
+ data.clinicReview.staffFriendliness,
10785
+ data.clinicReview.waitingTime,
10786
+ data.clinicReview.accessibility
10787
+ ];
10788
+ const clinicAverage = this.calculateAverage(clinicRatings);
10789
+ data.clinicReview.overallRating = clinicAverage;
10790
+ ratings.push(clinicAverage);
10791
+ }
10792
+ if (data.practitionerReview) {
10793
+ const practitionerRatings = [
10794
+ data.practitionerReview.knowledgeAndExpertise,
10795
+ data.practitionerReview.communicationSkills,
10796
+ data.practitionerReview.bedSideManner,
10797
+ data.practitionerReview.thoroughness,
10798
+ data.practitionerReview.trustworthiness
10799
+ ];
10800
+ const practitionerAverage = this.calculateAverage(practitionerRatings);
10801
+ data.practitionerReview.overallRating = practitionerAverage;
10802
+ ratings.push(practitionerAverage);
10803
+ }
10804
+ if (data.procedureReview) {
10805
+ const procedureRatings = [
10806
+ data.procedureReview.effectivenessOfTreatment,
10807
+ data.procedureReview.outcomeExplanation,
10808
+ data.procedureReview.painManagement,
10809
+ data.procedureReview.followUpCare,
10810
+ data.procedureReview.valueForMoney
10811
+ ];
10812
+ const procedureAverage = this.calculateAverage(procedureRatings);
10813
+ data.procedureReview.overallRating = procedureAverage;
10814
+ ratings.push(procedureAverage);
10815
+ }
10816
+ const overallRating = this.calculateAverage(ratings);
10817
+ const reviewId = this.generateId();
10818
+ if (data.clinicReview) {
10819
+ data.clinicReview.id = this.generateId();
10820
+ data.clinicReview.fullReviewId = reviewId;
10821
+ }
10822
+ if (data.practitionerReview) {
10823
+ data.practitionerReview.id = this.generateId();
10824
+ data.practitionerReview.fullReviewId = reviewId;
10825
+ }
10826
+ if (data.procedureReview) {
10827
+ data.procedureReview.id = this.generateId();
10828
+ data.procedureReview.fullReviewId = reviewId;
10829
+ }
10830
+ const now = /* @__PURE__ */ new Date();
10831
+ const review = {
10832
+ id: reviewId,
10833
+ appointmentId,
10834
+ patientId: data.patientId,
10835
+ clinicReview: data.clinicReview,
10836
+ practitionerReview: data.practitionerReview,
10837
+ procedureReview: data.procedureReview,
10838
+ overallComment: data.overallComment,
10839
+ overallRating,
10840
+ createdAt: now,
10841
+ updatedAt: now
10842
+ };
10843
+ reviewSchema.parse(review);
10844
+ const docRef = doc23(this.db, REVIEWS_COLLECTION, reviewId);
10845
+ await setDoc22(docRef, {
10846
+ ...review,
10847
+ createdAt: serverTimestamp22(),
10848
+ updatedAt: serverTimestamp22()
10849
+ });
10850
+ const updatePromises = [];
10851
+ if (data.clinicReview) {
10852
+ updatePromises.push(
10853
+ this.updateClinicReviewInfo(data.clinicReview.clinicId)
10854
+ );
10855
+ }
10856
+ if (data.practitionerReview) {
10857
+ updatePromises.push(
10858
+ this.updatePractitionerReviewInfo(
10859
+ data.practitionerReview.practitionerId
10860
+ )
10861
+ );
10862
+ }
10863
+ if (data.procedureReview) {
10864
+ updatePromises.push(
10865
+ this.updateProcedureReviewInfo(data.procedureReview.procedureId)
10866
+ );
10867
+ }
10868
+ await Promise.all(updatePromises);
10869
+ return review;
10870
+ } catch (error) {
10871
+ if (error instanceof z21.ZodError) {
10872
+ throw new Error(`Invalid review data: ${error.message}`);
10873
+ }
10874
+ throw error;
10875
+ }
10876
+ }
10877
+ /**
10878
+ * Gets a review by ID
10879
+ * @param reviewId The ID of the review to get
10880
+ * @returns The review if found, null otherwise
10881
+ */
10882
+ async getReview(reviewId) {
10883
+ const docRef = doc23(this.db, REVIEWS_COLLECTION, reviewId);
10884
+ const docSnap = await getDoc25(docRef);
10885
+ if (!docSnap.exists()) {
10886
+ return null;
10887
+ }
10888
+ return docSnap.data();
10889
+ }
10890
+ /**
10891
+ * Gets all reviews for a specific patient
10892
+ * @param patientId The ID of the patient
10893
+ * @returns Array of reviews for the patient
10894
+ */
10895
+ async getReviewsByPatient(patientId) {
10896
+ const q = query22(
10897
+ collection22(this.db, REVIEWS_COLLECTION),
10898
+ where22("patientId", "==", patientId)
10899
+ );
10900
+ const snapshot = await getDocs22(q);
10901
+ return snapshot.docs.map((doc29) => doc29.data());
10902
+ }
10903
+ /**
10904
+ * Gets all reviews for a specific clinic
10905
+ * @param clinicId The ID of the clinic
10906
+ * @returns Array of reviews containing clinic reviews
10907
+ */
10908
+ async getReviewsByClinic(clinicId) {
10909
+ const q = query22(
10910
+ collection22(this.db, REVIEWS_COLLECTION),
10911
+ where22("clinicReview.clinicId", "==", clinicId)
10912
+ );
10913
+ const snapshot = await getDocs22(q);
10914
+ return snapshot.docs.map((doc29) => doc29.data());
10915
+ }
10916
+ /**
10917
+ * Gets all reviews for a specific practitioner
10918
+ * @param practitionerId The ID of the practitioner
10919
+ * @returns Array of reviews containing practitioner reviews
10920
+ */
10921
+ async getReviewsByPractitioner(practitionerId) {
10922
+ const q = query22(
10923
+ collection22(this.db, REVIEWS_COLLECTION),
10924
+ where22("practitionerReview.practitionerId", "==", practitionerId)
10925
+ );
10926
+ const snapshot = await getDocs22(q);
10927
+ return snapshot.docs.map((doc29) => doc29.data());
10928
+ }
10929
+ /**
10930
+ * Gets all reviews for a specific procedure
10931
+ * @param procedureId The ID of the procedure
10932
+ * @returns Array of reviews containing procedure reviews
10933
+ */
10934
+ async getReviewsByProcedure(procedureId) {
10935
+ const q = query22(
10936
+ collection22(this.db, REVIEWS_COLLECTION),
10937
+ where22("procedureReview.procedureId", "==", procedureId)
10938
+ );
10939
+ const snapshot = await getDocs22(q);
10940
+ return snapshot.docs.map((doc29) => doc29.data());
10941
+ }
10942
+ /**
10943
+ * Gets all reviews for a specific appointment
10944
+ * @param appointmentId The ID of the appointment
10945
+ * @returns The review for the appointment if found, null otherwise
10946
+ */
10947
+ async getReviewByAppointment(appointmentId) {
10948
+ const q = query22(
10949
+ collection22(this.db, REVIEWS_COLLECTION),
10950
+ where22("appointmentId", "==", appointmentId)
10951
+ );
10952
+ const snapshot = await getDocs22(q);
10953
+ if (snapshot.empty) {
10954
+ return null;
10955
+ }
10956
+ return snapshot.docs[0].data();
10957
+ }
10958
+ /**
10959
+ * Deletes a review and updates related entities
10960
+ * @param reviewId The ID of the review to delete
10961
+ */
10962
+ async deleteReview(reviewId) {
10963
+ const review = await this.getReview(reviewId);
10964
+ if (!review) {
10965
+ throw new Error(`Review with ID ${reviewId} not found`);
10966
+ }
10967
+ await deleteDoc15(doc23(this.db, REVIEWS_COLLECTION, reviewId));
10968
+ const updatePromises = [];
10969
+ if (review.clinicReview) {
10970
+ updatePromises.push(
10971
+ this.updateClinicReviewInfo(
10972
+ review.clinicReview.clinicId,
10973
+ review.clinicReview,
10974
+ true
10975
+ )
10976
+ );
10977
+ }
10978
+ if (review.practitionerReview) {
10979
+ updatePromises.push(
10980
+ this.updatePractitionerReviewInfo(
10981
+ review.practitionerReview.practitionerId,
10982
+ review.practitionerReview,
10983
+ true
10984
+ )
10985
+ );
10986
+ }
10987
+ if (review.procedureReview) {
10988
+ updatePromises.push(
10989
+ this.updateProcedureReviewInfo(
10990
+ review.procedureReview.procedureId,
10991
+ review.procedureReview,
10992
+ true
10993
+ )
10994
+ );
10995
+ }
10996
+ await Promise.all(updatePromises);
10997
+ }
10998
+ /**
10999
+ * Updates the review info for a clinic
11000
+ * @param clinicId The ID of the clinic to update
11001
+ * @param newReview Optional new review being added or removed
11002
+ * @param isRemoval Whether this update is for a review removal
11003
+ * @returns The updated clinic review info
11004
+ */
11005
+ async updateClinicReviewInfo(clinicId, newReview, isRemoval = false) {
11006
+ const clinicDoc = await getDoc25(doc23(this.db, CLINICS_COLLECTION, clinicId));
11007
+ if (!clinicDoc.exists()) {
11008
+ throw new Error(`Clinic with ID ${clinicId} not found`);
11009
+ }
11010
+ const clinicData = clinicDoc.data();
11011
+ const currentReviewInfo = clinicData.reviewInfo || {
11012
+ totalReviews: 0,
11013
+ averageRating: 0,
11014
+ cleanliness: 0,
11015
+ facilities: 0,
11016
+ staffFriendliness: 0,
11017
+ waitingTime: 0,
11018
+ accessibility: 0,
11019
+ recommendationPercentage: 0
11020
+ };
11021
+ if (currentReviewInfo.totalReviews === 0 && !newReview) {
11022
+ await updateDoc24(doc23(this.db, CLINICS_COLLECTION, clinicId), {
11023
+ reviewInfo: currentReviewInfo,
11024
+ updatedAt: serverTimestamp22()
11025
+ });
11026
+ return currentReviewInfo;
11027
+ }
11028
+ let updatedReviewInfo;
11029
+ if (newReview) {
11030
+ const oldTotal = currentReviewInfo.totalReviews;
11031
+ const newTotal = isRemoval ? oldTotal - 1 : oldTotal + 1;
11032
+ if (newTotal === 0) {
11033
+ updatedReviewInfo = {
11034
+ totalReviews: 0,
11035
+ averageRating: 0,
11036
+ cleanliness: 0,
11037
+ facilities: 0,
11038
+ staffFriendliness: 0,
11039
+ waitingTime: 0,
11040
+ accessibility: 0,
11041
+ recommendationPercentage: 0
11042
+ };
11043
+ } else {
11044
+ const updateAverage = (currentAvg, newValue) => {
11045
+ const currentSum = currentAvg * oldTotal;
11046
+ const newSum = isRemoval ? currentSum - newValue : currentSum + newValue;
11047
+ const newAvg = newSum / newTotal;
11048
+ return Math.round(newAvg * 10) / 10;
11049
+ };
11050
+ const currentRecommendations = currentReviewInfo.recommendationPercentage / 100 * oldTotal;
11051
+ const newRecommendations = isRemoval ? newReview.wouldRecommend ? currentRecommendations - 1 : currentRecommendations : newReview.wouldRecommend ? currentRecommendations + 1 : currentRecommendations;
11052
+ const newRecommendationPercentage = newRecommendations / newTotal * 100;
11053
+ updatedReviewInfo = {
11054
+ totalReviews: newTotal,
11055
+ averageRating: updateAverage(
11056
+ currentReviewInfo.averageRating,
11057
+ newReview.overallRating
11058
+ ),
11059
+ cleanliness: updateAverage(
11060
+ currentReviewInfo.cleanliness,
11061
+ newReview.cleanliness
11062
+ ),
11063
+ facilities: updateAverage(
11064
+ currentReviewInfo.facilities,
11065
+ newReview.facilities
11066
+ ),
11067
+ staffFriendliness: updateAverage(
11068
+ currentReviewInfo.staffFriendliness,
11069
+ newReview.staffFriendliness
11070
+ ),
11071
+ waitingTime: updateAverage(
11072
+ currentReviewInfo.waitingTime,
11073
+ newReview.waitingTime
11074
+ ),
11075
+ accessibility: updateAverage(
11076
+ currentReviewInfo.accessibility,
11077
+ newReview.accessibility
11078
+ ),
11079
+ recommendationPercentage: Math.round(newRecommendationPercentage * 10) / 10
11080
+ };
11081
+ }
11082
+ } else {
11083
+ updatedReviewInfo = { ...currentReviewInfo };
11084
+ }
11085
+ await updateDoc24(doc23(this.db, CLINICS_COLLECTION, clinicId), {
11086
+ reviewInfo: updatedReviewInfo,
11087
+ updatedAt: serverTimestamp22()
11088
+ });
11089
+ return updatedReviewInfo;
11090
+ }
11091
+ /**
11092
+ * Updates the review info for a practitioner
11093
+ * @param practitionerId The ID of the practitioner to update
11094
+ * @param newReview Optional new review being added or removed
11095
+ * @param isRemoval Whether this update is for a review removal
11096
+ * @returns The updated practitioner review info
11097
+ */
11098
+ async updatePractitionerReviewInfo(practitionerId, newReview, isRemoval = false) {
11099
+ const practitionerDoc = await getDoc25(
11100
+ doc23(this.db, PRACTITIONERS_COLLECTION, practitionerId)
11101
+ );
11102
+ if (!practitionerDoc.exists()) {
11103
+ throw new Error(`Practitioner with ID ${practitionerId} not found`);
11104
+ }
11105
+ const practitionerData = practitionerDoc.data();
11106
+ const currentReviewInfo = practitionerData.reviewInfo || {
11107
+ totalReviews: 0,
11108
+ averageRating: 0,
11109
+ knowledgeAndExpertise: 0,
11110
+ communicationSkills: 0,
11111
+ bedSideManner: 0,
11112
+ thoroughness: 0,
11113
+ trustworthiness: 0,
11114
+ recommendationPercentage: 0
11115
+ };
11116
+ if (currentReviewInfo.totalReviews === 0 && !newReview) {
11117
+ await updateDoc24(doc23(this.db, PRACTITIONERS_COLLECTION, practitionerId), {
11118
+ reviewInfo: currentReviewInfo,
11119
+ updatedAt: serverTimestamp22()
11120
+ });
11121
+ return currentReviewInfo;
11122
+ }
11123
+ let updatedReviewInfo;
11124
+ if (newReview) {
11125
+ const oldTotal = currentReviewInfo.totalReviews;
11126
+ const newTotal = isRemoval ? oldTotal - 1 : oldTotal + 1;
11127
+ if (newTotal === 0) {
11128
+ updatedReviewInfo = {
11129
+ totalReviews: 0,
11130
+ averageRating: 0,
11131
+ knowledgeAndExpertise: 0,
11132
+ communicationSkills: 0,
11133
+ bedSideManner: 0,
11134
+ thoroughness: 0,
11135
+ trustworthiness: 0,
11136
+ recommendationPercentage: 0
11137
+ };
11138
+ } else {
11139
+ const updateAverage = (currentAvg, newValue) => {
11140
+ const currentSum = currentAvg * oldTotal;
11141
+ const newSum = isRemoval ? currentSum - newValue : currentSum + newValue;
11142
+ const newAvg = newSum / newTotal;
11143
+ return Math.round(newAvg * 10) / 10;
11144
+ };
11145
+ const currentRecommendations = currentReviewInfo.recommendationPercentage / 100 * oldTotal;
11146
+ const newRecommendations = isRemoval ? newReview.wouldRecommend ? currentRecommendations - 1 : currentRecommendations : newReview.wouldRecommend ? currentRecommendations + 1 : currentRecommendations;
11147
+ const newRecommendationPercentage = newRecommendations / newTotal * 100;
11148
+ updatedReviewInfo = {
11149
+ totalReviews: newTotal,
11150
+ averageRating: updateAverage(
11151
+ currentReviewInfo.averageRating,
11152
+ newReview.overallRating
11153
+ ),
11154
+ knowledgeAndExpertise: updateAverage(
11155
+ currentReviewInfo.knowledgeAndExpertise,
11156
+ newReview.knowledgeAndExpertise
11157
+ ),
11158
+ communicationSkills: updateAverage(
11159
+ currentReviewInfo.communicationSkills,
11160
+ newReview.communicationSkills
11161
+ ),
11162
+ bedSideManner: updateAverage(
11163
+ currentReviewInfo.bedSideManner,
11164
+ newReview.bedSideManner
11165
+ ),
11166
+ thoroughness: updateAverage(
11167
+ currentReviewInfo.thoroughness,
11168
+ newReview.thoroughness
11169
+ ),
11170
+ trustworthiness: updateAverage(
11171
+ currentReviewInfo.trustworthiness,
11172
+ newReview.trustworthiness
11173
+ ),
11174
+ recommendationPercentage: Math.round(newRecommendationPercentage * 10) / 10
11175
+ };
11176
+ }
11177
+ } else {
11178
+ updatedReviewInfo = { ...currentReviewInfo };
11179
+ }
11180
+ await updateDoc24(doc23(this.db, PRACTITIONERS_COLLECTION, practitionerId), {
11181
+ reviewInfo: updatedReviewInfo,
11182
+ updatedAt: serverTimestamp22()
11183
+ });
11184
+ await this.updateDoctorInfoInProcedures(
11185
+ practitionerId,
11186
+ updatedReviewInfo.averageRating
11187
+ );
11188
+ return updatedReviewInfo;
11189
+ }
11190
+ /**
11191
+ * Updates the review info for a procedure
11192
+ * @param procedureId The ID of the procedure to update
11193
+ * @param newReview Optional new review being added or removed
11194
+ * @param isRemoval Whether this update is for a review removal
11195
+ * @returns The updated procedure review info
11196
+ */
11197
+ async updateProcedureReviewInfo(procedureId, newReview, isRemoval = false) {
11198
+ const procedureDoc = await getDoc25(
11199
+ doc23(this.db, PROCEDURES_COLLECTION, procedureId)
11200
+ );
11201
+ if (!procedureDoc.exists()) {
11202
+ throw new Error(`Procedure with ID ${procedureId} not found`);
11203
+ }
11204
+ const procedureData = procedureDoc.data();
11205
+ const currentReviewInfo = procedureData.reviewInfo || {
11206
+ totalReviews: 0,
11207
+ averageRating: 0,
11208
+ effectivenessOfTreatment: 0,
11209
+ outcomeExplanation: 0,
11210
+ painManagement: 0,
11211
+ followUpCare: 0,
11212
+ valueForMoney: 0,
11213
+ recommendationPercentage: 0
11214
+ };
11215
+ if (currentReviewInfo.totalReviews === 0 && !newReview) {
11216
+ await updateDoc24(doc23(this.db, PROCEDURES_COLLECTION, procedureId), {
11217
+ reviewInfo: currentReviewInfo,
11218
+ updatedAt: serverTimestamp22()
11219
+ });
11220
+ return currentReviewInfo;
11221
+ }
11222
+ let updatedReviewInfo;
11223
+ if (newReview) {
11224
+ const oldTotal = currentReviewInfo.totalReviews;
11225
+ const newTotal = isRemoval ? oldTotal - 1 : oldTotal + 1;
11226
+ if (newTotal === 0) {
11227
+ updatedReviewInfo = {
11228
+ totalReviews: 0,
11229
+ averageRating: 0,
11230
+ effectivenessOfTreatment: 0,
11231
+ outcomeExplanation: 0,
11232
+ painManagement: 0,
11233
+ followUpCare: 0,
11234
+ valueForMoney: 0,
11235
+ recommendationPercentage: 0
11236
+ };
11237
+ } else {
11238
+ const updateAverage = (currentAvg, newValue) => {
11239
+ const currentSum = currentAvg * oldTotal;
11240
+ const newSum = isRemoval ? currentSum - newValue : currentSum + newValue;
11241
+ const newAvg = newSum / newTotal;
11242
+ return Math.round(newAvg * 10) / 10;
11243
+ };
11244
+ const currentRecommendations = currentReviewInfo.recommendationPercentage / 100 * oldTotal;
11245
+ const newRecommendations = isRemoval ? newReview.wouldRecommend ? currentRecommendations - 1 : currentRecommendations : newReview.wouldRecommend ? currentRecommendations + 1 : currentRecommendations;
11246
+ const newRecommendationPercentage = newRecommendations / newTotal * 100;
11247
+ updatedReviewInfo = {
11248
+ totalReviews: newTotal,
11249
+ averageRating: updateAverage(
11250
+ currentReviewInfo.averageRating,
11251
+ newReview.overallRating
11252
+ ),
11253
+ effectivenessOfTreatment: updateAverage(
11254
+ currentReviewInfo.effectivenessOfTreatment,
11255
+ newReview.effectivenessOfTreatment
11256
+ ),
11257
+ outcomeExplanation: updateAverage(
11258
+ currentReviewInfo.outcomeExplanation,
11259
+ newReview.outcomeExplanation
11260
+ ),
11261
+ painManagement: updateAverage(
11262
+ currentReviewInfo.painManagement,
11263
+ newReview.painManagement
11264
+ ),
11265
+ followUpCare: updateAverage(
11266
+ currentReviewInfo.followUpCare,
11267
+ newReview.followUpCare
11268
+ ),
11269
+ valueForMoney: updateAverage(
11270
+ currentReviewInfo.valueForMoney,
11271
+ newReview.valueForMoney
11272
+ ),
11273
+ recommendationPercentage: Math.round(newRecommendationPercentage * 10) / 10
11274
+ };
11275
+ }
11276
+ } else {
11277
+ updatedReviewInfo = { ...currentReviewInfo };
11278
+ }
11279
+ await updateDoc24(doc23(this.db, PROCEDURES_COLLECTION, procedureId), {
11280
+ reviewInfo: updatedReviewInfo,
11281
+ updatedAt: serverTimestamp22()
11282
+ });
11283
+ return updatedReviewInfo;
11284
+ }
11285
+ /**
11286
+ * Updates doctorInfo rating in all procedures for a practitioner
11287
+ * @param practitionerId The ID of the practitioner
11288
+ * @param rating The new rating to set
11289
+ */
11290
+ async updateDoctorInfoInProcedures(practitionerId, rating) {
11291
+ const q = query22(
11292
+ collection22(this.db, PROCEDURES_COLLECTION),
11293
+ where22("practitionerId", "==", practitionerId)
11294
+ );
11295
+ const snapshot = await getDocs22(q);
11296
+ if (snapshot.empty) {
11297
+ return;
11298
+ }
11299
+ const batch = writeBatch7(this.db);
11300
+ snapshot.docs.forEach((docSnapshot) => {
11301
+ const procedureRef = doc23(this.db, PROCEDURES_COLLECTION, docSnapshot.id);
11302
+ batch.update(procedureRef, {
11303
+ "doctorInfo.rating": rating,
11304
+ updatedAt: serverTimestamp22()
11305
+ });
11306
+ });
11307
+ await batch.commit();
11308
+ }
11309
+ /**
11310
+ * Verifies a review as checked by admin/staff
11311
+ * @param reviewId The ID of the review to verify
11312
+ */
11313
+ async verifyReview(reviewId) {
11314
+ const review = await this.getReview(reviewId);
11315
+ if (!review) {
11316
+ throw new Error(`Review with ID ${reviewId} not found`);
11317
+ }
11318
+ const batch = writeBatch7(this.db);
11319
+ batch.update(doc23(this.db, REVIEWS_COLLECTION, reviewId), {
11320
+ updatedAt: serverTimestamp22()
11321
+ });
11322
+ if (review.clinicReview) {
11323
+ review.clinicReview.isVerified = true;
11324
+ }
11325
+ if (review.practitionerReview) {
11326
+ review.practitionerReview.isVerified = true;
11327
+ }
11328
+ if (review.procedureReview) {
11329
+ review.procedureReview.isVerified = true;
11330
+ }
11331
+ await batch.commit();
11332
+ const updatePromises = [];
11333
+ if (review.clinicReview) {
11334
+ updatePromises.push(
11335
+ this.updateClinicReviewInfo(review.clinicReview.clinicId)
11336
+ );
11337
+ }
11338
+ if (review.practitionerReview) {
11339
+ updatePromises.push(
11340
+ this.updatePractitionerReviewInfo(
11341
+ review.practitionerReview.practitionerId
11342
+ )
11343
+ );
11344
+ }
11345
+ if (review.procedureReview) {
11346
+ updatePromises.push(
11347
+ this.updateProcedureReviewInfo(review.procedureReview.procedureId)
11348
+ );
11349
+ }
11350
+ await Promise.all(updatePromises);
11351
+ }
11352
+ /**
11353
+ * Calculates the average of an array of numbers
11354
+ * @param numbers Array of numbers to average
11355
+ * @returns The average, or 0 if the array is empty
11356
+ */
11357
+ calculateAverage(numbers) {
11358
+ if (numbers.length === 0) {
11359
+ return 0;
11360
+ }
11361
+ const sum = numbers.reduce((a, b) => a + b, 0);
11362
+ const avg = sum / numbers.length;
11363
+ return Math.round(avg * 10) / 10;
11364
+ }
11365
+ };
11366
+
11367
+ // src/backoffice/services/brand.service.ts
11368
+ import {
11369
+ addDoc as addDoc3,
11370
+ collection as collection23,
11371
+ doc as doc24,
11372
+ getDoc as getDoc26,
11373
+ getDocs as getDocs23,
11374
+ query as query23,
11375
+ updateDoc as updateDoc25,
11376
+ where as where23
10704
11377
  } from "firebase/firestore";
10705
11378
 
10706
11379
  // src/backoffice/types/brand.types.ts
@@ -10712,7 +11385,7 @@ var BrandService = class extends BaseService {
10712
11385
  * Gets reference to brands collection
10713
11386
  */
10714
11387
  getBrandsRef() {
10715
- return collection22(this.db, BRANDS_COLLECTION);
11388
+ return collection23(this.db, BRANDS_COLLECTION);
10716
11389
  }
10717
11390
  /**
10718
11391
  * Creates a new brand
@@ -10732,12 +11405,12 @@ var BrandService = class extends BaseService {
10732
11405
  * Gets all active brands
10733
11406
  */
10734
11407
  async getAll() {
10735
- const q = query22(this.getBrandsRef(), where22("isActive", "==", true));
10736
- const snapshot = await getDocs22(q);
11408
+ const q = query23(this.getBrandsRef(), where23("isActive", "==", true));
11409
+ const snapshot = await getDocs23(q);
10737
11410
  return snapshot.docs.map(
10738
- (doc28) => ({
10739
- id: doc28.id,
10740
- ...doc28.data()
11411
+ (doc29) => ({
11412
+ id: doc29.id,
11413
+ ...doc29.data()
10741
11414
  })
10742
11415
  );
10743
11416
  }
@@ -10749,8 +11422,8 @@ var BrandService = class extends BaseService {
10749
11422
  ...brand,
10750
11423
  updatedAt: /* @__PURE__ */ new Date()
10751
11424
  };
10752
- const docRef = doc23(this.getBrandsRef(), brandId);
10753
- await updateDoc24(docRef, updateData);
11425
+ const docRef = doc24(this.getBrandsRef(), brandId);
11426
+ await updateDoc25(docRef, updateData);
10754
11427
  return this.getById(brandId);
10755
11428
  }
10756
11429
  /**
@@ -10765,8 +11438,8 @@ var BrandService = class extends BaseService {
10765
11438
  * Gets a brand by ID
10766
11439
  */
10767
11440
  async getById(brandId) {
10768
- const docRef = doc23(this.getBrandsRef(), brandId);
10769
- const docSnap = await getDoc25(docRef);
11441
+ const docRef = doc24(this.getBrandsRef(), brandId);
11442
+ const docSnap = await getDoc26(docRef);
10770
11443
  if (!docSnap.exists()) return null;
10771
11444
  return {
10772
11445
  id: docSnap.id,
@@ -10778,13 +11451,13 @@ var BrandService = class extends BaseService {
10778
11451
  // src/backoffice/services/category.service.ts
10779
11452
  import {
10780
11453
  addDoc as addDoc4,
10781
- collection as collection23,
10782
- doc as doc24,
10783
- getDoc as getDoc26,
10784
- getDocs as getDocs23,
10785
- query as query23,
10786
- updateDoc as updateDoc25,
10787
- where as where23
11454
+ collection as collection24,
11455
+ doc as doc25,
11456
+ getDoc as getDoc27,
11457
+ getDocs as getDocs24,
11458
+ query as query24,
11459
+ updateDoc as updateDoc26,
11460
+ where as where24
10788
11461
  } from "firebase/firestore";
10789
11462
 
10790
11463
  // src/backoffice/types/category.types.ts
@@ -10796,7 +11469,7 @@ var CategoryService = class extends BaseService {
10796
11469
  * Referenca na Firestore kolekciju kategorija
10797
11470
  */
10798
11471
  get categoriesRef() {
10799
- return collection23(this.db, CATEGORIES_COLLECTION);
11472
+ return collection24(this.db, CATEGORIES_COLLECTION);
10800
11473
  }
10801
11474
  /**
10802
11475
  * Kreira novu kategoriju u sistemu
@@ -10819,12 +11492,12 @@ var CategoryService = class extends BaseService {
10819
11492
  * @returns Lista aktivnih kategorija
10820
11493
  */
10821
11494
  async getAll() {
10822
- const q = query23(this.categoriesRef, where23("isActive", "==", true));
10823
- const snapshot = await getDocs23(q);
11495
+ const q = query24(this.categoriesRef, where24("isActive", "==", true));
11496
+ const snapshot = await getDocs24(q);
10824
11497
  return snapshot.docs.map(
10825
- (doc28) => ({
10826
- id: doc28.id,
10827
- ...doc28.data()
11498
+ (doc29) => ({
11499
+ id: doc29.id,
11500
+ ...doc29.data()
10828
11501
  })
10829
11502
  );
10830
11503
  }
@@ -10834,16 +11507,16 @@ var CategoryService = class extends BaseService {
10834
11507
  * @returns Lista kategorija koje pripadaju traženoj familiji
10835
11508
  */
10836
11509
  async getAllByFamily(family) {
10837
- const q = query23(
11510
+ const q = query24(
10838
11511
  this.categoriesRef,
10839
- where23("family", "==", family),
10840
- where23("isActive", "==", true)
11512
+ where24("family", "==", family),
11513
+ where24("isActive", "==", true)
10841
11514
  );
10842
- const snapshot = await getDocs23(q);
11515
+ const snapshot = await getDocs24(q);
10843
11516
  return snapshot.docs.map(
10844
- (doc28) => ({
10845
- id: doc28.id,
10846
- ...doc28.data()
11517
+ (doc29) => ({
11518
+ id: doc29.id,
11519
+ ...doc29.data()
10847
11520
  })
10848
11521
  );
10849
11522
  }
@@ -10858,8 +11531,8 @@ var CategoryService = class extends BaseService {
10858
11531
  ...category,
10859
11532
  updatedAt: /* @__PURE__ */ new Date()
10860
11533
  };
10861
- const docRef = doc24(this.categoriesRef, id);
10862
- await updateDoc25(docRef, updateData);
11534
+ const docRef = doc25(this.categoriesRef, id);
11535
+ await updateDoc26(docRef, updateData);
10863
11536
  return this.getById(id);
10864
11537
  }
10865
11538
  /**
@@ -10875,8 +11548,8 @@ var CategoryService = class extends BaseService {
10875
11548
  * @returns Kategorija ili null ako ne postoji
10876
11549
  */
10877
11550
  async getById(id) {
10878
- const docRef = doc24(this.categoriesRef, id);
10879
- const docSnap = await getDoc26(docRef);
11551
+ const docRef = doc25(this.categoriesRef, id);
11552
+ const docSnap = await getDoc27(docRef);
10880
11553
  if (!docSnap.exists()) return null;
10881
11554
  return {
10882
11555
  id: docSnap.id,
@@ -10888,13 +11561,13 @@ var CategoryService = class extends BaseService {
10888
11561
  // src/backoffice/services/subcategory.service.ts
10889
11562
  import {
10890
11563
  addDoc as addDoc5,
10891
- collection as collection24,
10892
- doc as doc25,
10893
- getDoc as getDoc27,
10894
- getDocs as getDocs24,
10895
- query as query24,
10896
- updateDoc as updateDoc26,
10897
- where as where24
11564
+ collection as collection25,
11565
+ doc as doc26,
11566
+ getDoc as getDoc28,
11567
+ getDocs as getDocs25,
11568
+ query as query25,
11569
+ updateDoc as updateDoc27,
11570
+ where as where25
10898
11571
  } from "firebase/firestore";
10899
11572
 
10900
11573
  // src/backoffice/types/subcategory.types.ts
@@ -10907,7 +11580,7 @@ var SubcategoryService = class extends BaseService {
10907
11580
  * @param categoryId - ID roditeljske kategorije
10908
11581
  */
10909
11582
  getSubcategoriesRef(categoryId) {
10910
- return collection24(
11583
+ return collection25(
10911
11584
  this.db,
10912
11585
  CATEGORIES_COLLECTION,
10913
11586
  categoryId,
@@ -10941,15 +11614,15 @@ var SubcategoryService = class extends BaseService {
10941
11614
  * @returns Lista aktivnih podkategorija
10942
11615
  */
10943
11616
  async getAllByCategoryId(categoryId) {
10944
- const q = query24(
11617
+ const q = query25(
10945
11618
  this.getSubcategoriesRef(categoryId),
10946
- where24("isActive", "==", true)
11619
+ where25("isActive", "==", true)
10947
11620
  );
10948
- const snapshot = await getDocs24(q);
11621
+ const snapshot = await getDocs25(q);
10949
11622
  return snapshot.docs.map(
10950
- (doc28) => ({
10951
- id: doc28.id,
10952
- ...doc28.data()
11623
+ (doc29) => ({
11624
+ id: doc29.id,
11625
+ ...doc29.data()
10953
11626
  })
10954
11627
  );
10955
11628
  }
@@ -10965,8 +11638,8 @@ var SubcategoryService = class extends BaseService {
10965
11638
  ...subcategory,
10966
11639
  updatedAt: /* @__PURE__ */ new Date()
10967
11640
  };
10968
- const docRef = doc25(this.getSubcategoriesRef(categoryId), subcategoryId);
10969
- await updateDoc26(docRef, updateData);
11641
+ const docRef = doc26(this.getSubcategoriesRef(categoryId), subcategoryId);
11642
+ await updateDoc27(docRef, updateData);
10970
11643
  return this.getById(categoryId, subcategoryId);
10971
11644
  }
10972
11645
  /**
@@ -10984,8 +11657,8 @@ var SubcategoryService = class extends BaseService {
10984
11657
  * @returns Podkategorija ili null ako ne postoji
10985
11658
  */
10986
11659
  async getById(categoryId, subcategoryId) {
10987
- const docRef = doc25(this.getSubcategoriesRef(categoryId), subcategoryId);
10988
- const docSnap = await getDoc27(docRef);
11660
+ const docRef = doc26(this.getSubcategoriesRef(categoryId), subcategoryId);
11661
+ const docSnap = await getDoc28(docRef);
10989
11662
  if (!docSnap.exists()) return null;
10990
11663
  return {
10991
11664
  id: docSnap.id,
@@ -10997,13 +11670,13 @@ var SubcategoryService = class extends BaseService {
10997
11670
  // src/backoffice/services/technology.service.ts
10998
11671
  import {
10999
11672
  addDoc as addDoc6,
11000
- collection as collection25,
11001
- doc as doc26,
11002
- getDoc as getDoc28,
11003
- getDocs as getDocs25,
11004
- query as query25,
11005
- updateDoc as updateDoc27,
11006
- where as where25,
11673
+ collection as collection26,
11674
+ doc as doc27,
11675
+ getDoc as getDoc29,
11676
+ getDocs as getDocs26,
11677
+ query as query26,
11678
+ updateDoc as updateDoc28,
11679
+ where as where26,
11007
11680
  arrayUnion as arrayUnion8,
11008
11681
  arrayRemove as arrayRemove7
11009
11682
  } from "firebase/firestore";
@@ -11021,7 +11694,7 @@ var TechnologyService = class extends BaseService {
11021
11694
  * Vraća referencu na Firestore kolekciju tehnologija
11022
11695
  */
11023
11696
  getTechnologiesRef() {
11024
- return collection25(this.db, TECHNOLOGIES_COLLECTION);
11697
+ return collection26(this.db, TECHNOLOGIES_COLLECTION);
11025
11698
  }
11026
11699
  /**
11027
11700
  * Kreira novu tehnologiju
@@ -11052,12 +11725,12 @@ var TechnologyService = class extends BaseService {
11052
11725
  * @returns Lista aktivnih tehnologija
11053
11726
  */
11054
11727
  async getAll() {
11055
- const q = query25(this.getTechnologiesRef(), where25("isActive", "==", true));
11056
- const snapshot = await getDocs25(q);
11728
+ const q = query26(this.getTechnologiesRef(), where26("isActive", "==", true));
11729
+ const snapshot = await getDocs26(q);
11057
11730
  return snapshot.docs.map(
11058
- (doc28) => ({
11059
- id: doc28.id,
11060
- ...doc28.data()
11731
+ (doc29) => ({
11732
+ id: doc29.id,
11733
+ ...doc29.data()
11061
11734
  })
11062
11735
  );
11063
11736
  }
@@ -11067,16 +11740,16 @@ var TechnologyService = class extends BaseService {
11067
11740
  * @returns Lista aktivnih tehnologija
11068
11741
  */
11069
11742
  async getAllByFamily(family) {
11070
- const q = query25(
11743
+ const q = query26(
11071
11744
  this.getTechnologiesRef(),
11072
- where25("isActive", "==", true),
11073
- where25("family", "==", family)
11745
+ where26("isActive", "==", true),
11746
+ where26("family", "==", family)
11074
11747
  );
11075
- const snapshot = await getDocs25(q);
11748
+ const snapshot = await getDocs26(q);
11076
11749
  return snapshot.docs.map(
11077
- (doc28) => ({
11078
- id: doc28.id,
11079
- ...doc28.data()
11750
+ (doc29) => ({
11751
+ id: doc29.id,
11752
+ ...doc29.data()
11080
11753
  })
11081
11754
  );
11082
11755
  }
@@ -11086,16 +11759,16 @@ var TechnologyService = class extends BaseService {
11086
11759
  * @returns Lista aktivnih tehnologija
11087
11760
  */
11088
11761
  async getAllByCategoryId(categoryId) {
11089
- const q = query25(
11762
+ const q = query26(
11090
11763
  this.getTechnologiesRef(),
11091
- where25("isActive", "==", true),
11092
- where25("categoryId", "==", categoryId)
11764
+ where26("isActive", "==", true),
11765
+ where26("categoryId", "==", categoryId)
11093
11766
  );
11094
- const snapshot = await getDocs25(q);
11767
+ const snapshot = await getDocs26(q);
11095
11768
  return snapshot.docs.map(
11096
- (doc28) => ({
11097
- id: doc28.id,
11098
- ...doc28.data()
11769
+ (doc29) => ({
11770
+ id: doc29.id,
11771
+ ...doc29.data()
11099
11772
  })
11100
11773
  );
11101
11774
  }
@@ -11105,16 +11778,16 @@ var TechnologyService = class extends BaseService {
11105
11778
  * @returns Lista aktivnih tehnologija
11106
11779
  */
11107
11780
  async getAllBySubcategoryId(subcategoryId) {
11108
- const q = query25(
11781
+ const q = query26(
11109
11782
  this.getTechnologiesRef(),
11110
- where25("isActive", "==", true),
11111
- where25("subcategoryId", "==", subcategoryId)
11783
+ where26("isActive", "==", true),
11784
+ where26("subcategoryId", "==", subcategoryId)
11112
11785
  );
11113
- const snapshot = await getDocs25(q);
11786
+ const snapshot = await getDocs26(q);
11114
11787
  return snapshot.docs.map(
11115
- (doc28) => ({
11116
- id: doc28.id,
11117
- ...doc28.data()
11788
+ (doc29) => ({
11789
+ id: doc29.id,
11790
+ ...doc29.data()
11118
11791
  })
11119
11792
  );
11120
11793
  }
@@ -11129,8 +11802,8 @@ var TechnologyService = class extends BaseService {
11129
11802
  ...technology,
11130
11803
  updatedAt: /* @__PURE__ */ new Date()
11131
11804
  };
11132
- const docRef = doc26(this.getTechnologiesRef(), technologyId);
11133
- await updateDoc27(docRef, updateData);
11805
+ const docRef = doc27(this.getTechnologiesRef(), technologyId);
11806
+ await updateDoc28(docRef, updateData);
11134
11807
  return this.getById(technologyId);
11135
11808
  }
11136
11809
  /**
@@ -11148,8 +11821,8 @@ var TechnologyService = class extends BaseService {
11148
11821
  * @returns Tehnologija ili null ako ne postoji
11149
11822
  */
11150
11823
  async getById(technologyId) {
11151
- const docRef = doc26(this.getTechnologiesRef(), technologyId);
11152
- const docSnap = await getDoc28(docRef);
11824
+ const docRef = doc27(this.getTechnologiesRef(), technologyId);
11825
+ const docSnap = await getDoc29(docRef);
11153
11826
  if (!docSnap.exists()) return null;
11154
11827
  return {
11155
11828
  id: docSnap.id,
@@ -11163,9 +11836,9 @@ var TechnologyService = class extends BaseService {
11163
11836
  * @returns Ažurirana tehnologija sa novim zahtevom
11164
11837
  */
11165
11838
  async addRequirement(technologyId, requirement) {
11166
- const docRef = doc26(this.getTechnologiesRef(), technologyId);
11839
+ const docRef = doc27(this.getTechnologiesRef(), technologyId);
11167
11840
  const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
11168
- await updateDoc27(docRef, {
11841
+ await updateDoc28(docRef, {
11169
11842
  [requirementType]: arrayUnion8(requirement),
11170
11843
  updatedAt: /* @__PURE__ */ new Date()
11171
11844
  });
@@ -11178,9 +11851,9 @@ var TechnologyService = class extends BaseService {
11178
11851
  * @returns Ažurirana tehnologija bez uklonjenog zahteva
11179
11852
  */
11180
11853
  async removeRequirement(technologyId, requirement) {
11181
- const docRef = doc26(this.getTechnologiesRef(), technologyId);
11854
+ const docRef = doc27(this.getTechnologiesRef(), technologyId);
11182
11855
  const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
11183
- await updateDoc27(docRef, {
11856
+ await updateDoc28(docRef, {
11184
11857
  [requirementType]: arrayRemove7(requirement),
11185
11858
  updatedAt: /* @__PURE__ */ new Date()
11186
11859
  });
@@ -11218,8 +11891,8 @@ var TechnologyService = class extends BaseService {
11218
11891
  * @returns Ažurirana tehnologija
11219
11892
  */
11220
11893
  async addBlockingCondition(technologyId, condition) {
11221
- const docRef = doc26(this.getTechnologiesRef(), technologyId);
11222
- await updateDoc27(docRef, {
11894
+ const docRef = doc27(this.getTechnologiesRef(), technologyId);
11895
+ await updateDoc28(docRef, {
11223
11896
  blockingConditions: arrayUnion8(condition),
11224
11897
  updatedAt: /* @__PURE__ */ new Date()
11225
11898
  });
@@ -11232,8 +11905,8 @@ var TechnologyService = class extends BaseService {
11232
11905
  * @returns Ažurirana tehnologija
11233
11906
  */
11234
11907
  async removeBlockingCondition(technologyId, condition) {
11235
- const docRef = doc26(this.getTechnologiesRef(), technologyId);
11236
- await updateDoc27(docRef, {
11908
+ const docRef = doc27(this.getTechnologiesRef(), technologyId);
11909
+ await updateDoc28(docRef, {
11237
11910
  blockingConditions: arrayRemove7(condition),
11238
11911
  updatedAt: /* @__PURE__ */ new Date()
11239
11912
  });
@@ -11246,8 +11919,8 @@ var TechnologyService = class extends BaseService {
11246
11919
  * @returns Ažurirana tehnologija
11247
11920
  */
11248
11921
  async addContraindication(technologyId, contraindication) {
11249
- const docRef = doc26(this.getTechnologiesRef(), technologyId);
11250
- await updateDoc27(docRef, {
11922
+ const docRef = doc27(this.getTechnologiesRef(), technologyId);
11923
+ await updateDoc28(docRef, {
11251
11924
  contraindications: arrayUnion8(contraindication),
11252
11925
  updatedAt: /* @__PURE__ */ new Date()
11253
11926
  });
@@ -11260,8 +11933,8 @@ var TechnologyService = class extends BaseService {
11260
11933
  * @returns Ažurirana tehnologija
11261
11934
  */
11262
11935
  async removeContraindication(technologyId, contraindication) {
11263
- const docRef = doc26(this.getTechnologiesRef(), technologyId);
11264
- await updateDoc27(docRef, {
11936
+ const docRef = doc27(this.getTechnologiesRef(), technologyId);
11937
+ await updateDoc28(docRef, {
11265
11938
  contraindications: arrayRemove7(contraindication),
11266
11939
  updatedAt: /* @__PURE__ */ new Date()
11267
11940
  });
@@ -11274,8 +11947,8 @@ var TechnologyService = class extends BaseService {
11274
11947
  * @returns Ažurirana tehnologija
11275
11948
  */
11276
11949
  async addBenefit(technologyId, benefit) {
11277
- const docRef = doc26(this.getTechnologiesRef(), technologyId);
11278
- await updateDoc27(docRef, {
11950
+ const docRef = doc27(this.getTechnologiesRef(), technologyId);
11951
+ await updateDoc28(docRef, {
11279
11952
  benefits: arrayUnion8(benefit),
11280
11953
  updatedAt: /* @__PURE__ */ new Date()
11281
11954
  });
@@ -11288,8 +11961,8 @@ var TechnologyService = class extends BaseService {
11288
11961
  * @returns Ažurirana tehnologija
11289
11962
  */
11290
11963
  async removeBenefit(technologyId, benefit) {
11291
- const docRef = doc26(this.getTechnologiesRef(), technologyId);
11292
- await updateDoc27(docRef, {
11964
+ const docRef = doc27(this.getTechnologiesRef(), technologyId);
11965
+ await updateDoc28(docRef, {
11293
11966
  benefits: arrayRemove7(benefit),
11294
11967
  updatedAt: /* @__PURE__ */ new Date()
11295
11968
  });
@@ -11329,8 +12002,8 @@ var TechnologyService = class extends BaseService {
11329
12002
  * @returns Ažurirana tehnologija
11330
12003
  */
11331
12004
  async updateCertificationRequirement(technologyId, certificationRequirement) {
11332
- const docRef = doc26(this.getTechnologiesRef(), technologyId);
11333
- await updateDoc27(docRef, {
12005
+ const docRef = doc27(this.getTechnologiesRef(), technologyId);
12006
+ await updateDoc28(docRef, {
11334
12007
  certificationRequirement,
11335
12008
  updatedAt: /* @__PURE__ */ new Date()
11336
12009
  });
@@ -11432,13 +12105,13 @@ var TechnologyService = class extends BaseService {
11432
12105
  // src/backoffice/services/product.service.ts
11433
12106
  import {
11434
12107
  addDoc as addDoc7,
11435
- collection as collection26,
11436
- doc as doc27,
11437
- getDoc as getDoc29,
11438
- getDocs as getDocs26,
11439
- query as query26,
11440
- updateDoc as updateDoc28,
11441
- where as where26
12108
+ collection as collection27,
12109
+ doc as doc28,
12110
+ getDoc as getDoc30,
12111
+ getDocs as getDocs27,
12112
+ query as query27,
12113
+ updateDoc as updateDoc29,
12114
+ where as where27
11442
12115
  } from "firebase/firestore";
11443
12116
 
11444
12117
  // src/backoffice/types/product.types.ts
@@ -11452,7 +12125,7 @@ var ProductService = class extends BaseService {
11452
12125
  * @returns Firestore collection reference
11453
12126
  */
11454
12127
  getProductsRef(technologyId) {
11455
- return collection26(
12128
+ return collection27(
11456
12129
  this.db,
11457
12130
  TECHNOLOGIES_COLLECTION,
11458
12131
  technologyId,
@@ -11482,15 +12155,15 @@ var ProductService = class extends BaseService {
11482
12155
  * Gets all products for a technology
11483
12156
  */
11484
12157
  async getAllByTechnology(technologyId) {
11485
- const q = query26(
12158
+ const q = query27(
11486
12159
  this.getProductsRef(technologyId),
11487
- where26("isActive", "==", true)
12160
+ where27("isActive", "==", true)
11488
12161
  );
11489
- const snapshot = await getDocs26(q);
12162
+ const snapshot = await getDocs27(q);
11490
12163
  return snapshot.docs.map(
11491
- (doc28) => ({
11492
- id: doc28.id,
11493
- ...doc28.data()
12164
+ (doc29) => ({
12165
+ id: doc29.id,
12166
+ ...doc29.data()
11494
12167
  })
11495
12168
  );
11496
12169
  }
@@ -11498,21 +12171,21 @@ var ProductService = class extends BaseService {
11498
12171
  * Gets all products for a brand by filtering through all technologies
11499
12172
  */
11500
12173
  async getAllByBrand(brandId) {
11501
- const allTechnologiesRef = collection26(this.db, TECHNOLOGIES_COLLECTION);
11502
- const technologiesSnapshot = await getDocs26(allTechnologiesRef);
12174
+ const allTechnologiesRef = collection27(this.db, TECHNOLOGIES_COLLECTION);
12175
+ const technologiesSnapshot = await getDocs27(allTechnologiesRef);
11503
12176
  const products = [];
11504
12177
  for (const techDoc of technologiesSnapshot.docs) {
11505
- const q = query26(
12178
+ const q = query27(
11506
12179
  this.getProductsRef(techDoc.id),
11507
- where26("brandId", "==", brandId),
11508
- where26("isActive", "==", true)
12180
+ where27("brandId", "==", brandId),
12181
+ where27("isActive", "==", true)
11509
12182
  );
11510
- const snapshot = await getDocs26(q);
12183
+ const snapshot = await getDocs27(q);
11511
12184
  products.push(
11512
12185
  ...snapshot.docs.map(
11513
- (doc28) => ({
11514
- id: doc28.id,
11515
- ...doc28.data()
12186
+ (doc29) => ({
12187
+ id: doc29.id,
12188
+ ...doc29.data()
11516
12189
  })
11517
12190
  )
11518
12191
  );
@@ -11527,8 +12200,8 @@ var ProductService = class extends BaseService {
11527
12200
  ...product,
11528
12201
  updatedAt: /* @__PURE__ */ new Date()
11529
12202
  };
11530
- const docRef = doc27(this.getProductsRef(technologyId), productId);
11531
- await updateDoc28(docRef, updateData);
12203
+ const docRef = doc28(this.getProductsRef(technologyId), productId);
12204
+ await updateDoc29(docRef, updateData);
11532
12205
  return this.getById(technologyId, productId);
11533
12206
  }
11534
12207
  /**
@@ -11543,8 +12216,8 @@ var ProductService = class extends BaseService {
11543
12216
  * Gets a product by ID
11544
12217
  */
11545
12218
  async getById(technologyId, productId) {
11546
- const docRef = doc27(this.getProductsRef(technologyId), productId);
11547
- const docSnap = await getDoc29(docRef);
12219
+ const docRef = doc28(this.getProductsRef(technologyId), productId);
12220
+ const docSnap = await getDoc30(docRef);
11548
12221
  if (!docSnap.exists()) return null;
11549
12222
  return {
11550
12223
  id: docSnap.id,
@@ -11554,54 +12227,54 @@ var ProductService = class extends BaseService {
11554
12227
  };
11555
12228
 
11556
12229
  // src/validations/notification.schema.ts
11557
- import { z as z21 } from "zod";
11558
- var baseNotificationSchema = z21.object({
11559
- id: z21.string().optional(),
11560
- userId: z21.string(),
11561
- notificationTime: z21.any(),
12230
+ import { z as z22 } from "zod";
12231
+ var baseNotificationSchema = z22.object({
12232
+ id: z22.string().optional(),
12233
+ userId: z22.string(),
12234
+ notificationTime: z22.any(),
11562
12235
  // Timestamp
11563
- notificationType: z21.nativeEnum(NotificationType),
11564
- notificationTokens: z21.array(z21.string()),
11565
- status: z21.nativeEnum(NotificationStatus),
11566
- createdAt: z21.any().optional(),
12236
+ notificationType: z22.nativeEnum(NotificationType),
12237
+ notificationTokens: z22.array(z22.string()),
12238
+ status: z22.nativeEnum(NotificationStatus),
12239
+ createdAt: z22.any().optional(),
11567
12240
  // Timestamp
11568
- updatedAt: z21.any().optional(),
12241
+ updatedAt: z22.any().optional(),
11569
12242
  // Timestamp
11570
- title: z21.string(),
11571
- body: z21.string(),
11572
- isRead: z21.boolean(),
11573
- userRole: z21.nativeEnum(UserRole)
12243
+ title: z22.string(),
12244
+ body: z22.string(),
12245
+ isRead: z22.boolean(),
12246
+ userRole: z22.nativeEnum(UserRole)
11574
12247
  });
11575
12248
  var preRequirementNotificationSchema = baseNotificationSchema.extend({
11576
- notificationType: z21.literal("preRequirement" /* PRE_REQUIREMENT */),
11577
- treatmentId: z21.string(),
11578
- requirements: z21.array(z21.string()),
11579
- deadline: z21.any()
12249
+ notificationType: z22.literal("preRequirement" /* PRE_REQUIREMENT */),
12250
+ treatmentId: z22.string(),
12251
+ requirements: z22.array(z22.string()),
12252
+ deadline: z22.any()
11580
12253
  // Timestamp
11581
12254
  });
11582
12255
  var postRequirementNotificationSchema = baseNotificationSchema.extend({
11583
- notificationType: z21.literal("postRequirement" /* POST_REQUIREMENT */),
11584
- treatmentId: z21.string(),
11585
- requirements: z21.array(z21.string()),
11586
- deadline: z21.any()
12256
+ notificationType: z22.literal("postRequirement" /* POST_REQUIREMENT */),
12257
+ treatmentId: z22.string(),
12258
+ requirements: z22.array(z22.string()),
12259
+ deadline: z22.any()
11587
12260
  // Timestamp
11588
12261
  });
11589
12262
  var appointmentReminderNotificationSchema = baseNotificationSchema.extend({
11590
- notificationType: z21.literal("appointmentReminder" /* APPOINTMENT_REMINDER */),
11591
- appointmentId: z21.string(),
11592
- appointmentTime: z21.any(),
12263
+ notificationType: z22.literal("appointmentReminder" /* APPOINTMENT_REMINDER */),
12264
+ appointmentId: z22.string(),
12265
+ appointmentTime: z22.any(),
11593
12266
  // Timestamp
11594
- treatmentType: z21.string(),
11595
- doctorName: z21.string()
12267
+ treatmentType: z22.string(),
12268
+ doctorName: z22.string()
11596
12269
  });
11597
12270
  var appointmentNotificationSchema = baseNotificationSchema.extend({
11598
- notificationType: z21.literal("appointmentNotification" /* APPOINTMENT_NOTIFICATION */),
11599
- appointmentId: z21.string(),
11600
- appointmentStatus: z21.string(),
11601
- previousStatus: z21.string(),
11602
- reason: z21.string().optional()
12271
+ notificationType: z22.literal("appointmentNotification" /* APPOINTMENT_NOTIFICATION */),
12272
+ appointmentId: z22.string(),
12273
+ appointmentStatus: z22.string(),
12274
+ previousStatus: z22.string(),
12275
+ reason: z22.string().optional()
11603
12276
  });
11604
- var notificationSchema = z21.discriminatedUnion("notificationType", [
12277
+ var notificationSchema = z22.discriminatedUnion("notificationType", [
11605
12278
  preRequirementNotificationSchema,
11606
12279
  postRequirementNotificationSchema,
11607
12280
  appointmentReminderNotificationSchema,
@@ -11628,8 +12301,17 @@ var TreatmentBenefit = /* @__PURE__ */ ((TreatmentBenefit2) => {
11628
12301
  return TreatmentBenefit2;
11629
12302
  })(TreatmentBenefit || {});
11630
12303
 
11631
- // src/types/reviews/index.ts
11632
- var REVIEWS_COLLECTION = "reviews";
12304
+ // src/backoffice/types/requirement.types.ts
12305
+ var TimeUnit = /* @__PURE__ */ ((TimeUnit2) => {
12306
+ TimeUnit2["HOURS"] = "hours";
12307
+ TimeUnit2["DAYS"] = "days";
12308
+ return TimeUnit2;
12309
+ })(TimeUnit || {});
12310
+ var RequirementType = /* @__PURE__ */ ((RequirementType2) => {
12311
+ RequirementType2["PRE"] = "pre";
12312
+ RequirementType2["POST"] = "post";
12313
+ return RequirementType2;
12314
+ })(RequirementType || {});
11633
12315
  export {
11634
12316
  AUTH_ERRORS,
11635
12317
  AdminTokenStatus,
@@ -11693,6 +12375,8 @@ export {
11693
12375
  ProductService,
11694
12376
  REGISTER_TOKENS_COLLECTION,
11695
12377
  REVIEWS_COLLECTION,
12378
+ RequirementType,
12379
+ ReviewService,
11696
12380
  SYNCED_CALENDARS_COLLECTION,
11697
12381
  SearchLocationEnum,
11698
12382
  SubcategoryService,
@@ -11700,6 +12384,7 @@ export {
11700
12384
  SyncedCalendarProvider,
11701
12385
  SyncedCalendarsService,
11702
12386
  TechnologyService,
12387
+ TimeUnit,
11703
12388
  TreatmentBenefit,
11704
12389
  USER_ERRORS,
11705
12390
  UserService,