@blackcode_sa/metaestetics-api 1.8.15 → 1.8.17

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.d.mts CHANGED
@@ -4266,6 +4266,11 @@ declare class ProcedureService extends BaseService {
4266
4266
  })[];
4267
4267
  lastDoc: any;
4268
4268
  }>;
4269
+ /**
4270
+ * Applies in-memory filters to procedures array
4271
+ * Used when Firestore queries fail or for complex filtering
4272
+ */
4273
+ private applyInMemoryFilters;
4269
4274
  private handleGeoQuery;
4270
4275
  /**
4271
4276
  * Creates a consultation procedure without requiring a product
@@ -4465,6 +4470,11 @@ declare class PractitionerService extends BaseService {
4465
4470
  practitioners: Practitioner[];
4466
4471
  lastDoc: any;
4467
4472
  }>;
4473
+ /**
4474
+ * Applies in-memory filters to practitioners array
4475
+ * Used when Firestore queries fail or for complex filtering
4476
+ */
4477
+ private applyInMemoryFilters;
4468
4478
  /**
4469
4479
  * Enables free consultation for a practitioner in a specific clinic
4470
4480
  * Creates a free consultation procedure with hardcoded parameters
package/dist/index.d.ts CHANGED
@@ -4266,6 +4266,11 @@ declare class ProcedureService extends BaseService {
4266
4266
  })[];
4267
4267
  lastDoc: any;
4268
4268
  }>;
4269
+ /**
4270
+ * Applies in-memory filters to procedures array
4271
+ * Used when Firestore queries fail or for complex filtering
4272
+ */
4273
+ private applyInMemoryFilters;
4269
4274
  private handleGeoQuery;
