@blackcode_sa/metaestetics-api 1.8.12 → 1.8.14
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/admin/index.d.mts +2 -0
- package/dist/admin/index.d.ts +2 -0
- package/dist/backoffice/index.d.mts +1 -0
- package/dist/backoffice/index.d.ts +1 -0
- package/dist/index.d.mts +28 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +141 -222
- package/dist/index.mjs +144 -223
- package/package.json +1 -1
- package/src/services/clinic/clinic.service.ts +33 -0
- package/src/services/clinic/utils/filter.utils.ts +54 -225
- package/src/services/practitioner/practitioner.service.ts +51 -117
- package/src/services/procedure/procedure.service.ts +43 -3
- package/src/types/clinic/index.ts +1 -0
- package/src/types/practitioner/index.ts +1 -0
package/dist/admin/index.d.mts
CHANGED
|
@@ -788,6 +788,7 @@ interface Clinic {
|
|
|
788
788
|
id: string;
|
|
789
789
|
clinicGroupId: string;
|
|
790
790
|
name: string;
|
|
791
|
+
nameLower: string;
|
|
791
792
|
description?: string;
|
|
792
793
|
location: ClinicLocation;
|
|
793
794
|
contactInfo: ClinicContactInfo;
|
|
@@ -901,6 +902,7 @@ interface Practitioner {
|
|
|
901
902
|
id: string;
|
|
902
903
|
userRef: string;
|
|
903
904
|
basicInfo: PractitionerBasicInfo;
|
|
905
|
+
fullNameLower: string;
|
|
904
906
|
certification: PractitionerCertification;
|
|
905
907
|
clinics: string[];
|
|
906
908
|
clinicWorkingHours: PractitionerClinicWorkingHours[];
|
package/dist/admin/index.d.ts
CHANGED
|
@@ -788,6 +788,7 @@ interface Clinic {
|
|
|
788
788
|
id: string;
|
|
789
789
|
clinicGroupId: string;
|
|
790
790
|
name: string;
|
|
791
|
+
nameLower: string;
|
|
791
792
|
description?: string;
|
|
792
793
|
location: ClinicLocation;
|
|
793
794
|
contactInfo: ClinicContactInfo;
|
|
@@ -901,6 +902,7 @@ interface Practitioner {
|
|
|
901
902
|
id: string;
|
|
902
903
|
userRef: string;
|
|
903
904
|
basicInfo: PractitionerBasicInfo;
|
|
905
|
+
fullNameLower: string;
|
|
904
906
|
certification: PractitionerCertification;
|
|
905
907
|
clinics: string[];
|
|
906
908
|
clinicWorkingHours: PractitionerClinicWorkingHours[];
|
|
@@ -1187,6 +1187,7 @@ interface Practitioner {
|
|
|
1187
1187
|
id: string;
|
|
1188
1188
|
userRef: string;
|
|
1189
1189
|
basicInfo: PractitionerBasicInfo;
|
|
1190
|
+
fullNameLower: string;
|
|
1190
1191
|
certification: PractitionerCertification;
|
|
1191
1192
|
clinics: string[];
|
|
1192
1193
|
clinicWorkingHours: PractitionerClinicWorkingHours[];
|
|
@@ -1187,6 +1187,7 @@ interface Practitioner {
|
|
|
1187
1187
|
id: string;
|
|
1188
1188
|
userRef: string;
|
|
1189
1189
|
basicInfo: PractitionerBasicInfo;
|
|
1190
|
+
fullNameLower: string;
|
|
1190
1191
|
certification: PractitionerCertification;
|
|
1191
1192
|
clinics: string[];
|
|
1192
1193
|
clinicWorkingHours: PractitionerClinicWorkingHours[];
|
package/dist/index.d.mts
CHANGED
|
@@ -1207,6 +1207,7 @@ interface Clinic {
|
|
|
1207
1207
|
id: string;
|
|
1208
1208
|
clinicGroupId: string;
|
|
1209
1209
|
name: string;
|
|
1210
|
+
nameLower: string;
|
|
1210
1211
|
description?: string;
|
|
1211
1212
|
location: ClinicLocation;
|
|
1212
1213
|
contactInfo: ClinicContactInfo;
|
|
@@ -1432,6 +1433,7 @@ interface Practitioner {
|
|
|
1432
1433
|
id: string;
|
|
1433
1434
|
userRef: string;
|
|
1434
1435
|
basicInfo: PractitionerBasicInfo;
|
|
1436
|
+
fullNameLower: string;
|
|
1435
1437
|
certification: PractitionerCertification;
|
|
1436
1438
|
clinics: string[];
|
|
1437
1439
|
clinicWorkingHours: PractitionerClinicWorkingHours[];
|
|
@@ -4100,6 +4102,18 @@ declare class ClinicService extends BaseService {
|
|
|
4100
4102
|
})[];
|
|
4101
4103
|
lastDoc: any;
|
|
4102
4104
|
}>;
|
|
4105
|
+
/**
|
|
4106
|
+
* Gets all clinics with minimal info for map display (id, name, address, latitude, longitude)
|
|
4107
|
+
* This is optimized for mobile map usage to reduce payload size.
|
|
4108
|
+
* @returns Array of minimal clinic info for map
|
|
4109
|
+
*/
|
|
4110
|
+
getClinicsForMap(): Promise<{
|
|
4111
|
+
id: string;
|
|
4112
|
+
name: string;
|
|
4113
|
+
address: string;
|
|
4114
|
+
latitude: number | undefined;
|
|
4115
|
+
longitude: number | undefined;
|
|
4116
|
+
}[]>;
|
|
4103
4117
|
}
|
|
4104
4118
|
|
|
4105
4119
|
declare class ProcedureService extends BaseService {
|
|
@@ -4259,6 +4273,20 @@ declare class ProcedureService extends BaseService {
|
|
|
4259
4273
|
* @returns The created procedure
|
|
4260
4274
|
*/
|
|
4261
4275
|
createConsultationProcedure(data: Omit<CreateProcedureData, "productId">): Promise<Procedure>;
|
|
4276
|
+
/**
|
|
4277
|
+
* Gets all procedures with minimal info for map display (id, name, clinicId, clinicName, address, latitude, longitude)
|
|
4278
|
+
* This is optimized for mobile map usage to reduce payload size.
|
|
4279
|
+
* @returns Array of minimal procedure info for map
|
|
4280
|
+
*/
|
|
4281
|
+
getProceduresForMap(): Promise<{
|
|
4282
|
+
id: string;
|
|
4283
|
+
name: string;
|
|
4284
|
+
clinicId: string | undefined;
|
|
4285
|
+
clinicName: string | undefined;
|
|
4286
|
+
address: string;
|
|
4287
|
+
latitude: number | undefined;
|
|
4288
|
+
longitude: number | undefined;
|
|
4289
|
+
}[]>;
|
|
4262
4290
|
}
|
|
4263
4291
|
|
|
4264
4292
|
declare class PractitionerService extends BaseService {
|
package/dist/index.d.ts
CHANGED
|
@@ -1207,6 +1207,7 @@ interface Clinic {
|
|
|
1207
1207
|
id: string;
|
|
1208
1208
|
clinicGroupId: string;
|
|
1209
1209
|
name: string;
|
|
1210
|
+
nameLower: string;
|
|
1210
1211
|
description?: string;
|
|
1211
1212
|
location: ClinicLocation;
|
|
1212
1213
|
contactInfo: ClinicContactInfo;
|
|
@@ -1432,6 +1433,7 @@ interface Practitioner {
|
|
|
1432
1433
|
id: string;
|
|
1433
1434
|
userRef: string;
|
|
1434
1435
|
basicInfo: PractitionerBasicInfo;
|
|
1436
|
+
fullNameLower: string;
|
|
1435
1437
|
certification: PractitionerCertification;
|
|
1436
1438
|
clinics: string[];
|
|
1437
1439
|
clinicWorkingHours: PractitionerClinicWorkingHours[];
|
|
@@ -4100,6 +4102,18 @@ declare class ClinicService extends BaseService {
|
|
|
4100
4102
|
})[];
|
|
4101
4103
|
lastDoc: any;
|
|
4102
4104
|
}>;
|
|
4105
|
+
/**
|
|
4106
|
+
* Gets all clinics with minimal info for map display (id, name, address, latitude, longitude)
|
|
4107
|
+
* This is optimized for mobile map usage to reduce payload size.
|
|
4108
|
+
* @returns Array of minimal clinic info for map
|
|
4109
|
+
*/
|
|
4110
|
+
getClinicsForMap(): Promise<{
|
|
4111
|
+
id: string;
|
|
4112
|
+
name: string;
|
|
4113
|
+
address: string;
|
|
4114
|
+
latitude: number | undefined;
|
|
4115
|
+
longitude: number | undefined;
|
|
4116
|
+
}[]>;
|
|
4103
4117
|
}
|
|
4104
4118
|
|
|
4105
4119
|
declare class ProcedureService extends BaseService {
|
|
@@ -4259,6 +4273,20 @@ declare class ProcedureService extends BaseService {
|
|
|
4259
4273
|
* @returns The created procedure
|
|
4260
4274
|
*/
|
|
4261
4275
|
createConsultationProcedure(data: Omit<CreateProcedureData, "productId">): Promise<Procedure>;
|
|
4276
|
+
/**
|
|
4277
|
+
* Gets all procedures with minimal info for map display (id, name, clinicId, clinicName, address, latitude, longitude)
|
|
4278
|
+
* This is optimized for mobile map usage to reduce payload size.
|
|
4279
|
+
* @returns Array of minimal procedure info for map
|
|
4280
|
+
*/
|
|
4281
|
+
getProceduresForMap(): Promise<{
|
|
4282
|
+
id: string;
|
|
4283
|
+
name: string;
|
|
4284
|
+
clinicId: string | undefined;
|
|
4285
|
+
clinicName: string | undefined;
|
|
4286
|
+
address: string;
|
|
4287
|
+
latitude: number | undefined;
|
|
4288
|
+
longitude: number | undefined;
|
|
4289
|
+
}[]>;
|
|
4262
4290
|
}
|
|
4263
4291
|
|
|
4264
4292
|
declare class PractitionerService extends BaseService {
|
package/dist/index.js
CHANGED
|
@@ -6211,6 +6211,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6211
6211
|
trustworthiness: 0,
|
|
6212
6212
|
recommendationPercentage: 0
|
|
6213
6213
|
};
|
|
6214
|
+
const fullNameLower = `${validData.basicInfo.firstName} ${validData.basicInfo.lastName}`.toLowerCase();
|
|
6214
6215
|
const practitioner = {
|
|
6215
6216
|
id: practitionerId,
|
|
6216
6217
|
userRef: validData.userRef,
|
|
@@ -6218,6 +6219,8 @@ var PractitionerService = class extends BaseService {
|
|
|
6218
6219
|
validData.basicInfo,
|
|
6219
6220
|
practitionerId
|
|
6220
6221
|
),
|
|
6222
|
+
fullNameLower,
|
|
6223
|
+
// Ensure this is present
|
|
6221
6224
|
certification: validData.certification,
|
|
6222
6225
|
clinics: validData.clinics || [],
|
|
6223
6226
|
clinicWorkingHours: validData.clinicWorkingHours || [],
|
|
@@ -6313,6 +6316,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6313
6316
|
}
|
|
6314
6317
|
const finalClinicsInfo = validatedData.clinicsInfo && validatedData.clinicsInfo.length > 0 ? validatedData.clinicsInfo : clinicsInfo;
|
|
6315
6318
|
const proceduresInfo = [];
|
|
6319
|
+
const fullNameLowerDraft = `${validatedData.basicInfo.firstName} ${validatedData.basicInfo.lastName}`.toLowerCase();
|
|
6316
6320
|
const practitionerData = {
|
|
6317
6321
|
id: practitionerId,
|
|
6318
6322
|
userRef: "",
|
|
@@ -6321,6 +6325,8 @@ var PractitionerService = class extends BaseService {
|
|
|
6321
6325
|
validatedData.basicInfo,
|
|
6322
6326
|
practitionerId
|
|
6323
6327
|
),
|
|
6328
|
+
fullNameLower: fullNameLowerDraft,
|
|
6329
|
+
// Ensure this is present
|
|
6324
6330
|
certification: validatedData.certification,
|
|
6325
6331
|
clinics,
|
|
6326
6332
|
clinicWorkingHours: validatedData.clinicWorkingHours || [],
|
|
@@ -6599,6 +6605,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6599
6605
|
validData.basicInfo,
|
|
6600
6606
|
practitionerId
|
|
6601
6607
|
);
|
|
6608
|
+
processedData.fullNameLower = `${processedData.basicInfo.firstName} ${processedData.basicInfo.lastName}`.toLowerCase();
|
|
6602
6609
|
}
|
|
6603
6610
|
const updateData = {
|
|
6604
6611
|
...processedData,
|
|
@@ -6826,10 +6833,6 @@ var PractitionerService = class extends BaseService {
|
|
|
6826
6833
|
*/
|
|
6827
6834
|
async getPractitionersByFilters(filters) {
|
|
6828
6835
|
try {
|
|
6829
|
-
console.log(
|
|
6830
|
-
"[PRACTITIONER_SERVICE] Starting practitioner filtering with criteria:",
|
|
6831
|
-
filters
|
|
6832
|
-
);
|
|
6833
6836
|
const constraints = [];
|
|
6834
6837
|
if (!filters.includeDraftPractitioners) {
|
|
6835
6838
|
constraints.push((0, import_firestore21.where)("status", "==", "active" /* ACTIVE */));
|
|
@@ -6844,60 +6847,40 @@ var PractitionerService = class extends BaseService {
|
|
|
6844
6847
|
)
|
|
6845
6848
|
);
|
|
6846
6849
|
}
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
|
|
6850
|
-
|
|
6851
|
-
constraints.push((0, import_firestore21.startAfter)(filters.lastDoc));
|
|
6852
|
-
}
|
|
6853
|
-
constraints.push((0, import_firestore21.limit)(filters.pagination));
|
|
6850
|
+
if (filters.nameSearch && filters.nameSearch.trim()) {
|
|
6851
|
+
const searchTerm = filters.nameSearch.trim().toLowerCase();
|
|
6852
|
+
constraints.push((0, import_firestore21.where)("fullNameLower", ">=", searchTerm));
|
|
6853
|
+
constraints.push((0, import_firestore21.where)("fullNameLower", "<=", searchTerm + "\uF8FF"));
|
|
6854
6854
|
}
|
|
6855
|
-
|
|
6856
|
-
(0, import_firestore21.
|
|
6857
|
-
|
|
6858
|
-
|
|
6859
|
-
|
|
6860
|
-
|
|
6861
|
-
|
|
6862
|
-
|
|
6863
|
-
let practitioners = querySnapshot.docs.map((doc37) => {
|
|
6864
|
-
return { ...doc37.data(), id: doc37.id };
|
|
6865
|
-
});
|
|
6866
|
-
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
6867
|
-
if (filters.nameSearch && filters.nameSearch.trim() !== "") {
|
|
6868
|
-
const searchTerm = filters.nameSearch.toLowerCase().trim();
|
|
6869
|
-
practitioners = practitioners.filter((practitioner) => {
|
|
6870
|
-
const fullName = `${practitioner.basicInfo.firstName} ${practitioner.basicInfo.lastName}`.toLowerCase();
|
|
6871
|
-
return fullName.includes(searchTerm);
|
|
6872
|
-
});
|
|
6855
|
+
if (filters.procedureTechnology) {
|
|
6856
|
+
constraints.push((0, import_firestore21.where)("proceduresInfo.technologyName", "==", filters.procedureTechnology));
|
|
6857
|
+
} else if (filters.procedureSubcategory) {
|
|
6858
|
+
constraints.push((0, import_firestore21.where)("proceduresInfo.subcategoryName", "==", filters.procedureSubcategory));
|
|
6859
|
+
} else if (filters.procedureCategory) {
|
|
6860
|
+
constraints.push((0, import_firestore21.where)("proceduresInfo.categoryName", "==", filters.procedureCategory));
|
|
6861
|
+
} else if (filters.procedureFamily) {
|
|
6862
|
+
constraints.push((0, import_firestore21.where)("proceduresInfo.family", "==", filters.procedureFamily));
|
|
6873
6863
|
}
|
|
6874
|
-
if (filters.
|
|
6875
|
-
|
|
6876
|
-
return filters.specialties.every(
|
|
6877
|
-
(specialty) => practitioner.certification.specialties.includes(specialty)
|
|
6878
|
-
);
|
|
6879
|
-
});
|
|
6864
|
+
if (filters.minRating !== void 0) {
|
|
6865
|
+
constraints.push((0, import_firestore21.where)("reviewInfo.averageRating", ">=", filters.minRating));
|
|
6880
6866
|
}
|
|
6881
|
-
if (filters.
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
}
|
|
6894
|
-
if (filters.procedureFamily) {
|
|
6895
|
-
return procedure.family === filters.procedureFamily;
|
|
6896
|
-
}
|
|
6897
|
-
return false;
|
|
6898
|
-
});
|
|
6899
|
-
});
|
|
6867
|
+
if (filters.maxRating !== void 0) {
|
|
6868
|
+
constraints.push((0, import_firestore21.where)("reviewInfo.averageRating", "<=", filters.maxRating));
|
|
6869
|
+
}
|
|
6870
|
+
constraints.push((0, import_firestore21.orderBy)("fullNameLower"));
|
|
6871
|
+
if (filters.lastDoc) {
|
|
6872
|
+
if (typeof filters.lastDoc.data === "function") {
|
|
6873
|
+
constraints.push((0, import_firestore21.startAfter)(filters.lastDoc));
|
|
6874
|
+
} else if (Array.isArray(filters.lastDoc)) {
|
|
6875
|
+
constraints.push((0, import_firestore21.startAfter)(...filters.lastDoc));
|
|
6876
|
+
} else {
|
|
6877
|
+
constraints.push((0, import_firestore21.startAfter)(filters.lastDoc));
|
|
6878
|
+
}
|
|
6900
6879
|
}
|
|
6880
|
+
constraints.push((0, import_firestore21.limit)(filters.pagination || 5));
|
|
6881
|
+
const q = (0, import_firestore21.query)((0, import_firestore21.collection)(this.db, PRACTITIONERS_COLLECTION), ...constraints);
|
|
6882
|
+
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6883
|
+
let practitioners = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
|
|
6901
6884
|
if (filters.location && filters.radiusInKm && filters.radiusInKm > 0) {
|
|
6902
6885
|
const location = filters.location;
|
|
6903
6886
|
const radiusInKm = filters.radiusInKm;
|
|
@@ -6913,22 +6896,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6913
6896
|
});
|
|
6914
6897
|
});
|
|
6915
6898
|
}
|
|
6916
|
-
|
|
6917
|
-
practitioners = practitioners.filter(
|
|
6918
|
-
(p) => p.reviewInfo.averageRating >= filters.minRating
|
|
6919
|
-
);
|
|
6920
|
-
}
|
|
6921
|
-
if (filters.maxRating !== void 0) {
|
|
6922
|
-
practitioners = practitioners.filter(
|
|
6923
|
-
(p) => p.reviewInfo.averageRating <= filters.maxRating
|
|
6924
|
-
);
|
|
6925
|
-
}
|
|
6926
|
-
console.log(
|
|
6927
|
-
`[PRACTITIONER_SERVICE] Filtered to ${practitioners.length} practitioners`
|
|
6928
|
-
);
|
|
6929
|
-
if (filters.pagination && filters.pagination > 0) {
|
|
6930
|
-
practitioners = practitioners.slice(0, filters.pagination);
|
|
6931
|
-
}
|
|
6899
|
+
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
6932
6900
|
return {
|
|
6933
6901
|
practitioners,
|
|
6934
6902
|
lastDoc
|
|
@@ -8567,168 +8535,64 @@ async function findClinicsInRadius(db, center, radiusInKm, filters) {
|
|
|
8567
8535
|
var import_firestore26 = require("firebase/firestore");
|
|
8568
8536
|
var import_geofire_common6 = require("geofire-common");
|
|
8569
8537
|
async function getClinicsByFilters(db, filters) {
|
|
8570
|
-
|
|
8571
|
-
"[FILTER_UTILS] Starting clinic filtering with criteria:",
|
|
8572
|
-
filters
|
|
8573
|
-
);
|
|
8574
|
-
const isGeoQuery = filters.center && filters.radiusInKm && filters.radiusInKm > 0;
|
|
8538
|
+
var _a;
|
|
8575
8539
|
const constraints = [];
|
|
8576
|
-
|
|
8577
|
-
constraints.push((0, import_firestore26.where)("isActive", "==", filters.isActive));
|
|
8578
|
-
} else {
|
|
8579
|
-
constraints.push((0, import_firestore26.where)("isActive", "==", true));
|
|
8580
|
-
}
|
|
8540
|
+
constraints.push((0, import_firestore26.where)("isActive", "==", (_a = filters.isActive) != null ? _a : true));
|
|
8581
8541
|
if (filters.tags && filters.tags.length > 0) {
|
|
8582
8542
|
constraints.push((0, import_firestore26.where)("tags", "array-contains", filters.tags[0]));
|
|
8583
8543
|
}
|
|
8584
8544
|
if (filters.procedureTechnology) {
|
|
8585
|
-
constraints.push(
|
|
8586
|
-
(0, import_firestore26.where)("servicesInfo.technology", "==", filters.procedureTechnology)
|
|
8587
|
-
);
|
|
8545
|
+
constraints.push((0, import_firestore26.where)("servicesInfo.technology", "==", filters.procedureTechnology));
|
|
8588
8546
|
} else if (filters.procedureSubcategory) {
|
|
8589
|
-
constraints.push(
|
|
8590
|
-
(0, import_firestore26.where)("servicesInfo.subCategory", "==", filters.procedureSubcategory)
|
|
8591
|
-
);
|
|
8547
|
+
constraints.push((0, import_firestore26.where)("servicesInfo.subCategory", "==", filters.procedureSubcategory));
|
|
8592
8548
|
} else if (filters.procedureCategory) {
|
|
8593
|
-
constraints.push(
|
|
8594
|
-
(0, import_firestore26.where)("servicesInfo.category", "==", filters.procedureCategory)
|
|
8595
|
-
);
|
|
8549
|
+
constraints.push((0, import_firestore26.where)("servicesInfo.category", "==", filters.procedureCategory));
|
|
8596
8550
|
} else if (filters.procedureFamily) {
|
|
8597
|
-
constraints.push(
|
|
8598
|
-
|
|
8599
|
-
|
|
8600
|
-
|
|
8601
|
-
if (filters.
|
|
8602
|
-
|
|
8603
|
-
constraints.push((0, import_firestore26.
|
|
8604
|
-
|
|
8605
|
-
|
|
8606
|
-
}
|
|
8607
|
-
|
|
8608
|
-
|
|
8609
|
-
|
|
8610
|
-
if (
|
|
8611
|
-
|
|
8612
|
-
|
|
8613
|
-
|
|
8614
|
-
|
|
8615
|
-
|
|
8616
|
-
|
|
8617
|
-
)
|
|
8618
|
-
|
|
8619
|
-
for (const bound of bounds) {
|
|
8620
|
-
const geoConstraints = [
|
|
8621
|
-
...constraints,
|
|
8622
|
-
(0, import_firestore26.where)("location.geohash", ">=", bound[0]),
|
|
8623
|
-
(0, import_firestore26.where)("location.geohash", "<=", bound[1])
|
|
8624
|
-
];
|
|
8625
|
-
const q = (0, import_firestore26.query)((0, import_firestore26.collection)(db, CLINICS_COLLECTION), ...geoConstraints);
|
|
8626
|
-
const querySnapshot = await (0, import_firestore26.getDocs)(q);
|
|
8627
|
-
console.log(
|
|
8628
|
-
`[FILTER_UTILS] Found ${querySnapshot.docs.length} clinics in geo bound`
|
|
8629
|
-
);
|
|
8630
|
-
for (const doc37 of querySnapshot.docs) {
|
|
8631
|
-
const clinic = { ...doc37.data(), id: doc37.id };
|
|
8632
|
-
const distance = (0, import_geofire_common6.distanceBetween)(
|
|
8633
|
-
[center.latitude, center.longitude],
|
|
8634
|
-
[clinic.location.latitude, clinic.location.longitude]
|
|
8635
|
-
);
|
|
8636
|
-
const distanceInKm = distance / 1e3;
|
|
8637
|
-
if (distanceInKm <= radiusInKm) {
|
|
8638
|
-
matchingClinics.push({
|
|
8639
|
-
...clinic,
|
|
8640
|
-
distance: distanceInKm
|
|
8641
|
-
});
|
|
8642
|
-
}
|
|
8643
|
-
}
|
|
8644
|
-
}
|
|
8645
|
-
let filteredClinics = matchingClinics;
|
|
8646
|
-
if (filters.tags && filters.tags.length > 1) {
|
|
8647
|
-
filteredClinics = filteredClinics.filter((clinic) => {
|
|
8648
|
-
return filters.tags.every((tag) => clinic.tags.includes(tag));
|
|
8649
|
-
});
|
|
8650
|
-
}
|
|
8651
|
-
if (filters.minRating !== void 0) {
|
|
8652
|
-
filteredClinics = filteredClinics.filter(
|
|
8653
|
-
(clinic) => clinic.reviewInfo.averageRating >= filters.minRating
|
|
8654
|
-
);
|
|
8655
|
-
}
|
|
8656
|
-
if (filters.maxRating !== void 0) {
|
|
8657
|
-
filteredClinics = filteredClinics.filter(
|
|
8658
|
-
(clinic) => clinic.reviewInfo.averageRating <= filters.maxRating
|
|
8659
|
-
);
|
|
8660
|
-
}
|
|
8661
|
-
filteredClinics.sort((a, b) => a.distance - b.distance);
|
|
8662
|
-
if (filters.pagination && filters.pagination > 0) {
|
|
8663
|
-
let startIndex = 0;
|
|
8664
|
-
if (filters.lastDoc) {
|
|
8665
|
-
const lastDocIndex = filteredClinics.findIndex(
|
|
8666
|
-
(clinic) => clinic.id === filters.lastDoc.id
|
|
8667
|
-
);
|
|
8668
|
-
if (lastDocIndex !== -1) {
|
|
8669
|
-
startIndex = lastDocIndex + 1;
|
|
8670
|
-
}
|
|
8671
|
-
}
|
|
8672
|
-
const paginatedClinics = filteredClinics.slice(
|
|
8673
|
-
startIndex,
|
|
8674
|
-
startIndex + filters.pagination
|
|
8675
|
-
);
|
|
8676
|
-
lastVisibleDoc = paginatedClinics.length > 0 ? paginatedClinics[paginatedClinics.length - 1] : null;
|
|
8677
|
-
clinicsResult = paginatedClinics;
|
|
8551
|
+
constraints.push((0, import_firestore26.where)("servicesInfo.procedureFamily", "==", filters.procedureFamily));
|
|
8552
|
+
}
|
|
8553
|
+
let useNameLower = false;
|
|
8554
|
+
let searchTerm = "";
|
|
8555
|
+
if (filters.nameSearch && filters.nameSearch.trim()) {
|
|
8556
|
+
searchTerm = filters.nameSearch.trim().toLowerCase();
|
|
8557
|
+
constraints.push((0, import_firestore26.where)("nameLower", ">=", searchTerm));
|
|
8558
|
+
constraints.push((0, import_firestore26.where)("nameLower", "<=", searchTerm + "\uF8FF"));
|
|
8559
|
+
useNameLower = true;
|
|
8560
|
+
}
|
|
8561
|
+
if (filters.minRating !== void 0) {
|
|
8562
|
+
constraints.push((0, import_firestore26.where)("reviewInfo.averageRating", ">=", filters.minRating));
|
|
8563
|
+
}
|
|
8564
|
+
if (filters.maxRating !== void 0) {
|
|
8565
|
+
constraints.push((0, import_firestore26.where)("reviewInfo.averageRating", "<=", filters.maxRating));
|
|
8566
|
+
}
|
|
8567
|
+
constraints.push((0, import_firestore26.orderBy)("nameLower"));
|
|
8568
|
+
if (filters.lastDoc) {
|
|
8569
|
+
if (typeof filters.lastDoc.data === "function") {
|
|
8570
|
+
constraints.push((0, import_firestore26.startAfter)(filters.lastDoc));
|
|
8571
|
+
} else if (Array.isArray(filters.lastDoc)) {
|
|
8572
|
+
constraints.push((0, import_firestore26.startAfter)(...filters.lastDoc));
|
|
8678
8573
|
} else {
|
|
8679
|
-
|
|
8574
|
+
constraints.push((0, import_firestore26.startAfter)(filters.lastDoc));
|
|
8680
8575
|
}
|
|
8681
|
-
}
|
|
8682
|
-
|
|
8683
|
-
|
|
8684
|
-
|
|
8685
|
-
|
|
8686
|
-
|
|
8687
|
-
|
|
8688
|
-
|
|
8576
|
+
}
|
|
8577
|
+
constraints.push((0, import_firestore26.limit)(filters.pagination || 5));
|
|
8578
|
+
const q = (0, import_firestore26.query)((0, import_firestore26.collection)(db, CLINICS_COLLECTION), ...constraints);
|
|
8579
|
+
const querySnapshot = await (0, import_firestore26.getDocs)(q);
|
|
8580
|
+
let clinics = querySnapshot.docs.map((doc37) => ({ ...doc37.data(), id: doc37.id }));
|
|
8581
|
+
if (filters.tags && filters.tags.length > 1) {
|
|
8582
|
+
clinics = clinics.filter((clinic) => filters.tags.every((tag) => clinic.tags.includes(tag)));
|
|
8583
|
+
}
|
|
8584
|
+
if (filters.center && filters.radiusInKm) {
|
|
8585
|
+
clinics = clinics.filter((clinic) => {
|
|
8586
|
+
const distance = (0, import_geofire_common6.distanceBetween)(
|
|
8587
|
+
[filters.center.latitude, filters.center.longitude],
|
|
8588
|
+
[clinic.location.latitude, clinic.location.longitude]
|
|
8589
|
+
) / 1e3;
|
|
8590
|
+
clinic.distance = distance;
|
|
8591
|
+
return distance <= filters.radiusInKm;
|
|
8689
8592
|
});
|
|
8690
|
-
let filteredClinics = clinics;
|
|
8691
|
-
if (filters.center) {
|
|
8692
|
-
const center = filters.center;
|
|
8693
|
-
const clinicsWithDistance = [];
|
|
8694
|
-
filteredClinics.forEach((clinic) => {
|
|
8695
|
-
const distance = (0, import_geofire_common6.distanceBetween)(
|
|
8696
|
-
[center.latitude, center.longitude],
|
|
8697
|
-
[clinic.location.latitude, clinic.location.longitude]
|
|
8698
|
-
);
|
|
8699
|
-
clinicsWithDistance.push({
|
|
8700
|
-
...clinic,
|
|
8701
|
-
distance: distance / 1e3
|
|
8702
|
-
// Convert to kilometers
|
|
8703
|
-
});
|
|
8704
|
-
});
|
|
8705
|
-
filteredClinics = clinicsWithDistance;
|
|
8706
|
-
filteredClinics.sort(
|
|
8707
|
-
(a, b) => a.distance - b.distance
|
|
8708
|
-
);
|
|
8709
|
-
}
|
|
8710
|
-
if (filters.tags && filters.tags.length > 1) {
|
|
8711
|
-
filteredClinics = filteredClinics.filter((clinic) => {
|
|
8712
|
-
return filters.tags.every((tag) => clinic.tags.includes(tag));
|
|
8713
|
-
});
|
|
8714
|
-
}
|
|
8715
|
-
if (filters.minRating !== void 0) {
|
|
8716
|
-
filteredClinics = filteredClinics.filter(
|
|
8717
|
-
(clinic) => clinic.reviewInfo.averageRating >= filters.minRating
|
|
8718
|
-
);
|
|
8719
|
-
}
|
|
8720
|
-
if (filters.maxRating !== void 0) {
|
|
8721
|
-
filteredClinics = filteredClinics.filter(
|
|
8722
|
-
(clinic) => clinic.reviewInfo.averageRating <= filters.maxRating
|
|
8723
|
-
);
|
|
8724
|
-
}
|
|
8725
|
-
lastVisibleDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
8726
|
-
clinicsResult = filteredClinics;
|
|
8727
8593
|
}
|
|
8728
|
-
|
|
8729
|
-
|
|
8730
|
-
lastDoc: lastVisibleDoc
|
|
8731
|
-
};
|
|
8594
|
+
const lastVisibleDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
8595
|
+
return { clinics, lastDoc: lastVisibleDoc };
|
|
8732
8596
|
}
|
|
8733
8597
|
|
|
8734
8598
|
// src/services/clinic/clinic.service.ts
|
|
@@ -8864,6 +8728,8 @@ var ClinicService = class extends BaseService {
|
|
|
8864
8728
|
id: clinicId,
|
|
8865
8729
|
clinicGroupId: validatedData.clinicGroupId,
|
|
8866
8730
|
name: validatedData.name,
|
|
8731
|
+
nameLower: validatedData.name.toLowerCase(),
|
|
8732
|
+
// Add this line
|
|
8867
8733
|
description: validatedData.description,
|
|
8868
8734
|
location: { ...location, geohash: hash },
|
|
8869
8735
|
contactInfo: validatedData.contactInfo,
|
|
@@ -8964,6 +8830,9 @@ var ClinicService = class extends BaseService {
|
|
|
8964
8830
|
updatePayload[field] = validatedData[field];
|
|
8965
8831
|
}
|
|
8966
8832
|
}
|
|
8833
|
+
if (validatedData.name) {
|
|
8834
|
+
updatePayload.nameLower = validatedData.name.toLowerCase();
|
|
8835
|
+
}
|
|
8967
8836
|
if (validatedData.location) {
|
|
8968
8837
|
const loc = validatedData.location;
|
|
8969
8838
|
updatePayload.location = {
|
|
@@ -9139,6 +9008,27 @@ var ClinicService = class extends BaseService {
|
|
|
9139
9008
|
async getClinicsByFilters(filters) {
|
|
9140
9009
|
return getClinicsByFilters(this.db, filters);
|
|
9141
9010
|
}
|
|
9011
|
+
/**
|
|
9012
|
+
* Gets all clinics with minimal info for map display (id, name, address, latitude, longitude)
|
|
9013
|
+
* This is optimized for mobile map usage to reduce payload size.
|
|
9014
|
+
* @returns Array of minimal clinic info for map
|
|
9015
|
+
*/
|
|
9016
|
+
async getClinicsForMap() {
|
|
9017
|
+
const clinicsRef = (0, import_firestore27.collection)(this.db, CLINICS_COLLECTION);
|
|
9018
|
+
const snapshot = await (0, import_firestore27.getDocs)(clinicsRef);
|
|
9019
|
+
const clinicsForMap = snapshot.docs.map((doc37) => {
|
|
9020
|
+
var _a, _b, _c;
|
|
9021
|
+
const data = doc37.data();
|
|
9022
|
+
return {
|
|
9023
|
+
id: doc37.id,
|
|
9024
|
+
name: data.name,
|
|
9025
|
+
address: ((_a = data.location) == null ? void 0 : _a.address) || "",
|
|
9026
|
+
latitude: (_b = data.location) == null ? void 0 : _b.latitude,
|
|
9027
|
+
longitude: (_c = data.location) == null ? void 0 : _c.longitude
|
|
9028
|
+
};
|
|
9029
|
+
});
|
|
9030
|
+
return clinicsForMap;
|
|
9031
|
+
}
|
|
9142
9032
|
};
|
|
9143
9033
|
|
|
9144
9034
|
// src/services/auth/utils/firebase.utils.ts
|
|
@@ -14838,7 +14728,7 @@ var ProcedureService = class extends BaseService {
|
|
|
14838
14728
|
}
|
|
14839
14729
|
let finalCategoryId = existingProcedure.category.id;
|
|
14840
14730
|
if (validatedData.name) {
|
|
14841
|
-
updatedProcedureData.nameLower = validatedData.
|
|
14731
|
+
updatedProcedureData.nameLower = validatedData.name.toLowerCase();
|
|
14842
14732
|
}
|
|
14843
14733
|
if (validatedData.categoryId) {
|
|
14844
14734
|
const category = await this.categoryService.getById(
|
|
@@ -15065,7 +14955,13 @@ var ProcedureService = class extends BaseService {
|
|
|
15065
14955
|
constraints.push((0, import_firestore45.orderBy)("nameLower"));
|
|
15066
14956
|
}
|
|
15067
14957
|
if (filters.lastDoc) {
|
|
15068
|
-
|
|
14958
|
+
if (typeof filters.lastDoc.data === "function") {
|
|
14959
|
+
constraints.push((0, import_firestore45.startAfter)(filters.lastDoc));
|
|
14960
|
+
} else if (Array.isArray(filters.lastDoc)) {
|
|
14961
|
+
constraints.push((0, import_firestore45.startAfter)(...filters.lastDoc));
|
|
14962
|
+
} else {
|
|
14963
|
+
constraints.push((0, import_firestore45.startAfter)(filters.lastDoc));
|
|
14964
|
+
}
|
|
15069
14965
|
}
|
|
15070
14966
|
if (filters.pagination && filters.pagination > 0) {
|
|
15071
14967
|
constraints.push((0, import_firestore45.limit)(filters.pagination));
|
|
@@ -15244,6 +15140,29 @@ var ProcedureService = class extends BaseService {
|
|
|
15244
15140
|
const savedDoc = await (0, import_firestore45.getDoc)(procedureRef);
|
|
15245
15141
|
return savedDoc.data();
|
|
15246
15142
|
}
|
|
15143
|
+
/**
|
|
15144
|
+
* Gets all procedures with minimal info for map display (id, name, clinicId, clinicName, address, latitude, longitude)
|
|
15145
|
+
* This is optimized for mobile map usage to reduce payload size.
|
|
15146
|
+
* @returns Array of minimal procedure info for map
|
|
15147
|
+
*/
|
|
15148
|
+
async getProceduresForMap() {
|
|
15149
|
+
const proceduresRef = (0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION);
|
|
15150
|
+
const snapshot = await (0, import_firestore45.getDocs)(proceduresRef);
|
|
15151
|
+
const proceduresForMap = snapshot.docs.map((doc37) => {
|
|
15152
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
15153
|
+
const data = doc37.data();
|
|
15154
|
+
return {
|
|
15155
|
+
id: doc37.id,
|
|
15156
|
+
name: data.name,
|
|
15157
|
+
clinicId: (_a = data.clinicInfo) == null ? void 0 : _a.id,
|
|
15158
|
+
clinicName: (_b = data.clinicInfo) == null ? void 0 : _b.name,
|
|
15159
|
+
address: ((_d = (_c = data.clinicInfo) == null ? void 0 : _c.location) == null ? void 0 : _d.address) || "",
|
|
15160
|
+
latitude: (_f = (_e = data.clinicInfo) == null ? void 0 : _e.location) == null ? void 0 : _f.latitude,
|
|
15161
|
+
longitude: (_h = (_g = data.clinicInfo) == null ? void 0 : _g.location) == null ? void 0 : _h.longitude
|
|
15162
|
+
};
|
|
15163
|
+
});
|
|
15164
|
+
return proceduresForMap;
|
|
15165
|
+
}
|
|
15247
15166
|
};
|
|
15248
15167
|
|
|
15249
15168
|
// src/services/reviews/reviews.service.ts
|