@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 +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +268 -90
- package/dist/index.mjs +268 -90
- package/package.json +1 -1
- package/src/services/clinic/utils/filter.utils.ts +103 -45
- package/src/services/practitioner/practitioner.service.ts +118 -33
- package/src/services/procedure/procedure.service.ts +111 -44
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",
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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 };
|