@blackcode_sa/metaestetics-api 1.8.17 → 1.10.0
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 +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +233 -205
- package/dist/index.mjs +236 -210
- package/package.json +1 -1
- package/src/services/clinic/clinic.service.ts +91 -142
- package/src/services/clinic/utils/filter.utils.ts +180 -96
- package/src/services/practitioner/practitioner.service.ts +31 -0
- package/src/services/procedure/procedure.service.ts +326 -362
package/dist/index.js
CHANGED
|
@@ -6964,6 +6964,27 @@ var PractitionerService = class extends BaseService {
|
|
|
6964
6964
|
} catch (error) {
|
|
6965
6965
|
console.log("[PRACTITIONER_SERVICE] Strategy 3 failed:", error);
|
|
6966
6966
|
}
|
|
6967
|
+
try {
|
|
6968
|
+
console.log("[PRACTITIONER_SERVICE] Strategy 4: Client-side filtering fallback");
|
|
6969
|
+
const constraints = [
|
|
6970
|
+
(0, import_firestore21.where)("isActive", "==", true),
|
|
6971
|
+
(0, import_firestore21.where)("status", "==", "active" /* ACTIVE */),
|
|
6972
|
+
(0, import_firestore21.orderBy)("createdAt", "desc"),
|
|
6973
|
+
(0, import_firestore21.limit)(filters.pagination || 10)
|
|
6974
|
+
];
|
|
6975
|
+
const q = (0, import_firestore21.query)((0, import_firestore21.collection)(this.db, PRACTITIONERS_COLLECTION), ...constraints);
|
|
6976
|
+
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6977
|
+
let practitioners = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
|
|
6978
|
+
practitioners = this.applyInMemoryFilters(practitioners, filters);
|
|
6979
|
+
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
6980
|
+
console.log(`[PRACTITIONER_SERVICE] Strategy 4 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 4 failed:", error);
|
|
6987
|
+
}
|
|
6967
6988
|
console.log("[PRACTITIONER_SERVICE] All strategies failed, returning empty result");
|
|
6968
6989
|
return { practitioners: [], lastDoc: null };
|
|
6969
6990
|
} catch (error) {
|
|
@@ -8689,6 +8710,7 @@ async function findClinicsInRadius(db, center, radiusInKm, filters) {
|
|
|
8689
8710
|
var import_firestore26 = require("firebase/firestore");
|
|
8690
8711
|
var import_geofire_common6 = require("geofire-common");
|
|
8691
8712
|
async function getClinicsByFilters(db, filters) {
|
|
8713
|
+
var _a;
|
|
8692
8714
|
try {
|
|
8693
8715
|
console.log("[CLINIC_SERVICE] Starting clinic filtering with multiple strategies");
|
|
8694
8716
|
if (filters.center && filters.radiusInKm) {
|
|
@@ -8703,10 +8725,53 @@ async function getClinicsByFilters(db, filters) {
|
|
|
8703
8725
|
filters.radiusInKm = void 0;
|
|
8704
8726
|
}
|
|
8705
8727
|
}
|
|
8728
|
+
if (filters.center && filters.radiusInKm) {
|
|
8729
|
+
try {
|
|
8730
|
+
console.log("[CLINIC_SERVICE] Strategy 0: Geohash bounds prefilter");
|
|
8731
|
+
const bounds = (0, import_geofire_common6.geohashQueryBounds)(
|
|
8732
|
+
[filters.center.latitude, filters.center.longitude],
|
|
8733
|
+
(filters.radiusInKm || 0) * 1e3
|
|
8734
|
+
);
|
|
8735
|
+
const collected = [];
|
|
8736
|
+
for (const b of bounds) {
|
|
8737
|
+
const constraints = [
|
|
8738
|
+
(0, import_firestore26.where)("location.geohash", ">=", b[0]),
|
|
8739
|
+
(0, import_firestore26.where)("location.geohash", "<=", b[1]),
|
|
8740
|
+
(0, import_firestore26.where)("isActive", "==", (_a = filters.isActive) != null ? _a : true)
|
|
8741
|
+
];
|
|
8742
|
+
if (filters.tags && filters.tags.length > 0) {
|
|
8743
|
+
constraints.push((0, import_firestore26.where)("tags", "array-contains", filters.tags[0]));
|
|
8744
|
+
}
|
|
8745
|
+
const q0 = (0, import_firestore26.query)((0, import_firestore26.collection)(db, CLINICS_COLLECTION), ...constraints);
|
|
8746
|
+
const snap = await (0, import_firestore26.getDocs)(q0);
|
|
8747
|
+
snap.docs.forEach((d) => collected.push({ ...d.data(), id: d.id }));
|
|
8748
|
+
}
|
|
8749
|
+
const uniqueMap = /* @__PURE__ */ new Map();
|
|
8750
|
+
for (const c of collected) {
|
|
8751
|
+
uniqueMap.set(c.id, c);
|
|
8752
|
+
}
|
|
8753
|
+
let clinics = Array.from(uniqueMap.values());
|
|
8754
|
+
clinics = applyInMemoryFilters(clinics, filters);
|
|
8755
|
+
const pageSize = filters.pagination || 5;
|
|
8756
|
+
let startIndex = 0;
|
|
8757
|
+
if (filters.lastDoc && typeof filters.lastDoc === "object" && filters.lastDoc.id) {
|
|
8758
|
+
const idx = clinics.findIndex((c) => c.id === filters.lastDoc.id);
|
|
8759
|
+
if (idx >= 0) startIndex = idx + 1;
|
|
8760
|
+
}
|
|
8761
|
+
const page = clinics.slice(startIndex, startIndex + pageSize);
|
|
8762
|
+
const newLastDoc = page.length === pageSize ? page[page.length - 1] : null;
|
|
8763
|
+
console.log(
|
|
8764
|
+
`[CLINIC_SERVICE] Strategy 0 success: ${page.length} clinics (of ${clinics.length})`
|
|
8765
|
+
);
|
|
8766
|
+
return { clinics: page, lastDoc: newLastDoc };
|
|
8767
|
+
} catch (geoErr) {
|
|
8768
|
+
console.log("[CLINIC_SERVICE] Strategy 0 failed:", geoErr);
|
|
8769
|
+
}
|
|
8770
|
+
}
|
|
8706
8771
|
const getBaseConstraints = () => {
|
|
8707
|
-
var
|
|
8772
|
+
var _a2;
|
|
8708
8773
|
const constraints = [];
|
|
8709
|
-
constraints.push((0, import_firestore26.where)("isActive", "==", (
|
|
8774
|
+
constraints.push((0, import_firestore26.where)("isActive", "==", (_a2 = filters.isActive) != null ? _a2 : true));
|
|
8710
8775
|
if (filters.tags && filters.tags.length > 0) {
|
|
8711
8776
|
constraints.push((0, import_firestore26.where)("tags", "array-contains", filters.tags[0]));
|
|
8712
8777
|
}
|
|
@@ -8783,7 +8848,9 @@ async function getClinicsByFilters(db, filters) {
|
|
|
8783
8848
|
}
|
|
8784
8849
|
}
|
|
8785
8850
|
try {
|
|
8786
|
-
console.log(
|
|
8851
|
+
console.log(
|
|
8852
|
+
"[CLINIC_SERVICE] Strategy 3: Using createdAt ordering with client-side filtering"
|
|
8853
|
+
);
|
|
8787
8854
|
const constraints = getBaseConstraints();
|
|
8788
8855
|
constraints.push((0, import_firestore26.orderBy)("createdAt", "desc"));
|
|
8789
8856
|
if (filters.lastDoc) {
|
|
@@ -8838,20 +8905,24 @@ async function getClinicsByFilters(db, filters) {
|
|
|
8838
8905
|
}
|
|
8839
8906
|
function applyInMemoryFilters(clinics, filters) {
|
|
8840
8907
|
let filteredClinics = [...clinics];
|
|
8841
|
-
console.log(
|
|
8908
|
+
console.log(
|
|
8909
|
+
`[CLINIC_SERVICE] Applying in-memory filters - input: ${filteredClinics.length} clinics`
|
|
8910
|
+
);
|
|
8842
8911
|
if (filters.tags && filters.tags.length > 1) {
|
|
8843
8912
|
const initialCount = filteredClinics.length;
|
|
8844
8913
|
filteredClinics = filteredClinics.filter(
|
|
8845
8914
|
(clinic) => filters.tags.every((tag) => clinic.tags.includes(tag))
|
|
8846
8915
|
);
|
|
8847
|
-
console.log(
|
|
8916
|
+
console.log(
|
|
8917
|
+
`[CLINIC_SERVICE] Applied multi-tag filter: ${initialCount} \u2192 ${filteredClinics.length}`
|
|
8918
|
+
);
|
|
8848
8919
|
}
|
|
8849
8920
|
if (filters.tags && filters.tags.length === 1) {
|
|
8850
8921
|
const initialCount = filteredClinics.length;
|
|
8851
|
-
filteredClinics = filteredClinics.filter(
|
|
8852
|
-
|
|
8922
|
+
filteredClinics = filteredClinics.filter((clinic) => clinic.tags.includes(filters.tags[0]));
|
|
8923
|
+
console.log(
|
|
8924
|
+
`[CLINIC_SERVICE] Applied single-tag filter: ${initialCount} \u2192 ${filteredClinics.length}`
|
|
8853
8925
|
);
|
|
8854
|
-
console.log(`[CLINIC_SERVICE] Applied single-tag filter: ${initialCount} \u2192 ${filteredClinics.length}`);
|
|
8855
8926
|
}
|
|
8856
8927
|
if (filters.minRating !== void 0 || filters.maxRating !== void 0) {
|
|
8857
8928
|
const initialCount = filteredClinics.length;
|
|
@@ -8862,7 +8933,9 @@ function applyInMemoryFilters(clinics, filters) {
|
|
|
8862
8933
|
if (filters.maxRating !== void 0 && rating > filters.maxRating) return false;
|
|
8863
8934
|
return true;
|
|
8864
8935
|
});
|
|
8865
|
-
console.log(
|
|
8936
|
+
console.log(
|
|
8937
|
+
`[CLINIC_SERVICE] Applied rating filter (${filters.minRating}-${filters.maxRating}): ${initialCount} \u2192 ${filteredClinics.length}`
|
|
8938
|
+
);
|
|
8866
8939
|
}
|
|
8867
8940
|
if (filters.nameSearch && filters.nameSearch.trim()) {
|
|
8868
8941
|
const initialCount = filteredClinics.length;
|
|
@@ -8872,7 +8945,9 @@ function applyInMemoryFilters(clinics, filters) {
|
|
|
8872
8945
|
const nameLower = clinic.nameLower || "";
|
|
8873
8946
|
return name.includes(searchTerm) || nameLower.includes(searchTerm);
|
|
8874
8947
|
});
|
|
8875
|
-
console.log(
|
|
8948
|
+
console.log(
|
|
8949
|
+
`[CLINIC_SERVICE] Applied name search filter: ${initialCount} \u2192 ${filteredClinics.length}`
|
|
8950
|
+
);
|
|
8876
8951
|
}
|
|
8877
8952
|
if (filters.procedureFamily) {
|
|
8878
8953
|
const initialCount = filteredClinics.length;
|
|
@@ -8880,7 +8955,9 @@ function applyInMemoryFilters(clinics, filters) {
|
|
|
8880
8955
|
const proceduresInfo = clinic.proceduresInfo || [];
|
|
8881
8956
|
return proceduresInfo.some((proc) => proc.family === filters.procedureFamily);
|
|
8882
8957
|
});
|
|
8883
|
-
console.log(
|
|
8958
|
+
console.log(
|
|
8959
|
+
`[CLINIC_SERVICE] Applied procedure family filter: ${initialCount} \u2192 ${filteredClinics.length}`
|
|
8960
|
+
);
|
|
8884
8961
|
}
|
|
8885
8962
|
if (filters.procedureCategory) {
|
|
8886
8963
|
const initialCount = filteredClinics.length;
|
|
@@ -8888,7 +8965,9 @@ function applyInMemoryFilters(clinics, filters) {
|
|
|
8888
8965
|
const proceduresInfo = clinic.proceduresInfo || [];
|
|
8889
8966
|
return proceduresInfo.some((proc) => proc.categoryName === filters.procedureCategory);
|
|
8890
8967
|
});
|
|
8891
|
-
console.log(
|
|
8968
|
+
console.log(
|
|
8969
|
+
`[CLINIC_SERVICE] Applied procedure category filter: ${initialCount} \u2192 ${filteredClinics.length}`
|
|
8970
|
+
);
|
|
8892
8971
|
}
|
|
8893
8972
|
if (filters.procedureSubcategory) {
|
|
8894
8973
|
const initialCount = filteredClinics.length;
|
|
@@ -8896,7 +8975,9 @@ function applyInMemoryFilters(clinics, filters) {
|
|
|
8896
8975
|
const proceduresInfo = clinic.proceduresInfo || [];
|
|
8897
8976
|
return proceduresInfo.some((proc) => proc.subcategoryName === filters.procedureSubcategory);
|
|
8898
8977
|
});
|
|
8899
|
-
console.log(
|
|
8978
|
+
console.log(
|
|
8979
|
+
`[CLINIC_SERVICE] Applied procedure subcategory filter: ${initialCount} \u2192 ${filteredClinics.length}`
|
|
8980
|
+
);
|
|
8900
8981
|
}
|
|
8901
8982
|
if (filters.procedureTechnology) {
|
|
8902
8983
|
const initialCount = filteredClinics.length;
|
|
@@ -8904,7 +8985,9 @@ function applyInMemoryFilters(clinics, filters) {
|
|
|
8904
8985
|
const proceduresInfo = clinic.proceduresInfo || [];
|
|
8905
8986
|
return proceduresInfo.some((proc) => proc.technologyName === filters.procedureTechnology);
|
|
8906
8987
|
});
|
|
8907
|
-
console.log(
|
|
8988
|
+
console.log(
|
|
8989
|
+
`[CLINIC_SERVICE] Applied procedure technology filter: ${initialCount} \u2192 ${filteredClinics.length}`
|
|
8990
|
+
);
|
|
8908
8991
|
}
|
|
8909
8992
|
if (filters.center && filters.radiusInKm) {
|
|
8910
8993
|
const initialCount = filteredClinics.length;
|
|
@@ -8918,11 +9001,15 @@ function applyInMemoryFilters(clinics, filters) {
|
|
|
8918
9001
|
[filters.center.latitude, filters.center.longitude],
|
|
8919
9002
|
[clinic.location.latitude, clinic.location.longitude]
|
|
8920
9003
|
) / 1e3;
|
|
8921
|
-
console.log(
|
|
9004
|
+
console.log(
|
|
9005
|
+
`[CLINIC_SERVICE] Clinic ${clinic.name}: distance ${distance.toFixed(2)}km (limit: ${filters.radiusInKm}km)`
|
|
9006
|
+
);
|
|
8922
9007
|
clinic.distance = distance;
|
|
8923
9008
|
return distance <= filters.radiusInKm;
|
|
8924
9009
|
});
|
|
8925
|
-
console.log(
|
|
9010
|
+
console.log(
|
|
9011
|
+
`[CLINIC_SERVICE] Applied geo filter (${filters.radiusInKm}km): ${initialCount} \u2192 ${filteredClinics.length}`
|
|
9012
|
+
);
|
|
8926
9013
|
filteredClinics.sort((a, b) => (a.distance || 0) - (b.distance || 0));
|
|
8927
9014
|
}
|
|
8928
9015
|
console.log(`[CLINIC_SERVICE] Final filtered result: ${filteredClinics.length} clinics`);
|
|
@@ -8950,9 +9037,7 @@ var ClinicService = class extends BaseService {
|
|
|
8950
9037
|
return media;
|
|
8951
9038
|
}
|
|
8952
9039
|
if (media instanceof File || media instanceof Blob) {
|
|
8953
|
-
console.log(
|
|
8954
|
-
`[ClinicService] Uploading ${collectionName} media for ${ownerId}`
|
|
8955
|
-
);
|
|
9040
|
+
console.log(`[ClinicService] Uploading ${collectionName} media for ${ownerId}`);
|
|
8956
9041
|
const metadata = await this.mediaService.uploadMedia(
|
|
8957
9042
|
media,
|
|
8958
9043
|
ownerId,
|
|
@@ -8974,11 +9059,7 @@ var ClinicService = class extends BaseService {
|
|
|
8974
9059
|
if (!mediaArray || mediaArray.length === 0) return [];
|
|
8975
9060
|
const result = [];
|
|
8976
9061
|
for (const media of mediaArray) {
|
|
8977
|
-
const processedUrl = await this.processMedia(
|
|
8978
|
-
media,
|
|
8979
|
-
ownerId,
|
|
8980
|
-
collectionName
|
|
8981
|
-
);
|
|
9062
|
+
const processedUrl = await this.processMedia(media, ownerId, collectionName);
|
|
8982
9063
|
if (processedUrl) {
|
|
8983
9064
|
result.push(processedUrl);
|
|
8984
9065
|
}
|
|
@@ -8996,11 +9077,7 @@ var ClinicService = class extends BaseService {
|
|
|
8996
9077
|
if (!photosWithTags || photosWithTags.length === 0) return [];
|
|
8997
9078
|
const result = [];
|
|
8998
9079
|
for (const item of photosWithTags) {
|
|
8999
|
-
const processedUrl = await this.processMedia(
|
|
9000
|
-
item.url,
|
|
9001
|
-
ownerId,
|
|
9002
|
-
collectionName
|
|
9003
|
-
);
|
|
9080
|
+
const processedUrl = await this.processMedia(item.url, ownerId, collectionName);
|
|
9004
9081
|
if (processedUrl) {
|
|
9005
9082
|
result.push({
|
|
9006
9083
|
url: processedUrl,
|
|
@@ -9018,19 +9095,11 @@ var ClinicService = class extends BaseService {
|
|
|
9018
9095
|
try {
|
|
9019
9096
|
const clinicId = this.generateId();
|
|
9020
9097
|
const validatedData = createClinicSchema.parse(data);
|
|
9021
|
-
const group = await this.clinicGroupService.getClinicGroup(
|
|
9022
|
-
validatedData.clinicGroupId
|
|
9023
|
-
);
|
|
9098
|
+
const group = await this.clinicGroupService.getClinicGroup(validatedData.clinicGroupId);
|
|
9024
9099
|
if (!group) {
|
|
9025
|
-
throw new Error(
|
|
9026
|
-
`Clinic group ${validatedData.clinicGroupId} not found`
|
|
9027
|
-
);
|
|
9100
|
+
throw new Error(`Clinic group ${validatedData.clinicGroupId} not found`);
|
|
9028
9101
|
}
|
|
9029
|
-
const logoUrl = await this.processMedia(
|
|
9030
|
-
validatedData.logo,
|
|
9031
|
-
clinicId,
|
|
9032
|
-
"clinic-logos"
|
|
9033
|
-
);
|
|
9102
|
+
const logoUrl = await this.processMedia(validatedData.logo, clinicId, "clinic-logos");
|
|
9034
9103
|
const coverPhotoUrl = await this.processMedia(
|
|
9035
9104
|
validatedData.coverPhoto,
|
|
9036
9105
|
clinicId,
|
|
@@ -9120,11 +9189,7 @@ var ClinicService = class extends BaseService {
|
|
|
9120
9189
|
const validatedData = updateClinicSchema.parse(data);
|
|
9121
9190
|
const updatePayload = {};
|
|
9122
9191
|
if (validatedData.logo !== void 0) {
|
|
9123
|
-
updatePayload.logo = await this.processMedia(
|
|
9124
|
-
validatedData.logo,
|
|
9125
|
-
clinicId,
|
|
9126
|
-
"clinic-logos"
|
|
9127
|
-
);
|
|
9192
|
+
updatePayload.logo = await this.processMedia(validatedData.logo, clinicId, "clinic-logos");
|
|
9128
9193
|
}
|
|
9129
9194
|
if (validatedData.coverPhoto !== void 0) {
|
|
9130
9195
|
updatePayload.coverPhoto = await this.processMedia(
|
|
@@ -9224,22 +9289,10 @@ var ClinicService = class extends BaseService {
|
|
|
9224
9289
|
* Pretražuje klinike u određenom radijusu
|
|
9225
9290
|
*/
|
|
9226
9291
|
async findClinicsInRadius(center, radiusInKm, filters) {
|
|
9227
|
-
return findClinicsInRadius(
|
|
9228
|
-
this.db,
|
|
9229
|
-
center,
|
|
9230
|
-
radiusInKm,
|
|
9231
|
-
filters
|
|
9232
|
-
);
|
|
9292
|
+
return findClinicsInRadius(this.db, center, radiusInKm, filters);
|
|
9233
9293
|
}
|
|
9234
9294
|
async addTags(clinicId, adminId, newTags) {
|
|
9235
|
-
return addTags(
|
|
9236
|
-
this.db,
|
|
9237
|
-
clinicId,
|
|
9238
|
-
adminId,
|
|
9239
|
-
newTags,
|
|
9240
|
-
this.clinicAdminService,
|
|
9241
|
-
this.app
|
|
9242
|
-
);
|
|
9295
|
+
return addTags(this.db, clinicId, adminId, newTags, this.clinicAdminService, this.app);
|
|
9243
9296
|
}
|
|
9244
9297
|
async removeTags(clinicId, adminId, tagsToRemove) {
|
|
9245
9298
|
return removeTags(
|
|
@@ -9277,9 +9330,7 @@ var ClinicService = class extends BaseService {
|
|
|
9277
9330
|
clinicGroupId,
|
|
9278
9331
|
adminId
|
|
9279
9332
|
});
|
|
9280
|
-
const clinicGroup = await this.clinicGroupService.getClinicGroup(
|
|
9281
|
-
clinicGroupId
|
|
9282
|
-
);
|
|
9333
|
+
const clinicGroup = await this.clinicGroupService.getClinicGroup(clinicGroupId);
|
|
9283
9334
|
if (!clinicGroup) {
|
|
9284
9335
|
console.error("[CLINIC_SERVICE] Clinic group not found", {
|
|
9285
9336
|
clinicGroupId
|
|
@@ -9325,13 +9376,7 @@ var ClinicService = class extends BaseService {
|
|
|
9325
9376
|
return getAllClinics(this.db, pagination, lastDoc);
|
|
9326
9377
|
}
|
|
9327
9378
|
async getAllClinicsInRange(center, rangeInKm, pagination, lastDoc) {
|
|
9328
|
-
return getAllClinicsInRange(
|
|
9329
|
-
this.db,
|
|
9330
|
-
center,
|
|
9331
|
-
rangeInKm,
|
|
9332
|
-
pagination,
|
|
9333
|
-
lastDoc
|
|
9334
|
-
);
|
|
9379
|
+
return getAllClinicsInRange(this.db, center, rangeInKm, pagination, lastDoc);
|
|
9335
9380
|
}
|
|
9336
9381
|
/**
|
|
9337
9382
|
* Get clinics based on multiple filtering criteria
|
|
@@ -14637,9 +14682,7 @@ var ProcedureService = class extends BaseService {
|
|
|
14637
14682
|
return media;
|
|
14638
14683
|
}
|
|
14639
14684
|
if (media instanceof File || media instanceof Blob) {
|
|
14640
|
-
console.log(
|
|
14641
|
-
`[ProcedureService] Uploading ${collectionName} media for ${ownerId}`
|
|
14642
|
-
);
|
|
14685
|
+
console.log(`[ProcedureService] Uploading ${collectionName} media for ${ownerId}`);
|
|
14643
14686
|
const metadata = await this.mediaService.uploadMedia(
|
|
14644
14687
|
media,
|
|
14645
14688
|
ownerId,
|
|
@@ -14661,11 +14704,7 @@ var ProcedureService = class extends BaseService {
|
|
|
14661
14704
|
if (!mediaArray || mediaArray.length === 0) return [];
|
|
14662
14705
|
const result = [];
|
|
14663
14706
|
for (const media of mediaArray) {
|
|
14664
|
-
const processedUrl = await this.processMedia(
|
|
14665
|
-
media,
|
|
14666
|
-
ownerId,
|
|
14667
|
-
collectionName
|
|
14668
|
-
);
|
|
14707
|
+
const processedUrl = await this.processMedia(media, ownerId, collectionName);
|
|
14669
14708
|
if (processedUrl) {
|
|
14670
14709
|
result.push(processedUrl);
|
|
14671
14710
|
}
|
|
@@ -14683,41 +14722,23 @@ var ProcedureService = class extends BaseService {
|
|
|
14683
14722
|
const procedureId = this.generateId();
|
|
14684
14723
|
const [category, subcategory, technology, product] = await Promise.all([
|
|
14685
14724
|
this.categoryService.getById(validatedData.categoryId),
|
|
14686
|
-
this.subcategoryService.getById(
|
|
14687
|
-
validatedData.categoryId,
|
|
14688
|
-
validatedData.subcategoryId
|
|
14689
|
-
),
|
|
14725
|
+
this.subcategoryService.getById(validatedData.categoryId, validatedData.subcategoryId),
|
|
14690
14726
|
this.technologyService.getById(validatedData.technologyId),
|
|
14691
|
-
this.productService.getById(
|
|
14692
|
-
validatedData.technologyId,
|
|
14693
|
-
validatedData.productId
|
|
14694
|
-
)
|
|
14727
|
+
this.productService.getById(validatedData.technologyId, validatedData.productId)
|
|
14695
14728
|
]);
|
|
14696
14729
|
if (!category || !subcategory || !technology || !product) {
|
|
14697
14730
|
throw new Error("One or more required base entities not found");
|
|
14698
14731
|
}
|
|
14699
|
-
const clinicRef = (0, import_firestore45.doc)(
|
|
14700
|
-
this.db,
|
|
14701
|
-
CLINICS_COLLECTION,
|
|
14702
|
-
validatedData.clinicBranchId
|
|
14703
|
-
);
|
|
14732
|
+
const clinicRef = (0, import_firestore45.doc)(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId);
|
|
14704
14733
|
const clinicSnapshot = await (0, import_firestore45.getDoc)(clinicRef);
|
|
14705
14734
|
if (!clinicSnapshot.exists()) {
|
|
14706
|
-
throw new Error(
|
|
14707
|
-
`Clinic with ID ${validatedData.clinicBranchId} not found`
|
|
14708
|
-
);
|
|
14735
|
+
throw new Error(`Clinic with ID ${validatedData.clinicBranchId} not found`);
|
|
14709
14736
|
}
|
|
14710
14737
|
const clinic = clinicSnapshot.data();
|
|
14711
|
-
const practitionerRef = (0, import_firestore45.doc)(
|
|
14712
|
-
this.db,
|
|
14713
|
-
PRACTITIONERS_COLLECTION,
|
|
14714
|
-
validatedData.practitionerId
|
|
14715
|
-
);
|
|
14738
|
+
const practitionerRef = (0, import_firestore45.doc)(this.db, PRACTITIONERS_COLLECTION, validatedData.practitionerId);
|
|
14716
14739
|
const practitionerSnapshot = await (0, import_firestore45.getDoc)(practitionerRef);
|
|
14717
14740
|
if (!practitionerSnapshot.exists()) {
|
|
14718
|
-
throw new Error(
|
|
14719
|
-
`Practitioner with ID ${validatedData.practitionerId} not found`
|
|
14720
|
-
);
|
|
14741
|
+
throw new Error(`Practitioner with ID ${validatedData.practitionerId} not found`);
|
|
14721
14742
|
}
|
|
14722
14743
|
const practitioner = practitionerSnapshot.data();
|
|
14723
14744
|
let processedPhotos = [];
|
|
@@ -14806,24 +14827,16 @@ var ProcedureService = class extends BaseService {
|
|
|
14806
14827
|
const validatedData = createProcedureSchema.parse(validationData);
|
|
14807
14828
|
const [category, subcategory, technology, product, clinicSnapshot] = await Promise.all([
|
|
14808
14829
|
this.categoryService.getById(validatedData.categoryId),
|
|
14809
|
-
this.subcategoryService.getById(
|
|
14810
|
-
validatedData.categoryId,
|
|
14811
|
-
validatedData.subcategoryId
|
|
14812
|
-
),
|
|
14830
|
+
this.subcategoryService.getById(validatedData.categoryId, validatedData.subcategoryId),
|
|
14813
14831
|
this.technologyService.getById(validatedData.technologyId),
|
|
14814
|
-
this.productService.getById(
|
|
14815
|
-
validatedData.technologyId,
|
|
14816
|
-
validatedData.productId
|
|
14817
|
-
),
|
|
14832
|
+
this.productService.getById(validatedData.technologyId, validatedData.productId),
|
|
14818
14833
|
(0, import_firestore45.getDoc)((0, import_firestore45.doc)(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId))
|
|
14819
14834
|
]);
|
|
14820
14835
|
if (!category || !subcategory || !technology || !product) {
|
|
14821
14836
|
throw new Error("One or more required base entities not found");
|
|
14822
14837
|
}
|
|
14823
14838
|
if (!clinicSnapshot.exists()) {
|
|
14824
|
-
throw new Error(
|
|
14825
|
-
`Clinic with ID ${validatedData.clinicBranchId} not found`
|
|
14826
|
-
);
|
|
14839
|
+
throw new Error(`Clinic with ID ${validatedData.clinicBranchId} not found`);
|
|
14827
14840
|
}
|
|
14828
14841
|
const clinic = clinicSnapshot.data();
|
|
14829
14842
|
let processedPhotos = [];
|
|
@@ -14849,12 +14862,8 @@ var ProcedureService = class extends BaseService {
|
|
|
14849
14862
|
}
|
|
14850
14863
|
if (practitionersMap.size !== practitionerIds.length) {
|
|
14851
14864
|
const foundIds = Array.from(practitionersMap.keys());
|
|
14852
|
-
const notFoundIds = practitionerIds.filter(
|
|
14853
|
-
|
|
14854
|
-
);
|
|
14855
|
-
throw new Error(
|
|
14856
|
-
`The following practitioners were not found: ${notFoundIds.join(", ")}`
|
|
14857
|
-
);
|
|
14865
|
+
const notFoundIds = practitionerIds.filter((id) => !foundIds.includes(id));
|
|
14866
|
+
throw new Error(`The following practitioners were not found: ${notFoundIds.join(", ")}`);
|
|
14858
14867
|
}
|
|
14859
14868
|
const batch = (0, import_firestore45.writeBatch)(this.db);
|
|
14860
14869
|
const createdProcedureIds = [];
|
|
@@ -14922,10 +14931,7 @@ var ProcedureService = class extends BaseService {
|
|
|
14922
14931
|
const fetchedProcedures = [];
|
|
14923
14932
|
for (let i = 0; i < createdProcedureIds.length; i += 30) {
|
|
14924
14933
|
const chunk = createdProcedureIds.slice(i, i + 30);
|
|
14925
|
-
const q = (0, import_firestore45.query)(
|
|
14926
|
-
(0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION),
|
|
14927
|
-
(0, import_firestore45.where)((0, import_firestore45.documentId)(), "in", chunk)
|
|
14928
|
-
);
|
|
14934
|
+
const q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), (0, import_firestore45.where)((0, import_firestore45.documentId)(), "in", chunk));
|
|
14929
14935
|
const snapshot = await (0, import_firestore45.getDocs)(q);
|
|
14930
14936
|
snapshot.forEach((doc37) => {
|
|
14931
14937
|
fetchedProcedures.push(doc37.data());
|
|
@@ -15026,9 +15032,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15026
15032
|
);
|
|
15027
15033
|
const newPractitionerSnap = await (0, import_firestore45.getDoc)(newPractitionerRef);
|
|
15028
15034
|
if (!newPractitionerSnap.exists())
|
|
15029
|
-
throw new Error(
|
|
15030
|
-
`New Practitioner ${validatedData.practitionerId} not found`
|
|
15031
|
-
);
|
|
15035
|
+
throw new Error(`New Practitioner ${validatedData.practitionerId} not found`);
|
|
15032
15036
|
newPractitioner = newPractitionerSnap.data();
|
|
15033
15037
|
updatedProcedureData.doctorInfo = {
|
|
15034
15038
|
id: newPractitioner.id,
|
|
@@ -15042,11 +15046,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15042
15046
|
}
|
|
15043
15047
|
if (validatedData.clinicBranchId && validatedData.clinicBranchId !== oldClinicId) {
|
|
15044
15048
|
clinicChanged = true;
|
|
15045
|
-
const newClinicRef = (0, import_firestore45.doc)(
|
|
15046
|
-
this.db,
|
|
15047
|
-
CLINICS_COLLECTION,
|
|
15048
|
-
validatedData.clinicBranchId
|
|
15049
|
-
);
|
|
15049
|
+
const newClinicRef = (0, import_firestore45.doc)(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId);
|
|
15050
15050
|
const newClinicSnap = await (0, import_firestore45.getDoc)(newClinicRef);
|
|
15051
15051
|
if (!newClinicSnap.exists())
|
|
15052
15052
|
throw new Error(`New Clinic ${validatedData.clinicBranchId} not found`);
|
|
@@ -15065,11 +15065,8 @@ var ProcedureService = class extends BaseService {
|
|
|
15065
15065
|
updatedProcedureData.nameLower = validatedData.name.toLowerCase();
|
|
15066
15066
|
}
|
|
15067
15067
|
if (validatedData.categoryId) {
|
|
15068
|
-
const category = await this.categoryService.getById(
|
|
15069
|
-
|
|
15070
|
-
);
|
|
15071
|
-
if (!category)
|
|
15072
|
-
throw new Error(`Category ${validatedData.categoryId} not found`);
|
|
15068
|
+
const category = await this.categoryService.getById(validatedData.categoryId);
|
|
15069
|
+
if (!category) throw new Error(`Category ${validatedData.categoryId} not found`);
|
|
15073
15070
|
updatedProcedureData.category = category;
|
|
15074
15071
|
finalCategoryId = category.id;
|
|
15075
15072
|
}
|
|
@@ -15084,17 +15081,12 @@ var ProcedureService = class extends BaseService {
|
|
|
15084
15081
|
);
|
|
15085
15082
|
updatedProcedureData.subcategory = subcategory;
|
|
15086
15083
|
} else if (validatedData.subcategoryId) {
|
|
15087
|
-
console.warn(
|
|
15088
|
-
"Attempted to update subcategory without a valid categoryId"
|
|
15089
|
-
);
|
|
15084
|
+
console.warn("Attempted to update subcategory without a valid categoryId");
|
|
15090
15085
|
}
|
|
15091
15086
|
let finalTechnologyId = existingProcedure.technology.id;
|
|
15092
15087
|
if (validatedData.technologyId) {
|
|
15093
|
-
const technology = await this.technologyService.getById(
|
|
15094
|
-
|
|
15095
|
-
);
|
|
15096
|
-
if (!technology)
|
|
15097
|
-
throw new Error(`Technology ${validatedData.technologyId} not found`);
|
|
15088
|
+
const technology = await this.technologyService.getById(validatedData.technologyId);
|
|
15089
|
+
if (!technology) throw new Error(`Technology ${validatedData.technologyId} not found`);
|
|
15098
15090
|
updatedProcedureData.technology = technology;
|
|
15099
15091
|
finalTechnologyId = technology.id;
|
|
15100
15092
|
updatedProcedureData.blockingConditions = technology.blockingConditions;
|
|
@@ -15105,10 +15097,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15105
15097
|
updatedProcedureData.documentationTemplates = technology.documentationTemplates || [];
|
|
15106
15098
|
}
|
|
15107
15099
|
if (validatedData.productId && finalTechnologyId) {
|
|
15108
|
-
const product = await this.productService.getById(
|
|
15109
|
-
finalTechnologyId,
|
|
15110
|
-
validatedData.productId
|
|
15111
|
-
);
|
|
15100
|
+
const product = await this.productService.getById(finalTechnologyId, validatedData.productId);
|
|
15112
15101
|
if (!product)
|
|
15113
15102
|
throw new Error(
|
|
15114
15103
|
`Product ${validatedData.productId} not found for technology ${finalTechnologyId}`
|
|
@@ -15190,11 +15179,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15190
15179
|
limit16(pagination)
|
|
15191
15180
|
);
|
|
15192
15181
|
} else {
|
|
15193
|
-
proceduresQuery = (0, import_firestore45.query)(
|
|
15194
|
-
proceduresCollection,
|
|
15195
|
-
(0, import_firestore45.orderBy)("name"),
|
|
15196
|
-
limit16(pagination)
|
|
15197
|
-
);
|
|
15182
|
+
proceduresQuery = (0, import_firestore45.query)(proceduresCollection, (0, import_firestore45.orderBy)("name"), limit16(pagination));
|
|
15198
15183
|
}
|
|
15199
15184
|
} else {
|
|
15200
15185
|
proceduresQuery = (0, import_firestore45.query)(proceduresCollection, (0, import_firestore45.orderBy)("name"));
|
|
@@ -15317,7 +15302,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15317
15302
|
constraints.push((0, import_firestore45.limit)(filters.pagination || 10));
|
|
15318
15303
|
const q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
|
|
15319
15304
|
const querySnapshot = await (0, import_firestore45.getDocs)(q);
|
|
15320
|
-
const procedures = querySnapshot.docs.map(
|
|
15305
|
+
const procedures = querySnapshot.docs.map(
|
|
15306
|
+
(doc37) => ({ ...doc37.data(), id: doc37.id })
|
|
15307
|
+
);
|
|
15321
15308
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15322
15309
|
console.log(`[PROCEDURE_SERVICE] Strategy 1 success: ${procedures.length} procedures`);
|
|
15323
15310
|
if (procedures.length < (filters.pagination || 10)) {
|
|
@@ -15348,7 +15335,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15348
15335
|
constraints.push((0, import_firestore45.limit)(filters.pagination || 10));
|
|
15349
15336
|
const q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
|
|
15350
15337
|
const querySnapshot = await (0, import_firestore45.getDocs)(q);
|
|
15351
|
-
const procedures = querySnapshot.docs.map(
|
|
15338
|
+
const procedures = querySnapshot.docs.map(
|
|
15339
|
+
(doc37) => ({ ...doc37.data(), id: doc37.id })
|
|
15340
|
+
);
|
|
15352
15341
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15353
15342
|
console.log(`[PROCEDURE_SERVICE] Strategy 2 success: ${procedures.length} procedures`);
|
|
15354
15343
|
if (procedures.length < (filters.pagination || 10)) {
|
|
@@ -15360,7 +15349,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15360
15349
|
}
|
|
15361
15350
|
}
|
|
15362
15351
|
try {
|
|
15363
|
-
console.log(
|
|
15352
|
+
console.log(
|
|
15353
|
+
"[PROCEDURE_SERVICE] Strategy 3: Using createdAt orderBy with client-side filtering"
|
|
15354
|
+
);
|
|
15364
15355
|
const constraints = getBaseConstraints();
|
|
15365
15356
|
constraints.push((0, import_firestore45.orderBy)("createdAt", "desc"));
|
|
15366
15357
|
if (filters.lastDoc) {
|
|
@@ -15375,7 +15366,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15375
15366
|
constraints.push((0, import_firestore45.limit)(filters.pagination || 10));
|
|
15376
15367
|
const q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
|
|
15377
15368
|
const querySnapshot = await (0, import_firestore45.getDocs)(q);
|
|
15378
|
-
let procedures = querySnapshot.docs.map(
|
|
15369
|
+
let procedures = querySnapshot.docs.map(
|
|
15370
|
+
(doc37) => ({ ...doc37.data(), id: doc37.id })
|
|
15371
|
+
);
|
|
15379
15372
|
procedures = this.applyInMemoryFilters(procedures, filters);
|
|
15380
15373
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15381
15374
|
console.log(`[PROCEDURE_SERVICE] Strategy 3 success: ${procedures.length} procedures`);
|
|
@@ -15395,7 +15388,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15395
15388
|
];
|
|
15396
15389
|
const q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
|
|
15397
15390
|
const querySnapshot = await (0, import_firestore45.getDocs)(q);
|
|
15398
|
-
let procedures = querySnapshot.docs.map(
|
|
15391
|
+
let procedures = querySnapshot.docs.map(
|
|
15392
|
+
(doc37) => ({ ...doc37.data(), id: doc37.id })
|
|
15393
|
+
);
|
|
15399
15394
|
procedures = this.applyInMemoryFilters(procedures, filters);
|
|
15400
15395
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15401
15396
|
console.log(`[PROCEDURE_SERVICE] Strategy 4 success: ${procedures.length} procedures`);
|
|
@@ -15435,7 +15430,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15435
15430
|
if (filters.maxPrice !== void 0 && price > filters.maxPrice) return false;
|
|
15436
15431
|
return true;
|
|
15437
15432
|
});
|
|
15438
|
-
console.log(
|
|
15433
|
+
console.log(
|
|
15434
|
+
`[PROCEDURE_SERVICE] Applied price filter (${filters.minPrice}-${filters.maxPrice}), results: ${filteredProcedures.length}`
|
|
15435
|
+
);
|
|
15439
15436
|
}
|
|
15440
15437
|
if (filters.minRating !== void 0 || filters.maxRating !== void 0) {
|
|
15441
15438
|
filteredProcedures = filteredProcedures.filter((procedure) => {
|
|
@@ -15445,7 +15442,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15445
15442
|
if (filters.maxRating !== void 0 && rating > filters.maxRating) return false;
|
|
15446
15443
|
return true;
|
|
15447
15444
|
});
|
|
15448
|
-
console.log(
|
|
15445
|
+
console.log(
|
|
15446
|
+
`[PROCEDURE_SERVICE] Applied rating filter, results: ${filteredProcedures.length}`
|
|
15447
|
+
);
|
|
15449
15448
|
}
|
|
15450
15449
|
if (filters.treatmentBenefits && filters.treatmentBenefits.length > 0) {
|
|
15451
15450
|
const benefitsToMatch = filters.treatmentBenefits;
|
|
@@ -15453,32 +15452,50 @@ var ProcedureService = class extends BaseService {
|
|
|
15453
15452
|
const procedureBenefits = procedure.treatmentBenefits || [];
|
|
15454
15453
|
return benefitsToMatch.some((benefit) => procedureBenefits.includes(benefit));
|
|
15455
15454
|
});
|
|
15456
|
-
console.log(
|
|
15455
|
+
console.log(
|
|
15456
|
+
`[PROCEDURE_SERVICE] Applied benefits filter, results: ${filteredProcedures.length}`
|
|
15457
|
+
);
|
|
15457
15458
|
}
|
|
15458
15459
|
if (filters.procedureFamily) {
|
|
15459
|
-
filteredProcedures = filteredProcedures.filter(
|
|
15460
|
-
|
|
15460
|
+
filteredProcedures = filteredProcedures.filter(
|
|
15461
|
+
(procedure) => procedure.family === filters.procedureFamily
|
|
15462
|
+
);
|
|
15463
|
+
console.log(
|
|
15464
|
+
`[PROCEDURE_SERVICE] Applied family filter, results: ${filteredProcedures.length}`
|
|
15465
|
+
);
|
|
15461
15466
|
}
|
|
15462
15467
|
if (filters.procedureCategory) {
|
|
15463
|
-
filteredProcedures = filteredProcedures.filter(
|
|
15464
|
-
|
|
15465
|
-
|
|
15466
|
-
|
|
15467
|
-
|
|
15468
|
+
filteredProcedures = filteredProcedures.filter(
|
|
15469
|
+
(procedure) => {
|
|
15470
|
+
var _a;
|
|
15471
|
+
return ((_a = procedure.category) == null ? void 0 : _a.id) === filters.procedureCategory;
|
|
15472
|
+
}
|
|
15473
|
+
);
|
|
15474
|
+
console.log(
|
|
15475
|
+
`[PROCEDURE_SERVICE] Applied category filter, results: ${filteredProcedures.length}`
|
|
15476
|
+
);
|
|
15468
15477
|
}
|
|
15469
15478
|
if (filters.procedureSubcategory) {
|
|
15470
|
-
filteredProcedures = filteredProcedures.filter(
|
|
15471
|
-
|
|
15472
|
-
|
|
15473
|
-
|
|
15474
|
-
|
|
15479
|
+
filteredProcedures = filteredProcedures.filter(
|
|
15480
|
+
(procedure) => {
|
|
15481
|
+
var _a;
|
|
15482
|
+
return ((_a = procedure.subcategory) == null ? void 0 : _a.id) === filters.procedureSubcategory;
|
|
15483
|
+
}
|
|
15484
|
+
);
|
|
15485
|
+
console.log(
|
|
15486
|
+
`[PROCEDURE_SERVICE] Applied subcategory filter, results: ${filteredProcedures.length}`
|
|
15487
|
+
);
|
|
15475
15488
|
}
|
|
15476
15489
|
if (filters.procedureTechnology) {
|
|
15477
|
-
filteredProcedures = filteredProcedures.filter(
|
|
15478
|
-
|
|
15479
|
-
|
|
15480
|
-
|
|
15481
|
-
|
|
15490
|
+
filteredProcedures = filteredProcedures.filter(
|
|
15491
|
+
(procedure) => {
|
|
15492
|
+
var _a;
|
|
15493
|
+
return ((_a = procedure.technology) == null ? void 0 : _a.id) === filters.procedureTechnology;
|
|
15494
|
+
}
|
|
15495
|
+
);
|
|
15496
|
+
console.log(
|
|
15497
|
+
`[PROCEDURE_SERVICE] Applied technology filter, results: ${filteredProcedures.length}`
|
|
15498
|
+
);
|
|
15482
15499
|
}
|
|
15483
15500
|
if (filters.location && filters.radiusInKm && filters.radiusInKm > 0) {
|
|
15484
15501
|
const location = filters.location;
|
|
@@ -15502,29 +15519,48 @@ var ProcedureService = class extends BaseService {
|
|
|
15502
15519
|
return filteredProcedures;
|
|
15503
15520
|
}
|
|
15504
15521
|
handleGeoQuery(filters) {
|
|
15505
|
-
console.log("[PROCEDURE_SERVICE] Executing geo query with
|
|
15522
|
+
console.log("[PROCEDURE_SERVICE] Executing geo query with geohash bounds");
|
|
15506
15523
|
try {
|
|
15507
15524
|
const location = filters.location;
|
|
15508
15525
|
const radiusInKm = filters.radiusInKm;
|
|
15509
|
-
|
|
15510
|
-
|
|
15511
|
-
|
|
15512
|
-
|
|
15513
|
-
|
|
15526
|
+
if (!location || !radiusInKm) {
|
|
15527
|
+
return Promise.resolve({ procedures: [], lastDoc: null });
|
|
15528
|
+
}
|
|
15529
|
+
const bounds = (0, import_geofire_common8.geohashQueryBounds)([location.latitude, location.longitude], radiusInKm * 1e3);
|
|
15530
|
+
const fetches = bounds.map((b) => {
|
|
15531
|
+
const constraints = [
|
|
15532
|
+
(0, import_firestore45.where)("clinicInfo.location.geohash", ">=", b[0]),
|
|
15533
|
+
(0, import_firestore45.where)("clinicInfo.location.geohash", "<=", b[1]),
|
|
15534
|
+
(0, import_firestore45.where)("isActive", "==", filters.isActive !== void 0 ? filters.isActive : true)
|
|
15535
|
+
];
|
|
15536
|
+
return (0, import_firestore45.getDocs)((0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints));
|
|
15514
15537
|
});
|
|
15515
|
-
|
|
15516
|
-
|
|
15517
|
-
(
|
|
15518
|
-
|
|
15519
|
-
|
|
15520
|
-
|
|
15521
|
-
|
|
15522
|
-
|
|
15523
|
-
|
|
15538
|
+
return Promise.all(fetches).then((snaps) => {
|
|
15539
|
+
const collected = [];
|
|
15540
|
+
snaps.forEach((snap) => {
|
|
15541
|
+
snap.docs.forEach((d) => collected.push({ ...d.data(), id: d.id }));
|
|
15542
|
+
});
|
|
15543
|
+
const uniqueMap = /* @__PURE__ */ new Map();
|
|
15544
|
+
for (const p of collected) {
|
|
15545
|
+
uniqueMap.set(p.id, p);
|
|
15546
|
+
}
|
|
15547
|
+
let procedures = Array.from(uniqueMap.values());
|
|
15524
15548
|
procedures = this.applyInMemoryFilters(procedures, filters);
|
|
15525
|
-
|
|
15526
|
-
|
|
15527
|
-
|
|
15549
|
+
const pageSize = filters.pagination || 10;
|
|
15550
|
+
let startIndex = 0;
|
|
15551
|
+
if (filters.lastDoc && typeof filters.lastDoc === "object" && filters.lastDoc.id) {
|
|
15552
|
+
const idx = procedures.findIndex((p) => p.id === filters.lastDoc.id);
|
|
15553
|
+
if (idx >= 0) startIndex = idx + 1;
|
|
15554
|
+
}
|
|
15555
|
+
const page = procedures.slice(startIndex, startIndex + pageSize);
|
|
15556
|
+
const newLastDoc = page.length === pageSize ? page[page.length - 1] : null;
|
|
15557
|
+
console.log(
|
|
15558
|
+
`[PROCEDURE_SERVICE] Geo query success: ${page.length} (of ${procedures.length}) within ${radiusInKm}km`
|
|
15559
|
+
);
|
|
15560
|
+
return { procedures: page, lastDoc: newLastDoc };
|
|
15561
|
+
}).catch((err) => {
|
|
15562
|
+
console.error("[PROCEDURE_SERVICE] Geo bounds fetch failed:", err);
|
|
15563
|
+
return { procedures: [], lastDoc: null };
|
|
15528
15564
|
});
|
|
15529
15565
|
} catch (error) {
|
|
15530
15566
|
console.error("[PROCEDURE_SERVICE] Geo query failed:", error);
|
|
@@ -15554,11 +15590,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15554
15590
|
throw new Error(`Clinic with ID ${data.clinicBranchId} not found`);
|
|
15555
15591
|
}
|
|
15556
15592
|
const clinic = clinicSnapshot.data();
|
|
15557
|
-
const practitionerRef = (0, import_firestore45.doc)(
|
|
15558
|
-
this.db,
|
|
15559
|
-
PRACTITIONERS_COLLECTION,
|
|
15560
|
-
data.practitionerId
|
|
15561
|
-
);
|
|
15593
|
+
const practitionerRef = (0, import_firestore45.doc)(this.db, PRACTITIONERS_COLLECTION, data.practitionerId);
|
|
15562
15594
|
const practitionerSnapshot = await (0, import_firestore45.getDoc)(practitionerRef);
|
|
15563
15595
|
if (!practitionerSnapshot.exists()) {
|
|
15564
15596
|
throw new Error(`Practitioner with ID ${data.practitionerId} not found`);
|
|
@@ -15566,11 +15598,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15566
15598
|
const practitioner = practitionerSnapshot.data();
|
|
15567
15599
|
let processedPhotos = [];
|
|
15568
15600
|
if (data.photos && data.photos.length > 0) {
|
|
15569
|
-
processedPhotos = await this.processMediaArray(
|
|
15570
|
-
data.photos,
|
|
15571
|
-
procedureId,
|
|
15572
|
-
"procedure-photos"
|
|
15573
|
-
);
|
|
15601
|
+
processedPhotos = await this.processMediaArray(data.photos, procedureId, "procedure-photos");
|
|
15574
15602
|
}
|
|
15575
15603
|
const clinicInfo = {
|
|
15576
15604
|
id: clinicSnapshot.id,
|