@blackcode_sa/metaestetics-api 1.8.13 → 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.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +536 -213
- package/dist/index.mjs +537 -214
- package/package.json +1 -1
- package/src/services/clinic/utils/filter.utils.ts +242 -57
- package/src/services/practitioner/practitioner.service.ts +195 -82
- package/src/services/procedure/procedure.service.ts +279 -123
- package/src/admin/scripts/migrateProcedures.js +0 -23
- package/src/admin/scripts/serviceAccountKey.json +0 -13
package/dist/index.js
CHANGED
|
@@ -6605,6 +6605,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6605
6605
|
validData.basicInfo,
|
|
6606
6606
|
practitionerId
|
|
6607
6607
|
);
|
|
6608
|
+
processedData.fullNameLower = `${processedData.basicInfo.firstName} ${processedData.basicInfo.lastName}`.toLowerCase();
|
|
6608
6609
|
}
|
|
6609
6610
|
const updateData = {
|
|
6610
6611
|
...processedData,
|
|
@@ -6832,80 +6833,163 @@ var PractitionerService = class extends BaseService {
|
|
|
6832
6833
|
*/
|
|
6833
6834
|
async getPractitionersByFilters(filters) {
|
|
6834
6835
|
try {
|
|
6835
|
-
|
|
6836
|
-
if (
|
|
6837
|
-
|
|
6838
|
-
|
|
6839
|
-
|
|
6840
|
-
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
|
|
6847
|
-
);
|
|
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
|
+
}
|
|
6848
6848
|
}
|
|
6849
6849
|
if (filters.nameSearch && filters.nameSearch.trim()) {
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
6855
|
-
|
|
6856
|
-
|
|
6857
|
-
|
|
6858
|
-
|
|
6859
|
-
|
|
6860
|
-
|
|
6861
|
-
|
|
6862
|
-
|
|
6863
|
-
|
|
6864
|
-
|
|
6865
|
-
|
|
6866
|
-
|
|
6867
|
-
|
|
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
|
+
}
|
|
6868
6883
|
}
|
|
6869
|
-
|
|
6870
|
-
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
|
|
6874
|
-
|
|
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));
|
|
6875
6905
|
} else {
|
|
6876
|
-
|
|
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);
|
|
6877
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);
|
|
6878
6956
|
}
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
const
|
|
6894
|
-
|
|
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);
|
|
6895
6976
|
});
|
|
6896
|
-
|
|
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);
|
|
6897
6987
|
}
|
|
6898
|
-
|
|
6899
|
-
return {
|
|
6900
|
-
practitioners,
|
|
6901
|
-
lastDoc
|
|
6902
|
-
};
|
|
6988
|
+
console.log("[PRACTITIONER_SERVICE] All strategies failed, returning empty result");
|
|
6989
|
+
return { practitioners: [], lastDoc: null };
|
|
6903
6990
|
} catch (error) {
|
|
6904
|
-
console.error(
|
|
6905
|
-
|
|
6906
|
-
error
|
|
6907
|
-
);
|
|
6908
|
-
throw error;
|
|
6991
|
+
console.error("[PRACTITIONER_SERVICE] Error filtering practitioners:", error);
|
|
6992
|
+
return { practitioners: [], lastDoc: null };
|
|
6909
6993
|
}
|
|
6910
6994
|
}
|
|
6911
6995
|
/**
|
|
@@ -8534,49 +8618,181 @@ async function findClinicsInRadius(db, center, radiusInKm, filters) {
|
|
|
8534
8618
|
var import_firestore26 = require("firebase/firestore");
|
|
8535
8619
|
var import_geofire_common6 = require("geofire-common");
|
|
8536
8620
|
async function getClinicsByFilters(db, filters) {
|
|
8537
|
-
|
|
8538
|
-
|
|
8539
|
-
|
|
8540
|
-
|
|
8541
|
-
|
|
8542
|
-
|
|
8543
|
-
|
|
8544
|
-
|
|
8545
|
-
|
|
8546
|
-
|
|
8547
|
-
|
|
8548
|
-
|
|
8549
|
-
|
|
8550
|
-
|
|
8551
|
-
|
|
8552
|
-
|
|
8553
|
-
|
|
8554
|
-
|
|
8555
|
-
|
|
8556
|
-
|
|
8557
|
-
|
|
8558
|
-
|
|
8559
|
-
|
|
8560
|
-
|
|
8561
|
-
|
|
8562
|
-
|
|
8563
|
-
|
|
8564
|
-
|
|
8565
|
-
|
|
8566
|
-
|
|
8567
|
-
|
|
8568
|
-
|
|
8569
|
-
|
|
8570
|
-
|
|
8571
|
-
|
|
8572
|
-
|
|
8573
|
-
constraints
|
|
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);
|
|
8574
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 };
|
|
8575
8793
|
}
|
|
8576
|
-
|
|
8577
|
-
|
|
8578
|
-
const querySnapshot = await (0, import_firestore26.getDocs)(q);
|
|
8579
|
-
let clinics = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
|
|
8794
|
+
}
|
|
8795
|
+
function applyInMemoryFilters(clinics, filters) {
|
|
8580
8796
|
if (filters.tags && filters.tags.length > 1) {
|
|
8581
8797
|
clinics = clinics.filter((clinic) => filters.tags.every((tag) => clinic.tags.includes(tag)));
|
|
8582
8798
|
}
|
|
@@ -8589,9 +8805,9 @@ async function getClinicsByFilters(db, filters) {
|
|
|
8589
8805
|
clinic.distance = distance;
|
|
8590
8806
|
return distance <= filters.radiusInKm;
|
|
8591
8807
|
});
|
|
8808
|
+
clinics.sort((a, b) => (a.distance || 0) - (b.distance || 0));
|
|
8592
8809
|
}
|
|
8593
|
-
|
|
8594
|
-
return { clinics, lastDoc: lastVisibleDoc };
|
|
8810
|
+
return clinics;
|
|
8595
8811
|
}
|
|
8596
8812
|
|
|
8597
8813
|
// src/services/clinic/clinic.service.ts
|
|
@@ -14908,126 +15124,233 @@ var ProcedureService = class extends BaseService {
|
|
|
14908
15124
|
*/
|
|
14909
15125
|
async getProceduresByFilters(filters) {
|
|
14910
15126
|
try {
|
|
14911
|
-
|
|
14912
|
-
|
|
14913
|
-
|
|
14914
|
-
|
|
14915
|
-
|
|
14916
|
-
|
|
14917
|
-
|
|
14918
|
-
|
|
14919
|
-
|
|
14920
|
-
|
|
14921
|
-
|
|
14922
|
-
|
|
14923
|
-
}
|
|
14924
|
-
if (filters.procedureSubcategory) {
|
|
14925
|
-
constraints.push((0, import_firestore45.where)("subcategory.id", "==", filters.procedureSubcategory));
|
|
14926
|
-
}
|
|
14927
|
-
if (filters.procedureTechnology) {
|
|
14928
|
-
constraints.push((0, import_firestore45.where)("technology.id", "==", filters.procedureTechnology));
|
|
14929
|
-
}
|
|
14930
|
-
if (filters.minPrice !== void 0) {
|
|
14931
|
-
constraints.push((0, import_firestore45.where)("price", ">=", filters.minPrice));
|
|
14932
|
-
}
|
|
14933
|
-
if (filters.maxPrice !== void 0) {
|
|
14934
|
-
constraints.push((0, import_firestore45.where)("price", "<=", filters.maxPrice));
|
|
14935
|
-
}
|
|
14936
|
-
if (filters.minRating !== void 0) {
|
|
14937
|
-
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
|
+
}
|
|
14938
15139
|
}
|
|
14939
|
-
|
|
14940
|
-
|
|
14941
|
-
|
|
14942
|
-
if (filters.treatmentBenefits && filters.treatmentBenefits.length > 0) {
|
|
14943
|
-
constraints.push((0, import_firestore45.where)("treatmentBenefits", "array-contains-any", filters.treatmentBenefits));
|
|
14944
|
-
}
|
|
14945
|
-
let useNameLower = false;
|
|
14946
|
-
let searchTerm = "";
|
|
14947
|
-
if (filters.nameSearch && filters.nameSearch.trim() !== "") {
|
|
14948
|
-
searchTerm = filters.nameSearch.trim().toLowerCase();
|
|
14949
|
-
useNameLower = true;
|
|
14950
|
-
constraints.push((0, import_firestore45.where)("nameLower", ">=", searchTerm));
|
|
14951
|
-
constraints.push((0, import_firestore45.where)("nameLower", "<=", searchTerm + "\uF8FF"));
|
|
14952
|
-
constraints.push((0, import_firestore45.orderBy)("nameLower"));
|
|
14953
|
-
} else {
|
|
14954
|
-
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);
|
|
14955
15143
|
}
|
|
14956
|
-
|
|
14957
|
-
|
|
14958
|
-
|
|
14959
|
-
|
|
14960
|
-
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));
|
|
14961
15148
|
} else {
|
|
14962
|
-
constraints.push((0, import_firestore45.
|
|
15149
|
+
constraints.push((0, import_firestore45.where)("isActive", "==", true));
|
|
14963
15150
|
}
|
|
14964
|
-
|
|
14965
|
-
|
|
14966
|
-
constraints.push((0, import_firestore45.limit)(filters.pagination));
|
|
14967
|
-
}
|
|
14968
|
-
if (isGeoQuery) {
|
|
14969
|
-
const center = filters.location;
|
|
14970
|
-
const radiusInKm = filters.radiusInKm;
|
|
14971
|
-
const bounds = (0, import_geofire_common8.geohashQueryBounds)(
|
|
14972
|
-
[center.latitude, center.longitude],
|
|
14973
|
-
radiusInKm * 1e3
|
|
14974
|
-
// Convert to meters
|
|
14975
|
-
);
|
|
14976
|
-
let allDocs = [];
|
|
14977
|
-
for (const bound of bounds) {
|
|
14978
|
-
const geoConstraints = [
|
|
14979
|
-
...constraints.filter((c) => !c.fieldPath || c.fieldPath !== "name"),
|
|
14980
|
-
// Remove name orderBy for geo
|
|
14981
|
-
(0, import_firestore45.where)("clinicInfo.location.geohash", ">=", bound[0]),
|
|
14982
|
-
(0, import_firestore45.where)("clinicInfo.location.geohash", "<=", bound[1]),
|
|
14983
|
-
(0, import_firestore45.orderBy)("clinicInfo.location.geohash")
|
|
14984
|
-
];
|
|
14985
|
-
const q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...geoConstraints);
|
|
14986
|
-
const querySnapshot = await (0, import_firestore45.getDocs)(q);
|
|
14987
|
-
for (const doc37 of querySnapshot.docs) {
|
|
14988
|
-
const procedure = { ...doc37.data(), id: doc37.id };
|
|
14989
|
-
const distance = (0, import_geofire_common8.distanceBetween)(
|
|
14990
|
-
[center.latitude, center.longitude],
|
|
14991
|
-
[procedure.clinicInfo.location.latitude, procedure.clinicInfo.location.longitude]
|
|
14992
|
-
);
|
|
14993
|
-
const distanceInKm = distance / 1e3;
|
|
14994
|
-
if (distanceInKm <= radiusInKm) {
|
|
14995
|
-
allDocs.push({ ...procedure, distance: distanceInKm });
|
|
14996
|
-
}
|
|
14997
|
-
}
|
|
15151
|
+
if (filters.procedureFamily) {
|
|
15152
|
+
constraints.push((0, import_firestore45.where)("family", "==", filters.procedureFamily));
|
|
14998
15153
|
}
|
|
14999
|
-
|
|
15000
|
-
|
|
15001
|
-
|
|
15002
|
-
|
|
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"));
|
|
15003
15188
|
if (filters.lastDoc) {
|
|
15004
|
-
|
|
15005
|
-
|
|
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 };
|
|
15006
15205
|
}
|
|
15007
|
-
|
|
15206
|
+
return { procedures, lastDoc };
|
|
15207
|
+
} catch (error) {
|
|
15208
|
+
console.log("[PROCEDURE_SERVICE] Strategy 1 failed:", error);
|
|
15008
15209
|
}
|
|
15009
|
-
|
|
15010
|
-
|
|
15011
|
-
|
|
15012
|
-
|
|
15013
|
-
|
|
15014
|
-
|
|
15015
|
-
constraints.pop();
|
|
15016
|
-
constraints.pop();
|
|
15017
|
-
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();
|
|
15018
15216
|
constraints.push((0, import_firestore45.where)("name", ">=", searchTerm));
|
|
15019
15217
|
constraints.push((0, import_firestore45.where)("name", "<=", searchTerm + "\uF8FF"));
|
|
15020
15218
|
constraints.push((0, import_firestore45.orderBy)("name"));
|
|
15021
|
-
|
|
15022
|
-
|
|
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}`);
|
|
15023
15295
|
}
|
|
15024
|
-
const
|
|
15025
|
-
|
|
15026
|
-
|
|
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);
|
|
15027
15304
|
}
|
|
15305
|
+
console.log("[PROCEDURE_SERVICE] All strategies failed, returning empty result");
|
|
15306
|
+
return { procedures: [], lastDoc: null };
|
|
15028
15307
|
} catch (error) {
|
|
15029
15308
|
console.error("[PROCEDURE_SERVICE] Error filtering procedures:", error);
|
|
15030
|
-
|
|
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 });
|
|
15031
15354
|
}
|
|
15032
15355
|
}
|
|
15033
15356
|
/**
|