4270
4275
  /**
4271
4276
  * Creates a consultation procedure without requiring a product
@@ -4465,6 +4470,11 @@ declare class PractitionerService extends BaseService {
4465
4470
  practitioners: Practitioner[];
4466
4471
  lastDoc: any;
4467
4472
  }>;
4473
+ /**
4474
+ * Applies in-memory filters to practitioners array
4475
+ * Used when Firestore queries fail or for complex filtering
4476
+ */
4477
+ private applyInMemoryFilters;
4468
4478
  /**
4469
4479
  * Enables free consultation for a practitioner in a specific clinic
4470
4480
  * Creates a free consultation procedure with hardcoded parameters
package/dist/index.js CHANGED
@@ -6889,8 +6889,9 @@ var PractitionerService = class extends BaseService {
6889
6889
  }
6890
6890
  constraints.push((0, import_firestore21.where)("isActive", "==", true));
6891
6891
  if (filters.certifications && filters.certifications.length > 0) {
6892
+ const certificationsToMatch = filters.certifications;
6892
6893
  constraints.push(
6893
- (0, import_firestore21.where)("certification.specialties", "array-contains-any", filters.certifications)
6894
+ (0, import_firestore21.where)("certification.specialties", "array-contains-any", certificationsToMatch)
6894
6895
  );
6895
6896
  }
6896
6897
  if (filters.minRating !== void 0) {
@@ -6933,18 +6934,7 @@ var PractitionerService = class extends BaseService {
6933
6934
  });
6934
6935
  practitioners = practitioners.slice(0, filters.pagination || 10);
6935
6936
  }
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
- }
6937
+ practitioners = this.applyInMemoryFilters(practitioners, filters);
6948
6938
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
6949
6939
  console.log(`[PRACTITIONER_SERVICE] Strategy 2 success: ${practitioners.length} practitioners`);
6950
6940
  if (practitioners.length < (filters.pagination || 10)) {
@@ -6964,18 +6954,7 @@ var PractitionerService = class extends BaseService {
6964
6954
  const q = (0, import_firestore21.query)((0, import_firestore21.collection)(this.db, PRACTITIONERS_COLLECTION), ...constraints);
6965
6955
  const querySnapshot = await (0, import_firestore21.getDocs)(q);
6966
6956
  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);
6976
- });
6977
- console.log(`[PRACTITIONER_SERVICE] Applied name filter, results: ${practitioners.length}`);
6978
- }
6957
+ practitioners = this.applyInMemoryFilters(practitioners, filters);
6979
6958
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
6980
6959
  console.log(`[PRACTITIONER_SERVICE] Strategy 3 success: ${practitioners.length} practitioners`);
6981
6960
  if (practitioners.length < (filters.pagination || 10)) {
@@ -6992,6 +6971,98 @@ var PractitionerService = class extends BaseService {
6992
6971
  return { practitioners: [], lastDoc: null };
6993
6972
  }
6994
6973
  }
6974
+ /**
6975
+ * Applies in-memory filters to practitioners array
6976
+ * Used when Firestore queries fail or for complex filtering
6977
+ */
6978
+ applyInMemoryFilters(practitioners, filters) {
6979
+ let filteredPractitioners = [...practitioners];
6980
+ if (filters.nameSearch && filters.nameSearch.trim()) {
6981
+ const searchTerm = filters.nameSearch.trim().toLowerCase();
6982
+ filteredPractitioners = filteredPractitioners.filter((practitioner) => {
6983
+ var _a, _b;
6984
+ const firstName = (((_a = practitioner.basicInfo) == null ? void 0 : _a.firstName) || "").toLowerCase();
6985
+ const lastName = (((_b = practitioner.basicInfo) == null ? void 0 : _b.lastName) || "").toLowerCase();
6986
+ const fullName = `${firstName} ${lastName}`.trim();
6987
+ const fullNameLower = practitioner.fullNameLower || "";
6988
+ return firstName.includes(searchTerm) || lastName.includes(searchTerm) || fullName.includes(searchTerm) || fullNameLower.includes(searchTerm);
6989
+ });
6990
+ console.log(`[PRACTITIONER_SERVICE] Applied name filter, results: ${filteredPractitioners.length}`);
6991
+ }
6992
+ if (filters.certifications && filters.certifications.length > 0) {
6993
+ const certificationsToMatch = filters.certifications;
6994
+ filteredPractitioners = filteredPractitioners.filter((practitioner) => {
6995
+ var _a;
6996
+ const practitionerCerts = ((_a = practitioner.certification) == null ? void 0 : _a.specialties) || [];
6997
+ return certificationsToMatch.some((cert) => practitionerCerts.includes(cert));
6998
+ });
6999
+ console.log(`[PRACTITIONER_SERVICE] Applied certifications filter, results: ${filteredPractitioners.length}`);
7000
+ }
7001
+ if (filters.specialties && filters.specialties.length > 0) {
7002
+ const specialtiesToMatch = filters.specialties;
7003
+ filteredPractitioners = filteredPractitioners.filter((practitioner) => {
7004
+ var _a;
7005
+ const practitionerSpecs = ((_a = practitioner.certification) == null ? void 0 : _a.specialties) || [];
7006
+ return specialtiesToMatch.some((spec) => practitionerSpecs.includes(spec));
7007
+ });
7008
+ console.log(`[PRACTITIONER_SERVICE] Applied specialties filter, results: ${filteredPractitioners.length}`);
7009
+ }
7010
+ if (filters.minRating !== void 0 || filters.maxRating !== void 0) {
7011
+ filteredPractitioners = filteredPractitioners.filter((practitioner) => {
7012
+ var _a;
7013
+ const rating = ((_a = practitioner.reviewInfo) == null ? void 0 : _a.averageRating) || 0;
7014
+ if (filters.minRating !== void 0 && rating < filters.minRating) return false;
7015
+ if (filters.maxRating !== void 0 && rating > filters.maxRating) return false;
7016
+ return true;
7017
+ });
7018
+ console.log(`[PRACTITIONER_SERVICE] Applied rating filter, results: ${filteredPractitioners.length}`);
7019
+ }
7020
+ if (filters.procedureFamily) {
7021
+ filteredPractitioners = filteredPractitioners.filter((practitioner) => {
7022
+ const proceduresInfo = practitioner.proceduresInfo || [];
7023
+ return proceduresInfo.some((proc) => proc.family === filters.procedureFamily);
7024
+ });
7025
+ console.log(`[PRACTITIONER_SERVICE] Applied procedure family filter, results: ${filteredPractitioners.length}`);
7026
+ }
7027
+ if (filters.procedureCategory) {
7028
+ filteredPractitioners = filteredPractitioners.filter((practitioner) => {
7029
+ const proceduresInfo = practitioner.proceduresInfo || [];
7030
+ return proceduresInfo.some((proc) => proc.categoryName === filters.procedureCategory);
7031
+ });
7032
+ console.log(`[PRACTITIONER_SERVICE] Applied procedure category filter, results: ${filteredPractitioners.length}`);
7033
+ }
7034
+ if (filters.procedureSubcategory) {
7035
+ filteredPractitioners = filteredPractitioners.filter((practitioner) => {
7036
+ const proceduresInfo = practitioner.proceduresInfo || [];
7037
+ return proceduresInfo.some((proc) => proc.subcategoryName === filters.procedureSubcategory);
7038
+ });
7039
+ console.log(`[PRACTITIONER_SERVICE] Applied procedure subcategory filter, results: ${filteredPractitioners.length}`);
7040
+ }
7041
+ if (filters.procedureTechnology) {
7042
+ filteredPractitioners = filteredPractitioners.filter((practitioner) => {
7043
+ const proceduresInfo = practitioner.proceduresInfo || [];
7044
+ return proceduresInfo.some((proc) => proc.technologyName === filters.procedureTechnology);
7045
+ });
7046
+ console.log(`[PRACTITIONER_SERVICE] Applied procedure technology filter, results: ${filteredPractitioners.length}`);
7047
+ }
7048
+ if (filters.location && filters.radiusInKm && filters.radiusInKm > 0) {
7049
+ const location = filters.location;
7050
+ const radiusInKm = filters.radiusInKm;
7051
+ filteredPractitioners = filteredPractitioners.filter((practitioner) => {
7052
+ const clinics = practitioner.clinicsInfo || [];
7053
+ return clinics.some((clinic) => {
7054
+ const distance = (0, import_geofire_common2.distanceBetween)(
7055
+ [location.latitude, location.longitude],
7056
+ [clinic.location.latitude, clinic.location.longitude]
7057
+ );
7058
+ const distanceInKm = distance / 1e3;
7059
+ return distanceInKm <= radiusInKm;
7060
+ });
7061
+ });
7062
+ console.log(`[PRACTITIONER_SERVICE] Applied geo filter, results: ${filteredPractitioners.length}`);
7063
+ }
7064
+ return filteredPractitioners;
7065
+ }
6995
7066
  /**
6996
7067
  * Enables free consultation for a practitioner in a specific clinic
6997
7068
  * Creates a free consultation procedure with hardcoded parameters
@@ -8639,15 +8710,6 @@ async function getClinicsByFilters(db, filters) {
8639
8710
  if (filters.tags && filters.tags.length > 0) {
8640
8711
  constraints.push((0, import_firestore26.where)("tags", "array-contains", filters.tags[0]));
8641
8712
  }
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
8713
  if (filters.minRating !== void 0) {
8652
8714
  constraints.push((0, import_firestore26.where)("reviewInfo.averageRating", ">=", filters.minRating));
8653
8715
  }
@@ -8737,15 +8799,6 @@ async function getClinicsByFilters(db, filters) {
8737
8799
  const q = (0, import_firestore26.query)((0, import_firestore26.collection)(db, CLINICS_COLLECTION), ...constraints);
8738
8800
  const querySnapshot = await (0, import_firestore26.getDocs)(q);
8739
8801
  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
8802
  clinics = applyInMemoryFilters(clinics, filters);
8750
8803
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
8751
8804
  console.log(`[CLINIC_SERVICE] Strategy 3 success: ${clinics.length} clinics`);
@@ -8766,15 +8819,6 @@ async function getClinicsByFilters(db, filters) {
8766
8819
  const q = (0, import_firestore26.query)((0, import_firestore26.collection)(db, CLINICS_COLLECTION), ...constraints);
8767
8820
  const querySnapshot = await (0, import_firestore26.getDocs)(q);
8768
8821
  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
8822
  clinics = applyInMemoryFilters(clinics, filters);
8779
8823
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
8780
8824
  console.log(`[CLINIC_SERVICE] Strategy 4 success: ${clinics.length} clinics`);
@@ -8793,21 +8837,96 @@ async function getClinicsByFilters(db, filters) {
8793
8837
  }
8794
8838
  }
8795
8839
  function applyInMemoryFilters(clinics, filters) {
8840
+ let filteredClinics = [...clinics];
8841
+ console.log(`[CLINIC_SERVICE] Applying in-memory filters - input: ${filteredClinics.length} clinics`);
8796
8842
  if (filters.tags && filters.tags.length > 1) {
8797
- clinics = clinics.filter((clinic) => filters.tags.every((tag) => clinic.tags.includes(tag)));
8843
+ const initialCount = filteredClinics.length;
8844
+ filteredClinics = filteredClinics.filter(
8845
+ (clinic) => filters.tags.every((tag) => clinic.tags.includes(tag))
8846
+ );
8847
+ console.log(`[CLINIC_SERVICE] Applied multi-tag filter: ${initialCount} \u2192 ${filteredClinics.length}`);
8848
+ }
8849
+ if (filters.tags && filters.tags.length === 1) {
8850
+ const initialCount = filteredClinics.length;
8851
+ filteredClinics = filteredClinics.filter(
8852
+ (clinic) => clinic.tags.includes(filters.tags[0])
8853
+ );
8854
+ console.log(`[CLINIC_SERVICE] Applied single-tag filter: ${initialCount} \u2192 ${filteredClinics.length}`);
8855
+ }
8856
+ if (filters.minRating !== void 0 || filters.maxRating !== void 0) {
8857
+ const initialCount = filteredClinics.length;
8858
+ filteredClinics = filteredClinics.filter((clinic) => {
8859
+ var _a;
8860
+ const rating = ((_a = clinic.reviewInfo) == null ? void 0 : _a.averageRating) || 0;
8861
+ if (filters.minRating !== void 0 && rating < filters.minRating) return false;
8862
+ if (filters.maxRating !== void 0 && rating > filters.maxRating) return false;
8863
+ return true;
8864
+ });
8865
+ console.log(`[CLINIC_SERVICE] Applied rating filter (${filters.minRating}-${filters.maxRating}): ${initialCount} \u2192 ${filteredClinics.length}`);
8866
+ }
8867
+ if (filters.nameSearch && filters.nameSearch.trim()) {
8868
+ const initialCount = filteredClinics.length;
8869
+ const searchTerm = filters.nameSearch.trim().toLowerCase();
8870
+ filteredClinics = filteredClinics.filter((clinic) => {
8871
+ const name = (clinic.name || "").toLowerCase();
8872
+ const nameLower = clinic.nameLower || "";
8873
+ return name.includes(searchTerm) || nameLower.includes(searchTerm);
8874
+ });
8875
+ console.log(`[CLINIC_SERVICE] Applied name search filter: ${initialCount} \u2192 ${filteredClinics.length}`);
8876
+ }
8877
+ if (filters.procedureFamily) {
8878
+ const initialCount = filteredClinics.length;
8879
+ filteredClinics = filteredClinics.filter((clinic) => {
8880
+ const proceduresInfo = clinic.proceduresInfo || [];
8881
+ return proceduresInfo.some((proc) => proc.family === filters.procedureFamily);
8882
+ });
8883
+ console.log(`[CLINIC_SERVICE] Applied procedure family filter: ${initialCount} \u2192 ${filteredClinics.length}`);
8884
+ }
8885
+ if (filters.procedureCategory) {
8886
+ const initialCount = filteredClinics.length;
8887
+ filteredClinics = filteredClinics.filter((clinic) => {
8888
+ const proceduresInfo = clinic.proceduresInfo || [];
8889
+ return proceduresInfo.some((proc) => proc.categoryName === filters.procedureCategory);
8890
+ });
8891
+ console.log(`[CLINIC_SERVICE] Applied procedure category filter: ${initialCount} \u2192 ${filteredClinics.length}`);
8892
+ }
8893
+ if (filters.procedureSubcategory) {
8894
+ const initialCount = filteredClinics.length;
8895
+ filteredClinics = filteredClinics.filter((clinic) => {
8896
+ const proceduresInfo = clinic.proceduresInfo || [];
8897
+ return proceduresInfo.some((proc) => proc.subcategoryName === filters.procedureSubcategory);
8898
+ });
8899
+ console.log(`[CLINIC_SERVICE] Applied procedure subcategory filter: ${initialCount} \u2192 ${filteredClinics.length}`);
8900
+ }
8901
+ if (filters.procedureTechnology) {
8902
+ const initialCount = filteredClinics.length;
8903
+ filteredClinics = filteredClinics.filter((clinic) => {
8904
+ const proceduresInfo = clinic.proceduresInfo || [];
8905
+ return proceduresInfo.some((proc) => proc.technologyName === filters.procedureTechnology);
8906
+ });
8907
+ console.log(`[CLINIC_SERVICE] Applied procedure technology filter: ${initialCount} \u2192 ${filteredClinics.length}`);
8798
8908
  }
8799
8909
  if (filters.center && filters.radiusInKm) {
8800
- clinics = clinics.filter((clinic) => {
8910
+ const initialCount = filteredClinics.length;
8911
+ filteredClinics = filteredClinics.filter((clinic) => {
8912
+ var _a, _b;
8913
+ if (!((_a = clinic.location) == null ? void 0 : _a.latitude) || !((_b = clinic.location) == null ? void 0 : _b.longitude)) {
8914
+ console.log(`[CLINIC_SERVICE] Clinic ${clinic.id} missing location data`);
8915
+ return false;
8916
+ }
8801
8917
  const distance = (0, import_geofire_common6.distanceBetween)(
8802
8918
  [filters.center.latitude, filters.center.longitude],
8803
8919
  [clinic.location.latitude, clinic.location.longitude]
8804
8920
  ) / 1e3;
8921
+ console.log(`[CLINIC_SERVICE] Clinic ${clinic.name}: distance ${distance.toFixed(2)}km (limit: ${filters.radiusInKm}km)`);
8805
8922
  clinic.distance = distance;
8806
8923
  return distance <= filters.radiusInKm;
8807
8924
  });
8808
- clinics.sort((a, b) => (a.distance || 0) - (b.distance || 0));
8925
+ console.log(`[CLINIC_SERVICE] Applied geo filter (${filters.radiusInKm}km): ${initialCount} \u2192 ${filteredClinics.length}`);
8926
+ filteredClinics.sort((a, b) => (a.distance || 0) - (b.distance || 0));
8809
8927
  }
8810
- return clinics;
8928
+ console.log(`[CLINIC_SERVICE] Final filtered result: ${filteredClinics.length} clinics`);
8929
+ return filteredClinics;
8811
8930
  }
8812
8931
 
8813
8932
  // src/services/clinic/clinic.service.ts
@@ -15173,7 +15292,8 @@ var ProcedureService = class extends BaseService {
15173
15292
  constraints.push((0, import_firestore45.where)("reviewInfo.averageRating", "<=", filters.maxRating));
15174
15293
  }
15175
15294
  if (filters.treatmentBenefits && filters.treatmentBenefits.length > 0) {
15176
- constraints.push((0, import_firestore45.where)("treatmentBenefits", "array-contains-any", filters.treatmentBenefits));
15295
+ const benefitsToMatch = filters.treatmentBenefits;
15296
+ constraints.push((0, import_firestore45.where)("treatmentBenefits", "array-contains-any", benefitsToMatch));
15177
15297
  }
15178
15298
  return constraints;
15179
15299
  };
@@ -15256,15 +15376,7 @@ var ProcedureService = class extends BaseService {
15256
15376
  const q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
15257
15377
  const querySnapshot = await (0, import_firestore45.getDocs)(q);
15258
15378
  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
- }
15379
+ procedures = this.applyInMemoryFilters(procedures, filters);
15268
15380
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
15269
15381
  console.log(`[PROCEDURE_SERVICE] Strategy 3 success: ${procedures.length} procedures`);
15270
15382
  if (procedures.length < (filters.pagination || 10)) {
@@ -15284,15 +15396,7 @@ var ProcedureService = class extends BaseService {
15284
15396
  const q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
15285
15397
  const querySnapshot = await (0, import_firestore45.getDocs)(q);
15286
15398
  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}`);
15295
- }
15399
+ procedures = this.applyInMemoryFilters(procedures, filters);
15296
15400
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
15297
15401
  console.log(`[PROCEDURE_SERVICE] Strategy 4 success: ${procedures.length} procedures`);
15298
15402
  if (procedures.length < (filters.pagination || 10)) {
@@ -15309,6 +15413,94 @@ var ProcedureService = class extends BaseService {
15309
15413
  return { procedures: [], lastDoc: null };
15310
15414
  }
15311
15415
  }
15416
+ /**
15417
+ * Applies in-memory filters to procedures array
15418
+ * Used when Firestore queries fail or for complex filtering
15419
+ */
15420
+ applyInMemoryFilters(procedures, filters) {
15421
+ let filteredProcedures = [...procedures];
15422
+ if (filters.nameSearch && filters.nameSearch.trim()) {
15423
+ const searchTerm = filters.nameSearch.trim().toLowerCase();
15424
+ filteredProcedures = filteredProcedures.filter((procedure) => {
15425
+ const name = (procedure.name || "").toLowerCase();
15426
+ const nameLower = procedure.nameLower || "";
15427
+ return name.includes(searchTerm) || nameLower.includes(searchTerm);
15428
+ });
15429
+ console.log(`[PROCEDURE_SERVICE] Applied name filter, results: ${filteredProcedures.length}`);
15430
+ }
15431
+ if (filters.minPrice !== void 0 || filters.maxPrice !== void 0) {
15432
+ filteredProcedures = filteredProcedures.filter((procedure) => {
15433
+ const price = procedure.price || 0;
15434
+ if (filters.minPrice !== void 0 && price < filters.minPrice) return false;
15435
+ if (filters.maxPrice !== void 0 && price > filters.maxPrice) return false;
15436
+ return true;
15437
+ });
15438
+ console.log(`[PROCEDURE_SERVICE] Applied price filter (${filters.minPrice}-${filters.maxPrice}), results: ${filteredProcedures.length}`);
15439
+ }
15440
+ if (filters.minRating !== void 0 || filters.maxRating !== void 0) {
15441
+ filteredProcedures = filteredProcedures.filter((procedure) => {
15442
+ var _a;
15443
+ const rating = ((_a = procedure.reviewInfo) == null ? void 0 : _a.averageRating) || 0;
15444
+ if (filters.minRating !== void 0 && rating < filters.minRating) return false;
15445
+ if (filters.maxRating !== void 0 && rating > filters.maxRating) return false;
15446
+ return true;
15447
+ });
15448
+ console.log(`[PROCEDURE_SERVICE] Applied rating filter, results: ${filteredProcedures.length}`);
15449
+ }
15450
+ if (filters.treatmentBenefits && filters.treatmentBenefits.length > 0) {
15451
+ const benefitsToMatch = filters.treatmentBenefits;
15452
+ filteredProcedures = filteredProcedures.filter((procedure) => {
15453
+ const procedureBenefits = procedure.treatmentBenefits || [];
15454
+ return benefitsToMatch.some((benefit) => procedureBenefits.includes(benefit));
15455
+ });
15456
+ console.log(`[PROCEDURE_SERVICE] Applied benefits filter, results: ${filteredProcedures.length}`);
15457
+ }
15458
+ if (filters.procedureFamily) {
15459
+ filteredProcedures = filteredProcedures.filter((procedure) => procedure.family === filters.procedureFamily);
15460
+ console.log(`[PROCEDURE_SERVICE] Applied family filter, results: ${filteredProcedures.length}`);
15461
+ }
15462
+ if (filters.procedureCategory) {
15463
+ filteredProcedures = filteredProcedures.filter((procedure) => {
15464
+ var _a;
15465
+ return ((_a = procedure.category) == null ? void 0 : _a.id) === filters.procedureCategory;
15466
+ });
15467
+ console.log(`[PROCEDURE_SERVICE] Applied category filter, results: ${filteredProcedures.length}`);
15468
+ }
15469
+ if (filters.procedureSubcategory) {
15470
+ filteredProcedures = filteredProcedures.filter((procedure) => {
15471
+ var _a;
15472
+ return ((_a = procedure.subcategory) == null ? void 0 : _a.id) === filters.procedureSubcategory;
15473
+ });
15474
+ console.log(`[PROCEDURE_SERVICE] Applied subcategory filter, results: ${filteredProcedures.length}`);
15475
+ }
15476
+ if (filters.procedureTechnology) {
15477
+ filteredProcedures = filteredProcedures.filter((procedure) => {
15478
+ var _a;
15479
+ return ((_a = procedure.technology) == null ? void 0 : _a.id) === filters.procedureTechnology;
15480
+ });
15481
+ console.log(`[PROCEDURE_SERVICE] Applied technology filter, results: ${filteredProcedures.length}`);
15482
+ }
15483
+ if (filters.location && filters.radiusInKm && filters.radiusInKm > 0) {
15484
+ const location = filters.location;
15485
+ const radiusInKm = filters.radiusInKm;
15486
+ filteredProcedures = filteredProcedures.filter((procedure) => {
15487
+ var _a;
15488
+ const clinicLocation = (_a = procedure.clinicInfo) == null ? void 0 : _a.location;
15489
+ if (!(clinicLocation == null ? void 0 : clinicLocation.latitude) || !(clinicLocation == null ? void 0 : clinicLocation.longitude)) {
15490
+ return false;
15491
+ }
15492
+ const distance = (0, import_geofire_common8.distanceBetween)(
15493
+ [location.latitude, location.longitude],
15494
+ [clinicLocation.latitude, clinicLocation.longitude]
15495
+ ) / 1e3;
15496
+ procedure.distance = distance;
15497
+ return distance <= radiusInKm;
15498
+ });
15499
+ console.log(`[PROCEDURE_SERVICE] Applied geo filter, results: ${filteredProcedures.length}`);
15500
+ filteredProcedures.sort((a, b) => (a.distance || 0) - (b.distance || 0));
15501
+ }
15502
+ return filteredProcedures;
15503
+ }
15312
15504
  handleGeoQuery(filters) {
15313
15505
  console.log("[PROCEDURE_SERVICE] Executing geo query with enhanced debugging");
15314
15506
  try {
@@ -15329,21 +15521,7 @@ var ProcedureService = class extends BaseService {
15329
15521
  const q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
15330
15522
  return (0, import_firestore45.getDocs)(q).then((querySnapshot) => {
15331
15523
  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);
15524
+ procedures = this.applyInMemoryFilters(procedures, filters);
15347
15525
  console.log(`[PROCEDURE_SERVICE] Geo query success: ${procedures.length} procedures within ${radiusInKm}km`);
15348
15526
  const lastDoc = procedures.length < (filters.pagination || 10) ? null : querySnapshot.docs[querySnapshot.docs.length - 1];
15349
15527
  return { procedures, lastDoc };