@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.js CHANGED
@@ -8710,6 +8710,7 @@ async function findClinicsInRadius(db, center, radiusInKm, filters) {
8710
8710
  var import_firestore26 = require("firebase/firestore");
8711
8711
  var import_geofire_common6 = require("geofire-common");
8712
8712
  async function getClinicsByFilters(db, filters) {
8713
+ var _a;
8713
8714
  try {
8714
8715
  console.log("[CLINIC_SERVICE] Starting clinic filtering with multiple strategies");
8715
8716
  if (filters.center && filters.radiusInKm) {
@@ -8724,10 +8725,53 @@ async function getClinicsByFilters(db, filters) {
8724
8725
  filters.radiusInKm = void 0;
8725
8726
  }
8726
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
+ }
8727
8771
  const getBaseConstraints = () => {
8728
- var _a;
8772
+ var _a2;
8729
8773
  const constraints = [];
8730
- constraints.push((0, import_firestore26.where)("isActive", "==", (_a = filters.isActive) != null ? _a : true));
8774
+ constraints.push((0, import_firestore26.where)("isActive", "==", (_a2 = filters.isActive) != null ? _a2 : true));
8731
8775
  if (filters.tags && filters.tags.length > 0) {
8732
8776
  constraints.push((0, import_firestore26.where)("tags", "array-contains", filters.tags[0]));
8733
8777
  }
@@ -8804,7 +8848,9 @@ async function getClinicsByFilters(db, filters) {
8804
8848
  }
8805
8849
  }
8806
8850
  try {
8807
- console.log("[CLINIC_SERVICE] Strategy 3: Using createdAt ordering with client-side filtering");
8851
+ console.log(
8852
+ "[CLINIC_SERVICE] Strategy 3: Using createdAt ordering with client-side filtering"
8853
+ );
8808
8854
  const constraints = getBaseConstraints();
8809
8855
  constraints.push((0, import_firestore26.orderBy)("createdAt", "desc"));
8810
8856
  if (filters.lastDoc) {
@@ -8859,20 +8905,24 @@ async function getClinicsByFilters(db, filters) {
8859
8905
  }
8860
8906
  function applyInMemoryFilters(clinics, filters) {
8861
8907
  let filteredClinics = [...clinics];
8862
- console.log(`[CLINIC_SERVICE] Applying in-memory filters - input: ${filteredClinics.length} clinics`);
8908
+ console.log(
8909
+ `[CLINIC_SERVICE] Applying in-memory filters - input: ${filteredClinics.length} clinics`
8910
+ );
8863
8911
  if (filters.tags && filters.tags.length > 1) {
8864
8912
  const initialCount = filteredClinics.length;
8865
8913
  filteredClinics = filteredClinics.filter(
8866
8914
  (clinic) => filters.tags.every((tag) => clinic.tags.includes(tag))
8867
8915
  );
8868
- console.log(`[CLINIC_SERVICE] Applied multi-tag filter: ${initialCount} \u2192 ${filteredClinics.length}`);
8916
+ console.log(
8917
+ `[CLINIC_SERVICE] Applied multi-tag filter: ${initialCount} \u2192 ${filteredClinics.length}`
8918
+ );
8869
8919
  }
8870
8920
  if (filters.tags && filters.tags.length === 1) {
8871
8921
  const initialCount = filteredClinics.length;
8872
- filteredClinics = filteredClinics.filter(
8873
- (clinic) => clinic.tags.includes(filters.tags[0])
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}`
8874
8925
  );
8875
- console.log(`[CLINIC_SERVICE] Applied single-tag filter: ${initialCount} \u2192 ${filteredClinics.length}`);
8876
8926
  }
8877
8927
  if (filters.minRating !== void 0 || filters.maxRating !== void 0) {
8878
8928
  const initialCount = filteredClinics.length;
@@ -8883,7 +8933,9 @@ function applyInMemoryFilters(clinics, filters) {
8883
8933
  if (filters.maxRating !== void 0 && rating > filters.maxRating) return false;
8884
8934
  return true;
8885
8935
  });
8886
- console.log(`[CLINIC_SERVICE] Applied rating filter (${filters.minRating}-${filters.maxRating}): ${initialCount} \u2192 ${filteredClinics.length}`);
8936
+ console.log(
8937
+ `[CLINIC_SERVICE] Applied rating filter (${filters.minRating}-${filters.maxRating}): ${initialCount} \u2192 ${filteredClinics.length}`
8938
+ );
8887
8939
  }
8888
8940
  if (filters.nameSearch && filters.nameSearch.trim()) {
8889
8941
  const initialCount = filteredClinics.length;
@@ -8893,7 +8945,9 @@ function applyInMemoryFilters(clinics, filters) {
8893
8945
  const nameLower = clinic.nameLower || "";
8894
8946
  return name.includes(searchTerm) || nameLower.includes(searchTerm);
8895
8947
  });
8896
- console.log(`[CLINIC_SERVICE] Applied name search filter: ${initialCount} \u2192 ${filteredClinics.length}`);
8948
+ console.log(
8949
+ `[CLINIC_SERVICE] Applied name search filter: ${initialCount} \u2192 ${filteredClinics.length}`
8950
+ );
8897
8951
  }
8898
8952
  if (filters.procedureFamily) {
8899
8953
  const initialCount = filteredClinics.length;
@@ -8901,7 +8955,9 @@ function applyInMemoryFilters(clinics, filters) {
8901
8955
  const proceduresInfo = clinic.proceduresInfo || [];
8902
8956
  return proceduresInfo.some((proc) => proc.family === filters.procedureFamily);
8903
8957
  });
8904
- console.log(`[CLINIC_SERVICE] Applied procedure family filter: ${initialCount} \u2192 ${filteredClinics.length}`);
8958
+ console.log(
8959
+ `[CLINIC_SERVICE] Applied procedure family filter: ${initialCount} \u2192 ${filteredClinics.length}`
8960
+ );
8905
8961
  }
8906
8962
  if (filters.procedureCategory) {
8907
8963
  const initialCount = filteredClinics.length;
@@ -8909,7 +8965,9 @@ function applyInMemoryFilters(clinics, filters) {
8909
8965
  const proceduresInfo = clinic.proceduresInfo || [];
8910
8966
  return proceduresInfo.some((proc) => proc.categoryName === filters.procedureCategory);
8911
8967
  });
8912
- console.log(`[CLINIC_SERVICE] Applied procedure category filter: ${initialCount} \u2192 ${filteredClinics.length}`);
8968
+ console.log(
8969
+ `[CLINIC_SERVICE] Applied procedure category filter: ${initialCount} \u2192 ${filteredClinics.length}`
8970
+ );
8913
8971
  }
8914
8972
  if (filters.procedureSubcategory) {
8915
8973
  const initialCount = filteredClinics.length;
@@ -8917,7 +8975,9 @@ function applyInMemoryFilters(clinics, filters) {
8917
8975
  const proceduresInfo = clinic.proceduresInfo || [];
8918
8976
  return proceduresInfo.some((proc) => proc.subcategoryName === filters.procedureSubcategory);
8919
8977
  });
8920
- console.log(`[CLINIC_SERVICE] Applied procedure subcategory filter: ${initialCount} \u2192 ${filteredClinics.length}`);
8978
+ console.log(
8979
+ `[CLINIC_SERVICE] Applied procedure subcategory filter: ${initialCount} \u2192 ${filteredClinics.length}`
8980
+ );
8921
8981
  }
8922
8982
  if (filters.procedureTechnology) {
8923
8983
  const initialCount = filteredClinics.length;
@@ -8925,7 +8985,9 @@ function applyInMemoryFilters(clinics, filters) {
8925
8985
  const proceduresInfo = clinic.proceduresInfo || [];
8926
8986
  return proceduresInfo.some((proc) => proc.technologyName === filters.procedureTechnology);
8927
8987
  });
8928
- console.log(`[CLINIC_SERVICE] Applied procedure technology filter: ${initialCount} \u2192 ${filteredClinics.length}`);
8988
+ console.log(
8989
+ `[CLINIC_SERVICE] Applied procedure technology filter: ${initialCount} \u2192 ${filteredClinics.length}`
8990
+ );
8929
8991
  }
8930
8992
  if (filters.center && filters.radiusInKm) {
8931
8993
  const initialCount = filteredClinics.length;
@@ -8939,11 +9001,15 @@ function applyInMemoryFilters(clinics, filters) {
8939
9001
  [filters.center.latitude, filters.center.longitude],
8940
9002
  [clinic.location.latitude, clinic.location.longitude]
8941
9003
  ) / 1e3;
8942
- console.log(`[CLINIC_SERVICE] Clinic ${clinic.name}: distance ${distance.toFixed(2)}km (limit: ${filters.radiusInKm}km)`);
9004
+ console.log(
9005
+ `[CLINIC_SERVICE] Clinic ${clinic.name}: distance ${distance.toFixed(2)}km (limit: ${filters.radiusInKm}km)`
9006
+ );
8943
9007
  clinic.distance = distance;
8944
9008
  return distance <= filters.radiusInKm;
8945
9009
  });
8946
- console.log(`[CLINIC_SERVICE] Applied geo filter (${filters.radiusInKm}km): ${initialCount} \u2192 ${filteredClinics.length}`);
9010
+ console.log(
9011
+ `[CLINIC_SERVICE] Applied geo filter (${filters.radiusInKm}km): ${initialCount} \u2192 ${filteredClinics.length}`
9012
+ );
8947
9013
  filteredClinics.sort((a, b) => (a.distance || 0) - (b.distance || 0));
8948
9014
  }
8949
9015
  console.log(`[CLINIC_SERVICE] Final filtered result: ${filteredClinics.length} clinics`);
@@ -8971,9 +9037,7 @@ var ClinicService = class extends BaseService {
8971
9037
  return media;
8972
9038
  }
8973
9039
  if (media instanceof File || media instanceof Blob) {
8974
- console.log(
8975
- `[ClinicService] Uploading ${collectionName} media for ${ownerId}`
8976
- );
9040
+ console.log(`[ClinicService] Uploading ${collectionName} media for ${ownerId}`);
8977
9041
  const metadata = await this.mediaService.uploadMedia(
8978
9042
  media,
8979
9043
  ownerId,
@@ -8995,11 +9059,7 @@ var ClinicService = class extends BaseService {
8995
9059
  if (!mediaArray || mediaArray.length === 0) return [];
8996
9060
  const result = [];
8997
9061
  for (const media of mediaArray) {
8998
- const processedUrl = await this.processMedia(
8999
- media,
9000
- ownerId,
9001
- collectionName
9002
- );
9062
+ const processedUrl = await this.processMedia(media, ownerId, collectionName);
9003
9063
  if (processedUrl) {
9004
9064
  result.push(processedUrl);
9005
9065
  }
@@ -9017,11 +9077,7 @@ var ClinicService = class extends BaseService {
9017
9077
  if (!photosWithTags || photosWithTags.length === 0) return [];
9018
9078
  const result = [];
9019
9079
  for (const item of photosWithTags) {
9020
- const processedUrl = await this.processMedia(
9021
- item.url,
9022
- ownerId,
9023
- collectionName
9024
- );
9080
+ const processedUrl = await this.processMedia(item.url, ownerId, collectionName);
9025
9081
  if (processedUrl) {
9026
9082
  result.push({
9027
9083
  url: processedUrl,
@@ -9039,19 +9095,11 @@ var ClinicService = class extends BaseService {
9039
9095
  try {
9040
9096
  const clinicId = this.generateId();
9041
9097
  const validatedData = createClinicSchema.parse(data);
9042
- const group = await this.clinicGroupService.getClinicGroup(
9043
- validatedData.clinicGroupId
9044
- );
9098
+ const group = await this.clinicGroupService.getClinicGroup(validatedData.clinicGroupId);
9045
9099
  if (!group) {
9046
- throw new Error(
9047
- `Clinic group ${validatedData.clinicGroupId} not found`
9048
- );
9100
+ throw new Error(`Clinic group ${validatedData.clinicGroupId} not found`);
9049
9101
  }
9050
- const logoUrl = await this.processMedia(
9051
- validatedData.logo,
9052
- clinicId,
9053
- "clinic-logos"
9054
- );
9102
+ const logoUrl = await this.processMedia(validatedData.logo, clinicId, "clinic-logos");
9055
9103
  const coverPhotoUrl = await this.processMedia(
9056
9104
  validatedData.coverPhoto,
9057
9105
  clinicId,
@@ -9141,11 +9189,7 @@ var ClinicService = class extends BaseService {
9141
9189
  const validatedData = updateClinicSchema.parse(data);
9142
9190
  const updatePayload = {};
9143
9191
  if (validatedData.logo !== void 0) {
9144
- updatePayload.logo = await this.processMedia(
9145
- validatedData.logo,
9146
- clinicId,
9147
- "clinic-logos"
9148
- );
9192
+ updatePayload.logo = await this.processMedia(validatedData.logo, clinicId, "clinic-logos");
9149
9193
  }
9150
9194
  if (validatedData.coverPhoto !== void 0) {
9151
9195
  updatePayload.coverPhoto = await this.processMedia(
@@ -9245,22 +9289,10 @@ var ClinicService = class extends BaseService {
9245
9289
  * Pretražuje klinike u određenom radijusu
9246
9290
  */
9247
9291
  async findClinicsInRadius(center, radiusInKm, filters) {
9248
- return findClinicsInRadius(
9249
- this.db,
9250
- center,
9251
- radiusInKm,
9252
- filters
9253
- );
9292
+ return findClinicsInRadius(this.db, center, radiusInKm, filters);
9254
9293
  }
9255
9294
  async addTags(clinicId, adminId, newTags) {
9256
- return addTags(
9257
- this.db,
9258
- clinicId,
9259
- adminId,
9260
- newTags,
9261
- this.clinicAdminService,
9262
- this.app
9263
- );
9295
+ return addTags(this.db, clinicId, adminId, newTags, this.clinicAdminService, this.app);
9264
9296
  }
9265
9297
  async removeTags(clinicId, adminId, tagsToRemove) {
9266
9298
  return removeTags(
@@ -9298,9 +9330,7 @@ var ClinicService = class extends BaseService {
9298
9330
  clinicGroupId,
9299
9331
  adminId
9300
9332
  });
9301
- const clinicGroup = await this.clinicGroupService.getClinicGroup(
9302
- clinicGroupId
9303
- );
9333
+ const clinicGroup = await this.clinicGroupService.getClinicGroup(clinicGroupId);
9304
9334
  if (!clinicGroup) {
9305
9335
  console.error("[CLINIC_SERVICE] Clinic group not found", {
9306
9336
  clinicGroupId
@@ -9346,13 +9376,7 @@ var ClinicService = class extends BaseService {
9346
9376
  return getAllClinics(this.db, pagination, lastDoc);
9347
9377
  }
9348
9378
  async getAllClinicsInRange(center, rangeInKm, pagination, lastDoc) {
9349
- return getAllClinicsInRange(
9350
- this.db,
9351
- center,
9352
- rangeInKm,
9353
- pagination,
9354
- lastDoc
9355
- );
9379
+ return getAllClinicsInRange(this.db, center, rangeInKm, pagination, lastDoc);
9356
9380
  }
9357
9381
  /**
9358
9382
  * Get clinics based on multiple filtering criteria
@@ -14658,9 +14682,7 @@ var ProcedureService = class extends BaseService {
14658
14682
  return media;
14659
14683
  }
14660
14684
  if (media instanceof File || media instanceof Blob) {
14661
- console.log(
14662
- `[ProcedureService] Uploading ${collectionName} media for ${ownerId}`
14663
- );
14685
+ console.log(`[ProcedureService] Uploading ${collectionName} media for ${ownerId}`);
14664
14686
  const metadata = await this.mediaService.uploadMedia(
14665
14687
  media,
14666
14688
  ownerId,
@@ -14682,11 +14704,7 @@ var ProcedureService = class extends BaseService {
14682
14704
  if (!mediaArray || mediaArray.length === 0) return [];
14683
14705
  const result = [];
14684
14706
  for (const media of mediaArray) {
14685
- const processedUrl = await this.processMedia(
14686
- media,
14687
- ownerId,
14688
- collectionName
14689
- );
14707
+ const processedUrl = await this.processMedia(media, ownerId, collectionName);
14690
14708
  if (processedUrl) {
14691
14709
  result.push(processedUrl);
14692
14710
  }
@@ -14704,41 +14722,23 @@ var ProcedureService = class extends BaseService {
14704
14722
  const procedureId = this.generateId();
14705
14723
  const [category, subcategory, technology, product] = await Promise.all([
14706
14724
  this.categoryService.getById(validatedData.categoryId),
14707
- this.subcategoryService.getById(
14708
- validatedData.categoryId,
14709
- validatedData.subcategoryId
14710
- ),
14725
+ this.subcategoryService.getById(validatedData.categoryId, validatedData.subcategoryId),
14711
14726
  this.technologyService.getById(validatedData.technologyId),
14712
- this.productService.getById(
14713
- validatedData.technologyId,
14714
- validatedData.productId
14715
- )
14727
+ this.productService.getById(validatedData.technologyId, validatedData.productId)
14716
14728
  ]);
14717
14729
  if (!category || !subcategory || !technology || !product) {
14718
14730
  throw new Error("One or more required base entities not found");
14719
14731
  }
14720
- const clinicRef = (0, import_firestore45.doc)(
14721
- this.db,
14722
- CLINICS_COLLECTION,
14723
- validatedData.clinicBranchId
14724
- );
14732
+ const clinicRef = (0, import_firestore45.doc)(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId);
14725
14733
  const clinicSnapshot = await (0, import_firestore45.getDoc)(clinicRef);
14726
14734
  if (!clinicSnapshot.exists()) {
14727
- throw new Error(
14728
- `Clinic with ID ${validatedData.clinicBranchId} not found`
14729
- );
14735
+ throw new Error(`Clinic with ID ${validatedData.clinicBranchId} not found`);
14730
14736
  }
14731
14737
  const clinic = clinicSnapshot.data();
14732
- const practitionerRef = (0, import_firestore45.doc)(
14733
- this.db,
14734
- PRACTITIONERS_COLLECTION,
14735
- validatedData.practitionerId
14736
- );
14738
+ const practitionerRef = (0, import_firestore45.doc)(this.db, PRACTITIONERS_COLLECTION, validatedData.practitionerId);
14737
14739
  const practitionerSnapshot = await (0, import_firestore45.getDoc)(practitionerRef);
14738
14740
  if (!practitionerSnapshot.exists()) {
14739
- throw new Error(
14740
- `Practitioner with ID ${validatedData.practitionerId} not found`
14741
- );
14741
+ throw new Error(`Practitioner with ID ${validatedData.practitionerId} not found`);
14742
14742
  }
14743
14743
  const practitioner = practitionerSnapshot.data();
14744
14744
  let processedPhotos = [];
@@ -14827,24 +14827,16 @@ var ProcedureService = class extends BaseService {
14827
14827
  const validatedData = createProcedureSchema.parse(validationData);
14828
14828
  const [category, subcategory, technology, product, clinicSnapshot] = await Promise.all([
14829
14829
  this.categoryService.getById(validatedData.categoryId),
14830
- this.subcategoryService.getById(
14831
- validatedData.categoryId,
14832
- validatedData.subcategoryId
14833
- ),
14830
+ this.subcategoryService.getById(validatedData.categoryId, validatedData.subcategoryId),
14834
14831
  this.technologyService.getById(validatedData.technologyId),
14835
- this.productService.getById(
14836
- validatedData.technologyId,
14837
- validatedData.productId
14838
- ),
14832
+ this.productService.getById(validatedData.technologyId, validatedData.productId),
14839
14833
  (0, import_firestore45.getDoc)((0, import_firestore45.doc)(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId))
14840
14834
  ]);
14841
14835
  if (!category || !subcategory || !technology || !product) {
14842
14836
  throw new Error("One or more required base entities not found");
14843
14837
  }
14844
14838
  if (!clinicSnapshot.exists()) {
14845
- throw new Error(
14846
- `Clinic with ID ${validatedData.clinicBranchId} not found`
14847
- );
14839
+ throw new Error(`Clinic with ID ${validatedData.clinicBranchId} not found`);
14848
14840
  }
14849
14841
  const clinic = clinicSnapshot.data();
14850
14842
  let processedPhotos = [];
@@ -14870,12 +14862,8 @@ var ProcedureService = class extends BaseService {
14870
14862
  }
14871
14863
  if (practitionersMap.size !== practitionerIds.length) {
14872
14864
  const foundIds = Array.from(practitionersMap.keys());
14873
- const notFoundIds = practitionerIds.filter(
14874
- (id) => !foundIds.includes(id)
14875
- );
14876
- throw new Error(
14877
- `The following practitioners were not found: ${notFoundIds.join(", ")}`
14878
- );
14865
+ const notFoundIds = practitionerIds.filter((id) => !foundIds.includes(id));
14866
+ throw new Error(`The following practitioners were not found: ${notFoundIds.join(", ")}`);
14879
14867
  }
14880
14868
  const batch = (0, import_firestore45.writeBatch)(this.db);
14881
14869
  const createdProcedureIds = [];
@@ -14943,10 +14931,7 @@ var ProcedureService = class extends BaseService {
14943
14931
  const fetchedProcedures = [];
14944
14932
  for (let i = 0; i < createdProcedureIds.length; i += 30) {
14945
14933
  const chunk = createdProcedureIds.slice(i, i + 30);
14946
- const q = (0, import_firestore45.query)(
14947
- (0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION),
14948
- (0, import_firestore45.where)((0, import_firestore45.documentId)(), "in", chunk)
14949
- );
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));
14950
14935
  const snapshot = await (0, import_firestore45.getDocs)(q);
14951
14936
  snapshot.forEach((doc37) => {
14952
14937
  fetchedProcedures.push(doc37.data());
@@ -15047,9 +15032,7 @@ var ProcedureService = class extends BaseService {
15047
15032
  );
15048
15033
  const newPractitionerSnap = await (0, import_firestore45.getDoc)(newPractitionerRef);
15049
15034
  if (!newPractitionerSnap.exists())
15050
- throw new Error(
15051
- `New Practitioner ${validatedData.practitionerId} not found`
15052
- );
15035
+ throw new Error(`New Practitioner ${validatedData.practitionerId} not found`);
15053
15036
  newPractitioner = newPractitionerSnap.data();
15054
15037
  updatedProcedureData.doctorInfo = {
15055
15038
  id: newPractitioner.id,
@@ -15063,11 +15046,7 @@ var ProcedureService = class extends BaseService {
15063
15046
  }
15064
15047
  if (validatedData.clinicBranchId && validatedData.clinicBranchId !== oldClinicId) {
15065
15048
  clinicChanged = true;
15066
- const newClinicRef = (0, import_firestore45.doc)(
15067
- this.db,
15068
- CLINICS_COLLECTION,
15069
- validatedData.clinicBranchId
15070
- );
15049
+ const newClinicRef = (0, import_firestore45.doc)(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId);
15071
15050
  const newClinicSnap = await (0, import_firestore45.getDoc)(newClinicRef);
15072
15051
  if (!newClinicSnap.exists())
15073
15052
  throw new Error(`New Clinic ${validatedData.clinicBranchId} not found`);
@@ -15086,11 +15065,8 @@ var ProcedureService = class extends BaseService {
15086
15065
  updatedProcedureData.nameLower = validatedData.name.toLowerCase();
15087
15066
  }
15088
15067
  if (validatedData.categoryId) {
15089
- const category = await this.categoryService.getById(
15090
- validatedData.categoryId
15091
- );
15092
- if (!category)
15093
- 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`);
15094
15070
  updatedProcedureData.category = category;
15095
15071
  finalCategoryId = category.id;
15096
15072
  }
@@ -15105,17 +15081,12 @@ var ProcedureService = class extends BaseService {
15105
15081
  );
15106
15082
  updatedProcedureData.subcategory = subcategory;
15107
15083
  } else if (validatedData.subcategoryId) {
15108
- console.warn(
15109
- "Attempted to update subcategory without a valid categoryId"
15110
- );
15084
+ console.warn("Attempted to update subcategory without a valid categoryId");
15111
15085
  }
15112
15086
  let finalTechnologyId = existingProcedure.technology.id;
15113
15087
  if (validatedData.technologyId) {
15114
- const technology = await this.technologyService.getById(
15115
- validatedData.technologyId
15116
- );
15117
- if (!technology)
15118
- 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`);
15119
15090
  updatedProcedureData.technology = technology;
15120
15091
  finalTechnologyId = technology.id;
15121
15092
  updatedProcedureData.blockingConditions = technology.blockingConditions;
@@ -15126,10 +15097,7 @@ var ProcedureService = class extends BaseService {
15126
15097
  updatedProcedureData.documentationTemplates = technology.documentationTemplates || [];
15127
15098
  }
15128
15099
  if (validatedData.productId && finalTechnologyId) {
15129
- const product = await this.productService.getById(
15130
- finalTechnologyId,
15131
- validatedData.productId
15132
- );
15100
+ const product = await this.productService.getById(finalTechnologyId, validatedData.productId);
15133
15101
  if (!product)
15134
15102
  throw new Error(
15135
15103
  `Product ${validatedData.productId} not found for technology ${finalTechnologyId}`
@@ -15211,11 +15179,7 @@ var ProcedureService = class extends BaseService {
15211
15179
  limit16(pagination)
15212
15180
  );
15213
15181
  } else {
15214
- proceduresQuery = (0, import_firestore45.query)(
15215
- proceduresCollection,
15216
- (0, import_firestore45.orderBy)("name"),
15217
- limit16(pagination)
15218
- );
15182
+ proceduresQuery = (0, import_firestore45.query)(proceduresCollection, (0, import_firestore45.orderBy)("name"), limit16(pagination));
15219
15183
  }
15220
15184
  } else {
15221
15185
  proceduresQuery = (0, import_firestore45.query)(proceduresCollection, (0, import_firestore45.orderBy)("name"));
@@ -15338,7 +15302,9 @@ var ProcedureService = class extends BaseService {
15338
15302
  constraints.push((0, import_firestore45.limit)(filters.pagination || 10));
15339
15303
  const q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
15340
15304
  const querySnapshot = await (0, import_firestore45.getDocs)(q);
15341
- const procedures = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
15305
+ const procedures = querySnapshot.docs.map(
15306
+ (doc37) => ({ ...doc37.data(), id: doc37.id })
15307
+ );
15342
15308
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
15343
15309
  console.log(`[PROCEDURE_SERVICE] Strategy 1 success: ${procedures.length} procedures`);
15344
15310
  if (procedures.length < (filters.pagination || 10)) {
@@ -15369,7 +15335,9 @@ var ProcedureService = class extends BaseService {
15369
15335
  constraints.push((0, import_firestore45.limit)(filters.pagination || 10));
15370
15336
  const q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
15371
15337
  const querySnapshot = await (0, import_firestore45.getDocs)(q);
15372
- const procedures = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
15338
+ const procedures = querySnapshot.docs.map(
15339
+ (doc37) => ({ ...doc37.data(), id: doc37.id })
15340
+ );
15373
15341
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
15374
15342
  console.log(`[PROCEDURE_SERVICE] Strategy 2 success: ${procedures.length} procedures`);
15375
15343
  if (procedures.length < (filters.pagination || 10)) {
@@ -15381,7 +15349,9 @@ var ProcedureService = class extends BaseService {
15381
15349
  }
15382
15350
  }
15383
15351
  try {
15384
- console.log("[PROCEDURE_SERVICE] Strategy 3: Using createdAt orderBy with client-side filtering");
15352
+ console.log(
15353
+ "[PROCEDURE_SERVICE] Strategy 3: Using createdAt orderBy with client-side filtering"
15354
+ );
15385
15355
  const constraints = getBaseConstraints();
15386
15356
  constraints.push((0, import_firestore45.orderBy)("createdAt", "desc"));
15387
15357
  if (filters.lastDoc) {
@@ -15396,7 +15366,9 @@ var ProcedureService = class extends BaseService {
15396
15366
  constraints.push((0, import_firestore45.limit)(filters.pagination || 10));
15397
15367
  const q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
15398
15368
  const querySnapshot = await (0, import_firestore45.getDocs)(q);
15399
- let procedures = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
15369
+ let procedures = querySnapshot.docs.map(
15370
+ (doc37) => ({ ...doc37.data(), id: doc37.id })
15371
+ );
15400
15372
  procedures = this.applyInMemoryFilters(procedures, filters);
15401
15373
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
15402
15374
  console.log(`[PROCEDURE_SERVICE] Strategy 3 success: ${procedures.length} procedures`);
@@ -15416,7 +15388,9 @@ var ProcedureService = class extends BaseService {
15416
15388
  ];
15417
15389
  const q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
15418
15390
  const querySnapshot = await (0, import_firestore45.getDocs)(q);
15419
- let procedures = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
15391
+ let procedures = querySnapshot.docs.map(
15392
+ (doc37) => ({ ...doc37.data(), id: doc37.id })
15393
+ );
15420
15394
  procedures = this.applyInMemoryFilters(procedures, filters);
15421
15395
  const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
15422
15396
  console.log(`[PROCEDURE_SERVICE] Strategy 4 success: ${procedures.length} procedures`);
@@ -15456,7 +15430,9 @@ var ProcedureService = class extends BaseService {
15456
15430
  if (filters.maxPrice !== void 0 && price > filters.maxPrice) return false;
15457
15431
  return true;
15458
15432
  });
15459
- console.log(`[PROCEDURE_SERVICE] Applied price filter (${filters.minPrice}-${filters.maxPrice}), results: ${filteredProcedures.length}`);
15433
+ console.log(
15434
+ `[PROCEDURE_SERVICE] Applied price filter (${filters.minPrice}-${filters.maxPrice}), results: ${filteredProcedures.length}`
15435
+ );
15460
15436
  }
15461
15437
  if (filters.minRating !== void 0 || filters.maxRating !== void 0) {
15462
15438
  filteredProcedures = filteredProcedures.filter((procedure) => {
@@ -15466,7 +15442,9 @@ var ProcedureService = class extends BaseService {
15466
15442
  if (filters.maxRating !== void 0 && rating > filters.maxRating) return false;
15467
15443
  return true;
15468
15444
  });
15469
- console.log(`[PROCEDURE_SERVICE] Applied rating filter, results: ${filteredProcedures.length}`);
15445
+ console.log(
15446
+ `[PROCEDURE_SERVICE] Applied rating filter, results: ${filteredProcedures.length}`
15447
+ );
15470
15448
  }
15471
15449
  if (filters.treatmentBenefits && filters.treatmentBenefits.length > 0) {
15472
15450
  const benefitsToMatch = filters.treatmentBenefits;
@@ -15474,32 +15452,50 @@ var ProcedureService = class extends BaseService {
15474
15452
  const procedureBenefits = procedure.treatmentBenefits || [];
15475
15453
  return benefitsToMatch.some((benefit) => procedureBenefits.includes(benefit));
15476
15454
  });
15477
- console.log(`[PROCEDURE_SERVICE] Applied benefits filter, results: ${filteredProcedures.length}`);
15455
+ console.log(
15456
+ `[PROCEDURE_SERVICE] Applied benefits filter, results: ${filteredProcedures.length}`
15457
+ );
15478
15458
  }
15479
15459
  if (filters.procedureFamily) {
15480
- filteredProcedures = filteredProcedures.filter((procedure) => procedure.family === filters.procedureFamily);
15481
- console.log(`[PROCEDURE_SERVICE] Applied family filter, results: ${filteredProcedures.length}`);
15460
+ filteredProcedures = filteredProcedures.filter(
15461
+ (procedure) => procedure.family === filters.procedureFamily
15462
+ );
15463
+ console.log(
15464
+ `[PROCEDURE_SERVICE] Applied family filter, results: ${filteredProcedures.length}`
15465
+ );
15482
15466
  }
15483
15467
  if (filters.procedureCategory) {
15484
- filteredProcedures = filteredProcedures.filter((procedure) => {
15485
- var _a;
15486
- return ((_a = procedure.category) == null ? void 0 : _a.id) === filters.procedureCategory;
15487
- });
15488
- console.log(`[PROCEDURE_SERVICE] Applied category filter, results: ${filteredProcedures.length}`);
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
+ );
15489
15477
  }
15490
15478
  if (filters.procedureSubcategory) {
15491
- filteredProcedures = filteredProcedures.filter((procedure) => {
15492
- var _a;
15493
- return ((_a = procedure.subcategory) == null ? void 0 : _a.id) === filters.procedureSubcategory;
15494
- });
15495
- console.log(`[PROCEDURE_SERVICE] Applied subcategory filter, results: ${filteredProcedures.length}`);
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
+ );
15496
15488
  }
15497
15489
  if (filters.procedureTechnology) {
15498
- filteredProcedures = filteredProcedures.filter((procedure) => {
15499
- var _a;
15500
- return ((_a = procedure.technology) == null ? void 0 : _a.id) === filters.procedureTechnology;
15501
- });
15502
- console.log(`[PROCEDURE_SERVICE] Applied technology filter, results: ${filteredProcedures.length}`);
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
+ );
15503
15499
  }
15504
15500
  if (filters.location && filters.radiusInKm && filters.radiusInKm > 0) {
15505
15501
  const location = filters.location;
@@ -15523,29 +15519,48 @@ var ProcedureService = class extends BaseService {
15523
15519
  return filteredProcedures;
15524
15520
  }
15525
15521
  handleGeoQuery(filters) {
15526
- console.log("[PROCEDURE_SERVICE] Executing geo query with enhanced debugging");
15522
+ console.log("[PROCEDURE_SERVICE] Executing geo query with geohash bounds");
15527
15523
  try {
15528
15524
  const location = filters.location;
15529
15525
  const radiusInKm = filters.radiusInKm;
15530
- console.log("[PROCEDURE_SERVICE] Geo query parameters:", {
15531
- latitude: location.latitude,
15532
- longitude: location.longitude,
15533
- radiusInKm,
15534
- pagination: filters.pagination || 10
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));
15535
15537
  });
15536
- const constraints = [
15537
- (0, import_firestore45.where)("isActive", "==", true),
15538
- (0, import_firestore45.orderBy)("createdAt", "desc"),
15539
- (0, import_firestore45.limit)((filters.pagination || 10) * 3)
15540
- // Get more results for geo filtering
15541
- ];
15542
- const q = (0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints);
15543
- return (0, import_firestore45.getDocs)(q).then((querySnapshot) => {
15544
- let procedures = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
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());
15545
15548
  procedures = this.applyInMemoryFilters(procedures, filters);
15546
- console.log(`[PROCEDURE_SERVICE] Geo query success: ${procedures.length} procedures within ${radiusInKm}km`);
15547
- const lastDoc = procedures.length < (filters.pagination || 10) ? null : querySnapshot.docs[querySnapshot.docs.length - 1];
15548
- return { procedures, lastDoc };
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 };
15549
15564
  });
15550
15565
  } catch (error) {
15551
15566
  console.error("[PROCEDURE_SERVICE] Geo query failed:", error);
@@ -15575,11 +15590,7 @@ var ProcedureService = class extends BaseService {
15575
15590
  throw new Error(`Clinic with ID ${data.clinicBranchId} not found`);
15576
15591
  }
15577
15592
  const clinic = clinicSnapshot.data();
15578
- const practitionerRef = (0, import_firestore45.doc)(
15579
- this.db,
15580
- PRACTITIONERS_COLLECTION,
15581
- data.practitionerId
15582
- );
15593
+ const practitionerRef = (0, import_firestore45.doc)(this.db, PRACTITIONERS_COLLECTION, data.practitionerId);
15583
15594
  const practitionerSnapshot = await (0, import_firestore45.getDoc)(practitionerRef);
15584
15595
  if (!practitionerSnapshot.exists()) {
15585
15596
  throw new Error(`Practitioner with ID ${data.practitionerId} not found`);
@@ -15587,11 +15598,7 @@ var ProcedureService = class extends BaseService {
15587
15598
  const practitioner = practitionerSnapshot.data();
15588
15599
  let processedPhotos = [];
15589
15600
  if (data.photos && data.photos.length > 0) {
15590
- processedPhotos = await this.processMediaArray(
15591
- data.photos,
15592
- procedureId,
15593
- "procedure-photos"
15594
- );
15601
+ processedPhotos = await this.processMediaArray(data.photos, procedureId, "procedure-photos");
15595
15602
  }
15596
15603
  const clinicInfo = {
15597
15604
  id: clinicSnapshot.id,