@blackcode_sa/metaestetics-api 1.10.0 → 1.11.1
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 +337 -319
- package/dist/admin/index.d.ts +337 -319
- package/dist/admin/index.js +98 -79
- package/dist/admin/index.mjs +98 -79
- package/dist/backoffice/index.d.mts +284 -67
- package/dist/backoffice/index.d.ts +284 -67
- package/dist/backoffice/index.js +114 -6
- package/dist/backoffice/index.mjs +112 -6
- package/dist/index.d.mts +3145 -3065
- package/dist/index.d.ts +3145 -3065
- package/dist/index.js +460 -141
- package/dist/index.mjs +463 -143
- package/package.json +3 -1
- package/src/admin/booking/booking.admin.ts +2 -0
- package/src/admin/booking/booking.calculator.ts +121 -117
- package/src/admin/booking/booking.types.ts +3 -0
- package/src/backoffice/expo-safe/index.ts +2 -0
- package/src/backoffice/services/README.md +40 -0
- package/src/backoffice/services/constants.service.ts +268 -0
- package/src/backoffice/services/technology.service.ts +122 -10
- package/src/backoffice/types/admin-constants.types.ts +69 -0
- package/src/backoffice/types/index.ts +1 -0
- package/src/backoffice/types/product.types.ts +3 -1
- package/src/backoffice/types/technology.types.ts +4 -4
- package/src/backoffice/validations/schemas.ts +35 -9
- package/src/services/appointment/appointment.service.ts +0 -5
- package/src/services/appointment/utils/appointment.utils.ts +124 -113
- package/src/services/clinic/clinic.service.ts +163 -82
- package/src/services/procedure/procedure.service.ts +435 -234
- package/src/types/appointment/index.ts +9 -3
- package/src/types/clinic/index.ts +3 -6
- package/src/types/patient/medical-info.types.ts +3 -3
- package/src/types/procedure/index.ts +20 -17
- package/src/validations/appointment.schema.ts +2 -0
- package/src/validations/clinic.schema.ts +3 -6
- package/src/validations/patient/medical-info.schema.ts +7 -2
- package/src/validations/procedure.schema.ts +8 -10
- package/src/backoffice/services/__tests__/brand.service.test.ts +0 -196
- package/src/backoffice/services/__tests__/category.service.test.ts +0 -201
- package/src/backoffice/services/__tests__/product.service.test.ts +0 -358
- package/src/backoffice/services/__tests__/requirement.service.test.ts +0 -226
- package/src/backoffice/services/__tests__/subcategory.service.test.ts +0 -181
- package/src/backoffice/services/__tests__/technology.service.test.ts +0 -1097
package/dist/index.js
CHANGED
|
@@ -181,13 +181,13 @@ var AppointmentStatus = /* @__PURE__ */ ((AppointmentStatus2) => {
|
|
|
181
181
|
AppointmentStatus2["RESCHEDULED_BY_CLINIC"] = "rescheduled_by_clinic";
|
|
182
182
|
return AppointmentStatus2;
|
|
183
183
|
})(AppointmentStatus || {});
|
|
184
|
-
var PaymentStatus = /* @__PURE__ */ ((
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
return
|
|
184
|
+
var PaymentStatus = /* @__PURE__ */ ((PaymentStatus4) => {
|
|
185
|
+
PaymentStatus4["UNPAID"] = "unpaid";
|
|
186
|
+
PaymentStatus4["PAID"] = "paid";
|
|
187
|
+
PaymentStatus4["PARTIALLY_PAID"] = "partially_paid";
|
|
188
|
+
PaymentStatus4["REFUNDED"] = "refunded";
|
|
189
|
+
PaymentStatus4["NOT_APPLICABLE"] = "not_applicable";
|
|
190
|
+
return PaymentStatus4;
|
|
191
191
|
})(PaymentStatus || {});
|
|
192
192
|
var MediaType = /* @__PURE__ */ ((MediaType2) => {
|
|
193
193
|
MediaType2["BEFORE_PHOTO"] = "before_photo";
|
|
@@ -583,7 +583,8 @@ var createAppointmentSchema = import_zod3.z.object({
|
|
|
583
583
|
currency: import_zod3.z.string().min(1, "Currency is required"),
|
|
584
584
|
patientNotes: import_zod3.z.string().max(MAX_STRING_LENGTH, "Patient notes too long").nullable().optional(),
|
|
585
585
|
initialStatus: appointmentStatusSchema,
|
|
586
|
-
initialPaymentStatus: paymentStatusSchema.optional().default("unpaid" /* UNPAID */)
|
|
586
|
+
initialPaymentStatus: paymentStatusSchema.optional().default("unpaid" /* UNPAID */),
|
|
587
|
+
clinic_tz: import_zod3.z.string().min(1, "Timezone is required")
|
|
587
588
|
}).refine((data) => data.appointmentEndTime > data.appointmentStartTime, {
|
|
588
589
|
message: "Appointment end time must be after start time",
|
|
589
590
|
path: ["appointmentEndTime"]
|
|
@@ -617,6 +618,7 @@ var updateAppointmentSchema = import_zod3.z.object({
|
|
|
617
618
|
cost: import_zod3.z.number().min(0).optional(),
|
|
618
619
|
clinicBranchId: import_zod3.z.string().min(MIN_STRING_LENGTH).optional(),
|
|
619
620
|
practitionerId: import_zod3.z.string().min(MIN_STRING_LENGTH).optional(),
|
|
621
|
+
clinic_tz: import_zod3.z.string().min(MIN_STRING_LENGTH).optional(),
|
|
620
622
|
linkedForms: import_zod3.z.union([import_zod3.z.array(linkedFormInfoSchema).max(MAX_ARRAY_LENGTH), import_zod3.z.any()]).optional(),
|
|
621
623
|
media: import_zod3.z.union([
|
|
622
624
|
import_zod3.z.array(appointmentMediaItemSchema).max(MAX_ARRAY_LENGTH),
|
|
@@ -934,44 +936,48 @@ async function updateAppointmentUtil(db, appointmentId, data) {
|
|
|
934
936
|
const validPreReqIds = currentAppointment.preProcedureRequirements.map(
|
|
935
937
|
(req) => req.id
|
|
936
938
|
);
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
if (invalidPreReqIds.length > 0) {
|
|
941
|
-
throw new Error(
|
|
942
|
-
`Invalid pre-requirement IDs: ${invalidPreReqIds.join(", ")}`
|
|
939
|
+
if (Array.isArray(data.completedPreRequirements)) {
|
|
940
|
+
const invalidPreReqIds = data.completedPreRequirements.filter(
|
|
941
|
+
(id) => !validPreReqIds.includes(id)
|
|
943
942
|
);
|
|
943
|
+
if (invalidPreReqIds.length > 0) {
|
|
944
|
+
throw new Error(
|
|
945
|
+
`Invalid pre-requirement IDs: ${invalidPreReqIds.join(", ")}`
|
|
946
|
+
);
|
|
947
|
+
}
|
|
948
|
+
completedPreRequirements = [
|
|
949
|
+
.../* @__PURE__ */ new Set([
|
|
950
|
+
...completedPreRequirements,
|
|
951
|
+
...data.completedPreRequirements
|
|
952
|
+
])
|
|
953
|
+
];
|
|
944
954
|
}
|
|
945
|
-
completedPreRequirements = [
|
|
946
|
-
.../* @__PURE__ */ new Set([
|
|
947
|
-
...completedPreRequirements,
|
|
948
|
-
...data.completedPreRequirements
|
|
949
|
-
])
|
|
950
|
-
];
|
|
951
955
|
}
|
|
952
956
|
if (data.completedPostRequirements) {
|
|
953
957
|
const validPostReqIds = currentAppointment.postProcedureRequirements.map(
|
|
954
958
|
(req) => req.id
|
|
955
959
|
);
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
if (invalidPostReqIds.length > 0) {
|
|
960
|
-
throw new Error(
|
|
961
|
-
`Invalid post-requirement IDs: ${invalidPostReqIds.join(", ")}`
|
|
960
|
+
if (Array.isArray(data.completedPostRequirements)) {
|
|
961
|
+
const invalidPostReqIds = data.completedPostRequirements.filter(
|
|
962
|
+
(id) => !validPostReqIds.includes(id)
|
|
962
963
|
);
|
|
964
|
+
if (invalidPostReqIds.length > 0) {
|
|
965
|
+
throw new Error(
|
|
966
|
+
`Invalid post-requirement IDs: ${invalidPostReqIds.join(", ")}`
|
|
967
|
+
);
|
|
968
|
+
}
|
|
969
|
+
completedPostRequirements = [
|
|
970
|
+
.../* @__PURE__ */ new Set([
|
|
971
|
+
...completedPostRequirements,
|
|
972
|
+
...data.completedPostRequirements
|
|
973
|
+
])
|
|
974
|
+
];
|
|
963
975
|
}
|
|
964
|
-
completedPostRequirements = [
|
|
965
|
-
.../* @__PURE__ */ new Set([
|
|
966
|
-
...completedPostRequirements,
|
|
967
|
-
...data.completedPostRequirements
|
|
968
|
-
])
|
|
969
|
-
];
|
|
970
976
|
}
|
|
971
977
|
const updateData = {
|
|
972
978
|
...data,
|
|
973
|
-
completedPreRequirements,
|
|
974
|
-
completedPostRequirements,
|
|
979
|
+
completedPreRequirements: Array.isArray(data.completedPreRequirements) ? completedPreRequirements : data.completedPreRequirements,
|
|
980
|
+
completedPostRequirements: Array.isArray(data.completedPostRequirements) ? completedPostRequirements : data.completedPostRequirements,
|
|
975
981
|
updatedAt: (0, import_firestore.serverTimestamp)()
|
|
976
982
|
};
|
|
977
983
|
Object.keys(updateData).forEach((key) => {
|
|
@@ -1021,7 +1027,7 @@ async function updateCalendarEventStatus(db, calendarEventId, appointmentStatus)
|
|
|
1021
1027
|
case "canceled_clinic" /* CANCELED_CLINIC */:
|
|
1022
1028
|
calendarStatus = "canceled";
|
|
1023
1029
|
break;
|
|
1024
|
-
case
|
|
1030
|
+
case "rescheduled_by_clinic" /* RESCHEDULED_BY_CLINIC */:
|
|
1025
1031
|
calendarStatus = "rescheduled";
|
|
1026
1032
|
break;
|
|
1027
1033
|
case "completed" /* COMPLETED */:
|
|
@@ -2837,23 +2843,6 @@ var BlockingCondition = /* @__PURE__ */ ((BlockingCondition2) => {
|
|
|
2837
2843
|
return BlockingCondition2;
|
|
2838
2844
|
})(BlockingCondition || {});
|
|
2839
2845
|
|
|
2840
|
-
// src/backoffice/types/static/contraindication.types.ts
|
|
2841
|
-
var Contraindication = /* @__PURE__ */ ((Contraindication2) => {
|
|
2842
|
-
Contraindication2["SENSITIVE_SKIN"] = "sensitive_skin";
|
|
2843
|
-
Contraindication2["RECENT_TANNING"] = "recent_tanning";
|
|
2844
|
-
Contraindication2["RECENT_BOTOX"] = "recent_botox";
|
|
2845
|
-
Contraindication2["RECENT_FILLERS"] = "recent_fillers";
|
|
2846
|
-
Contraindication2["SKIN_ALLERGIES"] = "skin_allergies";
|
|
2847
|
-
Contraindication2["MEDICATIONS"] = "medications";
|
|
2848
|
-
Contraindication2["RECENT_CHEMICAL_PEEL"] = "recent_chemical_peel";
|
|
2849
|
-
Contraindication2["RECENT_LASER"] = "recent_laser";
|
|
2850
|
-
Contraindication2["SKIN_INFLAMMATION"] = "skin_inflammation";
|
|
2851
|
-
Contraindication2["OPEN_WOUNDS"] = "open_wounds";
|
|
2852
|
-
Contraindication2["HERPES_SIMPLEX"] = "herpes_simplex";
|
|
2853
|
-
Contraindication2["COLD_SORES"] = "cold_sores";
|
|
2854
|
-
return Contraindication2;
|
|
2855
|
-
})(Contraindication || {});
|
|
2856
|
-
|
|
2857
2846
|
// src/validations/common.schema.ts
|
|
2858
2847
|
var import_zod5 = require("zod");
|
|
2859
2848
|
var import_firestore6 = require("firebase/firestore");
|
|
@@ -2908,8 +2897,13 @@ var blockingConditionSchema = import_zod6.z.object({
|
|
|
2908
2897
|
notes: import_zod6.z.string().optional().nullable(),
|
|
2909
2898
|
isActive: import_zod6.z.boolean()
|
|
2910
2899
|
});
|
|
2900
|
+
var contraindicationDynamicSchema = import_zod6.z.object({
|
|
2901
|
+
id: import_zod6.z.string(),
|
|
2902
|
+
name: import_zod6.z.string(),
|
|
2903
|
+
description: import_zod6.z.string().optional()
|
|
2904
|
+
});
|
|
2911
2905
|
var contraindicationSchema = import_zod6.z.object({
|
|
2912
|
-
condition:
|
|
2906
|
+
condition: contraindicationDynamicSchema,
|
|
2913
2907
|
lastOccurrence: timestampSchema,
|
|
2914
2908
|
frequency: import_zod6.z.enum(["rare", "occasional", "frequent"]),
|
|
2915
2909
|
notes: import_zod6.z.string().optional().nullable(),
|
|
@@ -3453,7 +3447,8 @@ var clinicLocationSchema = import_zod10.z.object({
|
|
|
3453
3447
|
postalCode: import_zod10.z.string(),
|
|
3454
3448
|
latitude: import_zod10.z.number().min(-90).max(90),
|
|
3455
3449
|
longitude: import_zod10.z.number().min(-180).max(180),
|
|
3456
|
-
geohash: import_zod10.z.string().nullable().optional()
|
|
3450
|
+
geohash: import_zod10.z.string().nullable().optional(),
|
|
3451
|
+
tz: import_zod10.z.string().nullable().optional()
|
|
3457
3452
|
});
|
|
3458
3453
|
var workingHoursTimeSchema = import_zod10.z.object({
|
|
3459
3454
|
open: import_zod10.z.string(),
|
|
@@ -3607,6 +3602,7 @@ var createClinicGroupSchema = import_zod10.z.object({
|
|
|
3607
3602
|
calendarSyncEnabled: import_zod10.z.boolean().optional(),
|
|
3608
3603
|
autoConfirmAppointments: import_zod10.z.boolean().optional(),
|
|
3609
3604
|
businessIdentificationNumber: import_zod10.z.string().optional().nullable(),
|
|
3605
|
+
tz: import_zod10.z.string().nullable().optional(),
|
|
3610
3606
|
onboarding: import_zod10.z.object({
|
|
3611
3607
|
completed: import_zod10.z.boolean().optional().default(false),
|
|
3612
3608
|
step: import_zod10.z.number().optional().default(1)
|
|
@@ -8271,6 +8267,7 @@ var ClinicGroupService = class extends BaseService {
|
|
|
8271
8267
|
|
|
8272
8268
|
// src/services/clinic/clinic.service.ts
|
|
8273
8269
|
var import_firestore27 = require("firebase/firestore");
|
|
8270
|
+
var import_functions2 = require("firebase/functions");
|
|
8274
8271
|
var import_geofire_common7 = require("geofire-common");
|
|
8275
8272
|
var import_zod20 = require("zod");
|
|
8276
8273
|
|
|
@@ -9023,6 +9020,27 @@ var ClinicService = class extends BaseService {
|
|
|
9023
9020
|
this.clinicAdminService = clinicAdminService;
|
|
9024
9021
|
this.clinicGroupService = clinicGroupService;
|
|
9025
9022
|
this.mediaService = mediaService;
|
|
9023
|
+
this.functions = (0, import_functions2.getFunctions)(app);
|
|
9024
|
+
}
|
|
9025
|
+
/**
|
|
9026
|
+
* Get timezone from coordinates using the callable function
|
|
9027
|
+
* @param lat Latitude
|
|
9028
|
+
* @param lng Longitude
|
|
9029
|
+
* @returns IANA timezone string
|
|
9030
|
+
*/
|
|
9031
|
+
async getTimezone(lat, lng) {
|
|
9032
|
+
try {
|
|
9033
|
+
const getTimezoneFromCoordinates = (0, import_functions2.httpsCallable)(
|
|
9034
|
+
this.functions,
|
|
9035
|
+
"getTimezoneFromCoordinates"
|
|
9036
|
+
);
|
|
9037
|
+
const result = await getTimezoneFromCoordinates({ lat, lng });
|
|
9038
|
+
const data = result.data;
|
|
9039
|
+
return data.timezone;
|
|
9040
|
+
} catch (error) {
|
|
9041
|
+
console.error("Error getting timezone:", error);
|
|
9042
|
+
return null;
|
|
9043
|
+
}
|
|
9026
9044
|
}
|
|
9027
9045
|
/**
|
|
9028
9046
|
* Process media resource (string URL or File object)
|
|
@@ -9037,7 +9055,9 @@ var ClinicService = class extends BaseService {
|
|
|
9037
9055
|
return media;
|
|
9038
9056
|
}
|
|
9039
9057
|
if (media instanceof File || media instanceof Blob) {
|
|
9040
|
-
console.log(
|
|
9058
|
+
console.log(
|
|
9059
|
+
`[ClinicService] Uploading ${collectionName} media for ${ownerId}`
|
|
9060
|
+
);
|
|
9041
9061
|
const metadata = await this.mediaService.uploadMedia(
|
|
9042
9062
|
media,
|
|
9043
9063
|
ownerId,
|
|
@@ -9059,7 +9079,11 @@ var ClinicService = class extends BaseService {
|
|
|
9059
9079
|
if (!mediaArray || mediaArray.length === 0) return [];
|
|
9060
9080
|
const result = [];
|
|
9061
9081
|
for (const media of mediaArray) {
|
|
9062
|
-
const processedUrl = await this.processMedia(
|
|
9082
|
+
const processedUrl = await this.processMedia(
|
|
9083
|
+
media,
|
|
9084
|
+
ownerId,
|
|
9085
|
+
collectionName
|
|
9086
|
+
);
|
|
9063
9087
|
if (processedUrl) {
|
|
9064
9088
|
result.push(processedUrl);
|
|
9065
9089
|
}
|
|
@@ -9077,7 +9101,11 @@ var ClinicService = class extends BaseService {
|
|
|
9077
9101
|
if (!photosWithTags || photosWithTags.length === 0) return [];
|
|
9078
9102
|
const result = [];
|
|
9079
9103
|
for (const item of photosWithTags) {
|
|
9080
|
-
const processedUrl = await this.processMedia(
|
|
9104
|
+
const processedUrl = await this.processMedia(
|
|
9105
|
+
item.url,
|
|
9106
|
+
ownerId,
|
|
9107
|
+
collectionName
|
|
9108
|
+
);
|
|
9081
9109
|
if (processedUrl) {
|
|
9082
9110
|
result.push({
|
|
9083
9111
|
url: processedUrl,
|
|
@@ -9095,11 +9123,19 @@ var ClinicService = class extends BaseService {
|
|
|
9095
9123
|
try {
|
|
9096
9124
|
const clinicId = this.generateId();
|
|
9097
9125
|
const validatedData = createClinicSchema.parse(data);
|
|
9098
|
-
const group = await this.clinicGroupService.getClinicGroup(
|
|
9126
|
+
const group = await this.clinicGroupService.getClinicGroup(
|
|
9127
|
+
validatedData.clinicGroupId
|
|
9128
|
+
);
|
|
9099
9129
|
if (!group) {
|
|
9100
|
-
throw new Error(
|
|
9130
|
+
throw new Error(
|
|
9131
|
+
`Clinic group ${validatedData.clinicGroupId} not found`
|
|
9132
|
+
);
|
|
9101
9133
|
}
|
|
9102
|
-
const logoUrl = await this.processMedia(
|
|
9134
|
+
const logoUrl = await this.processMedia(
|
|
9135
|
+
validatedData.logo,
|
|
9136
|
+
clinicId,
|
|
9137
|
+
"clinic-logos"
|
|
9138
|
+
);
|
|
9103
9139
|
const coverPhotoUrl = await this.processMedia(
|
|
9104
9140
|
validatedData.coverPhoto,
|
|
9105
9141
|
clinicId,
|
|
@@ -9117,6 +9153,7 @@ var ClinicService = class extends BaseService {
|
|
|
9117
9153
|
);
|
|
9118
9154
|
const location = validatedData.location;
|
|
9119
9155
|
const hash = (0, import_geofire_common7.geohashForLocation)([location.latitude, location.longitude]);
|
|
9156
|
+
const tz = await this.getTimezone(location.latitude, location.longitude);
|
|
9120
9157
|
const defaultReviewInfo = {
|
|
9121
9158
|
totalReviews: 0,
|
|
9122
9159
|
averageRating: 0,
|
|
@@ -9134,7 +9171,7 @@ var ClinicService = class extends BaseService {
|
|
|
9134
9171
|
nameLower: validatedData.name.toLowerCase(),
|
|
9135
9172
|
// Add this line
|
|
9136
9173
|
description: validatedData.description,
|
|
9137
|
-
location: { ...location, geohash: hash },
|
|
9174
|
+
location: { ...location, geohash: hash, tz },
|
|
9138
9175
|
contactInfo: validatedData.contactInfo,
|
|
9139
9176
|
workingHours: validatedData.workingHours,
|
|
9140
9177
|
tags: validatedData.tags,
|
|
@@ -9189,7 +9226,11 @@ var ClinicService = class extends BaseService {
|
|
|
9189
9226
|
const validatedData = updateClinicSchema.parse(data);
|
|
9190
9227
|
const updatePayload = {};
|
|
9191
9228
|
if (validatedData.logo !== void 0) {
|
|
9192
|
-
updatePayload.logo = await this.processMedia(
|
|
9229
|
+
updatePayload.logo = await this.processMedia(
|
|
9230
|
+
validatedData.logo,
|
|
9231
|
+
clinicId,
|
|
9232
|
+
"clinic-logos"
|
|
9233
|
+
);
|
|
9193
9234
|
}
|
|
9194
9235
|
if (validatedData.coverPhoto !== void 0) {
|
|
9195
9236
|
updatePayload.coverPhoto = await this.processMedia(
|
|
@@ -9234,9 +9275,11 @@ var ClinicService = class extends BaseService {
|
|
|
9234
9275
|
}
|
|
9235
9276
|
if (validatedData.location) {
|
|
9236
9277
|
const loc = validatedData.location;
|
|
9278
|
+
const tz = await this.getTimezone(loc.latitude, loc.longitude);
|
|
9237
9279
|
updatePayload.location = {
|
|
9238
9280
|
...loc,
|
|
9239
|
-
geohash: (0, import_geofire_common7.geohashForLocation)([loc.latitude, loc.longitude])
|
|
9281
|
+
geohash: (0, import_geofire_common7.geohashForLocation)([loc.latitude, loc.longitude]),
|
|
9282
|
+
tz
|
|
9240
9283
|
};
|
|
9241
9284
|
}
|
|
9242
9285
|
updatePayload.updatedAt = (0, import_firestore27.serverTimestamp)();
|
|
@@ -9289,10 +9332,22 @@ var ClinicService = class extends BaseService {
|
|
|
9289
9332
|
* Pretražuje klinike u određenom radijusu
|
|
9290
9333
|
*/
|
|
9291
9334
|
async findClinicsInRadius(center, radiusInKm, filters) {
|
|
9292
|
-
return findClinicsInRadius(
|
|
9335
|
+
return findClinicsInRadius(
|
|
9336
|
+
this.db,
|
|
9337
|
+
center,
|
|
9338
|
+
radiusInKm,
|
|
9339
|
+
filters
|
|
9340
|
+
);
|
|
9293
9341
|
}
|
|
9294
9342
|
async addTags(clinicId, adminId, newTags) {
|
|
9295
|
-
return addTags(
|
|
9343
|
+
return addTags(
|
|
9344
|
+
this.db,
|
|
9345
|
+
clinicId,
|
|
9346
|
+
adminId,
|
|
9347
|
+
newTags,
|
|
9348
|
+
this.clinicAdminService,
|
|
9349
|
+
this.app
|
|
9350
|
+
);
|
|
9296
9351
|
}
|
|
9297
9352
|
async removeTags(clinicId, adminId, tagsToRemove) {
|
|
9298
9353
|
return removeTags(
|
|
@@ -9330,7 +9385,9 @@ var ClinicService = class extends BaseService {
|
|
|
9330
9385
|
clinicGroupId,
|
|
9331
9386
|
adminId
|
|
9332
9387
|
});
|
|
9333
|
-
const clinicGroup = await this.clinicGroupService.getClinicGroup(
|
|
9388
|
+
const clinicGroup = await this.clinicGroupService.getClinicGroup(
|
|
9389
|
+
clinicGroupId
|
|
9390
|
+
);
|
|
9334
9391
|
if (!clinicGroup) {
|
|
9335
9392
|
console.error("[CLINIC_SERVICE] Clinic group not found", {
|
|
9336
9393
|
clinicGroupId
|
|
@@ -9376,7 +9433,13 @@ var ClinicService = class extends BaseService {
|
|
|
9376
9433
|
return getAllClinics(this.db, pagination, lastDoc);
|
|
9377
9434
|
}
|
|
9378
9435
|
async getAllClinicsInRange(center, rangeInKm, pagination, lastDoc) {
|
|
9379
|
-
return getAllClinicsInRange(
|
|
9436
|
+
return getAllClinicsInRange(
|
|
9437
|
+
this.db,
|
|
9438
|
+
center,
|
|
9439
|
+
rangeInKm,
|
|
9440
|
+
pagination,
|
|
9441
|
+
lastDoc
|
|
9442
|
+
);
|
|
9380
9443
|
}
|
|
9381
9444
|
/**
|
|
9382
9445
|
* Get clinics based on multiple filtering criteria
|
|
@@ -10560,7 +10623,7 @@ async function updatePractitionerCalendarEventUtil(db, practitionerId, eventId,
|
|
|
10560
10623
|
}
|
|
10561
10624
|
|
|
10562
10625
|
// src/services/calendar/utils/appointment.utils.ts
|
|
10563
|
-
async function
|
|
10626
|
+
async function createAppointmentUtil(db, clinicId, practitionerId, patientId, eventData, generateId2) {
|
|
10564
10627
|
const eventId = generateId2();
|
|
10565
10628
|
const autoConfirm = await checkAutoConfirmAppointmentsUtil(db, clinicId);
|
|
10566
10629
|
const initialStatus = autoConfirm ? "confirmed" /* CONFIRMED */ : "pending" /* PENDING */;
|
|
@@ -11878,7 +11941,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
11878
11941
|
syncStatus: "internal" /* INTERNAL */,
|
|
11879
11942
|
eventType: "appointment" /* APPOINTMENT */
|
|
11880
11943
|
};
|
|
11881
|
-
const appointment = await
|
|
11944
|
+
const appointment = await createAppointmentUtil(
|
|
11882
11945
|
this.db,
|
|
11883
11946
|
params.clinicId,
|
|
11884
11947
|
params.doctorId,
|
|
@@ -14589,7 +14652,8 @@ var import_firestore45 = require("firebase/firestore");
|
|
|
14589
14652
|
var import_zod24 = require("zod");
|
|
14590
14653
|
var createProcedureSchema = import_zod24.z.object({
|
|
14591
14654
|
name: import_zod24.z.string().min(1).max(200),
|
|
14592
|
-
|
|
14655
|
+
// Optional: service will derive from name if not provided by client
|
|
14656
|
+
nameLower: import_zod24.z.string().min(1).max(200).optional(),
|
|
14593
14657
|
description: import_zod24.z.string().min(1).max(2e3),
|
|
14594
14658
|
family: import_zod24.z.nativeEnum(ProcedureFamily),
|
|
14595
14659
|
categoryId: import_zod24.z.string().min(1),
|
|
@@ -14682,7 +14746,9 @@ var ProcedureService = class extends BaseService {
|
|
|
14682
14746
|
return media;
|
|
14683
14747
|
}
|
|
14684
14748
|
if (media instanceof File || media instanceof Blob) {
|
|
14685
|
-
console.log(
|
|
14749
|
+
console.log(
|
|
14750
|
+
`[ProcedureService] Uploading ${collectionName} media for ${ownerId}`
|
|
14751
|
+
);
|
|
14686
14752
|
const metadata = await this.mediaService.uploadMedia(
|
|
14687
14753
|
media,
|
|
14688
14754
|
ownerId,
|
|
@@ -14704,7 +14770,11 @@ var ProcedureService = class extends BaseService {
|
|
|
14704
14770
|
if (!mediaArray || mediaArray.length === 0) return [];
|
|
14705
14771
|
const result = [];
|
|
14706
14772
|
for (const media of mediaArray) {
|
|
14707
|
-
const processedUrl = await this.processMedia(
|
|
14773
|
+
const processedUrl = await this.processMedia(
|
|
14774
|
+
media,
|
|
14775
|
+
ownerId,
|
|
14776
|
+
collectionName
|
|
14777
|
+
);
|
|
14708
14778
|
if (processedUrl) {
|
|
14709
14779
|
result.push(processedUrl);
|
|
14710
14780
|
}
|
|
@@ -14717,28 +14787,46 @@ var ProcedureService = class extends BaseService {
|
|
|
14717
14787
|
* @returns The created procedure
|
|
14718
14788
|
*/
|
|
14719
14789
|
async createProcedure(data) {
|
|
14720
|
-
var _a;
|
|
14790
|
+
var _a, _b, _c;
|
|
14721
14791
|
const validatedData = createProcedureSchema.parse(data);
|
|
14722
14792
|
const procedureId = this.generateId();
|
|
14723
14793
|
const [category, subcategory, technology, product] = await Promise.all([
|
|
14724
14794
|
this.categoryService.getById(validatedData.categoryId),
|
|
14725
|
-
this.subcategoryService.getById(
|
|
14795
|
+
this.subcategoryService.getById(
|
|
14796
|
+
validatedData.categoryId,
|
|
14797
|
+
validatedData.subcategoryId
|
|
14798
|
+
),
|
|
14726
14799
|
this.technologyService.getById(validatedData.technologyId),
|
|
14727
|
-
this.productService.getById(
|
|
14800
|
+
this.productService.getById(
|
|
14801
|
+
validatedData.technologyId,
|
|
14802
|
+
validatedData.productId
|
|
14803
|
+
)
|
|
14728
14804
|
]);
|
|
14729
14805
|
if (!category || !subcategory || !technology || !product) {
|
|
14730
14806
|
throw new Error("One or more required base entities not found");
|
|
14731
14807
|
}
|
|
14732
|
-
const clinicRef = (0, import_firestore45.doc)(
|
|
14808
|
+
const clinicRef = (0, import_firestore45.doc)(
|
|
14809
|
+
this.db,
|
|
14810
|
+
CLINICS_COLLECTION,
|
|
14811
|
+
validatedData.clinicBranchId
|
|
14812
|
+
);
|
|
14733
14813
|
const clinicSnapshot = await (0, import_firestore45.getDoc)(clinicRef);
|
|
14734
14814
|
if (!clinicSnapshot.exists()) {
|
|
14735
|
-
throw new Error(
|
|
14815
|
+
throw new Error(
|
|
14816
|
+
`Clinic with ID ${validatedData.clinicBranchId} not found`
|
|
14817
|
+
);
|
|
14736
14818
|
}
|
|
14737
14819
|
const clinic = clinicSnapshot.data();
|
|
14738
|
-
const practitionerRef = (0, import_firestore45.doc)(
|
|
14820
|
+
const practitionerRef = (0, import_firestore45.doc)(
|
|
14821
|
+
this.db,
|
|
14822
|
+
PRACTITIONERS_COLLECTION,
|
|
14823
|
+
validatedData.practitionerId
|
|
14824
|
+
);
|
|
14739
14825
|
const practitionerSnapshot = await (0, import_firestore45.getDoc)(practitionerRef);
|
|
14740
14826
|
if (!practitionerSnapshot.exists()) {
|
|
14741
|
-
throw new Error(
|
|
14827
|
+
throw new Error(
|
|
14828
|
+
`Practitioner with ID ${validatedData.practitionerId} not found`
|
|
14829
|
+
);
|
|
14742
14830
|
}
|
|
14743
14831
|
const practitioner = practitionerSnapshot.data();
|
|
14744
14832
|
let processedPhotos = [];
|
|
@@ -14769,6 +14857,7 @@ var ProcedureService = class extends BaseService {
|
|
|
14769
14857
|
const newProcedure = {
|
|
14770
14858
|
id: procedureId,
|
|
14771
14859
|
...validatedData,
|
|
14860
|
+
// Ensure nameLower is always set even if omitted by client
|
|
14772
14861
|
nameLower: validatedData.nameLower || validatedData.name.toLowerCase(),
|
|
14773
14862
|
photos: processedPhotos,
|
|
14774
14863
|
category,
|
|
@@ -14778,7 +14867,9 @@ var ProcedureService = class extends BaseService {
|
|
|
14778
14867
|
product,
|
|
14779
14868
|
blockingConditions: technology.blockingConditions,
|
|
14780
14869
|
contraindications: technology.contraindications || [],
|
|
14870
|
+
contraindicationIds: ((_b = technology.contraindications) == null ? void 0 : _b.map((c) => c.id)) || [],
|
|
14781
14871
|
treatmentBenefits: technology.benefits,
|
|
14872
|
+
treatmentBenefitIds: ((_c = technology.benefits) == null ? void 0 : _c.map((b) => b.id)) || [],
|
|
14782
14873
|
preRequirements: technology.requirements.pre,
|
|
14783
14874
|
postRequirements: technology.requirements.post,
|
|
14784
14875
|
certificationRequirement: technology.certificationRequirement,
|
|
@@ -14819,7 +14910,7 @@ var ProcedureService = class extends BaseService {
|
|
|
14819
14910
|
* @returns A promise that resolves to an array of the newly created procedures.
|
|
14820
14911
|
*/
|
|
14821
14912
|
async bulkCreateProcedures(baseData, practitionerIds) {
|
|
14822
|
-
var _a;
|
|
14913
|
+
var _a, _b, _c;
|
|
14823
14914
|
if (!practitionerIds || practitionerIds.length === 0) {
|
|
14824
14915
|
throw new Error("Practitioner IDs array cannot be empty.");
|
|
14825
14916
|
}
|
|
@@ -14827,16 +14918,24 @@ var ProcedureService = class extends BaseService {
|
|
|
14827
14918
|
const validatedData = createProcedureSchema.parse(validationData);
|
|
14828
14919
|
const [category, subcategory, technology, product, clinicSnapshot] = await Promise.all([
|
|
14829
14920
|
this.categoryService.getById(validatedData.categoryId),
|
|
14830
|
-
this.subcategoryService.getById(
|
|
14921
|
+
this.subcategoryService.getById(
|
|
14922
|
+
validatedData.categoryId,
|
|
14923
|
+
validatedData.subcategoryId
|
|
14924
|
+
),
|
|
14831
14925
|
this.technologyService.getById(validatedData.technologyId),
|
|
14832
|
-
this.productService.getById(
|
|
14926
|
+
this.productService.getById(
|
|
14927
|
+
validatedData.technologyId,
|
|
14928
|
+
validatedData.productId
|
|
14929
|
+
),
|
|
14833
14930
|
(0, import_firestore45.getDoc)((0, import_firestore45.doc)(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId))
|
|
14834
14931
|
]);
|
|
14835
14932
|
if (!category || !subcategory || !technology || !product) {
|
|
14836
14933
|
throw new Error("One or more required base entities not found");
|
|
14837
14934
|
}
|
|
14838
14935
|
if (!clinicSnapshot.exists()) {
|
|
14839
|
-
throw new Error(
|
|
14936
|
+
throw new Error(
|
|
14937
|
+
`Clinic with ID ${validatedData.clinicBranchId} not found`
|
|
14938
|
+
);
|
|
14840
14939
|
}
|
|
14841
14940
|
const clinic = clinicSnapshot.data();
|
|
14842
14941
|
let processedPhotos = [];
|
|
@@ -14862,8 +14961,12 @@ var ProcedureService = class extends BaseService {
|
|
|
14862
14961
|
}
|
|
14863
14962
|
if (practitionersMap.size !== practitionerIds.length) {
|
|
14864
14963
|
const foundIds = Array.from(practitionersMap.keys());
|
|
14865
|
-
const notFoundIds = practitionerIds.filter(
|
|
14866
|
-
|
|
14964
|
+
const notFoundIds = practitionerIds.filter(
|
|
14965
|
+
(id) => !foundIds.includes(id)
|
|
14966
|
+
);
|
|
14967
|
+
throw new Error(
|
|
14968
|
+
`The following practitioners were not found: ${notFoundIds.join(", ")}`
|
|
14969
|
+
);
|
|
14867
14970
|
}
|
|
14868
14971
|
const batch = (0, import_firestore45.writeBatch)(this.db);
|
|
14869
14972
|
const createdProcedureIds = [];
|
|
@@ -14901,7 +15004,9 @@ var ProcedureService = class extends BaseService {
|
|
|
14901
15004
|
product,
|
|
14902
15005
|
blockingConditions: technology.blockingConditions,
|
|
14903
15006
|
contraindications: technology.contraindications || [],
|
|
15007
|
+
contraindicationIds: ((_b = technology.contraindications) == null ? void 0 : _b.map((c) => c.id)) || [],
|
|
14904
15008
|
treatmentBenefits: technology.benefits,
|
|
15009
|
+
treatmentBenefitIds: ((_c = technology.benefits) == null ? void 0 : _c.map((b) => b.id)) || [],
|
|
14905
15010
|
preRequirements: technology.requirements.pre,
|
|
14906
15011
|
postRequirements: technology.requirements.post,
|
|
14907
15012
|
certificationRequirement: technology.certificationRequirement,
|
|
@@ -14931,7 +15036,10 @@ var ProcedureService = class extends BaseService {
|
|
|
14931
15036
|
const fetchedProcedures = [];
|
|
14932
15037
|
for (let i = 0; i < createdProcedureIds.length; i += 30) {
|
|
14933
15038
|
const chunk = createdProcedureIds.slice(i, i + 30);
|
|
14934
|
-
const q = (0, import_firestore45.query)(
|
|
15039
|
+
const q = (0, import_firestore45.query)(
|
|
15040
|
+
(0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION),
|
|
15041
|
+
(0, import_firestore45.where)((0, import_firestore45.documentId)(), "in", chunk)
|
|
15042
|
+
);
|
|
14935
15043
|
const snapshot = await (0, import_firestore45.getDocs)(q);
|
|
14936
15044
|
snapshot.forEach((doc37) => {
|
|
14937
15045
|
fetchedProcedures.push(doc37.data());
|
|
@@ -15001,7 +15109,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15001
15109
|
* @returns The updated procedure
|
|
15002
15110
|
*/
|
|
15003
15111
|
async updateProcedure(id, data) {
|
|
15004
|
-
var _a;
|
|
15112
|
+
var _a, _b, _c;
|
|
15005
15113
|
const validatedData = updateProcedureSchema.parse(data);
|
|
15006
15114
|
const procedureRef = (0, import_firestore45.doc)(this.db, PROCEDURES_COLLECTION, id);
|
|
15007
15115
|
const procedureSnapshot = await (0, import_firestore45.getDoc)(procedureRef);
|
|
@@ -15032,7 +15140,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15032
15140
|
);
|
|
15033
15141
|
const newPractitionerSnap = await (0, import_firestore45.getDoc)(newPractitionerRef);
|
|
15034
15142
|
if (!newPractitionerSnap.exists())
|
|
15035
|
-
throw new Error(
|
|
15143
|
+
throw new Error(
|
|
15144
|
+
`New Practitioner ${validatedData.practitionerId} not found`
|
|
15145
|
+
);
|
|
15036
15146
|
newPractitioner = newPractitionerSnap.data();
|
|
15037
15147
|
updatedProcedureData.doctorInfo = {
|
|
15038
15148
|
id: newPractitioner.id,
|
|
@@ -15046,7 +15156,11 @@ var ProcedureService = class extends BaseService {
|
|
|
15046
15156
|
}
|
|
15047
15157
|
if (validatedData.clinicBranchId && validatedData.clinicBranchId !== oldClinicId) {
|
|
15048
15158
|
clinicChanged = true;
|
|
15049
|
-
const newClinicRef = (0, import_firestore45.doc)(
|
|
15159
|
+
const newClinicRef = (0, import_firestore45.doc)(
|
|
15160
|
+
this.db,
|
|
15161
|
+
CLINICS_COLLECTION,
|
|
15162
|
+
validatedData.clinicBranchId
|
|
15163
|
+
);
|
|
15050
15164
|
const newClinicSnap = await (0, import_firestore45.getDoc)(newClinicRef);
|
|
15051
15165
|
if (!newClinicSnap.exists())
|
|
15052
15166
|
throw new Error(`New Clinic ${validatedData.clinicBranchId} not found`);
|
|
@@ -15065,8 +15179,11 @@ var ProcedureService = class extends BaseService {
|
|
|
15065
15179
|
updatedProcedureData.nameLower = validatedData.name.toLowerCase();
|
|
15066
15180
|
}
|
|
15067
15181
|
if (validatedData.categoryId) {
|
|
15068
|
-
const category = await this.categoryService.getById(
|
|
15069
|
-
|
|
15182
|
+
const category = await this.categoryService.getById(
|
|
15183
|
+
validatedData.categoryId
|
|
15184
|
+
);
|
|
15185
|
+
if (!category)
|
|
15186
|
+
throw new Error(`Category ${validatedData.categoryId} not found`);
|
|
15070
15187
|
updatedProcedureData.category = category;
|
|
15071
15188
|
finalCategoryId = category.id;
|
|
15072
15189
|
}
|
|
@@ -15081,23 +15198,34 @@ var ProcedureService = class extends BaseService {
|
|
|
15081
15198
|
);
|
|
15082
15199
|
updatedProcedureData.subcategory = subcategory;
|
|
15083
15200
|
} else if (validatedData.subcategoryId) {
|
|
15084
|
-
console.warn(
|
|
15201
|
+
console.warn(
|
|
15202
|
+
"Attempted to update subcategory without a valid categoryId"
|
|
15203
|
+
);
|
|
15085
15204
|
}
|
|
15086
15205
|
let finalTechnologyId = existingProcedure.technology.id;
|
|
15087
15206
|
if (validatedData.technologyId) {
|
|
15088
|
-
const technology = await this.technologyService.getById(
|
|
15089
|
-
|
|
15207
|
+
const technology = await this.technologyService.getById(
|
|
15208
|
+
validatedData.technologyId
|
|
15209
|
+
);
|
|
15210
|
+
if (!technology)
|
|
15211
|
+
throw new Error(`Technology ${validatedData.technologyId} not found`);
|
|
15090
15212
|
updatedProcedureData.technology = technology;
|
|
15091
15213
|
finalTechnologyId = technology.id;
|
|
15092
15214
|
updatedProcedureData.blockingConditions = technology.blockingConditions;
|
|
15215
|
+
updatedProcedureData.contraindications = technology.contraindications || [];
|
|
15216
|
+
updatedProcedureData.contraindicationIds = ((_b = technology.contraindications) == null ? void 0 : _b.map((c) => c.id)) || [];
|
|
15093
15217
|
updatedProcedureData.treatmentBenefits = technology.benefits;
|
|
15218
|
+
updatedProcedureData.treatmentBenefitIds = ((_c = technology.benefits) == null ? void 0 : _c.map((b) => b.id)) || [];
|
|
15094
15219
|
updatedProcedureData.preRequirements = technology.requirements.pre;
|
|
15095
15220
|
updatedProcedureData.postRequirements = technology.requirements.post;
|
|
15096
15221
|
updatedProcedureData.certificationRequirement = technology.certificationRequirement;
|
|
15097
15222
|
updatedProcedureData.documentationTemplates = technology.documentationTemplates || [];
|
|
15098
15223
|
}
|
|
15099
15224
|
if (validatedData.productId && finalTechnologyId) {
|
|
15100
|
-
const product = await this.productService.getById(
|
|
15225
|
+
const product = await this.productService.getById(
|
|
15226
|
+
finalTechnologyId,
|
|
15227
|
+
validatedData.productId
|
|
15228
|
+
);
|
|
15101
15229
|
if (!product)
|
|
15102
15230
|
throw new Error(
|
|
15103
15231
|
`Product ${validatedData.productId} not found for technology ${finalTechnologyId}`
|
|
@@ -15179,7 +15307,11 @@ var ProcedureService = class extends BaseService {
|
|
|
15179
15307
|
limit16(pagination)
|
|
15180
15308
|
);
|
|
15181
15309
|
} else {
|
|
15182
|
-
proceduresQuery = (0, import_firestore45.query)(
|
|
15310
|
+
proceduresQuery = (0, import_firestore45.query)(
|
|
15311
|
+
proceduresCollection,
|
|
15312
|
+
(0, import_firestore45.orderBy)("name"),
|
|
15313
|
+
limit16(pagination)
|
|
15314
|
+
);
|
|
15183
15315
|
}
|
|
15184
15316
|
} else {
|
|
15185
15317
|
proceduresQuery = (0, import_firestore45.query)(proceduresCollection, (0, import_firestore45.orderBy)("name"));
|
|
@@ -15210,7 +15342,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15210
15342
|
*
|
|
15211
15343
|
* @param filters - Various filters to apply
|
|
15212
15344
|
* @param filters.nameSearch - Optional search text for procedure name
|
|
15213
|
-
* @param filters.
|
|
15345
|
+
* @param filters.treatmentBenefitIds - Optional array of treatment benefits to filter by
|
|
15214
15346
|
* @param filters.procedureFamily - Optional procedure family to filter by
|
|
15215
15347
|
* @param filters.procedureCategory - Optional procedure category to filter by
|
|
15216
15348
|
* @param filters.procedureSubcategory - Optional procedure subcategory to filter by
|
|
@@ -15228,7 +15360,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15228
15360
|
*/
|
|
15229
15361
|
async getProceduresByFilters(filters) {
|
|
15230
15362
|
try {
|
|
15231
|
-
console.log(
|
|
15363
|
+
console.log(
|
|
15364
|
+
"[PROCEDURE_SERVICE] Starting procedure filtering with multiple strategies"
|
|
15365
|
+
);
|
|
15232
15366
|
if (filters.location && filters.radiusInKm) {
|
|
15233
15367
|
console.log("[PROCEDURE_SERVICE] Executing geo query:", {
|
|
15234
15368
|
location: filters.location,
|
|
@@ -15236,7 +15370,10 @@ var ProcedureService = class extends BaseService {
|
|
|
15236
15370
|
serviceName: "ProcedureService"
|
|
15237
15371
|
});
|
|
15238
15372
|
if (!filters.location.latitude || !filters.location.longitude) {
|
|
15239
|
-
console.warn(
|
|
15373
|
+
console.warn(
|
|
15374
|
+
"[PROCEDURE_SERVICE] Invalid location data:",
|
|
15375
|
+
filters.location
|
|
15376
|
+
);
|
|
15240
15377
|
filters.location = void 0;
|
|
15241
15378
|
filters.radiusInKm = void 0;
|
|
15242
15379
|
}
|
|
@@ -15256,13 +15393,19 @@ var ProcedureService = class extends BaseService {
|
|
|
15256
15393
|
constraints.push((0, import_firestore45.where)("family", "==", filters.procedureFamily));
|
|
15257
15394
|
}
|
|
15258
15395
|
if (filters.procedureCategory) {
|
|
15259
|
-
constraints.push(
|
|
15396
|
+
constraints.push(
|
|
15397
|
+
(0, import_firestore45.where)("category.id", "==", filters.procedureCategory)
|
|
15398
|
+
);
|
|
15260
15399
|
}
|
|
15261
15400
|
if (filters.procedureSubcategory) {
|
|
15262
|
-
constraints.push(
|
|
15401
|
+
constraints.push(
|
|
15402
|
+
(0, import_firestore45.where)("subcategory.id", "==", filters.procedureSubcategory)
|
|
15403
|
+
);
|
|
15263
15404
|
}
|
|
15264
15405
|
if (filters.procedureTechnology) {
|
|
15265
|
-
constraints.push(
|
|
15406
|
+
constraints.push(
|
|
15407
|
+
(0, import_firestore45.where)("technology.id", "==", filters.procedureTechnology)
|
|
15408
|
+
);
|
|
15266
15409
|
}
|
|
15267
15410
|
if (filters.minPrice !== void 0) {
|
|
15268
15411
|
constraints.push((0, import_firestore45.where)("price", ">=", filters.minPrice));
|
|
@@ -15271,20 +15414,32 @@ var ProcedureService = class extends BaseService {
|
|
|
15271
15414
|
constraints.push((0, import_firestore45.where)("price", "<=", filters.maxPrice));
|
|
15272
15415
|
}
|
|
15273
15416
|
if (filters.minRating !== void 0) {
|
|
15274
|
-
constraints.push(
|
|
15417
|
+
constraints.push(
|
|
15418
|
+
(0, import_firestore45.where)("reviewInfo.averageRating", ">=", filters.minRating)
|
|
15419
|
+
);
|
|
15275
15420
|
}
|
|
15276
15421
|
if (filters.maxRating !== void 0) {
|
|
15277
|
-
constraints.push(
|
|
15422
|
+
constraints.push(
|
|
15423
|
+
(0, import_firestore45.where)("reviewInfo.averageRating", "<=", filters.maxRating)
|
|
15424
|
+
);
|
|
15278
15425
|
}
|
|
15279
15426
|
if (filters.treatmentBenefits && filters.treatmentBenefits.length > 0) {
|
|
15280
|
-
const
|
|
15281
|
-
constraints.push(
|
|
15427
|
+
const benefitIdsToMatch = filters.treatmentBenefits;
|
|
15428
|
+
constraints.push(
|
|
15429
|
+
(0, import_firestore45.where)(
|
|
15430
|
+
"treatmentBenefitIds",
|
|
15431
|
+
"array-contains-any",
|
|
15432
|
+
benefitIdsToMatch
|
|
15433
|
+
)
|
|
15434
|
+
);
|
|
15282
15435
|
}
|
|
15283
15436
|
return constraints;
|
|
15284
15437
|
};
|
|
15285
15438
|
if (filters.nameSearch && filters.nameSearch.trim()) {
|
|
15286
15439
|
try {
|
|
15287
|
-
console.log(
|
|
15440
|
+
console.log(
|
|
15441
|
+
"[PROCEDURE_SERVICE] Strategy 1: Trying nameLower search"
|
|
15442
|
+
);
|
|
15288
15443
|
const searchTerm = filters.nameSearch.trim().toLowerCase();
|
|
15289
15444
|
const constraints = getBaseConstraints();
|
|
15290
15445
|
constraints.push((0, import_firestore45.where)("nameLower", ">=", searchTerm));
|
|
@@ -15300,13 +15455,18 @@ var ProcedureService = class extends BaseService {
|
|
|
15300
15455
|
}
|
|
15301
15456
|
}
|
|
15302
15457
|
constraints.push((0, import_firestore45.limit)(filters.pagination || 10));
|
|
15303
|
-
const q = (0, import_firestore45.query)(
|
|
15458
|
+
const q = (0, import_firestore45.query)(
|
|
15459
|
+
(0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION),
|
|
15460
|
+
...constraints
|
|
15461
|
+
);
|
|
15304
15462
|
const querySnapshot = await (0, import_firestore45.getDocs)(q);
|
|
15305
15463
|
const procedures = querySnapshot.docs.map(
|
|
15306
15464
|
(doc37) => ({ ...doc37.data(), id: doc37.id })
|
|
15307
15465
|
);
|
|
15308
15466
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15309
|
-
console.log(
|
|
15467
|
+
console.log(
|
|
15468
|
+
`[PROCEDURE_SERVICE] Strategy 1 success: ${procedures.length} procedures`
|
|
15469
|
+
);
|
|
15310
15470
|
if (procedures.length < (filters.pagination || 10)) {
|
|
15311
15471
|
return { procedures, lastDoc: null };
|
|
15312
15472
|
}
|
|
@@ -15317,7 +15477,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15317
15477
|
}
|
|
15318
15478
|
if (filters.nameSearch && filters.nameSearch.trim()) {
|
|
15319
15479
|
try {
|
|
15320
|
-
console.log(
|
|
15480
|
+
console.log(
|
|
15481
|
+
"[PROCEDURE_SERVICE] Strategy 2: Trying name field search"
|
|
15482
|
+
);
|
|
15321
15483
|
const searchTerm = filters.nameSearch.trim().toLowerCase();
|
|
15322
15484
|
const constraints = getBaseConstraints();
|
|
15323
15485
|
constraints.push((0, import_firestore45.where)("name", ">=", searchTerm));
|
|
@@ -15333,13 +15495,18 @@ var ProcedureService = class extends BaseService {
|
|
|
15333
15495
|
}
|
|
15334
15496
|
}
|
|
15335
15497
|
constraints.push((0, import_firestore45.limit)(filters.pagination || 10));
|
|
15336
|
-
const q = (0, import_firestore45.query)(
|
|
15498
|
+
const q = (0, import_firestore45.query)(
|
|
15499
|
+
(0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION),
|
|
15500
|
+
...constraints
|
|
15501
|
+
);
|
|
15337
15502
|
const querySnapshot = await (0, import_firestore45.getDocs)(q);
|
|
15338
15503
|
const procedures = querySnapshot.docs.map(
|
|
15339
15504
|
(doc37) => ({ ...doc37.data(), id: doc37.id })
|
|
15340
15505
|
);
|
|
15341
15506
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15342
|
-
console.log(
|
|
15507
|
+
console.log(
|
|
15508
|
+
`[PROCEDURE_SERVICE] Strategy 2 success: ${procedures.length} procedures`
|
|
15509
|
+
);
|
|
15343
15510
|
if (procedures.length < (filters.pagination || 10)) {
|
|
15344
15511
|
return { procedures, lastDoc: null };
|
|
15345
15512
|
}
|
|
@@ -15364,14 +15531,19 @@ var ProcedureService = class extends BaseService {
|
|
|
15364
15531
|
}
|
|
15365
15532
|
}
|
|
15366
15533
|
constraints.push((0, import_firestore45.limit)(filters.pagination || 10));
|
|
15367
|
-
const q = (0, import_firestore45.query)(
|
|
15534
|
+
const q = (0, import_firestore45.query)(
|
|
15535
|
+
(0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION),
|
|
15536
|
+
...constraints
|
|
15537
|
+
);
|
|
15368
15538
|
const querySnapshot = await (0, import_firestore45.getDocs)(q);
|
|
15369
15539
|
let procedures = querySnapshot.docs.map(
|
|
15370
15540
|
(doc37) => ({ ...doc37.data(), id: doc37.id })
|
|
15371
15541
|
);
|
|
15372
15542
|
procedures = this.applyInMemoryFilters(procedures, filters);
|
|
15373
15543
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15374
|
-
console.log(
|
|
15544
|
+
console.log(
|
|
15545
|
+
`[PROCEDURE_SERVICE] Strategy 3 success: ${procedures.length} procedures`
|
|
15546
|
+
);
|
|
15375
15547
|
if (procedures.length < (filters.pagination || 10)) {
|
|
15376
15548
|
return { procedures, lastDoc: null };
|
|
15377
15549
|
}
|
|
@@ -15386,14 +15558,19 @@ var ProcedureService = class extends BaseService {
|
|
|
15386
15558
|
(0, import_firestore45.orderBy)("createdAt", "desc"),
|
|
15387
15559
|
(0, import_firestore45.limit)(filters.pagination || 10)
|
|
15388
15560
|
];
|
|
15389
|
-
const q = (0, import_firestore45.query)(
|
|
15561
|
+
const q = (0, import_firestore45.query)(
|
|
15562
|
+
(0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION),
|
|
15563
|
+
...constraints
|
|
15564
|
+
);
|
|
15390
15565
|
const querySnapshot = await (0, import_firestore45.getDocs)(q);
|
|
15391
15566
|
let procedures = querySnapshot.docs.map(
|
|
15392
15567
|
(doc37) => ({ ...doc37.data(), id: doc37.id })
|
|
15393
15568
|
);
|
|
15394
15569
|
procedures = this.applyInMemoryFilters(procedures, filters);
|
|
15395
15570
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15396
|
-
console.log(
|
|
15571
|
+
console.log(
|
|
15572
|
+
`[PROCEDURE_SERVICE] Strategy 4 success: ${procedures.length} procedures`
|
|
15573
|
+
);
|
|
15397
15574
|
if (procedures.length < (filters.pagination || 10)) {
|
|
15398
15575
|
return { procedures, lastDoc: null };
|
|
15399
15576
|
}
|
|
@@ -15401,7 +15578,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15401
15578
|
} catch (error) {
|
|
15402
15579
|
console.log("[PROCEDURE_SERVICE] Strategy 4 failed:", error);
|
|
15403
15580
|
}
|
|
15404
|
-
console.log(
|
|
15581
|
+
console.log(
|
|
15582
|
+
"[PROCEDURE_SERVICE] All strategies failed, returning empty result"
|
|
15583
|
+
);
|
|
15405
15584
|
return { procedures: [], lastDoc: null };
|
|
15406
15585
|
} catch (error) {
|
|
15407
15586
|
console.error("[PROCEDURE_SERVICE] Error filtering procedures:", error);
|
|
@@ -15421,13 +15600,17 @@ var ProcedureService = class extends BaseService {
|
|
|
15421
15600
|
const nameLower = procedure.nameLower || "";
|
|
15422
15601
|
return name.includes(searchTerm) || nameLower.includes(searchTerm);
|
|
15423
15602
|
});
|
|
15424
|
-
console.log(
|
|
15603
|
+
console.log(
|
|
15604
|
+
`[PROCEDURE_SERVICE] Applied name filter, results: ${filteredProcedures.length}`
|
|
15605
|
+
);
|
|
15425
15606
|
}
|
|
15426
15607
|
if (filters.minPrice !== void 0 || filters.maxPrice !== void 0) {
|
|
15427
15608
|
filteredProcedures = filteredProcedures.filter((procedure) => {
|
|
15428
15609
|
const price = procedure.price || 0;
|
|
15429
|
-
if (filters.minPrice !== void 0 && price < filters.minPrice)
|
|
15430
|
-
|
|
15610
|
+
if (filters.minPrice !== void 0 && price < filters.minPrice)
|
|
15611
|
+
return false;
|
|
15612
|
+
if (filters.maxPrice !== void 0 && price > filters.maxPrice)
|
|
15613
|
+
return false;
|
|
15431
15614
|
return true;
|
|
15432
15615
|
});
|
|
15433
15616
|
console.log(
|
|
@@ -15438,8 +15621,10 @@ var ProcedureService = class extends BaseService {
|
|
|
15438
15621
|
filteredProcedures = filteredProcedures.filter((procedure) => {
|
|
15439
15622
|
var _a;
|
|
15440
15623
|
const rating = ((_a = procedure.reviewInfo) == null ? void 0 : _a.averageRating) || 0;
|
|
15441
|
-
if (filters.minRating !== void 0 && rating < filters.minRating)
|
|
15442
|
-
|
|
15624
|
+
if (filters.minRating !== void 0 && rating < filters.minRating)
|
|
15625
|
+
return false;
|
|
15626
|
+
if (filters.maxRating !== void 0 && rating > filters.maxRating)
|
|
15627
|
+
return false;
|
|
15443
15628
|
return true;
|
|
15444
15629
|
});
|
|
15445
15630
|
console.log(
|
|
@@ -15447,10 +15632,12 @@ var ProcedureService = class extends BaseService {
|
|
|
15447
15632
|
);
|
|
15448
15633
|
}
|
|
15449
15634
|
if (filters.treatmentBenefits && filters.treatmentBenefits.length > 0) {
|
|
15450
|
-
const
|
|
15635
|
+
const benefitIdsToMatch = filters.treatmentBenefits;
|
|
15451
15636
|
filteredProcedures = filteredProcedures.filter((procedure) => {
|
|
15452
|
-
const
|
|
15453
|
-
return
|
|
15637
|
+
const procedureBenefitIds = procedure.treatmentBenefitIds || [];
|
|
15638
|
+
return benefitIdsToMatch.some(
|
|
15639
|
+
(benefitId) => procedureBenefitIds.includes(benefitId)
|
|
15640
|
+
);
|
|
15454
15641
|
});
|
|
15455
15642
|
console.log(
|
|
15456
15643
|
`[PROCEDURE_SERVICE] Applied benefits filter, results: ${filteredProcedures.length}`
|
|
@@ -15513,8 +15700,12 @@ var ProcedureService = class extends BaseService {
|
|
|
15513
15700
|
procedure.distance = distance;
|
|
15514
15701
|
return distance <= radiusInKm;
|
|
15515
15702
|
});
|
|
15516
|
-
console.log(
|
|
15517
|
-
|
|
15703
|
+
console.log(
|
|
15704
|
+
`[PROCEDURE_SERVICE] Applied geo filter, results: ${filteredProcedures.length}`
|
|
15705
|
+
);
|
|
15706
|
+
filteredProcedures.sort(
|
|
15707
|
+
(a, b) => (a.distance || 0) - (b.distance || 0)
|
|
15708
|
+
);
|
|
15518
15709
|
}
|
|
15519
15710
|
return filteredProcedures;
|
|
15520
15711
|
}
|
|
@@ -15526,19 +15717,30 @@ var ProcedureService = class extends BaseService {
|
|
|
15526
15717
|
if (!location || !radiusInKm) {
|
|
15527
15718
|
return Promise.resolve({ procedures: [], lastDoc: null });
|
|
15528
15719
|
}
|
|
15529
|
-
const bounds = (0, import_geofire_common8.geohashQueryBounds)(
|
|
15720
|
+
const bounds = (0, import_geofire_common8.geohashQueryBounds)(
|
|
15721
|
+
[location.latitude, location.longitude],
|
|
15722
|
+
radiusInKm * 1e3
|
|
15723
|
+
);
|
|
15530
15724
|
const fetches = bounds.map((b) => {
|
|
15531
15725
|
const constraints = [
|
|
15532
15726
|
(0, import_firestore45.where)("clinicInfo.location.geohash", ">=", b[0]),
|
|
15533
15727
|
(0, import_firestore45.where)("clinicInfo.location.geohash", "<=", b[1]),
|
|
15534
|
-
(0, import_firestore45.where)(
|
|
15728
|
+
(0, import_firestore45.where)(
|
|
15729
|
+
"isActive",
|
|
15730
|
+
"==",
|
|
15731
|
+
filters.isActive !== void 0 ? filters.isActive : true
|
|
15732
|
+
)
|
|
15535
15733
|
];
|
|
15536
|
-
return (0, import_firestore45.getDocs)(
|
|
15734
|
+
return (0, import_firestore45.getDocs)(
|
|
15735
|
+
(0, import_firestore45.query)((0, import_firestore45.collection)(this.db, PROCEDURES_COLLECTION), ...constraints)
|
|
15736
|
+
);
|
|
15537
15737
|
});
|
|
15538
15738
|
return Promise.all(fetches).then((snaps) => {
|
|
15539
15739
|
const collected = [];
|
|
15540
15740
|
snaps.forEach((snap) => {
|
|
15541
|
-
snap.docs.forEach(
|
|
15741
|
+
snap.docs.forEach(
|
|
15742
|
+
(d) => collected.push({ ...d.data(), id: d.id })
|
|
15743
|
+
);
|
|
15542
15744
|
});
|
|
15543
15745
|
const uniqueMap = /* @__PURE__ */ new Map();
|
|
15544
15746
|
for (const p of collected) {
|
|
@@ -15549,7 +15751,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15549
15751
|
const pageSize = filters.pagination || 10;
|
|
15550
15752
|
let startIndex = 0;
|
|
15551
15753
|
if (filters.lastDoc && typeof filters.lastDoc === "object" && filters.lastDoc.id) {
|
|
15552
|
-
const idx = procedures.findIndex(
|
|
15754
|
+
const idx = procedures.findIndex(
|
|
15755
|
+
(p) => p.id === filters.lastDoc.id
|
|
15756
|
+
);
|
|
15553
15757
|
if (idx >= 0) startIndex = idx + 1;
|
|
15554
15758
|
}
|
|
15555
15759
|
const page = procedures.slice(startIndex, startIndex + pageSize);
|
|
@@ -15574,7 +15778,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15574
15778
|
* @returns The created procedure
|
|
15575
15779
|
*/
|
|
15576
15780
|
async createConsultationProcedure(data) {
|
|
15577
|
-
var _a;
|
|
15781
|
+
var _a, _b, _c;
|
|
15578
15782
|
const procedureId = this.generateId();
|
|
15579
15783
|
const [category, subcategory, technology] = await Promise.all([
|
|
15580
15784
|
this.categoryService.getById(data.categoryId),
|
|
@@ -15590,7 +15794,11 @@ var ProcedureService = class extends BaseService {
|
|
|
15590
15794
|
throw new Error(`Clinic with ID ${data.clinicBranchId} not found`);
|
|
15591
15795
|
}
|
|
15592
15796
|
const clinic = clinicSnapshot.data();
|
|
15593
|
-
const practitionerRef = (0, import_firestore45.doc)(
|
|
15797
|
+
const practitionerRef = (0, import_firestore45.doc)(
|
|
15798
|
+
this.db,
|
|
15799
|
+
PRACTITIONERS_COLLECTION,
|
|
15800
|
+
data.practitionerId
|
|
15801
|
+
);
|
|
15594
15802
|
const practitionerSnapshot = await (0, import_firestore45.getDoc)(practitionerRef);
|
|
15595
15803
|
if (!practitionerSnapshot.exists()) {
|
|
15596
15804
|
throw new Error(`Practitioner with ID ${data.practitionerId} not found`);
|
|
@@ -15598,7 +15806,11 @@ var ProcedureService = class extends BaseService {
|
|
|
15598
15806
|
const practitioner = practitionerSnapshot.data();
|
|
15599
15807
|
let processedPhotos = [];
|
|
15600
15808
|
if (data.photos && data.photos.length > 0) {
|
|
15601
|
-
processedPhotos = await this.processMediaArray(
|
|
15809
|
+
processedPhotos = await this.processMediaArray(
|
|
15810
|
+
data.photos,
|
|
15811
|
+
procedureId,
|
|
15812
|
+
"procedure-photos"
|
|
15813
|
+
);
|
|
15602
15814
|
}
|
|
15603
15815
|
const clinicInfo = {
|
|
15604
15816
|
id: clinicSnapshot.id,
|
|
@@ -15640,7 +15852,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15640
15852
|
// Use placeholder product
|
|
15641
15853
|
blockingConditions: technology.blockingConditions,
|
|
15642
15854
|
contraindications: technology.contraindications || [],
|
|
15855
|
+
contraindicationIds: ((_b = technology.contraindications) == null ? void 0 : _b.map((c) => c.id)) || [],
|
|
15643
15856
|
treatmentBenefits: technology.benefits,
|
|
15857
|
+
treatmentBenefitIds: ((_c = technology.benefits) == null ? void 0 : _c.map((b) => b.id)) || [],
|
|
15644
15858
|
preRequirements: technology.requirements.pre,
|
|
15645
15859
|
postRequirements: technology.requirements.post,
|
|
15646
15860
|
certificationRequirement: technology.certificationRequirement,
|
|
@@ -15902,7 +16116,7 @@ var import_auth9 = require("firebase/auth");
|
|
|
15902
16116
|
var import_analytics = require("firebase/analytics");
|
|
15903
16117
|
var import_react_native = require("react-native");
|
|
15904
16118
|
var import_storage4 = require("firebase/storage");
|
|
15905
|
-
var
|
|
16119
|
+
var import_functions3 = require("firebase/functions");
|
|
15906
16120
|
var firebaseInstance = null;
|
|
15907
16121
|
var initializeFirebase = (config) => {
|
|
15908
16122
|
if (!firebaseInstance) {
|
|
@@ -15910,7 +16124,7 @@ var initializeFirebase = (config) => {
|
|
|
15910
16124
|
const db = (0, import_firestore47.getFirestore)(app);
|
|
15911
16125
|
const auth = (0, import_auth9.getAuth)(app);
|
|
15912
16126
|
const storage = (0, import_storage4.getStorage)(app);
|
|
15913
|
-
const functions = (0,
|
|
16127
|
+
const functions = (0, import_functions3.getFunctions)(app);
|
|
15914
16128
|
let analytics = null;
|
|
15915
16129
|
if (typeof window !== "undefined" && import_react_native.Platform.OS === "web") {
|
|
15916
16130
|
analytics = (0, import_analytics.getAnalytics)(app);
|
|
@@ -16461,8 +16675,16 @@ var TechnologyService = class extends BaseService {
|
|
|
16461
16675
|
*/
|
|
16462
16676
|
async addContraindication(technologyId, contraindication) {
|
|
16463
16677
|
const docRef = (0, import_firestore51.doc)(this.getTechnologiesRef(), technologyId);
|
|
16678
|
+
const technology = await this.getById(technologyId);
|
|
16679
|
+
if (!technology) {
|
|
16680
|
+
throw new Error(`Technology with id ${technologyId} not found`);
|
|
16681
|
+
}
|
|
16682
|
+
const existingContraindications = technology.contraindications || [];
|
|
16683
|
+
if (existingContraindications.some((c) => c.id === contraindication.id)) {
|
|
16684
|
+
return technology;
|
|
16685
|
+
}
|
|
16464
16686
|
await (0, import_firestore51.updateDoc)(docRef, {
|
|
16465
|
-
contraindications:
|
|
16687
|
+
contraindications: [...existingContraindications, contraindication],
|
|
16466
16688
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16467
16689
|
});
|
|
16468
16690
|
return this.getById(technologyId);
|
|
@@ -16475,8 +16697,44 @@ var TechnologyService = class extends BaseService {
|
|
|
16475
16697
|
*/
|
|
16476
16698
|
async removeContraindication(technologyId, contraindication) {
|
|
16477
16699
|
const docRef = (0, import_firestore51.doc)(this.getTechnologiesRef(), technologyId);
|
|
16700
|
+
const technology = await this.getById(technologyId);
|
|
16701
|
+
if (!technology) {
|
|
16702
|
+
throw new Error(`Technology with id ${technologyId} not found`);
|
|
16703
|
+
}
|
|
16704
|
+
const updatedContraindications = (technology.contraindications || []).filter((c) => c.id !== contraindication.id);
|
|
16478
16705
|
await (0, import_firestore51.updateDoc)(docRef, {
|
|
16479
|
-
contraindications:
|
|
16706
|
+
contraindications: updatedContraindications,
|
|
16707
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
16708
|
+
});
|
|
16709
|
+
return this.getById(technologyId);
|
|
16710
|
+
}
|
|
16711
|
+
/**
|
|
16712
|
+
* Updates an existing contraindication in a technology's list.
|
|
16713
|
+
* If the contraindication does not exist, it will not be added.
|
|
16714
|
+
* @param technologyId - ID of the technology
|
|
16715
|
+
* @param contraindication - The updated contraindication object
|
|
16716
|
+
* @returns The updated technology
|
|
16717
|
+
*/
|
|
16718
|
+
async updateContraindication(technologyId, contraindication) {
|
|
16719
|
+
const docRef = (0, import_firestore51.doc)(this.getTechnologiesRef(), technologyId);
|
|
16720
|
+
const technology = await this.getById(technologyId);
|
|
16721
|
+
if (!technology) {
|
|
16722
|
+
throw new Error(`Technology with id ${technologyId} not found`);
|
|
16723
|
+
}
|
|
16724
|
+
const contraindications = technology.contraindications || [];
|
|
16725
|
+
const index = contraindications.findIndex(
|
|
16726
|
+
(c) => c.id === contraindication.id
|
|
16727
|
+
);
|
|
16728
|
+
if (index === -1) {
|
|
16729
|
+
console.warn(
|
|
16730
|
+
`Contraindication with id ${contraindication.id} not found for technology ${technologyId}. No update performed.`
|
|
16731
|
+
);
|
|
16732
|
+
return technology;
|
|
16733
|
+
}
|
|
16734
|
+
const updatedContraindications = [...contraindications];
|
|
16735
|
+
updatedContraindications[index] = contraindication;
|
|
16736
|
+
await (0, import_firestore51.updateDoc)(docRef, {
|
|
16737
|
+
contraindications: updatedContraindications,
|
|
16480
16738
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16481
16739
|
});
|
|
16482
16740
|
return this.getById(technologyId);
|
|
@@ -16489,8 +16747,16 @@ var TechnologyService = class extends BaseService {
|
|
|
16489
16747
|
*/
|
|
16490
16748
|
async addBenefit(technologyId, benefit) {
|
|
16491
16749
|
const docRef = (0, import_firestore51.doc)(this.getTechnologiesRef(), technologyId);
|
|
16750
|
+
const technology = await this.getById(technologyId);
|
|
16751
|
+
if (!technology) {
|
|
16752
|
+
throw new Error(`Technology with id ${technologyId} not found`);
|
|
16753
|
+
}
|
|
16754
|
+
const existingBenefits = technology.benefits || [];
|
|
16755
|
+
if (existingBenefits.some((b) => b.id === benefit.id)) {
|
|
16756
|
+
return technology;
|
|
16757
|
+
}
|
|
16492
16758
|
await (0, import_firestore51.updateDoc)(docRef, {
|
|
16493
|
-
benefits:
|
|
16759
|
+
benefits: [...existingBenefits, benefit],
|
|
16494
16760
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16495
16761
|
});
|
|
16496
16762
|
return this.getById(technologyId);
|
|
@@ -16503,8 +16769,44 @@ var TechnologyService = class extends BaseService {
|
|
|
16503
16769
|
*/
|
|
16504
16770
|
async removeBenefit(technologyId, benefit) {
|
|
16505
16771
|
const docRef = (0, import_firestore51.doc)(this.getTechnologiesRef(), technologyId);
|
|
16772
|
+
const technology = await this.getById(technologyId);
|
|
16773
|
+
if (!technology) {
|
|
16774
|
+
throw new Error(`Technology with id ${technologyId} not found`);
|
|
16775
|
+
}
|
|
16776
|
+
const updatedBenefits = (technology.benefits || []).filter(
|
|
16777
|
+
(b) => b.id !== benefit.id
|
|
16778
|
+
);
|
|
16779
|
+
await (0, import_firestore51.updateDoc)(docRef, {
|
|
16780
|
+
benefits: updatedBenefits,
|
|
16781
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
16782
|
+
});
|
|
16783
|
+
return this.getById(technologyId);
|
|
16784
|
+
}
|
|
16785
|
+
/**
|
|
16786
|
+
* Updates an existing benefit in a technology's list.
|
|
16787
|
+
* If the benefit does not exist, it will not be added.
|
|
16788
|
+
* @param technologyId - ID of the technology
|
|
16789
|
+
* @param benefit - The updated benefit object
|
|
16790
|
+
* @returns The updated technology
|
|
16791
|
+
*/
|
|
16792
|
+
async updateBenefit(technologyId, benefit) {
|
|
16793
|
+
const docRef = (0, import_firestore51.doc)(this.getTechnologiesRef(), technologyId);
|
|
16794
|
+
const technology = await this.getById(technologyId);
|
|
16795
|
+
if (!technology) {
|
|
16796
|
+
throw new Error(`Technology with id ${technologyId} not found`);
|
|
16797
|
+
}
|
|
16798
|
+
const benefits = technology.benefits || [];
|
|
16799
|
+
const index = benefits.findIndex((b) => b.id === benefit.id);
|
|
16800
|
+
if (index === -1) {
|
|
16801
|
+
console.warn(
|
|
16802
|
+
`Benefit with id ${benefit.id} not found for technology ${technologyId}. No update performed.`
|
|
16803
|
+
);
|
|
16804
|
+
return technology;
|
|
16805
|
+
}
|
|
16806
|
+
const updatedBenefits = [...benefits];
|
|
16807
|
+
updatedBenefits[index] = benefit;
|
|
16506
16808
|
await (0, import_firestore51.updateDoc)(docRef, {
|
|
16507
|
-
benefits:
|
|
16809
|
+
benefits: updatedBenefits,
|
|
16508
16810
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16509
16811
|
});
|
|
16510
16812
|
return this.getById(technologyId);
|
|
@@ -16758,6 +17060,23 @@ var ProductService = class extends BaseService {
|
|
|
16758
17060
|
}
|
|
16759
17061
|
};
|
|
16760
17062
|
|
|
17063
|
+
// src/backoffice/types/static/contraindication.types.ts
|
|
17064
|
+
var Contraindication = /* @__PURE__ */ ((Contraindication2) => {
|
|
17065
|
+
Contraindication2["SENSITIVE_SKIN"] = "sensitive_skin";
|
|
17066
|
+
Contraindication2["RECENT_TANNING"] = "recent_tanning";
|
|
17067
|
+
Contraindication2["RECENT_BOTOX"] = "recent_botox";
|
|
17068
|
+
Contraindication2["RECENT_FILLERS"] = "recent_fillers";
|
|
17069
|
+
Contraindication2["SKIN_ALLERGIES"] = "skin_allergies";
|
|
17070
|
+
Contraindication2["MEDICATIONS"] = "medications";
|
|
17071
|
+
Contraindication2["RECENT_CHEMICAL_PEEL"] = "recent_chemical_peel";
|
|
17072
|
+
Contraindication2["RECENT_LASER"] = "recent_laser";
|
|
17073
|
+
Contraindication2["SKIN_INFLAMMATION"] = "skin_inflammation";
|
|
17074
|
+
Contraindication2["OPEN_WOUNDS"] = "open_wounds";
|
|
17075
|
+
Contraindication2["HERPES_SIMPLEX"] = "herpes_simplex";
|
|
17076
|
+
Contraindication2["COLD_SORES"] = "cold_sores";
|
|
17077
|
+
return Contraindication2;
|
|
17078
|
+
})(Contraindication || {});
|
|
17079
|
+
|
|
16761
17080
|
// src/backoffice/types/static/treatment-benefit.types.ts
|
|
16762
17081
|
var TreatmentBenefit = /* @__PURE__ */ ((TreatmentBenefit2) => {
|
|
16763
17082
|
TreatmentBenefit2["WRINKLE_REDUCTION"] = "wrinkle_reduction";
|