@blackcode_sa/metaestetics-api 1.11.3 → 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 +329 -318
- package/dist/admin/index.d.ts +329 -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 +4428 -4035
- package/dist/index.d.ts +4428 -4035
- package/dist/index.js +1642 -665
- package/dist/index.mjs +1406 -401
- 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 +2 -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/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";
|
|
@@ -933,44 +936,48 @@ async function updateAppointmentUtil(db, appointmentId, data) {
|
|
|
933
936
|
const validPreReqIds = currentAppointment.preProcedureRequirements.map(
|
|
934
937
|
(req) => req.id
|
|
935
938
|
);
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
if (invalidPreReqIds.length > 0) {
|
|
940
|
-
throw new Error(
|
|
941
|
-
`Invalid pre-requirement IDs: ${invalidPreReqIds.join(", ")}`
|
|
939
|
+
if (Array.isArray(data.completedPreRequirements)) {
|
|
940
|
+
const invalidPreReqIds = data.completedPreRequirements.filter(
|
|
941
|
+
(id) => !validPreReqIds.includes(id)
|
|
942
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
|
+
];
|
|
943
954
|
}
|
|
944
|
-
completedPreRequirements = [
|
|
945
|
-
.../* @__PURE__ */ new Set([
|
|
946
|
-
...completedPreRequirements,
|
|
947
|
-
...data.completedPreRequirements
|
|
948
|
-
])
|
|
949
|
-
];
|
|
950
955
|
}
|
|
951
956
|
if (data.completedPostRequirements) {
|
|
952
957
|
const validPostReqIds = currentAppointment.postProcedureRequirements.map(
|
|
953
958
|
(req) => req.id
|
|
954
959
|
);
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
if (invalidPostReqIds.length > 0) {
|
|
959
|
-
throw new Error(
|
|
960
|
-
`Invalid post-requirement IDs: ${invalidPostReqIds.join(", ")}`
|
|
960
|
+
if (Array.isArray(data.completedPostRequirements)) {
|
|
961
|
+
const invalidPostReqIds = data.completedPostRequirements.filter(
|
|
962
|
+
(id) => !validPostReqIds.includes(id)
|
|
961
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
|
+
];
|
|
962
975
|
}
|
|
963
|
-
completedPostRequirements = [
|
|
964
|
-
.../* @__PURE__ */ new Set([
|
|
965
|
-
...completedPostRequirements,
|
|
966
|
-
...data.completedPostRequirements
|
|
967
|
-
])
|
|
968
|
-
];
|
|
969
976
|
}
|
|
970
977
|
const updateData = {
|
|
971
978
|
...data,
|
|
972
|
-
completedPreRequirements,
|
|
973
|
-
completedPostRequirements,
|
|
979
|
+
completedPreRequirements: Array.isArray(data.completedPreRequirements) ? completedPreRequirements : data.completedPreRequirements,
|
|
980
|
+
completedPostRequirements: Array.isArray(data.completedPostRequirements) ? completedPostRequirements : data.completedPostRequirements,
|
|
974
981
|
updatedAt: (0, import_firestore.serverTimestamp)()
|
|
975
982
|
};
|
|
976
983
|
Object.keys(updateData).forEach((key) => {
|
|
@@ -1020,7 +1027,7 @@ async function updateCalendarEventStatus(db, calendarEventId, appointmentStatus)
|
|
|
1020
1027
|
case "canceled_clinic" /* CANCELED_CLINIC */:
|
|
1021
1028
|
calendarStatus = "canceled";
|
|
1022
1029
|
break;
|
|
1023
|
-
case
|
|
1030
|
+
case "rescheduled_by_clinic" /* RESCHEDULED_BY_CLINIC */:
|
|
1024
1031
|
calendarStatus = "rescheduled";
|
|
1025
1032
|
break;
|
|
1026
1033
|
case "completed" /* COMPLETED */:
|
|
@@ -1094,7 +1101,7 @@ async function searchAppointmentsUtil(db, params) {
|
|
|
1094
1101
|
const q = (0, import_firestore.query)((0, import_firestore.collection)(db, APPOINTMENTS_COLLECTION), ...constraints);
|
|
1095
1102
|
const querySnapshot = await (0, import_firestore.getDocs)(q);
|
|
1096
1103
|
const appointments = querySnapshot.docs.map(
|
|
1097
|
-
(
|
|
1104
|
+
(doc38) => doc38.data()
|
|
1098
1105
|
);
|
|
1099
1106
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
1100
1107
|
return { appointments, lastDoc };
|
|
@@ -1901,7 +1908,7 @@ var AppointmentService = class extends BaseService {
|
|
|
1901
1908
|
);
|
|
1902
1909
|
const querySnapshot = await (0, import_firestore2.getDocs)(q);
|
|
1903
1910
|
const appointments = querySnapshot.docs.map(
|
|
1904
|
-
(
|
|
1911
|
+
(doc38) => doc38.data()
|
|
1905
1912
|
);
|
|
1906
1913
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
1907
1914
|
console.log(
|
|
@@ -1974,7 +1981,7 @@ var AppointmentService = class extends BaseService {
|
|
|
1974
1981
|
);
|
|
1975
1982
|
const querySnapshot = await (0, import_firestore2.getDocs)(q);
|
|
1976
1983
|
const appointments = querySnapshot.docs.map(
|
|
1977
|
-
(
|
|
1984
|
+
(doc38) => doc38.data()
|
|
1978
1985
|
);
|
|
1979
1986
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
1980
1987
|
console.log(
|
|
@@ -2470,8 +2477,8 @@ var MediaAccessLevel = /* @__PURE__ */ ((MediaAccessLevel2) => {
|
|
|
2470
2477
|
})(MediaAccessLevel || {});
|
|
2471
2478
|
var MEDIA_METADATA_COLLECTION = "media_metadata";
|
|
2472
2479
|
var MediaService = class extends BaseService {
|
|
2473
|
-
constructor(
|
|
2474
|
-
super(
|
|
2480
|
+
constructor(...args) {
|
|
2481
|
+
super(...args);
|
|
2475
2482
|
}
|
|
2476
2483
|
/**
|
|
2477
2484
|
* Upload a media file, store its metadata, and return the metadata including the URL.
|
|
@@ -2731,7 +2738,7 @@ var MediaService = class extends BaseService {
|
|
|
2731
2738
|
try {
|
|
2732
2739
|
const querySnapshot = await (0, import_firestore4.getDocs)(finalQuery);
|
|
2733
2740
|
const mediaList = querySnapshot.docs.map(
|
|
2734
|
-
(
|
|
2741
|
+
(doc38) => doc38.data()
|
|
2735
2742
|
);
|
|
2736
2743
|
console.log(`[MediaService] Found ${mediaList.length} media items.`);
|
|
2737
2744
|
return mediaList;
|
|
@@ -2785,8 +2792,8 @@ var getPatientsByClinicUtil = async (db, clinicId, options) => {
|
|
|
2785
2792
|
}
|
|
2786
2793
|
const patientsSnapshot = await (0, import_firestore5.getDocs)(q);
|
|
2787
2794
|
const patients = [];
|
|
2788
|
-
patientsSnapshot.forEach((
|
|
2789
|
-
patients.push(
|
|
2795
|
+
patientsSnapshot.forEach((doc38) => {
|
|
2796
|
+
patients.push(doc38.data());
|
|
2790
2797
|
});
|
|
2791
2798
|
console.log(
|
|
2792
2799
|
`[getPatientsByClinicUtil] Found ${patients.length} patients for clinic ID: ${clinicId}`
|
|
@@ -2836,23 +2843,6 @@ var BlockingCondition = /* @__PURE__ */ ((BlockingCondition2) => {
|
|
|
2836
2843
|
return BlockingCondition2;
|
|
2837
2844
|
})(BlockingCondition || {});
|
|
2838
2845
|
|
|
2839
|
-
// src/backoffice/types/static/contraindication.types.ts
|
|
2840
|
-
var Contraindication = /* @__PURE__ */ ((Contraindication2) => {
|
|
2841
|
-
Contraindication2["SENSITIVE_SKIN"] = "sensitive_skin";
|
|
2842
|
-
Contraindication2["RECENT_TANNING"] = "recent_tanning";
|
|
2843
|
-
Contraindication2["RECENT_BOTOX"] = "recent_botox";
|
|
2844
|
-
Contraindication2["RECENT_FILLERS"] = "recent_fillers";
|
|
2845
|
-
Contraindication2["SKIN_ALLERGIES"] = "skin_allergies";
|
|
2846
|
-
Contraindication2["MEDICATIONS"] = "medications";
|
|
2847
|
-
Contraindication2["RECENT_CHEMICAL_PEEL"] = "recent_chemical_peel";
|
|
2848
|
-
Contraindication2["RECENT_LASER"] = "recent_laser";
|
|
2849
|
-
Contraindication2["SKIN_INFLAMMATION"] = "skin_inflammation";
|
|
2850
|
-
Contraindication2["OPEN_WOUNDS"] = "open_wounds";
|
|
2851
|
-
Contraindication2["HERPES_SIMPLEX"] = "herpes_simplex";
|
|
2852
|
-
Contraindication2["COLD_SORES"] = "cold_sores";
|
|
2853
|
-
return Contraindication2;
|
|
2854
|
-
})(Contraindication || {});
|
|
2855
|
-
|
|
2856
2846
|
// src/validations/common.schema.ts
|
|
2857
2847
|
var import_zod5 = require("zod");
|
|
2858
2848
|
var import_firestore6 = require("firebase/firestore");
|
|
@@ -2907,8 +2897,13 @@ var blockingConditionSchema = import_zod6.z.object({
|
|
|
2907
2897
|
notes: import_zod6.z.string().optional().nullable(),
|
|
2908
2898
|
isActive: import_zod6.z.boolean()
|
|
2909
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
|
+
});
|
|
2910
2905
|
var contraindicationSchema = import_zod6.z.object({
|
|
2911
|
-
condition:
|
|
2906
|
+
condition: contraindicationDynamicSchema,
|
|
2912
2907
|
lastOccurrence: timestampSchema,
|
|
2913
2908
|
frequency: import_zod6.z.enum(["rare", "occasional", "frequent"]),
|
|
2914
2909
|
notes: import_zod6.z.string().optional().nullable(),
|
|
@@ -3139,8 +3134,8 @@ var getPatientsByPractitionerUtil = async (db, practitionerId, options) => {
|
|
|
3139
3134
|
}
|
|
3140
3135
|
const patientsSnapshot = await (0, import_firestore8.getDocs)(q);
|
|
3141
3136
|
const patients = [];
|
|
3142
|
-
patientsSnapshot.forEach((
|
|
3143
|
-
patients.push(
|
|
3137
|
+
patientsSnapshot.forEach((doc38) => {
|
|
3138
|
+
patients.push(doc38.data());
|
|
3144
3139
|
});
|
|
3145
3140
|
console.log(
|
|
3146
3141
|
`[getPatientsByPractitionerUtil] Found ${patients.length} patients for practitioner ID: ${practitionerId}`
|
|
@@ -3907,7 +3902,7 @@ async function getClinicAdminsByGroup(db, clinicGroupId) {
|
|
|
3907
3902
|
(0, import_firestore10.where)("clinicGroupId", "==", clinicGroupId)
|
|
3908
3903
|
);
|
|
3909
3904
|
const querySnapshot = await (0, import_firestore10.getDocs)(q);
|
|
3910
|
-
return querySnapshot.docs.map((
|
|
3905
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
3911
3906
|
}
|
|
3912
3907
|
async function updateClinicAdmin(db, adminId, data) {
|
|
3913
3908
|
const admin = await getClinicAdmin(db, adminId);
|
|
@@ -4570,9 +4565,9 @@ var updateAllergyUtil = async (db, patientId, data, requesterId, requesterRoles)
|
|
|
4570
4565
|
};
|
|
4571
4566
|
var removeAllergyUtil = async (db, patientId, allergyIndex, requesterId, requesterRoles) => {
|
|
4572
4567
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4573
|
-
const
|
|
4574
|
-
if (!
|
|
4575
|
-
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();
|
|
4576
4571
|
if (allergyIndex >= medicalInfo.allergies.length) {
|
|
4577
4572
|
throw new Error("Invalid allergy index");
|
|
4578
4573
|
}
|
|
@@ -4599,9 +4594,9 @@ var updateBlockingConditionUtil = async (db, patientId, data, requesterId, reque
|
|
|
4599
4594
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4600
4595
|
const validatedData = updateBlockingConditionSchema.parse(data);
|
|
4601
4596
|
const { conditionIndex, ...updateData } = validatedData;
|
|
4602
|
-
const
|
|
4603
|
-
if (!
|
|
4604
|
-
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();
|
|
4605
4600
|
if (conditionIndex >= medicalInfo.blockingConditions.length) {
|
|
4606
4601
|
throw new Error("Invalid blocking condition index");
|
|
4607
4602
|
}
|
|
@@ -4618,9 +4613,9 @@ var updateBlockingConditionUtil = async (db, patientId, data, requesterId, reque
|
|
|
4618
4613
|
};
|
|
4619
4614
|
var removeBlockingConditionUtil = async (db, patientId, conditionIndex, requesterId, requesterRoles) => {
|
|
4620
4615
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4621
|
-
const
|
|
4622
|
-
if (!
|
|
4623
|
-
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();
|
|
4624
4619
|
if (conditionIndex >= medicalInfo.blockingConditions.length) {
|
|
4625
4620
|
throw new Error("Invalid blocking condition index");
|
|
4626
4621
|
}
|
|
@@ -4647,9 +4642,9 @@ var updateContraindicationUtil = async (db, patientId, data, requesterId, reques
|
|
|
4647
4642
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4648
4643
|
const validatedData = updateContraindicationSchema.parse(data);
|
|
4649
4644
|
const { contraindicationIndex, ...updateData } = validatedData;
|
|
4650
|
-
const
|
|
4651
|
-
if (!
|
|
4652
|
-
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();
|
|
4653
4648
|
if (contraindicationIndex >= medicalInfo.contraindications.length) {
|
|
4654
4649
|
throw new Error("Invalid contraindication index");
|
|
4655
4650
|
}
|
|
@@ -4666,9 +4661,9 @@ var updateContraindicationUtil = async (db, patientId, data, requesterId, reques
|
|
|
4666
4661
|
};
|
|
4667
4662
|
var removeContraindicationUtil = async (db, patientId, contraindicationIndex, requesterId, requesterRoles) => {
|
|
4668
4663
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4669
|
-
const
|
|
4670
|
-
if (!
|
|
4671
|
-
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();
|
|
4672
4667
|
if (contraindicationIndex >= medicalInfo.contraindications.length) {
|
|
4673
4668
|
throw new Error("Invalid contraindication index");
|
|
4674
4669
|
}
|
|
@@ -4695,9 +4690,9 @@ var updateMedicationUtil = async (db, patientId, data, requesterId, requesterRol
|
|
|
4695
4690
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4696
4691
|
const validatedData = updateMedicationSchema.parse(data);
|
|
4697
4692
|
const { medicationIndex, ...updateData } = validatedData;
|
|
4698
|
-
const
|
|
4699
|
-
if (!
|
|
4700
|
-
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();
|
|
4701
4696
|
if (medicationIndex >= medicalInfo.currentMedications.length) {
|
|
4702
4697
|
throw new Error("Invalid medication index");
|
|
4703
4698
|
}
|
|
@@ -4714,9 +4709,9 @@ var updateMedicationUtil = async (db, patientId, data, requesterId, requesterRol
|
|
|
4714
4709
|
};
|
|
4715
4710
|
var removeMedicationUtil = async (db, patientId, medicationIndex, requesterId, requesterRoles) => {
|
|
4716
4711
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4717
|
-
const
|
|
4718
|
-
if (!
|
|
4719
|
-
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();
|
|
4720
4715
|
if (medicationIndex >= medicalInfo.currentMedications.length) {
|
|
4721
4716
|
throw new Error("Invalid medication index");
|
|
4722
4717
|
}
|
|
@@ -5003,7 +4998,7 @@ var searchPatientsUtil = async (db, params, requester) => {
|
|
|
5003
4998
|
const finalQuery = (0, import_firestore16.query)(patientsCollectionRef, ...constraints);
|
|
5004
4999
|
const querySnapshot = await (0, import_firestore16.getDocs)(finalQuery);
|
|
5005
5000
|
const patients = querySnapshot.docs.map(
|
|
5006
|
-
(
|
|
5001
|
+
(doc38) => doc38.data()
|
|
5007
5002
|
);
|
|
5008
5003
|
console.log(
|
|
5009
5004
|
`[searchPatientsUtil] Found ${patients.length} patients matching criteria.`
|
|
@@ -5035,8 +5030,8 @@ var getAllPatientsUtil = async (db, options) => {
|
|
|
5035
5030
|
}
|
|
5036
5031
|
const patientsSnapshot = await (0, import_firestore16.getDocs)(q);
|
|
5037
5032
|
const patients = [];
|
|
5038
|
-
patientsSnapshot.forEach((
|
|
5039
|
-
patients.push(
|
|
5033
|
+
patientsSnapshot.forEach((doc38) => {
|
|
5034
|
+
patients.push(doc38.data());
|
|
5040
5035
|
});
|
|
5041
5036
|
console.log(`[getAllPatientsUtil] Found ${patients.length} patients`);
|
|
5042
5037
|
return patients;
|
|
@@ -5158,7 +5153,7 @@ var getActiveInviteTokensByClinicUtil = async (db, clinicId) => {
|
|
|
5158
5153
|
if (querySnapshot.empty) {
|
|
5159
5154
|
return [];
|
|
5160
5155
|
}
|
|
5161
|
-
return querySnapshot.docs.map((
|
|
5156
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
5162
5157
|
};
|
|
5163
5158
|
var getActiveInviteTokensByPatientUtil = async (db, patientId) => {
|
|
5164
5159
|
const tokensRef = (0, import_firestore17.collection)(
|
|
@@ -5176,7 +5171,7 @@ var getActiveInviteTokensByPatientUtil = async (db, patientId) => {
|
|
|
5176
5171
|
if (querySnapshot.empty) {
|
|
5177
5172
|
return [];
|
|
5178
5173
|
}
|
|
5179
|
-
return querySnapshot.docs.map((
|
|
5174
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
5180
5175
|
};
|
|
5181
5176
|
|
|
5182
5177
|
// src/services/patient/patient.service.ts
|
|
@@ -6448,7 +6443,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6448
6443
|
(0, import_firestore21.where)("expiresAt", ">", import_firestore21.Timestamp.now())
|
|
6449
6444
|
);
|
|
6450
6445
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6451
|
-
return querySnapshot.docs.map((
|
|
6446
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
6452
6447
|
}
|
|
6453
6448
|
/**
|
|
6454
6449
|
* Gets a token by its string value and validates it
|
|
@@ -6558,7 +6553,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6558
6553
|
(0, import_firestore21.where)("status", "==", "active" /* ACTIVE */)
|
|
6559
6554
|
);
|
|
6560
6555
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6561
|
-
return querySnapshot.docs.map((
|
|
6556
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
6562
6557
|
}
|
|
6563
6558
|
/**
|
|
6564
6559
|
* Dohvata sve zdravstvene radnike za određenu kliniku
|
|
@@ -6570,7 +6565,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6570
6565
|
(0, import_firestore21.where)("isActive", "==", true)
|
|
6571
6566
|
);
|
|
6572
6567
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6573
|
-
return querySnapshot.docs.map((
|
|
6568
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
6574
6569
|
}
|
|
6575
6570
|
/**
|
|
6576
6571
|
* Dohvata sve draft zdravstvene radnike za određenu kliniku sa statusom DRAFT
|
|
@@ -6582,7 +6577,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6582
6577
|
(0, import_firestore21.where)("status", "==", "draft" /* DRAFT */)
|
|
6583
6578
|
);
|
|
6584
6579
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6585
|
-
return querySnapshot.docs.map((
|
|
6580
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
6586
6581
|
}
|
|
6587
6582
|
/**
|
|
6588
6583
|
* Updates a practitioner
|
|
@@ -6797,7 +6792,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6797
6792
|
);
|
|
6798
6793
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6799
6794
|
const practitioners = querySnapshot.docs.map(
|
|
6800
|
-
(
|
|
6795
|
+
(doc38) => doc38.data()
|
|
6801
6796
|
);
|
|
6802
6797
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
6803
6798
|
return {
|
|
@@ -6871,7 +6866,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6871
6866
|
constraints.push((0, import_firestore21.limit)(filters.pagination || 10));
|
|
6872
6867
|
const q = (0, import_firestore21.query)((0, import_firestore21.collection)(this.db, PRACTITIONERS_COLLECTION), ...constraints);
|
|
6873
6868
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6874
|
-
const practitioners = querySnapshot.docs.map((
|
|
6869
|
+
const practitioners = querySnapshot.docs.map((doc38) => ({ ...doc38.data(), id: doc38.id }));
|
|
6875
6870
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
6876
6871
|
console.log(`[PRACTITIONER_SERVICE] Strategy 1 success: ${practitioners.length} practitioners`);
|
|
6877
6872
|
if (practitioners.length < (filters.pagination || 10)) {
|
|
@@ -6918,7 +6913,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6918
6913
|
}
|
|
6919
6914
|
const q = (0, import_firestore21.query)((0, import_firestore21.collection)(this.db, PRACTITIONERS_COLLECTION), ...constraints);
|
|
6920
6915
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6921
|
-
let practitioners = querySnapshot.docs.map((
|
|
6916
|
+
let practitioners = querySnapshot.docs.map((doc38) => ({ ...doc38.data(), id: doc38.id }));
|
|
6922
6917
|
if (filters.location && filters.radiusInKm && filters.radiusInKm > 0) {
|
|
6923
6918
|
const location = filters.location;
|
|
6924
6919
|
const radiusInKm = filters.radiusInKm;
|
|
@@ -6954,7 +6949,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6954
6949
|
];
|
|
6955
6950
|
const q = (0, import_firestore21.query)((0, import_firestore21.collection)(this.db, PRACTITIONERS_COLLECTION), ...constraints);
|
|
6956
6951
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6957
|
-
let practitioners = querySnapshot.docs.map((
|
|
6952
|
+
let practitioners = querySnapshot.docs.map((doc38) => ({ ...doc38.data(), id: doc38.id }));
|
|
6958
6953
|
practitioners = this.applyInMemoryFilters(practitioners, filters);
|
|
6959
6954
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
6960
6955
|
console.log(`[PRACTITIONER_SERVICE] Strategy 3 success: ${practitioners.length} practitioners`);
|
|
@@ -6975,7 +6970,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6975
6970
|
];
|
|
6976
6971
|
const q = (0, import_firestore21.query)((0, import_firestore21.collection)(this.db, PRACTITIONERS_COLLECTION), ...constraints);
|
|
6977
6972
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6978
|
-
let practitioners = querySnapshot.docs.map((
|
|
6973
|
+
let practitioners = querySnapshot.docs.map((doc38) => ({ ...doc38.data(), id: doc38.id }));
|
|
6979
6974
|
practitioners = this.applyInMemoryFilters(practitioners, filters);
|
|
6980
6975
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
6981
6976
|
console.log(`[PRACTITIONER_SERVICE] Strategy 4 success: ${practitioners.length} practitioners`);
|
|
@@ -7490,7 +7485,7 @@ var UserService = class extends BaseService {
|
|
|
7490
7485
|
];
|
|
7491
7486
|
const q = (0, import_firestore22.query)((0, import_firestore22.collection)(this.db, USERS_COLLECTION), ...constraints);
|
|
7492
7487
|
const querySnapshot = await (0, import_firestore22.getDocs)(q);
|
|
7493
|
-
const users = querySnapshot.docs.map((
|
|
7488
|
+
const users = querySnapshot.docs.map((doc38) => doc38.data());
|
|
7494
7489
|
return users.map((userData) => userSchema.parse(userData));
|
|
7495
7490
|
}
|
|
7496
7491
|
/**
|
|
@@ -7854,7 +7849,7 @@ async function getAllActiveGroups(db) {
|
|
|
7854
7849
|
(0, import_firestore23.where)("isActive", "==", true)
|
|
7855
7850
|
);
|
|
7856
7851
|
const querySnapshot = await (0, import_firestore23.getDocs)(q);
|
|
7857
|
-
return querySnapshot.docs.map((
|
|
7852
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
7858
7853
|
}
|
|
7859
7854
|
async function updateClinicGroup(db, groupId, data, app) {
|
|
7860
7855
|
console.log("[CLINIC_GROUP] Updating clinic group", { groupId });
|
|
@@ -8295,7 +8290,7 @@ async function getClinicsByGroup(db, groupId) {
|
|
|
8295
8290
|
(0, import_firestore24.where)("isActive", "==", true)
|
|
8296
8291
|
);
|
|
8297
8292
|
const querySnapshot = await (0, import_firestore24.getDocs)(q);
|
|
8298
|
-
return querySnapshot.docs.map((
|
|
8293
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
8299
8294
|
}
|
|
8300
8295
|
async function updateClinic(db, clinicId, data, adminId, clinicAdminService, app) {
|
|
8301
8296
|
console.log("[CLINIC] Starting clinic update", { clinicId, adminId });
|
|
@@ -8489,7 +8484,7 @@ async function getClinicsByAdmin(db, adminId, options = {}, clinicAdminService,
|
|
|
8489
8484
|
}
|
|
8490
8485
|
const q = (0, import_firestore24.query)((0, import_firestore24.collection)(db, CLINICS_COLLECTION), ...constraints);
|
|
8491
8486
|
const querySnapshot = await (0, import_firestore24.getDocs)(q);
|
|
8492
|
-
return querySnapshot.docs.map((
|
|
8487
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
8493
8488
|
}
|
|
8494
8489
|
async function getActiveClinicsByAdmin(db, adminId, clinicAdminService, clinicGroupService) {
|
|
8495
8490
|
return getClinicsByAdmin(
|
|
@@ -8534,11 +8529,11 @@ async function getAllClinics(db, pagination, lastDoc) {
|
|
|
8534
8529
|
}
|
|
8535
8530
|
const clinicsSnapshot = await (0, import_firestore24.getDocs)(clinicsQuery);
|
|
8536
8531
|
const lastVisible = clinicsSnapshot.docs[clinicsSnapshot.docs.length - 1];
|
|
8537
|
-
const clinics = clinicsSnapshot.docs.map((
|
|
8538
|
-
const data =
|
|
8532
|
+
const clinics = clinicsSnapshot.docs.map((doc38) => {
|
|
8533
|
+
const data = doc38.data();
|
|
8539
8534
|
return {
|
|
8540
8535
|
...data,
|
|
8541
|
-
id:
|
|
8536
|
+
id: doc38.id
|
|
8542
8537
|
};
|
|
8543
8538
|
});
|
|
8544
8539
|
return {
|
|
@@ -8565,8 +8560,8 @@ async function getAllClinicsInRange(db, center, rangeInKm, pagination, lastDoc)
|
|
|
8565
8560
|
];
|
|
8566
8561
|
const q = (0, import_firestore24.query)((0, import_firestore24.collection)(db, CLINICS_COLLECTION), ...constraints);
|
|
8567
8562
|
const querySnapshot = await (0, import_firestore24.getDocs)(q);
|
|
8568
|
-
for (const
|
|
8569
|
-
const clinic =
|
|
8563
|
+
for (const doc38 of querySnapshot.docs) {
|
|
8564
|
+
const clinic = doc38.data();
|
|
8570
8565
|
const distance = (0, import_geofire_common4.distanceBetween)(
|
|
8571
8566
|
[center.latitude, center.longitude],
|
|
8572
8567
|
[clinic.location.latitude, clinic.location.longitude]
|
|
@@ -8683,8 +8678,8 @@ async function findClinicsInRadius(db, center, radiusInKm, filters) {
|
|
|
8683
8678
|
}
|
|
8684
8679
|
const q = (0, import_firestore25.query)((0, import_firestore25.collection)(db, CLINICS_COLLECTION), ...constraints);
|
|
8685
8680
|
const querySnapshot = await (0, import_firestore25.getDocs)(q);
|
|
8686
|
-
for (const
|
|
8687
|
-
const clinic =
|
|
8681
|
+
for (const doc38 of querySnapshot.docs) {
|
|
8682
|
+
const clinic = doc38.data();
|
|
8688
8683
|
const distance = (0, import_geofire_common5.distanceBetween)(
|
|
8689
8684
|
[center.latitude, center.longitude],
|
|
8690
8685
|
[clinic.location.latitude, clinic.location.longitude]
|
|
@@ -8805,7 +8800,7 @@ async function getClinicsByFilters(db, filters) {
|
|
|
8805
8800
|
constraints.push((0, import_firestore26.limit)(filters.pagination || 5));
|
|
8806
8801
|
const q = (0, import_firestore26.query)((0, import_firestore26.collection)(db, CLINICS_COLLECTION), ...constraints);
|
|
8807
8802
|
const querySnapshot = await (0, import_firestore26.getDocs)(q);
|
|
8808
|
-
let clinics = querySnapshot.docs.map((
|
|
8803
|
+
let clinics = querySnapshot.docs.map((doc38) => ({ ...doc38.data(), id: doc38.id }));
|
|
8809
8804
|
clinics = applyInMemoryFilters(clinics, filters);
|
|
8810
8805
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
8811
8806
|
console.log(`[CLINIC_SERVICE] Strategy 1 success: ${clinics.length} clinics`);
|
|
@@ -8837,7 +8832,7 @@ async function getClinicsByFilters(db, filters) {
|
|
|
8837
8832
|
constraints.push((0, import_firestore26.limit)(filters.pagination || 5));
|
|
8838
8833
|
const q = (0, import_firestore26.query)((0, import_firestore26.collection)(db, CLINICS_COLLECTION), ...constraints);
|
|
8839
8834
|
const querySnapshot = await (0, import_firestore26.getDocs)(q);
|
|
8840
|
-
let clinics = querySnapshot.docs.map((
|
|
8835
|
+
let clinics = querySnapshot.docs.map((doc38) => ({ ...doc38.data(), id: doc38.id }));
|
|
8841
8836
|
clinics = applyInMemoryFilters(clinics, filters);
|
|
8842
8837
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
8843
8838
|
console.log(`[CLINIC_SERVICE] Strategy 2 success: ${clinics.length} clinics`);
|
|
@@ -8867,7 +8862,7 @@ async function getClinicsByFilters(db, filters) {
|
|
|
8867
8862
|
constraints.push((0, import_firestore26.limit)(filters.pagination || 5));
|
|
8868
8863
|
const q = (0, import_firestore26.query)((0, import_firestore26.collection)(db, CLINICS_COLLECTION), ...constraints);
|
|
8869
8864
|
const querySnapshot = await (0, import_firestore26.getDocs)(q);
|
|
8870
|
-
let clinics = querySnapshot.docs.map((
|
|
8865
|
+
let clinics = querySnapshot.docs.map((doc38) => ({ ...doc38.data(), id: doc38.id }));
|
|
8871
8866
|
clinics = applyInMemoryFilters(clinics, filters);
|
|
8872
8867
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
8873
8868
|
console.log(`[CLINIC_SERVICE] Strategy 3 success: ${clinics.length} clinics`);
|
|
@@ -8887,7 +8882,7 @@ async function getClinicsByFilters(db, filters) {
|
|
|
8887
8882
|
];
|
|
8888
8883
|
const q = (0, import_firestore26.query)((0, import_firestore26.collection)(db, CLINICS_COLLECTION), ...constraints);
|
|
8889
8884
|
const querySnapshot = await (0, import_firestore26.getDocs)(q);
|
|
8890
|
-
let clinics = querySnapshot.docs.map((
|
|
8885
|
+
let clinics = querySnapshot.docs.map((doc38) => ({ ...doc38.data(), id: doc38.id }));
|
|
8891
8886
|
clinics = applyInMemoryFilters(clinics, filters);
|
|
8892
8887
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
8893
8888
|
console.log(`[CLINIC_SERVICE] Strategy 4 success: ${clinics.length} clinics`);
|
|
@@ -9463,11 +9458,11 @@ var ClinicService = class extends BaseService {
|
|
|
9463
9458
|
async getClinicsForMap() {
|
|
9464
9459
|
const clinicsRef = (0, import_firestore27.collection)(this.db, CLINICS_COLLECTION);
|
|
9465
9460
|
const snapshot = await (0, import_firestore27.getDocs)(clinicsRef);
|
|
9466
|
-
const clinicsForMap = snapshot.docs.map((
|
|
9461
|
+
const clinicsForMap = snapshot.docs.map((doc38) => {
|
|
9467
9462
|
var _a, _b, _c;
|
|
9468
|
-
const data =
|
|
9463
|
+
const data = doc38.data();
|
|
9469
9464
|
return {
|
|
9470
|
-
id:
|
|
9465
|
+
id: doc38.id,
|
|
9471
9466
|
name: data.name,
|
|
9472
9467
|
address: ((_a = data.location) == null ? void 0 : _a.address) || "",
|
|
9473
9468
|
latitude: (_b = data.location) == null ? void 0 : _b.latitude,
|
|
@@ -10628,7 +10623,7 @@ async function updatePractitionerCalendarEventUtil(db, practitionerId, eventId,
|
|
|
10628
10623
|
}
|
|
10629
10624
|
|
|
10630
10625
|
// src/services/calendar/utils/appointment.utils.ts
|
|
10631
|
-
async function
|
|
10626
|
+
async function createAppointmentUtil(db, clinicId, practitionerId, patientId, eventData, generateId2) {
|
|
10632
10627
|
const eventId = generateId2();
|
|
10633
10628
|
const autoConfirm = await checkAutoConfirmAppointmentsUtil(db, clinicId);
|
|
10634
10629
|
const initialStatus = autoConfirm ? "confirmed" /* CONFIRMED */ : "pending" /* PENDING */;
|
|
@@ -10762,7 +10757,7 @@ async function searchCalendarEventsUtil(db, params) {
|
|
|
10762
10757
|
const finalQuery = (0, import_firestore33.query)(collectionRef, ...constraints);
|
|
10763
10758
|
const querySnapshot = await (0, import_firestore33.getDocs)(finalQuery);
|
|
10764
10759
|
const events = querySnapshot.docs.map(
|
|
10765
|
-
(
|
|
10760
|
+
(doc38) => ({ id: doc38.id, ...doc38.data() })
|
|
10766
10761
|
);
|
|
10767
10762
|
return events;
|
|
10768
10763
|
} catch (error) {
|
|
@@ -10844,7 +10839,7 @@ async function getPractitionerSyncedCalendarsUtil(db, practitionerId) {
|
|
|
10844
10839
|
);
|
|
10845
10840
|
const q = (0, import_firestore34.query)(calendarsRef, (0, import_firestore34.orderBy)("createdAt", "desc"));
|
|
10846
10841
|
const querySnapshot = await (0, import_firestore34.getDocs)(q);
|
|
10847
|
-
return querySnapshot.docs.map((
|
|
10842
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
10848
10843
|
}
|
|
10849
10844
|
async function getPatientSyncedCalendarUtil(db, patientId, calendarId) {
|
|
10850
10845
|
const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
|
|
@@ -10861,7 +10856,7 @@ async function getPatientSyncedCalendarsUtil(db, patientId) {
|
|
|
10861
10856
|
);
|
|
10862
10857
|
const q = (0, import_firestore34.query)(calendarsRef, (0, import_firestore34.orderBy)("createdAt", "desc"));
|
|
10863
10858
|
const querySnapshot = await (0, import_firestore34.getDocs)(q);
|
|
10864
|
-
return querySnapshot.docs.map((
|
|
10859
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
10865
10860
|
}
|
|
10866
10861
|
async function getClinicSyncedCalendarUtil(db, clinicId, calendarId) {
|
|
10867
10862
|
const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
|
|
@@ -10878,7 +10873,7 @@ async function getClinicSyncedCalendarsUtil(db, clinicId) {
|
|
|
10878
10873
|
);
|
|
10879
10874
|
const q = (0, import_firestore34.query)(calendarsRef, (0, import_firestore34.orderBy)("createdAt", "desc"));
|
|
10880
10875
|
const querySnapshot = await (0, import_firestore34.getDocs)(q);
|
|
10881
|
-
return querySnapshot.docs.map((
|
|
10876
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
10882
10877
|
}
|
|
10883
10878
|
async function updatePractitionerSyncedCalendarUtil(db, practitionerId, calendarId, updateData) {
|
|
10884
10879
|
const calendarRef = getPractitionerSyncedCalendarDocRef(
|
|
@@ -11946,7 +11941,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
11946
11941
|
syncStatus: "internal" /* INTERNAL */,
|
|
11947
11942
|
eventType: "appointment" /* APPOINTMENT */
|
|
11948
11943
|
};
|
|
11949
|
-
const appointment = await
|
|
11944
|
+
const appointment = await createAppointmentUtil(
|
|
11950
11945
|
this.db,
|
|
11951
11946
|
params.clinicId,
|
|
11952
11947
|
params.doctorId,
|
|
@@ -12233,9 +12228,9 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
12233
12228
|
(0, import_firestore37.where)("eventTime.start", "<=", import_firestore36.Timestamp.fromDate(endDate))
|
|
12234
12229
|
);
|
|
12235
12230
|
const eventsSnapshot = await (0, import_firestore37.getDocs)(q);
|
|
12236
|
-
const events = eventsSnapshot.docs.map((
|
|
12237
|
-
id:
|
|
12238
|
-
...
|
|
12231
|
+
const events = eventsSnapshot.docs.map((doc38) => ({
|
|
12232
|
+
id: doc38.id,
|
|
12233
|
+
...doc38.data()
|
|
12239
12234
|
}));
|
|
12240
12235
|
const calendars = await this.syncedCalendarsService.getPractitionerSyncedCalendars(
|
|
12241
12236
|
doctorId
|
|
@@ -12869,7 +12864,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
12869
12864
|
])
|
|
12870
12865
|
);
|
|
12871
12866
|
const querySnapshot = await (0, import_firestore37.getDocs)(q);
|
|
12872
|
-
return querySnapshot.docs.map((
|
|
12867
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
12873
12868
|
}
|
|
12874
12869
|
/**
|
|
12875
12870
|
* Calculates available time slots based on working hours, schedule and existing appointments
|
|
@@ -13400,7 +13395,7 @@ var PractitionerInviteService = class extends BaseService {
|
|
|
13400
13395
|
...constraints
|
|
13401
13396
|
);
|
|
13402
13397
|
const querySnapshot = await (0, import_firestore40.getDocs)(q);
|
|
13403
|
-
return querySnapshot.docs.map((
|
|
13398
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
13404
13399
|
} catch (error) {
|
|
13405
13400
|
console.error(
|
|
13406
13401
|
"[PractitionerInviteService] Error getting doctor invites:",
|
|
@@ -13429,7 +13424,7 @@ var PractitionerInviteService = class extends BaseService {
|
|
|
13429
13424
|
...constraints
|
|
13430
13425
|
);
|
|
13431
13426
|
const querySnapshot = await (0, import_firestore40.getDocs)(q);
|
|
13432
|
-
return querySnapshot.docs.map((
|
|
13427
|
+
return querySnapshot.docs.map((doc38) => doc38.data());
|
|
13433
13428
|
} catch (error) {
|
|
13434
13429
|
console.error(
|
|
13435
13430
|
"[PractitionerInviteService] Error getting clinic invites:",
|
|
@@ -13585,7 +13580,7 @@ var PractitionerInviteService = class extends BaseService {
|
|
|
13585
13580
|
);
|
|
13586
13581
|
const querySnapshot = await (0, import_firestore40.getDocs)(q);
|
|
13587
13582
|
let invites = querySnapshot.docs.map(
|
|
13588
|
-
(
|
|
13583
|
+
(doc38) => doc38.data()
|
|
13589
13584
|
);
|
|
13590
13585
|
if (filters.fromDate) {
|
|
13591
13586
|
invites = invites.filter(
|
|
@@ -13688,9 +13683,10 @@ var PractitionerInviteService = class extends BaseService {
|
|
|
13688
13683
|
|
|
13689
13684
|
// src/services/documentation-templates/documentation-template.service.ts
|
|
13690
13685
|
var import_firestore41 = require("firebase/firestore");
|
|
13686
|
+
var import_firestore42 = require("firebase/firestore");
|
|
13691
13687
|
var DocumentationTemplateService = class extends BaseService {
|
|
13692
|
-
constructor() {
|
|
13693
|
-
super(...
|
|
13688
|
+
constructor(...args) {
|
|
13689
|
+
super(...args);
|
|
13694
13690
|
this.collectionRef = (0, import_firestore41.collection)(
|
|
13695
13691
|
this.db,
|
|
13696
13692
|
DOCUMENTATION_TEMPLATES_COLLECTION
|
|
@@ -13842,8 +13838,8 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
13842
13838
|
const q = (0, import_firestore41.query)(versionsCollectionRef, (0, import_firestore41.orderBy)("version", "desc"));
|
|
13843
13839
|
const querySnapshot = await (0, import_firestore41.getDocs)(q);
|
|
13844
13840
|
const versions = [];
|
|
13845
|
-
querySnapshot.forEach((
|
|
13846
|
-
versions.push(
|
|
13841
|
+
querySnapshot.forEach((doc38) => {
|
|
13842
|
+
versions.push(doc38.data());
|
|
13847
13843
|
});
|
|
13848
13844
|
return versions;
|
|
13849
13845
|
}
|
|
@@ -13874,15 +13870,97 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
13874
13870
|
const querySnapshot = await (0, import_firestore41.getDocs)(q);
|
|
13875
13871
|
const templates = [];
|
|
13876
13872
|
let lastVisible = null;
|
|
13877
|
-
querySnapshot.forEach((
|
|
13878
|
-
templates.push(
|
|
13879
|
-
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;
|
|
13880
13920
|
});
|
|
13881
13921
|
return {
|
|
13882
13922
|
templates,
|
|
13883
13923
|
lastDoc: lastVisible
|
|
13884
13924
|
};
|
|
13885
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
|
+
}
|
|
13886
13964
|
/**
|
|
13887
13965
|
* Get templates by tags
|
|
13888
13966
|
* @param tags - Tags to filter by
|
|
@@ -13904,9 +13982,9 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
13904
13982
|
const querySnapshot = await (0, import_firestore41.getDocs)(q);
|
|
13905
13983
|
const templates = [];
|
|
13906
13984
|
let lastVisible = null;
|
|
13907
|
-
querySnapshot.forEach((
|
|
13908
|
-
templates.push(
|
|
13909
|
-
lastVisible =
|
|
13985
|
+
querySnapshot.forEach((doc38) => {
|
|
13986
|
+
templates.push(doc38.data());
|
|
13987
|
+
lastVisible = doc38;
|
|
13910
13988
|
});
|
|
13911
13989
|
return {
|
|
13912
13990
|
templates,
|
|
@@ -13933,9 +14011,9 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
13933
14011
|
const querySnapshot = await (0, import_firestore41.getDocs)(q);
|
|
13934
14012
|
const templates = [];
|
|
13935
14013
|
let lastVisible = null;
|
|
13936
|
-
querySnapshot.forEach((
|
|
13937
|
-
templates.push(
|
|
13938
|
-
lastVisible =
|
|
14014
|
+
querySnapshot.forEach((doc38) => {
|
|
14015
|
+
templates.push(doc38.data());
|
|
14016
|
+
lastVisible = doc38;
|
|
13939
14017
|
});
|
|
13940
14018
|
return {
|
|
13941
14019
|
templates,
|
|
@@ -13961,15 +14039,15 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
13961
14039
|
}
|
|
13962
14040
|
const querySnapshot = await (0, import_firestore41.getDocs)(q);
|
|
13963
14041
|
const templates = [];
|
|
13964
|
-
querySnapshot.forEach((
|
|
13965
|
-
templates.push(
|
|
14042
|
+
querySnapshot.forEach((doc38) => {
|
|
14043
|
+
templates.push(doc38.data());
|
|
13966
14044
|
});
|
|
13967
14045
|
return templates;
|
|
13968
14046
|
}
|
|
13969
14047
|
};
|
|
13970
14048
|
|
|
13971
14049
|
// src/services/documentation-templates/filled-document.service.ts
|
|
13972
|
-
var
|
|
14050
|
+
var import_firestore43 = require("firebase/firestore");
|
|
13973
14051
|
var FilledDocumentService = class extends BaseService {
|
|
13974
14052
|
constructor(...args) {
|
|
13975
14053
|
super(...args);
|
|
@@ -14024,7 +14102,7 @@ var FilledDocumentService = class extends BaseService {
|
|
|
14024
14102
|
values: initialValues,
|
|
14025
14103
|
status: initialStatus
|
|
14026
14104
|
};
|
|
14027
|
-
const docRef = (0,
|
|
14105
|
+
const docRef = (0, import_firestore43.doc)(
|
|
14028
14106
|
this.db,
|
|
14029
14107
|
APPOINTMENTS_COLLECTION,
|
|
14030
14108
|
// Replaced "appointments"
|
|
@@ -14032,7 +14110,7 @@ var FilledDocumentService = class extends BaseService {
|
|
|
14032
14110
|
formSubcollection,
|
|
14033
14111
|
documentId3
|
|
14034
14112
|
);
|
|
14035
|
-
await (0,
|
|
14113
|
+
await (0, import_firestore43.setDoc)(docRef, filledDocument);
|
|
14036
14114
|
return filledDocument;
|
|
14037
14115
|
}
|
|
14038
14116
|
/**
|
|
@@ -14044,7 +14122,7 @@ var FilledDocumentService = class extends BaseService {
|
|
|
14044
14122
|
*/
|
|
14045
14123
|
async getFilledDocumentFromAppointmentById(appointmentId, formId, isUserForm) {
|
|
14046
14124
|
const formSubcollection = this.getFormSubcollectionPath(isUserForm);
|
|
14047
|
-
const docRef = (0,
|
|
14125
|
+
const docRef = (0, import_firestore43.doc)(
|
|
14048
14126
|
this.db,
|
|
14049
14127
|
APPOINTMENTS_COLLECTION,
|
|
14050
14128
|
// Replaced "appointments"
|
|
@@ -14052,7 +14130,7 @@ var FilledDocumentService = class extends BaseService {
|
|
|
14052
14130
|
formSubcollection,
|
|
14053
14131
|
formId
|
|
14054
14132
|
);
|
|
14055
|
-
const docSnap = await (0,
|
|
14133
|
+
const docSnap = await (0, import_firestore43.getDoc)(docRef);
|
|
14056
14134
|
if (!docSnap.exists()) {
|
|
14057
14135
|
return null;
|
|
14058
14136
|
}
|
|
@@ -14069,7 +14147,7 @@ var FilledDocumentService = class extends BaseService {
|
|
|
14069
14147
|
*/
|
|
14070
14148
|
async updateFilledDocumentInAppointment(appointmentId, formId, isUserForm, values, status) {
|
|
14071
14149
|
const formSubcollection = this.getFormSubcollectionPath(isUserForm);
|
|
14072
|
-
const docRef = (0,
|
|
14150
|
+
const docRef = (0, import_firestore43.doc)(
|
|
14073
14151
|
this.db,
|
|
14074
14152
|
APPOINTMENTS_COLLECTION,
|
|
14075
14153
|
// Replaced "appointments"
|
|
@@ -14101,7 +14179,7 @@ var FilledDocumentService = class extends BaseService {
|
|
|
14101
14179
|
}
|
|
14102
14180
|
if (Object.keys(updatePayload).length === 1 && "updatedAt" in updatePayload) {
|
|
14103
14181
|
}
|
|
14104
|
-
await (0,
|
|
14182
|
+
await (0, import_firestore43.updateDoc)(docRef, updatePayload);
|
|
14105
14183
|
return { ...existingDoc, ...updatePayload };
|
|
14106
14184
|
}
|
|
14107
14185
|
/**
|
|
@@ -14111,20 +14189,20 @@ var FilledDocumentService = class extends BaseService {
|
|
|
14111
14189
|
* @param lastDoc Last document from previous page for pagination.
|
|
14112
14190
|
*/
|
|
14113
14191
|
async getFilledUserFormsForAppointment(appointmentId, pageSize = 20, lastDoc) {
|
|
14114
|
-
const subcollectionRef = (0,
|
|
14192
|
+
const subcollectionRef = (0, import_firestore43.collection)(
|
|
14115
14193
|
this.db,
|
|
14116
14194
|
APPOINTMENTS_COLLECTION,
|
|
14117
14195
|
// Replaced "appointments"
|
|
14118
14196
|
appointmentId,
|
|
14119
14197
|
USER_FORMS_SUBCOLLECTION
|
|
14120
14198
|
);
|
|
14121
|
-
let q = (0,
|
|
14199
|
+
let q = (0, import_firestore43.query)(
|
|
14122
14200
|
subcollectionRef,
|
|
14123
|
-
(0,
|
|
14124
|
-
(0,
|
|
14201
|
+
(0, import_firestore43.orderBy)("updatedAt", "desc"),
|
|
14202
|
+
(0, import_firestore43.limit)(pageSize)
|
|
14125
14203
|
);
|
|
14126
14204
|
if (lastDoc) {
|
|
14127
|
-
q = (0,
|
|
14205
|
+
q = (0, import_firestore43.query)(q, (0, import_firestore43.startAfter)(lastDoc));
|
|
14128
14206
|
}
|
|
14129
14207
|
return this.executeQuery(q);
|
|
14130
14208
|
}
|
|
@@ -14135,31 +14213,31 @@ var FilledDocumentService = class extends BaseService {
|
|
|
14135
14213
|
* @param lastDoc Last document from previous page for pagination.
|
|
14136
14214
|
*/
|
|
14137
14215
|
async getFilledDoctorFormsForAppointment(appointmentId, pageSize = 20, lastDoc) {
|
|
14138
|
-
const subcollectionRef = (0,
|
|
14216
|
+
const subcollectionRef = (0, import_firestore43.collection)(
|
|
14139
14217
|
this.db,
|
|
14140
14218
|
APPOINTMENTS_COLLECTION,
|
|
14141
14219
|
// Replaced "appointments"
|
|
14142
14220
|
appointmentId,
|
|
14143
14221
|
DOCTOR_FORMS_SUBCOLLECTION
|
|
14144
14222
|
);
|
|
14145
|
-
let q = (0,
|
|
14223
|
+
let q = (0, import_firestore43.query)(
|
|
14146
14224
|
subcollectionRef,
|
|
14147
|
-
(0,
|
|
14148
|
-
(0,
|
|
14225
|
+
(0, import_firestore43.orderBy)("updatedAt", "desc"),
|
|
14226
|
+
(0, import_firestore43.limit)(pageSize)
|
|
14149
14227
|
);
|
|
14150
14228
|
if (lastDoc) {
|
|
14151
|
-
q = (0,
|
|
14229
|
+
q = (0, import_firestore43.query)(q, (0, import_firestore43.startAfter)(lastDoc));
|
|
14152
14230
|
}
|
|
14153
14231
|
return this.executeQuery(q);
|
|
14154
14232
|
}
|
|
14155
14233
|
// Helper to execute query and return documents + lastDoc
|
|
14156
14234
|
async executeQuery(q) {
|
|
14157
|
-
const querySnapshot = await (0,
|
|
14235
|
+
const querySnapshot = await (0, import_firestore43.getDocs)(q);
|
|
14158
14236
|
const documents = [];
|
|
14159
14237
|
let lastVisible = null;
|
|
14160
|
-
querySnapshot.forEach((
|
|
14161
|
-
documents.push(
|
|
14162
|
-
lastVisible =
|
|
14238
|
+
querySnapshot.forEach((doc38) => {
|
|
14239
|
+
documents.push(doc38.data());
|
|
14240
|
+
lastVisible = doc38;
|
|
14163
14241
|
});
|
|
14164
14242
|
return {
|
|
14165
14243
|
documents,
|
|
@@ -14318,14 +14396,14 @@ var FilledDocumentService = class extends BaseService {
|
|
|
14318
14396
|
};
|
|
14319
14397
|
|
|
14320
14398
|
// src/services/notifications/notification.service.ts
|
|
14321
|
-
var
|
|
14399
|
+
var import_firestore44 = require("firebase/firestore");
|
|
14322
14400
|
var NotificationService = class extends BaseService {
|
|
14323
14401
|
/**
|
|
14324
14402
|
* Kreira novu notifikaciju
|
|
14325
14403
|
*/
|
|
14326
14404
|
async createNotification(notification) {
|
|
14327
|
-
const notificationsRef = (0,
|
|
14328
|
-
const now =
|
|
14405
|
+
const notificationsRef = (0, import_firestore44.collection)(this.db, NOTIFICATIONS_COLLECTION);
|
|
14406
|
+
const now = import_firestore44.Timestamp.now();
|
|
14329
14407
|
const notificationData = {
|
|
14330
14408
|
...notification,
|
|
14331
14409
|
createdAt: now,
|
|
@@ -14334,7 +14412,7 @@ var NotificationService = class extends BaseService {
|
|
|
14334
14412
|
isRead: false,
|
|
14335
14413
|
userRole: notification.userRole || "patient" /* PATIENT */
|
|
14336
14414
|
};
|
|
14337
|
-
const docRef = await (0,
|
|
14415
|
+
const docRef = await (0, import_firestore44.addDoc)(notificationsRef, notificationData);
|
|
14338
14416
|
return {
|
|
14339
14417
|
...notificationData,
|
|
14340
14418
|
id: docRef.id
|
|
@@ -14344,12 +14422,12 @@ var NotificationService = class extends BaseService {
|
|
|
14344
14422
|
* Dohvata notifikaciju po ID-u
|
|
14345
14423
|
*/
|
|
14346
14424
|
async getNotification(notificationId) {
|
|
14347
|
-
const notificationRef = (0,
|
|
14425
|
+
const notificationRef = (0, import_firestore44.doc)(
|
|
14348
14426
|
this.db,
|
|
14349
14427
|
NOTIFICATIONS_COLLECTION,
|
|
14350
14428
|
notificationId
|
|
14351
14429
|
);
|
|
14352
|
-
const notificationDoc = await (0,
|
|
14430
|
+
const notificationDoc = await (0, import_firestore44.getDoc)(notificationRef);
|
|
14353
14431
|
if (!notificationDoc.exists()) {
|
|
14354
14432
|
return null;
|
|
14355
14433
|
}
|
|
@@ -14362,45 +14440,45 @@ var NotificationService = class extends BaseService {
|
|
|
14362
14440
|
* Dohvata sve notifikacije za korisnika
|
|
14363
14441
|
*/
|
|
14364
14442
|
async getUserNotifications(userId) {
|
|
14365
|
-
const q = (0,
|
|
14366
|
-
(0,
|
|
14367
|
-
(0,
|
|
14368
|
-
(0,
|
|
14369
|
-
);
|
|
14370
|
-
const querySnapshot = await (0,
|
|
14371
|
-
return querySnapshot.docs.map((
|
|
14372
|
-
id:
|
|
14373
|
-
...
|
|
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()
|
|
14374
14452
|
}));
|
|
14375
14453
|
}
|
|
14376
14454
|
/**
|
|
14377
14455
|
* Dohvata nepročitane notifikacije za korisnika
|
|
14378
14456
|
*/
|
|
14379
14457
|
async getUnreadNotifications(userId) {
|
|
14380
|
-
const q = (0,
|
|
14381
|
-
(0,
|
|
14382
|
-
(0,
|
|
14383
|
-
(0,
|
|
14384
|
-
(0,
|
|
14385
|
-
);
|
|
14386
|
-
const querySnapshot = await (0,
|
|
14387
|
-
return querySnapshot.docs.map((
|
|
14388
|
-
id:
|
|
14389
|
-
...
|
|
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()
|
|
14390
14468
|
}));
|
|
14391
14469
|
}
|
|
14392
14470
|
/**
|
|
14393
14471
|
* Označava notifikaciju kao pročitanu
|
|
14394
14472
|
*/
|
|
14395
14473
|
async markAsRead(notificationId) {
|
|
14396
|
-
const notificationRef = (0,
|
|
14474
|
+
const notificationRef = (0, import_firestore44.doc)(
|
|
14397
14475
|
this.db,
|
|
14398
14476
|
NOTIFICATIONS_COLLECTION,
|
|
14399
14477
|
notificationId
|
|
14400
14478
|
);
|
|
14401
|
-
await (0,
|
|
14479
|
+
await (0, import_firestore44.updateDoc)(notificationRef, {
|
|
14402
14480
|
isRead: true,
|
|
14403
|
-
updatedAt:
|
|
14481
|
+
updatedAt: import_firestore44.Timestamp.now()
|
|
14404
14482
|
});
|
|
14405
14483
|
}
|
|
14406
14484
|
/**
|
|
@@ -14408,16 +14486,16 @@ var NotificationService = class extends BaseService {
|
|
|
14408
14486
|
*/
|
|
14409
14487
|
async markAllAsRead(userId) {
|
|
14410
14488
|
const notifications = await this.getUnreadNotifications(userId);
|
|
14411
|
-
const batch = (0,
|
|
14489
|
+
const batch = (0, import_firestore44.writeBatch)(this.db);
|
|
14412
14490
|
notifications.forEach((notification) => {
|
|
14413
|
-
const notificationRef = (0,
|
|
14491
|
+
const notificationRef = (0, import_firestore44.doc)(
|
|
14414
14492
|
this.db,
|
|
14415
14493
|
NOTIFICATIONS_COLLECTION,
|
|
14416
14494
|
notification.id
|
|
14417
14495
|
);
|
|
14418
14496
|
batch.update(notificationRef, {
|
|
14419
14497
|
isRead: true,
|
|
14420
|
-
updatedAt:
|
|
14498
|
+
updatedAt: import_firestore44.Timestamp.now()
|
|
14421
14499
|
});
|
|
14422
14500
|
});
|
|
14423
14501
|
await batch.commit();
|
|
@@ -14426,74 +14504,74 @@ var NotificationService = class extends BaseService {
|
|
|
14426
14504
|
* Ažurira status notifikacije
|
|
14427
14505
|
*/
|
|
14428
14506
|
async updateNotificationStatus(notificationId, status) {
|
|
14429
|
-
const notificationRef = (0,
|
|
14507
|
+
const notificationRef = (0, import_firestore44.doc)(
|
|
14430
14508
|
this.db,
|
|
14431
14509
|
NOTIFICATIONS_COLLECTION,
|
|
14432
14510
|
notificationId
|
|
14433
14511
|
);
|
|
14434
|
-
await (0,
|
|
14512
|
+
await (0, import_firestore44.updateDoc)(notificationRef, {
|
|
14435
14513
|
status,
|
|
14436
|
-
updatedAt:
|
|
14514
|
+
updatedAt: import_firestore44.Timestamp.now()
|
|
14437
14515
|
});
|
|
14438
14516
|
}
|
|
14439
14517
|
/**
|
|
14440
14518
|
* Briše notifikaciju
|
|
14441
14519
|
*/
|
|
14442
14520
|
async deleteNotification(notificationId) {
|
|
14443
|
-
const notificationRef = (0,
|
|
14521
|
+
const notificationRef = (0, import_firestore44.doc)(
|
|
14444
14522
|
this.db,
|
|
14445
14523
|
NOTIFICATIONS_COLLECTION,
|
|
14446
14524
|
notificationId
|
|
14447
14525
|
);
|
|
14448
|
-
await (0,
|
|
14526
|
+
await (0, import_firestore44.deleteDoc)(notificationRef);
|
|
14449
14527
|
}
|
|
14450
14528
|
/**
|
|
14451
14529
|
* Dohvata notifikacije po tipu
|
|
14452
14530
|
*/
|
|
14453
14531
|
async getNotificationsByType(userId, type) {
|
|
14454
|
-
const q = (0,
|
|
14455
|
-
(0,
|
|
14456
|
-
(0,
|
|
14457
|
-
(0,
|
|
14458
|
-
(0,
|
|
14459
|
-
);
|
|
14460
|
-
const querySnapshot = await (0,
|
|
14461
|
-
return querySnapshot.docs.map((
|
|
14462
|
-
id:
|
|
14463
|
-
...
|
|
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()
|
|
14464
14542
|
}));
|
|
14465
14543
|
}
|
|
14466
14544
|
/**
|
|
14467
14545
|
* Dohvata notifikacije za određeni termin
|
|
14468
14546
|
*/
|
|
14469
14547
|
async getAppointmentNotifications(appointmentId) {
|
|
14470
|
-
const q = (0,
|
|
14471
|
-
(0,
|
|
14472
|
-
(0,
|
|
14473
|
-
(0,
|
|
14474
|
-
);
|
|
14475
|
-
const querySnapshot = await (0,
|
|
14476
|
-
return querySnapshot.docs.map((
|
|
14477
|
-
id:
|
|
14478
|
-
...
|
|
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()
|
|
14479
14557
|
}));
|
|
14480
14558
|
}
|
|
14481
14559
|
};
|
|
14482
14560
|
|
|
14483
14561
|
// src/services/patient/patientRequirements.service.ts
|
|
14484
|
-
var
|
|
14562
|
+
var import_firestore45 = require("firebase/firestore");
|
|
14485
14563
|
var PatientRequirementsService = class extends BaseService {
|
|
14486
14564
|
constructor(db, auth, app) {
|
|
14487
14565
|
super(db, auth, app);
|
|
14488
14566
|
}
|
|
14489
14567
|
getPatientRequirementsCollectionRef(patientId) {
|
|
14490
|
-
return (0,
|
|
14568
|
+
return (0, import_firestore45.collection)(
|
|
14491
14569
|
this.db,
|
|
14492
14570
|
`patients/${patientId}/${PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME}`
|
|
14493
14571
|
);
|
|
14494
14572
|
}
|
|
14495
14573
|
getPatientRequirementDocRef(patientId, instanceId) {
|
|
14496
|
-
return (0,
|
|
14574
|
+
return (0, import_firestore45.doc)(
|
|
14497
14575
|
this.getPatientRequirementsCollectionRef(patientId),
|
|
14498
14576
|
instanceId
|
|
14499
14577
|
);
|
|
@@ -14506,7 +14584,7 @@ var PatientRequirementsService = class extends BaseService {
|
|
|
14506
14584
|
*/
|
|
14507
14585
|
async getPatientRequirementInstance(patientId, instanceId) {
|
|
14508
14586
|
const docRef = this.getPatientRequirementDocRef(patientId, instanceId);
|
|
14509
|
-
const docSnap = await (0,
|
|
14587
|
+
const docSnap = await (0, import_firestore45.getDoc)(docRef);
|
|
14510
14588
|
if (!docSnap.exists()) {
|
|
14511
14589
|
return null;
|
|
14512
14590
|
}
|
|
@@ -14525,22 +14603,22 @@ var PatientRequirementsService = class extends BaseService {
|
|
|
14525
14603
|
*/
|
|
14526
14604
|
async getAllPatientRequirementInstances(patientId, filters, pageLimit = 20, lastVisible) {
|
|
14527
14605
|
const collRef = this.getPatientRequirementsCollectionRef(patientId);
|
|
14528
|
-
let q = (0,
|
|
14606
|
+
let q = (0, import_firestore45.query)(collRef, (0, import_firestore45.orderBy)("createdAt", "desc"));
|
|
14529
14607
|
const queryConstraints = [];
|
|
14530
14608
|
if ((filters == null ? void 0 : filters.appointmentId) && filters.appointmentId !== "all") {
|
|
14531
14609
|
queryConstraints.push(
|
|
14532
|
-
(0,
|
|
14610
|
+
(0, import_firestore45.where)("appointmentId", "==", filters.appointmentId)
|
|
14533
14611
|
);
|
|
14534
14612
|
}
|
|
14535
14613
|
if ((filters == null ? void 0 : filters.statuses) && filters.statuses.length > 0) {
|
|
14536
|
-
queryConstraints.push((0,
|
|
14614
|
+
queryConstraints.push((0, import_firestore45.where)("overallStatus", "in", filters.statuses));
|
|
14537
14615
|
}
|
|
14538
14616
|
if (lastVisible) {
|
|
14539
|
-
queryConstraints.push((0,
|
|
14617
|
+
queryConstraints.push((0, import_firestore45.startAfter)(lastVisible));
|
|
14540
14618
|
}
|
|
14541
|
-
queryConstraints.push((0,
|
|
14542
|
-
q = (0,
|
|
14543
|
-
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);
|
|
14544
14622
|
let requirements = snapshot.docs.map((docSnap) => {
|
|
14545
14623
|
const data = docSnap.data();
|
|
14546
14624
|
return { id: docSnap.id, ...data };
|
|
@@ -14583,7 +14661,7 @@ var PatientRequirementsService = class extends BaseService {
|
|
|
14583
14661
|
*/
|
|
14584
14662
|
async completeInstruction(patientId, instanceId, instructionId) {
|
|
14585
14663
|
const instanceRef = this.getPatientRequirementDocRef(patientId, instanceId);
|
|
14586
|
-
const instanceSnap = await (0,
|
|
14664
|
+
const instanceSnap = await (0, import_firestore45.getDoc)(instanceRef);
|
|
14587
14665
|
if (!instanceSnap.exists()) {
|
|
14588
14666
|
throw new Error(
|
|
14589
14667
|
`PatientRequirementInstance ${instanceId} not found for patient ${patientId}.`
|
|
@@ -14611,7 +14689,7 @@ var PatientRequirementsService = class extends BaseService {
|
|
|
14611
14689
|
`Instruction ${instructionId} is in status ${instructionToUpdate.status} and cannot be marked as completed.`
|
|
14612
14690
|
);
|
|
14613
14691
|
}
|
|
14614
|
-
const now =
|
|
14692
|
+
const now = import_firestore45.Timestamp.now();
|
|
14615
14693
|
const updatedInstructions = [...instance.instructions];
|
|
14616
14694
|
updatedInstructions[instructionIndex] = {
|
|
14617
14695
|
...instructionToUpdate,
|
|
@@ -14638,7 +14716,7 @@ var PatientRequirementsService = class extends BaseService {
|
|
|
14638
14716
|
if (newOverallStatus !== instance.overallStatus) {
|
|
14639
14717
|
updatePayload.overallStatus = newOverallStatus;
|
|
14640
14718
|
}
|
|
14641
|
-
await (0,
|
|
14719
|
+
await (0, import_firestore45.updateDoc)(instanceRef, updatePayload);
|
|
14642
14720
|
return {
|
|
14643
14721
|
...instance,
|
|
14644
14722
|
instructions: updatedInstructions,
|
|
@@ -14651,7 +14729,7 @@ var PatientRequirementsService = class extends BaseService {
|
|
|
14651
14729
|
};
|
|
14652
14730
|
|
|
14653
14731
|
// src/services/procedure/procedure.service.ts
|
|
14654
|
-
var
|
|
14732
|
+
var import_firestore46 = require("firebase/firestore");
|
|
14655
14733
|
|
|
14656
14734
|
// src/validations/procedure.schema.ts
|
|
14657
14735
|
var import_zod24 = require("zod");
|
|
@@ -14751,7 +14829,9 @@ var ProcedureService = class extends BaseService {
|
|
|
14751
14829
|
return media;
|
|
14752
14830
|
}
|
|
14753
14831
|
if (media instanceof File || media instanceof Blob) {
|
|
14754
|
-
console.log(
|
|
14832
|
+
console.log(
|
|
14833
|
+
`[ProcedureService] Uploading ${collectionName} media for ${ownerId}`
|
|
14834
|
+
);
|
|
14755
14835
|
const metadata = await this.mediaService.uploadMedia(
|
|
14756
14836
|
media,
|
|
14757
14837
|
ownerId,
|
|
@@ -14773,7 +14853,11 @@ var ProcedureService = class extends BaseService {
|
|
|
14773
14853
|
if (!mediaArray || mediaArray.length === 0) return [];
|
|
14774
14854
|
const result = [];
|
|
14775
14855
|
for (const media of mediaArray) {
|
|
14776
|
-
const processedUrl = await this.processMedia(
|
|
14856
|
+
const processedUrl = await this.processMedia(
|
|
14857
|
+
media,
|
|
14858
|
+
ownerId,
|
|
14859
|
+
collectionName
|
|
14860
|
+
);
|
|
14777
14861
|
if (processedUrl) {
|
|
14778
14862
|
result.push(processedUrl);
|
|
14779
14863
|
}
|
|
@@ -14786,28 +14870,46 @@ var ProcedureService = class extends BaseService {
|
|
|
14786
14870
|
* @returns The created procedure
|
|
14787
14871
|
*/
|
|
14788
14872
|
async createProcedure(data) {
|
|
14789
|
-
var _a;
|
|
14873
|
+
var _a, _b, _c;
|
|
14790
14874
|
const validatedData = createProcedureSchema.parse(data);
|
|
14791
14875
|
const procedureId = this.generateId();
|
|
14792
14876
|
const [category, subcategory, technology, product] = await Promise.all([
|
|
14793
14877
|
this.categoryService.getById(validatedData.categoryId),
|
|
14794
|
-
this.subcategoryService.getById(
|
|
14878
|
+
this.subcategoryService.getById(
|
|
14879
|
+
validatedData.categoryId,
|
|
14880
|
+
validatedData.subcategoryId
|
|
14881
|
+
),
|
|
14795
14882
|
this.technologyService.getById(validatedData.technologyId),
|
|
14796
|
-
this.productService.getById(
|
|
14883
|
+
this.productService.getById(
|
|
14884
|
+
validatedData.technologyId,
|
|
14885
|
+
validatedData.productId
|
|
14886
|
+
)
|
|
14797
14887
|
]);
|
|
14798
14888
|
if (!category || !subcategory || !technology || !product) {
|
|
14799
14889
|
throw new Error("One or more required base entities not found");
|
|
14800
14890
|
}
|
|
14801
|
-
const clinicRef = (0,
|
|
14802
|
-
|
|
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);
|
|
14803
14897
|
if (!clinicSnapshot.exists()) {
|
|
14804
|
-
throw new Error(
|
|
14898
|
+
throw new Error(
|
|
14899
|
+
`Clinic with ID ${validatedData.clinicBranchId} not found`
|
|
14900
|
+
);
|
|
14805
14901
|
}
|
|
14806
14902
|
const clinic = clinicSnapshot.data();
|
|
14807
|
-
const practitionerRef = (0,
|
|
14808
|
-
|
|
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);
|
|
14809
14909
|
if (!practitionerSnapshot.exists()) {
|
|
14810
|
-
throw new Error(
|
|
14910
|
+
throw new Error(
|
|
14911
|
+
`Practitioner with ID ${validatedData.practitionerId} not found`
|
|
14912
|
+
);
|
|
14811
14913
|
}
|
|
14812
14914
|
const practitioner = practitionerSnapshot.data();
|
|
14813
14915
|
let processedPhotos = [];
|
|
@@ -14848,7 +14950,9 @@ var ProcedureService = class extends BaseService {
|
|
|
14848
14950
|
product,
|
|
14849
14951
|
blockingConditions: technology.blockingConditions,
|
|
14850
14952
|
contraindications: technology.contraindications || [],
|
|
14953
|
+
contraindicationIds: ((_b = technology.contraindications) == null ? void 0 : _b.map((c) => c.id)) || [],
|
|
14851
14954
|
treatmentBenefits: technology.benefits,
|
|
14955
|
+
treatmentBenefitIds: ((_c = technology.benefits) == null ? void 0 : _c.map((b) => b.id)) || [],
|
|
14852
14956
|
preRequirements: technology.requirements.pre,
|
|
14853
14957
|
postRequirements: technology.requirements.post,
|
|
14854
14958
|
certificationRequirement: technology.certificationRequirement,
|
|
@@ -14871,13 +14975,13 @@ var ProcedureService = class extends BaseService {
|
|
|
14871
14975
|
isActive: true
|
|
14872
14976
|
// Default to active
|
|
14873
14977
|
};
|
|
14874
|
-
const procedureRef = (0,
|
|
14875
|
-
await (0,
|
|
14978
|
+
const procedureRef = (0, import_firestore46.doc)(this.db, PROCEDURES_COLLECTION, procedureId);
|
|
14979
|
+
await (0, import_firestore46.setDoc)(procedureRef, {
|
|
14876
14980
|
...newProcedure,
|
|
14877
|
-
createdAt: (0,
|
|
14878
|
-
updatedAt: (0,
|
|
14981
|
+
createdAt: (0, import_firestore46.serverTimestamp)(),
|
|
14982
|
+
updatedAt: (0, import_firestore46.serverTimestamp)()
|
|
14879
14983
|
});
|
|
14880
|
-
const savedDoc = await (0,
|
|
14984
|
+
const savedDoc = await (0, import_firestore46.getDoc)(procedureRef);
|
|
14881
14985
|
return savedDoc.data();
|
|
14882
14986
|
}
|
|
14883
14987
|
/**
|
|
@@ -14889,7 +14993,7 @@ var ProcedureService = class extends BaseService {
|
|
|
14889
14993
|
* @returns A promise that resolves to an array of the newly created procedures.
|
|
14890
14994
|
*/
|
|
14891
14995
|
async bulkCreateProcedures(baseData, practitionerIds) {
|
|
14892
|
-
var _a;
|
|
14996
|
+
var _a, _b, _c;
|
|
14893
14997
|
if (!practitionerIds || practitionerIds.length === 0) {
|
|
14894
14998
|
throw new Error("Practitioner IDs array cannot be empty.");
|
|
14895
14999
|
}
|
|
@@ -14897,16 +15001,24 @@ var ProcedureService = class extends BaseService {
|
|
|
14897
15001
|
const validatedData = createProcedureSchema.parse(validationData);
|
|
14898
15002
|
const [category, subcategory, technology, product, clinicSnapshot] = await Promise.all([
|
|
14899
15003
|
this.categoryService.getById(validatedData.categoryId),
|
|
14900
|
-
this.subcategoryService.getById(
|
|
15004
|
+
this.subcategoryService.getById(
|
|
15005
|
+
validatedData.categoryId,
|
|
15006
|
+
validatedData.subcategoryId
|
|
15007
|
+
),
|
|
14901
15008
|
this.technologyService.getById(validatedData.technologyId),
|
|
14902
|
-
this.productService.getById(
|
|
14903
|
-
|
|
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))
|
|
14904
15014
|
]);
|
|
14905
15015
|
if (!category || !subcategory || !technology || !product) {
|
|
14906
15016
|
throw new Error("One or more required base entities not found");
|
|
14907
15017
|
}
|
|
14908
15018
|
if (!clinicSnapshot.exists()) {
|
|
14909
|
-
throw new Error(
|
|
15019
|
+
throw new Error(
|
|
15020
|
+
`Clinic with ID ${validatedData.clinicBranchId} not found`
|
|
15021
|
+
);
|
|
14910
15022
|
}
|
|
14911
15023
|
const clinic = clinicSnapshot.data();
|
|
14912
15024
|
let processedPhotos = [];
|
|
@@ -14921,21 +15033,25 @@ var ProcedureService = class extends BaseService {
|
|
|
14921
15033
|
const practitionersMap = /* @__PURE__ */ new Map();
|
|
14922
15034
|
for (let i = 0; i < practitionerIds.length; i += 30) {
|
|
14923
15035
|
const chunk = practitionerIds.slice(i, i + 30);
|
|
14924
|
-
const practitionersQuery = (0,
|
|
14925
|
-
(0,
|
|
14926
|
-
(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)
|
|
14927
15039
|
);
|
|
14928
|
-
const practitionersSnapshot = await (0,
|
|
14929
|
-
practitionersSnapshot.docs.forEach((
|
|
14930
|
-
practitionersMap.set(
|
|
15040
|
+
const practitionersSnapshot = await (0, import_firestore46.getDocs)(practitionersQuery);
|
|
15041
|
+
practitionersSnapshot.docs.forEach((doc38) => {
|
|
15042
|
+
practitionersMap.set(doc38.id, doc38.data());
|
|
14931
15043
|
});
|
|
14932
15044
|
}
|
|
14933
15045
|
if (practitionersMap.size !== practitionerIds.length) {
|
|
14934
15046
|
const foundIds = Array.from(practitionersMap.keys());
|
|
14935
|
-
const notFoundIds = practitionerIds.filter(
|
|
14936
|
-
|
|
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
|
+
);
|
|
14937
15053
|
}
|
|
14938
|
-
const batch = (0,
|
|
15054
|
+
const batch = (0, import_firestore46.writeBatch)(this.db);
|
|
14939
15055
|
const createdProcedureIds = [];
|
|
14940
15056
|
const clinicInfo = {
|
|
14941
15057
|
id: clinicSnapshot.id,
|
|
@@ -14957,7 +15073,7 @@ var ProcedureService = class extends BaseService {
|
|
|
14957
15073
|
};
|
|
14958
15074
|
const procedureId = this.generateId();
|
|
14959
15075
|
createdProcedureIds.push(procedureId);
|
|
14960
|
-
const procedureRef = (0,
|
|
15076
|
+
const procedureRef = (0, import_firestore46.doc)(this.db, PROCEDURES_COLLECTION, procedureId);
|
|
14961
15077
|
const newProcedure = {
|
|
14962
15078
|
id: procedureId,
|
|
14963
15079
|
...validatedData,
|
|
@@ -14971,7 +15087,9 @@ var ProcedureService = class extends BaseService {
|
|
|
14971
15087
|
product,
|
|
14972
15088
|
blockingConditions: technology.blockingConditions,
|
|
14973
15089
|
contraindications: technology.contraindications || [],
|
|
15090
|
+
contraindicationIds: ((_b = technology.contraindications) == null ? void 0 : _b.map((c) => c.id)) || [],
|
|
14974
15091
|
treatmentBenefits: technology.benefits,
|
|
15092
|
+
treatmentBenefitIds: ((_c = technology.benefits) == null ? void 0 : _c.map((b) => b.id)) || [],
|
|
14975
15093
|
preRequirements: technology.requirements.pre,
|
|
14976
15094
|
postRequirements: technology.requirements.post,
|
|
14977
15095
|
certificationRequirement: technology.certificationRequirement,
|
|
@@ -14993,18 +15111,21 @@ var ProcedureService = class extends BaseService {
|
|
|
14993
15111
|
};
|
|
14994
15112
|
batch.set(procedureRef, {
|
|
14995
15113
|
...newProcedure,
|
|
14996
|
-
createdAt: (0,
|
|
14997
|
-
updatedAt: (0,
|
|
15114
|
+
createdAt: (0, import_firestore46.serverTimestamp)(),
|
|
15115
|
+
updatedAt: (0, import_firestore46.serverTimestamp)()
|
|
14998
15116
|
});
|
|
14999
15117
|
}
|
|
15000
15118
|
await batch.commit();
|
|
15001
15119
|
const fetchedProcedures = [];
|
|
15002
15120
|
for (let i = 0; i < createdProcedureIds.length; i += 30) {
|
|
15003
15121
|
const chunk = createdProcedureIds.slice(i, i + 30);
|
|
15004
|
-
const q = (0,
|
|
15005
|
-
|
|
15006
|
-
|
|
15007
|
-
|
|
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());
|
|
15008
15129
|
});
|
|
15009
15130
|
}
|
|
15010
15131
|
return fetchedProcedures;
|
|
@@ -15015,8 +15136,8 @@ var ProcedureService = class extends BaseService {
|
|
|
15015
15136
|
* @returns The procedure if found, null otherwise
|
|
15016
15137
|
*/
|
|
15017
15138
|
async getProcedure(id) {
|
|
15018
|
-
const docRef = (0,
|
|
15019
|
-
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);
|
|
15020
15141
|
if (!docSnap.exists()) {
|
|
15021
15142
|
return null;
|
|
15022
15143
|
}
|
|
@@ -15028,13 +15149,13 @@ var ProcedureService = class extends BaseService {
|
|
|
15028
15149
|
* @returns List of procedures
|
|
15029
15150
|
*/
|
|
15030
15151
|
async getProceduresByClinicBranch(clinicBranchId) {
|
|
15031
|
-
const q = (0,
|
|
15032
|
-
(0,
|
|
15033
|
-
(0,
|
|
15034
|
-
(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)
|
|
15035
15156
|
);
|
|
15036
|
-
const snapshot = await (0,
|
|
15037
|
-
return snapshot.docs.map((
|
|
15157
|
+
const snapshot = await (0, import_firestore46.getDocs)(q);
|
|
15158
|
+
return snapshot.docs.map((doc38) => doc38.data());
|
|
15038
15159
|
}
|
|
15039
15160
|
/**
|
|
15040
15161
|
* Gets all procedures for a practitioner
|
|
@@ -15042,13 +15163,13 @@ var ProcedureService = class extends BaseService {
|
|
|
15042
15163
|
* @returns List of procedures
|
|
15043
15164
|
*/
|
|
15044
15165
|
async getProceduresByPractitioner(practitionerId) {
|
|
15045
|
-
const q = (0,
|
|
15046
|
-
(0,
|
|
15047
|
-
(0,
|
|
15048
|
-
(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)
|
|
15049
15170
|
);
|
|
15050
|
-
const snapshot = await (0,
|
|
15051
|
-
return snapshot.docs.map((
|
|
15171
|
+
const snapshot = await (0, import_firestore46.getDocs)(q);
|
|
15172
|
+
return snapshot.docs.map((doc38) => doc38.data());
|
|
15052
15173
|
}
|
|
15053
15174
|
/**
|
|
15054
15175
|
* Gets all inactive procedures for a practitioner
|
|
@@ -15056,13 +15177,13 @@ var ProcedureService = class extends BaseService {
|
|
|
15056
15177
|
* @returns List of inactive procedures
|
|
15057
15178
|
*/
|
|
15058
15179
|
async getInactiveProceduresByPractitioner(practitionerId) {
|
|
15059
|
-
const q = (0,
|
|
15060
|
-
(0,
|
|
15061
|
-
(0,
|
|
15062
|
-
(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)
|
|
15063
15184
|
);
|
|
15064
|
-
const snapshot = await (0,
|
|
15065
|
-
return snapshot.docs.map((
|
|
15185
|
+
const snapshot = await (0, import_firestore46.getDocs)(q);
|
|
15186
|
+
return snapshot.docs.map((doc38) => doc38.data());
|
|
15066
15187
|
}
|
|
15067
15188
|
/**
|
|
15068
15189
|
* Updates a procedure
|
|
@@ -15071,10 +15192,10 @@ var ProcedureService = class extends BaseService {
|
|
|
15071
15192
|
* @returns The updated procedure
|
|
15072
15193
|
*/
|
|
15073
15194
|
async updateProcedure(id, data) {
|
|
15074
|
-
var _a;
|
|
15195
|
+
var _a, _b, _c;
|
|
15075
15196
|
const validatedData = updateProcedureSchema.parse(data);
|
|
15076
|
-
const procedureRef = (0,
|
|
15077
|
-
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);
|
|
15078
15199
|
if (!procedureSnapshot.exists()) {
|
|
15079
15200
|
throw new Error(`Procedure with ID ${id} not found`);
|
|
15080
15201
|
}
|
|
@@ -15095,14 +15216,16 @@ var ProcedureService = class extends BaseService {
|
|
|
15095
15216
|
}
|
|
15096
15217
|
if (validatedData.practitionerId && validatedData.practitionerId !== oldPractitionerId) {
|
|
15097
15218
|
practitionerChanged = true;
|
|
15098
|
-
const newPractitionerRef = (0,
|
|
15219
|
+
const newPractitionerRef = (0, import_firestore46.doc)(
|
|
15099
15220
|
this.db,
|
|
15100
15221
|
PRACTITIONERS_COLLECTION,
|
|
15101
15222
|
validatedData.practitionerId
|
|
15102
15223
|
);
|
|
15103
|
-
const newPractitionerSnap = await (0,
|
|
15224
|
+
const newPractitionerSnap = await (0, import_firestore46.getDoc)(newPractitionerRef);
|
|
15104
15225
|
if (!newPractitionerSnap.exists())
|
|
15105
|
-
throw new Error(
|
|
15226
|
+
throw new Error(
|
|
15227
|
+
`New Practitioner ${validatedData.practitionerId} not found`
|
|
15228
|
+
);
|
|
15106
15229
|
newPractitioner = newPractitionerSnap.data();
|
|
15107
15230
|
updatedProcedureData.doctorInfo = {
|
|
15108
15231
|
id: newPractitioner.id,
|
|
@@ -15116,8 +15239,12 @@ var ProcedureService = class extends BaseService {
|
|
|
15116
15239
|
}
|
|
15117
15240
|
if (validatedData.clinicBranchId && validatedData.clinicBranchId !== oldClinicId) {
|
|
15118
15241
|
clinicChanged = true;
|
|
15119
|
-
const newClinicRef = (0,
|
|
15120
|
-
|
|
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);
|
|
15121
15248
|
if (!newClinicSnap.exists())
|
|
15122
15249
|
throw new Error(`New Clinic ${validatedData.clinicBranchId} not found`);
|
|
15123
15250
|
newClinic = newClinicSnap.data();
|
|
@@ -15135,8 +15262,11 @@ var ProcedureService = class extends BaseService {
|
|
|
15135
15262
|
updatedProcedureData.nameLower = validatedData.name.toLowerCase();
|
|
15136
15263
|
}
|
|
15137
15264
|
if (validatedData.categoryId) {
|
|
15138
|
-
const category = await this.categoryService.getById(
|
|
15139
|
-
|
|
15265
|
+
const category = await this.categoryService.getById(
|
|
15266
|
+
validatedData.categoryId
|
|
15267
|
+
);
|
|
15268
|
+
if (!category)
|
|
15269
|
+
throw new Error(`Category ${validatedData.categoryId} not found`);
|
|
15140
15270
|
updatedProcedureData.category = category;
|
|
15141
15271
|
finalCategoryId = category.id;
|
|
15142
15272
|
}
|
|
@@ -15151,23 +15281,34 @@ var ProcedureService = class extends BaseService {
|
|
|
15151
15281
|
);
|
|
15152
15282
|
updatedProcedureData.subcategory = subcategory;
|
|
15153
15283
|
} else if (validatedData.subcategoryId) {
|
|
15154
|
-
console.warn(
|
|
15284
|
+
console.warn(
|
|
15285
|
+
"Attempted to update subcategory without a valid categoryId"
|
|
15286
|
+
);
|
|
15155
15287
|
}
|
|
15156
15288
|
let finalTechnologyId = existingProcedure.technology.id;
|
|
15157
15289
|
if (validatedData.technologyId) {
|
|
15158
|
-
const technology = await this.technologyService.getById(
|
|
15159
|
-
|
|
15290
|
+
const technology = await this.technologyService.getById(
|
|
15291
|
+
validatedData.technologyId
|
|
15292
|
+
);
|
|
15293
|
+
if (!technology)
|
|
15294
|
+
throw new Error(`Technology ${validatedData.technologyId} not found`);
|
|
15160
15295
|
updatedProcedureData.technology = technology;
|
|
15161
15296
|
finalTechnologyId = technology.id;
|
|
15162
15297
|
updatedProcedureData.blockingConditions = technology.blockingConditions;
|
|
15298
|
+
updatedProcedureData.contraindications = technology.contraindications || [];
|
|
15299
|
+
updatedProcedureData.contraindicationIds = ((_b = technology.contraindications) == null ? void 0 : _b.map((c) => c.id)) || [];
|
|
15163
15300
|
updatedProcedureData.treatmentBenefits = technology.benefits;
|
|
15301
|
+
updatedProcedureData.treatmentBenefitIds = ((_c = technology.benefits) == null ? void 0 : _c.map((b) => b.id)) || [];
|
|
15164
15302
|
updatedProcedureData.preRequirements = technology.requirements.pre;
|
|
15165
15303
|
updatedProcedureData.postRequirements = technology.requirements.post;
|
|
15166
15304
|
updatedProcedureData.certificationRequirement = technology.certificationRequirement;
|
|
15167
15305
|
updatedProcedureData.documentationTemplates = technology.documentationTemplates || [];
|
|
15168
15306
|
}
|
|
15169
15307
|
if (validatedData.productId && finalTechnologyId) {
|
|
15170
|
-
const product = await this.productService.getById(
|
|
15308
|
+
const product = await this.productService.getById(
|
|
15309
|
+
finalTechnologyId,
|
|
15310
|
+
validatedData.productId
|
|
15311
|
+
);
|
|
15171
15312
|
if (!product)
|
|
15172
15313
|
throw new Error(
|
|
15173
15314
|
`Product ${validatedData.productId} not found for technology ${finalTechnologyId}`
|
|
@@ -15176,11 +15317,11 @@ var ProcedureService = class extends BaseService {
|
|
|
15176
15317
|
} else if (validatedData.productId) {
|
|
15177
15318
|
console.warn("Attempted to update product without a valid technologyId");
|
|
15178
15319
|
}
|
|
15179
|
-
await (0,
|
|
15320
|
+
await (0, import_firestore46.updateDoc)(procedureRef, {
|
|
15180
15321
|
...updatedProcedureData,
|
|
15181
|
-
updatedAt: (0,
|
|
15322
|
+
updatedAt: (0, import_firestore46.serverTimestamp)()
|
|
15182
15323
|
});
|
|
15183
|
-
const updatedSnapshot = await (0,
|
|
15324
|
+
const updatedSnapshot = await (0, import_firestore46.getDoc)(procedureRef);
|
|
15184
15325
|
return updatedSnapshot.data();
|
|
15185
15326
|
}
|
|
15186
15327
|
/**
|
|
@@ -15188,15 +15329,15 @@ var ProcedureService = class extends BaseService {
|
|
|
15188
15329
|
* @param id - The ID of the procedure to deactivate
|
|
15189
15330
|
*/
|
|
15190
15331
|
async deactivateProcedure(id) {
|
|
15191
|
-
const procedureRef = (0,
|
|
15192
|
-
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);
|
|
15193
15334
|
if (!procedureSnap.exists()) {
|
|
15194
15335
|
console.warn(`Procedure ${id} not found for deactivation.`);
|
|
15195
15336
|
return;
|
|
15196
15337
|
}
|
|
15197
|
-
await (0,
|
|
15338
|
+
await (0, import_firestore46.updateDoc)(procedureRef, {
|
|
15198
15339
|
isActive: false,
|
|
15199
|
-
updatedAt: (0,
|
|
15340
|
+
updatedAt: (0, import_firestore46.serverTimestamp)()
|
|
15200
15341
|
});
|
|
15201
15342
|
}
|
|
15202
15343
|
/**
|
|
@@ -15205,12 +15346,12 @@ var ProcedureService = class extends BaseService {
|
|
|
15205
15346
|
* @returns A boolean indicating if the deletion was successful
|
|
15206
15347
|
*/
|
|
15207
15348
|
async deleteProcedure(id) {
|
|
15208
|
-
const procedureRef = (0,
|
|
15209
|
-
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);
|
|
15210
15351
|
if (!procedureSnapshot.exists()) {
|
|
15211
15352
|
return false;
|
|
15212
15353
|
}
|
|
15213
|
-
await (0,
|
|
15354
|
+
await (0, import_firestore46.deleteDoc)(procedureRef);
|
|
15214
15355
|
return true;
|
|
15215
15356
|
}
|
|
15216
15357
|
/**
|
|
@@ -15236,31 +15377,35 @@ var ProcedureService = class extends BaseService {
|
|
|
15236
15377
|
*/
|
|
15237
15378
|
async getAllProcedures(pagination, lastDoc) {
|
|
15238
15379
|
try {
|
|
15239
|
-
const proceduresCollection = (0,
|
|
15240
|
-
let proceduresQuery = (0,
|
|
15380
|
+
const proceduresCollection = (0, import_firestore46.collection)(this.db, PROCEDURES_COLLECTION);
|
|
15381
|
+
let proceduresQuery = (0, import_firestore46.query)(proceduresCollection);
|
|
15241
15382
|
if (pagination && pagination > 0) {
|
|
15242
|
-
const { limit:
|
|
15383
|
+
const { limit: limit21, startAfter: startAfter19 } = await import("firebase/firestore");
|
|
15243
15384
|
if (lastDoc) {
|
|
15244
|
-
proceduresQuery = (0,
|
|
15385
|
+
proceduresQuery = (0, import_firestore46.query)(
|
|
15245
15386
|
proceduresCollection,
|
|
15246
|
-
(0,
|
|
15387
|
+
(0, import_firestore46.orderBy)("name"),
|
|
15247
15388
|
// Use imported orderBy
|
|
15248
|
-
|
|
15249
|
-
|
|
15389
|
+
startAfter19(lastDoc),
|
|
15390
|
+
limit21(pagination)
|
|
15250
15391
|
);
|
|
15251
15392
|
} else {
|
|
15252
|
-
proceduresQuery = (0,
|
|
15393
|
+
proceduresQuery = (0, import_firestore46.query)(
|
|
15394
|
+
proceduresCollection,
|
|
15395
|
+
(0, import_firestore46.orderBy)("name"),
|
|
15396
|
+
limit21(pagination)
|
|
15397
|
+
);
|
|
15253
15398
|
}
|
|
15254
15399
|
} else {
|
|
15255
|
-
proceduresQuery = (0,
|
|
15400
|
+
proceduresQuery = (0, import_firestore46.query)(proceduresCollection, (0, import_firestore46.orderBy)("name"));
|
|
15256
15401
|
}
|
|
15257
|
-
const proceduresSnapshot = await (0,
|
|
15402
|
+
const proceduresSnapshot = await (0, import_firestore46.getDocs)(proceduresQuery);
|
|
15258
15403
|
const lastVisible = proceduresSnapshot.docs[proceduresSnapshot.docs.length - 1];
|
|
15259
|
-
const procedures = proceduresSnapshot.docs.map((
|
|
15260
|
-
const data =
|
|
15404
|
+
const procedures = proceduresSnapshot.docs.map((doc38) => {
|
|
15405
|
+
const data = doc38.data();
|
|
15261
15406
|
return {
|
|
15262
15407
|
...data,
|
|
15263
|
-
id:
|
|
15408
|
+
id: doc38.id
|
|
15264
15409
|
// Ensure ID is present
|
|
15265
15410
|
};
|
|
15266
15411
|
});
|
|
@@ -15280,7 +15425,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15280
15425
|
*
|
|
15281
15426
|
* @param filters - Various filters to apply
|
|
15282
15427
|
* @param filters.nameSearch - Optional search text for procedure name
|
|
15283
|
-
* @param filters.
|
|
15428
|
+
* @param filters.treatmentBenefitIds - Optional array of treatment benefits to filter by
|
|
15284
15429
|
* @param filters.procedureFamily - Optional procedure family to filter by
|
|
15285
15430
|
* @param filters.procedureCategory - Optional procedure category to filter by
|
|
15286
15431
|
* @param filters.procedureSubcategory - Optional procedure subcategory to filter by
|
|
@@ -15298,7 +15443,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15298
15443
|
*/
|
|
15299
15444
|
async getProceduresByFilters(filters) {
|
|
15300
15445
|
try {
|
|
15301
|
-
console.log(
|
|
15446
|
+
console.log(
|
|
15447
|
+
"[PROCEDURE_SERVICE] Starting procedure filtering with multiple strategies"
|
|
15448
|
+
);
|
|
15302
15449
|
if (filters.location && filters.radiusInKm) {
|
|
15303
15450
|
console.log("[PROCEDURE_SERVICE] Executing geo query:", {
|
|
15304
15451
|
location: filters.location,
|
|
@@ -15306,7 +15453,10 @@ var ProcedureService = class extends BaseService {
|
|
|
15306
15453
|
serviceName: "ProcedureService"
|
|
15307
15454
|
});
|
|
15308
15455
|
if (!filters.location.latitude || !filters.location.longitude) {
|
|
15309
|
-
console.warn(
|
|
15456
|
+
console.warn(
|
|
15457
|
+
"[PROCEDURE_SERVICE] Invalid location data:",
|
|
15458
|
+
filters.location
|
|
15459
|
+
);
|
|
15310
15460
|
filters.location = void 0;
|
|
15311
15461
|
filters.radiusInKm = void 0;
|
|
15312
15462
|
}
|
|
@@ -15318,65 +15468,88 @@ var ProcedureService = class extends BaseService {
|
|
|
15318
15468
|
const getBaseConstraints = () => {
|
|
15319
15469
|
const constraints = [];
|
|
15320
15470
|
if (filters.isActive !== void 0) {
|
|
15321
|
-
constraints.push((0,
|
|
15471
|
+
constraints.push((0, import_firestore46.where)("isActive", "==", filters.isActive));
|
|
15322
15472
|
} else {
|
|
15323
|
-
constraints.push((0,
|
|
15473
|
+
constraints.push((0, import_firestore46.where)("isActive", "==", true));
|
|
15324
15474
|
}
|
|
15325
15475
|
if (filters.procedureFamily) {
|
|
15326
|
-
constraints.push((0,
|
|
15476
|
+
constraints.push((0, import_firestore46.where)("family", "==", filters.procedureFamily));
|
|
15327
15477
|
}
|
|
15328
15478
|
if (filters.procedureCategory) {
|
|
15329
|
-
constraints.push(
|
|
15479
|
+
constraints.push(
|
|
15480
|
+
(0, import_firestore46.where)("category.id", "==", filters.procedureCategory)
|
|
15481
|
+
);
|
|
15330
15482
|
}
|
|
15331
15483
|
if (filters.procedureSubcategory) {
|
|
15332
|
-
constraints.push(
|
|
15484
|
+
constraints.push(
|
|
15485
|
+
(0, import_firestore46.where)("subcategory.id", "==", filters.procedureSubcategory)
|
|
15486
|
+
);
|
|
15333
15487
|
}
|
|
15334
15488
|
if (filters.procedureTechnology) {
|
|
15335
|
-
constraints.push(
|
|
15489
|
+
constraints.push(
|
|
15490
|
+
(0, import_firestore46.where)("technology.id", "==", filters.procedureTechnology)
|
|
15491
|
+
);
|
|
15336
15492
|
}
|
|
15337
15493
|
if (filters.minPrice !== void 0) {
|
|
15338
|
-
constraints.push((0,
|
|
15494
|
+
constraints.push((0, import_firestore46.where)("price", ">=", filters.minPrice));
|
|
15339
15495
|
}
|
|
15340
15496
|
if (filters.maxPrice !== void 0) {
|
|
15341
|
-
constraints.push((0,
|
|
15497
|
+
constraints.push((0, import_firestore46.where)("price", "<=", filters.maxPrice));
|
|
15342
15498
|
}
|
|
15343
15499
|
if (filters.minRating !== void 0) {
|
|
15344
|
-
constraints.push(
|
|
15500
|
+
constraints.push(
|
|
15501
|
+
(0, import_firestore46.where)("reviewInfo.averageRating", ">=", filters.minRating)
|
|
15502
|
+
);
|
|
15345
15503
|
}
|
|
15346
15504
|
if (filters.maxRating !== void 0) {
|
|
15347
|
-
constraints.push(
|
|
15505
|
+
constraints.push(
|
|
15506
|
+
(0, import_firestore46.where)("reviewInfo.averageRating", "<=", filters.maxRating)
|
|
15507
|
+
);
|
|
15348
15508
|
}
|
|
15349
15509
|
if (filters.treatmentBenefits && filters.treatmentBenefits.length > 0) {
|
|
15350
|
-
const
|
|
15351
|
-
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
|
+
);
|
|
15352
15518
|
}
|
|
15353
15519
|
return constraints;
|
|
15354
15520
|
};
|
|
15355
15521
|
if (filters.nameSearch && filters.nameSearch.trim()) {
|
|
15356
15522
|
try {
|
|
15357
|
-
console.log(
|
|
15523
|
+
console.log(
|
|
15524
|
+
"[PROCEDURE_SERVICE] Strategy 1: Trying nameLower search"
|
|
15525
|
+
);
|
|
15358
15526
|
const searchTerm = filters.nameSearch.trim().toLowerCase();
|
|
15359
15527
|
const constraints = getBaseConstraints();
|
|
15360
|
-
constraints.push((0,
|
|
15361
|
-
constraints.push((0,
|
|
15362
|
-
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"));
|
|
15363
15531
|
if (filters.lastDoc) {
|
|
15364
15532
|
if (typeof filters.lastDoc.data === "function") {
|
|
15365
|
-
constraints.push((0,
|
|
15533
|
+
constraints.push((0, import_firestore46.startAfter)(filters.lastDoc));
|
|
15366
15534
|
} else if (Array.isArray(filters.lastDoc)) {
|
|
15367
|
-
constraints.push((0,
|
|
15535
|
+
constraints.push((0, import_firestore46.startAfter)(...filters.lastDoc));
|
|
15368
15536
|
} else {
|
|
15369
|
-
constraints.push((0,
|
|
15537
|
+
constraints.push((0, import_firestore46.startAfter)(filters.lastDoc));
|
|
15370
15538
|
}
|
|
15371
15539
|
}
|
|
15372
|
-
constraints.push((0,
|
|
15373
|
-
const q = (0,
|
|
15374
|
-
|
|
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);
|
|
15375
15546
|
const procedures = querySnapshot.docs.map(
|
|
15376
|
-
(
|
|
15547
|
+
(doc38) => ({ ...doc38.data(), id: doc38.id })
|
|
15377
15548
|
);
|
|
15378
15549
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15379
|
-
console.log(
|
|
15550
|
+
console.log(
|
|
15551
|
+
`[PROCEDURE_SERVICE] Strategy 1 success: ${procedures.length} procedures`
|
|
15552
|
+
);
|
|
15380
15553
|
if (procedures.length < (filters.pagination || 10)) {
|
|
15381
15554
|
return { procedures, lastDoc: null };
|
|
15382
15555
|
}
|
|
@@ -15387,29 +15560,36 @@ var ProcedureService = class extends BaseService {
|
|
|
15387
15560
|
}
|
|
15388
15561
|
if (filters.nameSearch && filters.nameSearch.trim()) {
|
|
15389
15562
|
try {
|
|
15390
|
-
console.log(
|
|
15563
|
+
console.log(
|
|
15564
|
+
"[PROCEDURE_SERVICE] Strategy 2: Trying name field search"
|
|
15565
|
+
);
|
|
15391
15566
|
const searchTerm = filters.nameSearch.trim().toLowerCase();
|
|
15392
15567
|
const constraints = getBaseConstraints();
|
|
15393
|
-
constraints.push((0,
|
|
15394
|
-
constraints.push((0,
|
|
15395
|
-
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"));
|
|
15396
15571
|
if (filters.lastDoc) {
|
|
15397
15572
|
if (typeof filters.lastDoc.data === "function") {
|
|
15398
|
-
constraints.push((0,
|
|
15573
|
+
constraints.push((0, import_firestore46.startAfter)(filters.lastDoc));
|
|
15399
15574
|
} else if (Array.isArray(filters.lastDoc)) {
|
|
15400
|
-
constraints.push((0,
|
|
15575
|
+
constraints.push((0, import_firestore46.startAfter)(...filters.lastDoc));
|
|
15401
15576
|
} else {
|
|
15402
|
-
constraints.push((0,
|
|
15577
|
+
constraints.push((0, import_firestore46.startAfter)(filters.lastDoc));
|
|
15403
15578
|
}
|
|
15404
15579
|
}
|
|
15405
|
-
constraints.push((0,
|
|
15406
|
-
const q = (0,
|
|
15407
|
-
|
|
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);
|
|
15408
15586
|
const procedures = querySnapshot.docs.map(
|
|
15409
|
-
(
|
|
15587
|
+
(doc38) => ({ ...doc38.data(), id: doc38.id })
|
|
15410
15588
|
);
|
|
15411
15589
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15412
|
-
console.log(
|
|
15590
|
+
console.log(
|
|
15591
|
+
`[PROCEDURE_SERVICE] Strategy 2 success: ${procedures.length} procedures`
|
|
15592
|
+
);
|
|
15413
15593
|
if (procedures.length < (filters.pagination || 10)) {
|
|
15414
15594
|
return { procedures, lastDoc: null };
|
|
15415
15595
|
}
|
|
@@ -15423,25 +15603,30 @@ var ProcedureService = class extends BaseService {
|
|
|
15423
15603
|
"[PROCEDURE_SERVICE] Strategy 3: Using createdAt orderBy with client-side filtering"
|
|
15424
15604
|
);
|
|
15425
15605
|
const constraints = getBaseConstraints();
|
|
15426
|
-
constraints.push((0,
|
|
15606
|
+
constraints.push((0, import_firestore46.orderBy)("createdAt", "desc"));
|
|
15427
15607
|
if (filters.lastDoc) {
|
|
15428
15608
|
if (typeof filters.lastDoc.data === "function") {
|
|
15429
|
-
constraints.push((0,
|
|
15609
|
+
constraints.push((0, import_firestore46.startAfter)(filters.lastDoc));
|
|
15430
15610
|
} else if (Array.isArray(filters.lastDoc)) {
|
|
15431
|
-
constraints.push((0,
|
|
15611
|
+
constraints.push((0, import_firestore46.startAfter)(...filters.lastDoc));
|
|
15432
15612
|
} else {
|
|
15433
|
-
constraints.push((0,
|
|
15613
|
+
constraints.push((0, import_firestore46.startAfter)(filters.lastDoc));
|
|
15434
15614
|
}
|
|
15435
15615
|
}
|
|
15436
|
-
constraints.push((0,
|
|
15437
|
-
const q = (0,
|
|
15438
|
-
|
|
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);
|
|
15439
15622
|
let procedures = querySnapshot.docs.map(
|
|
15440
|
-
(
|
|
15623
|
+
(doc38) => ({ ...doc38.data(), id: doc38.id })
|
|
15441
15624
|
);
|
|
15442
15625
|
procedures = this.applyInMemoryFilters(procedures, filters);
|
|
15443
15626
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15444
|
-
console.log(
|
|
15627
|
+
console.log(
|
|
15628
|
+
`[PROCEDURE_SERVICE] Strategy 3 success: ${procedures.length} procedures`
|
|
15629
|
+
);
|
|
15445
15630
|
if (procedures.length < (filters.pagination || 10)) {
|
|
15446
15631
|
return { procedures, lastDoc: null };
|
|
15447
15632
|
}
|
|
@@ -15452,18 +15637,23 @@ var ProcedureService = class extends BaseService {
|
|
|
15452
15637
|
try {
|
|
15453
15638
|
console.log("[PROCEDURE_SERVICE] Strategy 4: Minimal query fallback");
|
|
15454
15639
|
const constraints = [
|
|
15455
|
-
(0,
|
|
15456
|
-
(0,
|
|
15457
|
-
(0,
|
|
15640
|
+
(0, import_firestore46.where)("isActive", "==", true),
|
|
15641
|
+
(0, import_firestore46.orderBy)("createdAt", "desc"),
|
|
15642
|
+
(0, import_firestore46.limit)(filters.pagination || 10)
|
|
15458
15643
|
];
|
|
15459
|
-
const q = (0,
|
|
15460
|
-
|
|
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);
|
|
15461
15649
|
let procedures = querySnapshot.docs.map(
|
|
15462
|
-
(
|
|
15650
|
+
(doc38) => ({ ...doc38.data(), id: doc38.id })
|
|
15463
15651
|
);
|
|
15464
15652
|
procedures = this.applyInMemoryFilters(procedures, filters);
|
|
15465
15653
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
15466
|
-
console.log(
|
|
15654
|
+
console.log(
|
|
15655
|
+
`[PROCEDURE_SERVICE] Strategy 4 success: ${procedures.length} procedures`
|
|
15656
|
+
);
|
|
15467
15657
|
if (procedures.length < (filters.pagination || 10)) {
|
|
15468
15658
|
return { procedures, lastDoc: null };
|
|
15469
15659
|
}
|
|
@@ -15471,7 +15661,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15471
15661
|
} catch (error) {
|
|
15472
15662
|
console.log("[PROCEDURE_SERVICE] Strategy 4 failed:", error);
|
|
15473
15663
|
}
|
|
15474
|
-
console.log(
|
|
15664
|
+
console.log(
|
|
15665
|
+
"[PROCEDURE_SERVICE] All strategies failed, returning empty result"
|
|
15666
|
+
);
|
|
15475
15667
|
return { procedures: [], lastDoc: null };
|
|
15476
15668
|
} catch (error) {
|
|
15477
15669
|
console.error("[PROCEDURE_SERVICE] Error filtering procedures:", error);
|
|
@@ -15491,13 +15683,17 @@ var ProcedureService = class extends BaseService {
|
|
|
15491
15683
|
const nameLower = procedure.nameLower || "";
|
|
15492
15684
|
return name.includes(searchTerm) || nameLower.includes(searchTerm);
|
|
15493
15685
|
});
|
|
15494
|
-
console.log(
|
|
15686
|
+
console.log(
|
|
15687
|
+
`[PROCEDURE_SERVICE] Applied name filter, results: ${filteredProcedures.length}`
|
|
15688
|
+
);
|
|
15495
15689
|
}
|
|
15496
15690
|
if (filters.minPrice !== void 0 || filters.maxPrice !== void 0) {
|
|
15497
15691
|
filteredProcedures = filteredProcedures.filter((procedure) => {
|
|
15498
15692
|
const price = procedure.price || 0;
|
|
15499
|
-
if (filters.minPrice !== void 0 && price < filters.minPrice)
|
|
15500
|
-
|
|
15693
|
+
if (filters.minPrice !== void 0 && price < filters.minPrice)
|
|
15694
|
+
return false;
|
|
15695
|
+
if (filters.maxPrice !== void 0 && price > filters.maxPrice)
|
|
15696
|
+
return false;
|
|
15501
15697
|
return true;
|
|
15502
15698
|
});
|
|
15503
15699
|
console.log(
|
|
@@ -15508,8 +15704,10 @@ var ProcedureService = class extends BaseService {
|
|
|
15508
15704
|
filteredProcedures = filteredProcedures.filter((procedure) => {
|
|
15509
15705
|
var _a;
|
|
15510
15706
|
const rating = ((_a = procedure.reviewInfo) == null ? void 0 : _a.averageRating) || 0;
|
|
15511
|
-
if (filters.minRating !== void 0 && rating < filters.minRating)
|
|
15512
|
-
|
|
15707
|
+
if (filters.minRating !== void 0 && rating < filters.minRating)
|
|
15708
|
+
return false;
|
|
15709
|
+
if (filters.maxRating !== void 0 && rating > filters.maxRating)
|
|
15710
|
+
return false;
|
|
15513
15711
|
return true;
|
|
15514
15712
|
});
|
|
15515
15713
|
console.log(
|
|
@@ -15517,10 +15715,12 @@ var ProcedureService = class extends BaseService {
|
|
|
15517
15715
|
);
|
|
15518
15716
|
}
|
|
15519
15717
|
if (filters.treatmentBenefits && filters.treatmentBenefits.length > 0) {
|
|
15520
|
-
const
|
|
15718
|
+
const benefitIdsToMatch = filters.treatmentBenefits;
|
|
15521
15719
|
filteredProcedures = filteredProcedures.filter((procedure) => {
|
|
15522
|
-
const
|
|
15523
|
-
return
|
|
15720
|
+
const procedureBenefitIds = procedure.treatmentBenefitIds || [];
|
|
15721
|
+
return benefitIdsToMatch.some(
|
|
15722
|
+
(benefitId) => procedureBenefitIds.includes(benefitId)
|
|
15723
|
+
);
|
|
15524
15724
|
});
|
|
15525
15725
|
console.log(
|
|
15526
15726
|
`[PROCEDURE_SERVICE] Applied benefits filter, results: ${filteredProcedures.length}`
|
|
@@ -15583,8 +15783,12 @@ var ProcedureService = class extends BaseService {
|
|
|
15583
15783
|
procedure.distance = distance;
|
|
15584
15784
|
return distance <= radiusInKm;
|
|
15585
15785
|
});
|
|
15586
|
-
console.log(
|
|
15587
|
-
|
|
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
|
+
);
|
|
15588
15792
|
}
|
|
15589
15793
|
return filteredProcedures;
|
|
15590
15794
|
}
|
|
@@ -15596,19 +15800,30 @@ var ProcedureService = class extends BaseService {
|
|
|
15596
15800
|
if (!location || !radiusInKm) {
|
|
15597
15801
|
return Promise.resolve({ procedures: [], lastDoc: null });
|
|
15598
15802
|
}
|
|
15599
|
-
const bounds = (0, import_geofire_common8.geohashQueryBounds)(
|
|
15803
|
+
const bounds = (0, import_geofire_common8.geohashQueryBounds)(
|
|
15804
|
+
[location.latitude, location.longitude],
|
|
15805
|
+
radiusInKm * 1e3
|
|
15806
|
+
);
|
|
15600
15807
|
const fetches = bounds.map((b) => {
|
|
15601
15808
|
const constraints = [
|
|
15602
|
-
(0,
|
|
15603
|
-
(0,
|
|
15604
|
-
(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
|
+
)
|
|
15605
15816
|
];
|
|
15606
|
-
return (0,
|
|
15817
|
+
return (0, import_firestore46.getDocs)(
|
|
15818
|
+
(0, import_firestore46.query)((0, import_firestore46.collection)(this.db, PROCEDURES_COLLECTION), ...constraints)
|
|
15819
|
+
);
|
|
15607
15820
|
});
|
|
15608
15821
|
return Promise.all(fetches).then((snaps) => {
|
|
15609
15822
|
const collected = [];
|
|
15610
15823
|
snaps.forEach((snap) => {
|
|
15611
|
-
snap.docs.forEach(
|
|
15824
|
+
snap.docs.forEach(
|
|
15825
|
+
(d) => collected.push({ ...d.data(), id: d.id })
|
|
15826
|
+
);
|
|
15612
15827
|
});
|
|
15613
15828
|
const uniqueMap = /* @__PURE__ */ new Map();
|
|
15614
15829
|
for (const p of collected) {
|
|
@@ -15619,7 +15834,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15619
15834
|
const pageSize = filters.pagination || 10;
|
|
15620
15835
|
let startIndex = 0;
|
|
15621
15836
|
if (filters.lastDoc && typeof filters.lastDoc === "object" && filters.lastDoc.id) {
|
|
15622
|
-
const idx = procedures.findIndex(
|
|
15837
|
+
const idx = procedures.findIndex(
|
|
15838
|
+
(p) => p.id === filters.lastDoc.id
|
|
15839
|
+
);
|
|
15623
15840
|
if (idx >= 0) startIndex = idx + 1;
|
|
15624
15841
|
}
|
|
15625
15842
|
const page = procedures.slice(startIndex, startIndex + pageSize);
|
|
@@ -15644,7 +15861,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15644
15861
|
* @returns The created procedure
|
|
15645
15862
|
*/
|
|
15646
15863
|
async createConsultationProcedure(data) {
|
|
15647
|
-
var _a;
|
|
15864
|
+
var _a, _b, _c;
|
|
15648
15865
|
const procedureId = this.generateId();
|
|
15649
15866
|
const [category, subcategory, technology] = await Promise.all([
|
|
15650
15867
|
this.categoryService.getById(data.categoryId),
|
|
@@ -15654,21 +15871,29 @@ var ProcedureService = class extends BaseService {
|
|
|
15654
15871
|
if (!category || !subcategory || !technology) {
|
|
15655
15872
|
throw new Error("One or more required base entities not found");
|
|
15656
15873
|
}
|
|
15657
|
-
const clinicRef = (0,
|
|
15658
|
-
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);
|
|
15659
15876
|
if (!clinicSnapshot.exists()) {
|
|
15660
15877
|
throw new Error(`Clinic with ID ${data.clinicBranchId} not found`);
|
|
15661
15878
|
}
|
|
15662
15879
|
const clinic = clinicSnapshot.data();
|
|
15663
|
-
const practitionerRef = (0,
|
|
15664
|
-
|
|
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);
|
|
15665
15886
|
if (!practitionerSnapshot.exists()) {
|
|
15666
15887
|
throw new Error(`Practitioner with ID ${data.practitionerId} not found`);
|
|
15667
15888
|
}
|
|
15668
15889
|
const practitioner = practitionerSnapshot.data();
|
|
15669
15890
|
let processedPhotos = [];
|
|
15670
15891
|
if (data.photos && data.photos.length > 0) {
|
|
15671
|
-
processedPhotos = await this.processMediaArray(
|
|
15892
|
+
processedPhotos = await this.processMediaArray(
|
|
15893
|
+
data.photos,
|
|
15894
|
+
procedureId,
|
|
15895
|
+
"procedure-photos"
|
|
15896
|
+
);
|
|
15672
15897
|
}
|
|
15673
15898
|
const clinicInfo = {
|
|
15674
15899
|
id: clinicSnapshot.id,
|
|
@@ -15694,6 +15919,8 @@ var ProcedureService = class extends BaseService {
|
|
|
15694
15919
|
brandName: "Consultation",
|
|
15695
15920
|
technologyId: data.technologyId,
|
|
15696
15921
|
technologyName: technology.name,
|
|
15922
|
+
categoryId: technology.categoryId,
|
|
15923
|
+
subcategoryId: technology.subcategoryId,
|
|
15697
15924
|
isActive: true,
|
|
15698
15925
|
createdAt: /* @__PURE__ */ new Date(),
|
|
15699
15926
|
updatedAt: /* @__PURE__ */ new Date()
|
|
@@ -15710,7 +15937,9 @@ var ProcedureService = class extends BaseService {
|
|
|
15710
15937
|
// Use placeholder product
|
|
15711
15938
|
blockingConditions: technology.blockingConditions,
|
|
15712
15939
|
contraindications: technology.contraindications || [],
|
|
15940
|
+
contraindicationIds: ((_b = technology.contraindications) == null ? void 0 : _b.map((c) => c.id)) || [],
|
|
15713
15941
|
treatmentBenefits: technology.benefits,
|
|
15942
|
+
treatmentBenefitIds: ((_c = technology.benefits) == null ? void 0 : _c.map((b) => b.id)) || [],
|
|
15714
15943
|
preRequirements: technology.requirements.pre,
|
|
15715
15944
|
postRequirements: technology.requirements.post,
|
|
15716
15945
|
certificationRequirement: technology.certificationRequirement,
|
|
@@ -15729,13 +15958,13 @@ var ProcedureService = class extends BaseService {
|
|
|
15729
15958
|
},
|
|
15730
15959
|
isActive: true
|
|
15731
15960
|
};
|
|
15732
|
-
const procedureRef = (0,
|
|
15733
|
-
await (0,
|
|
15961
|
+
const procedureRef = (0, import_firestore46.doc)(this.db, PROCEDURES_COLLECTION, procedureId);
|
|
15962
|
+
await (0, import_firestore46.setDoc)(procedureRef, {
|
|
15734
15963
|
...newProcedure,
|
|
15735
|
-
createdAt: (0,
|
|
15736
|
-
updatedAt: (0,
|
|
15964
|
+
createdAt: (0, import_firestore46.serverTimestamp)(),
|
|
15965
|
+
updatedAt: (0, import_firestore46.serverTimestamp)()
|
|
15737
15966
|
});
|
|
15738
|
-
const savedDoc = await (0,
|
|
15967
|
+
const savedDoc = await (0, import_firestore46.getDoc)(procedureRef);
|
|
15739
15968
|
return savedDoc.data();
|
|
15740
15969
|
}
|
|
15741
15970
|
/**
|
|
@@ -15744,13 +15973,13 @@ var ProcedureService = class extends BaseService {
|
|
|
15744
15973
|
* @returns Array of minimal procedure info for map
|
|
15745
15974
|
*/
|
|
15746
15975
|
async getProceduresForMap() {
|
|
15747
|
-
const proceduresRef = (0,
|
|
15748
|
-
const snapshot = await (0,
|
|
15749
|
-
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) => {
|
|
15750
15979
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
15751
|
-
const data =
|
|
15980
|
+
const data = doc38.data();
|
|
15752
15981
|
return {
|
|
15753
|
-
id:
|
|
15982
|
+
id: doc38.id,
|
|
15754
15983
|
name: data.name,
|
|
15755
15984
|
clinicId: (_a = data.clinicInfo) == null ? void 0 : _a.id,
|
|
15756
15985
|
clinicName: (_b = data.clinicInfo) == null ? void 0 : _b.name,
|
|
@@ -15764,7 +15993,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15764
15993
|
};
|
|
15765
15994
|
|
|
15766
15995
|
// src/services/reviews/reviews.service.ts
|
|
15767
|
-
var
|
|
15996
|
+
var import_firestore47 = require("firebase/firestore");
|
|
15768
15997
|
var import_zod25 = require("zod");
|
|
15769
15998
|
var ReviewService = class extends BaseService {
|
|
15770
15999
|
constructor(db, auth, app) {
|
|
@@ -15844,11 +16073,11 @@ var ReviewService = class extends BaseService {
|
|
|
15844
16073
|
updatedAt: now
|
|
15845
16074
|
};
|
|
15846
16075
|
reviewSchema.parse(review);
|
|
15847
|
-
const docRef = (0,
|
|
15848
|
-
await (0,
|
|
16076
|
+
const docRef = (0, import_firestore47.doc)(this.db, REVIEWS_COLLECTION, reviewId);
|
|
16077
|
+
await (0, import_firestore47.setDoc)(docRef, {
|
|
15849
16078
|
...review,
|
|
15850
|
-
createdAt: (0,
|
|
15851
|
-
updatedAt: (0,
|
|
16079
|
+
createdAt: (0, import_firestore47.serverTimestamp)(),
|
|
16080
|
+
updatedAt: (0, import_firestore47.serverTimestamp)()
|
|
15852
16081
|
});
|
|
15853
16082
|
return review;
|
|
15854
16083
|
} catch (error) {
|
|
@@ -15864,8 +16093,8 @@ var ReviewService = class extends BaseService {
|
|
|
15864
16093
|
* @returns The review if found, null otherwise
|
|
15865
16094
|
*/
|
|
15866
16095
|
async getReview(reviewId) {
|
|
15867
|
-
const docRef = (0,
|
|
15868
|
-
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);
|
|
15869
16098
|
if (!docSnap.exists()) {
|
|
15870
16099
|
return null;
|
|
15871
16100
|
}
|
|
@@ -15877,12 +16106,12 @@ var ReviewService = class extends BaseService {
|
|
|
15877
16106
|
* @returns Array of reviews for the patient
|
|
15878
16107
|
*/
|
|
15879
16108
|
async getReviewsByPatient(patientId) {
|
|
15880
|
-
const q = (0,
|
|
15881
|
-
(0,
|
|
15882
|
-
(0,
|
|
16109
|
+
const q = (0, import_firestore47.query)(
|
|
16110
|
+
(0, import_firestore47.collection)(this.db, REVIEWS_COLLECTION),
|
|
16111
|
+
(0, import_firestore47.where)("patientId", "==", patientId)
|
|
15883
16112
|
);
|
|
15884
|
-
const snapshot = await (0,
|
|
15885
|
-
return snapshot.docs.map((
|
|
16113
|
+
const snapshot = await (0, import_firestore47.getDocs)(q);
|
|
16114
|
+
return snapshot.docs.map((doc38) => doc38.data());
|
|
15886
16115
|
}
|
|
15887
16116
|
/**
|
|
15888
16117
|
* Gets all reviews for a specific clinic
|
|
@@ -15890,12 +16119,12 @@ var ReviewService = class extends BaseService {
|
|
|
15890
16119
|
* @returns Array of reviews containing clinic reviews
|
|
15891
16120
|
*/
|
|
15892
16121
|
async getReviewsByClinic(clinicId) {
|
|
15893
|
-
const q = (0,
|
|
15894
|
-
(0,
|
|
15895
|
-
(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)
|
|
15896
16125
|
);
|
|
15897
|
-
const snapshot = await (0,
|
|
15898
|
-
return snapshot.docs.map((
|
|
16126
|
+
const snapshot = await (0, import_firestore47.getDocs)(q);
|
|
16127
|
+
return snapshot.docs.map((doc38) => doc38.data());
|
|
15899
16128
|
}
|
|
15900
16129
|
/**
|
|
15901
16130
|
* Gets all reviews for a specific practitioner
|
|
@@ -15903,12 +16132,12 @@ var ReviewService = class extends BaseService {
|
|
|
15903
16132
|
* @returns Array of reviews containing practitioner reviews
|
|
15904
16133
|
*/
|
|
15905
16134
|
async getReviewsByPractitioner(practitionerId) {
|
|
15906
|
-
const q = (0,
|
|
15907
|
-
(0,
|
|
15908
|
-
(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)
|
|
15909
16138
|
);
|
|
15910
|
-
const snapshot = await (0,
|
|
15911
|
-
return snapshot.docs.map((
|
|
16139
|
+
const snapshot = await (0, import_firestore47.getDocs)(q);
|
|
16140
|
+
return snapshot.docs.map((doc38) => doc38.data());
|
|
15912
16141
|
}
|
|
15913
16142
|
/**
|
|
15914
16143
|
* Gets all reviews for a specific procedure
|
|
@@ -15916,12 +16145,12 @@ var ReviewService = class extends BaseService {
|
|
|
15916
16145
|
* @returns Array of reviews containing procedure reviews
|
|
15917
16146
|
*/
|
|
15918
16147
|
async getReviewsByProcedure(procedureId) {
|
|
15919
|
-
const q = (0,
|
|
15920
|
-
(0,
|
|
15921
|
-
(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)
|
|
15922
16151
|
);
|
|
15923
|
-
const snapshot = await (0,
|
|
15924
|
-
return snapshot.docs.map((
|
|
16152
|
+
const snapshot = await (0, import_firestore47.getDocs)(q);
|
|
16153
|
+
return snapshot.docs.map((doc38) => doc38.data());
|
|
15925
16154
|
}
|
|
15926
16155
|
/**
|
|
15927
16156
|
* Gets all reviews for a specific appointment
|
|
@@ -15929,11 +16158,11 @@ var ReviewService = class extends BaseService {
|
|
|
15929
16158
|
* @returns The review for the appointment if found, null otherwise
|
|
15930
16159
|
*/
|
|
15931
16160
|
async getReviewByAppointment(appointmentId) {
|
|
15932
|
-
const q = (0,
|
|
15933
|
-
(0,
|
|
15934
|
-
(0,
|
|
16161
|
+
const q = (0, import_firestore47.query)(
|
|
16162
|
+
(0, import_firestore47.collection)(this.db, REVIEWS_COLLECTION),
|
|
16163
|
+
(0, import_firestore47.where)("appointmentId", "==", appointmentId)
|
|
15935
16164
|
);
|
|
15936
|
-
const snapshot = await (0,
|
|
16165
|
+
const snapshot = await (0, import_firestore47.getDocs)(q);
|
|
15937
16166
|
if (snapshot.empty) {
|
|
15938
16167
|
return null;
|
|
15939
16168
|
}
|
|
@@ -15948,7 +16177,7 @@ var ReviewService = class extends BaseService {
|
|
|
15948
16177
|
if (!review) {
|
|
15949
16178
|
throw new Error(`Review with ID ${reviewId} not found`);
|
|
15950
16179
|
}
|
|
15951
|
-
await (0,
|
|
16180
|
+
await (0, import_firestore47.deleteDoc)((0, import_firestore47.doc)(this.db, REVIEWS_COLLECTION, reviewId));
|
|
15952
16181
|
}
|
|
15953
16182
|
/**
|
|
15954
16183
|
* Calculates the average of an array of numbers
|
|
@@ -15967,7 +16196,7 @@ var ReviewService = class extends BaseService {
|
|
|
15967
16196
|
|
|
15968
16197
|
// src/config/firebase.ts
|
|
15969
16198
|
var import_app = require("firebase/app");
|
|
15970
|
-
var
|
|
16199
|
+
var import_firestore48 = require("firebase/firestore");
|
|
15971
16200
|
var import_auth9 = require("firebase/auth");
|
|
15972
16201
|
var import_analytics = require("firebase/analytics");
|
|
15973
16202
|
var import_react_native = require("react-native");
|
|
@@ -15977,7 +16206,7 @@ var firebaseInstance = null;
|
|
|
15977
16206
|
var initializeFirebase = (config) => {
|
|
15978
16207
|
if (!firebaseInstance) {
|
|
15979
16208
|
const app = (0, import_app.initializeApp)(config);
|
|
15980
|
-
const db = (0,
|
|
16209
|
+
const db = (0, import_firestore48.getFirestore)(app);
|
|
15981
16210
|
const auth = (0, import_auth9.getAuth)(app);
|
|
15982
16211
|
const storage = (0, import_storage4.getStorage)(app);
|
|
15983
16212
|
const functions = (0, import_functions3.getFunctions)(app);
|
|
@@ -16019,7 +16248,7 @@ var getFirebaseFunctions = async () => {
|
|
|
16019
16248
|
};
|
|
16020
16249
|
|
|
16021
16250
|
// src/backoffice/services/brand.service.ts
|
|
16022
|
-
var
|
|
16251
|
+
var import_firestore49 = require("firebase/firestore");
|
|
16023
16252
|
|
|
16024
16253
|
// src/backoffice/types/brand.types.ts
|
|
16025
16254
|
var BRANDS_COLLECTION = "brands";
|
|
@@ -16030,7 +16259,7 @@ var BrandService = class extends BaseService {
|
|
|
16030
16259
|
* Gets reference to brands collection
|
|
16031
16260
|
*/
|
|
16032
16261
|
getBrandsRef() {
|
|
16033
|
-
return (0,
|
|
16262
|
+
return (0, import_firestore49.collection)(this.db, BRANDS_COLLECTION);
|
|
16034
16263
|
}
|
|
16035
16264
|
/**
|
|
16036
16265
|
* Creates a new brand
|
|
@@ -16039,23 +16268,78 @@ var BrandService = class extends BaseService {
|
|
|
16039
16268
|
const now = /* @__PURE__ */ new Date();
|
|
16040
16269
|
const newBrand = {
|
|
16041
16270
|
...brand,
|
|
16271
|
+
name_lowercase: brand.name.toLowerCase(),
|
|
16042
16272
|
createdAt: now,
|
|
16043
16273
|
updatedAt: now,
|
|
16044
16274
|
isActive: true
|
|
16045
16275
|
};
|
|
16046
|
-
const docRef = await (0,
|
|
16276
|
+
const docRef = await (0, import_firestore49.addDoc)(this.getBrandsRef(), newBrand);
|
|
16047
16277
|
return { id: docRef.id, ...newBrand };
|
|
16048
16278
|
}
|
|
16049
16279
|
/**
|
|
16050
|
-
* 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).
|
|
16051
16331
|
*/
|
|
16052
|
-
async
|
|
16053
|
-
const q = (0,
|
|
16054
|
-
|
|
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);
|
|
16055
16339
|
return snapshot.docs.map(
|
|
16056
|
-
(
|
|
16057
|
-
id:
|
|
16058
|
-
...
|
|
16340
|
+
(doc38) => ({
|
|
16341
|
+
id: doc38.id,
|
|
16342
|
+
...doc38.data()
|
|
16059
16343
|
})
|
|
16060
16344
|
);
|
|
16061
16345
|
}
|
|
@@ -16067,8 +16351,11 @@ var BrandService = class extends BaseService {
|
|
|
16067
16351
|
...brand,
|
|
16068
16352
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16069
16353
|
};
|
|
16070
|
-
|
|
16071
|
-
|
|
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);
|
|
16072
16359
|
return this.getById(brandId);
|
|
16073
16360
|
}
|
|
16074
16361
|
/**
|
|
@@ -16083,8 +16370,8 @@ var BrandService = class extends BaseService {
|
|
|
16083
16370
|
* Gets a brand by ID
|
|
16084
16371
|
*/
|
|
16085
16372
|
async getById(brandId) {
|
|
16086
|
-
const docRef = (0,
|
|
16087
|
-
const docSnap = await (0,
|
|
16373
|
+
const docRef = (0, import_firestore49.doc)(this.getBrandsRef(), brandId);
|
|
16374
|
+
const docSnap = await (0, import_firestore49.getDoc)(docRef);
|
|
16088
16375
|
if (!docSnap.exists()) return null;
|
|
16089
16376
|
return {
|
|
16090
16377
|
id: docSnap.id,
|
|
@@ -16094,7 +16381,7 @@ var BrandService = class extends BaseService {
|
|
|
16094
16381
|
};
|
|
16095
16382
|
|
|
16096
16383
|
// src/backoffice/services/category.service.ts
|
|
16097
|
-
var
|
|
16384
|
+
var import_firestore50 = require("firebase/firestore");
|
|
16098
16385
|
|
|
16099
16386
|
// src/backoffice/types/category.types.ts
|
|
16100
16387
|
var CATEGORIES_COLLECTION = "backoffice_categories";
|
|
@@ -16105,7 +16392,7 @@ var CategoryService = class extends BaseService {
|
|
|
16105
16392
|
* Referenca na Firestore kolekciju kategorija
|
|
16106
16393
|
*/
|
|
16107
16394
|
get categoriesRef() {
|
|
16108
|
-
return (0,
|
|
16395
|
+
return (0, import_firestore50.collection)(this.db, CATEGORIES_COLLECTION);
|
|
16109
16396
|
}
|
|
16110
16397
|
/**
|
|
16111
16398
|
* Kreira novu kategoriju u sistemu
|
|
@@ -16120,41 +16407,91 @@ var CategoryService = class extends BaseService {
|
|
|
16120
16407
|
updatedAt: now,
|
|
16121
16408
|
isActive: true
|
|
16122
16409
|
};
|
|
16123
|
-
const docRef = await (0,
|
|
16410
|
+
const docRef = await (0, import_firestore50.addDoc)(this.categoriesRef, newCategory);
|
|
16124
16411
|
return { id: docRef.id, ...newCategory };
|
|
16125
16412
|
}
|
|
16126
16413
|
/**
|
|
16127
|
-
*
|
|
16128
|
-
* @
|
|
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.
|
|
16129
16417
|
*/
|
|
16130
|
-
async
|
|
16131
|
-
const
|
|
16132
|
-
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);
|
|
16133
16439
|
return snapshot.docs.map(
|
|
16134
|
-
(
|
|
16135
|
-
id:
|
|
16136
|
-
...
|
|
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()
|
|
16137
16465
|
})
|
|
16138
16466
|
);
|
|
16467
|
+
const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
|
|
16468
|
+
return { categories, lastVisible: newLastVisible };
|
|
16139
16469
|
}
|
|
16140
16470
|
/**
|
|
16141
|
-
* Vraća sve aktivne kategorije za određenu familiju procedura
|
|
16471
|
+
* Vraća sve aktivne kategorije za određenu familiju procedura sa paginacijom
|
|
16142
16472
|
* @param family - Familija procedura (aesthetics/surgery)
|
|
16473
|
+
* @param options - Pagination options
|
|
16143
16474
|
* @returns Lista kategorija koje pripadaju traženoj familiji
|
|
16144
16475
|
*/
|
|
16145
|
-
async getAllByFamily(family) {
|
|
16146
|
-
const
|
|
16147
|
-
|
|
16148
|
-
(0,
|
|
16149
|
-
(0,
|
|
16150
|
-
|
|
16151
|
-
|
|
16152
|
-
|
|
16153
|
-
|
|
16154
|
-
|
|
16155
|
-
|
|
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()
|
|
16156
16491
|
})
|
|
16157
16492
|
);
|
|
16493
|
+
const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
|
|
16494
|
+
return { categories, lastVisible: newLastVisible };
|
|
16158
16495
|
}
|
|
16159
16496
|
/**
|
|
16160
16497
|
* Ažurira postojeću kategoriju
|
|
@@ -16167,8 +16504,8 @@ var CategoryService = class extends BaseService {
|
|
|
16167
16504
|
...category,
|
|
16168
16505
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16169
16506
|
};
|
|
16170
|
-
const docRef = (0,
|
|
16171
|
-
await (0,
|
|
16507
|
+
const docRef = (0, import_firestore50.doc)(this.categoriesRef, id);
|
|
16508
|
+
await (0, import_firestore50.updateDoc)(docRef, updateData);
|
|
16172
16509
|
return this.getById(id);
|
|
16173
16510
|
}
|
|
16174
16511
|
/**
|
|
@@ -16178,14 +16515,21 @@ var CategoryService = class extends BaseService {
|
|
|
16178
16515
|
async delete(id) {
|
|
16179
16516
|
await this.update(id, { isActive: false });
|
|
16180
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
|
+
}
|
|
16181
16525
|
/**
|
|
16182
16526
|
* Vraća kategoriju po ID-u
|
|
16183
16527
|
* @param id - ID tražene kategorije
|
|
16184
16528
|
* @returns Kategorija ili null ako ne postoji
|
|
16185
16529
|
*/
|
|
16186
16530
|
async getById(id) {
|
|
16187
|
-
const docRef = (0,
|
|
16188
|
-
const docSnap = await (0,
|
|
16531
|
+
const docRef = (0, import_firestore50.doc)(this.categoriesRef, id);
|
|
16532
|
+
const docSnap = await (0, import_firestore50.getDoc)(docRef);
|
|
16189
16533
|
if (!docSnap.exists()) return null;
|
|
16190
16534
|
return {
|
|
16191
16535
|
id: docSnap.id,
|
|
@@ -16195,7 +16539,7 @@ var CategoryService = class extends BaseService {
|
|
|
16195
16539
|
};
|
|
16196
16540
|
|
|
16197
16541
|
// src/backoffice/services/subcategory.service.ts
|
|
16198
|
-
var
|
|
16542
|
+
var import_firestore51 = require("firebase/firestore");
|
|
16199
16543
|
|
|
16200
16544
|
// src/backoffice/types/subcategory.types.ts
|
|
16201
16545
|
var SUBCATEGORIES_COLLECTION = "subcategories";
|
|
@@ -16207,7 +16551,7 @@ var SubcategoryService = class extends BaseService {
|
|
|
16207
16551
|
* @param categoryId - ID roditeljske kategorije
|
|
16208
16552
|
*/
|
|
16209
16553
|
getSubcategoriesRef(categoryId) {
|
|
16210
|
-
return (0,
|
|
16554
|
+
return (0, import_firestore51.collection)(
|
|
16211
16555
|
this.db,
|
|
16212
16556
|
CATEGORIES_COLLECTION,
|
|
16213
16557
|
categoryId,
|
|
@@ -16229,27 +16573,117 @@ var SubcategoryService = class extends BaseService {
|
|
|
16229
16573
|
updatedAt: now,
|
|
16230
16574
|
isActive: true
|
|
16231
16575
|
};
|
|
16232
|
-
const docRef = await (0,
|
|
16576
|
+
const docRef = await (0, import_firestore51.addDoc)(
|
|
16233
16577
|
this.getSubcategoriesRef(categoryId),
|
|
16234
16578
|
newSubcategory
|
|
16235
16579
|
);
|
|
16236
16580
|
return { id: docRef.id, ...newSubcategory };
|
|
16237
16581
|
}
|
|
16238
16582
|
/**
|
|
16239
|
-
*
|
|
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
|
|
16240
16602
|
* @param categoryId - ID kategorije čije podkategorije tražimo
|
|
16241
|
-
* @
|
|
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
|
|
16242
16632
|
*/
|
|
16243
|
-
async
|
|
16244
|
-
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)(
|
|
16245
16662
|
this.getSubcategoriesRef(categoryId),
|
|
16246
|
-
(0,
|
|
16663
|
+
(0, import_firestore51.where)("isActive", "==", true)
|
|
16247
16664
|
);
|
|
16248
|
-
const
|
|
16249
|
-
return
|
|
16250
|
-
(
|
|
16251
|
-
id:
|
|
16252
|
-
...
|
|
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()
|
|
16253
16687
|
})
|
|
16254
16688
|
);
|
|
16255
16689
|
}
|
|
@@ -16261,13 +16695,42 @@ var SubcategoryService = class extends BaseService {
|
|
|
16261
16695
|
* @returns Ažurirana podkategorija
|
|
16262
16696
|
*/
|
|
16263
16697
|
async update(categoryId, subcategoryId, subcategory) {
|
|
16264
|
-
const
|
|
16265
|
-
|
|
16266
|
-
|
|
16267
|
-
|
|
16268
|
-
|
|
16269
|
-
|
|
16270
|
-
|
|
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
|
+
}
|
|
16271
16734
|
}
|
|
16272
16735
|
/**
|
|
16273
16736
|
* Soft delete podkategorije (postavlja isActive na false)
|
|
@@ -16277,6 +16740,14 @@ var SubcategoryService = class extends BaseService {
|
|
|
16277
16740
|
async delete(categoryId, subcategoryId) {
|
|
16278
16741
|
await this.update(categoryId, subcategoryId, { isActive: false });
|
|
16279
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
|
+
}
|
|
16280
16751
|
/**
|
|
16281
16752
|
* Vraća podkategoriju po ID-u
|
|
16282
16753
|
* @param categoryId - ID kategorije kojoj pripada podkategorija
|
|
@@ -16284,8 +16755,8 @@ var SubcategoryService = class extends BaseService {
|
|
|
16284
16755
|
* @returns Podkategorija ili null ako ne postoji
|
|
16285
16756
|
*/
|
|
16286
16757
|
async getById(categoryId, subcategoryId) {
|
|
16287
|
-
const docRef = (0,
|
|
16288
|
-
const docSnap = await (0,
|
|
16758
|
+
const docRef = (0, import_firestore51.doc)(this.getSubcategoriesRef(categoryId), subcategoryId);
|
|
16759
|
+
const docSnap = await (0, import_firestore51.getDoc)(docRef);
|
|
16289
16760
|
if (!docSnap.exists()) return null;
|
|
16290
16761
|
return {
|
|
16291
16762
|
id: docSnap.id,
|
|
@@ -16295,145 +16766,193 @@ var SubcategoryService = class extends BaseService {
|
|
|
16295
16766
|
};
|
|
16296
16767
|
|
|
16297
16768
|
// src/backoffice/services/technology.service.ts
|
|
16298
|
-
var
|
|
16769
|
+
var import_firestore52 = require("firebase/firestore");
|
|
16299
16770
|
var DEFAULT_CERTIFICATION_REQUIREMENT = {
|
|
16300
16771
|
minimumLevel: "aesthetician" /* AESTHETICIAN */,
|
|
16301
16772
|
requiredSpecialties: []
|
|
16302
16773
|
};
|
|
16303
16774
|
var TechnologyService = class extends BaseService {
|
|
16304
16775
|
/**
|
|
16305
|
-
*
|
|
16776
|
+
* Reference to the Firestore collection of technologies.
|
|
16306
16777
|
*/
|
|
16307
|
-
|
|
16308
|
-
return (0,
|
|
16778
|
+
get technologiesRef() {
|
|
16779
|
+
return (0, import_firestore52.collection)(this.db, TECHNOLOGIES_COLLECTION);
|
|
16309
16780
|
}
|
|
16310
16781
|
/**
|
|
16311
|
-
*
|
|
16312
|
-
* @param technology -
|
|
16313
|
-
* @returns
|
|
16782
|
+
* Creates a new technology.
|
|
16783
|
+
* @param technology - Data for the new technology.
|
|
16784
|
+
* @returns The created technology with its generated ID.
|
|
16314
16785
|
*/
|
|
16315
16786
|
async create(technology) {
|
|
16316
16787
|
const now = /* @__PURE__ */ new Date();
|
|
16317
16788
|
const newTechnology = {
|
|
16318
|
-
|
|
16319
|
-
|
|
16320
|
-
|
|
16321
|
-
|
|
16322
|
-
|
|
16323
|
-
|
|
16324
|
-
post: []
|
|
16325
|
-
},
|
|
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: [] },
|
|
16326
16795
|
blockingConditions: technology.blockingConditions || [],
|
|
16327
16796
|
contraindications: technology.contraindications || [],
|
|
16328
16797
|
benefits: technology.benefits || [],
|
|
16329
|
-
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
|
|
16330
16803
|
};
|
|
16331
|
-
|
|
16804
|
+
if (technology.technicalDetails) {
|
|
16805
|
+
newTechnology.technicalDetails = technology.technicalDetails;
|
|
16806
|
+
}
|
|
16807
|
+
const docRef = await (0, import_firestore52.addDoc)(this.technologiesRef, newTechnology);
|
|
16332
16808
|
return { id: docRef.id, ...newTechnology };
|
|
16333
16809
|
}
|
|
16334
16810
|
/**
|
|
16335
|
-
*
|
|
16336
|
-
* @
|
|
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.
|
|
16337
16814
|
*/
|
|
16338
|
-
async
|
|
16339
|
-
const q = (0,
|
|
16340
|
-
const snapshot = await (0,
|
|
16341
|
-
|
|
16342
|
-
|
|
16343
|
-
|
|
16344
|
-
|
|
16345
|
-
|
|
16346
|
-
|
|
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;
|
|
16347
16824
|
}
|
|
16348
16825
|
/**
|
|
16349
|
-
*
|
|
16350
|
-
* @param
|
|
16351
|
-
* @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.
|
|
16352
16829
|
*/
|
|
16353
|
-
async
|
|
16354
|
-
const q = (0,
|
|
16355
|
-
|
|
16356
|
-
|
|
16357
|
-
|
|
16358
|
-
|
|
16359
|
-
|
|
16360
|
-
|
|
16361
|
-
|
|
16362
|
-
|
|
16363
|
-
|
|
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()
|
|
16364
16859
|
})
|
|
16365
16860
|
);
|
|
16861
|
+
const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
|
|
16862
|
+
return { technologies, lastVisible: newLastVisible };
|
|
16366
16863
|
}
|
|
16367
16864
|
/**
|
|
16368
|
-
*
|
|
16369
|
-
* @param categoryId - ID
|
|
16370
|
-
* @
|
|
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.
|
|
16371
16869
|
*/
|
|
16372
|
-
async getAllByCategoryId(categoryId) {
|
|
16373
|
-
const
|
|
16374
|
-
|
|
16375
|
-
(0,
|
|
16376
|
-
(0,
|
|
16377
|
-
|
|
16378
|
-
|
|
16379
|
-
|
|
16380
|
-
|
|
16381
|
-
|
|
16382
|
-
|
|
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()
|
|
16383
16885
|
})
|
|
16384
16886
|
);
|
|
16887
|
+
const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
|
|
16888
|
+
return { technologies, lastVisible: newLastVisible };
|
|
16385
16889
|
}
|
|
16386
16890
|
/**
|
|
16387
|
-
*
|
|
16388
|
-
* @param subcategoryId - ID
|
|
16389
|
-
* @
|
|
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.
|
|
16390
16895
|
*/
|
|
16391
|
-
async getAllBySubcategoryId(subcategoryId) {
|
|
16392
|
-
const
|
|
16393
|
-
|
|
16394
|
-
(0,
|
|
16395
|
-
(0,
|
|
16396
|
-
|
|
16397
|
-
|
|
16398
|
-
|
|
16399
|
-
|
|
16400
|
-
|
|
16401
|
-
|
|
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()
|
|
16402
16911
|
})
|
|
16403
16912
|
);
|
|
16913
|
+
const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
|
|
16914
|
+
return { technologies, lastVisible: newLastVisible };
|
|
16404
16915
|
}
|
|
16405
16916
|
/**
|
|
16406
|
-
*
|
|
16407
|
-
* @param
|
|
16408
|
-
* @param technology -
|
|
16409
|
-
* @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.
|
|
16410
16921
|
*/
|
|
16411
|
-
async update(
|
|
16412
|
-
const updateData = {
|
|
16413
|
-
|
|
16414
|
-
|
|
16415
|
-
|
|
16416
|
-
|
|
16417
|
-
|
|
16418
|
-
|
|
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);
|
|
16419
16933
|
}
|
|
16420
16934
|
/**
|
|
16421
|
-
* Soft
|
|
16422
|
-
* @param
|
|
16935
|
+
* Soft deletes a technology.
|
|
16936
|
+
* @param id - The ID of the technology to delete.
|
|
16423
16937
|
*/
|
|
16424
|
-
async delete(
|
|
16425
|
-
await this.update(
|
|
16426
|
-
isActive: false
|
|
16427
|
-
});
|
|
16938
|
+
async delete(id) {
|
|
16939
|
+
await this.update(id, { isActive: false });
|
|
16428
16940
|
}
|
|
16429
16941
|
/**
|
|
16430
|
-
*
|
|
16431
|
-
* @param
|
|
16432
|
-
* @returns Tehnologija ili null ako ne postoji
|
|
16942
|
+
* Reactivates a technology.
|
|
16943
|
+
* @param id - The ID of the technology to reactivate.
|
|
16433
16944
|
*/
|
|
16434
|
-
async
|
|
16435
|
-
|
|
16436
|
-
|
|
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);
|
|
16437
16956
|
if (!docSnap.exists()) return null;
|
|
16438
16957
|
return {
|
|
16439
16958
|
id: docSnap.id,
|
|
@@ -16447,10 +16966,10 @@ var TechnologyService = class extends BaseService {
|
|
|
16447
16966
|
* @returns Ažurirana tehnologija sa novim zahtevom
|
|
16448
16967
|
*/
|
|
16449
16968
|
async addRequirement(technologyId, requirement) {
|
|
16450
|
-
const docRef = (0,
|
|
16969
|
+
const docRef = (0, import_firestore52.doc)(this.technologiesRef, technologyId);
|
|
16451
16970
|
const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
|
|
16452
|
-
await (0,
|
|
16453
|
-
[requirementType]: (0,
|
|
16971
|
+
await (0, import_firestore52.updateDoc)(docRef, {
|
|
16972
|
+
[requirementType]: (0, import_firestore52.arrayUnion)(requirement),
|
|
16454
16973
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16455
16974
|
});
|
|
16456
16975
|
return this.getById(technologyId);
|
|
@@ -16462,10 +16981,10 @@ var TechnologyService = class extends BaseService {
|
|
|
16462
16981
|
* @returns Ažurirana tehnologija bez uklonjenog zahteva
|
|
16463
16982
|
*/
|
|
16464
16983
|
async removeRequirement(technologyId, requirement) {
|
|
16465
|
-
const docRef = (0,
|
|
16984
|
+
const docRef = (0, import_firestore52.doc)(this.technologiesRef, technologyId);
|
|
16466
16985
|
const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
|
|
16467
|
-
await (0,
|
|
16468
|
-
[requirementType]: (0,
|
|
16986
|
+
await (0, import_firestore52.updateDoc)(docRef, {
|
|
16987
|
+
[requirementType]: (0, import_firestore52.arrayRemove)(requirement),
|
|
16469
16988
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16470
16989
|
});
|
|
16471
16990
|
return this.getById(technologyId);
|
|
@@ -16502,9 +17021,9 @@ var TechnologyService = class extends BaseService {
|
|
|
16502
17021
|
* @returns Ažurirana tehnologija
|
|
16503
17022
|
*/
|
|
16504
17023
|
async addBlockingCondition(technologyId, condition) {
|
|
16505
|
-
const docRef = (0,
|
|
16506
|
-
await (0,
|
|
16507
|
-
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),
|
|
16508
17027
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16509
17028
|
});
|
|
16510
17029
|
return this.getById(technologyId);
|
|
@@ -16516,9 +17035,9 @@ var TechnologyService = class extends BaseService {
|
|
|
16516
17035
|
* @returns Ažurirana tehnologija
|
|
16517
17036
|
*/
|
|
16518
17037
|
async removeBlockingCondition(technologyId, condition) {
|
|
16519
|
-
const docRef = (0,
|
|
16520
|
-
await (0,
|
|
16521
|
-
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),
|
|
16522
17041
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16523
17042
|
});
|
|
16524
17043
|
return this.getById(technologyId);
|
|
@@ -16530,9 +17049,17 @@ var TechnologyService = class extends BaseService {
|
|
|
16530
17049
|
* @returns Ažurirana tehnologija
|
|
16531
17050
|
*/
|
|
16532
17051
|
async addContraindication(technologyId, contraindication) {
|
|
16533
|
-
const docRef = (0,
|
|
16534
|
-
await (
|
|
16535
|
-
|
|
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],
|
|
16536
17063
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16537
17064
|
});
|
|
16538
17065
|
return this.getById(technologyId);
|
|
@@ -16544,9 +17071,45 @@ var TechnologyService = class extends BaseService {
|
|
|
16544
17071
|
* @returns Ažurirana tehnologija
|
|
16545
17072
|
*/
|
|
16546
17073
|
async removeContraindication(technologyId, contraindication) {
|
|
16547
|
-
const docRef = (0,
|
|
16548
|
-
await (
|
|
16549
|
-
|
|
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,
|
|
16550
17113
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16551
17114
|
});
|
|
16552
17115
|
return this.getById(technologyId);
|
|
@@ -16558,9 +17121,17 @@ var TechnologyService = class extends BaseService {
|
|
|
16558
17121
|
* @returns Ažurirana tehnologija
|
|
16559
17122
|
*/
|
|
16560
17123
|
async addBenefit(technologyId, benefit) {
|
|
16561
|
-
const docRef = (0,
|
|
16562
|
-
await (
|
|
16563
|
-
|
|
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],
|
|
16564
17135
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16565
17136
|
});
|
|
16566
17137
|
return this.getById(technologyId);
|
|
@@ -16572,9 +17143,45 @@ var TechnologyService = class extends BaseService {
|
|
|
16572
17143
|
* @returns Ažurirana tehnologija
|
|
16573
17144
|
*/
|
|
16574
17145
|
async removeBenefit(technologyId, benefit) {
|
|
16575
|
-
const docRef = (0,
|
|
16576
|
-
await (
|
|
16577
|
-
|
|
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,
|
|
16578
17185
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16579
17186
|
});
|
|
16580
17187
|
return this.getById(technologyId);
|
|
@@ -16613,8 +17220,8 @@ var TechnologyService = class extends BaseService {
|
|
|
16613
17220
|
* @returns Ažurirana tehnologija
|
|
16614
17221
|
*/
|
|
16615
17222
|
async updateCertificationRequirement(technologyId, certificationRequirement) {
|
|
16616
|
-
const docRef = (0,
|
|
16617
|
-
await (0,
|
|
17223
|
+
const docRef = (0, import_firestore52.doc)(this.technologiesRef, technologyId);
|
|
17224
|
+
await (0, import_firestore52.updateDoc)(docRef, {
|
|
16618
17225
|
certificationRequirement,
|
|
16619
17226
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16620
17227
|
});
|
|
@@ -16691,7 +17298,7 @@ var TechnologyService = class extends BaseService {
|
|
|
16691
17298
|
*/
|
|
16692
17299
|
async getAllowedTechnologies(practitioner) {
|
|
16693
17300
|
const allTechnologies = await this.getAll();
|
|
16694
|
-
const allowedTechnologies = allTechnologies.filter(
|
|
17301
|
+
const allowedTechnologies = allTechnologies.technologies.filter(
|
|
16695
17302
|
(technology) => this.validateCertification(
|
|
16696
17303
|
technology.certificationRequirement,
|
|
16697
17304
|
practitioner.certification
|
|
@@ -16711,10 +17318,48 @@ var TechnologyService = class extends BaseService {
|
|
|
16711
17318
|
subcategories
|
|
16712
17319
|
};
|
|
16713
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
|
+
}
|
|
16714
17359
|
};
|
|
16715
17360
|
|
|
16716
17361
|
// src/backoffice/services/product.service.ts
|
|
16717
|
-
var
|
|
17362
|
+
var import_firestore53 = require("firebase/firestore");
|
|
16718
17363
|
|
|
16719
17364
|
// src/backoffice/types/product.types.ts
|
|
16720
17365
|
var PRODUCTS_COLLECTION = "products";
|
|
@@ -16727,7 +17372,7 @@ var ProductService = class extends BaseService {
|
|
|
16727
17372
|
* @returns Firestore collection reference
|
|
16728
17373
|
*/
|
|
16729
17374
|
getProductsRef(technologyId) {
|
|
16730
|
-
return (0,
|
|
17375
|
+
return (0, import_firestore53.collection)(
|
|
16731
17376
|
this.db,
|
|
16732
17377
|
TECHNOLOGIES_COLLECTION,
|
|
16733
17378
|
technologyId,
|
|
@@ -16747,47 +17392,129 @@ var ProductService = class extends BaseService {
|
|
|
16747
17392
|
updatedAt: now,
|
|
16748
17393
|
isActive: true
|
|
16749
17394
|
};
|
|
16750
|
-
const productRef = await (0,
|
|
17395
|
+
const productRef = await (0, import_firestore53.addDoc)(
|
|
16751
17396
|
this.getProductsRef(technologyId),
|
|
16752
17397
|
newProduct
|
|
16753
17398
|
);
|
|
16754
17399
|
return { id: productRef.id, ...newProduct };
|
|
16755
17400
|
}
|
|
16756
17401
|
/**
|
|
16757
|
-
* 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.
|
|
16758
17404
|
*/
|
|
16759
|
-
async
|
|
16760
|
-
const
|
|
16761
|
-
|
|
16762
|
-
|
|
16763
|
-
|
|
16764
|
-
|
|
16765
|
-
|
|
16766
|
-
|
|
16767
|
-
|
|
16768
|
-
|
|
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()
|
|
16769
17439
|
})
|
|
16770
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;
|
|
16771
17498
|
}
|
|
16772
17499
|
/**
|
|
16773
17500
|
* Gets all products for a brand by filtering through all technologies
|
|
16774
17501
|
*/
|
|
16775
17502
|
async getAllByBrand(brandId) {
|
|
16776
|
-
const allTechnologiesRef = (0,
|
|
16777
|
-
const technologiesSnapshot = await (0,
|
|
17503
|
+
const allTechnologiesRef = (0, import_firestore53.collection)(this.db, TECHNOLOGIES_COLLECTION);
|
|
17504
|
+
const technologiesSnapshot = await (0, import_firestore53.getDocs)(allTechnologiesRef);
|
|
16778
17505
|
const products = [];
|
|
16779
17506
|
for (const techDoc of technologiesSnapshot.docs) {
|
|
16780
|
-
const q = (0,
|
|
17507
|
+
const q = (0, import_firestore53.query)(
|
|
16781
17508
|
this.getProductsRef(techDoc.id),
|
|
16782
|
-
(0,
|
|
16783
|
-
(0,
|
|
17509
|
+
(0, import_firestore53.where)("brandId", "==", brandId),
|
|
17510
|
+
(0, import_firestore53.where)("isActive", "==", true)
|
|
16784
17511
|
);
|
|
16785
|
-
const snapshot = await (0,
|
|
17512
|
+
const snapshot = await (0, import_firestore53.getDocs)(q);
|
|
16786
17513
|
products.push(
|
|
16787
17514
|
...snapshot.docs.map(
|
|
16788
|
-
(
|
|
16789
|
-
id:
|
|
16790
|
-
...
|
|
17515
|
+
(doc38) => ({
|
|
17516
|
+
id: doc38.id,
|
|
17517
|
+
...doc38.data()
|
|
16791
17518
|
})
|
|
16792
17519
|
)
|
|
16793
17520
|
);
|
|
@@ -16802,8 +17529,8 @@ var ProductService = class extends BaseService {
|
|
|
16802
17529
|
...product,
|
|
16803
17530
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16804
17531
|
};
|
|
16805
|
-
const docRef = (0,
|
|
16806
|
-
await (0,
|
|
17532
|
+
const docRef = (0, import_firestore53.doc)(this.getProductsRef(technologyId), productId);
|
|
17533
|
+
await (0, import_firestore53.updateDoc)(docRef, updateData);
|
|
16807
17534
|
return this.getById(technologyId, productId);
|
|
16808
17535
|
}
|
|
16809
17536
|
/**
|
|
@@ -16818,8 +17545,8 @@ var ProductService = class extends BaseService {
|
|
|
16818
17545
|
* Gets a product by ID
|
|
16819
17546
|
*/
|
|
16820
17547
|
async getById(technologyId, productId) {
|
|
16821
|
-
const docRef = (0,
|
|
16822
|
-
const docSnap = await (0,
|
|
17548
|
+
const docRef = (0, import_firestore53.doc)(this.getProductsRef(technologyId), productId);
|
|
17549
|
+
const docSnap = await (0, import_firestore53.getDoc)(docRef);
|
|
16823
17550
|
if (!docSnap.exists()) return null;
|
|
16824
17551
|
return {
|
|
16825
17552
|
id: docSnap.id,
|
|
@@ -16828,6 +17555,255 @@ var ProductService = class extends BaseService {
|
|
|
16828
17555
|
}
|
|
16829
17556
|
};
|
|
16830
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
|
+
|
|
16831
17807
|
// src/backoffice/types/static/treatment-benefit.types.ts
|
|
16832
17808
|
var TreatmentBenefit = /* @__PURE__ */ ((TreatmentBenefit2) => {
|
|
16833
17809
|
TreatmentBenefit2["WRINKLE_REDUCTION"] = "wrinkle_reduction";
|
|
@@ -16887,6 +17863,7 @@ var RequirementType = /* @__PURE__ */ ((RequirementType2) => {
|
|
|
16887
17863
|
ClinicPhotoTag,
|
|
16888
17864
|
ClinicService,
|
|
16889
17865
|
ClinicTag,
|
|
17866
|
+
ConstantsService,
|
|
16890
17867
|
Contraindication,
|
|
16891
17868
|
CosmeticAllergySubtype,
|
|
16892
17869
|
Currency,
|