@blackcode_sa/metaestetics-api 1.8.18 → 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 +212 -205
- package/dist/index.mjs +215 -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/procedure/procedure.service.ts +326 -362
package/dist/index.mjs
CHANGED
|
@@ -8342,9 +8342,7 @@ import {
|
|
|
8342
8342
|
writeBatch as writeBatch4,
|
|
8343
8343
|
arrayUnion as arrayUnion7
|
|
8344
8344
|
} from "firebase/firestore";
|
|
8345
|
-
import {
|
|
8346
|
-
geohashForLocation as geohashForLocation4
|
|
8347
|
-
} from "geofire-common";
|
|
8345
|
+
import { geohashForLocation as geohashForLocation4 } from "geofire-common";
|
|
8348
8346
|
import { z as z20 } from "zod";
|
|
8349
8347
|
|
|
8350
8348
|
// src/services/clinic/utils/clinic.utils.ts
|
|
@@ -8810,8 +8808,9 @@ import {
|
|
|
8810
8808
|
limit as limit9,
|
|
8811
8809
|
orderBy as orderBy5
|
|
8812
8810
|
} from "firebase/firestore";
|
|
8813
|
-
import { distanceBetween as distanceBetween4 } from "geofire-common";
|
|
8811
|
+
import { geohashQueryBounds as geohashQueryBounds3, distanceBetween as distanceBetween4 } from "geofire-common";
|
|
8814
8812
|
async function getClinicsByFilters(db, filters) {
|
|
8813
|
+
var _a;
|
|
8815
8814
|
try {
|
|
8816
8815
|
console.log("[CLINIC_SERVICE] Starting clinic filtering with multiple strategies");
|
|
8817
8816
|
if (filters.center && filters.radiusInKm) {
|
|
@@ -8826,10 +8825,53 @@ async function getClinicsByFilters(db, filters) {
|
|
|
8826
8825
|
filters.radiusInKm = void 0;
|
|
8827
8826
|
}
|
|
8828
8827
|
}
|
|
8828
|
+
if (filters.center && filters.radiusInKm) {
|
|
8829
|
+
try {
|
|
8830
|
+
console.log("[CLINIC_SERVICE] Strategy 0: Geohash bounds prefilter");
|
|
8831
|
+
const bounds = geohashQueryBounds3(
|
|
8832
|
+
[filters.center.latitude, filters.center.longitude],
|
|
8833
|
+
(filters.radiusInKm || 0) * 1e3
|
|
8834
|
+
);
|
|
8835
|
+
const collected = [];
|
|
8836
|
+
for (const b of bounds) {
|
|
8837
|
+
const constraints = [
|
|
8838
|
+
where15("location.geohash", ">=", b[0]),
|
|
8839
|
+
where15("location.geohash", "<=", b[1]),
|
|
8840
|
+
where15("isActive", "==", (_a = filters.isActive) != null ? _a : true)
|
|
8841
|
+
];
|
|
8842
|
+
if (filters.tags && filters.tags.length > 0) {
|
|
8843
|
+
constraints.push(where15("tags", "array-contains", filters.tags[0]));
|
|
8844
|
+
}
|
|
8845
|
+
const q0 = query15(collection15(db, CLINICS_COLLECTION), ...constraints);
|
|
8846
|
+
const snap = await getDocs15(q0);
|
|
8847
|
+
snap.docs.forEach((d) => collected.push({ ...d.data(), id: d.id }));
|
|
8848
|
+
}
|
|
8849
|
+
const uniqueMap = /* @__PURE__ */ new Map();
|
|
8850
|
+
for (const c of collected) {
|
|
8851
|
+
uniqueMap.set(c.id, c);
|
|
8852
|
+
}
|
|
8853
|
+
let clinics = Array.from(uniqueMap.values());
|
|
8854
|
+
clinics = applyInMemoryFilters(clinics, filters);
|
|
8855
|
+
const pageSize = filters.pagination || 5;
|
|
8856
|
+
let startIndex = 0;
|
|
8857
|
+
if (filters.lastDoc && typeof filters.lastDoc === "object" && filters.lastDoc.id) {
|
|
8858
|
+
const idx = clinics.findIndex((c) => c.id === filters.lastDoc.id);
|
|
8859
|
+
if (idx >= 0) startIndex = idx + 1;
|
|
8860
|
+
}
|
|
8861
|
+
const page = clinics.slice(startIndex, startIndex + pageSize);
|
|
8862
|
+
const newLastDoc = page.length === pageSize ? page[page.length - 1] : null;
|
|
8863
|
+
console.log(
|
|
8864
|
+
`[CLINIC_SERVICE] Strategy 0 success: ${page.length} clinics (of ${clinics.length})`
|
|
8865
|
+
);
|
|
8866
|
+
return { clinics: page, lastDoc: newLastDoc };
|
|
8867
|
+
} catch (geoErr) {
|
|
8868
|
+
console.log("[CLINIC_SERVICE] Strategy 0 failed:", geoErr);
|
|
8869
|
+
}
|
|
8870
|
+
}
|
|
8829
8871
|
const getBaseConstraints = () => {
|
|
8830
|
-
var
|
|
8872
|
+
var _a2;
|
|
8831
8873
|
const constraints = [];
|
|
8832
|
-
constraints.push(where15("isActive", "==", (
|
|
8874
|
+
constraints.push(where15("isActive", "==", (_a2 = filters.isActive) != null ? _a2 : true));
|
|
8833
8875
|
if (filters.tags && filters.tags.length > 0) {
|
|
8834
8876
|
constraints.push(where15("tags", "array-contains", filters.tags[0]));
|
|
8835
8877
|
}
|
|
@@ -8906,7 +8948,9 @@ async function getClinicsByFilters(db, filters) {
|
|
|
8906
8948
|
}
|
|
8907
8949
|
}
|
|
8908
8950
|
try {
|
|
8909
|
-
console.log(
|
|
8951
|
+
console.log(
|
|
8952
|
+
"[CLINIC_SERVICE] Strategy 3: Using createdAt ordering with client-side filtering"
|
|
8953
|
+
);
|
|
8910
8954
|
const constraints = getBaseConstraints();
|
|
8911
8955
|
constraints.push(orderBy5("createdAt", "desc"));
|
|
8912
8956
|
if (filters.lastDoc) {
|
|
@@ -8961,20 +9005,24 @@ async function getClinicsByFilters(db, filters) {
|
|
|
8961
9005
|
}
|
|
8962
9006
|
function applyInMemoryFilters(clinics, filters) {
|
|
8963
9007
|
let filteredClinics = [...clinics];
|
|
8964
|
-
console.log(
|
|
9008
|
+
console.log(
|
|
9009
|
+
`[CLINIC_SERVICE] Applying in-memory filters - input: ${filteredClinics.length} clinics`
|
|
9010
|
+
);
|
|
8965
9011
|
if (filters.tags && filters.tags.length > 1) {
|
|
8966
9012
|
const initialCount = filteredClinics.length;
|
|
8967
9013
|
filteredClinics = filteredClinics.filter(
|
|
8968
9014
|
(clinic) => filters.tags.every((tag) => clinic.tags.includes(tag))
|
|
8969
9015
|
);
|
|
8970
|
-
console.log(
|
|
9016
|
+
console.log(
|
|
9017
|
+
`[CLINIC_SERVICE] Applied multi-tag filter: ${initialCount} \u2192 ${filteredClinics.length}`
|
|
9018
|
+
);
|
|
8971
9019
|
}
|
|
8972
9020
|
if (filters.tags && filters.tags.length === 1) {
|
|
8973
9021
|
const initialCount = filteredClinics.length;
|
|
8974
|
-
filteredClinics = filteredClinics.filter(
|
|
8975
|
-
|
|
9022
|
+
filteredClinics = filteredClinics.filter((clinic) => clinic.tags.includes(filters.tags[0]));
|
|
9023
|
+
console.log(
|
|
9024
|
+
`[CLINIC_SERVICE] Applied single-tag filter: ${initialCount} \u2192 ${filteredClinics.length}`
|
|
8976
9025
|
);
|
|
8977
|
-
console.log(`[CLINIC_SERVICE] Applied single-tag filter: ${initialCount} \u2192 ${filteredClinics.length}`);
|
|
8978
9026
|
}
|
|
8979
9027
|
if (filters.minRating !== void 0 || filters.maxRating !== void 0) {
|
|
8980
9028
|
const initialCount = filteredClinics.length;
|
|
@@ -8985,7 +9033,9 @@ function applyInMemoryFilters(clinics, filters) {
|
|
|
8985
9033
|
if (filters.maxRating !== void 0 && rating > filters.maxRating) return false;
|
|
8986
9034
|
return true;
|
|
8987
9035
|
});
|
|
8988
|
-
console.log(
|
|
9036
|
+
console.log(
|
|
9037
|
+
`[CLINIC_SERVICE] Applied rating filter (${filters.minRating}-${filters.maxRating}): ${initialCount} \u2192 ${filteredClinics.length}`
|
|
9038
|
+
);
|
|
8989
9039
|
}
|
|
8990
9040
|
if (filters.nameSearch && filters.nameSearch.trim()) {
|
|
8991
9041
|
const initialCount = filteredClinics.length;
|
|
@@ -8995,7 +9045,9 @@ function applyInMemoryFilters(clinics, filters) {
|
|
|
8995
9045
|
const nameLower = clinic.nameLower || "";
|
|
8996
9046
|
return name.includes(searchTerm) || nameLower.includes(searchTerm);
|
|
8997
9047
|
});
|
|
8998
|
-
console.log(
|
|
9048
|
+
console.log(
|
|
9049
|
+
`[CLINIC_SERVICE] Applied name search filter: ${initialCount} \u2192 ${filteredClinics.length}`
|
|
9050
|
+
);
|
|
8999
9051
|
}
|
|
9000
9052
|
if (filters.procedureFamily) {
|
|
9001
9053
|
const initialCount = filteredClinics.length;
|
|
@@ -9003,7 +9055,9 @@ function applyInMemoryFilters(clinics, filters) {
|
|
|
9003
9055
|
const proceduresInfo = clinic.proceduresInfo || [];
|
|
9004
9056
|
return proceduresInfo.some((proc) => proc.family === filters.procedureFamily);
|
|
9005
9057
|
});
|
|
9006
|
-
console.log(
|
|
9058
|
+
console.log(
|
|
9059
|
+
`[CLINIC_SERVICE] Applied procedure family filter: ${initialCount} \u2192 ${filteredClinics.length}`
|
|
9060
|
+
);
|
|
9007
9061
|
}
|
|
9008
9062
|
if (filters.procedureCategory) {
|
|
9009
9063
|
const initialCount = filteredClinics.length;
|
|
@@ -9011,7 +9065,9 @@ function applyInMemoryFilters(clinics, filters) {
|
|
|
9011
9065
|
const proceduresInfo = clinic.proceduresInfo || [];
|
|
9012
9066
|
return proceduresInfo.some((proc) => proc.categoryName === filters.procedureCategory);
|
|
9013
9067
|
});
|
|
9014
|
-
console.log(
|
|
9068
|
+
console.log(
|
|
9069
|
+
`[CLINIC_SERVICE] Applied procedure category filter: ${initialCount} \u2192 ${filteredClinics.length}`
|
|
9070
|
+
);
|
|
9015
9071
|
}
|
|
9016
9072
|
if (filters.procedureSubcategory) {
|
|
9017
9073
|
const initialCount = filteredClinics.length;
|
|
@@ -9019,7 +9075,9 @@ function applyInMemoryFilters(clinics, filters) {
|
|
|
9019
9075
|
const proceduresInfo = clinic.proceduresInfo || [];
|
|
9020
9076
|
return proceduresInfo.some((proc) => proc.subcategoryName === filters.procedureSubcategory);
|
|
9021
9077
|
});
|
|
9022
|
-
console.log(
|
|
9078
|
+
console.log(
|
|
9079
|
+
`[CLINIC_SERVICE] Applied procedure subcategory filter: ${initialCount} \u2192 ${filteredClinics.length}`
|
|
9080
|
+
);
|
|
9023
9081
|
}
|
|
9024
9082
|
if (filters.procedureTechnology) {
|
|
9025
9083
|
const initialCount = filteredClinics.length;
|
|
@@ -9027,7 +9085,9 @@ function applyInMemoryFilters(clinics, filters) {
|
|
|
9027
9085
|
const proceduresInfo = clinic.proceduresInfo || [];
|
|
9028
9086
|
return proceduresInfo.some((proc) => proc.technologyName === filters.procedureTechnology);
|
|
9029
9087
|
});
|
|
9030
|
-
console.log(
|
|
9088
|
+
console.log(
|
|
9089
|
+
`[CLINIC_SERVICE] Applied procedure technology filter: ${initialCount} \u2192 ${filteredClinics.length}`
|
|
9090
|
+
);
|
|
9031
9091
|
}
|
|
9032
9092
|
if (filters.center && filters.radiusInKm) {
|
|
9033
9093
|
const initialCount = filteredClinics.length;
|
|
@@ -9041,11 +9101,15 @@ function applyInMemoryFilters(clinics, filters) {
|
|
|
9041
9101
|
[filters.center.latitude, filters.center.longitude],
|
|
9042
9102
|
[clinic.location.latitude, clinic.location.longitude]
|
|
9043
9103
|
) / 1e3;
|
|
9044
|
-
console.log(
|
|
9104
|
+
console.log(
|
|
9105
|
+
`[CLINIC_SERVICE] Clinic ${clinic.name}: distance ${distance.toFixed(2)}km (limit: ${filters.radiusInKm}km)`
|
|
9106
|
+
);
|
|
9045
9107
|
clinic.distance = distance;
|
|
9046
9108
|
return distance <= filters.radiusInKm;
|
|
9047
9109
|
});
|
|
9048
|
-
console.log(
|
|
9110
|
+
console.log(
|
|
9111
|
+
`[CLINIC_SERVICE] Applied geo filter (${filters.radiusInKm}km): ${initialCount} \u2192 ${filteredClinics.length}`
|
|
9112
|
+
);
|
|
9049
9113
|
filteredClinics.sort((a, b) => (a.distance || 0) - (b.distance || 0));
|
|
9050
9114
|
}
|
|
9051
9115
|
console.log(`[CLINIC_SERVICE] Final filtered result: ${filteredClinics.length} clinics`);
|
|
@@ -9073,9 +9137,7 @@ var ClinicService = class extends BaseService {
|
|
|
9073
9137
|
return media;
|
|
9074
9138
|
}
|
|
9075
9139
|
if (media instanceof File || media instanceof Blob) {
|
|
9076
|
-
console.log(
|
|
9077
|
-
`[ClinicService] Uploading ${collectionName} media for ${ownerId}`
|
|
9078
|
-
);
|
|
9140
|
+
console.log(`[ClinicService] Uploading ${collectionName} media for ${ownerId}`);
|
|
9079
9141
|
const metadata = await this.mediaService.uploadMedia(
|
|
9080
9142
|
media,
|
|
9081
9143
|
ownerId,
|
|
@@ -9097,11 +9159,7 @@ var ClinicService = class extends BaseService {
|
|
|
9097
9159
|
if (!mediaArray || mediaArray.length === 0) return [];
|
|
9098
9160
|
const result = [];
|
|
9099
9161
|
for (const media of mediaArray) {
|
|
9100
|
-
const processedUrl = await this.processMedia(
|
|
9101
|
-
media,
|
|
9102
|
-
ownerId,
|
|
9103
|
-
collectionName
|
|
9104
|
-
);
|
|
9162
|
+
const processedUrl = await this.processMedia(media, ownerId, collectionName);
|
|
9105
9163
|
if (processedUrl) {
|
|
9106
9164
|
result.push(processedUrl);
|
|
9107
9165
|
}
|
|
@@ -9119,11 +9177,7 @@ var ClinicService = class extends BaseService {
|
|
|
9119
9177
|
if (!photosWithTags || photosWithTags.length === 0) return [];
|
|
9120
9178
|
const result = [];
|
|
9121
9179
|
for (const item of photosWithTags) {
|
|
9122
|
-
const processedUrl = await this.processMedia(
|
|
9123
|
-
item.url,
|
|
9124
|
-
ownerId,
|
|
9125
|
-
collectionName
|
|
9126
|
-
);
|
|
9180
|
+
const processedUrl = await this.processMedia(item.url, ownerId, collectionName);
|
|
9127
9181
|
if (processedUrl) {
|
|
9128
9182
|
result.push({
|
|
9129
9183
|
url: processedUrl,
|
|
@@ -9141,19 +9195,11 @@ var ClinicService = class extends BaseService {
|
|
|
9141
9195
|
try {
|
|
9142
9196
|
const clinicId = this.generateId();
|
|
9143
9197
|
const validatedData = createClinicSchema.parse(data);
|
|
9144
|
-
const group = await this.clinicGroupService.getClinicGroup(
|
|
9145
|
-
validatedData.clinicGroupId
|
|
9146
|
-
);
|
|
9198
|
+
const group = await this.clinicGroupService.getClinicGroup(validatedData.clinicGroupId);
|
|
9147
9199
|
if (!group) {
|
|
9148
|
-
throw new Error(
|
|
9149
|
-
`Clinic group ${validatedData.clinicGroupId} not found`
|
|
9150
|
-
);
|
|
9200
|
+
throw new Error(`Clinic group ${validatedData.clinicGroupId} not found`);
|
|
9151
9201
|
}
|
|
9152
|
-
const logoUrl = await this.processMedia(
|
|
9153
|
-
validatedData.logo,
|
|
9154
|
-
clinicId,
|
|
9155
|
-
"clinic-logos"
|
|
9156
|
-
);
|
|
9202
|
+
const logoUrl = await this.processMedia(validatedData.logo, clinicId, "clinic-logos");
|
|
9157
9203
|
const coverPhotoUrl = await this.processMedia(
|
|
9158
9204
|
validatedData.coverPhoto,
|
|
9159
9205
|
clinicId,
|
|
@@ -9243,11 +9289,7 @@ var ClinicService = class extends BaseService {
|
|
|
9243
9289
|
const validatedData = updateClinicSchema.parse(data);
|
|
9244
9290
|
const updatePayload = {};
|
|
9245
9291
|
if (validatedData.logo !== void 0) {
|
|
9246
|
-
updatePayload.logo = await this.processMedia(
|
|
9247
|
-
validatedData.logo,
|
|
9248
|
-
clinicId,
|
|
9249
|
-
"clinic-logos"
|
|
9250
|
-
);
|
|
9292
|
+
updatePayload.logo = await this.processMedia(validatedData.logo, clinicId, "clinic-logos");
|
|
9251
9293
|
}
|
|
9252
9294
|
if (validatedData.coverPhoto !== void 0) {
|
|
9253
9295
|
updatePayload.coverPhoto = await this.processMedia(
|
|
@@ -9347,22 +9389,10 @@ var ClinicService = class extends BaseService {
|
|
|
9347
9389
|
* Pretražuje klinike u određenom radijusu
|
|
9348
9390
|
*/
|
|
9349
9391
|
async findClinicsInRadius(center, radiusInKm, filters) {
|
|
9350
|
-
return findClinicsInRadius(
|
|
9351
|
-
this.db,
|
|
9352
|
-
center,
|
|
9353
|
-
radiusInKm,
|
|
9354
|
-
filters
|
|
9355
|
-
);
|
|
9392
|
+
return findClinicsInRadius(this.db, center, radiusInKm, filters);
|
|
9356
9393
|
}
|
|
9357
9394
|
async addTags(clinicId, adminId, newTags) {
|
|
9358
|
-
return addTags(
|
|
9359
|
-
this.db,
|
|
9360
|
-
clinicId,
|
|
9361
|
-
adminId,
|
|
9362
|
-
newTags,
|
|
9363
|
-
this.clinicAdminService,
|
|
9364
|
-
this.app
|
|
9365
|
-
);
|
|
9395
|
+
return addTags(this.db, clinicId, adminId, newTags, this.clinicAdminService, this.app);
|
|
9366
9396
|
}
|
|
9367
9397
|
async removeTags(clinicId, adminId, tagsToRemove) {
|
|
9368
9398
|
return removeTags(
|
|
@@ -9400,9 +9430,7 @@ var ClinicService = class extends BaseService {
|
|
|
9400
9430
|
clinicGroupId,
|
|
9401
9431
|
adminId
|
|
9402
9432
|
});
|
|
9403
|
-
const clinicGroup = await this.clinicGroupService.getClinicGroup(
|
|
9404
|
-
clinicGroupId
|
|
9405
|
-
);
|
|
9433
|
+
const clinicGroup = await this.clinicGroupService.getClinicGroup(clinicGroupId);
|
|
9406
9434
|
if (!clinicGroup) {
|
|
9407
9435
|
console.error("[CLINIC_SERVICE] Clinic group not found", {
|
|
9408
9436
|
clinicGroupId
|
|
@@ -9448,13 +9476,7 @@ var ClinicService = class extends BaseService {
|
|
|
9448
9476
|
return getAllClinics(this.db, pagination, lastDoc);
|
|
9449
9477
|
}
|
|
9450
9478
|
async getAllClinicsInRange(center, rangeInKm, pagination, lastDoc) {
|
|
9451
|
-
return getAllClinicsInRange(
|
|
9452
|
-
this.db,
|
|
9453
|
-
center,
|
|
9454
|
-
rangeInKm,
|
|
9455
|
-
pagination,
|
|
9456
|
-
lastDoc
|
|
9457
|
-
);
|
|
9479
|
+
return getAllClinicsInRange(this.db, center, rangeInKm, pagination, lastDoc);
|
|
9458
9480
|
}
|
|
9459
9481
|
/**
|
|
9460
9482
|
* Get clinics based on multiple filtering criteria
|
|
@@ -14886,7 +14908,7 @@ var procedureSchema = createProcedureSchema.extend({
|
|
|
14886
14908
|
});
|
|
14887
14909
|
|
|
14888
14910
|
// src/services/procedure/procedure.service.ts
|
|
14889
|
-
import { distanceBetween as distanceBetween6 } from "geofire-common";
|
|
14911
|
+
import { distanceBetween as distanceBetween6, geohashQueryBounds as geohashQueryBounds5 } from "geofire-common";
|
|
14890
14912
|
var ProcedureService = class extends BaseService {
|
|
14891
14913
|
constructor(db, auth, app, categoryService, subcategoryService, technologyService, productService, mediaService) {
|
|
14892
14914
|
super(db, auth, app);
|
|
@@ -14909,9 +14931,7 @@ var ProcedureService = class extends BaseService {
|
|
|
14909
14931
|
return media;
|
|
14910
14932
|
}
|
|
14911
14933
|
if (media instanceof File || media instanceof Blob) {
|
|
14912
|
-
console.log(
|
|
14913
|
-
`[ProcedureService] Uploading ${collectionName} media for ${ownerId}`
|
|
14914
|
-
);
|
|
14934
|
+
console.log(`[ProcedureService] Uploading ${collectionName} media for ${ownerId}`);
|
|
14915
14935
|
const metadata = await this.mediaService.uploadMedia(
|
|
14916
14936
|
media,
|
|
14917
14937
|
ownerId,
|
|
@@ -14933,11 +14953,7 @@ var ProcedureService = class extends BaseService {
|
|
|
14933
14953
|
if (!mediaArray || mediaArray.length === 0) return [];
|
|
14934
14954
|
const result = [];
|
|
14935
14955
|
for (const media of mediaArray) {
|
|
14936
|
-
const processedUrl = await this.processMedia(
|
|
14937
|
-
media,
|
|
14938
|
-
ownerId,
|
|
14939
|
-
collectionName
|
|
14940
|
-
);
|
|
14956
|
+
const processedUrl = await this.processMedia(media, ownerId, collectionName);
|
|
14941
14957
|
if (processedUrl) {
|
|
14942
14958
|
result.push(processedUrl);
|
|
14943
14959
|
}
|
|
@@ -14955,41 +14971,23 @@ var ProcedureService = class extends BaseService {
|
|
|
14955
14971
|
const procedureId = this.generateId();
|
|
14956
14972
|
const [category, subcategory, technology, product] = await Promise.all([
|
|
14957
14973
|
this.categoryService.getById(validatedData.categoryId),
|
|
14958
|
-
this.subcategoryService.getById(
|
|
14959
|
-
validatedData.categoryId,
|
|
14960
|
-
validatedData.subcategoryId
|
|
14961
|
-
),
|
|
14974
|
+
this.subcategoryService.getById(validatedData.categoryId, validatedData.subcategoryId),
|
|
14962
14975
|
this.technologyService.getById(validatedData.technologyId),
|
|
14963
|
-
this.productService.getById(
|
|
14964
|
-
validatedData.technologyId,
|
|
14965
|
-
validatedData.productId
|
|
14966
|
-
)
|
|
14976
|
+
this.productService.getById(validatedData.technologyId, validatedData.productId)
|
|
14967
14977
|
]);
|
|
14968
14978
|
if (!category || !subcategory || !technology || !product) {
|
|
14969
14979
|
throw new Error("One or more required base entities not found");
|
|
14970
14980
|
}
|
|
14971
|
-
const clinicRef = doc30(
|
|
14972
|
-
this.db,
|
|
14973
|
-
CLINICS_COLLECTION,
|
|
14974
|
-
validatedData.clinicBranchId
|
|
14975
|
-
);
|
|
14981
|
+
const clinicRef = doc30(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId);
|
|
14976
14982
|
const clinicSnapshot = await getDoc32(clinicRef);
|
|
14977
14983
|
if (!clinicSnapshot.exists()) {
|
|
14978
|
-
throw new Error(
|
|
14979
|
-
`Clinic with ID ${validatedData.clinicBranchId} not found`
|
|
14980
|
-
);
|
|
14984
|
+
throw new Error(`Clinic with ID ${validatedData.clinicBranchId} not found`);
|
|
14981
14985
|
}
|
|
14982
14986
|
const clinic = clinicSnapshot.data();
|
|
14983
|
-
const practitionerRef = doc30(
|
|
14984
|
-
this.db,
|
|
14985
|
-
PRACTITIONERS_COLLECTION,
|
|
14986
|
-
validatedData.practitionerId
|
|
14987
|
-
);
|
|
14987
|
+
const practitionerRef = doc30(this.db, PRACTITIONERS_COLLECTION, validatedData.practitionerId);
|
|
14988
14988
|
const practitionerSnapshot = await getDoc32(practitionerRef);
|
|
14989
14989
|
if (!practitionerSnapshot.exists()) {
|
|
14990
|
-
throw new Error(
|
|
14991
|
-
`Practitioner with ID ${validatedData.practitionerId} not found`
|
|
14992
|
-
);
|
|
14990
|
+
throw new Error(`Practitioner with ID ${validatedData.practitionerId} not found`);
|
|
14993
14991
|
}
|
|
14994
14992
|
const practitioner = practitionerSnapshot.data();
|
|
14995
14993
|
let processedPhotos = [];
|
|
@@ -15078,24 +15076,16 @@ var ProcedureService = class extends BaseService {
|
|
|
15078
15076
|
const validatedData = createProcedureSchema.parse(validationData);
|
|
15079
15077
|
const [category, subcategory, technology, product, clinicSnapshot] = await Promise.all([
|
|
15080
15078
|
this.categoryService.getById(validatedData.categoryId),
|
|
15081
|
-
this.subcategoryService.getById(
|
|
15082
|
-
validatedData.categoryId,
|
|
15083
|
-
validatedData.subcategoryId
|
|
15084
|
-
),
|
|
15079
|
+
this.subcategoryService.getById(validatedData.categoryId, validatedData.subcategoryId),
|
|
15085
15080
|
this.technologyService.getById(validatedData.technologyId),
|
|
15086
|
-
this.productService.getById(
|
|
15087
|
-
validatedData.technologyId,
|
|
15088
|
-
validatedData.productId
|
|
15089
|
-
),
|
|
15081
|
+
this.productService.getById(validatedData.technologyId, validatedData.productId),
|
|
15090
15082
|
getDoc32(doc30(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId))
|
|
15091
15083
|
]);
|
|
15092
15084
|
if (!category || !subcategory || !technology || !product) {
|
|
15093
15085
|
throw new Error("One or more required base entities not found");
|
|
15094
15086
|
}
|
|
15095
15087
|
if (!clinicSnapshot.exists()) {
|
|
15096
|
-
throw new Error(
|
|
15097
|
-
`Clinic with ID ${validatedData.clinicBranchId} not found`
|
|
15098
|
-
);
|
|
15088
|
+
throw new Error(`Clinic with ID ${validatedData.clinicBranchId} not found`);
|
|
15099
15089
|
}
|
|
15100
15090
|
const clinic = clinicSnapshot.data();
|
|
15101
15091
|
let processedPhotos = [];
|
|
@@ -15121,12 +15111,8 @@ var ProcedureService = class extends BaseService {
|
|
|
15121
15111
|
}
|
|
15122
15112
|
if (practitionersMap.size !== practitionerIds.length) {
|
|
15123
15113
|
const foundIds = Array.from(practitionersMap.keys());
|
|
15124
|
-
const notFoundIds = practitionerIds.filter(
|
|
15125
|
-
|
|
15126
|
-
);
|
|
15127
|
-
throw new Error(
|
|
15128
|
-
`The following practitioners were not found: ${notFoundIds.join(", ")}`
|
|
15129
|
-
);
|
|
15114
|
+
const notFoundIds = practitionerIds.filter((id) => !foundIds.includes(id));
|
|
15115
|
+
throw new Error(`The following practitioners were not found: ${notFoundIds.join(", ")}`);
|
|
15130
15116
|
}
|
|
15131
15117
|
const batch = writeBatch6(this.db);
|
|
15132
15118
|
const createdProcedureIds = [];
|
|
@@ -15194,10 +15180,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15194
15180
|
const fetchedProcedures = [];
|
|
15195
15181
|
for (let i = 0; i < createdProcedureIds.length; i += 30) {
|
|
15196
15182
|
const chunk = createdProcedureIds.slice(i, i + 30);
|
|
15197
|
-
const q = query29(
|
|
15198
|
-
collection29(this.db, PROCEDURES_COLLECTION),
|
|
15199
|
-
where29(documentId2(), "in", chunk)
|
|
15200
|
-
);
|
|
15183
|
+
const q = query29(collection29(this.db, PROCEDURES_COLLECTION), where29(documentId2(), "in", chunk));
|
|
15201
15184
|
const snapshot = await getDocs29(q);
|
|
15202
15185
|
snapshot.forEach((doc37) => {
|
|
15203
15186
|
fetchedProcedures.push(doc37.data());
|
|
@@ -15298,9 +15281,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15298
15281
|
);
|
|
15299
15282
|
const newPractitionerSnap = await getDoc32(newPractitionerRef);
|
|
15300
15283
|
if (!newPractitionerSnap.exists())
|
|
15301
|
-
throw new Error(
|
|
15302
|
-
`New Practitioner ${validatedData.practitionerId} not found`
|
|
15303
|
-
);
|
|
15284
|
+
throw new Error(`New Practitioner ${validatedData.practitionerId} not found`);
|
|
15304
15285
|
newPractitioner = newPractitionerSnap.data();
|
|
15305
15286
|
updatedProcedureData.doctorInfo = {
|
|
15306
15287
|
id: newPractitioner.id,
|
|
@@ -15314,11 +15295,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15314
15295
|
}
|
|
15315
15296
|
if (validatedData.clinicBranchId && validatedData.clinicBranchId !== oldClinicId) {
|
|
15316
15297
|
clinicChanged = true;
|
|
15317
|
-
const newClinicRef = doc30(
|
|
15318
|
-
this.db,
|
|
15319
|
-
CLINICS_COLLECTION,
|
|
15320
|
-
validatedData.clinicBranchId
|
|
15321
|
-
);
|
|
15298
|
+
const newClinicRef = doc30(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId);
|
|
15322
15299
|
const newClinicSnap = await getDoc32(newClinicRef);
|
|
15323
15300
|
if (!newClinicSnap.exists())
|
|
15324
15301
|
throw new Error(`New Clinic ${validatedData.clinicBranchId} not found`);
|
|
@@ -15337,11 +15314,8 @@ var ProcedureService = class extends BaseService {
|
|
|
15337
15314
|
updatedProcedureData.nameLower = validatedData.name.toLowerCase();
|
|
15338
15315
|
}
|
|
15339
15316
|
if (validatedData.categoryId) {
|
|
15340
|
-
const category = await this.categoryService.getById(
|
|
15341
|
-
|
|
15342
|
-
);
|
|
15343
|
-
if (!category)
|
|
15344
|
-
throw new Error(`Category ${validatedData.categoryId} not found`);
|
|
15317
|
+
const category = await this.categoryService.getById(validatedData.categoryId);
|
|
15318
|
+
if (!category) throw new Error(`Category ${validatedData.categoryId} not found`);
|
|
15345
15319
|
updatedProcedureData.category = category;
|
|
15346
15320
|
finalCategoryId = category.id;
|
|
15347
15321
|
}
|
|
@@ -15356,17 +15330,12 @@ var ProcedureService = class extends BaseService {
|
|
|
15356
15330
|
);
|
|
15357
15331
|
updatedProcedureData.subcategory = subcategory;
|
|
15358
15332
|
} else if (validatedData.subcategoryId) {
|
|
15359
|
-
console.warn(
|
|
15360
|
-
"Attempted to update subcategory without a valid categoryId"
|
|
15361
|
-
);
|
|
15333
|
+
console.warn("Attempted to update subcategory without a valid categoryId");
|
|
15362
15334
|
}
|
|
15363
15335
|
let finalTechnologyId = existingProcedure.technology.id;
|
|
15364
15336
|
if (validatedData.technologyId) {
|
|
15365
|
-
const technology = await this.technologyService.getById(
|
|
15366
|
-
|
|
15367
|
-
);
|
|
15368
|
-
if (!technology)
|
|
15369
|
-
throw new Error(`Technology ${validatedData.technologyId} not found`);
|
|
15337
|
+
const technology = await this.technologyService.getById(validatedData.technologyId);
|
|
15338
|
+
if (!technology) throw new Error(`Technology ${validatedData.technologyId} not found`);
|
|
15370
15339
|
updatedProcedureData.technology = technology;
|
|
15371
15340
|
finalTechnologyId = technology.id;
|
|
15372
15341
|
updatedProcedureData.blockingConditions = technology.blockingConditions;
|
|
@@ -15377,10 +15346,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15377
15346
|
updatedProcedureData.documentationTemplates = technology.documentationTemplates || [];
|
|
15378
15347
|
}
|
|
15379
15348
|
if (validatedData.productId && finalTechnologyId) {
|
|
15380
|
-
const product = await this.productService.getById(
|
|
15381
|
-
finalTechnologyId,
|
|
15382
|
-
validatedData.productId
|
|
15383
|
-
);
|
|
15349
|
+
const product = await this.productService.getById(finalTechnologyId, validatedData.productId);
|
|
15384
15350
|
if (!product)
|
|
15385
15351
|
throw new Error(
|
|
15386
15352
|
`Product ${validatedData.productId} not found for technology ${finalTechnologyId}`
|
|
@@ -15462,11 +15428,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15462
15428
|
limit16(pagination)
|
|
15463
15429
|
);
|
|
15464
15430
|
} else {
|
|
15465
|
-
proceduresQuery = query29(
|
|
15466
|
-
proceduresCollection,
|
|
15467
|
-
orderBy17("name"),
|
|
15468
|
-
limit16(pagination)
|
|
15469
|
-
);
|
|
15431
|
+
proceduresQuery = query29(proceduresCollection, orderBy17("name"), limit16(pagination));
|
|
15470
15432
|
}
|
|
15471
15433
|
} else {
|
|
15472
15434
|
proceduresQuery = query29(proceduresCollection, orderBy17("name"));
|
|
@@ -15589,7 +15551,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15589
15551
|
constraints.push(limit15(filters.pagination || 10));
|
|
15590
15552
|
const q = query29(collection29(this.db, PROCEDURES_COLLECTION), ...constraints);
|
|
15591
15553
|
const querySnapshot = await getDocs29(q);
|
|
15592
|
-
const procedures = querySnapshot.docs.map(
|
|
15554
|
+
const procedures = querySnapshot.docs.map(
|
|
15555
|
+
(doc37) => ({ ...doc37.data(), id: doc37.id })
|
|
15556
|
+
);
|
|
15593
15557
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15594
15558
|
console.log(`[PROCEDURE_SERVICE] Strategy 1 success: ${procedures.length} procedures`);
|
|
15595
15559
|
if (procedures.length < (filters.pagination || 10)) {
|
|
@@ -15620,7 +15584,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15620
15584
|
constraints.push(limit15(filters.pagination || 10));
|
|
15621
15585
|
const q = query29(collection29(this.db, PROCEDURES_COLLECTION), ...constraints);
|
|
15622
15586
|
const querySnapshot = await getDocs29(q);
|
|
15623
|
-
const procedures = querySnapshot.docs.map(
|
|
15587
|
+
const procedures = querySnapshot.docs.map(
|
|
15588
|
+
(doc37) => ({ ...doc37.data(), id: doc37.id })
|
|
15589
|
+
);
|
|
15624
15590
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15625
15591
|
console.log(`[PROCEDURE_SERVICE] Strategy 2 success: ${procedures.length} procedures`);
|
|
15626
15592
|
if (procedures.length < (filters.pagination || 10)) {
|
|
@@ -15632,7 +15598,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15632
15598
|
}
|
|
15633
15599
|
}
|
|
15634
15600
|
try {
|
|
15635
|
-
console.log(
|
|
15601
|
+
console.log(
|
|
15602
|
+
"[PROCEDURE_SERVICE] Strategy 3: Using createdAt orderBy with client-side filtering"
|
|
15603
|
+
);
|
|
15636
15604
|
const constraints = getBaseConstraints();
|
|
15637
15605
|
constraints.push(orderBy17("createdAt", "desc"));
|
|
15638
15606
|
if (filters.lastDoc) {
|
|
@@ -15647,7 +15615,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15647
15615
|
constraints.push(limit15(filters.pagination || 10));
|
|
15648
15616
|
const q = query29(collection29(this.db, PROCEDURES_COLLECTION), ...constraints);
|
|
15649
15617
|
const querySnapshot = await getDocs29(q);
|
|
15650
|
-
let procedures = querySnapshot.docs.map(
|
|
15618
|
+
let procedures = querySnapshot.docs.map(
|
|
15619
|
+
(doc37) => ({ ...doc37.data(), id: doc37.id })
|
|
15620
|
+
);
|
|
15651
15621
|
procedures = this.applyInMemoryFilters(procedures, filters);
|
|
15652
15622
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15653
15623
|
console.log(`[PROCEDURE_SERVICE] Strategy 3 success: ${procedures.length} procedures`);
|
|
@@ -15667,7 +15637,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15667
15637
|
];
|
|
15668
15638
|
const q = query29(collection29(this.db, PROCEDURES_COLLECTION), ...constraints);
|
|
15669
15639
|
const querySnapshot = await getDocs29(q);
|
|
15670
|
-
let procedures = querySnapshot.docs.map(
|
|
15640
|
+
let procedures = querySnapshot.docs.map(
|
|
15641
|
+
(doc37) => ({ ...doc37.data(), id: doc37.id })
|
|
15642
|
+
);
|
|
15671
15643
|
procedures = this.applyInMemoryFilters(procedures, filters);
|
|
15672
15644
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15673
15645
|
console.log(`[PROCEDURE_SERVICE] Strategy 4 success: ${procedures.length} procedures`);
|
|
@@ -15707,7 +15679,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15707
15679
|
if (filters.maxPrice !== void 0 && price > filters.maxPrice) return false;
|
|
15708
15680
|
return true;
|
|
15709
15681
|
});
|
|
15710
|
-
console.log(
|
|
15682
|
+
console.log(
|
|
15683
|
+
`[PROCEDURE_SERVICE] Applied price filter (${filters.minPrice}-${filters.maxPrice}), results: ${filteredProcedures.length}`
|
|
15684
|
+
);
|
|
15711
15685
|
}
|
|
15712
15686
|
if (filters.minRating !== void 0 || filters.maxRating !== void 0) {
|
|
15713
15687
|
filteredProcedures = filteredProcedures.filter((procedure) => {
|
|
@@ -15717,7 +15691,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15717
15691
|
if (filters.maxRating !== void 0 && rating > filters.maxRating) return false;
|
|
15718
15692
|
return true;
|
|
15719
15693
|
});
|
|
15720
|
-
console.log(
|
|
15694
|
+
console.log(
|
|
15695
|
+
`[PROCEDURE_SERVICE] Applied rating filter, results: ${filteredProcedures.length}`
|
|
15696
|
+
);
|
|
15721
15697
|
}
|
|
15722
15698
|
if (filters.treatmentBenefits && filters.treatmentBenefits.length > 0) {
|
|
15723
15699
|
const benefitsToMatch = filters.treatmentBenefits;
|
|
@@ -15725,32 +15701,50 @@ var ProcedureService = class extends BaseService {
|
|
|
15725
15701
|
const procedureBenefits = procedure.treatmentBenefits || [];
|
|
15726
15702
|
return benefitsToMatch.some((benefit) => procedureBenefits.includes(benefit));
|
|
15727
15703
|
});
|
|
15728
|
-
console.log(
|
|
15704
|
+
console.log(
|
|
15705
|
+
`[PROCEDURE_SERVICE] Applied benefits filter, results: ${filteredProcedures.length}`
|
|
15706
|
+
);
|
|
15729
15707
|
}
|
|
15730
15708
|
if (filters.procedureFamily) {
|
|
15731
|
-
filteredProcedures = filteredProcedures.filter(
|
|
15732
|
-
|
|
15709
|
+
filteredProcedures = filteredProcedures.filter(
|
|
15710
|
+
(procedure) => procedure.family === filters.procedureFamily
|
|
15711
|
+
);
|
|
15712
|
+
console.log(
|
|
15713
|
+
`[PROCEDURE_SERVICE] Applied family filter, results: ${filteredProcedures.length}`
|
|
15714
|
+
);
|
|
15733
15715
|
}
|
|
15734
15716
|
if (filters.procedureCategory) {
|
|
15735
|
-
filteredProcedures = filteredProcedures.filter(
|
|
15736
|
-
|
|
15737
|
-
|
|
15738
|
-
|
|
15739
|
-
|
|
15717
|
+
filteredProcedures = filteredProcedures.filter(
|
|
15718
|
+
(procedure) => {
|
|
15719
|
+
var _a;
|
|
15720
|
+
return ((_a = procedure.category) == null ? void 0 : _a.id) === filters.procedureCategory;
|
|
15721
|
+
}
|
|
15722
|
+
);
|
|
15723
|
+
console.log(
|
|
15724
|
+
`[PROCEDURE_SERVICE] Applied category filter, results: ${filteredProcedures.length}`
|
|
15725
|
+
);
|
|
15740
15726
|
}
|
|
15741
15727
|
if (filters.procedureSubcategory) {
|
|
15742
|
-
filteredProcedures = filteredProcedures.filter(
|
|
15743
|
-
|
|
15744
|
-
|
|
15745
|
-
|
|
15746
|
-
|
|
15728
|
+
filteredProcedures = filteredProcedures.filter(
|
|
15729
|
+
(procedure) => {
|
|
15730
|
+
var _a;
|
|
15731
|
+
return ((_a = procedure.subcategory) == null ? void 0 : _a.id) === filters.procedureSubcategory;
|
|
15732
|
+
}
|
|
15733
|
+
);
|
|
15734
|
+
console.log(
|
|
15735
|
+
`[PROCEDURE_SERVICE] Applied subcategory filter, results: ${filteredProcedures.length}`
|
|
15736
|
+
);
|
|
15747
15737
|
}
|
|
15748
15738
|
if (filters.procedureTechnology) {
|
|
15749
|
-
filteredProcedures = filteredProcedures.filter(
|
|
15750
|
-
|
|
15751
|
-
|
|
15752
|
-
|
|
15753
|
-
|
|
15739
|
+
filteredProcedures = filteredProcedures.filter(
|
|
15740
|
+
(procedure) => {
|
|
15741
|
+
var _a;
|
|
15742
|
+
return ((_a = procedure.technology) == null ? void 0 : _a.id) === filters.procedureTechnology;
|
|
15743
|
+
}
|
|
15744
|
+
);
|
|
15745
|
+
console.log(
|
|
15746
|
+
`[PROCEDURE_SERVICE] Applied technology filter, results: ${filteredProcedures.length}`
|
|
15747
|
+
);
|
|
15754
15748
|
}
|
|
15755
15749
|
if (filters.location && filters.radiusInKm && filters.radiusInKm > 0) {
|
|
15756
15750
|
const location = filters.location;
|
|
@@ -15774,29 +15768,48 @@ var ProcedureService = class extends BaseService {
|
|
|
15774
15768
|
return filteredProcedures;
|
|
15775
15769
|
}
|
|
15776
15770
|
handleGeoQuery(filters) {
|
|
15777
|
-
console.log("[PROCEDURE_SERVICE] Executing geo query with
|
|
15771
|
+
console.log("[PROCEDURE_SERVICE] Executing geo query with geohash bounds");
|
|
15778
15772
|
try {
|
|
15779
15773
|
const location = filters.location;
|
|
15780
15774
|
const radiusInKm = filters.radiusInKm;
|
|
15781
|
-
|
|
15782
|
-
|
|
15783
|
-
|
|
15784
|
-
|
|
15785
|
-
|
|
15775
|
+
if (!location || !radiusInKm) {
|
|
15776
|
+
return Promise.resolve({ procedures: [], lastDoc: null });
|
|
15777
|
+
}
|
|
15778
|
+
const bounds = geohashQueryBounds5([location.latitude, location.longitude], radiusInKm * 1e3);
|
|
15779
|
+
const fetches = bounds.map((b) => {
|
|
15780
|
+
const constraints = [
|
|
15781
|
+
where29("clinicInfo.location.geohash", ">=", b[0]),
|
|
15782
|
+
where29("clinicInfo.location.geohash", "<=", b[1]),
|
|
15783
|
+
where29("isActive", "==", filters.isActive !== void 0 ? filters.isActive : true)
|
|
15784
|
+
];
|
|
15785
|
+
return getDocs29(query29(collection29(this.db, PROCEDURES_COLLECTION), ...constraints));
|
|
15786
15786
|
});
|
|
15787
|
-
|
|
15788
|
-
|
|
15789
|
-
|
|
15790
|
-
|
|
15791
|
-
|
|
15792
|
-
|
|
15793
|
-
|
|
15794
|
-
|
|
15795
|
-
|
|
15787
|
+
return Promise.all(fetches).then((snaps) => {
|
|
15788
|
+
const collected = [];
|
|
15789
|
+
snaps.forEach((snap) => {
|
|
15790
|
+
snap.docs.forEach((d) => collected.push({ ...d.data(), id: d.id }));
|
|
15791
|
+
});
|
|
15792
|
+
const uniqueMap = /* @__PURE__ */ new Map();
|
|
15793
|
+
for (const p of collected) {
|
|
15794
|
+
uniqueMap.set(p.id, p);
|
|
15795
|
+
}
|
|
15796
|
+
let procedures = Array.from(uniqueMap.values());
|
|
15796
15797
|
procedures = this.applyInMemoryFilters(procedures, filters);
|
|
15797
|
-
|
|
15798
|
-
|
|
15799
|
-
|
|
15798
|
+
const pageSize = filters.pagination || 10;
|
|
15799
|
+
let startIndex = 0;
|
|
15800
|
+
if (filters.lastDoc && typeof filters.lastDoc === "object" && filters.lastDoc.id) {
|
|
15801
|
+
const idx = procedures.findIndex((p) => p.id === filters.lastDoc.id);
|
|
15802
|
+
if (idx >= 0) startIndex = idx + 1;
|
|
15803
|
+
}
|
|
15804
|
+
const page = procedures.slice(startIndex, startIndex + pageSize);
|
|
15805
|
+
const newLastDoc = page.length === pageSize ? page[page.length - 1] : null;
|
|
15806
|
+
console.log(
|
|
15807
|
+
`[PROCEDURE_SERVICE] Geo query success: ${page.length} (of ${procedures.length}) within ${radiusInKm}km`
|
|
15808
|
+
);
|
|
15809
|
+
return { procedures: page, lastDoc: newLastDoc };
|
|
15810
|
+
}).catch((err) => {
|
|
15811
|
+
console.error("[PROCEDURE_SERVICE] Geo bounds fetch failed:", err);
|
|
15812
|
+
return { procedures: [], lastDoc: null };
|
|
15800
15813
|
});
|
|
15801
15814
|
} catch (error) {
|
|
15802
15815
|
console.error("[PROCEDURE_SERVICE] Geo query failed:", error);
|
|
@@ -15826,11 +15839,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15826
15839
|
throw new Error(`Clinic with ID ${data.clinicBranchId} not found`);
|
|
15827
15840
|
}
|
|
15828
15841
|
const clinic = clinicSnapshot.data();
|
|
15829
|
-
const practitionerRef = doc30(
|
|
15830
|
-
this.db,
|
|
15831
|
-
PRACTITIONERS_COLLECTION,
|
|
15832
|
-
data.practitionerId
|
|
15833
|
-
);
|
|
15842
|
+
const practitionerRef = doc30(this.db, PRACTITIONERS_COLLECTION, data.practitionerId);
|
|
15834
15843
|
const practitionerSnapshot = await getDoc32(practitionerRef);
|
|
15835
15844
|
if (!practitionerSnapshot.exists()) {
|
|
15836
15845
|
throw new Error(`Practitioner with ID ${data.practitionerId} not found`);
|
|
@@ -15838,11 +15847,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15838
15847
|
const practitioner = practitionerSnapshot.data();
|
|
15839
15848
|
let processedPhotos = [];
|
|
15840
15849
|
if (data.photos && data.photos.length > 0) {
|
|
15841
|
-
processedPhotos = await this.processMediaArray(
|
|
15842
|
-
data.photos,
|
|
15843
|
-
procedureId,
|
|
15844
|
-
"procedure-photos"
|
|
15845
|
-
);
|
|
15850
|
+
processedPhotos = await this.processMediaArray(data.photos, procedureId, "procedure-photos");
|
|
15846
15851
|
}
|
|
15847
15852
|
const clinicInfo = {
|
|
15848
15853
|
id: clinicSnapshot.id,
|