@blackcode_sa/metaestetics-api 1.11.2 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/index.d.mts +331 -318
- package/dist/admin/index.d.ts +331 -318
- package/dist/backoffice/index.d.mts +1166 -430
- package/dist/backoffice/index.d.ts +1166 -430
- package/dist/backoffice/index.js +1128 -245
- package/dist/backoffice/index.mjs +1119 -209
- package/dist/index.d.mts +4429 -4034
- package/dist/index.d.ts +4429 -4034
- package/dist/index.js +1644 -666
- package/dist/index.mjs +1408 -402
- package/package.json +1 -1
- package/src/backoffice/expo-safe/index.ts +3 -0
- package/src/backoffice/services/README.md +40 -0
- package/src/backoffice/services/brand.service.ts +85 -6
- package/src/backoffice/services/category.service.ts +92 -10
- package/src/backoffice/services/constants.service.ts +308 -0
- package/src/backoffice/services/documentation-template.service.ts +56 -2
- package/src/backoffice/services/index.ts +1 -0
- package/src/backoffice/services/product.service.ts +126 -5
- package/src/backoffice/services/requirement.service.ts +13 -0
- package/src/backoffice/services/subcategory.service.ts +184 -13
- package/src/backoffice/services/technology.service.ts +344 -129
- package/src/backoffice/types/admin-constants.types.ts +69 -0
- package/src/backoffice/types/brand.types.ts +1 -0
- package/src/backoffice/types/index.ts +1 -0
- package/src/backoffice/types/product.types.ts +31 -4
- package/src/backoffice/types/static/contraindication.types.ts +1 -0
- package/src/backoffice/types/static/treatment-benefit.types.ts +1 -0
- package/src/backoffice/types/technology.types.ts +113 -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/base.service.ts +10 -3
- package/src/services/documentation-templates/documentation-template.service.ts +116 -0
- package/src/services/media/media.service.ts +2 -2
- package/src/services/procedure/procedure.service.ts +436 -234
- package/src/types/appointment/index.ts +4 -3
- package/src/types/clinic/index.ts +1 -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 +1 -0
- package/src/validations/clinic.schema.ts +1 -6
- package/src/validations/patient/medical-info.schema.ts +7 -2
- 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
|
@@ -56,6 +56,7 @@ __export(index_exports, {
|
|
|
56
56
|
ClinicPhotoTag: () => ClinicPhotoTag,
|
|
57
57
|
ClinicService: () => ClinicService,
|
|
58
58
|
ClinicTag: () => ClinicTag,
|
|
59
|
+
ConstantsService: () => ConstantsService,
|
|
59
60
|
Contraindication: () => Contraindication,
|
|
60
61
|
CosmeticAllergySubtype: () => CosmeticAllergySubtype,
|
|
61
62
|
Currency: () => Currency,
|
|
@@ -145,11 +146,13 @@ var import_functions = require("firebase/functions");
|
|
|
145
146
|
// src/services/base.service.ts
|
|
146
147
|
var import_storage = require("firebase/storage");
|
|
147
148
|
var BaseService = class {
|
|
148
|
-
constructor(db, auth, app) {
|
|
149
|
+
constructor(db, auth, app, storage) {
|
|
149
150
|
this.db = db;
|
|
150
151
|
this.auth = auth;
|
|
151
152
|
this.app = app;
|
|
152
|
-
|
|
153
|
+
if (app) {
|
|
154
|
+
this.storage = storage || (0, import_storage.getStorage)(app);
|
|
155
|
+
}
|
|
153
156
|
}
|
|
154
157
|
/**
|
|
155
158
|
* Generiše jedinstveni ID za dokumente
|
|
@@ -181,13 +184,13 @@ var AppointmentStatus = /* @__PURE__ */ ((AppointmentStatus2) => {
|
|
|
181
184
|
AppointmentStatus2["RESCHEDULED_BY_CLINIC"] = "rescheduled_by_clinic";
|
|
182
185
|
return AppointmentStatus2;
|
|
183
186
|
})(AppointmentStatus || {});
|
|
184
|
-
var PaymentStatus = /* @__PURE__ */ ((
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
return
|
|
187
|
+
var PaymentStatus = /* @__PURE__ */ ((PaymentStatus4) => {
|
|
188
|
+
PaymentStatus4["UNPAID"] = "unpaid";
|
|
189
|
+
PaymentStatus4["PAID"] = "paid";
|
|
190
|
+
PaymentStatus4["PARTIALLY_PAID"] = "partially_paid";
|
|
191
|
+
PaymentStatus4["REFUNDED"] = "refunded";
|
|
192
|
+
PaymentStatus4["NOT_APPLICABLE"] = "not_applicable";
|
|
193
|
+
return PaymentStatus4;
|
|
191
194
|
})(PaymentStatus || {});
|
|
192
195
|
var MediaType = /* @__PURE__ */ ((MediaType2) => {
|
|
193
196
|
MediaType2["BEFORE_PHOTO"] = "before_photo";
|
|
@@ -566,7 +569,8 @@ var appointmentMetadataSchema = import_zod3.z.object({
|
|
|
566
569
|
selectedZones: import_zod3.z.array(import_zod3.z.string()).nullable(),
|
|
567
570
|
zonePhotos: import_zod3.z.record(import_zod3.z.string(), beforeAfterPerZoneSchema).nullable(),
|
|
568
571
|
zoneBilling: import_zod3.z.record(import_zod3.z.string(), billingPerZoneSchema).nullable(),
|
|
569
|
-
finalbilling: finalBillingSchema.nullable()
|
|
572
|
+
finalbilling: finalBillingSchema.nullable(),
|
|
573
|
+
finalizationNotes: import_zod3.z.string().nullable()
|
|
570
574
|
});
|
|
571
575
|
var createAppointmentSchema = import_zod3.z.object({
|
|
572
576
|
clinicBranchId: import_zod3.z.string().min(MIN_STRING_LENGTH, "Clinic branch ID is required"),
|
|
@@ -932,44 +936,48 @@ async function updateAppointmentUtil(db, appointmentId, data) {
|
|
|
932
936
|
const validPreReqIds = currentAppointment.preProcedureRequirements.map(
|
|
933
937
|
(req) => req.id
|
|
934
938
|
);
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
if (invalidPreReqIds.length > 0) {
|
|
939
|
-
throw new Error(
|
|
940
|
-
`Invalid pre-requirement IDs: ${invalidPreReqIds.join(", ")}`
|
|
939
|
+
if (Array.isArray(data.completedPreRequirements)) {
|
|
940
|
+
const invalidPreReqIds = data.completedPreRequirements.filter(
|
|
941
|
+
(id) => !validPreReqIds.includes(id)
|
|
941
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
|
+
];
|
|
942
954
|
}
|
|
943
|
-
completedPreRequirements = [
|
|
944
|
-
.../* @__PURE__ */ new Set([
|
|
945
|
-
...completedPreRequirements,
|
|
946
|
-
...data.completedPreRequirements
|
|
947
|
-
])
|
|
948
|
-
];
|
|
949
955
|
}
|
|
950
956
|
if (data.completedPostRequirements) {
|
|
951
957
|
const validPostReqIds = currentAppointment.postProcedureRequirements.map(
|
|
952
958
|
(req) => req.id
|
|
953
959
|
);
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
if (invalidPostReqIds.length > 0) {
|
|
958
|
-
throw new Error(
|
|
959
|
-
`Invalid post-requirement IDs: ${invalidPostReqIds.join(", ")}`
|
|
960
|
+
if (Array.isArray(data.completedPostRequirements)) {
|
|
961
|
+
const invalidPostReqIds = data.completedPostRequirements.filter(
|
|
962
|
+
(id) => !validPostReqIds.includes(id)
|
|
960
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
|
+
];
|
|
961
975
|
}
|
|
962
|
-
completedPostRequirements = [
|
|
963
|
-
.../* @__PURE__ */ new Set([
|
|
964
|
-
...completedPostRequirements,
|
|
965
|
-
...data.completedPostRequirements
|
|
966
|
-
])
|
|
967
|
-
];
|
|
968
976
|
}
|
|
969
977
|
const updateData = {
|
|
970
978
|
...data,
|
|
971
|
-
completedPreRequirements,
|
|
972
|
-
completedPostRequirements,
|
|
979
|
+
completedPreRequirements: Array.isArray(data.completedPreRequirements) ? completedPreRequirements : data.completedPreRequirements,
|
|
980
|
+
completedPostRequirements: Array.isArray(data.completedPostRequirements) ? completedPostRequirements : data.completedPostRequirements,
|
|
973
981
|
updatedAt: (0, import_firestore.serverTimestamp)()
|
|
974
982
|
};
|
|
975
983
|
Object.keys(updateData).forEach((key) => {
|
|
@@ -1019,7 +1027,7 @@ async function updateCalendarEventStatus(db, calendarEventId, appointmentStatus)
|
|
|
1019
1027
|
case "canceled_clinic" /* CANCELED_CLINIC */:
|
|
1020
1028
|
calendarStatus = "canceled";
|
|
1021
1029
|
break;
|
|
1022
|
-
case
|
|
1030
|
+
case "rescheduled_by_clinic" /* RESCHEDULED_BY_CLINIC */:
|
|
1023
1031
|
calendarStatus = "rescheduled";
|
|
1024
1032
|
break;
|
|
1025
1033
|
case "completed" /* COMPLETED */:
|
|
@@ -1093,7 +1101,7 @@ async function searchAppointmentsUtil(db, params) {
|
|
|
1093
1101
|
const q = (0, import_firestore.query)((0, import_firestore.collection)(db, APPOINTMENTS_COLLECTION), ...constraints);
|
|
1094
1102
|
const querySnapshot = await (0, import_firestore.getDocs)(q);
|
|
1095
1103
|
const appointments = querySnapshot.docs.map(
|
|
1096
|
-
(
|
|
1104
|
+
(doc38) => doc38.data()
|
|
1097
1105
|
);
|
|
1098
1106
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
1099
1107
|
return { appointments, lastDoc };
|
|
@@ -1900,7 +1908,7 @@ var AppointmentService = class extends BaseService {
|
|
|
1900
1908
|
);
|
|
1901
1909
|
const querySnapshot = await (0, import_firestore2.getDocs)(q);
|
|
1902
1910
|
const appointments = querySnapshot.docs.map(
|
|
1903
|
-
(
|
|
1911
|
+
(doc38) => doc38.data()
|
|
1904
1912
|
);
|
|
1905
1913
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
1906
1914
|
console.log(
|
|
@@ -1973,7 +1981,7 @@ var AppointmentService = class extends BaseService {
|
|
|
1973
1981
|
);
|
|
1974
1982
|
const querySnapshot = await (0, import_firestore2.getDocs)(q);
|
|
1975
1983
|
const appointments = querySnapshot.docs.map(
|
|
1976
|
-
(
|
|
1984
|
+
(doc38) => doc38.data()
|
|
1977
1985
|
);
|
|
1978
1986
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
1979
1987
|
console.log(
|
|
@@ -2469,8 +2477,8 @@ var MediaAccessLevel = /* @__PURE__ */ ((MediaAccessLevel2) => {
|
|
|
2469
2477
|
})(MediaAccessLevel || {});
|
|
2470
2478
|
var MEDIA_METADATA_COLLECTION = "media_metadata";
|
|
2471
2479
|
var MediaService = class extends BaseService {
|
|
2472
|
-
constructor(
|
|
2473
|
-
super(
|
|
2480
|
+
constructor(...args) {
|
|
2481
|
+
super(...args);
|
|
2474
2482
|
}
|
|
2475
2483
|
/**
|
|
2476
2484
|
* Upload a media file, store its metadata, and return the metadata including the URL.
|
|
@@ -2730,7 +2738,7 @@ var MediaService = class extends BaseService {
|
|
|
2730
2738
|
try {
|
|
2731
2739
|
const querySnapshot = await (0, import_firestore4.getDocs)(finalQuery);
|
|
2732
2740
|
const mediaList = querySnapshot.docs.map(
|
|
2733
|
-
(
|
|
2741
|
+
(doc38) => doc38.data()
|
|
2734
2742
|
);
|
|
2735
2743
|
console.log(`[MediaService] Found ${mediaList.length} media items.`);
|
|
2736
2744
|
return mediaList;
|
|
@@ -2784,8 +2792,8 @@ var getPatientsByClinicUtil = async (db, clinicId, options) => {
|
|
|
2784
2792
|
}
|
|
2785
2793
|
const patientsSnapshot = await (0, import_firestore5.getDocs)(q);
|
|
2786
2794
|
const patients = [];
|
|
2787
|
-
patientsSnapshot.forEach((
|
|
2788
|
-
patients.push(
|
|
2795
|
+
patientsSnapshot.forEach((doc38) => {
|
|
2796
|
+
patients.push(doc38.data());
|
|
2789
2797
|
});
|
|
2790
2798
|
console.log(
|
|
2791
2799
|
`[getPatientsByClinicUtil] Found ${patients.length} patients for clinic ID: ${clinicId}`
|
|
@@ -2835,23 +2843,6 @@ var BlockingCondition = /* @__PURE__ */ ((BlockingCondition2) => {
|
|
|
2835
2843
|
return BlockingCondition2;
|
|
2836
2844
|
})(BlockingCondition || {});
|
|
2837
2845
|
|
|
2838
|
-
// src/backoffice/types/static/contraindication.types.ts
|
|
2839
|
-
var Contraindication = /* @__PURE__ */ ((Contraindication2) => {
|
|
2840
|
-
Contraindication2["SENSITIVE_SKIN"] = "sensitive_skin";
|
|
2841
|
-
Contraindication2["RECENT_TANNING"] = "recent_tanning";
|
|
2842
|
-
Contraindication2["RECENT_BOTOX"] = "recent_botox";
|
|
2843
|
-
Contraindication2["RECENT_FILLERS"] = "recent_fillers";
|
|
2844
|
-
Contraindication2["SKIN_ALLERGIES"] = "skin_allergies";
|
|
2845
|
-
Contraindication2["MEDICATIONS"] = "medications";
|
|
2846
|
-
Contraindication2["RECENT_CHEMICAL_PEEL"] = "recent_chemical_peel";
|
|
2847
|
-
Contraindication2["RECENT_LASER"] = "recent_laser";
|
|
2848
|
-
Contraindication2["SKIN_INFLAMMATION"] = "skin_inflammation";
|
|
2849
|
-
Contraindication2["OPEN_WOUNDS"] = "open_wounds";
|
|
2850
|
-
Contraindication2["HERPES_SIMPLEX"] = "herpes_simplex";
|
|
2851
|
-
Contraindication2["COLD_SORES"] = "cold_sores";
|
|
2852
|
-
return Contraindication2;
|
|
2853
|
-
})(Contraindication || {});
|
|
2854
|
-
|
|
2855
2846
|
// src/validations/common.schema.ts
|
|
2856
2847
|
var import_zod5 = require("zod");
|
|
2857
2848
|
var import_firestore6 = require("firebase/firestore");
|
|
@@ -2906,8 +2897,13 @@ var blockingConditionSchema = import_zod6.z.object({
|
|
|
2906
2897
|
notes: import_zod6.z.string().optional().nullable(),
|
|
2907
2898
|
isActive: import_zod6.z.boolean()
|
|
2908
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
|
+
});
|
|
2909
2905
|
var contraindicationSchema = import_zod6.z.object({
|
|
2910
|
-
condition:
|
|
2906
|
+
condition: contraindicationDynamicSchema,
|
|
2911
2907
|
lastOccurrence: timestampSchema,
|
|
2912
2908
|
frequency: import_zod6.z.enum(["rare", "occasional", "frequent"]),
|
|
2913
2909
|
notes: import_zod6.z.string().optional().nullable(),
|
|
@@ -3138,8 +3134,8 @@ var getPatientsByPractitionerUtil = async (db, practitionerId, options) => {
|
|
|
3138
3134
|
}
|
|
3139
3135
|
const patientsSnapshot = await (0, import_firestore8.getDocs)(q);
|
|
3140
3136
|
const patients = [];
|
|
3141
|
-
patientsSnapshot.forEach((
|
|
3142
|
-
patients.push(
|
|
3137
|
+
patientsSnapshot.forEach((doc38) => {
|
|
3138
|
+
patients.push(doc38.data());
|
|
3143
3139
|
});
|
|
3144
3140
|
console.log(
|
|
3145
3141
|
`[getPatientsByPractitionerUtil] Found ${patients.length} patients for practitioner ID: ${practitionerId}`
|
|
@@ -3906,7 +3902,7 @@ async function getClinicAdminsByGroup(db, clinicGroupId) {
|
|
|
3906
3902
|
(0, import_firestore10.where)("clinicGroupId", "==", clinicGroupId)
|
|
3907
3903
|
);
|
|
3908
3904
|
const querySnapshot = await (0, import_firestore10.getDocs)(q);
|
|
3909
|
-
return querySnapshot.docs.map((
|
|
3905
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
3910
3906
|
}
|
|
3911
3907
|
async function updateClinicAdmin(db, adminId, data) {
|
|
3912
3908
|
const admin = await getClinicAdmin(db, adminId);
|
|
@@ -4569,9 +4565,9 @@ var updateAllergyUtil = async (db, patientId, data, requesterId, requesterRoles)
|
|
|
4569
4565
|
};
|
|
4570
4566
|
var removeAllergyUtil = async (db, patientId, allergyIndex, requesterId, requesterRoles) => {
|
|
4571
4567
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4572
|
-
const
|
|
4573
|
-
if (!
|
|
4574
|
-
const medicalInfo =
|
|
4568
|
+
const doc38 = await (0, import_firestore15.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
4569
|
+
if (!doc38.exists()) throw new Error("Medical info not found");
|
|
4570
|
+
const medicalInfo = doc38.data();
|
|
4575
4571
|
if (allergyIndex >= medicalInfo.allergies.length) {
|
|
4576
4572
|
throw new Error("Invalid allergy index");
|
|
4577
4573
|
}
|
|
@@ -4598,9 +4594,9 @@ var updateBlockingConditionUtil = async (db, patientId, data, requesterId, reque
|
|
|
4598
4594
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4599
4595
|
const validatedData = updateBlockingConditionSchema.parse(data);
|
|
4600
4596
|
const { conditionIndex, ...updateData } = validatedData;
|
|
4601
|
-
const
|
|
4602
|
-
if (!
|
|
4603
|
-
const medicalInfo =
|
|
4597
|
+
const doc38 = await (0, import_firestore15.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
4598
|
+
if (!doc38.exists()) throw new Error("Medical info not found");
|
|
4599
|
+
const medicalInfo = doc38.data();
|
|
4604
4600
|
if (conditionIndex >= medicalInfo.blockingConditions.length) {
|
|
4605
4601
|
throw new Error("Invalid blocking condition index");
|
|
4606
4602
|
}
|
|
@@ -4617,9 +4613,9 @@ var updateBlockingConditionUtil = async (db, patientId, data, requesterId, reque
|
|
|
4617
4613
|
};
|
|
4618
4614
|
var removeBlockingConditionUtil = async (db, patientId, conditionIndex, requesterId, requesterRoles) => {
|
|
4619
4615
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4620
|
-
const
|
|
4621
|
-
if (!
|
|
4622
|
-
const medicalInfo =
|
|
4616
|
+
const doc38 = await (0, import_firestore15.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
4617
|
+
if (!doc38.exists()) throw new Error("Medical info not found");
|
|
4618
|
+
const medicalInfo = doc38.data();
|
|
4623
4619
|
if (conditionIndex >= medicalInfo.blockingConditions.length) {
|
|
4624
4620
|
throw new Error("Invalid blocking condition index");
|
|
4625
4621
|
}
|
|
@@ -4646,9 +4642,9 @@ var updateContraindicationUtil = async (db, patientId, data, requesterId, reques
|
|
|
4646
4642
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4647
4643
|
const validatedData = updateContraindicationSchema.parse(data);
|
|
4648
4644
|
const { contraindicationIndex, ...updateData } = validatedData;
|
|
4649
|
-
const
|
|
4650
|
-
if (!
|
|
4651
|
-
const medicalInfo =
|
|
4645
|
+
const doc38 = await (0, import_firestore15.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
4646
|
+
if (!doc38.exists()) throw new Error("Medical info not found");
|
|
4647
|
+
const medicalInfo = doc38.data();
|
|
4652
4648
|
if (contraindicationIndex >= medicalInfo.contraindications.length) {
|
|
4653
4649
|
throw new Error("Invalid contraindication index");
|
|
4654
4650
|
}
|
|
@@ -4665,9 +4661,9 @@ var updateContraindicationUtil = async (db, patientId, data, requesterId, reques
|
|
|
4665
4661
|
};
|
|
4666
4662
|
var removeContraindicationUtil = async (db, patientId, contraindicationIndex, requesterId, requesterRoles) => {
|
|
4667
4663
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4668
|
-
const
|
|
4669
|
-
if (!
|
|
4670
|
-
const medicalInfo =
|
|
4664
|
+
const doc38 = await (0, import_firestore15.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
4665
|
+
if (!doc38.exists()) throw new Error("Medical info not found");
|
|
4666
|
+
const medicalInfo = doc38.data();
|
|
4671
4667
|
if (contraindicationIndex >= medicalInfo.contraindications.length) {
|
|
4672
4668
|
throw new Error("Invalid contraindication index");
|
|
4673
4669
|
}
|
|
@@ -4694,9 +4690,9 @@ var updateMedicationUtil = async (db, patientId, data, requesterId, requesterRol
|
|
|
4694
4690
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4695
4691
|
const validatedData = updateMedicationSchema.parse(data);
|
|
4696
4692
|
const { medicationIndex, ...updateData } = validatedData;
|
|
4697
|
-
const
|
|
4698
|
-
if (!
|
|
4699
|
-
const medicalInfo =
|
|
4693
|
+
const doc38 = await (0, import_firestore15.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
4694
|
+
if (!doc38.exists()) throw new Error("Medical info not found");
|
|
4695
|
+
const medicalInfo = doc38.data();
|
|
4700
4696
|
if (medicationIndex >= medicalInfo.currentMedications.length) {
|
|
4701
4697
|
throw new Error("Invalid medication index");
|
|
4702
4698
|
}
|
|
@@ -4713,9 +4709,9 @@ var updateMedicationUtil = async (db, patientId, data, requesterId, requesterRol
|
|
|
4713
4709
|
};
|
|
4714
4710
|
var removeMedicationUtil = async (db, patientId, medicationIndex, requesterId, requesterRoles) => {
|
|
4715
4711
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4716
|
-
const
|
|
4717
|
-
if (!
|
|
4718
|
-
const medicalInfo =
|
|
4712
|
+
const doc38 = await (0, import_firestore15.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
4713
|
+
if (!doc38.exists()) throw new Error("Medical info not found");
|
|
4714
|
+
const medicalInfo = doc38.data();
|
|
4719
4715
|
if (medicationIndex >= medicalInfo.currentMedications.length) {
|
|
4720
4716
|
throw new Error("Invalid medication index");
|
|
4721
4717
|
}
|
|
@@ -5002,7 +4998,7 @@ var searchPatientsUtil = async (db, params, requester) => {
|
|
|
5002
4998
|
const finalQuery = (0, import_firestore16.query)(patientsCollectionRef, ...constraints);
|
|
5003
4999
|
const querySnapshot = await (0, import_firestore16.getDocs)(finalQuery);
|
|
5004
5000
|
const patients = querySnapshot.docs.map(
|
|
5005
|
-
(
|
|
5001
|
+
(doc38) => doc38.data()
|
|
5006
5002
|
);
|
|
5007
5003
|
console.log(
|
|
5008
5004
|
`[searchPatientsUtil] Found ${patients.length} patients matching criteria.`
|
|
@@ -5034,8 +5030,8 @@ var getAllPatientsUtil = async (db, options) => {
|
|
|
5034
5030
|
}
|
|
5035
5031
|
const patientsSnapshot = await (0, import_firestore16.getDocs)(q);
|
|
5036
5032
|
const patients = [];
|
|
5037
|
-
patientsSnapshot.forEach((
|
|
5038
|
-
patients.push(
|
|
5033
|
+
patientsSnapshot.forEach((doc38) => {
|
|
5034
|
+
patients.push(doc38.data());
|
|
5039
5035
|
});
|
|
5040
5036
|
console.log(`[getAllPatientsUtil] Found ${patients.length} patients`);
|
|
5041
5037
|
return patients;
|
|
@@ -5157,7 +5153,7 @@ var getActiveInviteTokensByClinicUtil = async (db, clinicId) => {
|
|
|
5157
5153
|
if (querySnapshot.empty) {
|
|
5158
5154
|
return [];
|
|
5159
5155
|
}
|
|
5160
|
-
return querySnapshot.docs.map((
|
|
5156
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
5161
5157
|
};
|
|
5162
5158
|
var getActiveInviteTokensByPatientUtil = async (db, patientId) => {
|
|
5163
5159
|
const tokensRef = (0, import_firestore17.collection)(
|
|
@@ -5175,7 +5171,7 @@ var getActiveInviteTokensByPatientUtil = async (db, patientId) => {
|
|
|
5175
5171
|
if (querySnapshot.empty) {
|
|
5176
5172
|
return [];
|
|
5177
5173
|
}
|
|
5178
|
-
return querySnapshot.docs.map((
|
|
5174
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
5179
5175
|
};
|
|
5180
5176
|
|
|
5181
5177
|
// src/services/patient/patient.service.ts
|
|
@@ -6447,7 +6443,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6447
6443
|
(0, import_firestore21.where)("expiresAt", ">", import_firestore21.Timestamp.now())
|
|
6448
6444
|
);
|
|
6449
6445
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6450
|
-
return querySnapshot.docs.map((
|
|
6446
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
6451
6447
|
}
|
|
6452
6448
|
/**
|
|
6453
6449
|
* Gets a token by its string value and validates it
|
|
@@ -6557,7 +6553,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6557
6553
|
(0, import_firestore21.where)("status", "==", "active" /* ACTIVE */)
|
|
6558
6554
|
);
|
|
6559
6555
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6560
|
-
return querySnapshot.docs.map((
|
|
6556
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
6561
6557
|
}
|
|
6562
6558
|
/**
|
|
6563
6559
|
* Dohvata sve zdravstvene radnike za određenu kliniku
|
|
@@ -6569,7 +6565,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6569
6565
|
(0, import_firestore21.where)("isActive", "==", true)
|
|
6570
6566
|
);
|
|
6571
6567
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6572
|
-
return querySnapshot.docs.map((
|
|
6568
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
6573
6569
|
}
|
|
6574
6570
|
/**
|
|
6575
6571
|
* Dohvata sve draft zdravstvene radnike za određenu kliniku sa statusom DRAFT
|
|
@@ -6581,7 +6577,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6581
6577
|
(0, import_firestore21.where)("status", "==", "draft" /* DRAFT */)
|
|
6582
6578
|
);
|
|
6583
6579
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6584
|
-
return querySnapshot.docs.map((
|
|
6580
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
6585
6581
|
}
|
|
6586
6582
|
/**
|
|
6587
6583
|
* Updates a practitioner
|
|
@@ -6796,7 +6792,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6796
6792
|
);
|
|
6797
6793
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6798
6794
|
const practitioners = querySnapshot.docs.map(
|
|
6799
|
-
(
|
|
6795
|
+
(doc38) => doc38.data()
|
|
6800
6796
|
);
|
|
6801
6797
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
6802
6798
|
return {
|
|
@@ -6870,7 +6866,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6870
6866
|
constraints.push((0, import_firestore21.limit)(filters.pagination || 10));
|
|
6871
6867
|
const q = (0, import_firestore21.query)((0, import_firestore21.collection)(this.db, PRACTITIONERS_COLLECTION), ...constraints);
|
|
6872
6868
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6873
|
-
const practitioners = querySnapshot.docs.map((
|
|
6869
|
+
const practitioners = querySnapshot.docs.map((doc38) => ({ ...doc38.data(), id: doc38.id }));
|
|
6874
6870
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
6875
6871
|
console.log(`[PRACTITIONER_SERVICE] Strategy 1 success: ${practitioners.length} practitioners`);
|
|
6876
6872
|
if (practitioners.length < (filters.pagination || 10)) {
|
|
@@ -6917,7 +6913,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6917
6913
|
}
|
|
6918
6914
|
const q = (0, import_firestore21.query)((0, import_firestore21.collection)(this.db, PRACTITIONERS_COLLECTION), ...constraints);
|
|
6919
6915
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6920
|
-
let practitioners = querySnapshot.docs.map((
|
|
6916
|
+
let practitioners = querySnapshot.docs.map((doc38) => ({ ...doc38.data(), id: doc38.id }));
|
|
6921
6917
|
if (filters.location && filters.radiusInKm && filters.radiusInKm > 0) {
|
|
6922
6918
|
const location = filters.location;
|
|
6923
6919
|
const radiusInKm = filters.radiusInKm;
|
|
@@ -6953,7 +6949,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6953
6949
|
];
|
|
6954
6950
|
const q = (0, import_firestore21.query)((0, import_firestore21.collection)(this.db, PRACTITIONERS_COLLECTION), ...constraints);
|
|
6955
6951
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6956
|
-
let practitioners = querySnapshot.docs.map((
|
|
6952
|
+
let practitioners = querySnapshot.docs.map((doc38) => ({ ...doc38.data(), id: doc38.id }));
|
|
6957
6953
|
practitioners = this.applyInMemoryFilters(practitioners, filters);
|
|
6958
6954
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
6959
6955
|
console.log(`[PRACTITIONER_SERVICE] Strategy 3 success: ${practitioners.length} practitioners`);
|
|
@@ -6974,7 +6970,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6974
6970
|
];
|
|
6975
6971
|
const q = (0, import_firestore21.query)((0, import_firestore21.collection)(this.db, PRACTITIONERS_COLLECTION), ...constraints);
|
|
6976
6972
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6977
|
-
let practitioners = querySnapshot.docs.map((
|
|
6973
|
+
let practitioners = querySnapshot.docs.map((doc38) => ({ ...doc38.data(), id: doc38.id }));
|
|
6978
6974
|
practitioners = this.applyInMemoryFilters(practitioners, filters);
|
|
6979
6975
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
6980
6976
|
console.log(`[PRACTITIONER_SERVICE] Strategy 4 success: ${practitioners.length} practitioners`);
|
|
@@ -7489,7 +7485,7 @@ var UserService = class extends BaseService {
|
|
|
7489
7485
|
];
|
|
7490
7486
|
const q = (0, import_firestore22.query)((0, import_firestore22.collection)(this.db, USERS_COLLECTION), ...constraints);
|
|
7491
7487
|
const querySnapshot = await (0, import_firestore22.getDocs)(q);
|
|
7492
|
-
const users = querySnapshot.docs.map((
|
|
7488
|
+
const users = querySnapshot.docs.map((doc38) => doc38.data());
|
|
7493
7489
|
return users.map((userData) => userSchema.parse(userData));
|
|
7494
7490
|
}
|
|
7495
7491
|
/**
|
|
@@ -7853,7 +7849,7 @@ async function getAllActiveGroups(db) {
|
|
|
7853
7849
|
(0, import_firestore23.where)("isActive", "==", true)
|
|
7854
7850
|
);
|
|
7855
7851
|
const querySnapshot = await (0, import_firestore23.getDocs)(q);
|
|
7856
|
-
return querySnapshot.docs.map((
|
|
7852
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
7857
7853
|
}
|
|
7858
7854
|
async function updateClinicGroup(db, groupId, data, app) {
|
|
7859
7855
|
console.log("[CLINIC_GROUP] Updating clinic group", { groupId });
|
|
@@ -8294,7 +8290,7 @@ async function getClinicsByGroup(db, groupId) {
|
|
|
8294
8290
|
(0, import_firestore24.where)("isActive", "==", true)
|
|
8295
8291
|
);
|
|
8296
8292
|
const querySnapshot = await (0, import_firestore24.getDocs)(q);
|
|
8297
|
-
return querySnapshot.docs.map((
|
|
8293
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
8298
8294
|
}
|
|
8299
8295
|
async function updateClinic(db, clinicId, data, adminId, clinicAdminService, app) {
|
|
8300
8296
|
console.log("[CLINIC] Starting clinic update", { clinicId, adminId });
|
|
@@ -8488,7 +8484,7 @@ async function getClinicsByAdmin(db, adminId, options = {}, clinicAdminService,
|
|
|
8488
8484
|
}
|
|
8489
8485
|
const q = (0, import_firestore24.query)((0, import_firestore24.collection)(db, CLINICS_COLLECTION), ...constraints);
|
|
8490
8486
|
const querySnapshot = await (0, import_firestore24.getDocs)(q);
|
|
8491
|
-
return querySnapshot.docs.map((
|
|
8487
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
8492
8488
|
}
|
|
8493
8489
|
async function getActiveClinicsByAdmin(db, adminId, clinicAdminService, clinicGroupService) {
|
|
8494
8490
|
return getClinicsByAdmin(
|
|
@@ -8533,11 +8529,11 @@ async function getAllClinics(db, pagination, lastDoc) {
|
|
|
8533
8529
|
}
|
|
8534
8530
|
const clinicsSnapshot = await (0, import_firestore24.getDocs)(clinicsQuery);
|
|
8535
8531
|
const lastVisible = clinicsSnapshot.docs[clinicsSnapshot.docs.length - 1];
|
|
8536
|
-
const clinics = clinicsSnapshot.docs.map((
|
|
8537
|
-
const data =
|
|
8532
|
+
const clinics = clinicsSnapshot.docs.map((doc38) => {
|
|
8533
|
+
const data = doc38.data();
|
|
8538
8534
|
return {
|
|
8539
8535
|
...data,
|
|
8540
|
-
id:
|
|
8536
|
+
id: doc38.id
|
|
8541
8537
|
};
|
|
8542
8538
|
});
|
|
8543
8539
|
return {
|
|
@@ -8564,8 +8560,8 @@ async function getAllClinicsInRange(db, center, rangeInKm, pagination, lastDoc)
|
|
|
8564
8560
|
];
|
|
8565
8561
|
const q = (0, import_firestore24.query)((0, import_firestore24.collection)(db, CLINICS_COLLECTION), ...constraints);
|
|
8566
8562
|
const querySnapshot = await (0, import_firestore24.getDocs)(q);
|
|
8567
|
-
for (const
|
|
8568
|
-
const clinic =
|
|
8563
|
+
for (const doc38 of querySnapshot.docs) {
|
|
8564
|
+
const clinic = doc38.data();
|
|
8569
8565
|
const distance = (0, import_geofire_common4.distanceBetween)(
|
|
8570
8566
|
[center.latitude, center.longitude],
|
|
8571
8567
|
[clinic.location.latitude, clinic.location.longitude]
|
|
@@ -8682,8 +8678,8 @@ async function findClinicsInRadius(db, center, radiusInKm, filters) {
|
|
|
8682
8678
|
}
|
|
8683
8679
|
const q = (0, import_firestore25.query)((0, import_firestore25.collection)(db, CLINICS_COLLECTION), ...constraints);
|
|
8684
8680
|
const querySnapshot = await (0, import_firestore25.getDocs)(q);
|
|
8685
|
-
for (const
|
|
8686
|
-
const clinic =
|
|
8681
|
+
for (const doc38 of querySnapshot.docs) {
|
|
8682
|
+
const clinic = doc38.data();
|
|
8687
8683
|
const distance = (0, import_geofire_common5.distanceBetween)(
|
|
8688
8684
|
[center.latitude, center.longitude],
|
|
8689
8685
|
[clinic.location.latitude, clinic.location.longitude]
|
|
@@ -8804,7 +8800,7 @@ async function getClinicsByFilters(db, filters) {
|
|
|
8804
8800
|
constraints.push((0, import_firestore26.limit)(filters.pagination || 5));
|
|
8805
8801
|
const q = (0, import_firestore26.query)((0, import_firestore26.collection)(db, CLINICS_COLLECTION), ...constraints);
|
|
8806
8802
|
const querySnapshot = await (0, import_firestore26.getDocs)(q);
|
|
8807
|
-
let clinics = querySnapshot.docs.map((
|
|
8803
|
+
let clinics = querySnapshot.docs.map((doc38) => ({ ...doc38.data(), id: doc38.id }));
|
|
8808
8804
|
clinics = applyInMemoryFilters(clinics, filters);
|
|
8809
8805
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
8810
8806
|
console.log(`[CLINIC_SERVICE] Strategy 1 success: ${clinics.length} clinics`);
|
|
@@ -8836,7 +8832,7 @@ async function getClinicsByFilters(db, filters) {
|
|
|
8836
8832
|
constraints.push((0, import_firestore26.limit)(filters.pagination || 5));
|
|
8837
8833
|
const q = (0, import_firestore26.query)((0, import_firestore26.collection)(db, CLINICS_COLLECTION), ...constraints);
|
|
8838
8834
|
const querySnapshot = await (0, import_firestore26.getDocs)(q);
|
|
8839
|
-
let clinics = querySnapshot.docs.map((
|
|
8835
|
+
let clinics = querySnapshot.docs.map((doc38) => ({ ...doc38.data(), id: doc38.id }));
|
|
8840
8836
|
clinics = applyInMemoryFilters(clinics, filters);
|
|
8841
8837
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
8842
8838
|
console.log(`[CLINIC_SERVICE] Strategy 2 success: ${clinics.length} clinics`);
|
|
@@ -8866,7 +8862,7 @@ async function getClinicsByFilters(db, filters) {
|
|
|
8866
8862
|
constraints.push((0, import_firestore26.limit)(filters.pagination || 5));
|
|
8867
8863
|
const q = (0, import_firestore26.query)((0, import_firestore26.collection)(db, CLINICS_COLLECTION), ...constraints);
|
|
8868
8864
|
const querySnapshot = await (0, import_firestore26.getDocs)(q);
|
|
8869
|
-
let clinics = querySnapshot.docs.map((
|
|
8865
|
+
let clinics = querySnapshot.docs.map((doc38) => ({ ...doc38.data(), id: doc38.id }));
|
|
8870
8866
|
clinics = applyInMemoryFilters(clinics, filters);
|
|
8871
8867
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
8872
8868
|
console.log(`[CLINIC_SERVICE] Strategy 3 success: ${clinics.length} clinics`);
|
|
@@ -8886,7 +8882,7 @@ async function getClinicsByFilters(db, filters) {
|
|
|
8886
8882
|
];
|
|
8887
8883
|
const q = (0, import_firestore26.query)((0, import_firestore26.collection)(db, CLINICS_COLLECTION), ...constraints);
|
|
8888
8884
|
const querySnapshot = await (0, import_firestore26.getDocs)(q);
|
|
8889
|
-
let clinics = querySnapshot.docs.map((
|
|
8885
|
+
let clinics = querySnapshot.docs.map((doc38) => ({ ...doc38.data(), id: doc38.id }));
|
|
8890
8886
|
clinics = applyInMemoryFilters(clinics, filters);
|
|
8891
8887
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
8892
8888
|
console.log(`[CLINIC_SERVICE] Strategy 4 success: ${clinics.length} clinics`);
|
|
@@ -9462,11 +9458,11 @@ var ClinicService = class extends BaseService {
|
|
|
9462
9458
|
async getClinicsForMap() {
|
|
9463
9459
|
const clinicsRef = (0, import_firestore27.collection)(this.db, CLINICS_COLLECTION);
|
|
9464
9460
|
const snapshot = await (0, import_firestore27.getDocs)(clinicsRef);
|
|
9465
|
-
const clinicsForMap = snapshot.docs.map((
|
|
9461
|
+
const clinicsForMap = snapshot.docs.map((doc38) => {
|
|
9466
9462
|
var _a, _b, _c;
|
|
9467
|
-
const data =
|
|
9463
|
+
const data = doc38.data();
|
|
9468
9464
|
return {
|
|
9469
|
-
id:
|
|
9465
|
+
id: doc38.id,
|
|
9470
9466
|
name: data.name,
|
|
9471
9467
|
address: ((_a = data.location) == null ? void 0 : _a.address) || "",
|
|
9472
9468
|
latitude: (_b = data.location) == null ? void 0 : _b.latitude,
|
|
@@ -10627,7 +10623,7 @@ async function updatePractitionerCalendarEventUtil(db, practitionerId, eventId,
|
|
|
10627
10623
|
}
|
|
10628
10624
|
|
|
10629
10625
|
// src/services/calendar/utils/appointment.utils.ts
|
|
10630
|
-
async function
|
|
10626
|
+
async function createAppointmentUtil(db, clinicId, practitionerId, patientId, eventData, generateId2) {
|
|
10631
10627
|
const eventId = generateId2();
|
|
10632
10628
|
const autoConfirm = await checkAutoConfirmAppointmentsUtil(db, clinicId);
|
|
10633
10629
|
const initialStatus = autoConfirm ? "confirmed" /* CONFIRMED */ : "pending" /* PENDING */;
|
|
@@ -10761,7 +10757,7 @@ async function searchCalendarEventsUtil(db, params) {
|
|
|
10761
10757
|
const finalQuery = (0, import_firestore33.query)(collectionRef, ...constraints);
|
|
10762
10758
|
const querySnapshot = await (0, import_firestore33.getDocs)(finalQuery);
|
|
10763
10759
|
const events = querySnapshot.docs.map(
|
|
10764
|
-
(
|
|
10760
|
+
(doc38) => ({ id: doc38.id, ...doc38.data() })
|
|
10765
10761
|
);
|
|
10766
10762
|
return events;
|
|
10767
10763
|
} catch (error) {
|
|
@@ -10843,7 +10839,7 @@ async function getPractitionerSyncedCalendarsUtil(db, practitionerId) {
|
|
|
10843
10839
|
);
|
|
10844
10840
|
const q = (0, import_firestore34.query)(calendarsRef, (0, import_firestore34.orderBy)("createdAt", "desc"));
|
|
10845
10841
|
const querySnapshot = await (0, import_firestore34.getDocs)(q);
|
|
10846
|
-
return querySnapshot.docs.map((
|
|
10842
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
10847
10843
|
}
|
|
10848
10844
|
async function getPatientSyncedCalendarUtil(db, patientId, calendarId) {
|
|
10849
10845
|
const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
|
|
@@ -10860,7 +10856,7 @@ async function getPatientSyncedCalendarsUtil(db, patientId) {
|
|
|
10860
10856
|
);
|
|
10861
10857
|
const q = (0, import_firestore34.query)(calendarsRef, (0, import_firestore34.orderBy)("createdAt", "desc"));
|
|
10862
10858
|
const querySnapshot = await (0, import_firestore34.getDocs)(q);
|
|
10863
|
-
return querySnapshot.docs.map((
|
|
10859
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
10864
10860
|
}
|
|
10865
10861
|
async function getClinicSyncedCalendarUtil(db, clinicId, calendarId) {
|
|
10866
10862
|
const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
|
|
@@ -10877,7 +10873,7 @@ async function getClinicSyncedCalendarsUtil(db, clinicId) {
|
|
|
10877
10873
|
);
|
|
10878
10874
|
const q = (0, import_firestore34.query)(calendarsRef, (0, import_firestore34.orderBy)("createdAt", "desc"));
|
|
10879
10875
|
const querySnapshot = await (0, import_firestore34.getDocs)(q);
|
|
10880
|
-
return querySnapshot.docs.map((
|
|
10876
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
10881
10877
|
}
|
|
10882
10878
|
async function updatePractitionerSyncedCalendarUtil(db, practitionerId, calendarId, updateData) {
|
|
10883
10879
|
const calendarRef = getPractitionerSyncedCalendarDocRef(
|
|
@@ -11945,7 +11941,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
11945
11941
|
syncStatus: "internal" /* INTERNAL */,
|
|
11946
11942
|
eventType: "appointment" /* APPOINTMENT */
|
|
11947
11943
|
};
|
|
11948
|
-
const appointment = await
|
|
11944
|
+
const appointment = await createAppointmentUtil(
|
|
11949
11945
|
this.db,
|
|
11950
11946
|
params.clinicId,
|
|
11951
11947
|
params.doctorId,
|
|
@@ -12232,9 +12228,9 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
12232
12228
|
(0, import_firestore37.where)("eventTime.start", "<=", import_firestore36.Timestamp.fromDate(endDate))
|
|
12233
12229
|
);
|
|
12234
12230
|
const eventsSnapshot = await (0, import_firestore37.getDocs)(q);
|
|
12235
|
-
const events = eventsSnapshot.docs.map((
|
|
12236
|
-
id:
|
|
12237
|
-
...
|
|
12231
|
+
const events = eventsSnapshot.docs.map((doc38) => ({
|
|
12232
|
+
id: doc38.id,
|
|
12233
|
+
...doc38.data()
|
|
12238
12234
|
}));
|
|
12239
12235
|
const calendars = await this.syncedCalendarsService.getPractitionerSyncedCalendars(
|
|
12240
12236
|
doctorId
|
|
@@ -12868,7 +12864,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
12868
12864
|
])
|
|
12869
12865
|
);
|
|
12870
12866
|
const querySnapshot = await (0, import_firestore37.getDocs)(q);
|
|
12871
|
-
return querySnapshot.docs.map((
|
|
12867
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
12872
12868
|
}
|
|
12873
12869
|
/**
|
|
12874
12870
|
* Calculates available time slots based on working hours, schedule and existing appointments
|
|
@@ -13399,7 +13395,7 @@ var PractitionerInviteService = class extends BaseService {
|
|
|
13399
13395
|
...constraints
|
|
13400
13396
|
);
|
|
13401
13397
|
const querySnapshot = await (0, import_firestore40.getDocs)(q);
|
|
13402
|
-
return querySnapshot.docs.map((
|
|
13398
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
13403
13399
|
} catch (error) {
|
|
13404
13400
|
console.error(
|
|
13405
13401
|
"[PractitionerInviteService] Error getting doctor invites:",
|
|
@@ -13428,7 +13424,7 @@ var PractitionerInviteService = class extends BaseService {
|
|
|
13428
13424
|
...constraints
|
|
13429
13425
|
);
|
|
13430
13426
|
const querySnapshot = await (0, import_firestore40.getDocs)(q);
|
|
13431
|
-
return querySnapshot.docs.map((
|
|
13427
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
13432
13428
|
} catch (error) {
|
|
13433
13429
|
console.error(
|
|
13434
13430
|
"[PractitionerInviteService] Error getting clinic invites:",
|
|
@@ -13584,7 +13580,7 @@ var PractitionerInviteService = class extends BaseService {
|
|
|
13584
13580
|
);
|
|
13585
13581
|
const querySnapshot = await (0, import_firestore40.getDocs)(q);
|
|
13586
13582
|
let invites = querySnapshot.docs.map(
|
|
13587
|
-
(
|
|
13583
|
+
(doc38) => doc38.data()
|
|
13588
13584
|
);
|
|
13589
13585
|
if (filters.fromDate) {
|
|
13590
13586
|
invites = invites.filter(
|
|
@@ -13687,9 +13683,10 @@ var PractitionerInviteService = class extends BaseService {
|
|
|
13687
13683
|
|
|
13688
13684
|
// src/services/documentation-templates/documentation-template.service.ts
|
|
13689
13685
|
var import_firestore41 = require("firebase/firestore");
|
|
13686
|
+
var import_firestore42 = require("firebase/firestore");
|
|
13690
13687
|
var DocumentationTemplateService = class extends BaseService {
|
|
13691
|
-
constructor() {
|
|
13692
|
-
super(...
|
|
13688
|
+
constructor(...args) {
|
|
13689
|
+
super(...args);
|
|
13693
13690
|
this.collectionRef = (0, import_firestore41.collection)(
|
|
13694
13691
|
this.db,
|
|
13695
13692
|
DOCUMENTATION_TEMPLATES_COLLECTION
|
|
@@ -13841,8 +13838,8 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
13841
13838
|
const q = (0, import_firestore41.query)(versionsCollectionRef, (0, import_firestore41.orderBy)("version", "desc"));
|
|
13842
13839
|
const querySnapshot = await (0, import_firestore41.getDocs)(q);
|
|
13843
13840
|
const versions = [];
|
|
13844
|
-
querySnapshot.forEach((
|
|
13845
|
-
versions.push(
|
|
13841
|
+
querySnapshot.forEach((doc38) => {
|
|
13842
|
+
versions.push(doc38.data());
|
|
13846
13843
|
});
|
|
13847
13844
|
return versions;
|
|
13848
13845
|
}
|
|
@@ -13873,15 +13870,97 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
13873
13870
|
const querySnapshot = await (0, import_firestore41.getDocs)(q);
|
|
13874
13871
|
const templates = [];
|
|
13875
13872
|
let lastVisible = null;
|
|
13876
|
-
querySnapshot.forEach((
|
|
13877
|
-
templates.push(
|
|
13878
|
-
lastVisible =
|
|
13873
|
+
querySnapshot.forEach((doc38) => {
|
|
13874
|
+
templates.push(doc38.data());
|
|
13875
|
+
lastVisible = doc38;
|
|
13876
|
+
});
|
|
13877
|
+
return {
|
|
13878
|
+
templates,
|
|
13879
|
+
lastDoc: lastVisible
|
|
13880
|
+
};
|
|
13881
|
+
}
|
|
13882
|
+
/**
|
|
13883
|
+
* Get all active templates with optional filters and pagination.
|
|
13884
|
+
* @param options - Options for filtering and pagination.
|
|
13885
|
+
* @returns A promise that resolves to the templates and the last visible document.
|
|
13886
|
+
*/
|
|
13887
|
+
async getTemplates(options) {
|
|
13888
|
+
const {
|
|
13889
|
+
pageSize = 20,
|
|
13890
|
+
lastDoc,
|
|
13891
|
+
isUserForm,
|
|
13892
|
+
isRequired,
|
|
13893
|
+
sortingOrder
|
|
13894
|
+
} = options;
|
|
13895
|
+
const constraints = [
|
|
13896
|
+
(0, import_firestore41.where)("isActive", "==", true),
|
|
13897
|
+
(0, import_firestore41.orderBy)("sortingOrder", "asc"),
|
|
13898
|
+
(0, import_firestore41.orderBy)("title", "asc"),
|
|
13899
|
+
(0, import_firestore41.limit)(pageSize)
|
|
13900
|
+
];
|
|
13901
|
+
if (isUserForm !== void 0) {
|
|
13902
|
+
constraints.push((0, import_firestore41.where)("isUserForm", "==", isUserForm));
|
|
13903
|
+
}
|
|
13904
|
+
if (isRequired !== void 0) {
|
|
13905
|
+
constraints.push((0, import_firestore41.where)("isRequired", "==", isRequired));
|
|
13906
|
+
}
|
|
13907
|
+
if (sortingOrder !== void 0) {
|
|
13908
|
+
constraints.push((0, import_firestore41.where)("sortingOrder", "==", sortingOrder));
|
|
13909
|
+
}
|
|
13910
|
+
if (lastDoc) {
|
|
13911
|
+
constraints.push((0, import_firestore41.startAfter)(lastDoc));
|
|
13912
|
+
}
|
|
13913
|
+
const q = (0, import_firestore41.query)(this.collectionRef, ...constraints.filter((c) => c));
|
|
13914
|
+
const querySnapshot = await (0, import_firestore41.getDocs)(q);
|
|
13915
|
+
const templates = [];
|
|
13916
|
+
let lastVisible = null;
|
|
13917
|
+
querySnapshot.forEach((doc38) => {
|
|
13918
|
+
templates.push(doc38.data());
|
|
13919
|
+
lastVisible = doc38;
|
|
13879
13920
|
});
|
|
13880
13921
|
return {
|
|
13881
13922
|
templates,
|
|
13882
13923
|
lastDoc: lastVisible
|
|
13883
13924
|
};
|
|
13884
13925
|
}
|
|
13926
|
+
/**
|
|
13927
|
+
* Get the total count of active templates with optional filters.
|
|
13928
|
+
* @param options - Options for filtering.
|
|
13929
|
+
* @returns A promise that resolves to the total count of templates.
|
|
13930
|
+
*/
|
|
13931
|
+
async getTemplatesCount(options) {
|
|
13932
|
+
const { isUserForm, isRequired, sortingOrder } = options;
|
|
13933
|
+
const constraints = [(0, import_firestore41.where)("isActive", "==", true)];
|
|
13934
|
+
if (isUserForm !== void 0) {
|
|
13935
|
+
constraints.push((0, import_firestore41.where)("isUserForm", "==", isUserForm));
|
|
13936
|
+
}
|
|
13937
|
+
if (isRequired !== void 0) {
|
|
13938
|
+
constraints.push((0, import_firestore41.where)("isRequired", "==", isRequired));
|
|
13939
|
+
}
|
|
13940
|
+
if (sortingOrder !== void 0) {
|
|
13941
|
+
constraints.push((0, import_firestore41.where)("sortingOrder", "==", sortingOrder));
|
|
13942
|
+
}
|
|
13943
|
+
const q = (0, import_firestore41.query)(this.collectionRef, ...constraints.filter((c) => c));
|
|
13944
|
+
const snapshot = await (0, import_firestore42.getCountFromServer)(q);
|
|
13945
|
+
return snapshot.data().count;
|
|
13946
|
+
}
|
|
13947
|
+
/**
|
|
13948
|
+
* Get all active templates without pagination for filtering purposes.
|
|
13949
|
+
* @returns A promise that resolves to an array of all active templates.
|
|
13950
|
+
*/
|
|
13951
|
+
async getAllActiveTemplates() {
|
|
13952
|
+
const q = (0, import_firestore41.query)(
|
|
13953
|
+
this.collectionRef,
|
|
13954
|
+
(0, import_firestore41.where)("isActive", "==", true),
|
|
13955
|
+
(0, import_firestore41.orderBy)("title", "asc")
|
|
13956
|
+
);
|
|
13957
|
+
const querySnapshot = await (0, import_firestore41.getDocs)(q);
|
|
13958
|
+
const templates = [];
|
|
13959
|
+
querySnapshot.forEach((doc38) => {
|
|
13960
|
+
templates.push(doc38.data());
|
|
13961
|
+
});
|
|
13962
|
+
return templates;
|
|
13963
|
+
}
|
|
13885
13964
|
/**
|
|
13886
13965
|
* Get templates by tags
|
|
13887
13966
|
* @param tags - Tags to filter by
|
|
@@ -13903,9 +13982,9 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
13903
13982
|
const querySnapshot = await (0, import_firestore41.getDocs)(q);
|
|
13904
13983
|
const templates = [];
|
|
13905
13984
|
let lastVisible = null;
|
|
13906
|
-
querySnapshot.forEach((
|
|
13907
|
-
templates.push(
|
|
13908
|
-
lastVisible =
|
|
13985
|
+
querySnapshot.forEach((doc38) => {
|
|
13986
|
+
templates.push(doc38.data());
|
|
13987
|
+
lastVisible = doc38;
|
|
13909
13988
|
});
|
|
13910
13989
|
return {
|
|
13911
13990
|
templates,
|
|
@@ -13932,9 +14011,9 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
13932
14011
|
const querySnapshot = await (0, import_firestore41.getDocs)(q);
|
|
13933
14012
|
const templates = [];
|
|
13934
14013
|
let lastVisible = null;
|
|
13935
|
-
querySnapshot.forEach((
|
|
13936
|
-
templates.push(
|
|
13937
|
-
lastVisible =
|
|
14014
|
+
querySnapshot.forEach((doc38) => {
|
|
14015
|
+
templates.push(doc38.data());
|
|
14016
|
+
lastVisible = doc38;
|
|
13938
14017
|
});
|
|
13939
14018
|
return {
|
|
13940
14019
|
templates,
|
|
@@ -13960,15 +14039,15 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
13960
14039
|
}
|
|
13961
14040
|
const querySnapshot = await (0, import_firestore41.getDocs)(q);
|
|
13962
14041
|
const templates = [];
|
|
13963
|
-
querySnapshot.forEach((
|
|
13964
|
-
templates.push(
|
|
14042
|
+
querySnapshot.forEach((doc38) => {
|
|
14043
|
+
templates.push(doc38.data());
|
|
13965
14044
|
});
|
|
13966
14045
|
return templates;
|
|
13967
14046
|
}
|
|
13968
14047
|
};
|
|
13969
14048
|
|
|
13970
14049
|
// src/services/documentation-templates/filled-document.service.ts
|
|
13971
|
-
var
|
|
14050
|
+
var import_firestore43 = require("firebase/firestore");
|
|
13972
14051
|
var FilledDocumentService = class extends BaseService {
|
|
13973
14052
|
constructor(...args) {
|
|
13974
14053
|
super(...args);
|
|
@@ -14023,7 +14102,7 @@ var FilledDocumentService = class extends BaseService {
|
|
|
14023
14102
|
values: initialValues,
|
|
14024
14103
|
status: initialStatus
|
|
14025
14104
|
};
|
|
14026
|
-
const docRef = (0,
|
|
14105
|
+
const docRef = (0, import_firestore43.doc)(
|
|
14027
14106
|
this.db,
|
|
14028
14107
|
APPOINTMENTS_COLLECTION,
|
|
14029
14108
|
// Replaced "appointments"
|
|
@@ -14031,7 +14110,7 @@ var FilledDocumentService = class extends BaseService {
|
|
|
14031
14110
|
formSubcollection,
|
|
14032
14111
|
documentId3
|
|
14033
14112
|
);
|
|
14034
|
-
await (0,
|
|
14113
|
+
await (0, import_firestore43.setDoc)(docRef, filledDocument);
|
|
14035
14114
|
return filledDocument;
|
|
14036
14115
|
}
|
|
14037
14116
|
/**
|
|
@@ -14043,7 +14122,7 @@ var FilledDocumentService = class extends BaseService {
|
|
|
14043
14122
|
*/
|
|
14044
14123
|
async getFilledDocumentFromAppointmentById(appointmentId, formId, isUserForm) {
|
|
14045
14124
|
const formSubcollection = this.getFormSubcollectionPath(isUserForm);
|
|
14046
|
-
const docRef = (0,
|
|
14125
|
+
const docRef = (0, import_firestore43.doc)(
|
|
14047
14126
|
this.db,
|
|
14048
14127
|
APPOINTMENTS_COLLECTION,
|
|
14049
14128
|
// Replaced "appointments"
|
|
@@ -14051,7 +14130,7 @@ var FilledDocumentService = class extends BaseService {
|
|
|
14051
14130
|
formSubcollection,
|
|
14052
14131
|
formId
|
|
14053
14132
|
);
|
|
14054
|
-
const docSnap = await (0,
|
|
14133
|
+
const docSnap = await (0, import_firestore43.getDoc)(docRef);
|
|
14055
14134
|
if (!docSnap.exists()) {
|
|
14056
14135
|
return null;
|
|
14057
14136
|
}
|
|
@@ -14068,7 +14147,7 @@ var FilledDocumentService = class extends BaseService {
|
|
|
14068
14147
|
*/
|
|
14069
14148
|
async updateFilledDocumentInAppointment(appointmentId, formId, isUserForm, values, status) {
|
|
14070
14149
|
const formSubcollection = this.getFormSubcollectionPath(isUserForm);
|
|
14071
|
-
const docRef = (0,
|
|
14150
|
+
const docRef = (0, import_firestore43.doc)(
|
|
14072
14151
|
this.db,
|
|
14073
14152
|
APPOINTMENTS_COLLECTION,
|
|
14074
14153
|
// Replaced "appointments"
|
|
@@ -14100,7 +14179,7 @@ var FilledDocumentService = class extends BaseService {
|
|
|
14100
14179
|
}
|
|
14101
14180
|
if (Object.keys(updatePayload).length === 1 && "updatedAt" in updatePayload) {
|
|
14102
14181
|
}
|
|
14103
|
-
await (0,
|
|
14182
|
+
await (0, import_firestore43.updateDoc)(docRef, updatePayload);
|
|
14104
14183
|
return { ...existingDoc, ...updatePayload };
|
|
14105
14184
|
}
|
|
14106
14185
|
/**
|
|
@@ -14110,20 +14189,20 @@ var FilledDocumentService = class extends BaseService {
|
|
|
14110
14189
|
* @param lastDoc Last document from previous page for pagination.
|
|
14111
14190
|
*/
|
|
14112
14191
|
async getFilledUserFormsForAppointment(appointmentId, pageSize = 20, lastDoc) {
|
|
14113
|
-
const subcollectionRef = (0,
|
|
14192
|
+
const subcollectionRef = (0, import_firestore43.collection)(
|
|
14114
14193
|
this.db,
|
|
14115
14194
|
APPOINTMENTS_COLLECTION,
|
|
14116
14195
|
// Replaced "appointments"
|
|
14117
14196
|
appointmentId,
|
|
14118
14197
|
USER_FORMS_SUBCOLLECTION
|
|
14119
14198
|
);
|
|
14120
|
-
let q = (0,
|
|
14199
|
+
let q = (0, import_firestore43.query)(
|
|
14121
14200
|
subcollectionRef,
|
|
14122
|
-
(0,
|
|
14123
|
-
(0,
|
|
14201
|
+
(0, import_firestore43.orderBy)("updatedAt", "desc"),
|
|
14202
|
+
(0, import_firestore43.limit)(pageSize)
|
|
14124
14203
|
);
|
|
14125
14204
|
if (lastDoc) {
|
|
14126
|
-
q = (0,
|
|
14205
|
+
q = (0, import_firestore43.query)(q, (0, import_firestore43.startAfter)(lastDoc));
|
|
14127
14206
|
}
|
|
14128
14207
|
return this.executeQuery(q);
|
|
14129
14208
|
}
|
|
@@ -14134,31 +14213,31 @@ var FilledDocumentService = class extends BaseService {
|
|
|
14134
14213
|
* @param lastDoc Last document from previous page for pagination.
|
|
14135
14214
|
*/
|
|
14136
14215
|
async getFilledDoctorFormsForAppointment(appointmentId, pageSize = 20, lastDoc) {
|
|
14137
|
-
const subcollectionRef = (0,
|
|
14216
|
+
const subcollectionRef = (0, import_firestore43.collection)(
|
|
14138
14217
|
this.db,
|
|
14139
14218
|
APPOINTMENTS_COLLECTION,
|
|
14140
14219
|
// Replaced "appointments"
|
|
14141
14220
|
appointmentId,
|
|
14142
14221
|
DOCTOR_FORMS_SUBCOLLECTION
|
|
14143
14222
|
);
|
|
14144
|
-
let q = (0,
|
|
14223
|
+
let q = (0, import_firestore43.query)(
|
|
14145
14224
|
subcollectionRef,
|
|
14146
|
-
(0,
|
|
14147
|
-
(0,
|
|
14225
|
+
(0, import_firestore43.orderBy)("updatedAt", "desc"),
|
|
14226
|
+
(0, import_firestore43.limit)(pageSize)
|
|
14148
14227
|
);
|
|
14149
14228
|
if (lastDoc) {
|
|
14150
|
-
q = (0,
|
|
14229
|
+
q = (0, import_firestore43.query)(q, (0, import_firestore43.startAfter)(lastDoc));
|
|
14151
14230
|
}
|
|
14152
14231
|
return this.executeQuery(q);
|
|
14153
14232
|
}
|
|
14154
14233
|
// Helper to execute query and return documents + lastDoc
|
|
14155
14234
|
async executeQuery(q) {
|
|
14156
|
-
const querySnapshot = await (0,
|
|
14235
|
+
const querySnapshot = await (0, import_firestore43.getDocs)(q);
|
|
14157
14236
|
const documents = [];
|
|
14158
14237
|
let lastVisible = null;
|
|
14159
|
-
querySnapshot.forEach((
|
|
14160
|
-
documents.push(
|
|
14161
|
-
lastVisible =
|
|
14238
|
+
querySnapshot.forEach((doc38) => {
|
|
14239
|
+
documents.push(doc38.data());
|
|
14240
|
+
lastVisible = doc38;
|
|
14162
14241
|
});
|
|
14163
14242
|
return {
|
|
14164
14243
|
documents,
|
|
@@ -14317,14 +14396,14 @@ var FilledDocumentService = class extends BaseService {
|
|
|
14317
14396
|
};
|
|
14318
14397
|
|
|
14319
14398
|
// src/services/notifications/notification.service.ts
|
|
14320
|
-
var
|
|
14399
|
+
var import_firestore44 = require("firebase/firestore");
|
|
14321
14400
|
var NotificationService = class extends BaseService {
|
|
14322
14401
|
/**
|
|
14323
14402
|
* Kreira novu notifikaciju
|
|
14324
14403
|
*/
|
|
14325
14404
|
async createNotification(notification) {
|
|
14326
|
-
const notificationsRef = (0,
|
|
14327
|
-
const now =
|
|
14405
|
+
const notificationsRef = (0, import_firestore44.collection)(this.db, NOTIFICATIONS_COLLECTION);
|
|
14406
|
+
const now = import_firestore44.Timestamp.now();
|
|
14328
14407
|
const notificationData = {
|
|
14329
14408
|
...notification,
|
|
14330
14409
|
createdAt: now,
|
|
@@ -14333,7 +14412,7 @@ var NotificationService = class extends BaseService {
|
|
|
14333
14412
|
isRead: false,
|
|
14334
14413
|
userRole: notification.userRole || "patient" /* PATIENT */
|
|
14335
14414
|
};
|
|
14336
|
-
const docRef = await (0,
|
|
14415
|
+
const docRef = await (0, import_firestore44.addDoc)(notificationsRef, notificationData);
|
|
14337
14416
|
return {
|
|
14338
14417
|
...notificationData,
|
|
14339
14418
|
id: docRef.id
|
|
@@ -14343,12 +14422,12 @@ var NotificationService = class extends BaseService {
|
|
|
14343
14422
|
* Dohvata notifikaciju po ID-u
|
|
14344
14423
|
*/
|
|
14345
14424
|
async getNotification(notificationId) {
|
|
14346
|
-
const notificationRef = (0,
|
|
14425
|
+
const notificationRef = (0, import_firestore44.doc)(
|
|
14347
14426
|
this.db,
|
|
14348
14427
|
NOTIFICATIONS_COLLECTION,
|
|
14349
14428
|
notificationId
|
|
14350
14429
|
);
|
|
14351
|
-
const notificationDoc = await (0,
|
|
14430
|
+
const notificationDoc = await (0, import_firestore44.getDoc)(notificationRef);
|
|
14352
14431
|
if (!notificationDoc.exists()) {
|
|
14353
14432
|
return null;
|
|
14354
14433
|
}
|
|
@@ -14361,45 +14440,45 @@ var NotificationService = class extends BaseService {
|
|
|
14361
14440
|
* Dohvata sve notifikacije za korisnika
|
|
14362
14441
|
*/
|
|
14363
14442
|
async getUserNotifications(userId) {
|
|
14364
|
-
const q = (0,
|
|
14365
|
-
(0,
|
|
14366
|
-
(0,
|
|
14367
|
-
(0,
|
|
14368
|
-
);
|
|
14369
|
-
const querySnapshot = await (0,
|
|
14370
|
-
return querySnapshot.docs.map((
|
|
14371
|
-
id:
|
|
14372
|
-
...
|
|
14443
|
+
const q = (0, import_firestore44.query)(
|
|
14444
|
+
(0, import_firestore44.collection)(this.db, NOTIFICATIONS_COLLECTION),
|
|
14445
|
+
(0, import_firestore44.where)("userId", "==", userId),
|
|
14446
|
+
(0, import_firestore44.orderBy)("notificationTime", "desc")
|
|
14447
|
+
);
|
|
14448
|
+
const querySnapshot = await (0, import_firestore44.getDocs)(q);
|
|
14449
|
+
return querySnapshot.docs.map((doc38) => ({
|
|
14450
|
+
id: doc38.id,
|
|
14451
|
+
...doc38.data()
|
|
14373
14452
|
}));
|
|
14374
14453
|
}
|
|
14375
14454
|
/**
|
|
14376
14455
|
* Dohvata nepročitane notifikacije za korisnika
|
|
14377
14456
|
*/
|
|
14378
14457
|
async getUnreadNotifications(userId) {
|
|
14379
|
-
const q = (0,
|
|
14380
|
-
(0,
|
|
14381
|
-
(0,
|
|
14382
|
-
(0,
|
|
14383
|
-
(0,
|
|
14384
|
-
);
|
|
14385
|
-
const querySnapshot = await (0,
|
|
14386
|
-
return querySnapshot.docs.map((
|
|
14387
|
-
id:
|
|
14388
|
-
...
|
|
14458
|
+
const q = (0, import_firestore44.query)(
|
|
14459
|
+
(0, import_firestore44.collection)(this.db, NOTIFICATIONS_COLLECTION),
|
|
14460
|
+
(0, import_firestore44.where)("userId", "==", userId),
|
|
14461
|
+
(0, import_firestore44.where)("isRead", "==", false),
|
|
14462
|
+
(0, import_firestore44.orderBy)("notificationTime", "desc")
|
|
14463
|
+
);
|
|
14464
|
+
const querySnapshot = await (0, import_firestore44.getDocs)(q);
|
|
14465
|
+
return querySnapshot.docs.map((doc38) => ({
|
|
14466
|
+
id: doc38.id,
|
|
14467
|
+
...doc38.data()
|
|
14389
14468
|
}));
|
|
14390
14469
|
}
|
|
14391
14470
|
/**
|
|
14392
14471
|
* Označava notifikaciju kao pročitanu
|
|
14393
14472
|
*/
|
|
14394
14473
|
async markAsRead(notificationId) {
|
|
14395
|
-
const notificationRef = (0,
|
|
14474
|
+
const notificationRef = (0, import_firestore44.doc)(
|
|
14396
14475
|
this.db,
|
|
14397
14476
|
NOTIFICATIONS_COLLECTION,
|
|
14398
14477
|
notificationId
|
|
14399
14478
|
);
|
|
14400
|
-
await (0,
|
|
14479
|
+
await (0, import_firestore44.updateDoc)(notificationRef, {
|
|
14401
14480
|
isRead: true,
|
|
14402
|
-
updatedAt:
|
|
14481
|
+
updatedAt: import_firestore44.Timestamp.now()
|
|
14403
14482
|
});
|
|
14404
14483
|
}
|
|
14405
14484
|
/**
|
|
@@ -14407,16 +14486,16 @@ var NotificationService = class extends BaseService {
|
|
|
14407
14486
|
*/
|
|
14408
14487
|
async markAllAsRead(userId) {
|
|
14409
14488
|
const notifications = await this.getUnreadNotifications(userId);
|
|
14410
|
-
const batch = (0,
|
|
14489
|
+
const batch = (0, import_firestore44.writeBatch)(this.db);
|
|
14411
14490
|
notifications.forEach((notification) => {
|
|
14412
|
-
const notificationRef = (0,
|
|
14491
|
+
const notificationRef = (0, import_firestore44.doc)(
|
|
14413
14492
|
this.db,
|
|
14414
14493
|
NOTIFICATIONS_COLLECTION,
|
|
14415
14494
|
notification.id
|
|
14416
14495
|
);
|
|
14417
14496
|
batch.update(notificationRef, {
|
|
14418
14497
|
isRead: true,
|
|
14419
|
-
updatedAt:
|
|
14498
|
+
updatedAt: import_firestore44.Timestamp.now()
|
|
14420
14499
|
});
|
|
14421
14500
|
});
|
|
14422
14501
|
await batch.commit();
|
|
@@ -14425,74 +14504,74 @@ var NotificationService = class extends BaseService {
|
|
|
14425
14504
|
* Ažurira status notifikacije
|
|
14426
14505
|
*/
|
|
14427
14506
|
async updateNotificationStatus(notificationId, status) {
|
|
14428
|
-
const notificationRef = (0,
|
|
14507
|
+
const notificationRef = (0, import_firestore44.doc)(
|
|
14429
14508
|
this.db,
|
|
14430
14509
|
NOTIFICATIONS_COLLECTION,
|
|
14431
14510
|
notificationId
|
|
14432
14511
|
);
|
|
14433
|
-
await (0,
|
|
14512
|
+
await (0, import_firestore44.updateDoc)(notificationRef, {
|
|
14434
14513
|
status,
|
|
14435
|
-
updatedAt:
|
|
14514
|
+
updatedAt: import_firestore44.Timestamp.now()
|
|
14436
14515
|
});
|
|
14437
14516
|
}
|
|
14438
14517
|
/**
|
|
14439
14518
|
* Briše notifikaciju
|
|
14440
14519
|
*/
|
|
14441
14520
|
async deleteNotification(notificationId) {
|
|
14442
|
-
const notificationRef = (0,
|
|
14521
|
+
const notificationRef = (0, import_firestore44.doc)(
|
|
14443
14522
|
this.db,
|
|
14444
14523
|
NOTIFICATIONS_COLLECTION,
|
|
14445
14524
|
notificationId
|
|
14446
14525
|
);
|
|
14447
|
-
await (0,
|
|
14526
|
+
await (0, import_firestore44.deleteDoc)(notificationRef);
|
|
14448
14527
|
}
|
|
14449
14528
|
/**
|
|
14450
14529
|
* Dohvata notifikacije po tipu
|
|
14451
14530
|
*/
|
|
14452
14531
|
async getNotificationsByType(userId, type) {
|
|
14453
|
-
const q = (0,
|
|
14454
|
-
(0,
|
|
14455
|
-
(0,
|
|
14456
|
-
(0,
|
|
14457
|
-
(0,
|
|
14458
|
-
);
|
|
14459
|
-
const querySnapshot = await (0,
|
|
14460
|
-
return querySnapshot.docs.map((
|
|
14461
|
-
id:
|
|
14462
|
-
...
|
|
14532
|
+
const q = (0, import_firestore44.query)(
|
|
14533
|
+
(0, import_firestore44.collection)(this.db, NOTIFICATIONS_COLLECTION),
|
|
14534
|
+
(0, import_firestore44.where)("userId", "==", userId),
|
|
14535
|
+
(0, import_firestore44.where)("notificationType", "==", type),
|
|
14536
|
+
(0, import_firestore44.orderBy)("notificationTime", "desc")
|
|
14537
|
+
);
|
|
14538
|
+
const querySnapshot = await (0, import_firestore44.getDocs)(q);
|
|
14539
|
+
return querySnapshot.docs.map((doc38) => ({
|
|
14540
|
+
id: doc38.id,
|
|
14541
|
+
...doc38.data()
|
|
14463
14542
|
}));
|
|
14464
14543
|
}
|
|
14465
14544
|
/**
|
|
14466
14545
|
* Dohvata notifikacije za određeni termin
|
|
14467
14546
|
*/
|
|
14468
14547
|
async getAppointmentNotifications(appointmentId) {
|
|
14469
|
-
const q = (0,
|
|
14470
|
-
(0,
|
|
14471
|
-
(0,
|
|
14472
|
-
(0,
|
|
14473
|
-
);
|
|
14474
|
-
const querySnapshot = await (0,
|
|
14475
|
-
return querySnapshot.docs.map((
|
|
14476
|
-
id:
|
|
14477
|
-
...
|
|
14548
|
+
const q = (0, import_firestore44.query)(
|
|
14549
|
+
(0, import_firestore44.collection)(this.db, NOTIFICATIONS_COLLECTION),
|
|
14550
|
+
(0, import_firestore44.where)("appointmentId", "==", appointmentId),
|
|
14551
|
+
(0, import_firestore44.orderBy)("notificationTime", "desc")
|
|
14552
|
+
);
|
|
14553
|
+
const querySnapshot = await (0, import_firestore44.getDocs)(q);
|
|
14554
|
+
return querySnapshot.docs.map((doc38) => ({
|
|
14555
|
+
id: doc38.id,
|
|
14556
|
+
...doc38.data()
|
|
14478
14557
|
}));
|
|
14479
14558
|
}
|
|
14480
14559
|
};
|
|
14481
14560
|
|
|
14482
14561
|
// src/services/patient/patientRequirements.service.ts
|
|
14483
|
-
var
|
|
14562
|
+
var import_firestore45 = require("firebase/firestore");
|
|
14484
14563
|
var PatientRequirementsService = class extends BaseService {
|
|
14485
14564
|
constructor(db, auth, app) {
|
|
14486
14565
|
super(db, auth, app);
|
|
14487
14566
|
}
|
|
14488
14567
|
getPatientRequirementsCollectionRef(patientId) {
|
|
14489
|
-
return (0,
|
|
14568
|
+
return (0, import_firestore45.collection)(
|
|
14490
14569
|
this.db,
|
|
14491
14570
|
`patients/${patientId}/${PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME}`
|
|
14492
14571
|
);
|
|
14493
14572
|
}
|
|
14494
14573
|
getPatientRequirementDocRef(patientId, instanceId) {
|
|
14495
|
-
return (0,
|
|
14574
|
+
return (0, import_firestore45.doc)(
|
|
14496
14575
|
this.getPatientRequirementsCollectionRef(patientId),
|
|
14497
14576
|
instanceId
|
|
14498
14577
|
);
|
|
@@ -14505,7 +14584,7 @@ var PatientRequirementsService = class extends BaseService {
|
|
|
14505
14584
|
*/
|
|
14506
14585
|
async getPatientRequirementInstance(patientId, instanceId) {
|
|
14507
14586
|
const docRef = this.getPatientRequirementDocRef(patientId, instanceId);
|
|
14508
|
-
const docSnap = await (0,
|
|
14587
|
+
const docSnap = await (0, import_firestore45.getDoc)(docRef);
|
|
14509
14588
|
if (!docSnap.exists()) {
|
|
14510
14589
|
return null;
|
|
14511
14590
|
}
|
|
@@ -14524,22 +14603,22 @@ var PatientRequirementsService = class extends BaseService {
|
|
|
14524
14603
|
*/
|
|
14525
14604
|
async getAllPatientRequirementInstances(patientId, filters, pageLimit = 20, lastVisible) {
|
|
14526
14605
|
const collRef = this.getPatientRequirementsCollectionRef(patientId);
|
|
14527
|
-
let q = (0,
|
|
14606
|
+
let q = (0, import_firestore45.query)(collRef, (0, import_firestore45.orderBy)("createdAt", "desc"));
|
|
14528
14607
|
const queryConstraints = [];
|
|
14529
14608
|
if ((filters == null ? void 0 : filters.appointmentId) && filters.appointmentId !== "all") {
|
|
14530
14609
|
queryConstraints.push(
|
|
14531
|
-
(0,
|
|
14610
|
+
(0, import_firestore45.where)("appointmentId", "==", filters.appointmentId)
|
|
14532
14611
|
);
|
|
14533
14612
|
}
|
|
14534
14613
|
if ((filters == null ? void 0 : filters.statuses) && filters.statuses.length > 0) {
|
|
14535
|
-
queryConstraints.push((0,
|
|
14614
|
+
queryConstraints.push((0, import_firestore45.where)("overallStatus", "in", filters.statuses));
|
|
14536
14615
|
}
|
|
14537
14616
|
if (lastVisible) {
|
|
14538
|
-
queryConstraints.push((0,
|
|
14617
|
+
queryConstraints.push((0, import_firestore45.startAfter)(lastVisible));
|
|
14539
14618
|
}
|
|
14540
|
-
queryConstraints.push((0,
|
|
14541
|
-
q = (0,
|
|
14542
|
-
const snapshot = await (0,
|
|
14619
|
+
queryConstraints.push((0, import_firestore45.limit)(pageLimit));
|
|
14620
|
+
q = (0, import_firestore45.query)(collRef, ...queryConstraints);
|
|
14621
|
+
const snapshot = await (0, import_firestore45.getDocs)(q);
|
|
14543
14622
|
let requirements = snapshot.docs.map((docSnap) => {
|
|
14544
14623
|
const data = docSnap.data();
|
|
14545
14624
|
return { id: docSnap.id, ...data };
|
|
@@ -14582,7 +14661,7 @@ var PatientRequirementsService = class extends BaseService {
|
|
|
14582
14661
|
*/
|
|
14583
14662
|
async completeInstruction(patientId, instanceId, instructionId) {
|
|
14584
14663
|
const instanceRef = this.getPatientRequirementDocRef(patientId, instanceId);
|
|
14585
|
-
const instanceSnap = await (0,
|
|
14664
|
+
const instanceSnap = await (0, import_firestore45.getDoc)(instanceRef);
|
|
14586
14665
|
if (!instanceSnap.exists()) {
|
|
14587
14666
|
throw new Error(
|
|
14588
14667
|
`PatientRequirementInstance ${instanceId} not found for patient ${patientId}.`
|
|
@@ -14610,7 +14689,7 @@ var PatientRequirementsService = class extends BaseService {
|
|
|
14610
14689
|
`Instruction ${instructionId} is in status ${instructionToUpdate.status} and cannot be marked as completed.`
|
|
14611
14690
|
);
|
|
14612
14691
|
}
|
|
14613
|
-
const now =
|
|
14692
|
+
const now = import_firestore45.Timestamp.now();
|
|
14614
14693
|
const updatedInstructions = [...instance.instructions];
|
|
14615
14694
|
updatedInstructions[instructionIndex] = {
|
|
14616
14695
|
...instructionToUpdate,
|
|
@@ -14637,7 +14716,7 @@ var PatientRequirementsService = class extends BaseService {
|
|
|
14637
14716
|
if (newOverallStatus !== instance.overallStatus) {
|
|
14638
14717
|
updatePayload.overallStatus = newOverallStatus;
|
|
14639
14718
|
}
|
|
14640
|
-
await (0,
|
|
14719
|
+
await (0, import_firestore45.updateDoc)(instanceRef, updatePayload);
|
|
14641
14720
|
return {
|
|
14642
14721
|
...instance,
|
|
14643
14722
|
instructions: updatedInstructions,
|
|
@@ -14650,7 +14729,7 @@ var PatientRequirementsService = class extends BaseService {
|
|
|
14650
14729
|
};
|
|
14651
14730
|
|
|
14652
14731
|
// src/services/procedure/procedure.service.ts
|
|
14653
|
-
var
|
|
14732
|
+
var import_firestore46 = require("firebase/firestore");
|
|
14654
14733
|
|
|
14655
14734
|
// src/validations/procedure.schema.ts
|
|
14656
14735
|
var import_zod24 = require("zod");
|
|
@@ -14750,7 +14829,9 @@ var ProcedureService = class extends BaseService {
|
|
|
14750
14829
|
return media;
|
|
14751
14830
|
}
|
|
14752
14831
|
if (media instanceof File || media instanceof Blob) {
|
|
14753
|
-
console.log(
|
|
14832
|
+
console.log(
|
|
14833
|
+
`[ProcedureService] Uploading ${collectionName} media for ${ownerId}`
|
|
14834
|
+
);
|
|
14754
14835
|
const metadata = await this.mediaService.uploadMedia(
|
|
14755
14836
|
media,
|
|
14756
14837
|
ownerId,
|
|
@@ -14772,7 +14853,11 @@ var ProcedureService = class extends BaseService {
|
|
|
14772
14853
|
if (!mediaArray || mediaArray.length === 0) return [];
|
|
14773
14854
|
const result = [];
|
|
14774
14855
|
for (const media of mediaArray) {
|
|
14775
|
-
const processedUrl = await this.processMedia(
|
|
14856
|
+
const processedUrl = await this.processMedia(
|
|
14857
|
+
media,
|
|
14858
|
+
ownerId,
|
|
14859
|
+
collectionName
|
|
14860
|
+
);
|
|
14776
14861
|
if (processedUrl) {
|
|
14777
14862
|
result.push(processedUrl);
|
|
14778
14863
|
}
|
|
@@ -14785,28 +14870,46 @@ var ProcedureService = class extends BaseService {
|
|
|
14785
14870
|
* @returns The created procedure
|
|
14786
14871
|
*/
|
|
14787
14872
|
async createProcedure(data) {
|
|
14788
|
-
var _a;
|
|
14873
|
+
var _a, _b, _c;
|
|
14789
14874
|
const validatedData = createProcedureSchema.parse(data);
|
|
14790
14875
|
const procedureId = this.generateId();
|
|
14791
14876
|
const [category, subcategory, technology, product] = await Promise.all([
|
|
14792
14877
|
this.categoryService.getById(validatedData.categoryId),
|
|
14793
|
-
this.subcategoryService.getById(
|
|
14878
|
+
this.subcategoryService.getById(
|
|
14879
|
+
validatedData.categoryId,
|
|
14880
|
+
validatedData.subcategoryId
|
|
14881
|
+
),
|
|
14794
14882
|
this.technologyService.getById(validatedData.technologyId),
|
|
14795
|
-
this.productService.getById(
|
|
14883
|
+
this.productService.getById(
|
|
14884
|
+
validatedData.technologyId,
|
|
14885
|
+
validatedData.productId
|
|
14886
|
+
)
|
|
14796
14887
|
]);
|
|
14797
14888
|
if (!category || !subcategory || !technology || !product) {
|
|
14798
14889
|
throw new Error("One or more required base entities not found");
|
|
14799
14890
|
}
|
|
14800
|
-
const clinicRef = (0,
|
|
14801
|
-
|
|
14891
|
+
const clinicRef = (0, import_firestore46.doc)(
|
|
14892
|
+
this.db,
|
|
14893
|
+
CLINICS_COLLECTION,
|
|
14894
|
+
validatedData.clinicBranchId
|
|
14895
|
+
);
|
|
14896
|
+
const clinicSnapshot = await (0, import_firestore46.getDoc)(clinicRef);
|
|
14802
14897
|
if (!clinicSnapshot.exists()) {
|
|
14803
|
-
throw new Error(
|
|
14898
|
+
throw new Error(
|
|
14899
|
+
`Clinic with ID ${validatedData.clinicBranchId} not found`
|
|
14900
|
+
);
|
|
14804
14901
|
}
|
|
14805
14902
|
const clinic = clinicSnapshot.data();
|
|
14806
|
-
const practitionerRef = (0,
|
|
14807
|
-
|
|
14903
|
+
const practitionerRef = (0, import_firestore46.doc)(
|
|
14904
|
+
this.db,
|
|
14905
|
+
PRACTITIONERS_COLLECTION,
|
|
14906
|
+
validatedData.practitionerId
|
|
14907
|
+
);
|
|
14908
|
+
const practitionerSnapshot = await (0, import_firestore46.getDoc)(practitionerRef);
|
|
14808
14909
|
if (!practitionerSnapshot.exists()) {
|
|
14809
|
-
throw new Error(
|
|
14910
|
+
throw new Error(
|
|
14911
|
+
`Practitioner with ID ${validatedData.practitionerId} not found`
|
|
14912
|
+
);
|
|
14810
14913
|
}
|
|
14811
14914
|
const practitioner = practitionerSnapshot.data();
|
|
14812
14915
|
let processedPhotos = [];
|
|
@@ -14847,7 +14950,9 @@ var ProcedureService = class extends BaseService {
|
|
|
14847
14950
|
product,
|
|
14848
14951
|
blockingConditions: technology.blockingConditions,
|
|
14849
14952
|
contraindications: technology.contraindications || [],
|
|
14953
|
+
contraindicationIds: ((_b = technology.contraindications) == null ? void 0 : _b.map((c) => c.id)) || [],
|
|
14850
14954
|
treatmentBenefits: technology.benefits,
|
|
14955
|
+
treatmentBenefitIds: ((_c = technology.benefits) == null ? void 0 : _c.map((b) => b.id)) || [],
|
|
14851
14956
|
preRequirements: technology.requirements.pre,
|
|
14852
14957
|
postRequirements: technology.requirements.post,
|
|
14853
14958
|
certificationRequirement: technology.certificationRequirement,
|
|
@@ -14870,13 +14975,13 @@ var ProcedureService = class extends BaseService {
|
|
|
14870
14975
|
isActive: true
|
|
14871
14976
|
// Default to active
|
|
14872
14977
|
};
|
|
14873
|
-
const procedureRef = (0,
|
|
14874
|
-
await (0,
|
|
14978
|
+
const procedureRef = (0, import_firestore46.doc)(this.db, PROCEDURES_COLLECTION, procedureId);
|
|
14979
|
+
await (0, import_firestore46.setDoc)(procedureRef, {
|
|
14875
14980
|
...newProcedure,
|
|
14876
|
-
createdAt: (0,
|
|
14877
|
-
updatedAt: (0,
|
|
14981
|
+
createdAt: (0, import_firestore46.serverTimestamp)(),
|
|
14982
|
+
updatedAt: (0, import_firestore46.serverTimestamp)()
|
|
14878
14983
|
});
|
|
14879
|
-
const savedDoc = await (0,
|
|
14984
|
+
const savedDoc = await (0, import_firestore46.getDoc)(procedureRef);
|
|
14880
14985
|
return savedDoc.data();
|
|
14881
14986
|
}
|
|
14882
14987
|
/**
|
|
@@ -14888,7 +14993,7 @@ var ProcedureService = class extends BaseService {
|
|
|
14888
14993
|
* @returns A promise that resolves to an array of the newly created procedures.
|
|
14889
14994
|
*/
|
|
14890
14995
|
async bulkCreateProcedures(baseData, practitionerIds) {
|
|
14891
|
-
var _a;
|
|
14996
|
+
var _a, _b, _c;
|
|
14892
14997
|
if (!practitionerIds || practitionerIds.length === 0) {
|
|
14893
14998
|
throw new Error("Practitioner IDs array cannot be empty.");
|
|
14894
14999
|
}
|
|
@@ -14896,16 +15001,24 @@ var ProcedureService = class extends BaseService {
|
|
|
14896
15001
|
const validatedData = createProcedureSchema.parse(validationData);
|
|
14897
15002
|
const [category, subcategory, technology, product, clinicSnapshot] = await Promise.all([
|
|
14898
15003
|
this.categoryService.getById(validatedData.categoryId),
|
|
14899
|
-
this.subcategoryService.getById(
|
|
15004
|
+
this.subcategoryService.getById(
|
|
15005
|
+
validatedData.categoryId,
|
|
15006
|
+
validatedData.subcategoryId
|
|
15007
|
+
),
|
|
14900
15008
|
this.technologyService.getById(validatedData.technologyId),
|
|
14901
|
-
this.productService.getById(
|
|
14902
|
-
|
|
15009
|
+
this.productService.getById(
|
|
15010
|
+
validatedData.technologyId,
|
|
15011
|
+
validatedData.productId
|
|
15012
|
+
),
|
|
15013
|
+
(0, import_firestore46.getDoc)((0, import_firestore46.doc)(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId))
|
|
14903
15014
|
]);
|
|
14904
15015
|
if (!category || !subcategory || !technology || !product) {
|
|
14905
15016
|
throw new Error("One or more required base entities not found");
|
|
14906
15017
|
}
|
|
14907
15018
|
if (!clinicSnapshot.exists()) {
|
|
14908
|
-
throw new Error(
|
|
15019
|
+
throw new Error(
|
|
15020
|
+
`Clinic with ID ${validatedData.clinicBranchId} not found`
|
|
15021
|
+
);
|
|
14909
15022
|
}
|
|
14910
15023
|
const clinic = clinicSnapshot.data();
|
|
14911
15024
|
let processedPhotos = [];
|
|
@@ -14920,21 +15033,25 @@ var ProcedureService = class extends BaseService {
|
|
|
14920
15033
|
const practitionersMap = /* @__PURE__ */ new Map();
|
|
14921
15034
|
for (let i = 0; i < practitionerIds.length; i += 30) {
|
|
14922
15035
|
const chunk = practitionerIds.slice(i, i + 30);
|
|
14923
|
-
const practitionersQuery = (0,
|
|
14924
|
-
(0,
|
|
14925
|
-
(0,
|
|
15036
|
+
const practitionersQuery = (0, import_firestore46.query)(
|
|
15037
|
+
(0, import_firestore46.collection)(this.db, PRACTITIONERS_COLLECTION),
|
|
15038
|
+
(0, import_firestore46.where)((0, import_firestore46.documentId)(), "in", chunk)
|
|
14926
15039
|
);
|
|
14927
|
-
const practitionersSnapshot = await (0,
|
|
14928
|
-
practitionersSnapshot.docs.forEach((
|
|
14929
|
-
practitionersMap.set(
|
|
15040
|
+
const practitionersSnapshot = await (0, import_firestore46.getDocs)(practitionersQuery);
|
|
15041
|
+
practitionersSnapshot.docs.forEach((doc38) => {
|
|
15042
|
+
practitionersMap.set(doc38.id, doc38.data());
|
|
14930
15043
|
});
|
|
14931
15044
|
}
|
|
14932
15045
|
if (practitionersMap.size !== practitionerIds.length) {
|
|
14933
15046
|
const foundIds = Array.from(practitionersMap.keys());
|
|
14934
|
-
const notFoundIds = practitionerIds.filter(
|
|
14935
|
-
|
|
15047
|
+
const notFoundIds = practitionerIds.filter(
|
|
15048
|
+
(id) => !foundIds.includes(id)
|
|
15049
|
+
);
|
|
15050
|
+
throw new Error(
|
|
15051
|
+
`The following practitioners were not found: ${notFoundIds.join(", ")}`
|
|
15052
|
+
);
|
|
14936
15053
|
}
|
|
14937
|
-
const batch = (0,
|
|
15054
|
+
const batch = (0, import_firestore46.writeBatch)(this.db);
|
|
14938
15055
|
const createdProcedureIds = [];
|
|
14939
15056
|
const clinicInfo = {
|
|
14940
15057
|
id: clinicSnapshot.id,
|
|
@@ -14956,7 +15073,7 @@ var ProcedureService = class extends BaseService {
|
|
|
14956
15073
|
};
|
|
14957
15074
|
const procedureId = this.generateId();
|
|
14958
15075
|
createdProcedureIds.push(procedureId);
|
|
14959
|
-
const procedureRef = (0,
|
|
15076
|
+
const procedureRef = (0, import_firestore46.doc)(this.db, PROCEDURES_COLLECTION, procedureId);
|
|
14960
15077
|
const newProcedure = {
|
|
14961
15078
|
id: procedureId,
|
|
14962
15079
|
...validatedData,
|
|
@@ -14970,7 +15087,9 @@ var ProcedureService = class extends BaseService {
|
|
|
14970
15087
|
product,
|
|
14971
15088
|
blockingConditions: technology.blockingConditions,
|
|
14972
15089
|
contraindications: technology.contraindications || [],
|
|
15090
|
+
contraindicationIds: ((_b = technology.contraindications) == null ? void 0 : _b.map((c) => c.id)) || [],
|
|
14973
15091
|
treatmentBenefits: technology.benefits,
|
|
15092
|
+
treatmentBenefitIds: ((_c = technology.benefits) == null ? void 0 : _c.map((b) => b.id)) || [],
|
|
14974
15093
|
preRequirements: technology.requirements.pre,
|
|
14975
15094
|
postRequirements: technology.requirements.post,
|
|
14976
15095
|
certificationRequirement: technology.certificationRequirement,
|
|
@@ -14992,18 +15111,21 @@ var ProcedureService = class extends BaseService {
|
|
|
14992
15111
|
};
|
|
14993
15112
|
batch.set(procedureRef, {
|
|
14994
15113
|
...newProcedure,
|
|
14995
|
-
createdAt: (0,
|
|
14996
|
-
updatedAt: (0,
|
|
15114
|
+
createdAt: (0, import_firestore46.serverTimestamp)(),
|
|
15115
|
+
updatedAt: (0, import_firestore46.serverTimestamp)()
|
|
14997
15116
|
});
|
|
14998
15117
|
}
|
|
14999
15118
|
await batch.commit();
|
|
15000
15119
|
const fetchedProcedures = [];
|
|
15001
15120
|
for (let i = 0; i < createdProcedureIds.length; i += 30) {
|
|
15002
15121
|
const chunk = createdProcedureIds.slice(i, i + 30);
|
|
15003
|
-
const q = (0,
|
|
15004
|
-
|
|
15005
|
-
|
|
15006
|
-
|
|
15122
|
+
const q = (0, import_firestore46.query)(
|
|
15123
|
+
(0, import_firestore46.collection)(this.db, PROCEDURES_COLLECTION),
|
|
15124
|
+
(0, import_firestore46.where)((0, import_firestore46.documentId)(), "in", chunk)
|
|
15125
|
+
);
|
|
15126
|
+
const snapshot = await (0, import_firestore46.getDocs)(q);
|
|
15127
|
+
snapshot.forEach((doc38) => {
|
|
15128
|
+
fetchedProcedures.push(doc38.data());
|
|
15007
15129
|
});
|
|
15008
15130
|
}
|
|
15009
15131
|
return fetchedProcedures;
|
|
@@ -15014,8 +15136,8 @@ var ProcedureService = class extends BaseService {
|
|
|
15014
15136
|
* @returns The procedure if found, null otherwise
|
|
15015
15137
|
*/
|
|
15016
15138
|
async getProcedure(id) {
|
|
15017
|
-
const docRef = (0,
|
|
15018
|
-
const docSnap = await (0,
|
|
15139
|
+
const docRef = (0, import_firestore46.doc)(this.db, PROCEDURES_COLLECTION, id);
|
|
15140
|
+
const docSnap = await (0, import_firestore46.getDoc)(docRef);
|
|
15019
15141
|
if (!docSnap.exists()) {
|
|
15020
15142
|
return null;
|
|
15021
15143
|
}
|
|
@@ -15027,13 +15149,13 @@ var ProcedureService = class extends BaseService {
|
|
|
15027
15149
|
* @returns List of procedures
|
|
15028
15150
|
*/
|
|
15029
15151
|
async getProceduresByClinicBranch(clinicBranchId) {
|
|
15030
|
-
const q = (0,
|
|
15031
|
-
(0,
|
|
15032
|
-
(0,
|
|
15033
|
-
(0,
|
|
15152
|
+
const q = (0, import_firestore46.query)(
|
|
15153
|
+
(0, import_firestore46.collection)(this.db, PROCEDURES_COLLECTION),
|
|
15154
|
+
(0, import_firestore46.where)("clinicBranchId", "==", clinicBranchId),
|
|
15155
|
+
(0, import_firestore46.where)("isActive", "==", true)
|
|
15034
15156
|
);
|
|
15035
|
-
const snapshot = await (0,
|
|
15036
|
-
return snapshot.docs.map((
|
|
15157
|
+
const snapshot = await (0, import_firestore46.getDocs)(q);
|
|
15158
|
+
return snapshot.docs.map((doc38) => doc38.data());
|
|
15037
15159
|
}
|
|
15038
15160
|
/**
|
|
15039
15161
|
* Gets all procedures for a practitioner
|
|
@@ -15041,13 +15163,13 @@ var ProcedureService = class extends BaseService {
|
|
|
15041
15163
|
* @returns List of procedures
|
|
15042
15164
|
*/
|
|
15043
15165
|
async getProceduresByPractitioner(practitionerId) {
|
|
15044
|
-
const q = (0,
|
|
15045
|
-
(0,
|
|
15046
|
-
(0,
|
|
15047
|
-
(0,
|
|
15166
|
+
const q = (0, import_firestore46.query)(
|
|
15167
|
+
(0, import_firestore46.collection)(this.db, PROCEDURES_COLLECTION),
|
|
15168
|
+
(0, import_firestore46.where)("practitionerId", "==", practitionerId),
|
|
15169
|
+
(0, import_firestore46.where)("isActive", "==", true)
|
|
15048
15170
|
);
|
|
15049
|
-
const snapshot = await (0,
|
|
15050
|
-
return snapshot.docs.map((
|
|
15171
|
+
const snapshot = await (0, import_firestore46.getDocs)(q);
|
|
15172
|
+
return snapshot.docs.map((doc38) => doc38.data());
|
|
15051
15173
|
}
|
|
15052
15174
|
/**
|
|
15053
15175
|
* Gets all inactive procedures for a practitioner
|
|
@@ -15055,13 +15177,13 @@ var ProcedureService = class extends BaseService {
|
|
|
15055
15177
|
* @returns List of inactive procedures
|
|
15056
15178
|
*/
|
|
15057
15179
|
async getInactiveProceduresByPractitioner(practitionerId) {
|
|
15058
|
-
const q = (0,
|
|
15059
|
-
(0,
|
|
15060
|
-
(0,
|
|
15061
|
-
(0,
|
|
15180
|
+
const q = (0, import_firestore46.query)(
|
|
15181
|
+
(0, import_firestore46.collection)(this.db, PROCEDURES_COLLECTION),
|
|
15182
|
+
(0, import_firestore46.where)("practitionerId", "==", practitionerId),
|
|
15183
|
+
(0, import_firestore46.where)("isActive", "==", false)
|
|
15062
15184
|
);
|
|
15063
|
-
const snapshot = await (0,
|
|
15064
|
-
return snapshot.docs.map((
|
|
15185
|
+
const snapshot = await (0, import_firestore46.getDocs)(q);
|
|
15186
|
+
return snapshot.docs.map((doc38) => doc38.data());
|
|
15065
15187
|
}
|
|
15066
15188
|
/**
|
|
15067
15189
|
* Updates a procedure
|
|
@@ -15070,10 +15192,10 @@ var ProcedureService = class extends BaseService {
|
|
|
15070
15192
|
* @returns The updated procedure
|
|
15071
15193
|
*/
|
|
15072
15194
|
async updateProcedure(id, data) {
|
|
15073
|
-
var _a;
|
|
15195
|
+
var _a, _b, _c;
|
|
15074
15196
|
const validatedData = updateProcedureSchema.parse(data);
|
|
15075
|
-
const procedureRef = (0,
|
|
15076
|
-
const procedureSnapshot = await (0,
|
|
15197
|
+
const procedureRef = (0, import_firestore46.doc)(this.db, PROCEDURES_COLLECTION, id);
|
|
15198
|
+
const procedureSnapshot = await (0, import_firestore46.getDoc)(procedureRef);
|
|
15077
15199
|
if (!procedureSnapshot.exists()) {
|
|
15078
15200
|
throw new Error(`Procedure with ID ${id} not found`);
|
|
15079
15201
|
}
|
|
@@ -15094,14 +15216,16 @@ var ProcedureService = class extends BaseService {
|
|
|
15094
15216
|
}
|
|
15095
15217
|
if (validatedData.practitionerId && validatedData.practitionerId !== oldPractitionerId) {
|
|
15096
15218
|
practitionerChanged = true;
|
|
15097
|
-
const newPractitionerRef = (0,
|
|
15219
|
+
const newPractitionerRef = (0, import_firestore46.doc)(
|
|
15098
15220
|
this.db,
|
|
15099
15221
|
PRACTITIONERS_COLLECTION,
|
|
15100
15222
|
validatedData.practitionerId
|
|
15101
15223
|
);
|
|
15102
|
-
const newPractitionerSnap = await (0,
|
|
15224
|
+
const newPractitionerSnap = await (0, import_firestore46.getDoc)(newPractitionerRef);
|
|
15103
15225
|
if (!newPractitionerSnap.exists())
|
|
15104
|
-
throw new Error(
|
|
15226
|
+
throw new Error(
|
|
15227
|
+
`New Practitioner ${validatedData.practitionerId} not found`
|
|
15228
|
+
);
|
|
15105
15229
|
newPractitioner = newPractitionerSnap.data();
|
|
15106
15230
|
updatedProcedureData.doctorInfo = {
|
|
15107
15231
|
id: newPractitioner.id,
|
|
@@ -15115,8 +15239,12 @@ var ProcedureService = class extends BaseService {
|
|
|
15115
15239
|
}
|
|
15116
15240
|
if (validatedData.clinicBranchId && validatedData.clinicBranchId !== oldClinicId) {
|
|
15117
15241
|
clinicChanged = true;
|
|
15118
|
-
const newClinicRef = (0,
|
|
15119
|
-
|
|
15242
|
+
const newClinicRef = (0, import_firestore46.doc)(
|
|
15243
|
+
this.db,
|
|
15244
|
+
CLINICS_COLLECTION,
|
|
15245
|
+
validatedData.clinicBranchId
|
|
15246
|
+
);
|
|
15247
|
+
const newClinicSnap = await (0, import_firestore46.getDoc)(newClinicRef);
|
|
15120
15248
|
if (!newClinicSnap.exists())
|
|
15121
15249
|
throw new Error(`New Clinic ${validatedData.clinicBranchId} not found`);
|
|
15122
15250
|
newClinic = newClinicSnap.data();
|
|
@@ -15134,8 +15262,11 @@ var ProcedureService = class extends BaseService {
|
|
|
15134
15262
|
updatedProcedureData.nameLower = validatedData.name.toLowerCase();
|
|
15135
15263
|
}
|
|
15136
15264
|
if (validatedData.categoryId) {
|
|
15137
|
-
const category = await this.categoryService.getById(
|
|
15138
|
-
|
|
15265
|
+
const category = await this.categoryService.getById(
|
|
15266
|
+
validatedData.categoryId
|
|
15267
|
+
);
|
|
15268
|
+
if (!category)
|
|
15269
|
+
throw new Error(`Category ${validatedData.categoryId} not found`);
|
|
15139
15270
|
updatedProcedureData.category = category;
|
|
15140
15271
|
finalCategoryId = category.id;
|
|
15141
15272
|
}
|
|
@@ -15150,23 +15281,34 @@ var ProcedureService = class extends BaseService {
|
|
|
15150
15281
|
);
|
|
15151
15282
|
updatedProcedureData.subcategory = subcategory;
|
|
15152
15283
|
} else if (validatedData.subcategoryId) {
|
|
15153
|
-
console.warn(
|
|
15284
|
+
console.warn(
|
|
15285
|
+
"Attempted to update subcategory without a valid categoryId"
|
|
15286
|
+
);
|
|
15154
15287
|
}
|
|
15155
15288
|
let finalTechnologyId = existingProcedure.technology.id;
|
|
15156
15289
|
if (validatedData.technologyId) {
|
|
15157
|
-
const technology = await this.technologyService.getById(
|
|
15158
|
-
|
|
15290
|
+
const technology = await this.technologyService.getById(
|
|
15291
|
+
validatedData.technologyId
|
|
15292
|
+
);
|
|
15293
|
+
if (!technology)
|
|
15294
|
+
throw new Error(`Technology ${validatedData.technologyId} not found`);
|
|
15159
15295
|
updatedProcedureData.technology = technology;
|
|
15160
15296
|
finalTechnologyId = technology.id;
|
|
15161
15297
|
updatedProcedureData.blockingConditions = technology.blockingConditions;
|
|
15298
|
+
updatedProcedureData.contraindications = technology.contraindications || [];
|
|
15299
|
+
updatedProcedureData.contraindicationIds = ((_b = technology.contraindications) == null ? void 0 : _b.map((c) => c.id)) || [];
|
|
15162
15300
|
updatedProcedureData.treatmentBenefits = technology.benefits;
|
|
15301
|
+
updatedProcedureData.treatmentBenefitIds = ((_c = technology.benefits) == null ? void 0 : _c.map((b) => b.id)) || [];
|
|
15163
15302
|
updatedProcedureData.preRequirements = technology.requirements.pre;
|
|
15164
15303
|
updatedProcedureData.postRequirements = technology.requirements.post;
|
|
15165
15304
|
updatedProcedureData.certificationRequirement = technology.certificationRequirement;
|
|
15166
15305
|
updatedProcedureData.documentationTemplates = technology.documentationTemplates || [];
|
|
15167
15306
|
}
|
|
15168
15307
|
if (validatedData.productId && finalTechnologyId) {
|
|
15169
|
-
const product = await this.productService.getById(
|
|
15308
|
+
const product = await this.productService.getById(
|
|
15309
|
+
finalTechnologyId,
|
|
15310
|
+
validatedData.productId
|
|
15311
|
+
);
|
|
15170
15312
|
if (!product)
|
|
15171
15313
|
throw new Error(
|
|
15172
15314
|
`Product ${validatedData.productId} not found for technology ${finalTechnologyId}`
|
|
@@ -15175,11 +15317,11 @@ var ProcedureService = class extends BaseService {
|
|
|
15175
15317
|
} else if (validatedData.productId) {
|
|
15176
15318
|
console.warn("Attempted to update product without a valid technologyId");
|
|
15177
15319
|
}
|
|
15178
|
-
await (0,
|
|
15320
|
+
await (0, import_firestore46.updateDoc)(procedureRef, {
|
|
15179
15321
|
...updatedProcedureData,
|
|
15180
|
-
updatedAt: (0,
|
|
15322
|
+
updatedAt: (0, import_firestore46.serverTimestamp)()
|
|
15181
15323
|
});
|
|
15182
|
-
const updatedSnapshot = await (0,
|
|
15324
|
+
const updatedSnapshot = await (0, import_firestore46.getDoc)(procedureRef);
|
|
15183
15325
|
return updatedSnapshot.data();
|
|
15184
15326
|
}
|
|
15185
15327
|
/**
|
|
@@ -15187,15 +15329,15 @@ var ProcedureService = class extends BaseService {
|
|
|
15187
15329
|
* @param id - The ID of the procedure to deactivate
|
|
15188
15330
|
*/
|
|
15189
15331
|
async deactivateProcedure(id) {
|
|
15190
|
-
const procedureRef = (0,
|
|
15191
|
-
const procedureSnap = await (0,
|
|
15332
|
+
const procedureRef = (0, import_firestore46.doc)(this.db, PROCEDURES_COLLECTION, id);
|
|
15333
|
+
const procedureSnap = await (0, import_firestore46.getDoc)(procedureRef);
|
|
15192
15334
|
if (!procedureSnap.exists()) {
|
|
15193
15335
|
console.warn(`Procedure ${id} not found for deactivation.`);
|
|
15194
15336
|
return;
|
|
15195
15337
|
}
|
|
15196
|
-
await (0,
|
|
15338
|
+
await (0, import_firestore46.updateDoc)(procedureRef, {
|
|
15197
15339
|
isActive: false,
|
|
15198
|
-
updatedAt: (0,
|
|
15340
|
+
updatedAt: (0, import_firestore46.serverTimestamp)()
|
|
15199
15341
|
});
|
|
15200
15342
|
}
|
|
15201
15343
|
/**
|
|
@@ -15204,12 +15346,12 @@ var ProcedureService = class extends BaseService {
|
|
|
15204
15346
|
* @returns A boolean indicating if the deletion was successful
|
|
15205
15347
|
*/
|
|
15206
15348
|
async deleteProcedure(id) {
|
|
15207
|
-
const procedureRef = (0,
|
|
15208
|
-
const procedureSnapshot = await (0,
|
|
15349
|
+
const procedureRef = (0, import_firestore46.doc)(this.db, PROCEDURES_COLLECTION, id);
|
|
15350
|
+
const procedureSnapshot = await (0, import_firestore46.getDoc)(procedureRef);
|
|
15209
15351
|
if (!procedureSnapshot.exists()) {
|
|
15210
15352
|
return false;
|
|
15211
15353
|
}
|
|
15212
|
-
await (0,
|
|
15354
|
+
await (0, import_firestore46.deleteDoc)(procedureRef);
|
|
15213
15355
|
return true;
|
|
15214
15356
|
}
|
|
15215
15357
|
/**
|
|
@@ -15235,31 +15377,35 @@ var ProcedureService = class extends BaseService {
|
|
|
15235
15377
|
*/
|
|
15236
15378
|
async getAllProcedures(pagination, lastDoc) {
|
|
15237
15379
|
try {
|
|
15238
|
-
const proceduresCollection = (0,
|
|
15239
|
-
let proceduresQuery = (0,
|
|
15380
|
+
const proceduresCollection = (0, import_firestore46.collection)(this.db, PROCEDURES_COLLECTION);
|
|
15381
|
+
let proceduresQuery = (0, import_firestore46.query)(proceduresCollection);
|
|
15240
15382
|
if (pagination && pagination > 0) {
|
|
15241
|
-
const { limit:
|
|
15383
|
+
const { limit: limit21, startAfter: startAfter19 } = await import("firebase/firestore");
|
|
15242
15384
|
if (lastDoc) {
|
|
15243
|
-
proceduresQuery = (0,
|
|
15385
|
+
proceduresQuery = (0, import_firestore46.query)(
|
|
15244
15386
|
proceduresCollection,
|
|
15245
|
-
(0,
|
|
15387
|
+
(0, import_firestore46.orderBy)("name"),
|
|
15246
15388
|
// Use imported orderBy
|
|
15247
|
-
|
|
15248
|
-
|
|
15389
|
+
startAfter19(lastDoc),
|
|
15390
|
+
limit21(pagination)
|
|
15249
15391
|
);
|
|
15250
15392
|
} else {
|
|
15251
|
-
proceduresQuery = (0,
|
|
15393
|
+
proceduresQuery = (0, import_firestore46.query)(
|
|
15394
|
+
proceduresCollection,
|
|
15395
|
+
(0, import_firestore46.orderBy)("name"),
|
|
15396
|
+
limit21(pagination)
|
|
15397
|
+
);
|
|
15252
15398
|
}
|
|
15253
15399
|
} else {
|
|
15254
|
-
proceduresQuery = (0,
|
|
15400
|
+
proceduresQuery = (0, import_firestore46.query)(proceduresCollection, (0, import_firestore46.orderBy)("name"));
|
|
15255
15401
|
}
|
|
15256
|
-
const proceduresSnapshot = await (0,
|
|
15402
|
+
const proceduresSnapshot = await (0, import_firestore46.getDocs)(proceduresQuery);
|
|
15257
15403
|
const lastVisible = proceduresSnapshot.docs[proceduresSnapshot.docs.length - 1];
|
|
15258
|
-
const procedures = proceduresSnapshot.docs.map((
|
|
15259
|
-
const data =
|
|
15404
|
+
const procedures = proceduresSnapshot.docs.map((doc38) => {
|
|
15405
|
+
const data = doc38.data();
|
|
15260
15406
|
return {
|
|
15261
15407
|
...data,
|
|
15262
|
-
id:
|
|
15408
|
+
id: doc38.id
|
|
15263
15409
|
// Ensure ID is present
|
|
15264
15410
|
};
|
|
15265
15411
|
});
|
|
@@ -15279,7 +15425,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15279
15425
|
*
|
|
15280
15426
|
* @param filters - Various filters to apply
|
|
15281
15427
|
* @param filters.nameSearch - Optional search text for procedure name
|
|
15282
|
-
* @param filters.
|
|
15428
|
+
* @param filters.treatmentBenefitIds - Optional array of treatment benefits to filter by
|
|
15283
15429
|
* @param filters.procedureFamily - Optional procedure family to filter by
|
|
15284
15430
|
* @param filters.procedureCategory - Optional procedure category to filter by
|
|
15285
15431
|
* @param filters.procedureSubcategory - Optional procedure subcategory to filter by
|
|
@@ -15297,7 +15443,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15297
15443
|
*/
|
|
15298
15444
|
async getProceduresByFilters(filters) {
|
|
15299
15445
|
try {
|
|
15300
|
-
console.log(
|
|
15446
|
+
console.log(
|
|
15447
|
+
"[PROCEDURE_SERVICE] Starting procedure filtering with multiple strategies"
|
|
15448
|
+
);
|
|
15301
15449
|
if (filters.location && filters.radiusInKm) {
|
|
15302
15450
|
console.log("[PROCEDURE_SERVICE] Executing geo query:", {
|
|
15303
15451
|
location: filters.location,
|
|
@@ -15305,7 +15453,10 @@ var ProcedureService = class extends BaseService {
|
|
|
15305
15453
|
serviceName: "ProcedureService"
|
|
15306
15454
|
});
|
|
15307
15455
|
if (!filters.location.latitude || !filters.location.longitude) {
|
|
15308
|
-
console.warn(
|
|
15456
|
+
console.warn(
|
|
15457
|
+
"[PROCEDURE_SERVICE] Invalid location data:",
|
|
15458
|
+
filters.location
|
|
15459
|
+
);
|
|
15309
15460
|
filters.location = void 0;
|
|
15310
15461
|
filters.radiusInKm = void 0;
|
|
15311
15462
|
}
|
|
@@ -15317,65 +15468,88 @@ var ProcedureService = class extends BaseService {
|
|
|
15317
15468
|
const getBaseConstraints = () => {
|
|
15318
15469
|
const constraints = [];
|
|
15319
15470
|
if (filters.isActive !== void 0) {
|
|
15320
|
-
constraints.push((0,
|
|
15471
|
+
constraints.push((0, import_firestore46.where)("isActive", "==", filters.isActive));
|
|
15321
15472
|
} else {
|
|
15322
|
-
constraints.push((0,
|
|
15473
|
+
constraints.push((0, import_firestore46.where)("isActive", "==", true));
|
|
15323
15474
|
}
|
|
15324
15475
|
if (filters.procedureFamily) {
|
|
15325
|
-
constraints.push((0,
|
|
15476
|
+
constraints.push((0, import_firestore46.where)("family", "==", filters.procedureFamily));
|
|
15326
15477
|
}
|
|
15327
15478
|
if (filters.procedureCategory) {
|
|
15328
|
-
constraints.push(
|
|
15479
|
+
constraints.push(
|
|
15480
|
+
(0, import_firestore46.where)("category.id", "==", filters.procedureCategory)
|
|
15481
|
+
);
|
|
15329
15482
|
}
|
|
15330
15483
|
if (filters.procedureSubcategory) {
|
|
15331
|
-
constraints.push(
|
|
15484
|
+
constraints.push(
|
|
15485
|
+
(0, import_firestore46.where)("subcategory.id", "==", filters.procedureSubcategory)
|
|
15486
|
+
);
|
|
15332
15487
|
}
|
|
15333
15488
|
if (filters.procedureTechnology) {
|
|
15334
|
-
constraints.push(
|
|
15489
|
+
constraints.push(
|
|
15490
|
+
(0, import_firestore46.where)("technology.id", "==", filters.procedureTechnology)
|
|
15491
|
+
);
|
|
15335
15492
|
}
|
|
15336
15493
|
if (filters.minPrice !== void 0) {
|
|
15337
|
-
constraints.push((0,
|
|
15494
|
+
constraints.push((0, import_firestore46.where)("price", ">=", filters.minPrice));
|
|
15338
15495
|
}
|
|
15339
15496
|
if (filters.maxPrice !== void 0) {
|
|
15340
|
-
constraints.push((0,
|
|
15497
|
+
constraints.push((0, import_firestore46.where)("price", "<=", filters.maxPrice));
|
|
15341
15498
|
}
|
|
15342
15499
|
if (filters.minRating !== void 0) {
|
|
15343
|
-
constraints.push(
|
|
15500
|
+
constraints.push(
|
|
15501
|
+
(0, import_firestore46.where)("reviewInfo.averageRating", ">=", filters.minRating)
|
|
15502
|
+
);
|
|
15344
15503
|
}
|
|
15345
15504
|
if (filters.maxRating !== void 0) {
|
|
15346
|
-
constraints.push(
|
|
15505
|
+
constraints.push(
|
|
15506
|
+
(0, import_firestore46.where)("reviewInfo.averageRating", "<=", filters.maxRating)
|
|
15507
|
+
);
|
|
15347
15508
|
}
|
|
15348
15509
|
if (filters.treatmentBenefits && filters.treatmentBenefits.length > 0) {
|
|
15349
|
-
const
|
|
15350
|
-
constraints.push(
|
|
15510
|
+
const benefitIdsToMatch = filters.treatmentBenefits;
|
|
15511
|
+
constraints.push(
|
|
15512
|
+
(0, import_firestore46.where)(
|
|
15513
|
+
"treatmentBenefitIds",
|
|
15514
|
+
"array-contains-any",
|
|
15515
|
+
benefitIdsToMatch
|
|
15516
|
+
)
|
|
15517
|
+
);
|
|
15351
15518
|
}
|
|
15352
15519
|
return constraints;
|
|
15353
15520
|
};
|
|
15354
15521
|
if (filters.nameSearch && filters.nameSearch.trim()) {
|
|
15355
15522
|
try {
|
|
15356
|
-
console.log(
|
|
15523
|
+
console.log(
|
|
15524
|
+
"[PROCEDURE_SERVICE] Strategy 1: Trying nameLower search"
|
|
15525
|
+
);
|
|
15357
15526
|
const searchTerm = filters.nameSearch.trim().toLowerCase();
|
|
15358
15527
|
const constraints = getBaseConstraints();
|
|
15359
|
-
constraints.push((0,
|
|
15360
|
-
constraints.push((0,
|
|
15361
|
-
constraints.push((0,
|
|
15528
|
+
constraints.push((0, import_firestore46.where)("nameLower", ">=", searchTerm));
|
|
15529
|
+
constraints.push((0, import_firestore46.where)("nameLower", "<=", searchTerm + "\uF8FF"));
|
|
15530
|
+
constraints.push((0, import_firestore46.orderBy)("nameLower"));
|
|
15362
15531
|
if (filters.lastDoc) {
|
|
15363
15532
|
if (typeof filters.lastDoc.data === "function") {
|
|
15364
|
-
constraints.push((0,
|
|
15533
|
+
constraints.push((0, import_firestore46.startAfter)(filters.lastDoc));
|
|
15365
15534
|
} else if (Array.isArray(filters.lastDoc)) {
|
|
15366
|
-
constraints.push((0,
|
|
15535
|
+
constraints.push((0, import_firestore46.startAfter)(...filters.lastDoc));
|
|
15367
15536
|
} else {
|
|
15368
|
-
constraints.push((0,
|
|
15537
|
+
constraints.push((0, import_firestore46.startAfter)(filters.lastDoc));
|
|
15369
15538
|
}
|
|
15370
15539
|
}
|
|
15371
|
-
constraints.push((0,
|
|
15372
|
-
const q = (0,
|
|
15373
|
-
|
|
15540
|
+
constraints.push((0, import_firestore46.limit)(filters.pagination || 10));
|
|
15541
|
+
const q = (0, import_firestore46.query)(
|
|
15542
|
+
(0, import_firestore46.collection)(this.db, PROCEDURES_COLLECTION),
|
|
15543
|
+
...constraints
|
|
15544
|
+
);
|
|
15545
|
+
const querySnapshot = await (0, import_firestore46.getDocs)(q);
|
|
15374
15546
|
const procedures = querySnapshot.docs.map(
|
|
15375
|
-
(
|
|
15547
|
+
(doc38) => ({ ...doc38.data(), id: doc38.id })
|
|
15376
15548
|
);
|
|
15377
15549
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15378
|
-
console.log(
|
|
15550
|
+
console.log(
|
|
15551
|
+
`[PROCEDURE_SERVICE] Strategy 1 success: ${procedures.length} procedures`
|
|
15552
|
+
);
|
|
15379
15553
|
if (procedures.length < (filters.pagination || 10)) {
|
|
15380
15554
|
return { procedures, lastDoc: null };
|
|
15381
15555
|
}
|
|
@@ -15386,29 +15560,36 @@ var ProcedureService = class extends BaseService {
|
|
|
15386
15560
|
}
|
|
15387
15561
|
if (filters.nameSearch && filters.nameSearch.trim()) {
|
|
15388
15562
|
try {
|
|
15389
|
-
console.log(
|
|
15563
|
+
console.log(
|
|
15564
|
+
"[PROCEDURE_SERVICE] Strategy 2: Trying name field search"
|
|
15565
|
+
);
|
|
15390
15566
|
const searchTerm = filters.nameSearch.trim().toLowerCase();
|
|
15391
15567
|
const constraints = getBaseConstraints();
|
|
15392
|
-
constraints.push((0,
|
|
15393
|
-
constraints.push((0,
|
|
15394
|
-
constraints.push((0,
|
|
15568
|
+
constraints.push((0, import_firestore46.where)("name", ">=", searchTerm));
|
|
15569
|
+
constraints.push((0, import_firestore46.where)("name", "<=", searchTerm + "\uF8FF"));
|
|
15570
|
+
constraints.push((0, import_firestore46.orderBy)("name"));
|
|
15395
15571
|
if (filters.lastDoc) {
|
|
15396
15572
|
if (typeof filters.lastDoc.data === "function") {
|
|
15397
|
-
constraints.push((0,
|
|
15573
|
+
constraints.push((0, import_firestore46.startAfter)(filters.lastDoc));
|
|
15398
15574
|
} else if (Array.isArray(filters.lastDoc)) {
|
|
15399
|
-
constraints.push((0,
|
|
15575
|
+
constraints.push((0, import_firestore46.startAfter)(...filters.lastDoc));
|
|
15400
15576
|
} else {
|
|
15401
|
-
constraints.push((0,
|
|
15577
|
+
constraints.push((0, import_firestore46.startAfter)(filters.lastDoc));
|
|
15402
15578
|
}
|
|
15403
15579
|
}
|
|
15404
|
-
constraints.push((0,
|
|
15405
|
-
const q = (0,
|
|
15406
|
-
|
|
15580
|
+
constraints.push((0, import_firestore46.limit)(filters.pagination || 10));
|
|
15581
|
+
const q = (0, import_firestore46.query)(
|
|
15582
|
+
(0, import_firestore46.collection)(this.db, PROCEDURES_COLLECTION),
|
|
15583
|
+
...constraints
|
|
15584
|
+
);
|
|
15585
|
+
const querySnapshot = await (0, import_firestore46.getDocs)(q);
|
|
15407
15586
|
const procedures = querySnapshot.docs.map(
|
|
15408
|
-
(
|
|
15587
|
+
(doc38) => ({ ...doc38.data(), id: doc38.id })
|
|
15409
15588
|
);
|
|
15410
15589
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15411
|
-
console.log(
|
|
15590
|
+
console.log(
|
|
15591
|
+
`[PROCEDURE_SERVICE] Strategy 2 success: ${procedures.length} procedures`
|
|
15592
|
+
);
|
|
15412
15593
|
if (procedures.length < (filters.pagination || 10)) {
|
|
15413
15594
|
return { procedures, lastDoc: null };
|
|
15414
15595
|
}
|
|
@@ -15422,25 +15603,30 @@ var ProcedureService = class extends BaseService {
|
|
|
15422
15603
|
"[PROCEDURE_SERVICE] Strategy 3: Using createdAt orderBy with client-side filtering"
|
|
15423
15604
|
);
|
|
15424
15605
|
const constraints = getBaseConstraints();
|
|
15425
|
-
constraints.push((0,
|
|
15606
|
+
constraints.push((0, import_firestore46.orderBy)("createdAt", "desc"));
|
|
15426
15607
|
if (filters.lastDoc) {
|
|
15427
15608
|
if (typeof filters.lastDoc.data === "function") {
|
|
15428
|
-
constraints.push((0,
|
|
15609
|
+
constraints.push((0, import_firestore46.startAfter)(filters.lastDoc));
|
|
15429
15610
|
} else if (Array.isArray(filters.lastDoc)) {
|
|
15430
|
-
constraints.push((0,
|
|
15611
|
+
constraints.push((0, import_firestore46.startAfter)(...filters.lastDoc));
|
|
15431
15612
|
} else {
|
|
15432
|
-
constraints.push((0,
|
|
15613
|
+
constraints.push((0, import_firestore46.startAfter)(filters.lastDoc));
|
|
15433
15614
|
}
|
|
15434
15615
|
}
|
|
15435
|
-
constraints.push((0,
|
|
15436
|
-
const q = (0,
|
|
15437
|
-
|
|
15616
|
+
constraints.push((0, import_firestore46.limit)(filters.pagination || 10));
|
|
15617
|
+
const q = (0, import_firestore46.query)(
|
|
15618
|
+
(0, import_firestore46.collection)(this.db, PROCEDURES_COLLECTION),
|
|
15619
|
+
...constraints
|
|
15620
|
+
);
|
|
15621
|
+
const querySnapshot = await (0, import_firestore46.getDocs)(q);
|
|
15438
15622
|
let procedures = querySnapshot.docs.map(
|
|
15439
|
-
(
|
|
15623
|
+
(doc38) => ({ ...doc38.data(), id: doc38.id })
|
|
15440
15624
|
);
|
|
15441
15625
|
procedures = this.applyInMemoryFilters(procedures, filters);
|
|
15442
15626
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15443
|
-
console.log(
|
|
15627
|
+
console.log(
|
|
15628
|
+
`[PROCEDURE_SERVICE] Strategy 3 success: ${procedures.length} procedures`
|
|
15629
|
+
);
|
|
15444
15630
|
if (procedures.length < (filters.pagination || 10)) {
|
|
15445
15631
|
return { procedures, lastDoc: null };
|
|
15446
15632
|
}
|
|
@@ -15451,18 +15637,23 @@ var ProcedureService = class extends BaseService {
|
|
|
15451
15637
|
try {
|
|
15452
15638
|
console.log("[PROCEDURE_SERVICE] Strategy 4: Minimal query fallback");
|
|
15453
15639
|
const constraints = [
|
|
15454
|
-
(0,
|
|
15455
|
-
(0,
|
|
15456
|
-
(0,
|
|
15640
|
+
(0, import_firestore46.where)("isActive", "==", true),
|
|
15641
|
+
(0, import_firestore46.orderBy)("createdAt", "desc"),
|
|
15642
|
+
(0, import_firestore46.limit)(filters.pagination || 10)
|
|
15457
15643
|
];
|
|
15458
|
-
const q = (0,
|
|
15459
|
-
|
|
15644
|
+
const q = (0, import_firestore46.query)(
|
|
15645
|
+
(0, import_firestore46.collection)(this.db, PROCEDURES_COLLECTION),
|
|
15646
|
+
...constraints
|
|
15647
|
+
);
|
|
15648
|
+
const querySnapshot = await (0, import_firestore46.getDocs)(q);
|
|
15460
15649
|
let procedures = querySnapshot.docs.map(
|
|
15461
|
-
(
|
|
15650
|
+
(doc38) => ({ ...doc38.data(), id: doc38.id })
|
|
15462
15651
|
);
|
|
15463
15652
|
procedures = this.applyInMemoryFilters(procedures, filters);
|
|
15464
15653
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15465
|
-
console.log(
|
|
15654
|
+
console.log(
|
|
15655
|
+
`[PROCEDURE_SERVICE] Strategy 4 success: ${procedures.length} procedures`
|
|
15656
|
+
);
|
|
15466
15657
|
if (procedures.length < (filters.pagination || 10)) {
|
|
15467
15658
|
return { procedures, lastDoc: null };
|
|
15468
15659
|
}
|
|
@@ -15470,7 +15661,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15470
15661
|
} catch (error) {
|
|
15471
15662
|
console.log("[PROCEDURE_SERVICE] Strategy 4 failed:", error);
|
|
15472
15663
|
}
|
|
15473
|
-
console.log(
|
|
15664
|
+
console.log(
|
|
15665
|
+
"[PROCEDURE_SERVICE] All strategies failed, returning empty result"
|
|
15666
|
+
);
|
|
15474
15667
|
return { procedures: [], lastDoc: null };
|
|
15475
15668
|
} catch (error) {
|
|
15476
15669
|
console.error("[PROCEDURE_SERVICE] Error filtering procedures:", error);
|
|
@@ -15490,13 +15683,17 @@ var ProcedureService = class extends BaseService {
|
|
|
15490
15683
|
const nameLower = procedure.nameLower || "";
|
|
15491
15684
|
return name.includes(searchTerm) || nameLower.includes(searchTerm);
|
|
15492
15685
|
});
|
|
15493
|
-
console.log(
|
|
15686
|
+
console.log(
|
|
15687
|
+
`[PROCEDURE_SERVICE] Applied name filter, results: ${filteredProcedures.length}`
|
|
15688
|
+
);
|
|
15494
15689
|
}
|
|
15495
15690
|
if (filters.minPrice !== void 0 || filters.maxPrice !== void 0) {
|
|
15496
15691
|
filteredProcedures = filteredProcedures.filter((procedure) => {
|
|
15497
15692
|
const price = procedure.price || 0;
|
|
15498
|
-
if (filters.minPrice !== void 0 && price < filters.minPrice)
|
|
15499
|
-
|
|
15693
|
+
if (filters.minPrice !== void 0 && price < filters.minPrice)
|
|
15694
|
+
return false;
|
|
15695
|
+
if (filters.maxPrice !== void 0 && price > filters.maxPrice)
|
|
15696
|
+
return false;
|
|
15500
15697
|
return true;
|
|
15501
15698
|
});
|
|
15502
15699
|
console.log(
|
|
@@ -15507,8 +15704,10 @@ var ProcedureService = class extends BaseService {
|
|
|
15507
15704
|
filteredProcedures = filteredProcedures.filter((procedure) => {
|
|
15508
15705
|
var _a;
|
|
15509
15706
|
const rating = ((_a = procedure.reviewInfo) == null ? void 0 : _a.averageRating) || 0;
|
|
15510
|
-
if (filters.minRating !== void 0 && rating < filters.minRating)
|
|
15511
|
-
|
|
15707
|
+
if (filters.minRating !== void 0 && rating < filters.minRating)
|
|
15708
|
+
return false;
|
|
15709
|
+
if (filters.maxRating !== void 0 && rating > filters.maxRating)
|
|
15710
|
+
return false;
|
|
15512
15711
|
return true;
|
|
15513
15712
|
});
|
|
15514
15713
|
console.log(
|
|
@@ -15516,10 +15715,12 @@ var ProcedureService = class extends BaseService {
|
|
|
15516
15715
|
);
|
|
15517
15716
|
}
|
|
15518
15717
|
if (filters.treatmentBenefits && filters.treatmentBenefits.length > 0) {
|
|
15519
|
-
const
|
|
15718
|
+
const benefitIdsToMatch = filters.treatmentBenefits;
|
|
15520
15719
|
filteredProcedures = filteredProcedures.filter((procedure) => {
|
|
15521
|
-
const
|
|
15522
|
-
return
|
|
15720
|
+
const procedureBenefitIds = procedure.treatmentBenefitIds || [];
|
|
15721
|
+
return benefitIdsToMatch.some(
|
|
15722
|
+
(benefitId) => procedureBenefitIds.includes(benefitId)
|
|
15723
|
+
);
|
|
15523
15724
|
});
|
|
15524
15725
|
console.log(
|
|
15525
15726
|
`[PROCEDURE_SERVICE] Applied benefits filter, results: ${filteredProcedures.length}`
|
|
@@ -15582,8 +15783,12 @@ var ProcedureService = class extends BaseService {
|
|
|
15582
15783
|
procedure.distance = distance;
|
|
15583
15784
|
return distance <= radiusInKm;
|
|
15584
15785
|
});
|
|
15585
|
-
console.log(
|
|
15586
|
-
|
|
15786
|
+
console.log(
|
|
15787
|
+
`[PROCEDURE_SERVICE] Applied geo filter, results: ${filteredProcedures.length}`
|
|
15788
|
+
);
|
|
15789
|
+
filteredProcedures.sort(
|
|
15790
|
+
(a, b) => (a.distance || 0) - (b.distance || 0)
|
|
15791
|
+
);
|
|
15587
15792
|
}
|
|
15588
15793
|
return filteredProcedures;
|
|
15589
15794
|
}
|
|
@@ -15595,19 +15800,30 @@ var ProcedureService = class extends BaseService {
|
|
|
15595
15800
|
if (!location || !radiusInKm) {
|
|
15596
15801
|
return Promise.resolve({ procedures: [], lastDoc: null });
|
|
15597
15802
|
}
|
|
15598
|
-
const bounds = (0, import_geofire_common8.geohashQueryBounds)(
|
|
15803
|
+
const bounds = (0, import_geofire_common8.geohashQueryBounds)(
|
|
15804
|
+
[location.latitude, location.longitude],
|
|
15805
|
+
radiusInKm * 1e3
|
|
15806
|
+
);
|
|
15599
15807
|
const fetches = bounds.map((b) => {
|
|
15600
15808
|
const constraints = [
|
|
15601
|
-
(0,
|
|
15602
|
-
(0,
|
|
15603
|
-
(0,
|
|
15809
|
+
(0, import_firestore46.where)("clinicInfo.location.geohash", ">=", b[0]),
|
|
15810
|
+
(0, import_firestore46.where)("clinicInfo.location.geohash", "<=", b[1]),
|
|
15811
|
+
(0, import_firestore46.where)(
|
|
15812
|
+
"isActive",
|
|
15813
|
+
"==",
|
|
15814
|
+
filters.isActive !== void 0 ? filters.isActive : true
|
|
15815
|
+
)
|
|
15604
15816
|
];
|
|
15605
|
-
return (0,
|
|
15817
|
+
return (0, import_firestore46.getDocs)(
|
|
15818
|
+
(0, import_firestore46.query)((0, import_firestore46.collection)(this.db, PROCEDURES_COLLECTION), ...constraints)
|
|
15819
|
+
);
|
|
15606
15820
|
});
|
|
15607
15821
|
return Promise.all(fetches).then((snaps) => {
|
|
15608
15822
|
const collected = [];
|
|
15609
15823
|
snaps.forEach((snap) => {
|
|
15610
|
-
snap.docs.forEach(
|
|
15824
|
+
snap.docs.forEach(
|
|
15825
|
+
(d) => collected.push({ ...d.data(), id: d.id })
|
|
15826
|
+
);
|
|
15611
15827
|
});
|
|
15612
15828
|
const uniqueMap = /* @__PURE__ */ new Map();
|
|
15613
15829
|
for (const p of collected) {
|
|
@@ -15618,7 +15834,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15618
15834
|
const pageSize = filters.pagination || 10;
|
|
15619
15835
|
let startIndex = 0;
|
|
15620
15836
|
if (filters.lastDoc && typeof filters.lastDoc === "object" && filters.lastDoc.id) {
|
|
15621
|
-
const idx = procedures.findIndex(
|
|
15837
|
+
const idx = procedures.findIndex(
|
|
15838
|
+
(p) => p.id === filters.lastDoc.id
|
|
15839
|
+
);
|
|
15622
15840
|
if (idx >= 0) startIndex = idx + 1;
|
|
15623
15841
|
}
|
|
15624
15842
|
const page = procedures.slice(startIndex, startIndex + pageSize);
|
|
@@ -15643,7 +15861,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15643
15861
|
* @returns The created procedure
|
|
15644
15862
|
*/
|
|
15645
15863
|
async createConsultationProcedure(data) {
|
|
15646
|
-
var _a;
|
|
15864
|
+
var _a, _b, _c;
|
|
15647
15865
|
const procedureId = this.generateId();
|
|
15648
15866
|
const [category, subcategory, technology] = await Promise.all([
|
|
15649
15867
|
this.categoryService.getById(data.categoryId),
|
|
@@ -15653,21 +15871,29 @@ var ProcedureService = class extends BaseService {
|
|
|
15653
15871
|
if (!category || !subcategory || !technology) {
|
|
15654
15872
|
throw new Error("One or more required base entities not found");
|
|
15655
15873
|
}
|
|
15656
|
-
const clinicRef = (0,
|
|
15657
|
-
const clinicSnapshot = await (0,
|
|
15874
|
+
const clinicRef = (0, import_firestore46.doc)(this.db, CLINICS_COLLECTION, data.clinicBranchId);
|
|
15875
|
+
const clinicSnapshot = await (0, import_firestore46.getDoc)(clinicRef);
|
|
15658
15876
|
if (!clinicSnapshot.exists()) {
|
|
15659
15877
|
throw new Error(`Clinic with ID ${data.clinicBranchId} not found`);
|
|
15660
15878
|
}
|
|
15661
15879
|
const clinic = clinicSnapshot.data();
|
|
15662
|
-
const practitionerRef = (0,
|
|
15663
|
-
|
|
15880
|
+
const practitionerRef = (0, import_firestore46.doc)(
|
|
15881
|
+
this.db,
|
|
15882
|
+
PRACTITIONERS_COLLECTION,
|
|
15883
|
+
data.practitionerId
|
|
15884
|
+
);
|
|
15885
|
+
const practitionerSnapshot = await (0, import_firestore46.getDoc)(practitionerRef);
|
|
15664
15886
|
if (!practitionerSnapshot.exists()) {
|
|
15665
15887
|
throw new Error(`Practitioner with ID ${data.practitionerId} not found`);
|
|
15666
15888
|
}
|
|
15667
15889
|
const practitioner = practitionerSnapshot.data();
|
|
15668
15890
|
let processedPhotos = [];
|
|
15669
15891
|
if (data.photos && data.photos.length > 0) {
|
|
15670
|
-
processedPhotos = await this.processMediaArray(
|
|
15892
|
+
processedPhotos = await this.processMediaArray(
|
|
15893
|
+
data.photos,
|
|
15894
|
+
procedureId,
|
|
15895
|
+
"procedure-photos"
|
|
15896
|
+
);
|
|
15671
15897
|
}
|
|
15672
15898
|
const clinicInfo = {
|
|
15673
15899
|
id: clinicSnapshot.id,
|
|
@@ -15693,6 +15919,8 @@ var ProcedureService = class extends BaseService {
|
|
|
15693
15919
|
brandName: "Consultation",
|
|
15694
15920
|
technologyId: data.technologyId,
|
|
15695
15921
|
technologyName: technology.name,
|
|
15922
|
+
categoryId: technology.categoryId,
|
|
15923
|
+
subcategoryId: technology.subcategoryId,
|
|
15696
15924
|
isActive: true,
|
|
15697
15925
|
createdAt: /* @__PURE__ */ new Date(),
|
|
15698
15926
|
updatedAt: /* @__PURE__ */ new Date()
|
|
@@ -15709,7 +15937,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15709
15937
|
// Use placeholder product
|
|
15710
15938
|
blockingConditions: technology.blockingConditions,
|
|
15711
15939
|
contraindications: technology.contraindications || [],
|
|
15940
|
+
contraindicationIds: ((_b = technology.contraindications) == null ? void 0 : _b.map((c) => c.id)) || [],
|
|
15712
15941
|
treatmentBenefits: technology.benefits,
|
|
15942
|
+
treatmentBenefitIds: ((_c = technology.benefits) == null ? void 0 : _c.map((b) => b.id)) || [],
|
|
15713
15943
|
preRequirements: technology.requirements.pre,
|
|
15714
15944
|
postRequirements: technology.requirements.post,
|
|
15715
15945
|
certificationRequirement: technology.certificationRequirement,
|
|
@@ -15728,13 +15958,13 @@ var ProcedureService = class extends BaseService {
|
|
|
15728
15958
|
},
|
|
15729
15959
|
isActive: true
|
|
15730
15960
|
};
|
|
15731
|
-
const procedureRef = (0,
|
|
15732
|
-
await (0,
|
|
15961
|
+
const procedureRef = (0, import_firestore46.doc)(this.db, PROCEDURES_COLLECTION, procedureId);
|
|
15962
|
+
await (0, import_firestore46.setDoc)(procedureRef, {
|
|
15733
15963
|
...newProcedure,
|
|
15734
|
-
createdAt: (0,
|
|
15735
|
-
updatedAt: (0,
|
|
15964
|
+
createdAt: (0, import_firestore46.serverTimestamp)(),
|
|
15965
|
+
updatedAt: (0, import_firestore46.serverTimestamp)()
|
|
15736
15966
|
});
|
|
15737
|
-
const savedDoc = await (0,
|
|
15967
|
+
const savedDoc = await (0, import_firestore46.getDoc)(procedureRef);
|
|
15738
15968
|
return savedDoc.data();
|
|
15739
15969
|
}
|
|
15740
15970
|
/**
|
|
@@ -15743,13 +15973,13 @@ var ProcedureService = class extends BaseService {
|
|
|
15743
15973
|
* @returns Array of minimal procedure info for map
|
|
15744
15974
|
*/
|
|
15745
15975
|
async getProceduresForMap() {
|
|
15746
|
-
const proceduresRef = (0,
|
|
15747
|
-
const snapshot = await (0,
|
|
15748
|
-
const proceduresForMap = snapshot.docs.map((
|
|
15976
|
+
const proceduresRef = (0, import_firestore46.collection)(this.db, PROCEDURES_COLLECTION);
|
|
15977
|
+
const snapshot = await (0, import_firestore46.getDocs)(proceduresRef);
|
|
15978
|
+
const proceduresForMap = snapshot.docs.map((doc38) => {
|
|
15749
15979
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
15750
|
-
const data =
|
|
15980
|
+
const data = doc38.data();
|
|
15751
15981
|
return {
|
|
15752
|
-
id:
|
|
15982
|
+
id: doc38.id,
|
|
15753
15983
|
name: data.name,
|
|
15754
15984
|
clinicId: (_a = data.clinicInfo) == null ? void 0 : _a.id,
|
|
15755
15985
|
clinicName: (_b = data.clinicInfo) == null ? void 0 : _b.name,
|
|
@@ -15763,7 +15993,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15763
15993
|
};
|
|
15764
15994
|
|
|
15765
15995
|
// src/services/reviews/reviews.service.ts
|
|
15766
|
-
var
|
|
15996
|
+
var import_firestore47 = require("firebase/firestore");
|
|
15767
15997
|
var import_zod25 = require("zod");
|
|
15768
15998
|
var ReviewService = class extends BaseService {
|
|
15769
15999
|
constructor(db, auth, app) {
|
|
@@ -15843,11 +16073,11 @@ var ReviewService = class extends BaseService {
|
|
|
15843
16073
|
updatedAt: now
|
|
15844
16074
|
};
|
|
15845
16075
|
reviewSchema.parse(review);
|
|
15846
|
-
const docRef = (0,
|
|
15847
|
-
await (0,
|
|
16076
|
+
const docRef = (0, import_firestore47.doc)(this.db, REVIEWS_COLLECTION, reviewId);
|
|
16077
|
+
await (0, import_firestore47.setDoc)(docRef, {
|
|
15848
16078
|
...review,
|
|
15849
|
-
createdAt: (0,
|
|
15850
|
-
updatedAt: (0,
|
|
16079
|
+
createdAt: (0, import_firestore47.serverTimestamp)(),
|
|
16080
|
+
updatedAt: (0, import_firestore47.serverTimestamp)()
|
|
15851
16081
|
});
|
|
15852
16082
|
return review;
|
|
15853
16083
|
} catch (error) {
|
|
@@ -15863,8 +16093,8 @@ var ReviewService = class extends BaseService {
|
|
|
15863
16093
|
* @returns The review if found, null otherwise
|
|
15864
16094
|
*/
|
|
15865
16095
|
async getReview(reviewId) {
|
|
15866
|
-
const docRef = (0,
|
|
15867
|
-
const docSnap = await (0,
|
|
16096
|
+
const docRef = (0, import_firestore47.doc)(this.db, REVIEWS_COLLECTION, reviewId);
|
|
16097
|
+
const docSnap = await (0, import_firestore47.getDoc)(docRef);
|
|
15868
16098
|
if (!docSnap.exists()) {
|
|
15869
16099
|
return null;
|
|
15870
16100
|
}
|
|
@@ -15876,12 +16106,12 @@ var ReviewService = class extends BaseService {
|
|
|
15876
16106
|
* @returns Array of reviews for the patient
|
|
15877
16107
|
*/
|
|
15878
16108
|
async getReviewsByPatient(patientId) {
|
|
15879
|
-
const q = (0,
|
|
15880
|
-
(0,
|
|
15881
|
-
(0,
|
|
16109
|
+
const q = (0, import_firestore47.query)(
|
|
16110
|
+
(0, import_firestore47.collection)(this.db, REVIEWS_COLLECTION),
|
|
16111
|
+
(0, import_firestore47.where)("patientId", "==", patientId)
|
|
15882
16112
|
);
|
|
15883
|
-
const snapshot = await (0,
|
|
15884
|
-
return snapshot.docs.map((
|
|
16113
|
+
const snapshot = await (0, import_firestore47.getDocs)(q);
|
|
16114
|
+
return snapshot.docs.map((doc38) => doc38.data());
|
|
15885
16115
|
}
|
|
15886
16116
|
/**
|
|
15887
16117
|
* Gets all reviews for a specific clinic
|
|
@@ -15889,12 +16119,12 @@ var ReviewService = class extends BaseService {
|
|
|
15889
16119
|
* @returns Array of reviews containing clinic reviews
|
|
15890
16120
|
*/
|
|
15891
16121
|
async getReviewsByClinic(clinicId) {
|
|
15892
|
-
const q = (0,
|
|
15893
|
-
(0,
|
|
15894
|
-
(0,
|
|
16122
|
+
const q = (0, import_firestore47.query)(
|
|
16123
|
+
(0, import_firestore47.collection)(this.db, REVIEWS_COLLECTION),
|
|
16124
|
+
(0, import_firestore47.where)("clinicReview.clinicId", "==", clinicId)
|
|
15895
16125
|
);
|
|
15896
|
-
const snapshot = await (0,
|
|
15897
|
-
return snapshot.docs.map((
|
|
16126
|
+
const snapshot = await (0, import_firestore47.getDocs)(q);
|
|
16127
|
+
return snapshot.docs.map((doc38) => doc38.data());
|
|
15898
16128
|
}
|
|
15899
16129
|
/**
|
|
15900
16130
|
* Gets all reviews for a specific practitioner
|
|
@@ -15902,12 +16132,12 @@ var ReviewService = class extends BaseService {
|
|
|
15902
16132
|
* @returns Array of reviews containing practitioner reviews
|
|
15903
16133
|
*/
|
|
15904
16134
|
async getReviewsByPractitioner(practitionerId) {
|
|
15905
|
-
const q = (0,
|
|
15906
|
-
(0,
|
|
15907
|
-
(0,
|
|
16135
|
+
const q = (0, import_firestore47.query)(
|
|
16136
|
+
(0, import_firestore47.collection)(this.db, REVIEWS_COLLECTION),
|
|
16137
|
+
(0, import_firestore47.where)("practitionerReview.practitionerId", "==", practitionerId)
|
|
15908
16138
|
);
|
|
15909
|
-
const snapshot = await (0,
|
|
15910
|
-
return snapshot.docs.map((
|
|
16139
|
+
const snapshot = await (0, import_firestore47.getDocs)(q);
|
|
16140
|
+
return snapshot.docs.map((doc38) => doc38.data());
|
|
15911
16141
|
}
|
|
15912
16142
|
/**
|
|
15913
16143
|
* Gets all reviews for a specific procedure
|
|
@@ -15915,12 +16145,12 @@ var ReviewService = class extends BaseService {
|
|
|
15915
16145
|
* @returns Array of reviews containing procedure reviews
|
|
15916
16146
|
*/
|
|
15917
16147
|
async getReviewsByProcedure(procedureId) {
|
|
15918
|
-
const q = (0,
|
|
15919
|
-
(0,
|
|
15920
|
-
(0,
|
|
16148
|
+
const q = (0, import_firestore47.query)(
|
|
16149
|
+
(0, import_firestore47.collection)(this.db, REVIEWS_COLLECTION),
|
|
16150
|
+
(0, import_firestore47.where)("procedureReview.procedureId", "==", procedureId)
|
|
15921
16151
|
);
|
|
15922
|
-
const snapshot = await (0,
|
|
15923
|
-
return snapshot.docs.map((
|
|
16152
|
+
const snapshot = await (0, import_firestore47.getDocs)(q);
|
|
16153
|
+
return snapshot.docs.map((doc38) => doc38.data());
|
|
15924
16154
|
}
|
|
15925
16155
|
/**
|
|
15926
16156
|
* Gets all reviews for a specific appointment
|
|
@@ -15928,11 +16158,11 @@ var ReviewService = class extends BaseService {
|
|
|
15928
16158
|
* @returns The review for the appointment if found, null otherwise
|
|
15929
16159
|
*/
|
|
15930
16160
|
async getReviewByAppointment(appointmentId) {
|
|
15931
|
-
const q = (0,
|
|
15932
|
-
(0,
|
|
15933
|
-
(0,
|
|
16161
|
+
const q = (0, import_firestore47.query)(
|
|
16162
|
+
(0, import_firestore47.collection)(this.db, REVIEWS_COLLECTION),
|
|
16163
|
+
(0, import_firestore47.where)("appointmentId", "==", appointmentId)
|
|
15934
16164
|
);
|
|
15935
|
-
const snapshot = await (0,
|
|
16165
|
+
const snapshot = await (0, import_firestore47.getDocs)(q);
|
|
15936
16166
|
if (snapshot.empty) {
|
|
15937
16167
|
return null;
|
|
15938
16168
|
}
|
|
@@ -15947,7 +16177,7 @@ var ReviewService = class extends BaseService {
|
|
|
15947
16177
|
if (!review) {
|
|
15948
16178
|
throw new Error(`Review with ID ${reviewId} not found`);
|
|
15949
16179
|
}
|
|
15950
|
-
await (0,
|
|
16180
|
+
await (0, import_firestore47.deleteDoc)((0, import_firestore47.doc)(this.db, REVIEWS_COLLECTION, reviewId));
|
|
15951
16181
|
}
|
|
15952
16182
|
/**
|
|
15953
16183
|
* Calculates the average of an array of numbers
|
|
@@ -15966,7 +16196,7 @@ var ReviewService = class extends BaseService {
|
|
|
15966
16196
|
|
|
15967
16197
|
// src/config/firebase.ts
|
|
15968
16198
|
var import_app = require("firebase/app");
|
|
15969
|
-
var
|
|
16199
|
+
var import_firestore48 = require("firebase/firestore");
|
|
15970
16200
|
var import_auth9 = require("firebase/auth");
|
|
15971
16201
|
var import_analytics = require("firebase/analytics");
|
|
15972
16202
|
var import_react_native = require("react-native");
|
|
@@ -15976,7 +16206,7 @@ var firebaseInstance = null;
|
|
|
15976
16206
|
var initializeFirebase = (config) => {
|
|
15977
16207
|
if (!firebaseInstance) {
|
|
15978
16208
|
const app = (0, import_app.initializeApp)(config);
|
|
15979
|
-
const db = (0,
|
|
16209
|
+
const db = (0, import_firestore48.getFirestore)(app);
|
|
15980
16210
|
const auth = (0, import_auth9.getAuth)(app);
|
|
15981
16211
|
const storage = (0, import_storage4.getStorage)(app);
|
|
15982
16212
|
const functions = (0, import_functions3.getFunctions)(app);
|
|
@@ -16018,7 +16248,7 @@ var getFirebaseFunctions = async () => {
|
|
|
16018
16248
|
};
|
|
16019
16249
|
|
|
16020
16250
|
// src/backoffice/services/brand.service.ts
|
|
16021
|
-
var
|
|
16251
|
+
var import_firestore49 = require("firebase/firestore");
|
|
16022
16252
|
|
|
16023
16253
|
// src/backoffice/types/brand.types.ts
|
|
16024
16254
|
var BRANDS_COLLECTION = "brands";
|
|
@@ -16029,7 +16259,7 @@ var BrandService = class extends BaseService {
|
|
|
16029
16259
|
* Gets reference to brands collection
|
|
16030
16260
|
*/
|
|
16031
16261
|
getBrandsRef() {
|
|
16032
|
-
return (0,
|
|
16262
|
+
return (0, import_firestore49.collection)(this.db, BRANDS_COLLECTION);
|
|
16033
16263
|
}
|
|
16034
16264
|
/**
|
|
16035
16265
|
* Creates a new brand
|
|
@@ -16038,23 +16268,78 @@ var BrandService = class extends BaseService {
|
|
|
16038
16268
|
const now = /* @__PURE__ */ new Date();
|
|
16039
16269
|
const newBrand = {
|
|
16040
16270
|
...brand,
|
|
16271
|
+
name_lowercase: brand.name.toLowerCase(),
|
|
16041
16272
|
createdAt: now,
|
|
16042
16273
|
updatedAt: now,
|
|
16043
16274
|
isActive: true
|
|
16044
16275
|
};
|
|
16045
|
-
const docRef = await (0,
|
|
16276
|
+
const docRef = await (0, import_firestore49.addDoc)(this.getBrandsRef(), newBrand);
|
|
16046
16277
|
return { id: docRef.id, ...newBrand };
|
|
16047
16278
|
}
|
|
16048
16279
|
/**
|
|
16049
|
-
* Gets
|
|
16280
|
+
* Gets a paginated list of active brands, optionally filtered by name.
|
|
16281
|
+
* @param rowsPerPage - The number of brands to fetch.
|
|
16282
|
+
* @param searchTerm - An optional string to filter brand names by (starts-with search).
|
|
16283
|
+
* @param lastVisible - An optional document snapshot to use as a cursor for pagination.
|
|
16284
|
+
*/
|
|
16285
|
+
async getAll(rowsPerPage, searchTerm, lastVisible) {
|
|
16286
|
+
const constraints = [
|
|
16287
|
+
(0, import_firestore49.where)("isActive", "==", true),
|
|
16288
|
+
(0, import_firestore49.orderBy)("name_lowercase")
|
|
16289
|
+
];
|
|
16290
|
+
if (searchTerm) {
|
|
16291
|
+
const lowercasedSearchTerm = searchTerm.toLowerCase();
|
|
16292
|
+
constraints.push((0, import_firestore49.where)("name_lowercase", ">=", lowercasedSearchTerm));
|
|
16293
|
+
constraints.push(
|
|
16294
|
+
(0, import_firestore49.where)("name_lowercase", "<=", lowercasedSearchTerm + "\uF8FF")
|
|
16295
|
+
);
|
|
16296
|
+
}
|
|
16297
|
+
if (lastVisible) {
|
|
16298
|
+
constraints.push((0, import_firestore49.startAfter)(lastVisible));
|
|
16299
|
+
}
|
|
16300
|
+
constraints.push((0, import_firestore49.limit)(rowsPerPage));
|
|
16301
|
+
const q = (0, import_firestore49.query)(this.getBrandsRef(), ...constraints);
|
|
16302
|
+
const snapshot = await (0, import_firestore49.getDocs)(q);
|
|
16303
|
+
const brands = snapshot.docs.map(
|
|
16304
|
+
(doc38) => ({
|
|
16305
|
+
id: doc38.id,
|
|
16306
|
+
...doc38.data()
|
|
16307
|
+
})
|
|
16308
|
+
);
|
|
16309
|
+
const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
|
|
16310
|
+
return { brands, lastVisible: newLastVisible };
|
|
16311
|
+
}
|
|
16312
|
+
/**
|
|
16313
|
+
* Gets the total count of active brands, optionally filtered by name.
|
|
16314
|
+
* @param searchTerm - An optional string to filter brand names by (starts-with search).
|
|
16315
|
+
*/
|
|
16316
|
+
async getBrandsCount(searchTerm) {
|
|
16317
|
+
const constraints = [(0, import_firestore49.where)("isActive", "==", true)];
|
|
16318
|
+
if (searchTerm) {
|
|
16319
|
+
const lowercasedSearchTerm = searchTerm.toLowerCase();
|
|
16320
|
+
constraints.push((0, import_firestore49.where)("name_lowercase", ">=", lowercasedSearchTerm));
|
|
16321
|
+
constraints.push(
|
|
16322
|
+
(0, import_firestore49.where)("name_lowercase", "<=", lowercasedSearchTerm + "\uF8FF")
|
|
16323
|
+
);
|
|
16324
|
+
}
|
|
16325
|
+
const q = (0, import_firestore49.query)(this.getBrandsRef(), ...constraints);
|
|
16326
|
+
const snapshot = await (0, import_firestore49.getCountFromServer)(q);
|
|
16327
|
+
return snapshot.data().count;
|
|
16328
|
+
}
|
|
16329
|
+
/**
|
|
16330
|
+
* Gets all active brands for filter dropdowns (not paginated).
|
|
16050
16331
|
*/
|
|
16051
|
-
async
|
|
16052
|
-
const q = (0,
|
|
16053
|
-
|
|
16332
|
+
async getAllForFilter() {
|
|
16333
|
+
const q = (0, import_firestore49.query)(
|
|
16334
|
+
this.getBrandsRef(),
|
|
16335
|
+
(0, import_firestore49.where)("isActive", "==", true),
|
|
16336
|
+
(0, import_firestore49.orderBy)("name")
|
|
16337
|
+
);
|
|
16338
|
+
const snapshot = await (0, import_firestore49.getDocs)(q);
|
|
16054
16339
|
return snapshot.docs.map(
|
|
16055
|
-
(
|
|
16056
|
-
id:
|
|
16057
|
-
...
|
|
16340
|
+
(doc38) => ({
|
|
16341
|
+
id: doc38.id,
|
|
16342
|
+
...doc38.data()
|
|
16058
16343
|
})
|
|
16059
16344
|
);
|
|
16060
16345
|
}
|
|
@@ -16066,8 +16351,11 @@ var BrandService = class extends BaseService {
|
|
|
16066
16351
|
...brand,
|
|
16067
16352
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16068
16353
|
};
|
|
16069
|
-
|
|
16070
|
-
|
|
16354
|
+
if (brand.name) {
|
|
16355
|
+
updateData.name_lowercase = brand.name.toLowerCase();
|
|
16356
|
+
}
|
|
16357
|
+
const docRef = (0, import_firestore49.doc)(this.getBrandsRef(), brandId);
|
|
16358
|
+
await (0, import_firestore49.updateDoc)(docRef, updateData);
|
|
16071
16359
|
return this.getById(brandId);
|
|
16072
16360
|
}
|
|
16073
16361
|
/**
|
|
@@ -16082,8 +16370,8 @@ var BrandService = class extends BaseService {
|
|
|
16082
16370
|
* Gets a brand by ID
|
|
16083
16371
|
*/
|
|
16084
16372
|
async getById(brandId) {
|
|
16085
|
-
const docRef = (0,
|
|
16086
|
-
const docSnap = await (0,
|
|
16373
|
+
const docRef = (0, import_firestore49.doc)(this.getBrandsRef(), brandId);
|
|
16374
|
+
const docSnap = await (0, import_firestore49.getDoc)(docRef);
|
|
16087
16375
|
if (!docSnap.exists()) return null;
|
|
16088
16376
|
return {
|
|
16089
16377
|
id: docSnap.id,
|
|
@@ -16093,7 +16381,7 @@ var BrandService = class extends BaseService {
|
|
|
16093
16381
|
};
|
|
16094
16382
|
|
|
16095
16383
|
// src/backoffice/services/category.service.ts
|
|
16096
|
-
var
|
|
16384
|
+
var import_firestore50 = require("firebase/firestore");
|
|
16097
16385
|
|
|
16098
16386
|
// src/backoffice/types/category.types.ts
|
|
16099
16387
|
var CATEGORIES_COLLECTION = "backoffice_categories";
|
|
@@ -16104,7 +16392,7 @@ var CategoryService = class extends BaseService {
|
|
|
16104
16392
|
* Referenca na Firestore kolekciju kategorija
|
|
16105
16393
|
*/
|
|
16106
16394
|
get categoriesRef() {
|
|
16107
|
-
return (0,
|
|
16395
|
+
return (0, import_firestore50.collection)(this.db, CATEGORIES_COLLECTION);
|
|
16108
16396
|
}
|
|
16109
16397
|
/**
|
|
16110
16398
|
* Kreira novu kategoriju u sistemu
|
|
@@ -16119,41 +16407,91 @@ var CategoryService = class extends BaseService {
|
|
|
16119
16407
|
updatedAt: now,
|
|
16120
16408
|
isActive: true
|
|
16121
16409
|
};
|
|
16122
|
-
const docRef = await (0,
|
|
16410
|
+
const docRef = await (0, import_firestore50.addDoc)(this.categoriesRef, newCategory);
|
|
16123
16411
|
return { id: docRef.id, ...newCategory };
|
|
16124
16412
|
}
|
|
16125
16413
|
/**
|
|
16126
|
-
*
|
|
16127
|
-
* @
|
|
16414
|
+
* Returns counts of categories for each family.
|
|
16415
|
+
* @param active - Whether to count active or inactive categories.
|
|
16416
|
+
* @returns A record mapping family to category count.
|
|
16128
16417
|
*/
|
|
16129
|
-
async
|
|
16130
|
-
const
|
|
16131
|
-
const
|
|
16418
|
+
async getCategoryCounts(active = true) {
|
|
16419
|
+
const counts = {};
|
|
16420
|
+
const families = Object.values(ProcedureFamily);
|
|
16421
|
+
for (const family of families) {
|
|
16422
|
+
const q = (0, import_firestore50.query)(
|
|
16423
|
+
this.categoriesRef,
|
|
16424
|
+
(0, import_firestore50.where)("family", "==", family),
|
|
16425
|
+
(0, import_firestore50.where)("isActive", "==", active)
|
|
16426
|
+
);
|
|
16427
|
+
const snapshot = await (0, import_firestore50.getCountFromServer)(q);
|
|
16428
|
+
counts[family] = snapshot.data().count;
|
|
16429
|
+
}
|
|
16430
|
+
return counts;
|
|
16431
|
+
}
|
|
16432
|
+
/**
|
|
16433
|
+
* Vraća sve kategorije za potrebe filtera (bez paginacije)
|
|
16434
|
+
* @returns Lista svih aktivnih kategorija
|
|
16435
|
+
*/
|
|
16436
|
+
async getAllForFilter() {
|
|
16437
|
+
const q = (0, import_firestore50.query)(this.categoriesRef, (0, import_firestore50.where)("isActive", "==", true));
|
|
16438
|
+
const snapshot = await (0, import_firestore50.getDocs)(q);
|
|
16132
16439
|
return snapshot.docs.map(
|
|
16133
|
-
(
|
|
16134
|
-
id:
|
|
16135
|
-
...
|
|
16440
|
+
(doc38) => ({
|
|
16441
|
+
id: doc38.id,
|
|
16442
|
+
...doc38.data()
|
|
16443
|
+
})
|
|
16444
|
+
);
|
|
16445
|
+
}
|
|
16446
|
+
/**
|
|
16447
|
+
* Vraća sve kategorije sa paginacijom
|
|
16448
|
+
* @param options - Pagination and filter options
|
|
16449
|
+
* @returns Lista kategorija i poslednji vidljiv dokument
|
|
16450
|
+
*/
|
|
16451
|
+
async getAll(options = {}) {
|
|
16452
|
+
const { active = true, limit: queryLimit = 10, lastVisible } = options;
|
|
16453
|
+
const constraints = [
|
|
16454
|
+
(0, import_firestore50.where)("isActive", "==", active),
|
|
16455
|
+
(0, import_firestore50.orderBy)("name"),
|
|
16456
|
+
queryLimit ? (0, import_firestore50.limit)(queryLimit) : void 0,
|
|
16457
|
+
lastVisible ? (0, import_firestore50.startAfter)(lastVisible) : void 0
|
|
16458
|
+
].filter((c) => !!c);
|
|
16459
|
+
const q = (0, import_firestore50.query)(this.categoriesRef, ...constraints);
|
|
16460
|
+
const snapshot = await (0, import_firestore50.getDocs)(q);
|
|
16461
|
+
const categories = snapshot.docs.map(
|
|
16462
|
+
(doc38) => ({
|
|
16463
|
+
id: doc38.id,
|
|
16464
|
+
...doc38.data()
|
|
16136
16465
|
})
|
|
16137
16466
|
);
|
|
16467
|
+
const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
|
|
16468
|
+
return { categories, lastVisible: newLastVisible };
|
|
16138
16469
|
}
|
|
16139
16470
|
/**
|
|
16140
|
-
* Vraća sve aktivne kategorije za određenu familiju procedura
|
|
16471
|
+
* Vraća sve aktivne kategorije za određenu familiju procedura sa paginacijom
|
|
16141
16472
|
* @param family - Familija procedura (aesthetics/surgery)
|
|
16473
|
+
* @param options - Pagination options
|
|
16142
16474
|
* @returns Lista kategorija koje pripadaju traženoj familiji
|
|
16143
16475
|
*/
|
|
16144
|
-
async getAllByFamily(family) {
|
|
16145
|
-
const
|
|
16146
|
-
|
|
16147
|
-
(0,
|
|
16148
|
-
(0,
|
|
16149
|
-
|
|
16150
|
-
|
|
16151
|
-
|
|
16152
|
-
|
|
16153
|
-
|
|
16154
|
-
|
|
16476
|
+
async getAllByFamily(family, options = {}) {
|
|
16477
|
+
const { active = true, limit: queryLimit = 10, lastVisible } = options;
|
|
16478
|
+
const constraints = [
|
|
16479
|
+
(0, import_firestore50.where)("family", "==", family),
|
|
16480
|
+
(0, import_firestore50.where)("isActive", "==", active),
|
|
16481
|
+
(0, import_firestore50.orderBy)("name"),
|
|
16482
|
+
queryLimit ? (0, import_firestore50.limit)(queryLimit) : void 0,
|
|
16483
|
+
lastVisible ? (0, import_firestore50.startAfter)(lastVisible) : void 0
|
|
16484
|
+
].filter((c) => !!c);
|
|
16485
|
+
const q = (0, import_firestore50.query)(this.categoriesRef, ...constraints);
|
|
16486
|
+
const snapshot = await (0, import_firestore50.getDocs)(q);
|
|
16487
|
+
const categories = snapshot.docs.map(
|
|
16488
|
+
(doc38) => ({
|
|
16489
|
+
id: doc38.id,
|
|
16490
|
+
...doc38.data()
|
|
16155
16491
|
})
|
|
16156
16492
|
);
|
|
16493
|
+
const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
|
|
16494
|
+
return { categories, lastVisible: newLastVisible };
|
|
16157
16495
|
}
|
|
16158
16496
|
/**
|
|
16159
16497
|
* Ažurira postojeću kategoriju
|
|
@@ -16166,8 +16504,8 @@ var CategoryService = class extends BaseService {
|
|
|
16166
16504
|
...category,
|
|
16167
16505
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16168
16506
|
};
|
|
16169
|
-
const docRef = (0,
|
|
16170
|
-
await (0,
|
|
16507
|
+
const docRef = (0, import_firestore50.doc)(this.categoriesRef, id);
|
|
16508
|
+
await (0, import_firestore50.updateDoc)(docRef, updateData);
|
|
16171
16509
|
return this.getById(id);
|
|
16172
16510
|
}
|
|
16173
16511
|
/**
|
|
@@ -16177,14 +16515,21 @@ var CategoryService = class extends BaseService {
|
|
|
16177
16515
|
async delete(id) {
|
|
16178
16516
|
await this.update(id, { isActive: false });
|
|
16179
16517
|
}
|
|
16518
|
+
/**
|
|
16519
|
+
* Reactivates a category by setting its isActive flag to true.
|
|
16520
|
+
* @param id - The ID of the category to reactivate.
|
|
16521
|
+
*/
|
|
16522
|
+
async reactivate(id) {
|
|
16523
|
+
await this.update(id, { isActive: true });
|
|
16524
|
+
}
|
|
16180
16525
|
/**
|
|
16181
16526
|
* Vraća kategoriju po ID-u
|
|
16182
16527
|
* @param id - ID tražene kategorije
|
|
16183
16528
|
* @returns Kategorija ili null ako ne postoji
|
|
16184
16529
|
*/
|
|
16185
16530
|
async getById(id) {
|
|
16186
|
-
const docRef = (0,
|
|
16187
|
-
const docSnap = await (0,
|
|
16531
|
+
const docRef = (0, import_firestore50.doc)(this.categoriesRef, id);
|
|
16532
|
+
const docSnap = await (0, import_firestore50.getDoc)(docRef);
|
|
16188
16533
|
if (!docSnap.exists()) return null;
|
|
16189
16534
|
return {
|
|
16190
16535
|
id: docSnap.id,
|
|
@@ -16194,7 +16539,7 @@ var CategoryService = class extends BaseService {
|
|
|
16194
16539
|
};
|
|
16195
16540
|
|
|
16196
16541
|
// src/backoffice/services/subcategory.service.ts
|
|
16197
|
-
var
|
|
16542
|
+
var import_firestore51 = require("firebase/firestore");
|
|
16198
16543
|
|
|
16199
16544
|
// src/backoffice/types/subcategory.types.ts
|
|
16200
16545
|
var SUBCATEGORIES_COLLECTION = "subcategories";
|
|
@@ -16206,7 +16551,7 @@ var SubcategoryService = class extends BaseService {
|
|
|
16206
16551
|
* @param categoryId - ID roditeljske kategorije
|
|
16207
16552
|
*/
|
|
16208
16553
|
getSubcategoriesRef(categoryId) {
|
|
16209
|
-
return (0,
|
|
16554
|
+
return (0, import_firestore51.collection)(
|
|
16210
16555
|
this.db,
|
|
16211
16556
|
CATEGORIES_COLLECTION,
|
|
16212
16557
|
categoryId,
|
|
@@ -16228,27 +16573,117 @@ var SubcategoryService = class extends BaseService {
|
|
|
16228
16573
|
updatedAt: now,
|
|
16229
16574
|
isActive: true
|
|
16230
16575
|
};
|
|
16231
|
-
const docRef = await (0,
|
|
16576
|
+
const docRef = await (0, import_firestore51.addDoc)(
|
|
16232
16577
|
this.getSubcategoriesRef(categoryId),
|
|
16233
16578
|
newSubcategory
|
|
16234
16579
|
);
|
|
16235
16580
|
return { id: docRef.id, ...newSubcategory };
|
|
16236
16581
|
}
|
|
16237
16582
|
/**
|
|
16238
|
-
*
|
|
16583
|
+
* Returns counts of subcategories for all categories.
|
|
16584
|
+
* @param active - Whether to count active or inactive subcategories.
|
|
16585
|
+
* @returns A record mapping category ID to subcategory count.
|
|
16586
|
+
*/
|
|
16587
|
+
async getSubcategoryCounts(active = true) {
|
|
16588
|
+
const categoriesRef = (0, import_firestore51.collection)(this.db, CATEGORIES_COLLECTION);
|
|
16589
|
+
const categoriesSnapshot = await (0, import_firestore51.getDocs)(categoriesRef);
|
|
16590
|
+
const counts = {};
|
|
16591
|
+
for (const categoryDoc of categoriesSnapshot.docs) {
|
|
16592
|
+
const categoryId = categoryDoc.id;
|
|
16593
|
+
const subcategoriesRef = this.getSubcategoriesRef(categoryId);
|
|
16594
|
+
const q = (0, import_firestore51.query)(subcategoriesRef, (0, import_firestore51.where)("isActive", "==", active));
|
|
16595
|
+
const snapshot = await (0, import_firestore51.getCountFromServer)(q);
|
|
16596
|
+
counts[categoryId] = snapshot.data().count;
|
|
16597
|
+
}
|
|
16598
|
+
return counts;
|
|
16599
|
+
}
|
|
16600
|
+
/**
|
|
16601
|
+
* Vraća sve aktivne podkategorije za određenu kategoriju sa paginacijom
|
|
16239
16602
|
* @param categoryId - ID kategorije čije podkategorije tražimo
|
|
16240
|
-
* @
|
|
16603
|
+
* @param options - Pagination options
|
|
16604
|
+
* @returns Lista aktivnih podkategorija i poslednji vidljiv dokument
|
|
16605
|
+
*/
|
|
16606
|
+
async getAllByCategoryId(categoryId, options = {}) {
|
|
16607
|
+
const { active = true, limit: queryLimit = 10, lastVisible } = options;
|
|
16608
|
+
const constraints = [
|
|
16609
|
+
(0, import_firestore51.where)("isActive", "==", active),
|
|
16610
|
+
(0, import_firestore51.orderBy)("name"),
|
|
16611
|
+
queryLimit ? (0, import_firestore51.limit)(queryLimit) : void 0,
|
|
16612
|
+
lastVisible ? (0, import_firestore51.startAfter)(lastVisible) : void 0
|
|
16613
|
+
].filter((c) => !!c);
|
|
16614
|
+
const q = (0, import_firestore51.query)(this.getSubcategoriesRef(categoryId), ...constraints);
|
|
16615
|
+
const querySnapshot = await (0, import_firestore51.getDocs)(q);
|
|
16616
|
+
const subcategories = querySnapshot.docs.map(
|
|
16617
|
+
(doc38) => ({
|
|
16618
|
+
id: doc38.id,
|
|
16619
|
+
...doc38.data()
|
|
16620
|
+
})
|
|
16621
|
+
);
|
|
16622
|
+
const newLastVisible = querySnapshot.docs[querySnapshot.docs.length - 1];
|
|
16623
|
+
return { subcategories, lastVisible: newLastVisible };
|
|
16624
|
+
}
|
|
16625
|
+
/**
|
|
16626
|
+
* Vraća sve podkategorije sa paginacijom koristeći collection group query.
|
|
16627
|
+
* NOTE: This query requires a composite index in Firestore on the 'subcategories' collection group.
|
|
16628
|
+
* The index should be on 'isActive' (ascending) and 'name' (ascending).
|
|
16629
|
+
* Firestore will provide a link to create this index in the console error if it's missing.
|
|
16630
|
+
* @param options - Pagination options
|
|
16631
|
+
* @returns Lista podkategorija i poslednji vidljiv dokument
|
|
16241
16632
|
*/
|
|
16242
|
-
async
|
|
16243
|
-
const
|
|
16633
|
+
async getAll(options = {}) {
|
|
16634
|
+
const { active = true, limit: queryLimit = 10, lastVisible } = options;
|
|
16635
|
+
const constraints = [
|
|
16636
|
+
(0, import_firestore51.where)("isActive", "==", active),
|
|
16637
|
+
(0, import_firestore51.orderBy)("name"),
|
|
16638
|
+
queryLimit ? (0, import_firestore51.limit)(queryLimit) : void 0,
|
|
16639
|
+
lastVisible ? (0, import_firestore51.startAfter)(lastVisible) : void 0
|
|
16640
|
+
].filter((c) => !!c);
|
|
16641
|
+
const q = (0, import_firestore51.query)(
|
|
16642
|
+
(0, import_firestore51.collectionGroup)(this.db, SUBCATEGORIES_COLLECTION),
|
|
16643
|
+
...constraints
|
|
16644
|
+
);
|
|
16645
|
+
const querySnapshot = await (0, import_firestore51.getDocs)(q);
|
|
16646
|
+
const subcategories = querySnapshot.docs.map(
|
|
16647
|
+
(doc38) => ({
|
|
16648
|
+
id: doc38.id,
|
|
16649
|
+
...doc38.data()
|
|
16650
|
+
})
|
|
16651
|
+
);
|
|
16652
|
+
const newLastVisible = querySnapshot.docs[querySnapshot.docs.length - 1];
|
|
16653
|
+
return { subcategories, lastVisible: newLastVisible };
|
|
16654
|
+
}
|
|
16655
|
+
/**
|
|
16656
|
+
* Vraća sve subkategorije za određenu kategoriju za potrebe filtera (bez paginacije)
|
|
16657
|
+
* @param categoryId - ID kategorije čije subkategorije tražimo
|
|
16658
|
+
* @returns Lista svih aktivnih subkategorija
|
|
16659
|
+
*/
|
|
16660
|
+
async getAllForFilterByCategoryId(categoryId) {
|
|
16661
|
+
const q = (0, import_firestore51.query)(
|
|
16244
16662
|
this.getSubcategoriesRef(categoryId),
|
|
16245
|
-
(0,
|
|
16663
|
+
(0, import_firestore51.where)("isActive", "==", true)
|
|
16246
16664
|
);
|
|
16247
|
-
const
|
|
16248
|
-
return
|
|
16249
|
-
(
|
|
16250
|
-
id:
|
|
16251
|
-
...
|
|
16665
|
+
const querySnapshot = await (0, import_firestore51.getDocs)(q);
|
|
16666
|
+
return querySnapshot.docs.map(
|
|
16667
|
+
(doc38) => ({
|
|
16668
|
+
id: doc38.id,
|
|
16669
|
+
...doc38.data()
|
|
16670
|
+
})
|
|
16671
|
+
);
|
|
16672
|
+
}
|
|
16673
|
+
/**
|
|
16674
|
+
* Vraća sve subkategorije za potrebe filtera (bez paginacije)
|
|
16675
|
+
* @returns Lista svih aktivnih subkategorija
|
|
16676
|
+
*/
|
|
16677
|
+
async getAllForFilter() {
|
|
16678
|
+
const q = (0, import_firestore51.query)(
|
|
16679
|
+
(0, import_firestore51.collectionGroup)(this.db, SUBCATEGORIES_COLLECTION),
|
|
16680
|
+
(0, import_firestore51.where)("isActive", "==", true)
|
|
16681
|
+
);
|
|
16682
|
+
const querySnapshot = await (0, import_firestore51.getDocs)(q);
|
|
16683
|
+
return querySnapshot.docs.map(
|
|
16684
|
+
(doc38) => ({
|
|
16685
|
+
id: doc38.id,
|
|
16686
|
+
...doc38.data()
|
|
16252
16687
|
})
|
|
16253
16688
|
);
|
|
16254
16689
|
}
|
|
@@ -16260,13 +16695,42 @@ var SubcategoryService = class extends BaseService {
|
|
|
16260
16695
|
* @returns Ažurirana podkategorija
|
|
16261
16696
|
*/
|
|
16262
16697
|
async update(categoryId, subcategoryId, subcategory) {
|
|
16263
|
-
const
|
|
16264
|
-
|
|
16265
|
-
|
|
16266
|
-
|
|
16267
|
-
|
|
16268
|
-
|
|
16269
|
-
|
|
16698
|
+
const newCategoryId = subcategory.categoryId;
|
|
16699
|
+
if (newCategoryId && newCategoryId !== categoryId) {
|
|
16700
|
+
const oldDocRef = (0, import_firestore51.doc)(
|
|
16701
|
+
this.getSubcategoriesRef(categoryId),
|
|
16702
|
+
subcategoryId
|
|
16703
|
+
);
|
|
16704
|
+
const docSnap = await (0, import_firestore51.getDoc)(oldDocRef);
|
|
16705
|
+
if (!docSnap.exists()) {
|
|
16706
|
+
throw new Error("Subcategory to update does not exist.");
|
|
16707
|
+
}
|
|
16708
|
+
const existingData = docSnap.data();
|
|
16709
|
+
const newData = {
|
|
16710
|
+
...existingData,
|
|
16711
|
+
...subcategory,
|
|
16712
|
+
categoryId: newCategoryId,
|
|
16713
|
+
// Ensure categoryId is updated
|
|
16714
|
+
createdAt: existingData.createdAt,
|
|
16715
|
+
// Preserve original creation date
|
|
16716
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
16717
|
+
};
|
|
16718
|
+
const newDocRef = (0, import_firestore51.doc)(
|
|
16719
|
+
this.getSubcategoriesRef(newCategoryId),
|
|
16720
|
+
subcategoryId
|
|
16721
|
+
);
|
|
16722
|
+
await (0, import_firestore51.setDoc)(newDocRef, newData);
|
|
16723
|
+
await (0, import_firestore51.deleteDoc)(oldDocRef);
|
|
16724
|
+
return { id: subcategoryId, ...newData };
|
|
16725
|
+
} else {
|
|
16726
|
+
const updateData = {
|
|
16727
|
+
...subcategory,
|
|
16728
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
16729
|
+
};
|
|
16730
|
+
const docRef = (0, import_firestore51.doc)(this.getSubcategoriesRef(categoryId), subcategoryId);
|
|
16731
|
+
await (0, import_firestore51.updateDoc)(docRef, updateData);
|
|
16732
|
+
return this.getById(categoryId, subcategoryId);
|
|
16733
|
+
}
|
|
16270
16734
|
}
|
|
16271
16735
|
/**
|
|
16272
16736
|
* Soft delete podkategorije (postavlja isActive na false)
|
|
@@ -16276,6 +16740,14 @@ var SubcategoryService = class extends BaseService {
|
|
|
16276
16740
|
async delete(categoryId, subcategoryId) {
|
|
16277
16741
|
await this.update(categoryId, subcategoryId, { isActive: false });
|
|
16278
16742
|
}
|
|
16743
|
+
/**
|
|
16744
|
+
* Reactivates a subcategory by setting its isActive flag to true.
|
|
16745
|
+
* @param categoryId - The ID of the category to which the subcategory belongs.
|
|
16746
|
+
* @param subcategoryId - The ID of the subcategory to reactivate.
|
|
16747
|
+
*/
|
|
16748
|
+
async reactivate(categoryId, subcategoryId) {
|
|
16749
|
+
await this.update(categoryId, subcategoryId, { isActive: true });
|
|
16750
|
+
}
|
|
16279
16751
|
/**
|
|
16280
16752
|
* Vraća podkategoriju po ID-u
|
|
16281
16753
|
* @param categoryId - ID kategorije kojoj pripada podkategorija
|
|
@@ -16283,8 +16755,8 @@ var SubcategoryService = class extends BaseService {
|
|
|
16283
16755
|
* @returns Podkategorija ili null ako ne postoji
|
|
16284
16756
|
*/
|
|
16285
16757
|
async getById(categoryId, subcategoryId) {
|
|
16286
|
-
const docRef = (0,
|
|
16287
|
-
const docSnap = await (0,
|
|
16758
|
+
const docRef = (0, import_firestore51.doc)(this.getSubcategoriesRef(categoryId), subcategoryId);
|
|
16759
|
+
const docSnap = await (0, import_firestore51.getDoc)(docRef);
|
|
16288
16760
|
if (!docSnap.exists()) return null;
|
|
16289
16761
|
return {
|
|
16290
16762
|
id: docSnap.id,
|
|
@@ -16294,145 +16766,193 @@ var SubcategoryService = class extends BaseService {
|
|
|
16294
16766
|
};
|
|
16295
16767
|
|
|
16296
16768
|
// src/backoffice/services/technology.service.ts
|
|
16297
|
-
var
|
|
16769
|
+
var import_firestore52 = require("firebase/firestore");
|
|
16298
16770
|
var DEFAULT_CERTIFICATION_REQUIREMENT = {
|
|
16299
16771
|
minimumLevel: "aesthetician" /* AESTHETICIAN */,
|
|
16300
16772
|
requiredSpecialties: []
|
|
16301
16773
|
};
|
|
16302
16774
|
var TechnologyService = class extends BaseService {
|
|
16303
16775
|
/**
|
|
16304
|
-
*
|
|
16776
|
+
* Reference to the Firestore collection of technologies.
|
|
16305
16777
|
*/
|
|
16306
|
-
|
|
16307
|
-
return (0,
|
|
16778
|
+
get technologiesRef() {
|
|
16779
|
+
return (0, import_firestore52.collection)(this.db, TECHNOLOGIES_COLLECTION);
|
|
16308
16780
|
}
|
|
16309
16781
|
/**
|
|
16310
|
-
*
|
|
16311
|
-
* @param technology -
|
|
16312
|
-
* @returns
|
|
16782
|
+
* Creates a new technology.
|
|
16783
|
+
* @param technology - Data for the new technology.
|
|
16784
|
+
* @returns The created technology with its generated ID.
|
|
16313
16785
|
*/
|
|
16314
16786
|
async create(technology) {
|
|
16315
16787
|
const now = /* @__PURE__ */ new Date();
|
|
16316
16788
|
const newTechnology = {
|
|
16317
|
-
|
|
16318
|
-
|
|
16319
|
-
|
|
16320
|
-
|
|
16321
|
-
|
|
16322
|
-
|
|
16323
|
-
post: []
|
|
16324
|
-
},
|
|
16789
|
+
name: technology.name,
|
|
16790
|
+
description: technology.description,
|
|
16791
|
+
family: technology.family,
|
|
16792
|
+
categoryId: technology.categoryId,
|
|
16793
|
+
subcategoryId: technology.subcategoryId,
|
|
16794
|
+
requirements: technology.requirements || { pre: [], post: [] },
|
|
16325
16795
|
blockingConditions: technology.blockingConditions || [],
|
|
16326
16796
|
contraindications: technology.contraindications || [],
|
|
16327
16797
|
benefits: technology.benefits || [],
|
|
16328
|
-
certificationRequirement: technology.certificationRequirement || DEFAULT_CERTIFICATION_REQUIREMENT
|
|
16798
|
+
certificationRequirement: technology.certificationRequirement || DEFAULT_CERTIFICATION_REQUIREMENT,
|
|
16799
|
+
documentationTemplates: technology.documentationTemplates || [],
|
|
16800
|
+
isActive: true,
|
|
16801
|
+
createdAt: now,
|
|
16802
|
+
updatedAt: now
|
|
16329
16803
|
};
|
|
16330
|
-
|
|
16804
|
+
if (technology.technicalDetails) {
|
|
16805
|
+
newTechnology.technicalDetails = technology.technicalDetails;
|
|
16806
|
+
}
|
|
16807
|
+
const docRef = await (0, import_firestore52.addDoc)(this.technologiesRef, newTechnology);
|
|
16331
16808
|
return { id: docRef.id, ...newTechnology };
|
|
16332
16809
|
}
|
|
16333
16810
|
/**
|
|
16334
|
-
*
|
|
16335
|
-
* @
|
|
16811
|
+
* Returns counts of technologies for each subcategory.
|
|
16812
|
+
* @param active - Whether to count active or inactive technologies.
|
|
16813
|
+
* @returns A record mapping subcategory ID to technology count.
|
|
16336
16814
|
*/
|
|
16337
|
-
async
|
|
16338
|
-
const q = (0,
|
|
16339
|
-
const snapshot = await (0,
|
|
16340
|
-
|
|
16341
|
-
|
|
16342
|
-
|
|
16343
|
-
|
|
16344
|
-
|
|
16345
|
-
|
|
16815
|
+
async getTechnologyCounts(active = true) {
|
|
16816
|
+
const q = (0, import_firestore52.query)(this.technologiesRef, (0, import_firestore52.where)("isActive", "==", active));
|
|
16817
|
+
const snapshot = await (0, import_firestore52.getDocs)(q);
|
|
16818
|
+
const counts = {};
|
|
16819
|
+
snapshot.docs.forEach((doc38) => {
|
|
16820
|
+
const tech = doc38.data();
|
|
16821
|
+
counts[tech.subcategoryId] = (counts[tech.subcategoryId] || 0) + 1;
|
|
16822
|
+
});
|
|
16823
|
+
return counts;
|
|
16346
16824
|
}
|
|
16347
16825
|
/**
|
|
16348
|
-
*
|
|
16349
|
-
* @param
|
|
16350
|
-
* @returns
|
|
16826
|
+
* Returns counts of technologies for each category.
|
|
16827
|
+
* @param active - Whether to count active or inactive technologies.
|
|
16828
|
+
* @returns A record mapping category ID to technology count.
|
|
16351
16829
|
*/
|
|
16352
|
-
async
|
|
16353
|
-
const q = (0,
|
|
16354
|
-
|
|
16355
|
-
|
|
16356
|
-
|
|
16357
|
-
|
|
16358
|
-
|
|
16359
|
-
|
|
16360
|
-
|
|
16361
|
-
|
|
16362
|
-
|
|
16830
|
+
async getTechnologyCountsByCategory(active = true) {
|
|
16831
|
+
const q = (0, import_firestore52.query)(this.technologiesRef, (0, import_firestore52.where)("isActive", "==", active));
|
|
16832
|
+
const snapshot = await (0, import_firestore52.getDocs)(q);
|
|
16833
|
+
const counts = {};
|
|
16834
|
+
snapshot.docs.forEach((doc38) => {
|
|
16835
|
+
const tech = doc38.data();
|
|
16836
|
+
counts[tech.categoryId] = (counts[tech.categoryId] || 0) + 1;
|
|
16837
|
+
});
|
|
16838
|
+
return counts;
|
|
16839
|
+
}
|
|
16840
|
+
/**
|
|
16841
|
+
* Returns all technologies with pagination.
|
|
16842
|
+
* @param options - Pagination and filter options.
|
|
16843
|
+
* @returns A list of technologies and the last visible document.
|
|
16844
|
+
*/
|
|
16845
|
+
async getAll(options = {}) {
|
|
16846
|
+
const { active = true, limit: queryLimit = 10, lastVisible } = options;
|
|
16847
|
+
const constraints = [
|
|
16848
|
+
(0, import_firestore52.where)("isActive", "==", active),
|
|
16849
|
+
(0, import_firestore52.orderBy)("name"),
|
|
16850
|
+
queryLimit ? (0, import_firestore52.limit)(queryLimit) : void 0,
|
|
16851
|
+
lastVisible ? (0, import_firestore52.startAfter)(lastVisible) : void 0
|
|
16852
|
+
].filter((c) => !!c);
|
|
16853
|
+
const q = (0, import_firestore52.query)(this.technologiesRef, ...constraints);
|
|
16854
|
+
const snapshot = await (0, import_firestore52.getDocs)(q);
|
|
16855
|
+
const technologies = snapshot.docs.map(
|
|
16856
|
+
(doc38) => ({
|
|
16857
|
+
id: doc38.id,
|
|
16858
|
+
...doc38.data()
|
|
16363
16859
|
})
|
|
16364
16860
|
);
|
|
16861
|
+
const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
|
|
16862
|
+
return { technologies, lastVisible: newLastVisible };
|
|
16365
16863
|
}
|
|
16366
16864
|
/**
|
|
16367
|
-
*
|
|
16368
|
-
* @param categoryId - ID
|
|
16369
|
-
* @
|
|
16865
|
+
* Returns all technologies for a specific category with pagination.
|
|
16866
|
+
* @param categoryId - The ID of the category.
|
|
16867
|
+
* @param options - Pagination options.
|
|
16868
|
+
* @returns A list of technologies for the specified category.
|
|
16370
16869
|
*/
|
|
16371
|
-
async getAllByCategoryId(categoryId) {
|
|
16372
|
-
const
|
|
16373
|
-
|
|
16374
|
-
(0,
|
|
16375
|
-
(0,
|
|
16376
|
-
|
|
16377
|
-
|
|
16378
|
-
|
|
16379
|
-
|
|
16380
|
-
|
|
16381
|
-
|
|
16870
|
+
async getAllByCategoryId(categoryId, options = {}) {
|
|
16871
|
+
const { active = true, limit: queryLimit = 10, lastVisible } = options;
|
|
16872
|
+
const constraints = [
|
|
16873
|
+
(0, import_firestore52.where)("categoryId", "==", categoryId),
|
|
16874
|
+
(0, import_firestore52.where)("isActive", "==", active),
|
|
16875
|
+
(0, import_firestore52.orderBy)("name"),
|
|
16876
|
+
queryLimit ? (0, import_firestore52.limit)(queryLimit) : void 0,
|
|
16877
|
+
lastVisible ? (0, import_firestore52.startAfter)(lastVisible) : void 0
|
|
16878
|
+
].filter((c) => !!c);
|
|
16879
|
+
const q = (0, import_firestore52.query)(this.technologiesRef, ...constraints);
|
|
16880
|
+
const snapshot = await (0, import_firestore52.getDocs)(q);
|
|
16881
|
+
const technologies = snapshot.docs.map(
|
|
16882
|
+
(doc38) => ({
|
|
16883
|
+
id: doc38.id,
|
|
16884
|
+
...doc38.data()
|
|
16382
16885
|
})
|
|
16383
16886
|
);
|
|
16887
|
+
const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
|
|
16888
|
+
return { technologies, lastVisible: newLastVisible };
|
|
16384
16889
|
}
|
|
16385
16890
|
/**
|
|
16386
|
-
*
|
|
16387
|
-
* @param subcategoryId - ID
|
|
16388
|
-
* @
|
|
16891
|
+
* Returns all technologies for a specific subcategory with pagination.
|
|
16892
|
+
* @param subcategoryId - The ID of the subcategory.
|
|
16893
|
+
* @param options - Pagination options.
|
|
16894
|
+
* @returns A list of technologies for the specified subcategory.
|
|
16389
16895
|
*/
|
|
16390
|
-
async getAllBySubcategoryId(subcategoryId) {
|
|
16391
|
-
const
|
|
16392
|
-
|
|
16393
|
-
(0,
|
|
16394
|
-
(0,
|
|
16395
|
-
|
|
16396
|
-
|
|
16397
|
-
|
|
16398
|
-
|
|
16399
|
-
|
|
16400
|
-
|
|
16896
|
+
async getAllBySubcategoryId(subcategoryId, options = {}) {
|
|
16897
|
+
const { active = true, limit: queryLimit = 10, lastVisible } = options;
|
|
16898
|
+
const constraints = [
|
|
16899
|
+
(0, import_firestore52.where)("subcategoryId", "==", subcategoryId),
|
|
16900
|
+
(0, import_firestore52.where)("isActive", "==", active),
|
|
16901
|
+
(0, import_firestore52.orderBy)("name"),
|
|
16902
|
+
queryLimit ? (0, import_firestore52.limit)(queryLimit) : void 0,
|
|
16903
|
+
lastVisible ? (0, import_firestore52.startAfter)(lastVisible) : void 0
|
|
16904
|
+
].filter((c) => !!c);
|
|
16905
|
+
const q = (0, import_firestore52.query)(this.technologiesRef, ...constraints);
|
|
16906
|
+
const snapshot = await (0, import_firestore52.getDocs)(q);
|
|
16907
|
+
const technologies = snapshot.docs.map(
|
|
16908
|
+
(doc38) => ({
|
|
16909
|
+
id: doc38.id,
|
|
16910
|
+
...doc38.data()
|
|
16401
16911
|
})
|
|
16402
16912
|
);
|
|
16913
|
+
const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
|
|
16914
|
+
return { technologies, lastVisible: newLastVisible };
|
|
16403
16915
|
}
|
|
16404
16916
|
/**
|
|
16405
|
-
*
|
|
16406
|
-
* @param
|
|
16407
|
-
* @param technology -
|
|
16408
|
-
* @returns
|
|
16917
|
+
* Updates an existing technology.
|
|
16918
|
+
* @param id - The ID of the technology to update.
|
|
16919
|
+
* @param technology - New data for the technology.
|
|
16920
|
+
* @returns The updated technology.
|
|
16409
16921
|
*/
|
|
16410
|
-
async update(
|
|
16411
|
-
const updateData = {
|
|
16412
|
-
|
|
16413
|
-
|
|
16414
|
-
|
|
16415
|
-
|
|
16416
|
-
|
|
16417
|
-
|
|
16922
|
+
async update(id, technology) {
|
|
16923
|
+
const updateData = { ...technology };
|
|
16924
|
+
Object.keys(updateData).forEach((key) => {
|
|
16925
|
+
if (updateData[key] === void 0) {
|
|
16926
|
+
delete updateData[key];
|
|
16927
|
+
}
|
|
16928
|
+
});
|
|
16929
|
+
updateData.updatedAt = /* @__PURE__ */ new Date();
|
|
16930
|
+
const docRef = (0, import_firestore52.doc)(this.technologiesRef, id);
|
|
16931
|
+
await (0, import_firestore52.updateDoc)(docRef, updateData);
|
|
16932
|
+
return this.getById(id);
|
|
16418
16933
|
}
|
|
16419
16934
|
/**
|
|
16420
|
-
* Soft
|
|
16421
|
-
* @param
|
|
16935
|
+
* Soft deletes a technology.
|
|
16936
|
+
* @param id - The ID of the technology to delete.
|
|
16422
16937
|
*/
|
|
16423
|
-
async delete(
|
|
16424
|
-
await this.update(
|
|
16425
|
-
isActive: false
|
|
16426
|
-
});
|
|
16938
|
+
async delete(id) {
|
|
16939
|
+
await this.update(id, { isActive: false });
|
|
16427
16940
|
}
|
|
16428
16941
|
/**
|
|
16429
|
-
*
|
|
16430
|
-
* @param
|
|
16431
|
-
* @returns Tehnologija ili null ako ne postoji
|
|
16942
|
+
* Reactivates a technology.
|
|
16943
|
+
* @param id - The ID of the technology to reactivate.
|
|
16432
16944
|
*/
|
|
16433
|
-
async
|
|
16434
|
-
|
|
16435
|
-
|
|
16945
|
+
async reactivate(id) {
|
|
16946
|
+
await this.update(id, { isActive: true });
|
|
16947
|
+
}
|
|
16948
|
+
/**
|
|
16949
|
+
* Returns a technology by its ID.
|
|
16950
|
+
* @param id - The ID of the requested technology.
|
|
16951
|
+
* @returns The technology or null if it doesn't exist.
|
|
16952
|
+
*/
|
|
16953
|
+
async getById(id) {
|
|
16954
|
+
const docRef = (0, import_firestore52.doc)(this.technologiesRef, id);
|
|
16955
|
+
const docSnap = await (0, import_firestore52.getDoc)(docRef);
|
|
16436
16956
|
if (!docSnap.exists()) return null;
|
|
16437
16957
|
return {
|
|
16438
16958
|
id: docSnap.id,
|
|
@@ -16446,10 +16966,10 @@ var TechnologyService = class extends BaseService {
|
|
|
16446
16966
|
* @returns Ažurirana tehnologija sa novim zahtevom
|
|
16447
16967
|
*/
|
|
16448
16968
|
async addRequirement(technologyId, requirement) {
|
|
16449
|
-
const docRef = (0,
|
|
16969
|
+
const docRef = (0, import_firestore52.doc)(this.technologiesRef, technologyId);
|
|
16450
16970
|
const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
|
|
16451
|
-
await (0,
|
|
16452
|
-
[requirementType]: (0,
|
|
16971
|
+
await (0, import_firestore52.updateDoc)(docRef, {
|
|
16972
|
+
[requirementType]: (0, import_firestore52.arrayUnion)(requirement),
|
|
16453
16973
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16454
16974
|
});
|
|
16455
16975
|
return this.getById(technologyId);
|
|
@@ -16461,10 +16981,10 @@ var TechnologyService = class extends BaseService {
|
|
|
16461
16981
|
* @returns Ažurirana tehnologija bez uklonjenog zahteva
|
|
16462
16982
|
*/
|
|
16463
16983
|
async removeRequirement(technologyId, requirement) {
|
|
16464
|
-
const docRef = (0,
|
|
16984
|
+
const docRef = (0, import_firestore52.doc)(this.technologiesRef, technologyId);
|
|
16465
16985
|
const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
|
|
16466
|
-
await (0,
|
|
16467
|
-
[requirementType]: (0,
|
|
16986
|
+
await (0, import_firestore52.updateDoc)(docRef, {
|
|
16987
|
+
[requirementType]: (0, import_firestore52.arrayRemove)(requirement),
|
|
16468
16988
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16469
16989
|
});
|
|
16470
16990
|
return this.getById(technologyId);
|
|
@@ -16501,9 +17021,9 @@ var TechnologyService = class extends BaseService {
|
|
|
16501
17021
|
* @returns Ažurirana tehnologija
|
|
16502
17022
|
*/
|
|
16503
17023
|
async addBlockingCondition(technologyId, condition) {
|
|
16504
|
-
const docRef = (0,
|
|
16505
|
-
await (0,
|
|
16506
|
-
blockingConditions: (0,
|
|
17024
|
+
const docRef = (0, import_firestore52.doc)(this.technologiesRef, technologyId);
|
|
17025
|
+
await (0, import_firestore52.updateDoc)(docRef, {
|
|
17026
|
+
blockingConditions: (0, import_firestore52.arrayUnion)(condition),
|
|
16507
17027
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16508
17028
|
});
|
|
16509
17029
|
return this.getById(technologyId);
|
|
@@ -16515,9 +17035,9 @@ var TechnologyService = class extends BaseService {
|
|
|
16515
17035
|
* @returns Ažurirana tehnologija
|
|
16516
17036
|
*/
|
|
16517
17037
|
async removeBlockingCondition(technologyId, condition) {
|
|
16518
|
-
const docRef = (0,
|
|
16519
|
-
await (0,
|
|
16520
|
-
blockingConditions: (0,
|
|
17038
|
+
const docRef = (0, import_firestore52.doc)(this.technologiesRef, technologyId);
|
|
17039
|
+
await (0, import_firestore52.updateDoc)(docRef, {
|
|
17040
|
+
blockingConditions: (0, import_firestore52.arrayRemove)(condition),
|
|
16521
17041
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16522
17042
|
});
|
|
16523
17043
|
return this.getById(technologyId);
|
|
@@ -16529,9 +17049,17 @@ var TechnologyService = class extends BaseService {
|
|
|
16529
17049
|
* @returns Ažurirana tehnologija
|
|
16530
17050
|
*/
|
|
16531
17051
|
async addContraindication(technologyId, contraindication) {
|
|
16532
|
-
const docRef = (0,
|
|
16533
|
-
await (
|
|
16534
|
-
|
|
17052
|
+
const docRef = (0, import_firestore52.doc)(this.technologiesRef, technologyId);
|
|
17053
|
+
const technology = await this.getById(technologyId);
|
|
17054
|
+
if (!technology) {
|
|
17055
|
+
throw new Error(`Technology with id ${technologyId} not found`);
|
|
17056
|
+
}
|
|
17057
|
+
const existingContraindications = technology.contraindications || [];
|
|
17058
|
+
if (existingContraindications.some((c) => c.id === contraindication.id)) {
|
|
17059
|
+
return technology;
|
|
17060
|
+
}
|
|
17061
|
+
await (0, import_firestore52.updateDoc)(docRef, {
|
|
17062
|
+
contraindications: [...existingContraindications, contraindication],
|
|
16535
17063
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16536
17064
|
});
|
|
16537
17065
|
return this.getById(technologyId);
|
|
@@ -16543,9 +17071,45 @@ var TechnologyService = class extends BaseService {
|
|
|
16543
17071
|
* @returns Ažurirana tehnologija
|
|
16544
17072
|
*/
|
|
16545
17073
|
async removeContraindication(technologyId, contraindication) {
|
|
16546
|
-
const docRef = (0,
|
|
16547
|
-
await (
|
|
16548
|
-
|
|
17074
|
+
const docRef = (0, import_firestore52.doc)(this.technologiesRef, technologyId);
|
|
17075
|
+
const technology = await this.getById(technologyId);
|
|
17076
|
+
if (!technology) {
|
|
17077
|
+
throw new Error(`Technology with id ${technologyId} not found`);
|
|
17078
|
+
}
|
|
17079
|
+
const updatedContraindications = (technology.contraindications || []).filter((c) => c.id !== contraindication.id);
|
|
17080
|
+
await (0, import_firestore52.updateDoc)(docRef, {
|
|
17081
|
+
contraindications: updatedContraindications,
|
|
17082
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
17083
|
+
});
|
|
17084
|
+
return this.getById(technologyId);
|
|
17085
|
+
}
|
|
17086
|
+
/**
|
|
17087
|
+
* Updates an existing contraindication in a technology's list.
|
|
17088
|
+
* If the contraindication does not exist, it will not be added.
|
|
17089
|
+
* @param technologyId - ID of the technology
|
|
17090
|
+
* @param contraindication - The updated contraindication object
|
|
17091
|
+
* @returns The updated technology
|
|
17092
|
+
*/
|
|
17093
|
+
async updateContraindication(technologyId, contraindication) {
|
|
17094
|
+
const docRef = (0, import_firestore52.doc)(this.technologiesRef, technologyId);
|
|
17095
|
+
const technology = await this.getById(technologyId);
|
|
17096
|
+
if (!technology) {
|
|
17097
|
+
throw new Error(`Technology with id ${technologyId} not found`);
|
|
17098
|
+
}
|
|
17099
|
+
const contraindications = technology.contraindications || [];
|
|
17100
|
+
const index = contraindications.findIndex(
|
|
17101
|
+
(c) => c.id === contraindication.id
|
|
17102
|
+
);
|
|
17103
|
+
if (index === -1) {
|
|
17104
|
+
console.warn(
|
|
17105
|
+
`Contraindication with id ${contraindication.id} not found for technology ${technologyId}. No update performed.`
|
|
17106
|
+
);
|
|
17107
|
+
return technology;
|
|
17108
|
+
}
|
|
17109
|
+
const updatedContraindications = [...contraindications];
|
|
17110
|
+
updatedContraindications[index] = contraindication;
|
|
17111
|
+
await (0, import_firestore52.updateDoc)(docRef, {
|
|
17112
|
+
contraindications: updatedContraindications,
|
|
16549
17113
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16550
17114
|
});
|
|
16551
17115
|
return this.getById(technologyId);
|
|
@@ -16557,9 +17121,17 @@ var TechnologyService = class extends BaseService {
|
|
|
16557
17121
|
* @returns Ažurirana tehnologija
|
|
16558
17122
|
*/
|
|
16559
17123
|
async addBenefit(technologyId, benefit) {
|
|
16560
|
-
const docRef = (0,
|
|
16561
|
-
await (
|
|
16562
|
-
|
|
17124
|
+
const docRef = (0, import_firestore52.doc)(this.technologiesRef, technologyId);
|
|
17125
|
+
const technology = await this.getById(technologyId);
|
|
17126
|
+
if (!technology) {
|
|
17127
|
+
throw new Error(`Technology with id ${technologyId} not found`);
|
|
17128
|
+
}
|
|
17129
|
+
const existingBenefits = technology.benefits || [];
|
|
17130
|
+
if (existingBenefits.some((b) => b.id === benefit.id)) {
|
|
17131
|
+
return technology;
|
|
17132
|
+
}
|
|
17133
|
+
await (0, import_firestore52.updateDoc)(docRef, {
|
|
17134
|
+
benefits: [...existingBenefits, benefit],
|
|
16563
17135
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16564
17136
|
});
|
|
16565
17137
|
return this.getById(technologyId);
|
|
@@ -16571,9 +17143,45 @@ var TechnologyService = class extends BaseService {
|
|
|
16571
17143
|
* @returns Ažurirana tehnologija
|
|
16572
17144
|
*/
|
|
16573
17145
|
async removeBenefit(technologyId, benefit) {
|
|
16574
|
-
const docRef = (0,
|
|
16575
|
-
await (
|
|
16576
|
-
|
|
17146
|
+
const docRef = (0, import_firestore52.doc)(this.technologiesRef, technologyId);
|
|
17147
|
+
const technology = await this.getById(technologyId);
|
|
17148
|
+
if (!technology) {
|
|
17149
|
+
throw new Error(`Technology with id ${technologyId} not found`);
|
|
17150
|
+
}
|
|
17151
|
+
const updatedBenefits = (technology.benefits || []).filter(
|
|
17152
|
+
(b) => b.id !== benefit.id
|
|
17153
|
+
);
|
|
17154
|
+
await (0, import_firestore52.updateDoc)(docRef, {
|
|
17155
|
+
benefits: updatedBenefits,
|
|
17156
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
17157
|
+
});
|
|
17158
|
+
return this.getById(technologyId);
|
|
17159
|
+
}
|
|
17160
|
+
/**
|
|
17161
|
+
* Updates an existing benefit in a technology's list.
|
|
17162
|
+
* If the benefit does not exist, it will not be added.
|
|
17163
|
+
* @param technologyId - ID of the technology
|
|
17164
|
+
* @param benefit - The updated benefit object
|
|
17165
|
+
* @returns The updated technology
|
|
17166
|
+
*/
|
|
17167
|
+
async updateBenefit(technologyId, benefit) {
|
|
17168
|
+
const docRef = (0, import_firestore52.doc)(this.technologiesRef, technologyId);
|
|
17169
|
+
const technology = await this.getById(technologyId);
|
|
17170
|
+
if (!technology) {
|
|
17171
|
+
throw new Error(`Technology with id ${technologyId} not found`);
|
|
17172
|
+
}
|
|
17173
|
+
const benefits = technology.benefits || [];
|
|
17174
|
+
const index = benefits.findIndex((b) => b.id === benefit.id);
|
|
17175
|
+
if (index === -1) {
|
|
17176
|
+
console.warn(
|
|
17177
|
+
`Benefit with id ${benefit.id} not found for technology ${technologyId}. No update performed.`
|
|
17178
|
+
);
|
|
17179
|
+
return technology;
|
|
17180
|
+
}
|
|
17181
|
+
const updatedBenefits = [...benefits];
|
|
17182
|
+
updatedBenefits[index] = benefit;
|
|
17183
|
+
await (0, import_firestore52.updateDoc)(docRef, {
|
|
17184
|
+
benefits: updatedBenefits,
|
|
16577
17185
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16578
17186
|
});
|
|
16579
17187
|
return this.getById(technologyId);
|
|
@@ -16612,8 +17220,8 @@ var TechnologyService = class extends BaseService {
|
|
|
16612
17220
|
* @returns Ažurirana tehnologija
|
|
16613
17221
|
*/
|
|
16614
17222
|
async updateCertificationRequirement(technologyId, certificationRequirement) {
|
|
16615
|
-
const docRef = (0,
|
|
16616
|
-
await (0,
|
|
17223
|
+
const docRef = (0, import_firestore52.doc)(this.technologiesRef, technologyId);
|
|
17224
|
+
await (0, import_firestore52.updateDoc)(docRef, {
|
|
16617
17225
|
certificationRequirement,
|
|
16618
17226
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16619
17227
|
});
|
|
@@ -16690,7 +17298,7 @@ var TechnologyService = class extends BaseService {
|
|
|
16690
17298
|
*/
|
|
16691
17299
|
async getAllowedTechnologies(practitioner) {
|
|
16692
17300
|
const allTechnologies = await this.getAll();
|
|
16693
|
-
const allowedTechnologies = allTechnologies.filter(
|
|
17301
|
+
const allowedTechnologies = allTechnologies.technologies.filter(
|
|
16694
17302
|
(technology) => this.validateCertification(
|
|
16695
17303
|
technology.certificationRequirement,
|
|
16696
17304
|
practitioner.certification
|
|
@@ -16710,10 +17318,48 @@ var TechnologyService = class extends BaseService {
|
|
|
16710
17318
|
subcategories
|
|
16711
17319
|
};
|
|
16712
17320
|
}
|
|
17321
|
+
/**
|
|
17322
|
+
* Gets all active technologies for a subcategory for filter dropdowns.
|
|
17323
|
+
* @param categoryId - The ID of the parent category.
|
|
17324
|
+
* @param subcategoryId - The ID of the subcategory.
|
|
17325
|
+
*/
|
|
17326
|
+
async getAllForFilterBySubcategoryId(categoryId, subcategoryId) {
|
|
17327
|
+
const q = (0, import_firestore52.query)(
|
|
17328
|
+
(0, import_firestore52.collection)(this.db, TECHNOLOGIES_COLLECTION),
|
|
17329
|
+
(0, import_firestore52.where)("isActive", "==", true),
|
|
17330
|
+
(0, import_firestore52.where)("categoryId", "==", categoryId),
|
|
17331
|
+
(0, import_firestore52.where)("subcategoryId", "==", subcategoryId),
|
|
17332
|
+
(0, import_firestore52.orderBy)("name")
|
|
17333
|
+
);
|
|
17334
|
+
const snapshot = await (0, import_firestore52.getDocs)(q);
|
|
17335
|
+
return snapshot.docs.map(
|
|
17336
|
+
(doc38) => ({
|
|
17337
|
+
id: doc38.id,
|
|
17338
|
+
...doc38.data()
|
|
17339
|
+
})
|
|
17340
|
+
);
|
|
17341
|
+
}
|
|
17342
|
+
/**
|
|
17343
|
+
* Gets all active technologies for filter dropdowns.
|
|
17344
|
+
*/
|
|
17345
|
+
async getAllForFilter() {
|
|
17346
|
+
const q = (0, import_firestore52.query)(
|
|
17347
|
+
(0, import_firestore52.collection)(this.db, TECHNOLOGIES_COLLECTION),
|
|
17348
|
+
(0, import_firestore52.where)("isActive", "==", true),
|
|
17349
|
+
(0, import_firestore52.orderBy)("name")
|
|
17350
|
+
);
|
|
17351
|
+
const snapshot = await (0, import_firestore52.getDocs)(q);
|
|
17352
|
+
return snapshot.docs.map(
|
|
17353
|
+
(doc38) => ({
|
|
17354
|
+
id: doc38.id,
|
|
17355
|
+
...doc38.data()
|
|
17356
|
+
})
|
|
17357
|
+
);
|
|
17358
|
+
}
|
|
16713
17359
|
};
|
|
16714
17360
|
|
|
16715
17361
|
// src/backoffice/services/product.service.ts
|
|
16716
|
-
var
|
|
17362
|
+
var import_firestore53 = require("firebase/firestore");
|
|
16717
17363
|
|
|
16718
17364
|
// src/backoffice/types/product.types.ts
|
|
16719
17365
|
var PRODUCTS_COLLECTION = "products";
|
|
@@ -16726,7 +17372,7 @@ var ProductService = class extends BaseService {
|
|
|
16726
17372
|
* @returns Firestore collection reference
|
|
16727
17373
|
*/
|
|
16728
17374
|
getProductsRef(technologyId) {
|
|
16729
|
-
return (0,
|
|
17375
|
+
return (0, import_firestore53.collection)(
|
|
16730
17376
|
this.db,
|
|
16731
17377
|
TECHNOLOGIES_COLLECTION,
|
|
16732
17378
|
technologyId,
|
|
@@ -16746,47 +17392,129 @@ var ProductService = class extends BaseService {
|
|
|
16746
17392
|
updatedAt: now,
|
|
16747
17393
|
isActive: true
|
|
16748
17394
|
};
|
|
16749
|
-
const productRef = await (0,
|
|
17395
|
+
const productRef = await (0, import_firestore53.addDoc)(
|
|
16750
17396
|
this.getProductsRef(technologyId),
|
|
16751
17397
|
newProduct
|
|
16752
17398
|
);
|
|
16753
17399
|
return { id: productRef.id, ...newProduct };
|
|
16754
17400
|
}
|
|
16755
17401
|
/**
|
|
16756
|
-
* Gets all products
|
|
17402
|
+
* Gets a paginated list of all products, with optional filters.
|
|
17403
|
+
* This uses a collectionGroup query to search across all technologies.
|
|
16757
17404
|
*/
|
|
16758
|
-
async
|
|
16759
|
-
const
|
|
16760
|
-
|
|
16761
|
-
|
|
16762
|
-
|
|
16763
|
-
|
|
16764
|
-
|
|
16765
|
-
|
|
16766
|
-
|
|
16767
|
-
|
|
17405
|
+
async getAll(options) {
|
|
17406
|
+
const {
|
|
17407
|
+
rowsPerPage,
|
|
17408
|
+
lastVisible,
|
|
17409
|
+
categoryId,
|
|
17410
|
+
subcategoryId,
|
|
17411
|
+
technologyId
|
|
17412
|
+
} = options;
|
|
17413
|
+
const constraints = [
|
|
17414
|
+
(0, import_firestore53.where)("isActive", "==", true),
|
|
17415
|
+
(0, import_firestore53.orderBy)("name")
|
|
17416
|
+
];
|
|
17417
|
+
if (categoryId) {
|
|
17418
|
+
constraints.push((0, import_firestore53.where)("categoryId", "==", categoryId));
|
|
17419
|
+
}
|
|
17420
|
+
if (subcategoryId) {
|
|
17421
|
+
constraints.push((0, import_firestore53.where)("subcategoryId", "==", subcategoryId));
|
|
17422
|
+
}
|
|
17423
|
+
if (technologyId) {
|
|
17424
|
+
constraints.push((0, import_firestore53.where)("technologyId", "==", technologyId));
|
|
17425
|
+
}
|
|
17426
|
+
if (lastVisible) {
|
|
17427
|
+
constraints.push((0, import_firestore53.startAfter)(lastVisible));
|
|
17428
|
+
}
|
|
17429
|
+
constraints.push((0, import_firestore53.limit)(rowsPerPage));
|
|
17430
|
+
const q = (0, import_firestore53.query)(
|
|
17431
|
+
(0, import_firestore53.collectionGroup)(this.db, PRODUCTS_COLLECTION),
|
|
17432
|
+
...constraints
|
|
17433
|
+
);
|
|
17434
|
+
const snapshot = await (0, import_firestore53.getDocs)(q);
|
|
17435
|
+
const products = snapshot.docs.map(
|
|
17436
|
+
(doc38) => ({
|
|
17437
|
+
id: doc38.id,
|
|
17438
|
+
...doc38.data()
|
|
16768
17439
|
})
|
|
16769
17440
|
);
|
|
17441
|
+
const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
|
|
17442
|
+
return { products, lastVisible: newLastVisible };
|
|
17443
|
+
}
|
|
17444
|
+
/**
|
|
17445
|
+
* Gets the total count of active products, with optional filters.
|
|
17446
|
+
*/
|
|
17447
|
+
async getProductsCount(options) {
|
|
17448
|
+
const { categoryId, subcategoryId, technologyId } = options;
|
|
17449
|
+
const constraints = [(0, import_firestore53.where)("isActive", "==", true)];
|
|
17450
|
+
if (categoryId) {
|
|
17451
|
+
constraints.push((0, import_firestore53.where)("categoryId", "==", categoryId));
|
|
17452
|
+
}
|
|
17453
|
+
if (subcategoryId) {
|
|
17454
|
+
constraints.push((0, import_firestore53.where)("subcategoryId", "==", subcategoryId));
|
|
17455
|
+
}
|
|
17456
|
+
if (technologyId) {
|
|
17457
|
+
constraints.push((0, import_firestore53.where)("technologyId", "==", technologyId));
|
|
17458
|
+
}
|
|
17459
|
+
const q = (0, import_firestore53.query)(
|
|
17460
|
+
(0, import_firestore53.collectionGroup)(this.db, PRODUCTS_COLLECTION),
|
|
17461
|
+
...constraints
|
|
17462
|
+
);
|
|
17463
|
+
const snapshot = await (0, import_firestore53.getCountFromServer)(q);
|
|
17464
|
+
return snapshot.data().count;
|
|
17465
|
+
}
|
|
17466
|
+
/**
|
|
17467
|
+
* Gets counts of active products grouped by category, subcategory, and technology.
|
|
17468
|
+
* This uses a single collectionGroup query for efficiency.
|
|
17469
|
+
*/
|
|
17470
|
+
async getProductCounts() {
|
|
17471
|
+
const q = (0, import_firestore53.query)(
|
|
17472
|
+
(0, import_firestore53.collectionGroup)(this.db, PRODUCTS_COLLECTION),
|
|
17473
|
+
(0, import_firestore53.where)("isActive", "==", true)
|
|
17474
|
+
);
|
|
17475
|
+
const snapshot = await (0, import_firestore53.getDocs)(q);
|
|
17476
|
+
const counts = {
|
|
17477
|
+
byCategory: {},
|
|
17478
|
+
bySubcategory: {},
|
|
17479
|
+
byTechnology: {}
|
|
17480
|
+
};
|
|
17481
|
+
if (snapshot.empty) {
|
|
17482
|
+
return counts;
|
|
17483
|
+
}
|
|
17484
|
+
snapshot.docs.forEach((doc38) => {
|
|
17485
|
+
const product = doc38.data();
|
|
17486
|
+
const { categoryId, subcategoryId, technologyId } = product;
|
|
17487
|
+
if (categoryId) {
|
|
17488
|
+
counts.byCategory[categoryId] = (counts.byCategory[categoryId] || 0) + 1;
|
|
17489
|
+
}
|
|
17490
|
+
if (subcategoryId) {
|
|
17491
|
+
counts.bySubcategory[subcategoryId] = (counts.bySubcategory[subcategoryId] || 0) + 1;
|
|
17492
|
+
}
|
|
17493
|
+
if (technologyId) {
|
|
17494
|
+
counts.byTechnology[technologyId] = (counts.byTechnology[technologyId] || 0) + 1;
|
|
17495
|
+
}
|
|
17496
|
+
});
|
|
17497
|
+
return counts;
|
|
16770
17498
|
}
|
|
16771
17499
|
/**
|
|
16772
17500
|
* Gets all products for a brand by filtering through all technologies
|
|
16773
17501
|
*/
|
|
16774
17502
|
async getAllByBrand(brandId) {
|
|
16775
|
-
const allTechnologiesRef = (0,
|
|
16776
|
-
const technologiesSnapshot = await (0,
|
|
17503
|
+
const allTechnologiesRef = (0, import_firestore53.collection)(this.db, TECHNOLOGIES_COLLECTION);
|
|
17504
|
+
const technologiesSnapshot = await (0, import_firestore53.getDocs)(allTechnologiesRef);
|
|
16777
17505
|
const products = [];
|
|
16778
17506
|
for (const techDoc of technologiesSnapshot.docs) {
|
|
16779
|
-
const q = (0,
|
|
17507
|
+
const q = (0, import_firestore53.query)(
|
|
16780
17508
|
this.getProductsRef(techDoc.id),
|
|
16781
|
-
(0,
|
|
16782
|
-
(0,
|
|
17509
|
+
(0, import_firestore53.where)("brandId", "==", brandId),
|
|
17510
|
+
(0, import_firestore53.where)("isActive", "==", true)
|
|
16783
17511
|
);
|
|
16784
|
-
const snapshot = await (0,
|
|
17512
|
+
const snapshot = await (0, import_firestore53.getDocs)(q);
|
|
16785
17513
|
products.push(
|
|
16786
17514
|
...snapshot.docs.map(
|
|
16787
|
-
(
|
|
16788
|
-
id:
|
|
16789
|
-
...
|
|
17515
|
+
(doc38) => ({
|
|
17516
|
+
id: doc38.id,
|
|
17517
|
+
...doc38.data()
|
|
16790
17518
|
})
|
|
16791
17519
|
)
|
|
16792
17520
|
);
|
|
@@ -16801,8 +17529,8 @@ var ProductService = class extends BaseService {
|
|
|
16801
17529
|
...product,
|
|
16802
17530
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16803
17531
|
};
|
|
16804
|
-
const docRef = (0,
|
|
16805
|
-
await (0,
|
|
17532
|
+
const docRef = (0, import_firestore53.doc)(this.getProductsRef(technologyId), productId);
|
|
17533
|
+
await (0, import_firestore53.updateDoc)(docRef, updateData);
|
|
16806
17534
|
return this.getById(technologyId, productId);
|
|
16807
17535
|
}
|
|
16808
17536
|
/**
|
|
@@ -16817,8 +17545,8 @@ var ProductService = class extends BaseService {
|
|
|
16817
17545
|
* Gets a product by ID
|
|
16818
17546
|
*/
|
|
16819
17547
|
async getById(technologyId, productId) {
|
|
16820
|
-
const docRef = (0,
|
|
16821
|
-
const docSnap = await (0,
|
|
17548
|
+
const docRef = (0, import_firestore53.doc)(this.getProductsRef(technologyId), productId);
|
|
17549
|
+
const docSnap = await (0, import_firestore53.getDoc)(docRef);
|
|
16822
17550
|
if (!docSnap.exists()) return null;
|
|
16823
17551
|
return {
|
|
16824
17552
|
id: docSnap.id,
|
|
@@ -16827,6 +17555,255 @@ var ProductService = class extends BaseService {
|
|
|
16827
17555
|
}
|
|
16828
17556
|
};
|
|
16829
17557
|
|
|
17558
|
+
// src/backoffice/services/constants.service.ts
|
|
17559
|
+
var import_firestore54 = require("firebase/firestore");
|
|
17560
|
+
var ADMIN_CONSTANTS_COLLECTION = "admin-constants";
|
|
17561
|
+
var TREATMENT_BENEFITS_DOC = "treatment-benefits";
|
|
17562
|
+
var CONTRAINDICATIONS_DOC = "contraindications";
|
|
17563
|
+
var ConstantsService = class extends BaseService {
|
|
17564
|
+
/**
|
|
17565
|
+
* @description Gets the reference to the document holding treatment benefits.
|
|
17566
|
+
* @private
|
|
17567
|
+
* @type {DocumentReference}
|
|
17568
|
+
*/
|
|
17569
|
+
get treatmentBenefitsDocRef() {
|
|
17570
|
+
return (0, import_firestore54.doc)(this.db, ADMIN_CONSTANTS_COLLECTION, TREATMENT_BENEFITS_DOC);
|
|
17571
|
+
}
|
|
17572
|
+
/**
|
|
17573
|
+
* @description Gets the reference to the document holding contraindications.
|
|
17574
|
+
* @private
|
|
17575
|
+
* @type {DocumentReference}
|
|
17576
|
+
*/
|
|
17577
|
+
get contraindicationsDocRef() {
|
|
17578
|
+
return (0, import_firestore54.doc)(this.db, ADMIN_CONSTANTS_COLLECTION, CONTRAINDICATIONS_DOC);
|
|
17579
|
+
}
|
|
17580
|
+
// =================================================================
|
|
17581
|
+
// Treatment Benefits
|
|
17582
|
+
// =================================================================
|
|
17583
|
+
/**
|
|
17584
|
+
* @description Retrieves all treatment benefits without pagination.
|
|
17585
|
+
* @returns {Promise<TreatmentBenefitDynamic[]>} An array of all treatment benefits.
|
|
17586
|
+
*/
|
|
17587
|
+
async getAllBenefitsForFilter() {
|
|
17588
|
+
const docSnap = await (0, import_firestore54.getDoc)(this.treatmentBenefitsDocRef);
|
|
17589
|
+
if (!docSnap.exists()) {
|
|
17590
|
+
return [];
|
|
17591
|
+
}
|
|
17592
|
+
return docSnap.data().benefits;
|
|
17593
|
+
}
|
|
17594
|
+
/**
|
|
17595
|
+
* @description Retrieves a paginated list of treatment benefits.
|
|
17596
|
+
* @param {{ page: number; limit: number }} options - Pagination options.
|
|
17597
|
+
* @returns {Promise<{ benefits: TreatmentBenefitDynamic[]; total: number }>} A paginated list of benefits and the total count.
|
|
17598
|
+
*/
|
|
17599
|
+
async getAllBenefits(options) {
|
|
17600
|
+
const allBenefits = await this.getAllBenefitsForFilter();
|
|
17601
|
+
const { page, limit: limit21 } = options;
|
|
17602
|
+
const startIndex = page * limit21;
|
|
17603
|
+
const endIndex = startIndex + limit21;
|
|
17604
|
+
const paginatedBenefits = allBenefits.slice(startIndex, endIndex);
|
|
17605
|
+
return { benefits: paginatedBenefits, total: allBenefits.length };
|
|
17606
|
+
}
|
|
17607
|
+
/**
|
|
17608
|
+
* @description Adds a new treatment benefit.
|
|
17609
|
+
* @param {Omit<TreatmentBenefitDynamic, "id">} benefit - The treatment benefit to add, without an ID.
|
|
17610
|
+
* @returns {Promise<TreatmentBenefitDynamic>} The newly created treatment benefit with its generated ID.
|
|
17611
|
+
*/
|
|
17612
|
+
async addTreatmentBenefit(benefit) {
|
|
17613
|
+
const newBenefit = {
|
|
17614
|
+
id: this.generateId(),
|
|
17615
|
+
...benefit
|
|
17616
|
+
};
|
|
17617
|
+
const docSnap = await (0, import_firestore54.getDoc)(this.treatmentBenefitsDocRef);
|
|
17618
|
+
if (!docSnap.exists()) {
|
|
17619
|
+
await (0, import_firestore54.setDoc)(this.treatmentBenefitsDocRef, { benefits: [newBenefit] });
|
|
17620
|
+
} else {
|
|
17621
|
+
await (0, import_firestore54.updateDoc)(this.treatmentBenefitsDocRef, {
|
|
17622
|
+
benefits: (0, import_firestore54.arrayUnion)(newBenefit)
|
|
17623
|
+
});
|
|
17624
|
+
}
|
|
17625
|
+
return newBenefit;
|
|
17626
|
+
}
|
|
17627
|
+
/**
|
|
17628
|
+
* @description Retrieves a single treatment benefit by its ID.
|
|
17629
|
+
* @param {string} benefitId - The ID of the treatment benefit to retrieve.
|
|
17630
|
+
* @returns {Promise<TreatmentBenefitDynamic | undefined>} The found treatment benefit or undefined.
|
|
17631
|
+
*/
|
|
17632
|
+
async getBenefitById(benefitId) {
|
|
17633
|
+
const benefits = await this.getAllBenefitsForFilter();
|
|
17634
|
+
return benefits.find((b) => b.id === benefitId);
|
|
17635
|
+
}
|
|
17636
|
+
/**
|
|
17637
|
+
* @description Searches for treatment benefits by name (case-insensitive).
|
|
17638
|
+
* @param {string} searchTerm - The term to search for in the benefit names.
|
|
17639
|
+
* @returns {Promise<TreatmentBenefitDynamic[]>} An array of matching treatment benefits.
|
|
17640
|
+
*/
|
|
17641
|
+
async searchBenefitsByName(searchTerm) {
|
|
17642
|
+
const benefits = await this.getAllBenefitsForFilter();
|
|
17643
|
+
const normalizedSearchTerm = searchTerm.toLowerCase();
|
|
17644
|
+
return benefits.filter(
|
|
17645
|
+
(b) => b.name.toLowerCase().includes(normalizedSearchTerm)
|
|
17646
|
+
);
|
|
17647
|
+
}
|
|
17648
|
+
/**
|
|
17649
|
+
* @description Updates an existing treatment benefit.
|
|
17650
|
+
* @param {TreatmentBenefitDynamic} benefit - The treatment benefit with updated data. Its ID must match an existing benefit.
|
|
17651
|
+
* @returns {Promise<TreatmentBenefitDynamic>} The updated treatment benefit.
|
|
17652
|
+
* @throws {Error} If the treatment benefit is not found.
|
|
17653
|
+
*/
|
|
17654
|
+
async updateTreatmentBenefit(benefit) {
|
|
17655
|
+
const benefits = await this.getAllBenefitsForFilter();
|
|
17656
|
+
const benefitIndex = benefits.findIndex((b) => b.id === benefit.id);
|
|
17657
|
+
if (benefitIndex === -1) {
|
|
17658
|
+
throw new Error("Treatment benefit not found.");
|
|
17659
|
+
}
|
|
17660
|
+
benefits[benefitIndex] = benefit;
|
|
17661
|
+
await (0, import_firestore54.updateDoc)(this.treatmentBenefitsDocRef, { benefits });
|
|
17662
|
+
return benefit;
|
|
17663
|
+
}
|
|
17664
|
+
/**
|
|
17665
|
+
* @description Deletes a treatment benefit by its ID.
|
|
17666
|
+
* @param {string} benefitId - The ID of the treatment benefit to delete.
|
|
17667
|
+
* @returns {Promise<void>}
|
|
17668
|
+
*/
|
|
17669
|
+
async deleteTreatmentBenefit(benefitId) {
|
|
17670
|
+
const benefits = await this.getAllBenefitsForFilter();
|
|
17671
|
+
const benefitToRemove = benefits.find((b) => b.id === benefitId);
|
|
17672
|
+
if (!benefitToRemove) {
|
|
17673
|
+
return;
|
|
17674
|
+
}
|
|
17675
|
+
await (0, import_firestore54.updateDoc)(this.treatmentBenefitsDocRef, {
|
|
17676
|
+
benefits: (0, import_firestore54.arrayRemove)(benefitToRemove)
|
|
17677
|
+
});
|
|
17678
|
+
}
|
|
17679
|
+
// =================================================================
|
|
17680
|
+
// Contraindications
|
|
17681
|
+
// =================================================================
|
|
17682
|
+
/**
|
|
17683
|
+
* @description Retrieves all contraindications without pagination.
|
|
17684
|
+
* @returns {Promise<ContraindicationDynamic[]>} An array of all contraindications.
|
|
17685
|
+
*/
|
|
17686
|
+
async getAllContraindicationsForFilter() {
|
|
17687
|
+
const docSnap = await (0, import_firestore54.getDoc)(this.contraindicationsDocRef);
|
|
17688
|
+
if (!docSnap.exists()) {
|
|
17689
|
+
return [];
|
|
17690
|
+
}
|
|
17691
|
+
return docSnap.data().contraindications;
|
|
17692
|
+
}
|
|
17693
|
+
/**
|
|
17694
|
+
* @description Retrieves a paginated list of contraindications.
|
|
17695
|
+
* @param {{ page: number; limit: number }} options - Pagination options.
|
|
17696
|
+
* @returns {Promise<{ contraindications: ContraindicationDynamic[]; total: number }>} A paginated list and the total count.
|
|
17697
|
+
*/
|
|
17698
|
+
async getAllContraindications(options) {
|
|
17699
|
+
const allContraindications = await this.getAllContraindicationsForFilter();
|
|
17700
|
+
const { page, limit: limit21 } = options;
|
|
17701
|
+
const startIndex = page * limit21;
|
|
17702
|
+
const endIndex = startIndex + limit21;
|
|
17703
|
+
const paginatedContraindications = allContraindications.slice(
|
|
17704
|
+
startIndex,
|
|
17705
|
+
endIndex
|
|
17706
|
+
);
|
|
17707
|
+
return {
|
|
17708
|
+
contraindications: paginatedContraindications,
|
|
17709
|
+
total: allContraindications.length
|
|
17710
|
+
};
|
|
17711
|
+
}
|
|
17712
|
+
/**
|
|
17713
|
+
* @description Adds a new contraindication.
|
|
17714
|
+
* @param {Omit<ContraindicationDynamic, "id">} contraindication - The contraindication to add, without an ID.
|
|
17715
|
+
* @returns {Promise<ContraindicationDynamic>} The newly created contraindication with its generated ID.
|
|
17716
|
+
*/
|
|
17717
|
+
async addContraindication(contraindication) {
|
|
17718
|
+
const newContraindication = {
|
|
17719
|
+
id: this.generateId(),
|
|
17720
|
+
...contraindication
|
|
17721
|
+
};
|
|
17722
|
+
const docSnap = await (0, import_firestore54.getDoc)(this.contraindicationsDocRef);
|
|
17723
|
+
if (!docSnap.exists()) {
|
|
17724
|
+
await (0, import_firestore54.setDoc)(this.contraindicationsDocRef, {
|
|
17725
|
+
contraindications: [newContraindication]
|
|
17726
|
+
});
|
|
17727
|
+
} else {
|
|
17728
|
+
await (0, import_firestore54.updateDoc)(this.contraindicationsDocRef, {
|
|
17729
|
+
contraindications: (0, import_firestore54.arrayUnion)(newContraindication)
|
|
17730
|
+
});
|
|
17731
|
+
}
|
|
17732
|
+
return newContraindication;
|
|
17733
|
+
}
|
|
17734
|
+
/**
|
|
17735
|
+
* @description Retrieves a single contraindication by its ID.
|
|
17736
|
+
* @param {string} contraindicationId - The ID of the contraindication to retrieve.
|
|
17737
|
+
* @returns {Promise<ContraindicationDynamic | undefined>} The found contraindication or undefined.
|
|
17738
|
+
*/
|
|
17739
|
+
async getContraindicationById(contraindicationId) {
|
|
17740
|
+
const contraindications = await this.getAllContraindicationsForFilter();
|
|
17741
|
+
return contraindications.find((c) => c.id === contraindicationId);
|
|
17742
|
+
}
|
|
17743
|
+
/**
|
|
17744
|
+
* @description Searches for contraindications by name (case-insensitive).
|
|
17745
|
+
* @param {string} searchTerm - The term to search for in the contraindication names.
|
|
17746
|
+
* @returns {Promise<ContraindicationDynamic[]>} An array of matching contraindications.
|
|
17747
|
+
*/
|
|
17748
|
+
async searchContraindicationsByName(searchTerm) {
|
|
17749
|
+
const contraindications = await this.getAllContraindicationsForFilter();
|
|
17750
|
+
const normalizedSearchTerm = searchTerm.toLowerCase();
|
|
17751
|
+
return contraindications.filter(
|
|
17752
|
+
(c) => c.name.toLowerCase().includes(normalizedSearchTerm)
|
|
17753
|
+
);
|
|
17754
|
+
}
|
|
17755
|
+
/**
|
|
17756
|
+
* @description Updates an existing contraindication.
|
|
17757
|
+
* @param {ContraindicationDynamic} contraindication - The contraindication with updated data. Its ID must match an existing one.
|
|
17758
|
+
* @returns {Promise<ContraindicationDynamic>} The updated contraindication.
|
|
17759
|
+
* @throws {Error} If the contraindication is not found.
|
|
17760
|
+
*/
|
|
17761
|
+
async updateContraindication(contraindication) {
|
|
17762
|
+
const contraindications = await this.getAllContraindicationsForFilter();
|
|
17763
|
+
const index = contraindications.findIndex(
|
|
17764
|
+
(c) => c.id === contraindication.id
|
|
17765
|
+
);
|
|
17766
|
+
if (index === -1) {
|
|
17767
|
+
throw new Error("Contraindication not found.");
|
|
17768
|
+
}
|
|
17769
|
+
contraindications[index] = contraindication;
|
|
17770
|
+
await (0, import_firestore54.updateDoc)(this.contraindicationsDocRef, { contraindications });
|
|
17771
|
+
return contraindication;
|
|
17772
|
+
}
|
|
17773
|
+
/**
|
|
17774
|
+
* @description Deletes a contraindication by its ID.
|
|
17775
|
+
* @param {string} contraindicationId - The ID of the contraindication to delete.
|
|
17776
|
+
* @returns {Promise<void>}
|
|
17777
|
+
*/
|
|
17778
|
+
async deleteContraindication(contraindicationId) {
|
|
17779
|
+
const contraindications = await this.getAllContraindicationsForFilter();
|
|
17780
|
+
const toRemove = contraindications.find((c) => c.id === contraindicationId);
|
|
17781
|
+
if (!toRemove) {
|
|
17782
|
+
return;
|
|
17783
|
+
}
|
|
17784
|
+
await (0, import_firestore54.updateDoc)(this.contraindicationsDocRef, {
|
|
17785
|
+
contraindications: (0, import_firestore54.arrayRemove)(toRemove)
|
|
17786
|
+
});
|
|
17787
|
+
}
|
|
17788
|
+
};
|
|
17789
|
+
|
|
17790
|
+
// src/backoffice/types/static/contraindication.types.ts
|
|
17791
|
+
var Contraindication = /* @__PURE__ */ ((Contraindication2) => {
|
|
17792
|
+
Contraindication2["SENSITIVE_SKIN"] = "sensitive_skin";
|
|
17793
|
+
Contraindication2["RECENT_TANNING"] = "recent_tanning";
|
|
17794
|
+
Contraindication2["RECENT_BOTOX"] = "recent_botox";
|
|
17795
|
+
Contraindication2["RECENT_FILLERS"] = "recent_fillers";
|
|
17796
|
+
Contraindication2["SKIN_ALLERGIES"] = "skin_allergies";
|
|
17797
|
+
Contraindication2["MEDICATIONS"] = "medications";
|
|
17798
|
+
Contraindication2["RECENT_CHEMICAL_PEEL"] = "recent_chemical_peel";
|
|
17799
|
+
Contraindication2["RECENT_LASER"] = "recent_laser";
|
|
17800
|
+
Contraindication2["SKIN_INFLAMMATION"] = "skin_inflammation";
|
|
17801
|
+
Contraindication2["OPEN_WOUNDS"] = "open_wounds";
|
|
17802
|
+
Contraindication2["HERPES_SIMPLEX"] = "herpes_simplex";
|
|
17803
|
+
Contraindication2["COLD_SORES"] = "cold_sores";
|
|
17804
|
+
return Contraindication2;
|
|
17805
|
+
})(Contraindication || {});
|
|
17806
|
+
|
|
16830
17807
|
// src/backoffice/types/static/treatment-benefit.types.ts
|
|
16831
17808
|
var TreatmentBenefit = /* @__PURE__ */ ((TreatmentBenefit2) => {
|
|
16832
17809
|
TreatmentBenefit2["WRINKLE_REDUCTION"] = "wrinkle_reduction";
|
|
@@ -16886,6 +17863,7 @@ var RequirementType = /* @__PURE__ */ ((RequirementType2) => {
|
|
|
16886
17863
|
ClinicPhotoTag,
|
|
16887
17864
|
ClinicService,
|
|
16888
17865
|
ClinicTag,
|
|
17866
|
+
ConstantsService,
|
|
16889
17867
|
Contraindication,
|
|
16890
17868
|
CosmeticAllergySubtype,
|
|
16891
17869
|
Currency,
|