@blackcode_sa/metaestetics-api 1.11.1 → 1.11.3
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 +326 -330
- package/dist/admin/index.d.ts +326 -330
- package/dist/backoffice/index.d.mts +67 -283
- package/dist/backoffice/index.d.ts +67 -283
- package/dist/backoffice/index.js +6 -114
- package/dist/backoffice/index.mjs +6 -112
- package/dist/index.d.mts +3039 -3100
- package/dist/index.d.ts +3039 -3100
- package/dist/index.js +131 -380
- package/dist/index.mjs +132 -380
- package/package.json +1 -1
- package/src/backoffice/expo-safe/index.ts +0 -2
- package/src/backoffice/services/__tests__/brand.service.test.ts +196 -0
- package/src/backoffice/services/__tests__/category.service.test.ts +201 -0
- package/src/backoffice/services/__tests__/product.service.test.ts +358 -0
- package/src/backoffice/services/__tests__/requirement.service.test.ts +226 -0
- package/src/backoffice/services/__tests__/subcategory.service.test.ts +181 -0
- package/src/backoffice/services/__tests__/technology.service.test.ts +1097 -0
- package/src/backoffice/services/technology.service.ts +10 -122
- package/src/backoffice/types/index.ts +0 -1
- package/src/backoffice/types/product.types.ts +1 -3
- package/src/backoffice/types/technology.types.ts +4 -4
- package/src/backoffice/validations/schemas.ts +9 -35
- package/src/services/appointment/appointment.service.ts +5 -0
- package/src/services/appointment/utils/appointment.utils.ts +113 -124
- package/src/services/procedure/procedure.service.ts +234 -434
- package/src/types/appointment/index.ts +39 -43
- package/src/types/clinic/index.ts +6 -1
- package/src/types/patient/medical-info.types.ts +3 -3
- package/src/types/procedure/index.ts +17 -20
- package/src/validations/appointment.schema.ts +119 -170
- package/src/validations/clinic.schema.ts +6 -1
- package/src/validations/patient/medical-info.schema.ts +2 -7
- package/src/backoffice/services/README.md +0 -40
- package/src/backoffice/services/constants.service.ts +0 -268
- package/src/backoffice/types/admin-constants.types.ts +0 -69
package/dist/index.mjs
CHANGED
|
@@ -53,13 +53,13 @@ var AppointmentStatus = /* @__PURE__ */ ((AppointmentStatus2) => {
|
|
|
53
53
|
AppointmentStatus2["RESCHEDULED_BY_CLINIC"] = "rescheduled_by_clinic";
|
|
54
54
|
return AppointmentStatus2;
|
|
55
55
|
})(AppointmentStatus || {});
|
|
56
|
-
var PaymentStatus = /* @__PURE__ */ ((
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return
|
|
56
|
+
var PaymentStatus = /* @__PURE__ */ ((PaymentStatus3) => {
|
|
57
|
+
PaymentStatus3["UNPAID"] = "unpaid";
|
|
58
|
+
PaymentStatus3["PAID"] = "paid";
|
|
59
|
+
PaymentStatus3["PARTIALLY_PAID"] = "partially_paid";
|
|
60
|
+
PaymentStatus3["REFUNDED"] = "refunded";
|
|
61
|
+
PaymentStatus3["NOT_APPLICABLE"] = "not_applicable";
|
|
62
|
+
return PaymentStatus3;
|
|
63
63
|
})(PaymentStatus || {});
|
|
64
64
|
var MediaType = /* @__PURE__ */ ((MediaType2) => {
|
|
65
65
|
MediaType2["BEFORE_PHOTO"] = "before_photo";
|
|
@@ -411,7 +411,8 @@ var finalizedDetailsSchema = z3.object({
|
|
|
411
411
|
var beforeAfterPerZoneSchema = z3.object({
|
|
412
412
|
before: mediaResourceSchema.nullable(),
|
|
413
413
|
after: mediaResourceSchema.nullable(),
|
|
414
|
-
|
|
414
|
+
afterNote: z3.string().nullable().optional(),
|
|
415
|
+
beforeNote: z3.string().nullable().optional()
|
|
415
416
|
});
|
|
416
417
|
var billingPerZoneSchema = z3.object({
|
|
417
418
|
Product: z3.string().min(MIN_STRING_LENGTH, "Product name is required"),
|
|
@@ -421,7 +422,8 @@ var billingPerZoneSchema = z3.object({
|
|
|
421
422
|
UnitPrice: z3.number().min(0, "Unit price must be non-negative"),
|
|
422
423
|
UnitCurency: z3.nativeEnum(Currency),
|
|
423
424
|
Subtotal: z3.number().min(0, "Subtotal must be non-negative"),
|
|
424
|
-
Note: z3.string().nullable()
|
|
425
|
+
Note: z3.string().nullable(),
|
|
426
|
+
IonNumber: z3.string().nullable()
|
|
425
427
|
});
|
|
426
428
|
var finalBillingSchema = z3.object({
|
|
427
429
|
subtotalAll: z3.number().min(0, "Subtotal all must be non-negative"),
|
|
@@ -436,7 +438,8 @@ var appointmentMetadataSchema = z3.object({
|
|
|
436
438
|
selectedZones: z3.array(z3.string()).nullable(),
|
|
437
439
|
zonePhotos: z3.record(z3.string(), beforeAfterPerZoneSchema).nullable(),
|
|
438
440
|
zoneBilling: z3.record(z3.string(), billingPerZoneSchema).nullable(),
|
|
439
|
-
finalbilling: finalBillingSchema.nullable()
|
|
441
|
+
finalbilling: finalBillingSchema.nullable(),
|
|
442
|
+
finalizationNotes: z3.string().nullable()
|
|
440
443
|
});
|
|
441
444
|
var createAppointmentSchema = z3.object({
|
|
442
445
|
clinicBranchId: z3.string().min(MIN_STRING_LENGTH, "Clinic branch ID is required"),
|
|
@@ -492,10 +495,7 @@ var updateAppointmentSchema = z3.object({
|
|
|
492
495
|
practitionerId: z3.string().min(MIN_STRING_LENGTH).optional(),
|
|
493
496
|
clinic_tz: z3.string().min(MIN_STRING_LENGTH).optional(),
|
|
494
497
|
linkedForms: z3.union([z3.array(linkedFormInfoSchema).max(MAX_ARRAY_LENGTH), z3.any()]).optional(),
|
|
495
|
-
media: z3.union([
|
|
496
|
-
z3.array(appointmentMediaItemSchema).max(MAX_ARRAY_LENGTH),
|
|
497
|
-
z3.any()
|
|
498
|
-
]).optional(),
|
|
498
|
+
media: z3.union([z3.array(appointmentMediaItemSchema).max(MAX_ARRAY_LENGTH), z3.any()]).optional(),
|
|
499
499
|
reviewInfo: z3.union([patientReviewInfoSchema.nullable(), z3.any()]).optional(),
|
|
500
500
|
finalizedDetails: z3.union([finalizedDetailsSchema.nullable(), z3.any()]).optional(),
|
|
501
501
|
isArchived: z3.boolean().optional(),
|
|
@@ -536,10 +536,7 @@ var searchAppointmentsSchema = z3.object({
|
|
|
536
536
|
(val) => val === void 0 || val instanceof Date || (val == null ? void 0 : val._seconds) !== void 0 || (val == null ? void 0 : val.seconds) !== void 0 || typeof val === "number" || typeof val === "string" || val && typeof val.toMillis === "function",
|
|
537
537
|
"End date must be a valid timestamp or Date object"
|
|
538
538
|
).optional(),
|
|
539
|
-
status: z3.union([
|
|
540
|
-
appointmentStatusSchema,
|
|
541
|
-
z3.array(appointmentStatusSchema).nonempty()
|
|
542
|
-
]).optional(),
|
|
539
|
+
status: z3.union([appointmentStatusSchema, z3.array(appointmentStatusSchema).nonempty()]).optional(),
|
|
543
540
|
limit: z3.number().positive().int().optional().default(20),
|
|
544
541
|
startAfter: z3.any().optional()
|
|
545
542
|
}).refine(
|
|
@@ -585,6 +582,7 @@ import {
|
|
|
585
582
|
getDocs,
|
|
586
583
|
query,
|
|
587
584
|
where,
|
|
585
|
+
setDoc,
|
|
588
586
|
updateDoc,
|
|
589
587
|
serverTimestamp,
|
|
590
588
|
Timestamp,
|
|
@@ -821,48 +819,44 @@ async function updateAppointmentUtil(db, appointmentId, data) {
|
|
|
821
819
|
const validPreReqIds = currentAppointment.preProcedureRequirements.map(
|
|
822
820
|
(req) => req.id
|
|
823
821
|
);
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
822
|
+
const invalidPreReqIds = data.completedPreRequirements.filter(
|
|
823
|
+
(id) => !validPreReqIds.includes(id)
|
|
824
|
+
);
|
|
825
|
+
if (invalidPreReqIds.length > 0) {
|
|
826
|
+
throw new Error(
|
|
827
|
+
`Invalid pre-requirement IDs: ${invalidPreReqIds.join(", ")}`
|
|
827
828
|
);
|
|
828
|
-
if (invalidPreReqIds.length > 0) {
|
|
829
|
-
throw new Error(
|
|
830
|
-
`Invalid pre-requirement IDs: ${invalidPreReqIds.join(", ")}`
|
|
831
|
-
);
|
|
832
|
-
}
|
|
833
|
-
completedPreRequirements = [
|
|
834
|
-
.../* @__PURE__ */ new Set([
|
|
835
|
-
...completedPreRequirements,
|
|
836
|
-
...data.completedPreRequirements
|
|
837
|
-
])
|
|
838
|
-
];
|
|
839
829
|
}
|
|
830
|
+
completedPreRequirements = [
|
|
831
|
+
.../* @__PURE__ */ new Set([
|
|
832
|
+
...completedPreRequirements,
|
|
833
|
+
...data.completedPreRequirements
|
|
834
|
+
])
|
|
835
|
+
];
|
|
840
836
|
}
|
|
841
837
|
if (data.completedPostRequirements) {
|
|
842
838
|
const validPostReqIds = currentAppointment.postProcedureRequirements.map(
|
|
843
839
|
(req) => req.id
|
|
844
840
|
);
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
841
|
+
const invalidPostReqIds = data.completedPostRequirements.filter(
|
|
842
|
+
(id) => !validPostReqIds.includes(id)
|
|
843
|
+
);
|
|
844
|
+
if (invalidPostReqIds.length > 0) {
|
|
845
|
+
throw new Error(
|
|
846
|
+
`Invalid post-requirement IDs: ${invalidPostReqIds.join(", ")}`
|
|
848
847
|
);
|
|
849
|
-
if (invalidPostReqIds.length > 0) {
|
|
850
|
-
throw new Error(
|
|
851
|
-
`Invalid post-requirement IDs: ${invalidPostReqIds.join(", ")}`
|
|
852
|
-
);
|
|
853
|
-
}
|
|
854
|
-
completedPostRequirements = [
|
|
855
|
-
.../* @__PURE__ */ new Set([
|
|
856
|
-
...completedPostRequirements,
|
|
857
|
-
...data.completedPostRequirements
|
|
858
|
-
])
|
|
859
|
-
];
|
|
860
848
|
}
|
|
849
|
+
completedPostRequirements = [
|
|
850
|
+
.../* @__PURE__ */ new Set([
|
|
851
|
+
...completedPostRequirements,
|
|
852
|
+
...data.completedPostRequirements
|
|
853
|
+
])
|
|
854
|
+
];
|
|
861
855
|
}
|
|
862
856
|
const updateData = {
|
|
863
857
|
...data,
|
|
864
|
-
completedPreRequirements
|
|
865
|
-
completedPostRequirements
|
|
858
|
+
completedPreRequirements,
|
|
859
|
+
completedPostRequirements,
|
|
866
860
|
updatedAt: serverTimestamp()
|
|
867
861
|
};
|
|
868
862
|
Object.keys(updateData).forEach((key) => {
|
|
@@ -912,7 +906,7 @@ async function updateCalendarEventStatus(db, calendarEventId, appointmentStatus)
|
|
|
912
906
|
case "canceled_clinic" /* CANCELED_CLINIC */:
|
|
913
907
|
calendarStatus = "canceled";
|
|
914
908
|
break;
|
|
915
|
-
case
|
|
909
|
+
case AppointmentStatus.RESCHEDULED:
|
|
916
910
|
calendarStatus = "rescheduled";
|
|
917
911
|
break;
|
|
918
912
|
case "completed" /* COMPLETED */:
|
|
@@ -2805,6 +2799,23 @@ var BlockingCondition = /* @__PURE__ */ ((BlockingCondition2) => {
|
|
|
2805
2799
|
return BlockingCondition2;
|
|
2806
2800
|
})(BlockingCondition || {});
|
|
2807
2801
|
|
|
2802
|
+
// src/backoffice/types/static/contraindication.types.ts
|
|
2803
|
+
var Contraindication = /* @__PURE__ */ ((Contraindication2) => {
|
|
2804
|
+
Contraindication2["SENSITIVE_SKIN"] = "sensitive_skin";
|
|
2805
|
+
Contraindication2["RECENT_TANNING"] = "recent_tanning";
|
|
2806
|
+
Contraindication2["RECENT_BOTOX"] = "recent_botox";
|
|
2807
|
+
Contraindication2["RECENT_FILLERS"] = "recent_fillers";
|
|
2808
|
+
Contraindication2["SKIN_ALLERGIES"] = "skin_allergies";
|
|
2809
|
+
Contraindication2["MEDICATIONS"] = "medications";
|
|
2810
|
+
Contraindication2["RECENT_CHEMICAL_PEEL"] = "recent_chemical_peel";
|
|
2811
|
+
Contraindication2["RECENT_LASER"] = "recent_laser";
|
|
2812
|
+
Contraindication2["SKIN_INFLAMMATION"] = "skin_inflammation";
|
|
2813
|
+
Contraindication2["OPEN_WOUNDS"] = "open_wounds";
|
|
2814
|
+
Contraindication2["HERPES_SIMPLEX"] = "herpes_simplex";
|
|
2815
|
+
Contraindication2["COLD_SORES"] = "cold_sores";
|
|
2816
|
+
return Contraindication2;
|
|
2817
|
+
})(Contraindication || {});
|
|
2818
|
+
|
|
2808
2819
|
// src/validations/common.schema.ts
|
|
2809
2820
|
import { z as z5 } from "zod";
|
|
2810
2821
|
import { Timestamp as Timestamp4 } from "firebase/firestore";
|
|
@@ -2859,13 +2870,8 @@ var blockingConditionSchema = z6.object({
|
|
|
2859
2870
|
notes: z6.string().optional().nullable(),
|
|
2860
2871
|
isActive: z6.boolean()
|
|
2861
2872
|
});
|
|
2862
|
-
var contraindicationDynamicSchema = z6.object({
|
|
2863
|
-
id: z6.string(),
|
|
2864
|
-
name: z6.string(),
|
|
2865
|
-
description: z6.string().optional()
|
|
2866
|
-
});
|
|
2867
2873
|
var contraindicationSchema = z6.object({
|
|
2868
|
-
condition:
|
|
2874
|
+
condition: z6.nativeEnum(Contraindication),
|
|
2869
2875
|
lastOccurrence: timestampSchema,
|
|
2870
2876
|
frequency: z6.enum(["rare", "occasional", "frequent"]),
|
|
2871
2877
|
notes: z6.string().optional().nullable(),
|
|
@@ -10770,7 +10776,7 @@ async function updatePractitionerCalendarEventUtil(db, practitionerId, eventId,
|
|
|
10770
10776
|
}
|
|
10771
10777
|
|
|
10772
10778
|
// src/services/calendar/utils/appointment.utils.ts
|
|
10773
|
-
async function
|
|
10779
|
+
async function createAppointmentUtil2(db, clinicId, practitionerId, patientId, eventData, generateId2) {
|
|
10774
10780
|
const eventId = generateId2();
|
|
10775
10781
|
const autoConfirm = await checkAutoConfirmAppointmentsUtil(db, clinicId);
|
|
10776
10782
|
const initialStatus = autoConfirm ? "confirmed" /* CONFIRMED */ : "pending" /* PENDING */;
|
|
@@ -12112,7 +12118,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
12112
12118
|
syncStatus: "internal" /* INTERNAL */,
|
|
12113
12119
|
eventType: "appointment" /* APPOINTMENT */
|
|
12114
12120
|
};
|
|
12115
|
-
const appointment = await
|
|
12121
|
+
const appointment = await createAppointmentUtil2(
|
|
12116
12122
|
this.db,
|
|
12117
12123
|
params.clinicId,
|
|
12118
12124
|
params.doctorId,
|
|
@@ -14996,9 +15002,7 @@ var ProcedureService = class extends BaseService {
|
|
|
14996
15002
|
return media;
|
|
14997
15003
|
}
|
|
14998
15004
|
if (media instanceof File || media instanceof Blob) {
|
|
14999
|
-
console.log(
|
|
15000
|
-
`[ProcedureService] Uploading ${collectionName} media for ${ownerId}`
|
|
15001
|
-
);
|
|
15005
|
+
console.log(`[ProcedureService] Uploading ${collectionName} media for ${ownerId}`);
|
|
15002
15006
|
const metadata = await this.mediaService.uploadMedia(
|
|
15003
15007
|
media,
|
|
15004
15008
|
ownerId,
|
|
@@ -15020,11 +15024,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15020
15024
|
if (!mediaArray || mediaArray.length === 0) return [];
|
|
15021
15025
|
const result = [];
|
|
15022
15026
|
for (const media of mediaArray) {
|
|
15023
|
-
const processedUrl = await this.processMedia(
|
|
15024
|
-
media,
|
|
15025
|
-
ownerId,
|
|
15026
|
-
collectionName
|
|
15027
|
-
);
|
|
15027
|
+
const processedUrl = await this.processMedia(media, ownerId, collectionName);
|
|
15028
15028
|
if (processedUrl) {
|
|
15029
15029
|
result.push(processedUrl);
|
|
15030
15030
|
}
|
|
@@ -15037,46 +15037,28 @@ var ProcedureService = class extends BaseService {
|
|
|
15037
15037
|
* @returns The created procedure
|
|
15038
15038
|
*/
|
|
15039
15039
|
async createProcedure(data) {
|
|
15040
|
-
var _a
|
|
15040
|
+
var _a;
|
|
15041
15041
|
const validatedData = createProcedureSchema.parse(data);
|
|
15042
15042
|
const procedureId = this.generateId();
|
|
15043
15043
|
const [category, subcategory, technology, product] = await Promise.all([
|
|
15044
15044
|
this.categoryService.getById(validatedData.categoryId),
|
|
15045
|
-
this.subcategoryService.getById(
|
|
15046
|
-
validatedData.categoryId,
|
|
15047
|
-
validatedData.subcategoryId
|
|
15048
|
-
),
|
|
15045
|
+
this.subcategoryService.getById(validatedData.categoryId, validatedData.subcategoryId),
|
|
15049
15046
|
this.technologyService.getById(validatedData.technologyId),
|
|
15050
|
-
this.productService.getById(
|
|
15051
|
-
validatedData.technologyId,
|
|
15052
|
-
validatedData.productId
|
|
15053
|
-
)
|
|
15047
|
+
this.productService.getById(validatedData.technologyId, validatedData.productId)
|
|
15054
15048
|
]);
|
|
15055
15049
|
if (!category || !subcategory || !technology || !product) {
|
|
15056
15050
|
throw new Error("One or more required base entities not found");
|
|
15057
15051
|
}
|
|
15058
|
-
const clinicRef = doc30(
|
|
15059
|
-
this.db,
|
|
15060
|
-
CLINICS_COLLECTION,
|
|
15061
|
-
validatedData.clinicBranchId
|
|
15062
|
-
);
|
|
15052
|
+
const clinicRef = doc30(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId);
|
|
15063
15053
|
const clinicSnapshot = await getDoc32(clinicRef);
|
|
15064
15054
|
if (!clinicSnapshot.exists()) {
|
|
15065
|
-
throw new Error(
|
|
15066
|
-
`Clinic with ID ${validatedData.clinicBranchId} not found`
|
|
15067
|
-
);
|
|
15055
|
+
throw new Error(`Clinic with ID ${validatedData.clinicBranchId} not found`);
|
|
15068
15056
|
}
|
|
15069
15057
|
const clinic = clinicSnapshot.data();
|
|
15070
|
-
const practitionerRef = doc30(
|
|
15071
|
-
this.db,
|
|
15072
|
-
PRACTITIONERS_COLLECTION,
|
|
15073
|
-
validatedData.practitionerId
|
|
15074
|
-
);
|
|
15058
|
+
const practitionerRef = doc30(this.db, PRACTITIONERS_COLLECTION, validatedData.practitionerId);
|
|
15075
15059
|
const practitionerSnapshot = await getDoc32(practitionerRef);
|
|
15076
15060
|
if (!practitionerSnapshot.exists()) {
|
|
15077
|
-
throw new Error(
|
|
15078
|
-
`Practitioner with ID ${validatedData.practitionerId} not found`
|
|
15079
|
-
);
|
|
15061
|
+
throw new Error(`Practitioner with ID ${validatedData.practitionerId} not found`);
|
|
15080
15062
|
}
|
|
15081
15063
|
const practitioner = practitionerSnapshot.data();
|
|
15082
15064
|
let processedPhotos = [];
|
|
@@ -15117,9 +15099,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15117
15099
|
product,
|
|
15118
15100
|
blockingConditions: technology.blockingConditions,
|
|
15119
15101
|
contraindications: technology.contraindications || [],
|
|
15120
|
-
contraindicationIds: ((_b = technology.contraindications) == null ? void 0 : _b.map((c) => c.id)) || [],
|
|
15121
15102
|
treatmentBenefits: technology.benefits,
|
|
15122
|
-
treatmentBenefitIds: ((_c = technology.benefits) == null ? void 0 : _c.map((b) => b.id)) || [],
|
|
15123
15103
|
preRequirements: technology.requirements.pre,
|
|
15124
15104
|
postRequirements: technology.requirements.post,
|
|
15125
15105
|
certificationRequirement: technology.certificationRequirement,
|
|
@@ -15160,7 +15140,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15160
15140
|
* @returns A promise that resolves to an array of the newly created procedures.
|
|
15161
15141
|
*/
|
|
15162
15142
|
async bulkCreateProcedures(baseData, practitionerIds) {
|
|
15163
|
-
var _a
|
|
15143
|
+
var _a;
|
|
15164
15144
|
if (!practitionerIds || practitionerIds.length === 0) {
|
|
15165
15145
|
throw new Error("Practitioner IDs array cannot be empty.");
|
|
15166
15146
|
}
|
|
@@ -15168,24 +15148,16 @@ var ProcedureService = class extends BaseService {
|
|
|
15168
15148
|
const validatedData = createProcedureSchema.parse(validationData);
|
|
15169
15149
|
const [category, subcategory, technology, product, clinicSnapshot] = await Promise.all([
|
|
15170
15150
|
this.categoryService.getById(validatedData.categoryId),
|
|
15171
|
-
this.subcategoryService.getById(
|
|
15172
|
-
validatedData.categoryId,
|
|
15173
|
-
validatedData.subcategoryId
|
|
15174
|
-
),
|
|
15151
|
+
this.subcategoryService.getById(validatedData.categoryId, validatedData.subcategoryId),
|
|
15175
15152
|
this.technologyService.getById(validatedData.technologyId),
|
|
15176
|
-
this.productService.getById(
|
|
15177
|
-
validatedData.technologyId,
|
|
15178
|
-
validatedData.productId
|
|
15179
|
-
),
|
|
15153
|
+
this.productService.getById(validatedData.technologyId, validatedData.productId),
|
|
15180
15154
|
getDoc32(doc30(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId))
|
|
15181
15155
|
]);
|
|
15182
15156
|
if (!category || !subcategory || !technology || !product) {
|
|
15183
15157
|
throw new Error("One or more required base entities not found");
|
|
15184
15158
|
}
|
|
15185
15159
|
if (!clinicSnapshot.exists()) {
|
|
15186
|
-
throw new Error(
|
|
15187
|
-
`Clinic with ID ${validatedData.clinicBranchId} not found`
|
|
15188
|
-
);
|
|
15160
|
+
throw new Error(`Clinic with ID ${validatedData.clinicBranchId} not found`);
|
|
15189
15161
|
}
|
|
15190
15162
|
const clinic = clinicSnapshot.data();
|
|
15191
15163
|
let processedPhotos = [];
|
|
@@ -15211,12 +15183,8 @@ var ProcedureService = class extends BaseService {
|
|
|
15211
15183
|
}
|
|
15212
15184
|
if (practitionersMap.size !== practitionerIds.length) {
|
|
15213
15185
|
const foundIds = Array.from(practitionersMap.keys());
|
|
15214
|
-
const notFoundIds = practitionerIds.filter(
|
|
15215
|
-
|
|
15216
|
-
);
|
|
15217
|
-
throw new Error(
|
|
15218
|
-
`The following practitioners were not found: ${notFoundIds.join(", ")}`
|
|
15219
|
-
);
|
|
15186
|
+
const notFoundIds = practitionerIds.filter((id) => !foundIds.includes(id));
|
|
15187
|
+
throw new Error(`The following practitioners were not found: ${notFoundIds.join(", ")}`);
|
|
15220
15188
|
}
|
|
15221
15189
|
const batch = writeBatch6(this.db);
|
|
15222
15190
|
const createdProcedureIds = [];
|
|
@@ -15254,9 +15222,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15254
15222
|
product,
|
|
15255
15223
|
blockingConditions: technology.blockingConditions,
|
|
15256
15224
|
contraindications: technology.contraindications || [],
|
|
15257
|
-
contraindicationIds: ((_b = technology.contraindications) == null ? void 0 : _b.map((c) => c.id)) || [],
|
|
15258
15225
|
treatmentBenefits: technology.benefits,
|
|
15259
|
-
treatmentBenefitIds: ((_c = technology.benefits) == null ? void 0 : _c.map((b) => b.id)) || [],
|
|
15260
15226
|
preRequirements: technology.requirements.pre,
|
|
15261
15227
|
postRequirements: technology.requirements.post,
|
|
15262
15228
|
certificationRequirement: technology.certificationRequirement,
|
|
@@ -15286,10 +15252,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15286
15252
|
const fetchedProcedures = [];
|
|
15287
15253
|
for (let i = 0; i < createdProcedureIds.length; i += 30) {
|
|
15288
15254
|
const chunk = createdProcedureIds.slice(i, i + 30);
|
|
15289
|
-
const q = query29(
|
|
15290
|
-
collection29(this.db, PROCEDURES_COLLECTION),
|
|
15291
|
-
where29(documentId2(), "in", chunk)
|
|
15292
|
-
);
|
|
15255
|
+
const q = query29(collection29(this.db, PROCEDURES_COLLECTION), where29(documentId2(), "in", chunk));
|
|
15293
15256
|
const snapshot = await getDocs29(q);
|
|
15294
15257
|
snapshot.forEach((doc37) => {
|
|
15295
15258
|
fetchedProcedures.push(doc37.data());
|
|
@@ -15359,7 +15322,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15359
15322
|
* @returns The updated procedure
|
|
15360
15323
|
*/
|
|
15361
15324
|
async updateProcedure(id, data) {
|
|
15362
|
-
var _a
|
|
15325
|
+
var _a;
|
|
15363
15326
|
const validatedData = updateProcedureSchema.parse(data);
|
|
15364
15327
|
const procedureRef = doc30(this.db, PROCEDURES_COLLECTION, id);
|
|
15365
15328
|
const procedureSnapshot = await getDoc32(procedureRef);
|
|
@@ -15390,9 +15353,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15390
15353
|
);
|
|
15391
15354
|
const newPractitionerSnap = await getDoc32(newPractitionerRef);
|
|
15392
15355
|
if (!newPractitionerSnap.exists())
|
|
15393
|
-
throw new Error(
|
|
15394
|
-
`New Practitioner ${validatedData.practitionerId} not found`
|
|
15395
|
-
);
|
|
15356
|
+
throw new Error(`New Practitioner ${validatedData.practitionerId} not found`);
|
|
15396
15357
|
newPractitioner = newPractitionerSnap.data();
|
|
15397
15358
|
updatedProcedureData.doctorInfo = {
|
|
15398
15359
|
id: newPractitioner.id,
|
|
@@ -15406,11 +15367,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15406
15367
|
}
|
|
15407
15368
|
if (validatedData.clinicBranchId && validatedData.clinicBranchId !== oldClinicId) {
|
|
15408
15369
|
clinicChanged = true;
|
|
15409
|
-
const newClinicRef = doc30(
|
|
15410
|
-
this.db,
|
|
15411
|
-
CLINICS_COLLECTION,
|
|
15412
|
-
validatedData.clinicBranchId
|
|
15413
|
-
);
|
|
15370
|
+
const newClinicRef = doc30(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId);
|
|
15414
15371
|
const newClinicSnap = await getDoc32(newClinicRef);
|
|
15415
15372
|
if (!newClinicSnap.exists())
|
|
15416
15373
|
throw new Error(`New Clinic ${validatedData.clinicBranchId} not found`);
|
|
@@ -15429,11 +15386,8 @@ var ProcedureService = class extends BaseService {
|
|
|
15429
15386
|
updatedProcedureData.nameLower = validatedData.name.toLowerCase();
|
|
15430
15387
|
}
|
|
15431
15388
|
if (validatedData.categoryId) {
|
|
15432
|
-
const category = await this.categoryService.getById(
|
|
15433
|
-
|
|
15434
|
-
);
|
|
15435
|
-
if (!category)
|
|
15436
|
-
throw new Error(`Category ${validatedData.categoryId} not found`);
|
|
15389
|
+
const category = await this.categoryService.getById(validatedData.categoryId);
|
|
15390
|
+
if (!category) throw new Error(`Category ${validatedData.categoryId} not found`);
|
|
15437
15391
|
updatedProcedureData.category = category;
|
|
15438
15392
|
finalCategoryId = category.id;
|
|
15439
15393
|
}
|
|
@@ -15448,34 +15402,23 @@ var ProcedureService = class extends BaseService {
|
|
|
15448
15402
|
);
|
|
15449
15403
|
updatedProcedureData.subcategory = subcategory;
|
|
15450
15404
|
} else if (validatedData.subcategoryId) {
|
|
15451
|
-
console.warn(
|
|
15452
|
-
"Attempted to update subcategory without a valid categoryId"
|
|
15453
|
-
);
|
|
15405
|
+
console.warn("Attempted to update subcategory without a valid categoryId");
|
|
15454
15406
|
}
|
|
15455
15407
|
let finalTechnologyId = existingProcedure.technology.id;
|
|
15456
15408
|
if (validatedData.technologyId) {
|
|
15457
|
-
const technology = await this.technologyService.getById(
|
|
15458
|
-
|
|
15459
|
-
);
|
|
15460
|
-
if (!technology)
|
|
15461
|
-
throw new Error(`Technology ${validatedData.technologyId} not found`);
|
|
15409
|
+
const technology = await this.technologyService.getById(validatedData.technologyId);
|
|
15410
|
+
if (!technology) throw new Error(`Technology ${validatedData.technologyId} not found`);
|
|
15462
15411
|
updatedProcedureData.technology = technology;
|
|
15463
15412
|
finalTechnologyId = technology.id;
|
|
15464
15413
|
updatedProcedureData.blockingConditions = technology.blockingConditions;
|
|
15465
|
-
updatedProcedureData.contraindications = technology.contraindications || [];
|
|
15466
|
-
updatedProcedureData.contraindicationIds = ((_b = technology.contraindications) == null ? void 0 : _b.map((c) => c.id)) || [];
|
|
15467
15414
|
updatedProcedureData.treatmentBenefits = technology.benefits;
|
|
15468
|
-
updatedProcedureData.treatmentBenefitIds = ((_c = technology.benefits) == null ? void 0 : _c.map((b) => b.id)) || [];
|
|
15469
15415
|
updatedProcedureData.preRequirements = technology.requirements.pre;
|
|
15470
15416
|
updatedProcedureData.postRequirements = technology.requirements.post;
|
|
15471
15417
|
updatedProcedureData.certificationRequirement = technology.certificationRequirement;
|
|
15472
15418
|
updatedProcedureData.documentationTemplates = technology.documentationTemplates || [];
|
|
15473
15419
|
}
|
|
15474
15420
|
if (validatedData.productId && finalTechnologyId) {
|
|
15475
|
-
const product = await this.productService.getById(
|
|
15476
|
-
finalTechnologyId,
|
|
15477
|
-
validatedData.productId
|
|
15478
|
-
);
|
|
15421
|
+
const product = await this.productService.getById(finalTechnologyId, validatedData.productId);
|
|
15479
15422
|
if (!product)
|
|
15480
15423
|
throw new Error(
|
|
15481
15424
|
`Product ${validatedData.productId} not found for technology ${finalTechnologyId}`
|
|
@@ -15557,11 +15500,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15557
15500
|
limit16(pagination)
|
|
15558
15501
|
);
|
|
15559
15502
|
} else {
|
|
15560
|
-
proceduresQuery = query29(
|
|
15561
|
-
proceduresCollection,
|
|
15562
|
-
orderBy17("name"),
|
|
15563
|
-
limit16(pagination)
|
|
15564
|
-
);
|
|
15503
|
+
proceduresQuery = query29(proceduresCollection, orderBy17("name"), limit16(pagination));
|
|
15565
15504
|
}
|
|
15566
15505
|
} else {
|
|
15567
15506
|
proceduresQuery = query29(proceduresCollection, orderBy17("name"));
|
|
@@ -15592,7 +15531,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15592
15531
|
*
|
|
15593
15532
|
* @param filters - Various filters to apply
|
|
15594
15533
|
* @param filters.nameSearch - Optional search text for procedure name
|
|
15595
|
-
* @param filters.
|
|
15534
|
+
* @param filters.treatmentBenefits - Optional array of treatment benefits to filter by
|
|
15596
15535
|
* @param filters.procedureFamily - Optional procedure family to filter by
|
|
15597
15536
|
* @param filters.procedureCategory - Optional procedure category to filter by
|
|
15598
15537
|
* @param filters.procedureSubcategory - Optional procedure subcategory to filter by
|
|
@@ -15610,9 +15549,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15610
15549
|
*/
|
|
15611
15550
|
async getProceduresByFilters(filters) {
|
|
15612
15551
|
try {
|
|
15613
|
-
console.log(
|
|
15614
|
-
"[PROCEDURE_SERVICE] Starting procedure filtering with multiple strategies"
|
|
15615
|
-
);
|
|
15552
|
+
console.log("[PROCEDURE_SERVICE] Starting procedure filtering with multiple strategies");
|
|
15616
15553
|
if (filters.location && filters.radiusInKm) {
|
|
15617
15554
|
console.log("[PROCEDURE_SERVICE] Executing geo query:", {
|
|
15618
15555
|
location: filters.location,
|
|
@@ -15620,10 +15557,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15620
15557
|
serviceName: "ProcedureService"
|
|
15621
15558
|
});
|
|
15622
15559
|
if (!filters.location.latitude || !filters.location.longitude) {
|
|
15623
|
-
console.warn(
|
|
15624
|
-
"[PROCEDURE_SERVICE] Invalid location data:",
|
|
15625
|
-
filters.location
|
|
15626
|
-
);
|
|
15560
|
+
console.warn("[PROCEDURE_SERVICE] Invalid location data:", filters.location);
|
|
15627
15561
|
filters.location = void 0;
|
|
15628
15562
|
filters.radiusInKm = void 0;
|
|
15629
15563
|
}
|
|
@@ -15643,19 +15577,13 @@ var ProcedureService = class extends BaseService {
|
|
|
15643
15577
|
constraints.push(where29("family", "==", filters.procedureFamily));
|
|
15644
15578
|
}
|
|
15645
15579
|
if (filters.procedureCategory) {
|
|
15646
|
-
constraints.push(
|
|
15647
|
-
where29("category.id", "==", filters.procedureCategory)
|
|
15648
|
-
);
|
|
15580
|
+
constraints.push(where29("category.id", "==", filters.procedureCategory));
|
|
15649
15581
|
}
|
|
15650
15582
|
if (filters.procedureSubcategory) {
|
|
15651
|
-
constraints.push(
|
|
15652
|
-
where29("subcategory.id", "==", filters.procedureSubcategory)
|
|
15653
|
-
);
|
|
15583
|
+
constraints.push(where29("subcategory.id", "==", filters.procedureSubcategory));
|
|
15654
15584
|
}
|
|
15655
15585
|
if (filters.procedureTechnology) {
|
|
15656
|
-
constraints.push(
|
|
15657
|
-
where29("technology.id", "==", filters.procedureTechnology)
|
|
15658
|
-
);
|
|
15586
|
+
constraints.push(where29("technology.id", "==", filters.procedureTechnology));
|
|
15659
15587
|
}
|
|
15660
15588
|
if (filters.minPrice !== void 0) {
|
|
15661
15589
|
constraints.push(where29("price", ">=", filters.minPrice));
|
|
@@ -15664,32 +15592,20 @@ var ProcedureService = class extends BaseService {
|
|
|
15664
15592
|
constraints.push(where29("price", "<=", filters.maxPrice));
|
|
15665
15593
|
}
|
|
15666
15594
|
if (filters.minRating !== void 0) {
|
|
15667
|
-
constraints.push(
|
|
15668
|
-
where29("reviewInfo.averageRating", ">=", filters.minRating)
|
|
15669
|
-
);
|
|
15595
|
+
constraints.push(where29("reviewInfo.averageRating", ">=", filters.minRating));
|
|
15670
15596
|
}
|
|
15671
15597
|
if (filters.maxRating !== void 0) {
|
|
15672
|
-
constraints.push(
|
|
15673
|
-
where29("reviewInfo.averageRating", "<=", filters.maxRating)
|
|
15674
|
-
);
|
|
15598
|
+
constraints.push(where29("reviewInfo.averageRating", "<=", filters.maxRating));
|
|
15675
15599
|
}
|
|
15676
15600
|
if (filters.treatmentBenefits && filters.treatmentBenefits.length > 0) {
|
|
15677
|
-
const
|
|
15678
|
-
constraints.push(
|
|
15679
|
-
where29(
|
|
15680
|
-
"treatmentBenefitIds",
|
|
15681
|
-
"array-contains-any",
|
|
15682
|
-
benefitIdsToMatch
|
|
15683
|
-
)
|
|
15684
|
-
);
|
|
15601
|
+
const benefitsToMatch = filters.treatmentBenefits;
|
|
15602
|
+
constraints.push(where29("treatmentBenefits", "array-contains-any", benefitsToMatch));
|
|
15685
15603
|
}
|
|
15686
15604
|
return constraints;
|
|
15687
15605
|
};
|
|
15688
15606
|
if (filters.nameSearch && filters.nameSearch.trim()) {
|
|
15689
15607
|
try {
|
|
15690
|
-
console.log(
|
|
15691
|
-
"[PROCEDURE_SERVICE] Strategy 1: Trying nameLower search"
|
|
15692
|
-
);
|
|
15608
|
+
console.log("[PROCEDURE_SERVICE] Strategy 1: Trying nameLower search");
|
|
15693
15609
|
const searchTerm = filters.nameSearch.trim().toLowerCase();
|
|
15694
15610
|
const constraints = getBaseConstraints();
|
|
15695
15611
|
constraints.push(where29("nameLower", ">=", searchTerm));
|
|
@@ -15705,18 +15621,13 @@ var ProcedureService = class extends BaseService {
|
|
|
15705
15621
|
}
|
|
15706
15622
|
}
|
|
15707
15623
|
constraints.push(limit15(filters.pagination || 10));
|
|
15708
|
-
const q = query29(
|
|
15709
|
-
collection29(this.db, PROCEDURES_COLLECTION),
|
|
15710
|
-
...constraints
|
|
15711
|
-
);
|
|
15624
|
+
const q = query29(collection29(this.db, PROCEDURES_COLLECTION), ...constraints);
|
|
15712
15625
|
const querySnapshot = await getDocs29(q);
|
|
15713
15626
|
const procedures = querySnapshot.docs.map(
|
|
15714
15627
|
(doc37) => ({ ...doc37.data(), id: doc37.id })
|
|
15715
15628
|
);
|
|
15716
15629
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15717
|
-
console.log(
|
|
15718
|
-
`[PROCEDURE_SERVICE] Strategy 1 success: ${procedures.length} procedures`
|
|
15719
|
-
);
|
|
15630
|
+
console.log(`[PROCEDURE_SERVICE] Strategy 1 success: ${procedures.length} procedures`);
|
|
15720
15631
|
if (procedures.length < (filters.pagination || 10)) {
|
|
15721
15632
|
return { procedures, lastDoc: null };
|
|
15722
15633
|
}
|
|
@@ -15727,9 +15638,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15727
15638
|
}
|
|
15728
15639
|
if (filters.nameSearch && filters.nameSearch.trim()) {
|
|
15729
15640
|
try {
|
|
15730
|
-
console.log(
|
|
15731
|
-
"[PROCEDURE_SERVICE] Strategy 2: Trying name field search"
|
|
15732
|
-
);
|
|
15641
|
+
console.log("[PROCEDURE_SERVICE] Strategy 2: Trying name field search");
|
|
15733
15642
|
const searchTerm = filters.nameSearch.trim().toLowerCase();
|
|
15734
15643
|
const constraints = getBaseConstraints();
|
|
15735
15644
|
constraints.push(where29("name", ">=", searchTerm));
|
|
@@ -15745,18 +15654,13 @@ var ProcedureService = class extends BaseService {
|
|
|
15745
15654
|
}
|
|
15746
15655
|
}
|
|
15747
15656
|
constraints.push(limit15(filters.pagination || 10));
|
|
15748
|
-
const q = query29(
|
|
15749
|
-
collection29(this.db, PROCEDURES_COLLECTION),
|
|
15750
|
-
...constraints
|
|
15751
|
-
);
|
|
15657
|
+
const q = query29(collection29(this.db, PROCEDURES_COLLECTION), ...constraints);
|
|
15752
15658
|
const querySnapshot = await getDocs29(q);
|
|
15753
15659
|
const procedures = querySnapshot.docs.map(
|
|
15754
15660
|
(doc37) => ({ ...doc37.data(), id: doc37.id })
|
|
15755
15661
|
);
|
|
15756
15662
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15757
|
-
console.log(
|
|
15758
|
-
`[PROCEDURE_SERVICE] Strategy 2 success: ${procedures.length} procedures`
|
|
15759
|
-
);
|
|
15663
|
+
console.log(`[PROCEDURE_SERVICE] Strategy 2 success: ${procedures.length} procedures`);
|
|
15760
15664
|
if (procedures.length < (filters.pagination || 10)) {
|
|
15761
15665
|
return { procedures, lastDoc: null };
|
|
15762
15666
|
}
|
|
@@ -15781,19 +15685,14 @@ var ProcedureService = class extends BaseService {
|
|
|
15781
15685
|
}
|
|
15782
15686
|
}
|
|
15783
15687
|
constraints.push(limit15(filters.pagination || 10));
|
|
15784
|
-
const q = query29(
|
|
15785
|
-
collection29(this.db, PROCEDURES_COLLECTION),
|
|
15786
|
-
...constraints
|
|
15787
|
-
);
|
|
15688
|
+
const q = query29(collection29(this.db, PROCEDURES_COLLECTION), ...constraints);
|
|
15788
15689
|
const querySnapshot = await getDocs29(q);
|
|
15789
15690
|
let procedures = querySnapshot.docs.map(
|
|
15790
15691
|
(doc37) => ({ ...doc37.data(), id: doc37.id })
|
|
15791
15692
|
);
|
|
15792
15693
|
procedures = this.applyInMemoryFilters(procedures, filters);
|
|
15793
15694
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15794
|
-
console.log(
|
|
15795
|
-
`[PROCEDURE_SERVICE] Strategy 3 success: ${procedures.length} procedures`
|
|
15796
|
-
);
|
|
15695
|
+
console.log(`[PROCEDURE_SERVICE] Strategy 3 success: ${procedures.length} procedures`);
|
|
15797
15696
|
if (procedures.length < (filters.pagination || 10)) {
|
|
15798
15697
|
return { procedures, lastDoc: null };
|
|
15799
15698
|
}
|
|
@@ -15808,19 +15707,14 @@ var ProcedureService = class extends BaseService {
|
|
|
15808
15707
|
orderBy17("createdAt", "desc"),
|
|
15809
15708
|
limit15(filters.pagination || 10)
|
|
15810
15709
|
];
|
|
15811
|
-
const q = query29(
|
|
15812
|
-
collection29(this.db, PROCEDURES_COLLECTION),
|
|
15813
|
-
...constraints
|
|
15814
|
-
);
|
|
15710
|
+
const q = query29(collection29(this.db, PROCEDURES_COLLECTION), ...constraints);
|
|
15815
15711
|
const querySnapshot = await getDocs29(q);
|
|
15816
15712
|
let procedures = querySnapshot.docs.map(
|
|
15817
15713
|
(doc37) => ({ ...doc37.data(), id: doc37.id })
|
|
15818
15714
|
);
|
|
15819
15715
|
procedures = this.applyInMemoryFilters(procedures, filters);
|
|
15820
15716
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15821
|
-
console.log(
|
|
15822
|
-
`[PROCEDURE_SERVICE] Strategy 4 success: ${procedures.length} procedures`
|
|
15823
|
-
);
|
|
15717
|
+
console.log(`[PROCEDURE_SERVICE] Strategy 4 success: ${procedures.length} procedures`);
|
|
15824
15718
|
if (procedures.length < (filters.pagination || 10)) {
|
|
15825
15719
|
return { procedures, lastDoc: null };
|
|
15826
15720
|
}
|
|
@@ -15828,9 +15722,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15828
15722
|
} catch (error) {
|
|
15829
15723
|
console.log("[PROCEDURE_SERVICE] Strategy 4 failed:", error);
|
|
15830
15724
|
}
|
|
15831
|
-
console.log(
|
|
15832
|
-
"[PROCEDURE_SERVICE] All strategies failed, returning empty result"
|
|
15833
|
-
);
|
|
15725
|
+
console.log("[PROCEDURE_SERVICE] All strategies failed, returning empty result");
|
|
15834
15726
|
return { procedures: [], lastDoc: null };
|
|
15835
15727
|
} catch (error) {
|
|
15836
15728
|
console.error("[PROCEDURE_SERVICE] Error filtering procedures:", error);
|
|
@@ -15850,17 +15742,13 @@ var ProcedureService = class extends BaseService {
|
|
|
15850
15742
|
const nameLower = procedure.nameLower || "";
|
|
15851
15743
|
return name.includes(searchTerm) || nameLower.includes(searchTerm);
|
|
15852
15744
|
});
|
|
15853
|
-
console.log(
|
|
15854
|
-
`[PROCEDURE_SERVICE] Applied name filter, results: ${filteredProcedures.length}`
|
|
15855
|
-
);
|
|
15745
|
+
console.log(`[PROCEDURE_SERVICE] Applied name filter, results: ${filteredProcedures.length}`);
|
|
15856
15746
|
}
|
|
15857
15747
|
if (filters.minPrice !== void 0 || filters.maxPrice !== void 0) {
|
|
15858
15748
|
filteredProcedures = filteredProcedures.filter((procedure) => {
|
|
15859
15749
|
const price = procedure.price || 0;
|
|
15860
|
-
if (filters.minPrice !== void 0 && price < filters.minPrice)
|
|
15861
|
-
|
|
15862
|
-
if (filters.maxPrice !== void 0 && price > filters.maxPrice)
|
|
15863
|
-
return false;
|
|
15750
|
+
if (filters.minPrice !== void 0 && price < filters.minPrice) return false;
|
|
15751
|
+
if (filters.maxPrice !== void 0 && price > filters.maxPrice) return false;
|
|
15864
15752
|
return true;
|
|
15865
15753
|
});
|
|
15866
15754
|
console.log(
|
|
@@ -15871,10 +15759,8 @@ var ProcedureService = class extends BaseService {
|
|
|
15871
15759
|
filteredProcedures = filteredProcedures.filter((procedure) => {
|
|
15872
15760
|
var _a;
|
|
15873
15761
|
const rating = ((_a = procedure.reviewInfo) == null ? void 0 : _a.averageRating) || 0;
|
|
15874
|
-
if (filters.minRating !== void 0 && rating < filters.minRating)
|
|
15875
|
-
|
|
15876
|
-
if (filters.maxRating !== void 0 && rating > filters.maxRating)
|
|
15877
|
-
return false;
|
|
15762
|
+
if (filters.minRating !== void 0 && rating < filters.minRating) return false;
|
|
15763
|
+
if (filters.maxRating !== void 0 && rating > filters.maxRating) return false;
|
|
15878
15764
|
return true;
|
|
15879
15765
|
});
|
|
15880
15766
|
console.log(
|
|
@@ -15882,12 +15768,10 @@ var ProcedureService = class extends BaseService {
|
|
|
15882
15768
|
);
|
|
15883
15769
|
}
|
|
15884
15770
|
if (filters.treatmentBenefits && filters.treatmentBenefits.length > 0) {
|
|
15885
|
-
const
|
|
15771
|
+
const benefitsToMatch = filters.treatmentBenefits;
|
|
15886
15772
|
filteredProcedures = filteredProcedures.filter((procedure) => {
|
|
15887
|
-
const
|
|
15888
|
-
return
|
|
15889
|
-
(benefitId) => procedureBenefitIds.includes(benefitId)
|
|
15890
|
-
);
|
|
15773
|
+
const procedureBenefits = procedure.treatmentBenefits || [];
|
|
15774
|
+
return benefitsToMatch.some((benefit) => procedureBenefits.includes(benefit));
|
|
15891
15775
|
});
|
|
15892
15776
|
console.log(
|
|
15893
15777
|
`[PROCEDURE_SERVICE] Applied benefits filter, results: ${filteredProcedures.length}`
|
|
@@ -15950,12 +15834,8 @@ var ProcedureService = class extends BaseService {
|
|
|
15950
15834
|
procedure.distance = distance;
|
|
15951
15835
|
return distance <= radiusInKm;
|
|
15952
15836
|
});
|
|
15953
|
-
console.log(
|
|
15954
|
-
|
|
15955
|
-
);
|
|
15956
|
-
filteredProcedures.sort(
|
|
15957
|
-
(a, b) => (a.distance || 0) - (b.distance || 0)
|
|
15958
|
-
);
|
|
15837
|
+
console.log(`[PROCEDURE_SERVICE] Applied geo filter, results: ${filteredProcedures.length}`);
|
|
15838
|
+
filteredProcedures.sort((a, b) => (a.distance || 0) - (b.distance || 0));
|
|
15959
15839
|
}
|
|
15960
15840
|
return filteredProcedures;
|
|
15961
15841
|
}
|
|
@@ -15967,30 +15847,19 @@ var ProcedureService = class extends BaseService {
|
|
|
15967
15847
|
if (!location || !radiusInKm) {
|
|
15968
15848
|
return Promise.resolve({ procedures: [], lastDoc: null });
|
|
15969
15849
|
}
|
|
15970
|
-
const bounds = geohashQueryBounds5(
|
|
15971
|
-
[location.latitude, location.longitude],
|
|
15972
|
-
radiusInKm * 1e3
|
|
15973
|
-
);
|
|
15850
|
+
const bounds = geohashQueryBounds5([location.latitude, location.longitude], radiusInKm * 1e3);
|
|
15974
15851
|
const fetches = bounds.map((b) => {
|
|
15975
15852
|
const constraints = [
|
|
15976
15853
|
where29("clinicInfo.location.geohash", ">=", b[0]),
|
|
15977
15854
|
where29("clinicInfo.location.geohash", "<=", b[1]),
|
|
15978
|
-
where29(
|
|
15979
|
-
"isActive",
|
|
15980
|
-
"==",
|
|
15981
|
-
filters.isActive !== void 0 ? filters.isActive : true
|
|
15982
|
-
)
|
|
15855
|
+
where29("isActive", "==", filters.isActive !== void 0 ? filters.isActive : true)
|
|
15983
15856
|
];
|
|
15984
|
-
return getDocs29(
|
|
15985
|
-
query29(collection29(this.db, PROCEDURES_COLLECTION), ...constraints)
|
|
15986
|
-
);
|
|
15857
|
+
return getDocs29(query29(collection29(this.db, PROCEDURES_COLLECTION), ...constraints));
|
|
15987
15858
|
});
|
|
15988
15859
|
return Promise.all(fetches).then((snaps) => {
|
|
15989
15860
|
const collected = [];
|
|
15990
15861
|
snaps.forEach((snap) => {
|
|
15991
|
-
snap.docs.forEach(
|
|
15992
|
-
(d) => collected.push({ ...d.data(), id: d.id })
|
|
15993
|
-
);
|
|
15862
|
+
snap.docs.forEach((d) => collected.push({ ...d.data(), id: d.id }));
|
|
15994
15863
|
});
|
|
15995
15864
|
const uniqueMap = /* @__PURE__ */ new Map();
|
|
15996
15865
|
for (const p of collected) {
|
|
@@ -16001,9 +15870,7 @@ var ProcedureService = class extends BaseService {
|
|
|
16001
15870
|
const pageSize = filters.pagination || 10;
|
|
16002
15871
|
let startIndex = 0;
|
|
16003
15872
|
if (filters.lastDoc && typeof filters.lastDoc === "object" && filters.lastDoc.id) {
|
|
16004
|
-
const idx = procedures.findIndex(
|
|
16005
|
-
(p) => p.id === filters.lastDoc.id
|
|
16006
|
-
);
|
|
15873
|
+
const idx = procedures.findIndex((p) => p.id === filters.lastDoc.id);
|
|
16007
15874
|
if (idx >= 0) startIndex = idx + 1;
|
|
16008
15875
|
}
|
|
16009
15876
|
const page = procedures.slice(startIndex, startIndex + pageSize);
|
|
@@ -16028,7 +15895,7 @@ var ProcedureService = class extends BaseService {
|
|
|
16028
15895
|
* @returns The created procedure
|
|
16029
15896
|
*/
|
|
16030
15897
|
async createConsultationProcedure(data) {
|
|
16031
|
-
var _a
|
|
15898
|
+
var _a;
|
|
16032
15899
|
const procedureId = this.generateId();
|
|
16033
15900
|
const [category, subcategory, technology] = await Promise.all([
|
|
16034
15901
|
this.categoryService.getById(data.categoryId),
|
|
@@ -16044,11 +15911,7 @@ var ProcedureService = class extends BaseService {
|
|
|
16044
15911
|
throw new Error(`Clinic with ID ${data.clinicBranchId} not found`);
|
|
16045
15912
|
}
|
|
16046
15913
|
const clinic = clinicSnapshot.data();
|
|
16047
|
-
const practitionerRef = doc30(
|
|
16048
|
-
this.db,
|
|
16049
|
-
PRACTITIONERS_COLLECTION,
|
|
16050
|
-
data.practitionerId
|
|
16051
|
-
);
|
|
15914
|
+
const practitionerRef = doc30(this.db, PRACTITIONERS_COLLECTION, data.practitionerId);
|
|
16052
15915
|
const practitionerSnapshot = await getDoc32(practitionerRef);
|
|
16053
15916
|
if (!practitionerSnapshot.exists()) {
|
|
16054
15917
|
throw new Error(`Practitioner with ID ${data.practitionerId} not found`);
|
|
@@ -16056,11 +15919,7 @@ var ProcedureService = class extends BaseService {
|
|
|
16056
15919
|
const practitioner = practitionerSnapshot.data();
|
|
16057
15920
|
let processedPhotos = [];
|
|
16058
15921
|
if (data.photos && data.photos.length > 0) {
|
|
16059
|
-
processedPhotos = await this.processMediaArray(
|
|
16060
|
-
data.photos,
|
|
16061
|
-
procedureId,
|
|
16062
|
-
"procedure-photos"
|
|
16063
|
-
);
|
|
15922
|
+
processedPhotos = await this.processMediaArray(data.photos, procedureId, "procedure-photos");
|
|
16064
15923
|
}
|
|
16065
15924
|
const clinicInfo = {
|
|
16066
15925
|
id: clinicSnapshot.id,
|
|
@@ -16102,9 +15961,7 @@ var ProcedureService = class extends BaseService {
|
|
|
16102
15961
|
// Use placeholder product
|
|
16103
15962
|
blockingConditions: technology.blockingConditions,
|
|
16104
15963
|
contraindications: technology.contraindications || [],
|
|
16105
|
-
contraindicationIds: ((_b = technology.contraindications) == null ? void 0 : _b.map((c) => c.id)) || [],
|
|
16106
15964
|
treatmentBenefits: technology.benefits,
|
|
16107
|
-
treatmentBenefitIds: ((_c = technology.benefits) == null ? void 0 : _c.map((b) => b.id)) || [],
|
|
16108
15965
|
preRequirements: technology.requirements.pre,
|
|
16109
15966
|
postRequirements: technology.requirements.post,
|
|
16110
15967
|
certificationRequirement: technology.certificationRequirement,
|
|
@@ -16973,16 +16830,8 @@ var TechnologyService = class extends BaseService {
|
|
|
16973
16830
|
*/
|
|
16974
16831
|
async addContraindication(technologyId, contraindication) {
|
|
16975
16832
|
const docRef = doc35(this.getTechnologiesRef(), technologyId);
|
|
16976
|
-
const technology = await this.getById(technologyId);
|
|
16977
|
-
if (!technology) {
|
|
16978
|
-
throw new Error(`Technology with id ${technologyId} not found`);
|
|
16979
|
-
}
|
|
16980
|
-
const existingContraindications = technology.contraindications || [];
|
|
16981
|
-
if (existingContraindications.some((c) => c.id === contraindication.id)) {
|
|
16982
|
-
return technology;
|
|
16983
|
-
}
|
|
16984
16833
|
await updateDoc33(docRef, {
|
|
16985
|
-
contraindications:
|
|
16834
|
+
contraindications: arrayUnion9(contraindication),
|
|
16986
16835
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16987
16836
|
});
|
|
16988
16837
|
return this.getById(technologyId);
|
|
@@ -16995,44 +16844,8 @@ var TechnologyService = class extends BaseService {
|
|
|
16995
16844
|
*/
|
|
16996
16845
|
async removeContraindication(technologyId, contraindication) {
|
|
16997
16846
|
const docRef = doc35(this.getTechnologiesRef(), technologyId);
|
|
16998
|
-
const technology = await this.getById(technologyId);
|
|
16999
|
-
if (!technology) {
|
|
17000
|
-
throw new Error(`Technology with id ${technologyId} not found`);
|
|
17001
|
-
}
|
|
17002
|
-
const updatedContraindications = (technology.contraindications || []).filter((c) => c.id !== contraindication.id);
|
|
17003
|
-
await updateDoc33(docRef, {
|
|
17004
|
-
contraindications: updatedContraindications,
|
|
17005
|
-
updatedAt: /* @__PURE__ */ new Date()
|
|
17006
|
-
});
|
|
17007
|
-
return this.getById(technologyId);
|
|
17008
|
-
}
|
|
17009
|
-
/**
|
|
17010
|
-
* Updates an existing contraindication in a technology's list.
|
|
17011
|
-
* If the contraindication does not exist, it will not be added.
|
|
17012
|
-
* @param technologyId - ID of the technology
|
|
17013
|
-
* @param contraindication - The updated contraindication object
|
|
17014
|
-
* @returns The updated technology
|
|
17015
|
-
*/
|
|
17016
|
-
async updateContraindication(technologyId, contraindication) {
|
|
17017
|
-
const docRef = doc35(this.getTechnologiesRef(), technologyId);
|
|
17018
|
-
const technology = await this.getById(technologyId);
|
|
17019
|
-
if (!technology) {
|
|
17020
|
-
throw new Error(`Technology with id ${technologyId} not found`);
|
|
17021
|
-
}
|
|
17022
|
-
const contraindications = technology.contraindications || [];
|
|
17023
|
-
const index = contraindications.findIndex(
|
|
17024
|
-
(c) => c.id === contraindication.id
|
|
17025
|
-
);
|
|
17026
|
-
if (index === -1) {
|
|
17027
|
-
console.warn(
|
|
17028
|
-
`Contraindication with id ${contraindication.id} not found for technology ${technologyId}. No update performed.`
|
|
17029
|
-
);
|
|
17030
|
-
return technology;
|
|
17031
|
-
}
|
|
17032
|
-
const updatedContraindications = [...contraindications];
|
|
17033
|
-
updatedContraindications[index] = contraindication;
|
|
17034
16847
|
await updateDoc33(docRef, {
|
|
17035
|
-
contraindications:
|
|
16848
|
+
contraindications: arrayRemove8(contraindication),
|
|
17036
16849
|
updatedAt: /* @__PURE__ */ new Date()
|
|
17037
16850
|
});
|
|
17038
16851
|
return this.getById(technologyId);
|
|
@@ -17045,16 +16858,8 @@ var TechnologyService = class extends BaseService {
|
|
|
17045
16858
|
*/
|
|
17046
16859
|
async addBenefit(technologyId, benefit) {
|
|
17047
16860
|
const docRef = doc35(this.getTechnologiesRef(), technologyId);
|
|
17048
|
-
const technology = await this.getById(technologyId);
|
|
17049
|
-
if (!technology) {
|
|
17050
|
-
throw new Error(`Technology with id ${technologyId} not found`);
|
|
17051
|
-
}
|
|
17052
|
-
const existingBenefits = technology.benefits || [];
|
|
17053
|
-
if (existingBenefits.some((b) => b.id === benefit.id)) {
|
|
17054
|
-
return technology;
|
|
17055
|
-
}
|
|
17056
16861
|
await updateDoc33(docRef, {
|
|
17057
|
-
benefits:
|
|
16862
|
+
benefits: arrayUnion9(benefit),
|
|
17058
16863
|
updatedAt: /* @__PURE__ */ new Date()
|
|
17059
16864
|
});
|
|
17060
16865
|
return this.getById(technologyId);
|
|
@@ -17067,44 +16872,8 @@ var TechnologyService = class extends BaseService {
|
|
|
17067
16872
|
*/
|
|
17068
16873
|
async removeBenefit(technologyId, benefit) {
|
|
17069
16874
|
const docRef = doc35(this.getTechnologiesRef(), technologyId);
|
|
17070
|
-
const technology = await this.getById(technologyId);
|
|
17071
|
-
if (!technology) {
|
|
17072
|
-
throw new Error(`Technology with id ${technologyId} not found`);
|
|
17073
|
-
}
|
|
17074
|
-
const updatedBenefits = (technology.benefits || []).filter(
|
|
17075
|
-
(b) => b.id !== benefit.id
|
|
17076
|
-
);
|
|
17077
16875
|
await updateDoc33(docRef, {
|
|
17078
|
-
benefits:
|
|
17079
|
-
updatedAt: /* @__PURE__ */ new Date()
|
|
17080
|
-
});
|
|
17081
|
-
return this.getById(technologyId);
|
|
17082
|
-
}
|
|
17083
|
-
/**
|
|
17084
|
-
* Updates an existing benefit in a technology's list.
|
|
17085
|
-
* If the benefit does not exist, it will not be added.
|
|
17086
|
-
* @param technologyId - ID of the technology
|
|
17087
|
-
* @param benefit - The updated benefit object
|
|
17088
|
-
* @returns The updated technology
|
|
17089
|
-
*/
|
|
17090
|
-
async updateBenefit(technologyId, benefit) {
|
|
17091
|
-
const docRef = doc35(this.getTechnologiesRef(), technologyId);
|
|
17092
|
-
const technology = await this.getById(technologyId);
|
|
17093
|
-
if (!technology) {
|
|
17094
|
-
throw new Error(`Technology with id ${technologyId} not found`);
|
|
17095
|
-
}
|
|
17096
|
-
const benefits = technology.benefits || [];
|
|
17097
|
-
const index = benefits.findIndex((b) => b.id === benefit.id);
|
|
17098
|
-
if (index === -1) {
|
|
17099
|
-
console.warn(
|
|
17100
|
-
`Benefit with id ${benefit.id} not found for technology ${technologyId}. No update performed.`
|
|
17101
|
-
);
|
|
17102
|
-
return technology;
|
|
17103
|
-
}
|
|
17104
|
-
const updatedBenefits = [...benefits];
|
|
17105
|
-
updatedBenefits[index] = benefit;
|
|
17106
|
-
await updateDoc33(docRef, {
|
|
17107
|
-
benefits: updatedBenefits,
|
|
16876
|
+
benefits: arrayRemove8(benefit),
|
|
17108
16877
|
updatedAt: /* @__PURE__ */ new Date()
|
|
17109
16878
|
});
|
|
17110
16879
|
return this.getById(technologyId);
|
|
@@ -17367,23 +17136,6 @@ var ProductService = class extends BaseService {
|
|
|
17367
17136
|
}
|
|
17368
17137
|
};
|
|
17369
17138
|
|
|
17370
|
-
// src/backoffice/types/static/contraindication.types.ts
|
|
17371
|
-
var Contraindication = /* @__PURE__ */ ((Contraindication2) => {
|
|
17372
|
-
Contraindication2["SENSITIVE_SKIN"] = "sensitive_skin";
|
|
17373
|
-
Contraindication2["RECENT_TANNING"] = "recent_tanning";
|
|
17374
|
-
Contraindication2["RECENT_BOTOX"] = "recent_botox";
|
|
17375
|
-
Contraindication2["RECENT_FILLERS"] = "recent_fillers";
|
|
17376
|
-
Contraindication2["SKIN_ALLERGIES"] = "skin_allergies";
|
|
17377
|
-
Contraindication2["MEDICATIONS"] = "medications";
|
|
17378
|
-
Contraindication2["RECENT_CHEMICAL_PEEL"] = "recent_chemical_peel";
|
|
17379
|
-
Contraindication2["RECENT_LASER"] = "recent_laser";
|
|
17380
|
-
Contraindication2["SKIN_INFLAMMATION"] = "skin_inflammation";
|
|
17381
|
-
Contraindication2["OPEN_WOUNDS"] = "open_wounds";
|
|
17382
|
-
Contraindication2["HERPES_SIMPLEX"] = "herpes_simplex";
|
|
17383
|
-
Contraindication2["COLD_SORES"] = "cold_sores";
|
|
17384
|
-
return Contraindication2;
|
|
17385
|
-
})(Contraindication || {});
|
|
17386
|
-
|
|
17387
17139
|
// src/backoffice/types/static/treatment-benefit.types.ts
|
|
17388
17140
|
var TreatmentBenefit = /* @__PURE__ */ ((TreatmentBenefit2) => {
|
|
17389
17141
|
TreatmentBenefit2["WRINKLE_REDUCTION"] = "wrinkle_reduction";
|