@blackcode_sa/metaestetics-api 1.8.14 → 1.8.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6833,80 +6833,163 @@ var PractitionerService = class extends BaseService {
6833
6833
  */
6834
6834
  async getPractitionersByFilters(filters) {
6835
6835
  try {
6836
- const constraints = [];
6837
- if (!filters.includeDraftPractitioners) {
6838
- constraints.push((0, import_firestore21.where)("status", "==", "active" /* ACTIVE */));
6839
- }
6840
- constraints.push((0, import_firestore21.where)("isActive", "==", true));
6841
- if (filters.certifications && filters.certifications.length > 0) {
6842
- constraints.push(
6843
- (0, import_firestore21.where)(
6844
- "certification.certifications",
6845
- "array-contains-any",
6846
- filters.certifications
6847
- )
6848
- );
6836
+ console.log("[PRACTITIONER_SERVICE] Starting practitioner filtering with fallback strategies");
6837
+ if (filters.location && filters.radiusInKm) {
6838
+ console.log("[PRACTITIONER_SERVICE] Executing geo query:", {
6839
+ location: filters.location,
6840
+ radius: filters.radiusInKm,
6841
+ serviceName: "PractitionerService"
6842
+ });
6843
+ if (!filters.location.latitude || !filters.location.longitude) {
6844
+ console.warn("[PRACTITIONER_SERVICE] Invalid location data:", filters.location);
6845
+ filters.location = void 0;
6846
+ filters.radiusInKm = void 0;
6847
+ }
6849
6848
  }
6850
6849
  if (filters.nameSearch && filters.nameSearch.trim()) {
6851
- const searchTerm = filters.nameSearch.trim().toLowerCase();
6852
- constraints.push((0, import_firestore21.where)("fullNameLower", ">=", searchTerm));
6853
- constraints.push((0, import_firestore21.where)("fullNameLower", "<=", searchTerm + "\uF8FF"));
6854
- }
6855
- if (filters.procedureTechnology) {
6856
- constraints.push((0, import_firestore21.where)("proceduresInfo.technologyName", "==", filters.procedureTechnology));
6857
- } else if (filters.procedureSubcategory) {
6858
- constraints.push((0, import_firestore21.where)("proceduresInfo.subcategoryName", "==", filters.procedureSubcategory));
6859
- } else if (filters.procedureCategory) {
6860
- constraints.push((0, import_firestore21.where)("proceduresInfo.categoryName", "==", filters.procedureCategory));
6861
- } else if (filters.procedureFamily) {
6862
- constraints.push((0, import_firestore21.where)("proceduresInfo.family", "==", filters.procedureFamily));
6863
- }
6864
- if (filters.minRating !== void 0) {
6865
- constraints.push((0, import_firestore21.where)("reviewInfo.averageRating", ">=", filters.minRating));
6866
- }
6867
- if (filters.maxRating !== void 0) {
6868
- constraints.push((0, import_firestore21.where)("reviewInfo.averageRating", "<=", filters.maxRating));
6850
+ try {
6851
+ console.log("[PRACTITIONER_SERVICE] Strategy 1: Trying fullNameLower search");
6852
+ const searchTerm = filters.nameSearch.trim().toLowerCase();
6853
+ const constraints = [];
6854
+ if (!filters.includeDraftPractitioners) {
6855
+ constraints.push((0, import_firestore21.where)("status", "==", "active" /* ACTIVE */));
6856
+ }
6857
+ constraints.push((0, import_firestore21.where)("isActive", "==", true));
6858
+ constraints.push((0, import_firestore21.where)("fullNameLower", ">=", searchTerm));
6859
+ constraints.push((0, import_firestore21.where)("fullNameLower", "<=", searchTerm + "\uF8FF"));
6860
+ constraints.push((0, import_firestore21.orderBy)("fullNameLower"));
6861
+ if (filters.lastDoc) {
6862
+ if (typeof filters.lastDoc.data === "function") {
6863
+ constraints.push((0, import_firestore21.startAfter)(filters.lastDoc));
6864
+ } else if (Array.isArray(filters.lastDoc)) {
6865
+ constraints.push((0, import_firestore21.startAfter)(...filters.lastDoc));
6866
+ } else {
6867
+ constraints.push((0, import_firestore21.startAfter)(filters.lastDoc));
6868
+ }
6869
+ }
6870
+ constraints.push((0, import_firestore21.limit)(filters.pagination || 10));
6871
+ const q = (0, import_firestore21.query)((0, import_firestore21.collection)(this.db, PRACTITIONERS_COLLECTION), ...constraints);
6872
+ const querySnapshot = await (0, import_firestore21.getDocs)(q);
6873
+ const practitioners = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
6874
+ const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
6875
+ console.log(`[PRACTITIONER_SERVICE] Strategy 1 success: ${practitioners.length} practitioners`);
6876
+ if (practitioners.length < (filters.pagination || 10)) {
6877
+ return { practitioners, lastDoc: null };
6878
+ }
6879
+ return { practitioners, lastDoc };
6880
+ } catch (error) {
6881
+ console.log("[PRACTITIONER_SERVICE] Strategy 1 failed:", error);
6882
+ }
6869
6883
  }
6870
- constraints.push((0, import_firestore21.orderBy)("fullNameLower"));
6871
- if (filters.lastDoc) {
6872
- if (typeof filters.lastDoc.data === "function") {
6873
- constraints.push((0, import_firestore21.startAfter)(filters.lastDoc));
6874
- } else if (Array.isArray(filters.lastDoc)) {
6875
- constraints.push((0, import_firestore21.startAfter)(...filters.lastDoc));
6884
+ try {
6885
+ console.log("[PRACTITIONER_SERVICE] Strategy 2: Basic query with createdAt ordering");
6886
+ const constraints = [];
6887
+ if (!filters.includeDraftPractitioners) {
6888
+ constraints.push((0, import_firestore21.where)("status", "==", "active" /* ACTIVE */));
6889
+ }
6890
+ constraints.push((0, import_firestore21.where)("isActive", "==", true));
6891
+ if (filters.certifications && filters.certifications.length > 0) {
6892
+ constraints.push(
6893
+ (0, import_firestore21.where)("certification.specialties", "array-contains-any", filters.certifications)
6894
+ );
6895
+ }
6896
+ if (filters.minRating !== void 0) {
6897
+ constraints.push((0, import_firestore21.where)("reviewInfo.averageRating", ">=", filters.minRating));
6898
+ }
6899
+ if (filters.maxRating !== void 0) {
6900
+ constraints.push((0, import_firestore21.where)("reviewInfo.averageRating", "<=", filters.maxRating));
6901
+ }
6902
+ constraints.push((0, import_firestore21.orderBy)("createdAt", "desc"));
6903
+ if (filters.location && filters.radiusInKm) {
6904
+ constraints.push((0, import_firestore21.limit)((filters.pagination || 10) * 2));
6876
6905
  } else {
6877
- constraints.push((0, import_firestore21.startAfter)(filters.lastDoc));
6906
+ if (filters.lastDoc) {
6907
+ if (typeof filters.lastDoc.data === "function") {
6908
+ constraints.push((0, import_firestore21.startAfter)(filters.lastDoc));
6909
+ } else if (Array.isArray(filters.lastDoc)) {
6910
+ constraints.push((0, import_firestore21.startAfter)(...filters.lastDoc));
6911
+ } else {
6912
+ constraints.push((0, import_firestore21.startAfter)(filters.lastDoc));
6913
+ }
6914
+ }
6915
+ constraints.push((0, import_firestore21.limit)(filters.pagination || 10));
6916
+ }
6917
+ const q = (0, import_firestore21.query)((0, import_firestore21.collection)(this.db, PRACTITIONERS_COLLECTION), ...constraints);
6918
+ const querySnapshot = await (0, import_firestore21.getDocs)(q);
6919
+ let practitioners = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
6920
+ if (filters.location && filters.radiusInKm && filters.radiusInKm > 0) {
6921
+ const location = filters.location;
6922
+ const radiusInKm = filters.radiusInKm;
6923
+ practitioners = practitioners.filter((practitioner) => {
6924
+ const clinics = practitioner.clinicsInfo || [];
6925
+ return clinics.some((clinic) => {
6926
+ const distance = (0, import_geofire_common2.distanceBetween)(
6927
+ [location.latitude, location.longitude],
6928
+ [clinic.location.latitude, clinic.location.longitude]
6929
+ );
6930
+ const distanceInKm = distance / 1e3;
6931
+ return distanceInKm <= radiusInKm;
6932
+ });
6933
+ });
6934
+ practitioners = practitioners.slice(0, filters.pagination || 10);
6878
6935
  }
6936
+ if (filters.nameSearch && filters.nameSearch.trim()) {
6937
+ const searchTerm = filters.nameSearch.trim().toLowerCase();
6938
+ practitioners = practitioners.filter((practitioner) => {
6939
+ var _a, _b;
6940
+ const firstName = (((_a = practitioner.basicInfo) == null ? void 0 : _a.firstName) || "").toLowerCase();
6941
+ const lastName = (((_b = practitioner.basicInfo) == null ? void 0 : _b.lastName) || "").toLowerCase();
6942
+ const fullName = `${firstName} ${lastName}`.trim();
6943
+ const fullNameLower = practitioner.fullNameLower || "";
6944
+ return firstName.includes(searchTerm) || lastName.includes(searchTerm) || fullName.includes(searchTerm) || fullNameLower.includes(searchTerm);
6945
+ });
6946
+ console.log(`[PRACTITIONER_SERVICE] Applied name filter, results: ${practitioners.length}`);
6947
+ }
6948
+ const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
6949
+ console.log(`[PRACTITIONER_SERVICE] Strategy 2 success: ${practitioners.length} practitioners`);
6950
+ if (practitioners.length < (filters.pagination || 10)) {
6951
+ return { practitioners, lastDoc: null };
6952
+ }
6953
+ return { practitioners, lastDoc };
6954
+ } catch (error) {
6955
+ console.log("[PRACTITIONER_SERVICE] Strategy 2 failed:", error);
6879
6956
  }
6880
- constraints.push((0, import_firestore21.limit)(filters.pagination || 5));
6881
- const q = (0, import_firestore21.query)((0, import_firestore21.collection)(this.db, PRACTITIONERS_COLLECTION), ...constraints);
6882
- const querySnapshot = await (0, import_firestore21.getDocs)(q);
6883
- let practitioners = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
6884
- if (filters.location && filters.radiusInKm && filters.radiusInKm > 0) {
6885
- const location = filters.location;
6886
- const radiusInKm = filters.radiusInKm;
6887
- practitioners = practitioners.filter((practitioner) => {
6888
- const clinics = practitioner.clinicsInfo || [];
6889
- return clinics.some((clinic) => {
6890
- const distance = (0, import_geofire_common2.distanceBetween)(
6891
- [location.latitude, location.longitude],
6892
- [clinic.location.latitude, clinic.location.longitude]
6893
- );
6894
- const distanceInKm = distance / 1e3;
6895
- return distanceInKm <= radiusInKm;
6957
+ try {
6958
+ console.log("[PRACTITIONER_SERVICE] Strategy 3: Minimal query fallback");
6959
+ const constraints = [
6960
+ (0, import_firestore21.where)("isActive", "==", true),
6961
+ (0, import_firestore21.orderBy)("createdAt", "desc"),
6962
+ (0, import_firestore21.limit)(filters.pagination || 10)
6963
+ ];
6964
+ const q = (0, import_firestore21.query)((0, import_firestore21.collection)(this.db, PRACTITIONERS_COLLECTION), ...constraints);
6965
+ const querySnapshot = await (0, import_firestore21.getDocs)(q);
6966
+ let practitioners = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
6967
+ if (filters.nameSearch && filters.nameSearch.trim()) {
6968
+ const searchTerm = filters.nameSearch.trim().toLowerCase();
6969
+ practitioners = practitioners.filter((practitioner) => {
6970
+ var _a, _b;
6971
+ const firstName = (((_a = practitioner.basicInfo) == null ? void 0 : _a.firstName) || "").toLowerCase();
6972
+ const lastName = (((_b = practitioner.basicInfo) == null ? void 0 : _b.lastName) || "").toLowerCase();
6973
+ const fullName = `${firstName} ${lastName}`.trim();
6974
+ const fullNameLower = practitioner.fullNameLower || "";
6975
+ return firstName.includes(searchTerm) || lastName.includes(searchTerm) || fullName.includes(searchTerm) || fullNameLower.includes(searchTerm);
6896
6976
  });
6897
- });
6977
+ console.log(`[PRACTITIONER_SERVICE] Applied name filter, results: ${practitioners.length}`);
6978
+ }
6979
+ const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
6980
+ console.log(`[PRACTITIONER_SERVICE] Strategy 3 success: ${practitioners.length} practitioners`);
6981
+ if (practitioners.length < (filters.pagination || 10)) {
6982
+ return { practitioners, lastDoc: null };
6983
+ }
6984
+ return { practitioners, lastDoc };
6985
+ } catch (error) {
6986
+ console.log("[PRACTITIONER_SERVICE] Strategy 3 failed:", error);
6898
6987
  }
6899
- const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
6900
- return {
6901
- practitioners,
6902
- lastDoc
6903
- };
6988
+ console.log("[PRACTITIONER_SERVICE] All strategies failed, returning empty result");
6989
+ return { practitioners: [], lastDoc: null };
6904
6990
  } catch (error) {
6905
- console.error(
6906
- "[PRACTITIONER_SERVICE] Error filtering practitioners:",
6907
- error
6908
- );
6909
- throw error;
6991
+ console.error("[PRACTITIONER_SERVICE] Error filtering practitioners:", error);
6992
+ return { practitioners: [], lastDoc: null };
6910
6993
  }
6911
6994
  }
6912
6995
  /**
@@ -8535,49 +8618,181 @@ async function findClinicsInRadius(db, center, radiusInKm, filters) {
8535
8618
  var import_firestore26 = require("firebase/firestore");
8536
8619
  var import_geofire_common6 = require("geofire-common");
8537
8620
  async function getClinicsByFilters(db, filters) {
8538
- var _a;
8539
- const constraints = [];
8540
- constraints.push((0, import_firestore26.where)("isActive", "==", (_a = filters.isActive) != null ? _a : true));
8541
- if (filters.tags && filters.tags.length > 0) {
8542
- constraints.push((0, import_firestore26.where)("tags", "array-contains", filters.tags[0]));
8543
- }
8544
- if (filters.procedureTechnology) {
8545
- constraints.push((0, import_firestore26.where)("servicesInfo.technology", "==", filters.procedureTechnology));
8546
- } else if (filters.procedureSubcategory) {
8547
- constraints.push((0, import_firestore26.where)("servicesInfo.subCategory", "==", filters.procedureSubcategory));
8548
- } else if (filters.procedureCategory) {
8549
- constraints.push((0, import_firestore26.where)("servicesInfo.category", "==", filters.procedureCategory));
8550
- } else if (filters.procedureFamily) {
8551
- constraints.push((0, import_firestore26.where)("servicesInfo.procedureFamily", "==", filters.procedureFamily));
8552
- }
8553
- let useNameLower = false;
8554
- let searchTerm = "";
8555
- if (filters.nameSearch && filters.nameSearch.trim()) {
8556
- searchTerm = filters.nameSearch.trim().toLowerCase();
8557
- constraints.push((0, import_firestore26.where)("nameLower", ">=", searchTerm));
8558
- constraints.push((0, import_firestore26.where)("nameLower", "<=", searchTerm + "\uF8FF"));
8559
- useNameLower = true;
8560
- }
8561
- if (filters.minRating !== void 0) {
8562
- constraints.push((0, import_firestore26.where)("reviewInfo.averageRating", ">=", filters.minRating));
8563
- }
8564
- if (filters.maxRating !== void 0) {
8565
- constraints.push((0, import_firestore26.where)("reviewInfo.averageRating", "<=", filters.maxRating));
8566
- }
8567
- constraints.push((0, import_firestore26.orderBy)("nameLower"));
8568
- if (filters.lastDoc) {
8569
- if (typeof filters.lastDoc.data === "function") {
8570
- constraints.push((0, import_firestore26.startAfter)(filters.lastDoc));
8571
- } else if (Array.isArray(filters.lastDoc)) {
8572
- constraints.push((0, import_firestore26.startAfter)(...filters.lastDoc));
8573
- } else {
8574
- constraints.push((0, import_firestore26.startAfter)(filters.lastDoc));
8621
+ try {
8622
+ console.log("[CLINIC_SERVICE] Starting clinic filtering with multiple strategies");
8623
+ if (filters.center && filters.radiusInKm) {
8624
+ console.log("[CLINIC_SERVICE] Executing geo query:", {
8625
+ center: filters.center,
8626
+ radius: filters.radiusInKm,
8627
+ serviceName: "ClinicService"
8628
+ });
8629
+ if (!filters.center.latitude || !filters.center.longitude) {
8630
+ console.warn("[CLINIC_SERVICE] Invalid location data:", filters.center);
8631
+ filters.center = void 0;
8632
+ filters.radiusInKm = void 0;
8633
+ }
8634
+ }
8635
+ const getBaseConstraints = () => {
8636
+ var _a;
8637
+ const constraints = [];
8638
+ constraints.push((0, import_firestore26.where)("isActive", "==", (_a = filters.isActive) != null ? _a : true));
8639
+ if (filters.tags && filters.tags.length > 0) {
8640
+ constraints.push((0, import_firestore26.where)("tags", "array-contains", filters.tags[0]));
8641
+ }
8642
+ if (filters.procedureTechnology) {
8643
+ constraints.push((0, import_firestore26.where)("servicesInfo.technology", "==", filters.procedureTechnology));
8644
+ } else if (filters.procedureSubcategory) {
8645
+ constraints.push((0, import_firestore26.where)("servicesInfo.subCategory", "==", filters.procedureSubcategory));
8646
+ } else if (filters.procedureCategory) {
8647
+ constraints.push((0, import_firestore26.where)("servicesInfo.category", "==", filters.procedureCategory));
8648
+ } else if (filters.procedureFamily) {
8649
+ constraints.push((0, import_firestore26.where)("servicesInfo.procedureFamily", "==", filters.procedureFamily));
8650
+ }
8651
+ if (filters.minRating !== void 0) {
8652
+ constraints.push((0, import_firestore26.where)("reviewInfo.averageRating", ">=", filters.minRating));
8653
+ }
8654
+ if (filters.maxRating !== void 0) {
8655
+ constraints.push((0, import_firestore26.where)("reviewInfo.averageRating", "<=", filters.maxRating));
8656
+ }
8657
+ return constraints;
8658
+ };
8659
+ if (filters.nameSearch && filters.nameSearch.trim()) {
8660
+ try {
8661
+ console.log("[CLINIC_SERVICE] Strategy 1: Trying nameLower search");
8662
+ const searchTerm = filters.nameSearch.trim().toLowerCase();
8663
+ const constraints = getBaseConstraints();
8664
+ constraints.push((0, import_firestore26.where)("nameLower", ">=", searchTerm));
8665
+ constraints.push((0, import_firestore26.where)("nameLower", "<=", searchTerm + "\uF8FF"));
8666
+ constraints.push((0, import_firestore26.orderBy)("nameLower"));
8667
+ if (filters.lastDoc) {
8668
+ if (typeof filters.lastDoc.data === "function") {
8669
+ constraints.push((0, import_firestore26.startAfter)(filters.lastDoc));
8670
+ } else if (Array.isArray(filters.lastDoc)) {
8671
+ constraints.push((0, import_firestore26.startAfter)(...filters.lastDoc));
8672
+ } else {
8673
+ constraints.push((0, import_firestore26.startAfter)(filters.lastDoc));
8674
+ }
8675
+ }
8676
+ constraints.push((0, import_firestore26.limit)(filters.pagination || 5));
8677
+ const q = (0, import_firestore26.query)((0, import_firestore26.collection)(db, CLINICS_COLLECTION), ...constraints);
8678
+ const querySnapshot = await (0, import_firestore26.getDocs)(q);
8679
+ let clinics = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
8680
+ clinics = applyInMemoryFilters(clinics, filters);
8681
+ const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
8682
+ console.log(`[CLINIC_SERVICE] Strategy 1 success: ${clinics.length} clinics`);
8683
+ if (clinics.length < (filters.pagination || 5)) {
8684
+ return { clinics, lastDoc: null };
8685
+ }
8686
+ return { clinics, lastDoc };
8687
+ } catch (error) {
8688
+ console.log("[CLINIC_SERVICE] Strategy 1 failed:", error);
8689
+ }
8690
+ }
8691
+ if (filters.nameSearch && filters.nameSearch.trim()) {
8692
+ try {
8693
+ console.log("[CLINIC_SERVICE] Strategy 2: Trying name field search");
8694
+ const searchTerm = filters.nameSearch.trim().toLowerCase();
8695
+ const constraints = getBaseConstraints();
8696
+ constraints.push((0, import_firestore26.where)("name", ">=", searchTerm));
8697
+ constraints.push((0, import_firestore26.where)("name", "<=", searchTerm + "\uF8FF"));
8698
+ constraints.push((0, import_firestore26.orderBy)("name"));
8699
+ if (filters.lastDoc) {
8700
+ if (typeof filters.lastDoc.data === "function") {
8701
+ constraints.push((0, import_firestore26.startAfter)(filters.lastDoc));
8702
+ } else if (Array.isArray(filters.lastDoc)) {
8703
+ constraints.push((0, import_firestore26.startAfter)(...filters.lastDoc));
8704
+ } else {
8705
+ constraints.push((0, import_firestore26.startAfter)(filters.lastDoc));
8706
+ }
8707
+ }
8708
+ constraints.push((0, import_firestore26.limit)(filters.pagination || 5));
8709
+ const q = (0, import_firestore26.query)((0, import_firestore26.collection)(db, CLINICS_COLLECTION), ...constraints);
8710
+ const querySnapshot = await (0, import_firestore26.getDocs)(q);
8711
+ let clinics = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
8712
+ clinics = applyInMemoryFilters(clinics, filters);
8713
+ const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
8714
+ console.log(`[CLINIC_SERVICE] Strategy 2 success: ${clinics.length} clinics`);
8715
+ if (clinics.length < (filters.pagination || 5)) {
8716
+ return { clinics, lastDoc: null };
8717
+ }
8718
+ return { clinics, lastDoc };
8719
+ } catch (error) {
8720
+ console.log("[CLINIC_SERVICE] Strategy 2 failed:", error);
8721
+ }
8722
+ }
8723
+ try {
8724
+ console.log("[CLINIC_SERVICE] Strategy 3: Using createdAt ordering with client-side filtering");
8725
+ const constraints = getBaseConstraints();
8726
+ constraints.push((0, import_firestore26.orderBy)("createdAt", "desc"));
8727
+ if (filters.lastDoc) {
8728
+ if (typeof filters.lastDoc.data === "function") {
8729
+ constraints.push((0, import_firestore26.startAfter)(filters.lastDoc));
8730
+ } else if (Array.isArray(filters.lastDoc)) {
8731
+ constraints.push((0, import_firestore26.startAfter)(...filters.lastDoc));
8732
+ } else {
8733
+ constraints.push((0, import_firestore26.startAfter)(filters.lastDoc));
8734
+ }
8735
+ }
8736
+ constraints.push((0, import_firestore26.limit)(filters.pagination || 5));
8737
+ const q = (0, import_firestore26.query)((0, import_firestore26.collection)(db, CLINICS_COLLECTION), ...constraints);
8738
+ const querySnapshot = await (0, import_firestore26.getDocs)(q);
8739
+ let clinics = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
8740
+ if (filters.nameSearch && filters.nameSearch.trim()) {
8741
+ const searchTerm = filters.nameSearch.trim().toLowerCase();
8742
+ clinics = clinics.filter((clinic) => {
8743
+ const name = (clinic.name || "").toLowerCase();
8744
+ const nameLower = clinic.nameLower || "";
8745
+ return name.includes(searchTerm) || nameLower.includes(searchTerm);
8746
+ });
8747
+ console.log(`[CLINIC_SERVICE] Applied name filter, results: ${clinics.length}`);
8748
+ }
8749
+ clinics = applyInMemoryFilters(clinics, filters);
8750
+ const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
8751
+ console.log(`[CLINIC_SERVICE] Strategy 3 success: ${clinics.length} clinics`);
8752
+ if (clinics.length < (filters.pagination || 5)) {
8753
+ return { clinics, lastDoc: null };
8754
+ }
8755
+ return { clinics, lastDoc };
8756
+ } catch (error) {
8757
+ console.log("[CLINIC_SERVICE] Strategy 3 failed:", error);
8758
+ }
8759
+ try {
8760
+ console.log("[CLINIC_SERVICE] Strategy 4: Minimal fallback");
8761
+ const constraints = [
8762
+ (0, import_firestore26.where)("isActive", "==", true),
8763
+ (0, import_firestore26.orderBy)("createdAt", "desc"),
8764
+ (0, import_firestore26.limit)(filters.pagination || 5)
8765
+ ];
8766
+ const q = (0, import_firestore26.query)((0, import_firestore26.collection)(db, CLINICS_COLLECTION), ...constraints);
8767
+ const querySnapshot = await (0, import_firestore26.getDocs)(q);
8768
+ let clinics = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
8769
+ if (filters.nameSearch && filters.nameSearch.trim()) {
8770
+ const searchTerm = filters.nameSearch.trim().toLowerCase();
8771
+ clinics = clinics.filter((clinic) => {
8772
+ const name = (clinic.name || "").toLowerCase();
8773
+ const nameLower = clinic.nameLower || "";
8774
+ return name.includes(searchTerm) || nameLower.includes(searchTerm);
8775
+ });
8776
+ console.log(`[CLINIC_SERVICE] Applied name filter, results: ${clinics.length}`);
8777
+ }
8778
+ clinics = applyInMemoryFilters(clinics, filters);
8779
+ const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
8780
+ console.log(`[CLINIC_SERVICE] Strategy 4 success: ${clinics.length} clinics`);
8781
+ if (clinics.length < (filters.pagination || 5)) {
8782
+ return { clinics, lastDoc: null };
8783
+ }
8784
+ return { clinics, lastDoc };
8785
+ } catch (error) {
8786
+ console.log("[CLINIC_SERVICE] Strategy 4 failed:", error);
8575
8787
  }
8788
+ console.log("[CLINIC_SERVICE] All strategies failed, returning empty result");
8789
+ return { clinics: [], lastDoc: null };
8790
+ } catch (error) {
8791
+ console.error("[CLINIC_SERVICE] Error filtering clinics:", error);
8792
+ return { clinics: [], lastDoc: null };
8576
8793
  }
8577
- constraints.push((0, import_firestore26.limit)(filters.pagination || 5));
8578
- const q = (0, import_firestore26.query)((0, import_firestore26.collection)(db, CLINICS_COLLECTION), ...constraints);
8579
- const querySnapshot = await (0, import_firestore26.getDocs)(q);
8580
- let clinics = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
8794
+ }
8795
+ function applyInMemoryFilters(clinics, filters) {
8581
8796
  if (filters.tags && filters.tags.length > 1) {
8582
8797
  clinics = clinics.filter((clinic) => filters.tags.every((tag) => clinic.tags.includes(tag)));
8583
8798
  }
@@ -8590,9 +8805,9 @@ async function getClinicsByFilters(db, filters) {
8590
8805
  clinic.distance = distance;
8591
8806
  return distance <= filters.radiusInKm;
8592
8807
  });
8808
+ clinics.sort((a, b) => (a.distance || 0) - (b.distance || 0));
8593
8809
  }
8594
- const lastVisibleDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
8595
- return { clinics, lastDoc: lastVisibleDoc };
8810
+ return clinics;
8596
8811
  }
8597
8812
 
8598
8813
  // src/services/clinic/clinic.service.ts
@@ -14909,126 +15124,233 @@ var ProcedureService = class extends BaseService {
14909
15124
  */
14910
15125
  async getProceduresByFilters(filters) {
14911
15126
  try {
14912
- const isGeoQuery = filters.location && filters.radiusInKm && filters.radiusInKm > 0;
14913
- const constraints = [];
14914
- if (filters.isActive !== void 0) {
14915
- constraints.push((0, import_firestore45.where)("isActive", "==", filters.isActive));
14916
- } else {
14917
- constraints.push((0, import_firestore45.where)("isActive", "==", true));
14918
- }
14919
- if (filters.procedureFamily) {
14920
- constraints.push((0, import_firestore45.where)("family", "==", filters.procedureFamily));
14921
- }
14922
- if (filters.procedureCategory) {
14923
- constraints.push((0, import_firestore45.where)("category.id", "==", filters.procedureCategory));
14924
- }
14925
- if (filters.procedureSubcategory) {
14926
- constraints.push((0, import_firestore45.where)("subcategory.id", "==", filters.procedureSubcategory));
14927
- }
14928
- if (filters.procedureTechnology) {
14929
- constraints.push((0, import_firestore45.where)("technology.id", "==", filters.procedureTechnology));
14930
- }
14931
- if (filters.minPrice !== void 0) {
14932
- constraints.push((0, import_firestore45.where)("price", ">=", filters.minPrice));
14933
- }
14934
- if (filters.maxPrice !== void 0) {
14935
- constraints.push((0, import_firestore45.where)("price", "<=", filters.maxPrice));
14936
- }
14937
- if (filters.minRating !== void 0) {
14938
- constraints.push((0, import_firestore45.where)("reviewInfo.averageRating", ">=", filters.minRating));
15127
+ console.log("[PROCEDURE_SERVICE] Starting procedure filtering with multiple strategies");
15128
+ if (filters.location && filters.radiusInKm) {
15129
+ console.log("[PROCEDURE_SERVICE] Executing geo query:", {
15130
+ location: filters.location,
15131
+ radius: filters.radiusInKm,
15132
+ serviceName: "ProcedureService"
15133
+ });
15134
+ if (!filters.location.latitude || !filters.location.longitude) {
15135
+ console.warn("[PROCEDURE_SERVICE] Invalid location data:", filters.location);
15136
+ filters.location = void 0;
15137
+ filters.radiusInKm = void 0;
15138
+ }
14939
15139
  }
14940
- if (filters.maxRating !== void 0) {
14941
- constraints.push((0, import_firestore45.where)("reviewInfo.averageRating", "<=", filters.maxRating));
14942
- }
14943
- if (filters.treatmentBenefits && filters.treatmentBenefits.length > 0) {
14944
- constraints.push((0, import_firestore45.where)("treatmentBenefits", "array-contains-any", filters.treatmentBenefits));
14945
- }
14946
- let useNameLower = false;
14947
- let searchTerm = "";
14948
- if (filters.nameSearch && filters.nameSearch.trim() !== "") {
14949
- searchTerm = filters.nameSearch.trim().toLowerCase();
14950
- useNameLower = true;
14951
- constraints.push((0, import_firestore45.where)("nameLower", ">=", searchTerm));
14952
- constraints.push((0, import_firestore45.where)("nameLower", "<=", searchTerm + "\uF8FF"));
14953
- constraints.push((0, import_firestore45.orderBy)("nameLower"));
14954
- } else {
14955
- constraints.push((0, import_firestore45.orderBy)("nameLower"));
15140
+ const isGeoQuery = filters.location && filters.radiusInKm && filters.radiusInKm > 0;
15141
+ if (isGeoQuery) {
15142
+ return this.handleGeoQuery(filters);
14956
15143
  }
14957
- if (filters.lastDoc) {
14958
- if (typeof filters.lastDoc.data === "function") {
14959
- constraints.push((0, import_firestore45.startAfter)(filters.lastDoc));
14960
- } else if (Array.isArray(filters.lastDoc)) {
14961
- constraints.push((0, import_firestore45.startAfter)(...filters.lastDoc));
15144
+ const getBaseConstraints = () => {
15145
+ const constraints = [];
15146
+ if (filters.isActive !== void 0) {
15147
+ constraints.push((0, import_firestore45.where)("isActive", "==", filters.isActive));
14962
15148
  } else {
14963
- constraints.push((0, import_firestore45.startAfter)(filters.lastDoc));
15149
+ constraints.push((0, import_firestore45.where)("isActive", "==", true));
14964
15150
  }
14965
- }
14966
- if (filters.pagination && filters.pagination > 0) {
14967
- constraints.push((0, import_firestore45.limit)(filters.pagination));
14968
- }
14969
- if (isGeoQuery) {
14970
- const center = filters.location;
14971
- const radiusInKm = filters.radiusInKm;
14972
- const bounds = (0, import_geofire_common8.geohashQueryBounds)(
14973
- [center.latitude, center.longitude],
14974
- radiusInKm * 1e3
14975
- // Convert to meters
14976
- );
14977
- let allDocs = [];
14978
- for (const bound of bounds) {
14979
- const geoConstraints = [
14980
- ...constraints.filter((c) => !c.fieldPath || c.fieldPath !== "name"),
14981
- // Remove name orderBy for geo
14982
- (0, import_firestore45.where)("clinicInfo.location.geohash", ">=", bound[0]),
14983
- (0, import_firestore45.where)("clinicInfo.location.geohash", "<=", bound[1]),
14984
- (0, import_firestore45.orderBy)("clinicInfo.location.geohash")
14985
- ];
14986
- const q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...geoConstraints);
14987
- const querySnapshot = await (0, import_firestore45.getDocs)(q);
14988
- for (const doc37 of querySnapshot.docs) {
14989
- const procedure = { ...doc37.data(), id: doc37.id };
14990
- const distance = (0, import_geofire_common8.distanceBetween)(
14991
- [center.latitude, center.longitude],
14992
- [procedure.clinicInfo.location.latitude, procedure.clinicInfo.location.longitude]
14993
- );
14994
- const distanceInKm = distance / 1e3;
14995
- if (distanceInKm <= radiusInKm) {
14996
- allDocs.push({ ...procedure, distance: distanceInKm });
14997
- }
14998
- }
15151
+ if (filters.procedureFamily) {
15152
+ constraints.push((0, import_firestore45.where)("family", "==", filters.procedureFamily));
14999
15153
  }
15000
- allDocs.sort((a, b) => a.distance - b.distance);
15001
- let paginated = allDocs;
15002
- if (filters.pagination && filters.pagination > 0) {
15003
- let startIndex = 0;
15154
+ if (filters.procedureCategory) {
15155
+ constraints.push((0, import_firestore45.where)("category.id", "==", filters.procedureCategory));
15156
+ }
15157
+ if (filters.procedureSubcategory) {
15158
+ constraints.push((0, import_firestore45.where)("subcategory.id", "==", filters.procedureSubcategory));
15159
+ }
15160
+ if (filters.procedureTechnology) {
15161
+ constraints.push((0, import_firestore45.where)("technology.id", "==", filters.procedureTechnology));
15162
+ }
15163
+ if (filters.minPrice !== void 0) {
15164
+ constraints.push((0, import_firestore45.where)("price", ">=", filters.minPrice));
15165
+ }
15166
+ if (filters.maxPrice !== void 0) {
15167
+ constraints.push((0, import_firestore45.where)("price", "<=", filters.maxPrice));
15168
+ }
15169
+ if (filters.minRating !== void 0) {
15170
+ constraints.push((0, import_firestore45.where)("reviewInfo.averageRating", ">=", filters.minRating));
15171
+ }
15172
+ if (filters.maxRating !== void 0) {
15173
+ constraints.push((0, import_firestore45.where)("reviewInfo.averageRating", "<=", filters.maxRating));
15174
+ }
15175
+ if (filters.treatmentBenefits && filters.treatmentBenefits.length > 0) {
15176
+ constraints.push((0, import_firestore45.where)("treatmentBenefits", "array-contains-any", filters.treatmentBenefits));
15177
+ }
15178
+ return constraints;
15179
+ };
15180
+ if (filters.nameSearch && filters.nameSearch.trim()) {
15181
+ try {
15182
+ console.log("[PROCEDURE_SERVICE] Strategy 1: Trying nameLower search");
15183
+ const searchTerm = filters.nameSearch.trim().toLowerCase();
15184
+ const constraints = getBaseConstraints();
15185
+ constraints.push((0, import_firestore45.where)("nameLower", ">=", searchTerm));
15186
+ constraints.push((0, import_firestore45.where)("nameLower", "<=", searchTerm + "\uF8FF"));
15187
+ constraints.push((0, import_firestore45.orderBy)("nameLower"));
15004
15188
  if (filters.lastDoc) {
15005
- const lastDocIndex = allDocs.findIndex((p) => p.id === filters.lastDoc.id);
15006
- if (lastDocIndex !== -1) startIndex = lastDocIndex + 1;
15189
+ if (typeof filters.lastDoc.data === "function") {
15190
+ constraints.push((0, import_firestore45.startAfter)(filters.lastDoc));
15191
+ } else if (Array.isArray(filters.lastDoc)) {
15192
+ constraints.push((0, import_firestore45.startAfter)(...filters.lastDoc));
15193
+ } else {
15194
+ constraints.push((0, import_firestore45.startAfter)(filters.lastDoc));
15195
+ }
15196
+ }
15197
+ constraints.push((0, import_firestore45.limit)(filters.pagination || 10));
15198
+ const q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
15199
+ const querySnapshot = await (0, import_firestore45.getDocs)(q);
15200
+ const procedures = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
15201
+ const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
15202
+ console.log(`[PROCEDURE_SERVICE] Strategy 1 success: ${procedures.length} procedures`);
15203
+ if (procedures.length < (filters.pagination || 10)) {
15204
+ return { procedures, lastDoc: null };
15007
15205
  }
15008
- paginated = allDocs.slice(startIndex, startIndex + filters.pagination);
15206
+ return { procedures, lastDoc };
15207
+ } catch (error) {
15208
+ console.log("[PROCEDURE_SERVICE] Strategy 1 failed:", error);
15009
15209
  }
15010
- const lastVisibleDoc = paginated.length > 0 ? paginated[paginated.length - 1] : null;
15011
- return { procedures: paginated, lastDoc: lastVisibleDoc };
15012
- } else {
15013
- let q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
15014
- let querySnapshot = await (0, import_firestore45.getDocs)(q);
15015
- if (useNameLower && querySnapshot.empty && searchTerm) {
15016
- constraints.pop();
15017
- constraints.pop();
15018
- constraints.pop();
15210
+ }
15211
+ if (filters.nameSearch && filters.nameSearch.trim()) {
15212
+ try {
15213
+ console.log("[PROCEDURE_SERVICE] Strategy 2: Trying name field search");
15214
+ const searchTerm = filters.nameSearch.trim().toLowerCase();
15215
+ const constraints = getBaseConstraints();
15019
15216
  constraints.push((0, import_firestore45.where)("name", ">=", searchTerm));
15020
15217
  constraints.push((0, import_firestore45.where)("name", "<=", searchTerm + "\uF8FF"));
15021
15218
  constraints.push((0, import_firestore45.orderBy)("name"));
15022
- q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
15023
- querySnapshot = await (0, import_firestore45.getDocs)(q);
15219
+ if (filters.lastDoc) {
15220
+ if (typeof filters.lastDoc.data === "function") {
15221
+ constraints.push((0, import_firestore45.startAfter)(filters.lastDoc));
15222
+ } else if (Array.isArray(filters.lastDoc)) {
15223
+ constraints.push((0, import_firestore45.startAfter)(...filters.lastDoc));
15224
+ } else {
15225
+ constraints.push((0, import_firestore45.startAfter)(filters.lastDoc));
15226
+ }
15227
+ }
15228
+ constraints.push((0, import_firestore45.limit)(filters.pagination || 10));
15229
+ const q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
15230
+ const querySnapshot = await (0, import_firestore45.getDocs)(q);
15231
+ const procedures = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
15232
+ const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
15233
+ console.log(`[PROCEDURE_SERVICE] Strategy 2 success: ${procedures.length} procedures`);
15234
+ if (procedures.length < (filters.pagination || 10)) {
15235
+ return { procedures, lastDoc: null };
15236
+ }
15237
+ return { procedures, lastDoc };
15238
+ } catch (error) {
15239
+ console.log("[PROCEDURE_SERVICE] Strategy 2 failed:", error);
15240
+ }
15241
+ }
15242
+ try {
15243
+ console.log("[PROCEDURE_SERVICE] Strategy 3: Using createdAt orderBy with client-side filtering");
15244
+ const constraints = getBaseConstraints();
15245
+ constraints.push((0, import_firestore45.orderBy)("createdAt", "desc"));
15246
+ if (filters.lastDoc) {
15247
+ if (typeof filters.lastDoc.data === "function") {
15248
+ constraints.push((0, import_firestore45.startAfter)(filters.lastDoc));
15249
+ } else if (Array.isArray(filters.lastDoc)) {
15250
+ constraints.push((0, import_firestore45.startAfter)(...filters.lastDoc));
15251
+ } else {
15252
+ constraints.push((0, import_firestore45.startAfter)(filters.lastDoc));
15253
+ }
15254
+ }
15255
+ constraints.push((0, import_firestore45.limit)(filters.pagination || 10));
15256
+ const q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
15257
+ const querySnapshot = await (0, import_firestore45.getDocs)(q);
15258
+ let procedures = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
15259
+ if (filters.nameSearch && filters.nameSearch.trim()) {
15260
+ const searchTerm = filters.nameSearch.trim().toLowerCase();
15261
+ procedures = procedures.filter((procedure) => {
15262
+ const name = (procedure.name || "").toLowerCase();
15263
+ const nameLower = procedure.nameLower || "";
15264
+ return name.includes(searchTerm) || nameLower.includes(searchTerm);
15265
+ });
15266
+ console.log(`[PROCEDURE_SERVICE] Applied name filter, results: ${procedures.length}`);
15267
+ }
15268
+ const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
15269
+ console.log(`[PROCEDURE_SERVICE] Strategy 3 success: ${procedures.length} procedures`);
15270
+ if (procedures.length < (filters.pagination || 10)) {
15271
+ return { procedures, lastDoc: null };
15272
+ }
15273
+ return { procedures, lastDoc };
15274
+ } catch (error) {
15275
+ console.log("[PROCEDURE_SERVICE] Strategy 3 failed:", error);
15276
+ }
15277
+ try {
15278
+ console.log("[PROCEDURE_SERVICE] Strategy 4: Minimal query fallback");
15279
+ const constraints = [
15280
+ (0, import_firestore45.where)("isActive", "==", true),
15281
+ (0, import_firestore45.orderBy)("createdAt", "desc"),
15282
+ (0, import_firestore45.limit)(filters.pagination || 10)
15283
+ ];
15284
+ const q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
15285
+ const querySnapshot = await (0, import_firestore45.getDocs)(q);
15286
+ let procedures = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
15287
+ if (filters.nameSearch && filters.nameSearch.trim()) {
15288
+ const searchTerm = filters.nameSearch.trim().toLowerCase();
15289
+ procedures = procedures.filter((procedure) => {
15290
+ const name = (procedure.name || "").toLowerCase();
15291
+ const nameLower = procedure.nameLower || "";
15292
+ return name.includes(searchTerm) || nameLower.includes(searchTerm);
15293
+ });
15294
+ console.log(`[PROCEDURE_SERVICE] Applied name filter, results: ${procedures.length}`);
15024
15295
  }
15025
- const procedures = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
15026
- const lastVisibleDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
15027
- return { procedures, lastDoc: lastVisibleDoc };
15296
+ const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
15297
+ console.log(`[PROCEDURE_SERVICE] Strategy 4 success: ${procedures.length} procedures`);
15298
+ if (procedures.length < (filters.pagination || 10)) {
15299
+ return { procedures, lastDoc: null };
15300
+ }
15301
+ return { procedures, lastDoc };
15302
+ } catch (error) {
15303
+ console.log("[PROCEDURE_SERVICE] Strategy 4 failed:", error);
15028
15304
  }
15305
+ console.log("[PROCEDURE_SERVICE] All strategies failed, returning empty result");
15306
+ return { procedures: [], lastDoc: null };
15029
15307
  } catch (error) {
15030
15308
  console.error("[PROCEDURE_SERVICE] Error filtering procedures:", error);
15031
- throw error;
15309
+ return { procedures: [], lastDoc: null };
15310
+ }
15311
+ }
15312
+ handleGeoQuery(filters) {
15313
+ console.log("[PROCEDURE_SERVICE] Executing geo query with enhanced debugging");
15314
+ try {
15315
+ const location = filters.location;
15316
+ const radiusInKm = filters.radiusInKm;
15317
+ console.log("[PROCEDURE_SERVICE] Geo query parameters:", {
15318
+ latitude: location.latitude,
15319
+ longitude: location.longitude,
15320
+ radiusInKm,
15321
+ pagination: filters.pagination || 10
15322
+ });
15323
+ const constraints = [
15324
+ (0, import_firestore45.where)("isActive", "==", true),
15325
+ (0, import_firestore45.orderBy)("createdAt", "desc"),
15326
+ (0, import_firestore45.limit)((filters.pagination || 10) * 3)
15327
+ // Get more results for geo filtering
15328
+ ];
15329
+ const q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
15330
+ return (0, import_firestore45.getDocs)(q).then((querySnapshot) => {
15331
+ let procedures = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
15332
+ procedures = procedures.filter((procedure) => {
15333
+ var _a;
15334
+ const clinicLocation = (_a = procedure.clinicInfo) == null ? void 0 : _a.location;
15335
+ if (!(clinicLocation == null ? void 0 : clinicLocation.latitude) || !(clinicLocation == null ? void 0 : clinicLocation.longitude)) {
15336
+ return false;
15337
+ }
15338
+ const distance = (0, import_geofire_common8.distanceBetween)(
15339
+ [location.latitude, location.longitude],
15340
+ [clinicLocation.latitude, clinicLocation.longitude]
15341
+ ) / 1e3;
15342
+ procedure.distance = distance;
15343
+ return distance <= radiusInKm;
15344
+ });
15345
+ procedures.sort((a, b) => (a.distance || 0) - (b.distance || 0));
15346
+ procedures = procedures.slice(0, filters.pagination || 10);
15347
+ console.log(`[PROCEDURE_SERVICE] Geo query success: ${procedures.length} procedures within ${radiusInKm}km`);
15348
+ const lastDoc = procedures.length < (filters.pagination || 10) ? null : querySnapshot.docs[querySnapshot.docs.length - 1];
15349
+ return { procedures, lastDoc };
15350
+ });
15351
+ } catch (error) {
15352
+ console.error("[PROCEDURE_SERVICE] Geo query failed:", error);
15353
+ return Promise.resolve({ procedures: [], lastDoc: null });
15032
15354
  }
15033
15355
  }
15034
15356
  /**