@blackcode_sa/metaestetics-api 1.8.4 → 1.8.6
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/index.d.mts +61 -1
- package/dist/index.d.ts +61 -1
- package/dist/index.js +967 -124
- package/dist/index.mjs +999 -124
- package/package.json +1 -1
- package/src/backoffice/expo-safe/README.md +26 -0
- package/src/backoffice/expo-safe/index.ts +37 -0
- package/src/index.ts +1 -0
package/dist/index.mjs
CHANGED
|
@@ -802,6 +802,9 @@ var Gender = /* @__PURE__ */ ((Gender2) => {
|
|
|
802
802
|
// src/types/procedure/index.ts
|
|
803
803
|
var PROCEDURES_COLLECTION = "procedures";
|
|
804
804
|
|
|
805
|
+
// src/backoffice/types/technology.types.ts
|
|
806
|
+
var TECHNOLOGIES_COLLECTION = "technologies";
|
|
807
|
+
|
|
805
808
|
// src/services/appointment/utils/appointment.utils.ts
|
|
806
809
|
async function updateAppointmentUtil(db, appointmentId, data) {
|
|
807
810
|
try {
|
|
@@ -978,7 +981,7 @@ async function searchAppointmentsUtil(db, params) {
|
|
|
978
981
|
const q = query(collection(db, APPOINTMENTS_COLLECTION), ...constraints);
|
|
979
982
|
const querySnapshot = await getDocs(q);
|
|
980
983
|
const appointments = querySnapshot.docs.map(
|
|
981
|
-
(
|
|
984
|
+
(doc37) => doc37.data()
|
|
982
985
|
);
|
|
983
986
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
984
987
|
return { appointments, lastDoc };
|
|
@@ -1785,7 +1788,7 @@ var AppointmentService = class extends BaseService {
|
|
|
1785
1788
|
);
|
|
1786
1789
|
const querySnapshot = await getDocs2(q);
|
|
1787
1790
|
const appointments = querySnapshot.docs.map(
|
|
1788
|
-
(
|
|
1791
|
+
(doc37) => doc37.data()
|
|
1789
1792
|
);
|
|
1790
1793
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
1791
1794
|
console.log(
|
|
@@ -1858,7 +1861,7 @@ var AppointmentService = class extends BaseService {
|
|
|
1858
1861
|
);
|
|
1859
1862
|
const querySnapshot = await getDocs2(q);
|
|
1860
1863
|
const appointments = querySnapshot.docs.map(
|
|
1861
|
-
(
|
|
1864
|
+
(doc37) => doc37.data()
|
|
1862
1865
|
);
|
|
1863
1866
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
1864
1867
|
console.log(
|
|
@@ -2152,16 +2155,16 @@ var CertificationLevel = /* @__PURE__ */ ((CertificationLevel2) => {
|
|
|
2152
2155
|
CertificationLevel2["PLASTIC_SURGEON"] = "plastic_surgeon";
|
|
2153
2156
|
return CertificationLevel2;
|
|
2154
2157
|
})(CertificationLevel || {});
|
|
2155
|
-
var CertificationSpecialty = /* @__PURE__ */ ((
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
return
|
|
2158
|
+
var CertificationSpecialty = /* @__PURE__ */ ((CertificationSpecialty3) => {
|
|
2159
|
+
CertificationSpecialty3["LASER"] = "laser";
|
|
2160
|
+
CertificationSpecialty3["INJECTABLES"] = "injectables";
|
|
2161
|
+
CertificationSpecialty3["CHEMICAL_PEELS"] = "chemical_peels";
|
|
2162
|
+
CertificationSpecialty3["MICRODERMABRASION"] = "microdermabrasion";
|
|
2163
|
+
CertificationSpecialty3["BODY_CONTOURING"] = "body_contouring";
|
|
2164
|
+
CertificationSpecialty3["SKIN_CARE"] = "skin_care";
|
|
2165
|
+
CertificationSpecialty3["WOUND_CARE"] = "wound_care";
|
|
2166
|
+
CertificationSpecialty3["ANESTHESIA"] = "anesthesia";
|
|
2167
|
+
return CertificationSpecialty3;
|
|
2165
2168
|
})(CertificationSpecialty || {});
|
|
2166
2169
|
|
|
2167
2170
|
// src/services/auth/utils/practitioner.utils.ts
|
|
@@ -3167,7 +3170,7 @@ var MediaService = class extends BaseService {
|
|
|
3167
3170
|
try {
|
|
3168
3171
|
const querySnapshot = await getDocs3(finalQuery);
|
|
3169
3172
|
const mediaList = querySnapshot.docs.map(
|
|
3170
|
-
(
|
|
3173
|
+
(doc37) => doc37.data()
|
|
3171
3174
|
);
|
|
3172
3175
|
console.log(`[MediaService] Found ${mediaList.length} media items.`);
|
|
3173
3176
|
return mediaList;
|
|
@@ -3230,8 +3233,8 @@ var getPatientsByClinicUtil = async (db, clinicId, options) => {
|
|
|
3230
3233
|
}
|
|
3231
3234
|
const patientsSnapshot = await getDocs4(q);
|
|
3232
3235
|
const patients = [];
|
|
3233
|
-
patientsSnapshot.forEach((
|
|
3234
|
-
patients.push(
|
|
3236
|
+
patientsSnapshot.forEach((doc37) => {
|
|
3237
|
+
patients.push(doc37.data());
|
|
3235
3238
|
});
|
|
3236
3239
|
console.log(
|
|
3237
3240
|
`[getPatientsByClinicUtil] Found ${patients.length} patients for clinic ID: ${clinicId}`
|
|
@@ -3605,8 +3608,8 @@ var getPatientsByPractitionerUtil = async (db, practitionerId, options) => {
|
|
|
3605
3608
|
}
|
|
3606
3609
|
const patientsSnapshot = await getDocs5(q);
|
|
3607
3610
|
const patients = [];
|
|
3608
|
-
patientsSnapshot.forEach((
|
|
3609
|
-
patients.push(
|
|
3611
|
+
patientsSnapshot.forEach((doc37) => {
|
|
3612
|
+
patients.push(doc37.data());
|
|
3610
3613
|
});
|
|
3611
3614
|
console.log(
|
|
3612
3615
|
`[getPatientsByPractitionerUtil] Found ${patients.length} patients for practitioner ID: ${practitionerId}`
|
|
@@ -4186,7 +4189,7 @@ async function getClinicAdminsByGroup(db, clinicGroupId) {
|
|
|
4186
4189
|
where6("clinicGroupId", "==", clinicGroupId)
|
|
4187
4190
|
);
|
|
4188
4191
|
const querySnapshot = await getDocs6(q);
|
|
4189
|
-
return querySnapshot.docs.map((
|
|
4192
|
+
return querySnapshot.docs.map((doc37) => doc37.data());
|
|
4190
4193
|
}
|
|
4191
4194
|
async function updateClinicAdmin(db, adminId, data) {
|
|
4192
4195
|
const admin2 = await getClinicAdmin(db, adminId);
|
|
@@ -4867,9 +4870,9 @@ var updateAllergyUtil = async (db, patientId, data, requesterId, requesterRoles)
|
|
|
4867
4870
|
};
|
|
4868
4871
|
var removeAllergyUtil = async (db, patientId, allergyIndex, requesterId, requesterRoles) => {
|
|
4869
4872
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4870
|
-
const
|
|
4871
|
-
if (!
|
|
4872
|
-
const medicalInfo =
|
|
4873
|
+
const doc37 = await getDoc10(getMedicalInfoDocRef(db, patientId));
|
|
4874
|
+
if (!doc37.exists()) throw new Error("Medical info not found");
|
|
4875
|
+
const medicalInfo = doc37.data();
|
|
4873
4876
|
if (allergyIndex >= medicalInfo.allergies.length) {
|
|
4874
4877
|
throw new Error("Invalid allergy index");
|
|
4875
4878
|
}
|
|
@@ -4896,9 +4899,9 @@ var updateBlockingConditionUtil = async (db, patientId, data, requesterId, reque
|
|
|
4896
4899
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4897
4900
|
const validatedData = updateBlockingConditionSchema.parse(data);
|
|
4898
4901
|
const { conditionIndex, ...updateData } = validatedData;
|
|
4899
|
-
const
|
|
4900
|
-
if (!
|
|
4901
|
-
const medicalInfo =
|
|
4902
|
+
const doc37 = await getDoc10(getMedicalInfoDocRef(db, patientId));
|
|
4903
|
+
if (!doc37.exists()) throw new Error("Medical info not found");
|
|
4904
|
+
const medicalInfo = doc37.data();
|
|
4902
4905
|
if (conditionIndex >= medicalInfo.blockingConditions.length) {
|
|
4903
4906
|
throw new Error("Invalid blocking condition index");
|
|
4904
4907
|
}
|
|
@@ -4915,9 +4918,9 @@ var updateBlockingConditionUtil = async (db, patientId, data, requesterId, reque
|
|
|
4915
4918
|
};
|
|
4916
4919
|
var removeBlockingConditionUtil = async (db, patientId, conditionIndex, requesterId, requesterRoles) => {
|
|
4917
4920
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4918
|
-
const
|
|
4919
|
-
if (!
|
|
4920
|
-
const medicalInfo =
|
|
4921
|
+
const doc37 = await getDoc10(getMedicalInfoDocRef(db, patientId));
|
|
4922
|
+
if (!doc37.exists()) throw new Error("Medical info not found");
|
|
4923
|
+
const medicalInfo = doc37.data();
|
|
4921
4924
|
if (conditionIndex >= medicalInfo.blockingConditions.length) {
|
|
4922
4925
|
throw new Error("Invalid blocking condition index");
|
|
4923
4926
|
}
|
|
@@ -4944,9 +4947,9 @@ var updateContraindicationUtil = async (db, patientId, data, requesterId, reques
|
|
|
4944
4947
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4945
4948
|
const validatedData = updateContraindicationSchema.parse(data);
|
|
4946
4949
|
const { contraindicationIndex, ...updateData } = validatedData;
|
|
4947
|
-
const
|
|
4948
|
-
if (!
|
|
4949
|
-
const medicalInfo =
|
|
4950
|
+
const doc37 = await getDoc10(getMedicalInfoDocRef(db, patientId));
|
|
4951
|
+
if (!doc37.exists()) throw new Error("Medical info not found");
|
|
4952
|
+
const medicalInfo = doc37.data();
|
|
4950
4953
|
if (contraindicationIndex >= medicalInfo.contraindications.length) {
|
|
4951
4954
|
throw new Error("Invalid contraindication index");
|
|
4952
4955
|
}
|
|
@@ -4963,9 +4966,9 @@ var updateContraindicationUtil = async (db, patientId, data, requesterId, reques
|
|
|
4963
4966
|
};
|
|
4964
4967
|
var removeContraindicationUtil = async (db, patientId, contraindicationIndex, requesterId, requesterRoles) => {
|
|
4965
4968
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4966
|
-
const
|
|
4967
|
-
if (!
|
|
4968
|
-
const medicalInfo =
|
|
4969
|
+
const doc37 = await getDoc10(getMedicalInfoDocRef(db, patientId));
|
|
4970
|
+
if (!doc37.exists()) throw new Error("Medical info not found");
|
|
4971
|
+
const medicalInfo = doc37.data();
|
|
4969
4972
|
if (contraindicationIndex >= medicalInfo.contraindications.length) {
|
|
4970
4973
|
throw new Error("Invalid contraindication index");
|
|
4971
4974
|
}
|
|
@@ -4992,9 +4995,9 @@ var updateMedicationUtil = async (db, patientId, data, requesterId, requesterRol
|
|
|
4992
4995
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4993
4996
|
const validatedData = updateMedicationSchema.parse(data);
|
|
4994
4997
|
const { medicationIndex, ...updateData } = validatedData;
|
|
4995
|
-
const
|
|
4996
|
-
if (!
|
|
4997
|
-
const medicalInfo =
|
|
4998
|
+
const doc37 = await getDoc10(getMedicalInfoDocRef(db, patientId));
|
|
4999
|
+
if (!doc37.exists()) throw new Error("Medical info not found");
|
|
5000
|
+
const medicalInfo = doc37.data();
|
|
4998
5001
|
if (medicationIndex >= medicalInfo.currentMedications.length) {
|
|
4999
5002
|
throw new Error("Invalid medication index");
|
|
5000
5003
|
}
|
|
@@ -5011,9 +5014,9 @@ var updateMedicationUtil = async (db, patientId, data, requesterId, requesterRol
|
|
|
5011
5014
|
};
|
|
5012
5015
|
var removeMedicationUtil = async (db, patientId, medicationIndex, requesterId, requesterRoles) => {
|
|
5013
5016
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
5014
|
-
const
|
|
5015
|
-
if (!
|
|
5016
|
-
const medicalInfo =
|
|
5017
|
+
const doc37 = await getDoc10(getMedicalInfoDocRef(db, patientId));
|
|
5018
|
+
if (!doc37.exists()) throw new Error("Medical info not found");
|
|
5019
|
+
const medicalInfo = doc37.data();
|
|
5017
5020
|
if (medicationIndex >= medicalInfo.currentMedications.length) {
|
|
5018
5021
|
throw new Error("Invalid medication index");
|
|
5019
5022
|
}
|
|
@@ -5316,7 +5319,7 @@ var searchPatientsUtil = async (db, params, requester) => {
|
|
|
5316
5319
|
const finalQuery = query8(patientsCollectionRef, ...constraints);
|
|
5317
5320
|
const querySnapshot = await getDocs8(finalQuery);
|
|
5318
5321
|
const patients = querySnapshot.docs.map(
|
|
5319
|
-
(
|
|
5322
|
+
(doc37) => doc37.data()
|
|
5320
5323
|
);
|
|
5321
5324
|
console.log(
|
|
5322
5325
|
`[searchPatientsUtil] Found ${patients.length} patients matching criteria.`
|
|
@@ -5348,8 +5351,8 @@ var getAllPatientsUtil = async (db, options) => {
|
|
|
5348
5351
|
}
|
|
5349
5352
|
const patientsSnapshot = await getDocs8(q);
|
|
5350
5353
|
const patients = [];
|
|
5351
|
-
patientsSnapshot.forEach((
|
|
5352
|
-
patients.push(
|
|
5354
|
+
patientsSnapshot.forEach((doc37) => {
|
|
5355
|
+
patients.push(doc37.data());
|
|
5353
5356
|
});
|
|
5354
5357
|
console.log(`[getAllPatientsUtil] Found ${patients.length} patients`);
|
|
5355
5358
|
return patients;
|
|
@@ -5482,7 +5485,7 @@ var getActiveInviteTokensByClinicUtil = async (db, clinicId) => {
|
|
|
5482
5485
|
if (querySnapshot.empty) {
|
|
5483
5486
|
return [];
|
|
5484
5487
|
}
|
|
5485
|
-
return querySnapshot.docs.map((
|
|
5488
|
+
return querySnapshot.docs.map((doc37) => doc37.data());
|
|
5486
5489
|
};
|
|
5487
5490
|
var getActiveInviteTokensByPatientUtil = async (db, patientId) => {
|
|
5488
5491
|
const tokensRef = collection9(
|
|
@@ -5500,7 +5503,7 @@ var getActiveInviteTokensByPatientUtil = async (db, patientId) => {
|
|
|
5500
5503
|
if (querySnapshot.empty) {
|
|
5501
5504
|
return [];
|
|
5502
5505
|
}
|
|
5503
|
-
return querySnapshot.docs.map((
|
|
5506
|
+
return querySnapshot.docs.map((doc37) => doc37.data());
|
|
5504
5507
|
};
|
|
5505
5508
|
|
|
5506
5509
|
// src/services/patient/patient.service.ts
|
|
@@ -6623,7 +6626,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6623
6626
|
where10("expiresAt", ">", Timestamp14.now())
|
|
6624
6627
|
);
|
|
6625
6628
|
const querySnapshot = await getDocs10(q);
|
|
6626
|
-
return querySnapshot.docs.map((
|
|
6629
|
+
return querySnapshot.docs.map((doc37) => doc37.data());
|
|
6627
6630
|
}
|
|
6628
6631
|
/**
|
|
6629
6632
|
* Gets a token by its string value and validates it
|
|
@@ -6733,7 +6736,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6733
6736
|
where10("status", "==", "active" /* ACTIVE */)
|
|
6734
6737
|
);
|
|
6735
6738
|
const querySnapshot = await getDocs10(q);
|
|
6736
|
-
return querySnapshot.docs.map((
|
|
6739
|
+
return querySnapshot.docs.map((doc37) => doc37.data());
|
|
6737
6740
|
}
|
|
6738
6741
|
/**
|
|
6739
6742
|
* Dohvata sve zdravstvene radnike za određenu kliniku
|
|
@@ -6745,7 +6748,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6745
6748
|
where10("isActive", "==", true)
|
|
6746
6749
|
);
|
|
6747
6750
|
const querySnapshot = await getDocs10(q);
|
|
6748
|
-
return querySnapshot.docs.map((
|
|
6751
|
+
return querySnapshot.docs.map((doc37) => doc37.data());
|
|
6749
6752
|
}
|
|
6750
6753
|
/**
|
|
6751
6754
|
* Dohvata sve draft zdravstvene radnike za određenu kliniku sa statusom DRAFT
|
|
@@ -6757,7 +6760,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6757
6760
|
where10("status", "==", "draft" /* DRAFT */)
|
|
6758
6761
|
);
|
|
6759
6762
|
const querySnapshot = await getDocs10(q);
|
|
6760
|
-
return querySnapshot.docs.map((
|
|
6763
|
+
return querySnapshot.docs.map((doc37) => doc37.data());
|
|
6761
6764
|
}
|
|
6762
6765
|
/**
|
|
6763
6766
|
* Updates a practitioner
|
|
@@ -6971,7 +6974,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6971
6974
|
);
|
|
6972
6975
|
const querySnapshot = await getDocs10(q);
|
|
6973
6976
|
const practitioners = querySnapshot.docs.map(
|
|
6974
|
-
(
|
|
6977
|
+
(doc37) => doc37.data()
|
|
6975
6978
|
);
|
|
6976
6979
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
6977
6980
|
return {
|
|
@@ -7042,8 +7045,8 @@ var PractitionerService = class extends BaseService {
|
|
|
7042
7045
|
console.log(
|
|
7043
7046
|
`[PRACTITIONER_SERVICE] Found ${querySnapshot.docs.length} practitioners with base query`
|
|
7044
7047
|
);
|
|
7045
|
-
let practitioners = querySnapshot.docs.map((
|
|
7046
|
-
return { ...
|
|
7048
|
+
let practitioners = querySnapshot.docs.map((doc37) => {
|
|
7049
|
+
return { ...doc37.data(), id: doc37.id };
|
|
7047
7050
|
});
|
|
7048
7051
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
7049
7052
|
if (filters.nameSearch && filters.nameSearch.trim() !== "") {
|
|
@@ -7527,7 +7530,7 @@ var UserService = class extends BaseService {
|
|
|
7527
7530
|
];
|
|
7528
7531
|
const q = query11(collection11(this.db, USERS_COLLECTION), ...constraints);
|
|
7529
7532
|
const querySnapshot = await getDocs11(q);
|
|
7530
|
-
const users = querySnapshot.docs.map((
|
|
7533
|
+
const users = querySnapshot.docs.map((doc37) => doc37.data());
|
|
7531
7534
|
return users.map((userData) => userSchema.parse(userData));
|
|
7532
7535
|
}
|
|
7533
7536
|
/**
|
|
@@ -7907,7 +7910,7 @@ async function getAllActiveGroups(db) {
|
|
|
7907
7910
|
where12("isActive", "==", true)
|
|
7908
7911
|
);
|
|
7909
7912
|
const querySnapshot = await getDocs12(q);
|
|
7910
|
-
return querySnapshot.docs.map((
|
|
7913
|
+
return querySnapshot.docs.map((doc37) => doc37.data());
|
|
7911
7914
|
}
|
|
7912
7915
|
async function updateClinicGroup(db, groupId, data, app) {
|
|
7913
7916
|
console.log("[CLINIC_GROUP] Updating clinic group", { groupId });
|
|
@@ -8372,7 +8375,7 @@ async function getClinicsByGroup(db, groupId) {
|
|
|
8372
8375
|
where13("isActive", "==", true)
|
|
8373
8376
|
);
|
|
8374
8377
|
const querySnapshot = await getDocs13(q);
|
|
8375
|
-
return querySnapshot.docs.map((
|
|
8378
|
+
return querySnapshot.docs.map((doc37) => doc37.data());
|
|
8376
8379
|
}
|
|
8377
8380
|
async function updateClinic(db, clinicId, data, adminId, clinicAdminService, app) {
|
|
8378
8381
|
console.log("[CLINIC] Starting clinic update", { clinicId, adminId });
|
|
@@ -8566,7 +8569,7 @@ async function getClinicsByAdmin(db, adminId, options = {}, clinicAdminService,
|
|
|
8566
8569
|
}
|
|
8567
8570
|
const q = query13(collection13(db, CLINICS_COLLECTION), ...constraints);
|
|
8568
8571
|
const querySnapshot = await getDocs13(q);
|
|
8569
|
-
return querySnapshot.docs.map((
|
|
8572
|
+
return querySnapshot.docs.map((doc37) => doc37.data());
|
|
8570
8573
|
}
|
|
8571
8574
|
async function getActiveClinicsByAdmin(db, adminId, clinicAdminService, clinicGroupService) {
|
|
8572
8575
|
return getClinicsByAdmin(
|
|
@@ -8611,11 +8614,11 @@ async function getAllClinics(db, pagination, lastDoc) {
|
|
|
8611
8614
|
}
|
|
8612
8615
|
const clinicsSnapshot = await getDocs13(clinicsQuery);
|
|
8613
8616
|
const lastVisible = clinicsSnapshot.docs[clinicsSnapshot.docs.length - 1];
|
|
8614
|
-
const clinics = clinicsSnapshot.docs.map((
|
|
8615
|
-
const data =
|
|
8617
|
+
const clinics = clinicsSnapshot.docs.map((doc37) => {
|
|
8618
|
+
const data = doc37.data();
|
|
8616
8619
|
return {
|
|
8617
8620
|
...data,
|
|
8618
|
-
id:
|
|
8621
|
+
id: doc37.id
|
|
8619
8622
|
};
|
|
8620
8623
|
});
|
|
8621
8624
|
return {
|
|
@@ -8642,8 +8645,8 @@ async function getAllClinicsInRange(db, center, rangeInKm, pagination, lastDoc)
|
|
|
8642
8645
|
];
|
|
8643
8646
|
const q = query13(collection13(db, CLINICS_COLLECTION), ...constraints);
|
|
8644
8647
|
const querySnapshot = await getDocs13(q);
|
|
8645
|
-
for (const
|
|
8646
|
-
const clinic =
|
|
8648
|
+
for (const doc37 of querySnapshot.docs) {
|
|
8649
|
+
const clinic = doc37.data();
|
|
8647
8650
|
const distance = distanceBetween2(
|
|
8648
8651
|
[center.latitude, center.longitude],
|
|
8649
8652
|
[clinic.location.latitude, clinic.location.longitude]
|
|
@@ -8765,8 +8768,8 @@ async function findClinicsInRadius(db, center, radiusInKm, filters) {
|
|
|
8765
8768
|
}
|
|
8766
8769
|
const q = query14(collection14(db, CLINICS_COLLECTION), ...constraints);
|
|
8767
8770
|
const querySnapshot = await getDocs14(q);
|
|
8768
|
-
for (const
|
|
8769
|
-
const clinic =
|
|
8771
|
+
for (const doc37 of querySnapshot.docs) {
|
|
8772
|
+
const clinic = doc37.data();
|
|
8770
8773
|
const distance = distanceBetween3(
|
|
8771
8774
|
[center.latitude, center.longitude],
|
|
8772
8775
|
[clinic.location.latitude, clinic.location.longitude]
|
|
@@ -8862,8 +8865,8 @@ async function getClinicsByFilters(db, filters) {
|
|
|
8862
8865
|
console.log(
|
|
8863
8866
|
`[FILTER_UTILS] Found ${querySnapshot.docs.length} clinics in geo bound`
|
|
8864
8867
|
);
|
|
8865
|
-
for (const
|
|
8866
|
-
const clinic = { ...
|
|
8868
|
+
for (const doc37 of querySnapshot.docs) {
|
|
8869
|
+
const clinic = { ...doc37.data(), id: doc37.id };
|
|
8867
8870
|
const distance = distanceBetween4(
|
|
8868
8871
|
[center.latitude, center.longitude],
|
|
8869
8872
|
[clinic.location.latitude, clinic.location.longitude]
|
|
@@ -8919,8 +8922,8 @@ async function getClinicsByFilters(db, filters) {
|
|
|
8919
8922
|
console.log(
|
|
8920
8923
|
`[FILTER_UTILS] Found ${querySnapshot.docs.length} clinics with regular query`
|
|
8921
8924
|
);
|
|
8922
|
-
const clinics = querySnapshot.docs.map((
|
|
8923
|
-
return { ...
|
|
8925
|
+
const clinics = querySnapshot.docs.map((doc37) => {
|
|
8926
|
+
return { ...doc37.data(), id: doc37.id };
|
|
8924
8927
|
});
|
|
8925
8928
|
let filteredClinics = clinics;
|
|
8926
8929
|
if (filters.center) {
|
|
@@ -10600,7 +10603,7 @@ async function searchCalendarEventsUtil(db, params) {
|
|
|
10600
10603
|
const finalQuery = query21(collectionRef, ...constraints);
|
|
10601
10604
|
const querySnapshot = await getDocs21(finalQuery);
|
|
10602
10605
|
const events = querySnapshot.docs.map(
|
|
10603
|
-
(
|
|
10606
|
+
(doc37) => ({ id: doc37.id, ...doc37.data() })
|
|
10604
10607
|
);
|
|
10605
10608
|
return events;
|
|
10606
10609
|
} catch (error) {
|
|
@@ -10693,7 +10696,7 @@ async function getPractitionerSyncedCalendarsUtil(db, practitionerId) {
|
|
|
10693
10696
|
);
|
|
10694
10697
|
const q = query22(calendarsRef, orderBy11("createdAt", "desc"));
|
|
10695
10698
|
const querySnapshot = await getDocs22(q);
|
|
10696
|
-
return querySnapshot.docs.map((
|
|
10699
|
+
return querySnapshot.docs.map((doc37) => doc37.data());
|
|
10697
10700
|
}
|
|
10698
10701
|
async function getPatientSyncedCalendarUtil(db, patientId, calendarId) {
|
|
10699
10702
|
const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
|
|
@@ -10710,7 +10713,7 @@ async function getPatientSyncedCalendarsUtil(db, patientId) {
|
|
|
10710
10713
|
);
|
|
10711
10714
|
const q = query22(calendarsRef, orderBy11("createdAt", "desc"));
|
|
10712
10715
|
const querySnapshot = await getDocs22(q);
|
|
10713
|
-
return querySnapshot.docs.map((
|
|
10716
|
+
return querySnapshot.docs.map((doc37) => doc37.data());
|
|
10714
10717
|
}
|
|
10715
10718
|
async function getClinicSyncedCalendarUtil(db, clinicId, calendarId) {
|
|
10716
10719
|
const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
|
|
@@ -10727,7 +10730,7 @@ async function getClinicSyncedCalendarsUtil(db, clinicId) {
|
|
|
10727
10730
|
);
|
|
10728
10731
|
const q = query22(calendarsRef, orderBy11("createdAt", "desc"));
|
|
10729
10732
|
const querySnapshot = await getDocs22(q);
|
|
10730
|
-
return querySnapshot.docs.map((
|
|
10733
|
+
return querySnapshot.docs.map((doc37) => doc37.data());
|
|
10731
10734
|
}
|
|
10732
10735
|
async function updatePractitionerSyncedCalendarUtil(db, practitionerId, calendarId, updateData) {
|
|
10733
10736
|
const calendarRef = getPractitionerSyncedCalendarDocRef(
|
|
@@ -12082,9 +12085,9 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
12082
12085
|
where23("eventTime.start", "<=", Timestamp26.fromDate(endDate))
|
|
12083
12086
|
);
|
|
12084
12087
|
const eventsSnapshot = await getDocs23(q);
|
|
12085
|
-
const events = eventsSnapshot.docs.map((
|
|
12086
|
-
id:
|
|
12087
|
-
...
|
|
12088
|
+
const events = eventsSnapshot.docs.map((doc37) => ({
|
|
12089
|
+
id: doc37.id,
|
|
12090
|
+
...doc37.data()
|
|
12088
12091
|
}));
|
|
12089
12092
|
const calendars = await this.syncedCalendarsService.getPractitionerSyncedCalendars(
|
|
12090
12093
|
doctorId
|
|
@@ -12718,7 +12721,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
12718
12721
|
])
|
|
12719
12722
|
);
|
|
12720
12723
|
const querySnapshot = await getDocs23(q);
|
|
12721
|
-
return querySnapshot.docs.map((
|
|
12724
|
+
return querySnapshot.docs.map((doc37) => doc37.data());
|
|
12722
12725
|
}
|
|
12723
12726
|
/**
|
|
12724
12727
|
* Calculates available time slots based on working hours, schedule and existing appointments
|
|
@@ -13263,7 +13266,7 @@ var PractitionerInviteService = class extends BaseService {
|
|
|
13263
13266
|
...constraints
|
|
13264
13267
|
);
|
|
13265
13268
|
const querySnapshot = await getDocs24(q);
|
|
13266
|
-
return querySnapshot.docs.map((
|
|
13269
|
+
return querySnapshot.docs.map((doc37) => doc37.data());
|
|
13267
13270
|
} catch (error) {
|
|
13268
13271
|
console.error(
|
|
13269
13272
|
"[PractitionerInviteService] Error getting doctor invites:",
|
|
@@ -13292,7 +13295,7 @@ var PractitionerInviteService = class extends BaseService {
|
|
|
13292
13295
|
...constraints
|
|
13293
13296
|
);
|
|
13294
13297
|
const querySnapshot = await getDocs24(q);
|
|
13295
|
-
return querySnapshot.docs.map((
|
|
13298
|
+
return querySnapshot.docs.map((doc37) => doc37.data());
|
|
13296
13299
|
} catch (error) {
|
|
13297
13300
|
console.error(
|
|
13298
13301
|
"[PractitionerInviteService] Error getting clinic invites:",
|
|
@@ -13448,7 +13451,7 @@ var PractitionerInviteService = class extends BaseService {
|
|
|
13448
13451
|
);
|
|
13449
13452
|
const querySnapshot = await getDocs24(q);
|
|
13450
13453
|
let invites = querySnapshot.docs.map(
|
|
13451
|
-
(
|
|
13454
|
+
(doc37) => doc37.data()
|
|
13452
13455
|
);
|
|
13453
13456
|
if (filters.fromDate) {
|
|
13454
13457
|
invites = invites.filter(
|
|
@@ -13718,8 +13721,8 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
13718
13721
|
const q = query25(versionsCollectionRef, orderBy13("version", "desc"));
|
|
13719
13722
|
const querySnapshot = await getDocs25(q);
|
|
13720
13723
|
const versions = [];
|
|
13721
|
-
querySnapshot.forEach((
|
|
13722
|
-
versions.push(
|
|
13724
|
+
querySnapshot.forEach((doc37) => {
|
|
13725
|
+
versions.push(doc37.data());
|
|
13723
13726
|
});
|
|
13724
13727
|
return versions;
|
|
13725
13728
|
}
|
|
@@ -13750,9 +13753,9 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
13750
13753
|
const querySnapshot = await getDocs25(q);
|
|
13751
13754
|
const templates = [];
|
|
13752
13755
|
let lastVisible = null;
|
|
13753
|
-
querySnapshot.forEach((
|
|
13754
|
-
templates.push(
|
|
13755
|
-
lastVisible =
|
|
13756
|
+
querySnapshot.forEach((doc37) => {
|
|
13757
|
+
templates.push(doc37.data());
|
|
13758
|
+
lastVisible = doc37;
|
|
13756
13759
|
});
|
|
13757
13760
|
return {
|
|
13758
13761
|
templates,
|
|
@@ -13780,9 +13783,9 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
13780
13783
|
const querySnapshot = await getDocs25(q);
|
|
13781
13784
|
const templates = [];
|
|
13782
13785
|
let lastVisible = null;
|
|
13783
|
-
querySnapshot.forEach((
|
|
13784
|
-
templates.push(
|
|
13785
|
-
lastVisible =
|
|
13786
|
+
querySnapshot.forEach((doc37) => {
|
|
13787
|
+
templates.push(doc37.data());
|
|
13788
|
+
lastVisible = doc37;
|
|
13786
13789
|
});
|
|
13787
13790
|
return {
|
|
13788
13791
|
templates,
|
|
@@ -13809,9 +13812,9 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
13809
13812
|
const querySnapshot = await getDocs25(q);
|
|
13810
13813
|
const templates = [];
|
|
13811
13814
|
let lastVisible = null;
|
|
13812
|
-
querySnapshot.forEach((
|
|
13813
|
-
templates.push(
|
|
13814
|
-
lastVisible =
|
|
13815
|
+
querySnapshot.forEach((doc37) => {
|
|
13816
|
+
templates.push(doc37.data());
|
|
13817
|
+
lastVisible = doc37;
|
|
13815
13818
|
});
|
|
13816
13819
|
return {
|
|
13817
13820
|
templates,
|
|
@@ -13837,8 +13840,8 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
13837
13840
|
}
|
|
13838
13841
|
const querySnapshot = await getDocs25(q);
|
|
13839
13842
|
const templates = [];
|
|
13840
|
-
querySnapshot.forEach((
|
|
13841
|
-
templates.push(
|
|
13843
|
+
querySnapshot.forEach((doc37) => {
|
|
13844
|
+
templates.push(doc37.data());
|
|
13842
13845
|
});
|
|
13843
13846
|
return templates;
|
|
13844
13847
|
}
|
|
@@ -14044,9 +14047,9 @@ var FilledDocumentService = class extends BaseService {
|
|
|
14044
14047
|
const querySnapshot = await getDocs26(q);
|
|
14045
14048
|
const documents = [];
|
|
14046
14049
|
let lastVisible = null;
|
|
14047
|
-
querySnapshot.forEach((
|
|
14048
|
-
documents.push(
|
|
14049
|
-
lastVisible =
|
|
14050
|
+
querySnapshot.forEach((doc37) => {
|
|
14051
|
+
documents.push(doc37.data());
|
|
14052
|
+
lastVisible = doc37;
|
|
14050
14053
|
});
|
|
14051
14054
|
return {
|
|
14052
14055
|
documents,
|
|
@@ -14268,9 +14271,9 @@ var NotificationService = class extends BaseService {
|
|
|
14268
14271
|
orderBy15("notificationTime", "desc")
|
|
14269
14272
|
);
|
|
14270
14273
|
const querySnapshot = await getDocs27(q);
|
|
14271
|
-
return querySnapshot.docs.map((
|
|
14272
|
-
id:
|
|
14273
|
-
...
|
|
14274
|
+
return querySnapshot.docs.map((doc37) => ({
|
|
14275
|
+
id: doc37.id,
|
|
14276
|
+
...doc37.data()
|
|
14274
14277
|
}));
|
|
14275
14278
|
}
|
|
14276
14279
|
/**
|
|
@@ -14284,9 +14287,9 @@ var NotificationService = class extends BaseService {
|
|
|
14284
14287
|
orderBy15("notificationTime", "desc")
|
|
14285
14288
|
);
|
|
14286
14289
|
const querySnapshot = await getDocs27(q);
|
|
14287
|
-
return querySnapshot.docs.map((
|
|
14288
|
-
id:
|
|
14289
|
-
...
|
|
14290
|
+
return querySnapshot.docs.map((doc37) => ({
|
|
14291
|
+
id: doc37.id,
|
|
14292
|
+
...doc37.data()
|
|
14290
14293
|
}));
|
|
14291
14294
|
}
|
|
14292
14295
|
/**
|
|
@@ -14358,9 +14361,9 @@ var NotificationService = class extends BaseService {
|
|
|
14358
14361
|
orderBy15("notificationTime", "desc")
|
|
14359
14362
|
);
|
|
14360
14363
|
const querySnapshot = await getDocs27(q);
|
|
14361
|
-
return querySnapshot.docs.map((
|
|
14362
|
-
id:
|
|
14363
|
-
...
|
|
14364
|
+
return querySnapshot.docs.map((doc37) => ({
|
|
14365
|
+
id: doc37.id,
|
|
14366
|
+
...doc37.data()
|
|
14364
14367
|
}));
|
|
14365
14368
|
}
|
|
14366
14369
|
/**
|
|
@@ -14373,9 +14376,9 @@ var NotificationService = class extends BaseService {
|
|
|
14373
14376
|
orderBy15("notificationTime", "desc")
|
|
14374
14377
|
);
|
|
14375
14378
|
const querySnapshot = await getDocs27(q);
|
|
14376
|
-
return querySnapshot.docs.map((
|
|
14377
|
-
id:
|
|
14378
|
-
...
|
|
14379
|
+
return querySnapshot.docs.map((doc37) => ({
|
|
14380
|
+
id: doc37.id,
|
|
14381
|
+
...doc37.data()
|
|
14379
14382
|
}));
|
|
14380
14383
|
}
|
|
14381
14384
|
};
|
|
@@ -14880,8 +14883,8 @@ var ProcedureService = class extends BaseService {
|
|
|
14880
14883
|
where29(documentId2(), "in", chunk)
|
|
14881
14884
|
);
|
|
14882
14885
|
const practitionersSnapshot = await getDocs29(practitionersQuery);
|
|
14883
|
-
practitionersSnapshot.docs.forEach((
|
|
14884
|
-
practitionersMap.set(
|
|
14886
|
+
practitionersSnapshot.docs.forEach((doc37) => {
|
|
14887
|
+
practitionersMap.set(doc37.id, doc37.data());
|
|
14885
14888
|
});
|
|
14886
14889
|
}
|
|
14887
14890
|
if (practitionersMap.size !== practitionerIds.length) {
|
|
@@ -14963,8 +14966,8 @@ var ProcedureService = class extends BaseService {
|
|
|
14963
14966
|
where29(documentId2(), "in", chunk)
|
|
14964
14967
|
);
|
|
14965
14968
|
const snapshot = await getDocs29(q);
|
|
14966
|
-
snapshot.forEach((
|
|
14967
|
-
fetchedProcedures.push(
|
|
14969
|
+
snapshot.forEach((doc37) => {
|
|
14970
|
+
fetchedProcedures.push(doc37.data());
|
|
14968
14971
|
});
|
|
14969
14972
|
}
|
|
14970
14973
|
return fetchedProcedures;
|
|
@@ -14994,7 +14997,7 @@ var ProcedureService = class extends BaseService {
|
|
|
14994
14997
|
where29("isActive", "==", true)
|
|
14995
14998
|
);
|
|
14996
14999
|
const snapshot = await getDocs29(q);
|
|
14997
|
-
return snapshot.docs.map((
|
|
15000
|
+
return snapshot.docs.map((doc37) => doc37.data());
|
|
14998
15001
|
}
|
|
14999
15002
|
/**
|
|
15000
15003
|
* Gets all procedures for a practitioner
|
|
@@ -15008,7 +15011,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15008
15011
|
where29("isActive", "==", true)
|
|
15009
15012
|
);
|
|
15010
15013
|
const snapshot = await getDocs29(q);
|
|
15011
|
-
return snapshot.docs.map((
|
|
15014
|
+
return snapshot.docs.map((doc37) => doc37.data());
|
|
15012
15015
|
}
|
|
15013
15016
|
/**
|
|
15014
15017
|
* Gets all inactive procedures for a practitioner
|
|
@@ -15022,7 +15025,7 @@ var ProcedureService = class extends BaseService {
|
|
|
15022
15025
|
where29("isActive", "==", false)
|
|
15023
15026
|
);
|
|
15024
15027
|
const snapshot = await getDocs29(q);
|
|
15025
|
-
return snapshot.docs.map((
|
|
15028
|
+
return snapshot.docs.map((doc37) => doc37.data());
|
|
15026
15029
|
}
|
|
15027
15030
|
/**
|
|
15028
15031
|
* Updates a procedure
|
|
@@ -15234,11 +15237,11 @@ var ProcedureService = class extends BaseService {
|
|
|
15234
15237
|
}
|
|
15235
15238
|
const proceduresSnapshot = await getDocs29(proceduresQuery);
|
|
15236
15239
|
const lastVisible = proceduresSnapshot.docs[proceduresSnapshot.docs.length - 1];
|
|
15237
|
-
const procedures = proceduresSnapshot.docs.map((
|
|
15238
|
-
const data =
|
|
15240
|
+
const procedures = proceduresSnapshot.docs.map((doc37) => {
|
|
15241
|
+
const data = doc37.data();
|
|
15239
15242
|
return {
|
|
15240
15243
|
...data,
|
|
15241
|
-
id:
|
|
15244
|
+
id: doc37.id
|
|
15242
15245
|
// Ensure ID is present
|
|
15243
15246
|
};
|
|
15244
15247
|
});
|
|
@@ -15320,8 +15323,8 @@ var ProcedureService = class extends BaseService {
|
|
|
15320
15323
|
console.log(
|
|
15321
15324
|
`[PROCEDURE_SERVICE] Found ${querySnapshot.docs.length} procedures in geo bound`
|
|
15322
15325
|
);
|
|
15323
|
-
for (const
|
|
15324
|
-
const procedure = { ...
|
|
15326
|
+
for (const doc37 of querySnapshot.docs) {
|
|
15327
|
+
const procedure = { ...doc37.data(), id: doc37.id };
|
|
15325
15328
|
const distance = distanceBetween6(
|
|
15326
15329
|
[center.latitude, center.longitude],
|
|
15327
15330
|
[
|
|
@@ -15372,8 +15375,8 @@ var ProcedureService = class extends BaseService {
|
|
|
15372
15375
|
console.log(
|
|
15373
15376
|
`[PROCEDURE_SERVICE] Found ${querySnapshot.docs.length} procedures with regular query`
|
|
15374
15377
|
);
|
|
15375
|
-
const procedures = querySnapshot.docs.map((
|
|
15376
|
-
return { ...
|
|
15378
|
+
const procedures = querySnapshot.docs.map((doc37) => {
|
|
15379
|
+
return { ...doc37.data(), id: doc37.id };
|
|
15377
15380
|
});
|
|
15378
15381
|
if (filters.location) {
|
|
15379
15382
|
const center = filters.location;
|
|
@@ -15716,7 +15719,7 @@ var ReviewService = class extends BaseService {
|
|
|
15716
15719
|
where30("patientId", "==", patientId)
|
|
15717
15720
|
);
|
|
15718
15721
|
const snapshot = await getDocs30(q);
|
|
15719
|
-
return snapshot.docs.map((
|
|
15722
|
+
return snapshot.docs.map((doc37) => doc37.data());
|
|
15720
15723
|
}
|
|
15721
15724
|
/**
|
|
15722
15725
|
* Gets all reviews for a specific clinic
|
|
@@ -15729,7 +15732,7 @@ var ReviewService = class extends BaseService {
|
|
|
15729
15732
|
where30("clinicReview.clinicId", "==", clinicId)
|
|
15730
15733
|
);
|
|
15731
15734
|
const snapshot = await getDocs30(q);
|
|
15732
|
-
return snapshot.docs.map((
|
|
15735
|
+
return snapshot.docs.map((doc37) => doc37.data());
|
|
15733
15736
|
}
|
|
15734
15737
|
/**
|
|
15735
15738
|
* Gets all reviews for a specific practitioner
|
|
@@ -15742,7 +15745,7 @@ var ReviewService = class extends BaseService {
|
|
|
15742
15745
|
where30("practitionerReview.practitionerId", "==", practitionerId)
|
|
15743
15746
|
);
|
|
15744
15747
|
const snapshot = await getDocs30(q);
|
|
15745
|
-
return snapshot.docs.map((
|
|
15748
|
+
return snapshot.docs.map((doc37) => doc37.data());
|
|
15746
15749
|
}
|
|
15747
15750
|
/**
|
|
15748
15751
|
* Gets all reviews for a specific procedure
|
|
@@ -15755,7 +15758,7 @@ var ReviewService = class extends BaseService {
|
|
|
15755
15758
|
where30("procedureReview.procedureId", "==", procedureId)
|
|
15756
15759
|
);
|
|
15757
15760
|
const snapshot = await getDocs30(q);
|
|
15758
|
-
return snapshot.docs.map((
|
|
15761
|
+
return snapshot.docs.map((doc37) => doc37.data());
|
|
15759
15762
|
}
|
|
15760
15763
|
/**
|
|
15761
15764
|
* Gets all reviews for a specific appointment
|
|
@@ -16421,6 +16424,863 @@ var getFirebaseFunctions = async () => {
|
|
|
16421
16424
|
const instance = await getFirebaseInstance();
|
|
16422
16425
|
return instance.functions;
|
|
16423
16426
|
};
|
|
16427
|
+
|
|
16428
|
+
// src/backoffice/services/brand.service.ts
|
|
16429
|
+
import {
|
|
16430
|
+
addDoc as addDoc3,
|
|
16431
|
+
collection as collection31,
|
|
16432
|
+
doc as doc32,
|
|
16433
|
+
getDoc as getDoc34,
|
|
16434
|
+
getDocs as getDocs31,
|
|
16435
|
+
query as query31,
|
|
16436
|
+
updateDoc as updateDoc30,
|
|
16437
|
+
where as where31
|
|
16438
|
+
} from "firebase/firestore";
|
|
16439
|
+
|
|
16440
|
+
// src/backoffice/types/brand.types.ts
|
|
16441
|
+
var BRANDS_COLLECTION = "brands";
|
|
16442
|
+
|
|
16443
|
+
// src/backoffice/services/brand.service.ts
|
|
16444
|
+
var BrandService = class extends BaseService {
|
|
16445
|
+
/**
|
|
16446
|
+
* Gets reference to brands collection
|
|
16447
|
+
*/
|
|
16448
|
+
getBrandsRef() {
|
|
16449
|
+
return collection31(this.db, BRANDS_COLLECTION);
|
|
16450
|
+
}
|
|
16451
|
+
/**
|
|
16452
|
+
* Creates a new brand
|
|
16453
|
+
*/
|
|
16454
|
+
async create(brand) {
|
|
16455
|
+
const now = /* @__PURE__ */ new Date();
|
|
16456
|
+
const newBrand = {
|
|
16457
|
+
...brand,
|
|
16458
|
+
createdAt: now,
|
|
16459
|
+
updatedAt: now,
|
|
16460
|
+
isActive: true
|
|
16461
|
+
};
|
|
16462
|
+
const docRef = await addDoc3(this.getBrandsRef(), newBrand);
|
|
16463
|
+
return { id: docRef.id, ...newBrand };
|
|
16464
|
+
}
|
|
16465
|
+
/**
|
|
16466
|
+
* Gets all active brands
|
|
16467
|
+
*/
|
|
16468
|
+
async getAll() {
|
|
16469
|
+
const q = query31(this.getBrandsRef(), where31("isActive", "==", true));
|
|
16470
|
+
const snapshot = await getDocs31(q);
|
|
16471
|
+
return snapshot.docs.map(
|
|
16472
|
+
(doc37) => ({
|
|
16473
|
+
id: doc37.id,
|
|
16474
|
+
...doc37.data()
|
|
16475
|
+
})
|
|
16476
|
+
);
|
|
16477
|
+
}
|
|
16478
|
+
/**
|
|
16479
|
+
* Updates a brand
|
|
16480
|
+
*/
|
|
16481
|
+
async update(brandId, brand) {
|
|
16482
|
+
const updateData = {
|
|
16483
|
+
...brand,
|
|
16484
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
16485
|
+
};
|
|
16486
|
+
const docRef = doc32(this.getBrandsRef(), brandId);
|
|
16487
|
+
await updateDoc30(docRef, updateData);
|
|
16488
|
+
return this.getById(brandId);
|
|
16489
|
+
}
|
|
16490
|
+
/**
|
|
16491
|
+
* Soft deletes a brand
|
|
16492
|
+
*/
|
|
16493
|
+
async delete(brandId) {
|
|
16494
|
+
await this.update(brandId, {
|
|
16495
|
+
isActive: false
|
|
16496
|
+
});
|
|
16497
|
+
}
|
|
16498
|
+
/**
|
|
16499
|
+
* Gets a brand by ID
|
|
16500
|
+
*/
|
|
16501
|
+
async getById(brandId) {
|
|
16502
|
+
const docRef = doc32(this.getBrandsRef(), brandId);
|
|
16503
|
+
const docSnap = await getDoc34(docRef);
|
|
16504
|
+
if (!docSnap.exists()) return null;
|
|
16505
|
+
return {
|
|
16506
|
+
id: docSnap.id,
|
|
16507
|
+
...docSnap.data()
|
|
16508
|
+
};
|
|
16509
|
+
}
|
|
16510
|
+
};
|
|
16511
|
+
|
|
16512
|
+
// src/backoffice/services/category.service.ts
|
|
16513
|
+
import {
|
|
16514
|
+
addDoc as addDoc4,
|
|
16515
|
+
collection as collection32,
|
|
16516
|
+
doc as doc33,
|
|
16517
|
+
getDoc as getDoc35,
|
|
16518
|
+
getDocs as getDocs32,
|
|
16519
|
+
query as query32,
|
|
16520
|
+
updateDoc as updateDoc31,
|
|
16521
|
+
where as where32
|
|
16522
|
+
} from "firebase/firestore";
|
|
16523
|
+
|
|
16524
|
+
// src/backoffice/types/category.types.ts
|
|
16525
|
+
var CATEGORIES_COLLECTION = "backoffice_categories";
|
|
16526
|
+
|
|
16527
|
+
// src/backoffice/services/category.service.ts
|
|
16528
|
+
var CategoryService = class extends BaseService {
|
|
16529
|
+
/**
|
|
16530
|
+
* Referenca na Firestore kolekciju kategorija
|
|
16531
|
+
*/
|
|
16532
|
+
get categoriesRef() {
|
|
16533
|
+
return collection32(this.db, CATEGORIES_COLLECTION);
|
|
16534
|
+
}
|
|
16535
|
+
/**
|
|
16536
|
+
* Kreira novu kategoriju u sistemu
|
|
16537
|
+
* @param category - Podaci za novu kategoriju
|
|
16538
|
+
* @returns Kreirana kategorija sa generisanim ID-em
|
|
16539
|
+
*/
|
|
16540
|
+
async create(category) {
|
|
16541
|
+
const now = /* @__PURE__ */ new Date();
|
|
16542
|
+
const newCategory = {
|
|
16543
|
+
...category,
|
|
16544
|
+
createdAt: now,
|
|
16545
|
+
updatedAt: now,
|
|
16546
|
+
isActive: true
|
|
16547
|
+
};
|
|
16548
|
+
const docRef = await addDoc4(this.categoriesRef, newCategory);
|
|
16549
|
+
return { id: docRef.id, ...newCategory };
|
|
16550
|
+
}
|
|
16551
|
+
/**
|
|
16552
|
+
* Vraća sve aktivne kategorije
|
|
16553
|
+
* @returns Lista aktivnih kategorija
|
|
16554
|
+
*/
|
|
16555
|
+
async getAll() {
|
|
16556
|
+
const q = query32(this.categoriesRef, where32("isActive", "==", true));
|
|
16557
|
+
const snapshot = await getDocs32(q);
|
|
16558
|
+
return snapshot.docs.map(
|
|
16559
|
+
(doc37) => ({
|
|
16560
|
+
id: doc37.id,
|
|
16561
|
+
...doc37.data()
|
|
16562
|
+
})
|
|
16563
|
+
);
|
|
16564
|
+
}
|
|
16565
|
+
/**
|
|
16566
|
+
* Vraća sve aktivne kategorije za određenu familiju procedura
|
|
16567
|
+
* @param family - Familija procedura (aesthetics/surgery)
|
|
16568
|
+
* @returns Lista kategorija koje pripadaju traženoj familiji
|
|
16569
|
+
*/
|
|
16570
|
+
async getAllByFamily(family) {
|
|
16571
|
+
const q = query32(
|
|
16572
|
+
this.categoriesRef,
|
|
16573
|
+
where32("family", "==", family),
|
|
16574
|
+
where32("isActive", "==", true)
|
|
16575
|
+
);
|
|
16576
|
+
const snapshot = await getDocs32(q);
|
|
16577
|
+
return snapshot.docs.map(
|
|
16578
|
+
(doc37) => ({
|
|
16579
|
+
id: doc37.id,
|
|
16580
|
+
...doc37.data()
|
|
16581
|
+
})
|
|
16582
|
+
);
|
|
16583
|
+
}
|
|
16584
|
+
/**
|
|
16585
|
+
* Ažurira postojeću kategoriju
|
|
16586
|
+
* @param id - ID kategorije koja se ažurira
|
|
16587
|
+
* @param category - Novi podaci za kategoriju
|
|
16588
|
+
* @returns Ažurirana kategorija
|
|
16589
|
+
*/
|
|
16590
|
+
async update(id, category) {
|
|
16591
|
+
const updateData = {
|
|
16592
|
+
...category,
|
|
16593
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
16594
|
+
};
|
|
16595
|
+
const docRef = doc33(this.categoriesRef, id);
|
|
16596
|
+
await updateDoc31(docRef, updateData);
|
|
16597
|
+
return this.getById(id);
|
|
16598
|
+
}
|
|
16599
|
+
/**
|
|
16600
|
+
* Soft delete kategorije (postavlja isActive na false)
|
|
16601
|
+
* @param id - ID kategorije koja se briše
|
|
16602
|
+
*/
|
|
16603
|
+
async delete(id) {
|
|
16604
|
+
await this.update(id, { isActive: false });
|
|
16605
|
+
}
|
|
16606
|
+
/**
|
|
16607
|
+
* Vraća kategoriju po ID-u
|
|
16608
|
+
* @param id - ID tražene kategorije
|
|
16609
|
+
* @returns Kategorija ili null ako ne postoji
|
|
16610
|
+
*/
|
|
16611
|
+
async getById(id) {
|
|
16612
|
+
const docRef = doc33(this.categoriesRef, id);
|
|
16613
|
+
const docSnap = await getDoc35(docRef);
|
|
16614
|
+
if (!docSnap.exists()) return null;
|
|
16615
|
+
return {
|
|
16616
|
+
id: docSnap.id,
|
|
16617
|
+
...docSnap.data()
|
|
16618
|
+
};
|
|
16619
|
+
}
|
|
16620
|
+
};
|
|
16621
|
+
|
|
16622
|
+
// src/backoffice/services/subcategory.service.ts
|
|
16623
|
+
import {
|
|
16624
|
+
addDoc as addDoc5,
|
|
16625
|
+
collection as collection33,
|
|
16626
|
+
doc as doc34,
|
|
16627
|
+
getDoc as getDoc36,
|
|
16628
|
+
getDocs as getDocs33,
|
|
16629
|
+
query as query33,
|
|
16630
|
+
updateDoc as updateDoc32,
|
|
16631
|
+
where as where33
|
|
16632
|
+
} from "firebase/firestore";
|
|
16633
|
+
|
|
16634
|
+
// src/backoffice/types/subcategory.types.ts
|
|
16635
|
+
var SUBCATEGORIES_COLLECTION = "subcategories";
|
|
16636
|
+
|
|
16637
|
+
// src/backoffice/services/subcategory.service.ts
|
|
16638
|
+
var SubcategoryService = class extends BaseService {
|
|
16639
|
+
/**
|
|
16640
|
+
* Vraća referencu na Firestore kolekciju podkategorija za određenu kategoriju
|
|
16641
|
+
* @param categoryId - ID roditeljske kategorije
|
|
16642
|
+
*/
|
|
16643
|
+
getSubcategoriesRef(categoryId) {
|
|
16644
|
+
return collection33(
|
|
16645
|
+
this.db,
|
|
16646
|
+
CATEGORIES_COLLECTION,
|
|
16647
|
+
categoryId,
|
|
16648
|
+
SUBCATEGORIES_COLLECTION
|
|
16649
|
+
);
|
|
16650
|
+
}
|
|
16651
|
+
/**
|
|
16652
|
+
* Kreira novu podkategoriju u okviru kategorije
|
|
16653
|
+
* @param categoryId - ID kategorije kojoj će pripadati nova podkategorija
|
|
16654
|
+
* @param subcategory - Podaci za novu podkategoriju
|
|
16655
|
+
* @returns Kreirana podkategorija sa generisanim ID-em
|
|
16656
|
+
*/
|
|
16657
|
+
async create(categoryId, subcategory) {
|
|
16658
|
+
const now = /* @__PURE__ */ new Date();
|
|
16659
|
+
const newSubcategory = {
|
|
16660
|
+
...subcategory,
|
|
16661
|
+
categoryId,
|
|
16662
|
+
createdAt: now,
|
|
16663
|
+
updatedAt: now,
|
|
16664
|
+
isActive: true
|
|
16665
|
+
};
|
|
16666
|
+
const docRef = await addDoc5(
|
|
16667
|
+
this.getSubcategoriesRef(categoryId),
|
|
16668
|
+
newSubcategory
|
|
16669
|
+
);
|
|
16670
|
+
return { id: docRef.id, ...newSubcategory };
|
|
16671
|
+
}
|
|
16672
|
+
/**
|
|
16673
|
+
* Vraća sve aktivne podkategorije za određenu kategoriju
|
|
16674
|
+
* @param categoryId - ID kategorije čije podkategorije tražimo
|
|
16675
|
+
* @returns Lista aktivnih podkategorija
|
|
16676
|
+
*/
|
|
16677
|
+
async getAllByCategoryId(categoryId) {
|
|
16678
|
+
const q = query33(
|
|
16679
|
+
this.getSubcategoriesRef(categoryId),
|
|
16680
|
+
where33("isActive", "==", true)
|
|
16681
|
+
);
|
|
16682
|
+
const snapshot = await getDocs33(q);
|
|
16683
|
+
return snapshot.docs.map(
|
|
16684
|
+
(doc37) => ({
|
|
16685
|
+
id: doc37.id,
|
|
16686
|
+
...doc37.data()
|
|
16687
|
+
})
|
|
16688
|
+
);
|
|
16689
|
+
}
|
|
16690
|
+
/**
|
|
16691
|
+
* Ažurira postojeću podkategoriju
|
|
16692
|
+
* @param categoryId - ID kategorije kojoj pripada podkategorija
|
|
16693
|
+
* @param subcategoryId - ID podkategorije koja se ažurira
|
|
16694
|
+
* @param subcategory - Novi podaci za podkategoriju
|
|
16695
|
+
* @returns Ažurirana podkategorija
|
|
16696
|
+
*/
|
|
16697
|
+
async update(categoryId, subcategoryId, subcategory) {
|
|
16698
|
+
const updateData = {
|
|
16699
|
+
...subcategory,
|
|
16700
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
16701
|
+
};
|
|
16702
|
+
const docRef = doc34(this.getSubcategoriesRef(categoryId), subcategoryId);
|
|
16703
|
+
await updateDoc32(docRef, updateData);
|
|
16704
|
+
return this.getById(categoryId, subcategoryId);
|
|
16705
|
+
}
|
|
16706
|
+
/**
|
|
16707
|
+
* Soft delete podkategorije (postavlja isActive na false)
|
|
16708
|
+
* @param categoryId - ID kategorije kojoj pripada podkategorija
|
|
16709
|
+
* @param subcategoryId - ID podkategorije koja se briše
|
|
16710
|
+
*/
|
|
16711
|
+
async delete(categoryId, subcategoryId) {
|
|
16712
|
+
await this.update(categoryId, subcategoryId, { isActive: false });
|
|
16713
|
+
}
|
|
16714
|
+
/**
|
|
16715
|
+
* Vraća podkategoriju po ID-u
|
|
16716
|
+
* @param categoryId - ID kategorije kojoj pripada podkategorija
|
|
16717
|
+
* @param subcategoryId - ID tražene podkategorije
|
|
16718
|
+
* @returns Podkategorija ili null ako ne postoji
|
|
16719
|
+
*/
|
|
16720
|
+
async getById(categoryId, subcategoryId) {
|
|
16721
|
+
const docRef = doc34(this.getSubcategoriesRef(categoryId), subcategoryId);
|
|
16722
|
+
const docSnap = await getDoc36(docRef);
|
|
16723
|
+
if (!docSnap.exists()) return null;
|
|
16724
|
+
return {
|
|
16725
|
+
id: docSnap.id,
|
|
16726
|
+
...docSnap.data()
|
|
16727
|
+
};
|
|
16728
|
+
}
|
|
16729
|
+
};
|
|
16730
|
+
|
|
16731
|
+
// src/backoffice/services/technology.service.ts
|
|
16732
|
+
import {
|
|
16733
|
+
addDoc as addDoc6,
|
|
16734
|
+
collection as collection34,
|
|
16735
|
+
doc as doc35,
|
|
16736
|
+
getDoc as getDoc37,
|
|
16737
|
+
getDocs as getDocs34,
|
|
16738
|
+
query as query34,
|
|
16739
|
+
updateDoc as updateDoc33,
|
|
16740
|
+
where as where34,
|
|
16741
|
+
arrayUnion as arrayUnion9,
|
|
16742
|
+
arrayRemove as arrayRemove8
|
|
16743
|
+
} from "firebase/firestore";
|
|
16744
|
+
var DEFAULT_CERTIFICATION_REQUIREMENT = {
|
|
16745
|
+
minimumLevel: "aesthetician" /* AESTHETICIAN */,
|
|
16746
|
+
requiredSpecialties: []
|
|
16747
|
+
};
|
|
16748
|
+
var TechnologyService = class extends BaseService {
|
|
16749
|
+
/**
|
|
16750
|
+
* Vraća referencu na Firestore kolekciju tehnologija
|
|
16751
|
+
*/
|
|
16752
|
+
getTechnologiesRef() {
|
|
16753
|
+
return collection34(this.db, TECHNOLOGIES_COLLECTION);
|
|
16754
|
+
}
|
|
16755
|
+
/**
|
|
16756
|
+
* Kreira novu tehnologiju
|
|
16757
|
+
* @param technology - Podaci za novu tehnologiju
|
|
16758
|
+
* @returns Kreirana tehnologija sa generisanim ID-em
|
|
16759
|
+
*/
|
|
16760
|
+
async create(technology) {
|
|
16761
|
+
const now = /* @__PURE__ */ new Date();
|
|
16762
|
+
const newTechnology = {
|
|
16763
|
+
...technology,
|
|
16764
|
+
createdAt: now,
|
|
16765
|
+
updatedAt: now,
|
|
16766
|
+
isActive: true,
|
|
16767
|
+
requirements: technology.requirements || {
|
|
16768
|
+
pre: [],
|
|
16769
|
+
post: []
|
|
16770
|
+
},
|
|
16771
|
+
blockingConditions: technology.blockingConditions || [],
|
|
16772
|
+
contraindications: technology.contraindications || [],
|
|
16773
|
+
benefits: technology.benefits || [],
|
|
16774
|
+
certificationRequirement: technology.certificationRequirement || DEFAULT_CERTIFICATION_REQUIREMENT
|
|
16775
|
+
};
|
|
16776
|
+
const docRef = await addDoc6(this.getTechnologiesRef(), newTechnology);
|
|
16777
|
+
return { id: docRef.id, ...newTechnology };
|
|
16778
|
+
}
|
|
16779
|
+
/**
|
|
16780
|
+
* Vraća sve aktivne tehnologije
|
|
16781
|
+
* @returns Lista aktivnih tehnologija
|
|
16782
|
+
*/
|
|
16783
|
+
async getAll() {
|
|
16784
|
+
const q = query34(this.getTechnologiesRef(), where34("isActive", "==", true));
|
|
16785
|
+
const snapshot = await getDocs34(q);
|
|
16786
|
+
return snapshot.docs.map(
|
|
16787
|
+
(doc37) => ({
|
|
16788
|
+
id: doc37.id,
|
|
16789
|
+
...doc37.data()
|
|
16790
|
+
})
|
|
16791
|
+
);
|
|
16792
|
+
}
|
|
16793
|
+
/**
|
|
16794
|
+
* Vraća sve aktivne tehnologije za određenu familiju
|
|
16795
|
+
* @param family - Familija procedura
|
|
16796
|
+
* @returns Lista aktivnih tehnologija
|
|
16797
|
+
*/
|
|
16798
|
+
async getAllByFamily(family) {
|
|
16799
|
+
const q = query34(
|
|
16800
|
+
this.getTechnologiesRef(),
|
|
16801
|
+
where34("isActive", "==", true),
|
|
16802
|
+
where34("family", "==", family)
|
|
16803
|
+
);
|
|
16804
|
+
const snapshot = await getDocs34(q);
|
|
16805
|
+
return snapshot.docs.map(
|
|
16806
|
+
(doc37) => ({
|
|
16807
|
+
id: doc37.id,
|
|
16808
|
+
...doc37.data()
|
|
16809
|
+
})
|
|
16810
|
+
);
|
|
16811
|
+
}
|
|
16812
|
+
/**
|
|
16813
|
+
* Vraća sve aktivne tehnologije za određenu kategoriju
|
|
16814
|
+
* @param categoryId - ID kategorije
|
|
16815
|
+
* @returns Lista aktivnih tehnologija
|
|
16816
|
+
*/
|
|
16817
|
+
async getAllByCategoryId(categoryId) {
|
|
16818
|
+
const q = query34(
|
|
16819
|
+
this.getTechnologiesRef(),
|
|
16820
|
+
where34("isActive", "==", true),
|
|
16821
|
+
where34("categoryId", "==", categoryId)
|
|
16822
|
+
);
|
|
16823
|
+
const snapshot = await getDocs34(q);
|
|
16824
|
+
return snapshot.docs.map(
|
|
16825
|
+
(doc37) => ({
|
|
16826
|
+
id: doc37.id,
|
|
16827
|
+
...doc37.data()
|
|
16828
|
+
})
|
|
16829
|
+
);
|
|
16830
|
+
}
|
|
16831
|
+
/**
|
|
16832
|
+
* Vraća sve aktivne tehnologije za određenu podkategoriju
|
|
16833
|
+
* @param subcategoryId - ID podkategorije
|
|
16834
|
+
* @returns Lista aktivnih tehnologija
|
|
16835
|
+
*/
|
|
16836
|
+
async getAllBySubcategoryId(subcategoryId) {
|
|
16837
|
+
const q = query34(
|
|
16838
|
+
this.getTechnologiesRef(),
|
|
16839
|
+
where34("isActive", "==", true),
|
|
16840
|
+
where34("subcategoryId", "==", subcategoryId)
|
|
16841
|
+
);
|
|
16842
|
+
const snapshot = await getDocs34(q);
|
|
16843
|
+
return snapshot.docs.map(
|
|
16844
|
+
(doc37) => ({
|
|
16845
|
+
id: doc37.id,
|
|
16846
|
+
...doc37.data()
|
|
16847
|
+
})
|
|
16848
|
+
);
|
|
16849
|
+
}
|
|
16850
|
+
/**
|
|
16851
|
+
* Ažurira postojeću tehnologiju
|
|
16852
|
+
* @param technologyId - ID tehnologije
|
|
16853
|
+
* @param technology - Novi podaci za tehnologiju
|
|
16854
|
+
* @returns Ažurirana tehnologija
|
|
16855
|
+
*/
|
|
16856
|
+
async update(technologyId, technology) {
|
|
16857
|
+
const updateData = {
|
|
16858
|
+
...technology,
|
|
16859
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
16860
|
+
};
|
|
16861
|
+
const docRef = doc35(this.getTechnologiesRef(), technologyId);
|
|
16862
|
+
await updateDoc33(docRef, updateData);
|
|
16863
|
+
return this.getById(technologyId);
|
|
16864
|
+
}
|
|
16865
|
+
/**
|
|
16866
|
+
* Soft delete tehnologije (postavlja isActive na false)
|
|
16867
|
+
* @param technologyId - ID tehnologije koja se briše
|
|
16868
|
+
*/
|
|
16869
|
+
async delete(technologyId) {
|
|
16870
|
+
await this.update(technologyId, {
|
|
16871
|
+
isActive: false
|
|
16872
|
+
});
|
|
16873
|
+
}
|
|
16874
|
+
/**
|
|
16875
|
+
* Vraća tehnologiju po ID-u
|
|
16876
|
+
* @param technologyId - ID tražene tehnologije
|
|
16877
|
+
* @returns Tehnologija ili null ako ne postoji
|
|
16878
|
+
*/
|
|
16879
|
+
async getById(technologyId) {
|
|
16880
|
+
const docRef = doc35(this.getTechnologiesRef(), technologyId);
|
|
16881
|
+
const docSnap = await getDoc37(docRef);
|
|
16882
|
+
if (!docSnap.exists()) return null;
|
|
16883
|
+
return {
|
|
16884
|
+
id: docSnap.id,
|
|
16885
|
+
...docSnap.data()
|
|
16886
|
+
};
|
|
16887
|
+
}
|
|
16888
|
+
/**
|
|
16889
|
+
* Dodaje novi zahtev tehnologiji
|
|
16890
|
+
* @param technologyId - ID tehnologije
|
|
16891
|
+
* @param requirement - Zahtev koji se dodaje
|
|
16892
|
+
* @returns Ažurirana tehnologija sa novim zahtevom
|
|
16893
|
+
*/
|
|
16894
|
+
async addRequirement(technologyId, requirement) {
|
|
16895
|
+
const docRef = doc35(this.getTechnologiesRef(), technologyId);
|
|
16896
|
+
const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
|
|
16897
|
+
await updateDoc33(docRef, {
|
|
16898
|
+
[requirementType]: arrayUnion9(requirement),
|
|
16899
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
16900
|
+
});
|
|
16901
|
+
return this.getById(technologyId);
|
|
16902
|
+
}
|
|
16903
|
+
/**
|
|
16904
|
+
* Uklanja zahtev iz tehnologije
|
|
16905
|
+
* @param technologyId - ID tehnologije
|
|
16906
|
+
* @param requirement - Zahtev koji se uklanja
|
|
16907
|
+
* @returns Ažurirana tehnologija bez uklonjenog zahteva
|
|
16908
|
+
*/
|
|
16909
|
+
async removeRequirement(technologyId, requirement) {
|
|
16910
|
+
const docRef = doc35(this.getTechnologiesRef(), technologyId);
|
|
16911
|
+
const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
|
|
16912
|
+
await updateDoc33(docRef, {
|
|
16913
|
+
[requirementType]: arrayRemove8(requirement),
|
|
16914
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
16915
|
+
});
|
|
16916
|
+
return this.getById(technologyId);
|
|
16917
|
+
}
|
|
16918
|
+
/**
|
|
16919
|
+
* Vraća sve zahteve za tehnologiju
|
|
16920
|
+
* @param technologyId - ID tehnologije
|
|
16921
|
+
* @param type - Opcioni filter za tip zahteva (pre/post)
|
|
16922
|
+
* @returns Lista zahteva
|
|
16923
|
+
*/
|
|
16924
|
+
async getRequirements(technologyId, type) {
|
|
16925
|
+
const technology = await this.getById(technologyId);
|
|
16926
|
+
if (!technology || !technology.requirements) return [];
|
|
16927
|
+
if (type) {
|
|
16928
|
+
return technology.requirements[type];
|
|
16929
|
+
}
|
|
16930
|
+
return [...technology.requirements.pre, ...technology.requirements.post];
|
|
16931
|
+
}
|
|
16932
|
+
/**
|
|
16933
|
+
* Ažurira postojeći zahtev
|
|
16934
|
+
* @param technologyId - ID tehnologije
|
|
16935
|
+
* @param oldRequirement - Stari zahtev koji se menja
|
|
16936
|
+
* @param newRequirement - Novi zahtev koji zamenjuje stari
|
|
16937
|
+
* @returns Ažurirana tehnologija
|
|
16938
|
+
*/
|
|
16939
|
+
async updateRequirement(technologyId, oldRequirement, newRequirement) {
|
|
16940
|
+
await this.removeRequirement(technologyId, oldRequirement);
|
|
16941
|
+
return this.addRequirement(technologyId, newRequirement);
|
|
16942
|
+
}
|
|
16943
|
+
/**
|
|
16944
|
+
* Dodaje blokirajući uslov tehnologiji
|
|
16945
|
+
* @param technologyId - ID tehnologije
|
|
16946
|
+
* @param condition - Blokirajući uslov koji se dodaje
|
|
16947
|
+
* @returns Ažurirana tehnologija
|
|
16948
|
+
*/
|
|
16949
|
+
async addBlockingCondition(technologyId, condition) {
|
|
16950
|
+
const docRef = doc35(this.getTechnologiesRef(), technologyId);
|
|
16951
|
+
await updateDoc33(docRef, {
|
|
16952
|
+
blockingConditions: arrayUnion9(condition),
|
|
16953
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
16954
|
+
});
|
|
16955
|
+
return this.getById(technologyId);
|
|
16956
|
+
}
|
|
16957
|
+
/**
|
|
16958
|
+
* Uklanja blokirajući uslov iz tehnologije
|
|
16959
|
+
* @param technologyId - ID tehnologije
|
|
16960
|
+
* @param condition - Blokirajući uslov koji se uklanja
|
|
16961
|
+
* @returns Ažurirana tehnologija
|
|
16962
|
+
*/
|
|
16963
|
+
async removeBlockingCondition(technologyId, condition) {
|
|
16964
|
+
const docRef = doc35(this.getTechnologiesRef(), technologyId);
|
|
16965
|
+
await updateDoc33(docRef, {
|
|
16966
|
+
blockingConditions: arrayRemove8(condition),
|
|
16967
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
16968
|
+
});
|
|
16969
|
+
return this.getById(technologyId);
|
|
16970
|
+
}
|
|
16971
|
+
/**
|
|
16972
|
+
* Dodaje kontraindikaciju tehnologiji
|
|
16973
|
+
* @param technologyId - ID tehnologije
|
|
16974
|
+
* @param contraindication - Kontraindikacija koja se dodaje
|
|
16975
|
+
* @returns Ažurirana tehnologija
|
|
16976
|
+
*/
|
|
16977
|
+
async addContraindication(technologyId, contraindication) {
|
|
16978
|
+
const docRef = doc35(this.getTechnologiesRef(), technologyId);
|
|
16979
|
+
await updateDoc33(docRef, {
|
|
16980
|
+
contraindications: arrayUnion9(contraindication),
|
|
16981
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
16982
|
+
});
|
|
16983
|
+
return this.getById(technologyId);
|
|
16984
|
+
}
|
|
16985
|
+
/**
|
|
16986
|
+
* Uklanja kontraindikaciju iz tehnologije
|
|
16987
|
+
* @param technologyId - ID tehnologije
|
|
16988
|
+
* @param contraindication - Kontraindikacija koja se uklanja
|
|
16989
|
+
* @returns Ažurirana tehnologija
|
|
16990
|
+
*/
|
|
16991
|
+
async removeContraindication(technologyId, contraindication) {
|
|
16992
|
+
const docRef = doc35(this.getTechnologiesRef(), technologyId);
|
|
16993
|
+
await updateDoc33(docRef, {
|
|
16994
|
+
contraindications: arrayRemove8(contraindication),
|
|
16995
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
16996
|
+
});
|
|
16997
|
+
return this.getById(technologyId);
|
|
16998
|
+
}
|
|
16999
|
+
/**
|
|
17000
|
+
* Dodaje benefit tehnologiji
|
|
17001
|
+
* @param technologyId - ID tehnologije
|
|
17002
|
+
* @param benefit - Benefit koji se dodaje
|
|
17003
|
+
* @returns Ažurirana tehnologija
|
|
17004
|
+
*/
|
|
17005
|
+
async addBenefit(technologyId, benefit) {
|
|
17006
|
+
const docRef = doc35(this.getTechnologiesRef(), technologyId);
|
|
17007
|
+
await updateDoc33(docRef, {
|
|
17008
|
+
benefits: arrayUnion9(benefit),
|
|
17009
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
17010
|
+
});
|
|
17011
|
+
return this.getById(technologyId);
|
|
17012
|
+
}
|
|
17013
|
+
/**
|
|
17014
|
+
* Uklanja benefit iz tehnologije
|
|
17015
|
+
* @param technologyId - ID tehnologije
|
|
17016
|
+
* @param benefit - Benefit koji se uklanja
|
|
17017
|
+
* @returns Ažurirana tehnologija
|
|
17018
|
+
*/
|
|
17019
|
+
async removeBenefit(technologyId, benefit) {
|
|
17020
|
+
const docRef = doc35(this.getTechnologiesRef(), technologyId);
|
|
17021
|
+
await updateDoc33(docRef, {
|
|
17022
|
+
benefits: arrayRemove8(benefit),
|
|
17023
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
17024
|
+
});
|
|
17025
|
+
return this.getById(technologyId);
|
|
17026
|
+
}
|
|
17027
|
+
/**
|
|
17028
|
+
* Vraća sve blokirajuće uslove za tehnologiju
|
|
17029
|
+
* @param technologyId - ID tehnologije
|
|
17030
|
+
* @returns Lista blokirajućih uslova
|
|
17031
|
+
*/
|
|
17032
|
+
async getBlockingConditions(technologyId) {
|
|
17033
|
+
const technology = await this.getById(technologyId);
|
|
17034
|
+
return (technology == null ? void 0 : technology.blockingConditions) || [];
|
|
17035
|
+
}
|
|
17036
|
+
/**
|
|
17037
|
+
* Vraća sve kontraindikacije za tehnologiju
|
|
17038
|
+
* @param technologyId - ID tehnologije
|
|
17039
|
+
* @returns Lista kontraindikacija
|
|
17040
|
+
*/
|
|
17041
|
+
async getContraindications(technologyId) {
|
|
17042
|
+
const technology = await this.getById(technologyId);
|
|
17043
|
+
return (technology == null ? void 0 : technology.contraindications) || [];
|
|
17044
|
+
}
|
|
17045
|
+
/**
|
|
17046
|
+
* Vraća sve benefite za tehnologiju
|
|
17047
|
+
* @param technologyId - ID tehnologije
|
|
17048
|
+
* @returns Lista benefita
|
|
17049
|
+
*/
|
|
17050
|
+
async getBenefits(technologyId) {
|
|
17051
|
+
const technology = await this.getById(technologyId);
|
|
17052
|
+
return (technology == null ? void 0 : technology.benefits) || [];
|
|
17053
|
+
}
|
|
17054
|
+
/**
|
|
17055
|
+
* Ažurira zahteve sertifikacije za tehnologiju
|
|
17056
|
+
* @param technologyId - ID tehnologije
|
|
17057
|
+
* @param certificationRequirement - Novi zahtevi sertifikacije
|
|
17058
|
+
* @returns Ažurirana tehnologija
|
|
17059
|
+
*/
|
|
17060
|
+
async updateCertificationRequirement(technologyId, certificationRequirement) {
|
|
17061
|
+
const docRef = doc35(this.getTechnologiesRef(), technologyId);
|
|
17062
|
+
await updateDoc33(docRef, {
|
|
17063
|
+
certificationRequirement,
|
|
17064
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
17065
|
+
});
|
|
17066
|
+
return this.getById(technologyId);
|
|
17067
|
+
}
|
|
17068
|
+
/**
|
|
17069
|
+
* Vraća zahteve sertifikacije za tehnologiju
|
|
17070
|
+
* @param technologyId - ID tehnologije
|
|
17071
|
+
* @returns Zahtevi sertifikacije ili null ako tehnologija ne postoji
|
|
17072
|
+
*/
|
|
17073
|
+
async getCertificationRequirement(technologyId) {
|
|
17074
|
+
const technology = await this.getById(technologyId);
|
|
17075
|
+
return (technology == null ? void 0 : technology.certificationRequirement) || null;
|
|
17076
|
+
}
|
|
17077
|
+
/**
|
|
17078
|
+
* Proverava da li doktor ima odgovarajuću sertifikaciju za izvođenje tehnologije
|
|
17079
|
+
*
|
|
17080
|
+
* @param requiredCertification - Zahtevana sertifikacija za tehnologiju
|
|
17081
|
+
* @param practitionerCertification - Sertifikacija zdravstvenog radnika
|
|
17082
|
+
* @returns true ako zdravstveni radnik ima odgovarajuću sertifikaciju, false ako nema
|
|
17083
|
+
*
|
|
17084
|
+
* @example
|
|
17085
|
+
* const isValid = technologyService.validateCertification(
|
|
17086
|
+
* {
|
|
17087
|
+
* minimumLevel: CertificationLevel.DOCTOR,
|
|
17088
|
+
* requiredSpecialties: [CertificationSpecialty.INJECTABLES]
|
|
17089
|
+
* },
|
|
17090
|
+
* {
|
|
17091
|
+
* level: CertificationLevel.SPECIALIST,
|
|
17092
|
+
* specialties: [CertificationSpecialty.INJECTABLES, CertificationSpecialty.LASER]
|
|
17093
|
+
* }
|
|
17094
|
+
* );
|
|
17095
|
+
*/
|
|
17096
|
+
validateCertification(requiredCertification, practitionerCertification) {
|
|
17097
|
+
const doctorLevel = Object.values(CertificationLevel).indexOf(
|
|
17098
|
+
practitionerCertification.level
|
|
17099
|
+
);
|
|
17100
|
+
const requiredLevel = Object.values(CertificationLevel).indexOf(
|
|
17101
|
+
requiredCertification.minimumLevel
|
|
17102
|
+
);
|
|
17103
|
+
if (doctorLevel < requiredLevel) return false;
|
|
17104
|
+
const requiredSpecialties = requiredCertification.requiredSpecialties || [];
|
|
17105
|
+
if (requiredSpecialties.length > 0) {
|
|
17106
|
+
const doctorSpecialties = practitionerCertification.specialties;
|
|
17107
|
+
const hasAllRequiredSpecialties = requiredSpecialties.every(
|
|
17108
|
+
(requiredSpecialty) => doctorSpecialties.includes(requiredSpecialty)
|
|
17109
|
+
);
|
|
17110
|
+
if (!hasAllRequiredSpecialties) return false;
|
|
17111
|
+
}
|
|
17112
|
+
return true;
|
|
17113
|
+
}
|
|
17114
|
+
/**
|
|
17115
|
+
* Vraća sve tehnologije koje je zdravstveni radnik sertifikovan da izvodi
|
|
17116
|
+
* zajedno sa listama dozvoljenih familija, kategorija i podkategorija
|
|
17117
|
+
*
|
|
17118
|
+
* @param practitioner - Profil zdravstvenog radnika
|
|
17119
|
+
* @returns Objekat koji sadrži:
|
|
17120
|
+
* - technologies: Lista tehnologija koje zdravstveni radnik može da izvodi
|
|
17121
|
+
* - families: Lista familija procedura koje zdravstveni radnik može da izvodi
|
|
17122
|
+
* - categories: Lista ID-eva kategorija koje zdravstveni radnik može da izvodi
|
|
17123
|
+
* - subcategories: Lista ID-eva podkategorija koje zdravstveni radnik može da izvodi
|
|
17124
|
+
*
|
|
17125
|
+
* @example
|
|
17126
|
+
* const practitioner = {
|
|
17127
|
+
* certification: {
|
|
17128
|
+
* level: CertificationLevel.DOCTOR,
|
|
17129
|
+
* specialties: [CertificationSpecialty.INJECTABLES]
|
|
17130
|
+
* }
|
|
17131
|
+
* };
|
|
17132
|
+
* const allowedTechnologies = await technologyService.getAllowedTechnologies(practitioner);
|
|
17133
|
+
* console.log(allowedTechnologies.families); // [ProcedureFamily.AESTHETICS]
|
|
17134
|
+
* console.log(allowedTechnologies.categories); // ["category1", "category2"]
|
|
17135
|
+
* console.log(allowedTechnologies.subcategories); // ["subcategory1", "subcategory2"]
|
|
17136
|
+
*/
|
|
17137
|
+
async getAllowedTechnologies(practitioner) {
|
|
17138
|
+
const allTechnologies = await this.getAll();
|
|
17139
|
+
const allowedTechnologies = allTechnologies.filter(
|
|
17140
|
+
(technology) => this.validateCertification(
|
|
17141
|
+
technology.certificationRequirement,
|
|
17142
|
+
practitioner.certification
|
|
17143
|
+
)
|
|
17144
|
+
);
|
|
17145
|
+
const families = [...new Set(allowedTechnologies.map((t) => t.family))];
|
|
17146
|
+
const categories = [
|
|
17147
|
+
...new Set(allowedTechnologies.map((t) => t.categoryId))
|
|
17148
|
+
];
|
|
17149
|
+
const subcategories = [
|
|
17150
|
+
...new Set(allowedTechnologies.map((t) => t.subcategoryId))
|
|
17151
|
+
];
|
|
17152
|
+
return {
|
|
17153
|
+
technologies: allowedTechnologies,
|
|
17154
|
+
families,
|
|
17155
|
+
categories,
|
|
17156
|
+
subcategories
|
|
17157
|
+
};
|
|
17158
|
+
}
|
|
17159
|
+
};
|
|
17160
|
+
|
|
17161
|
+
// src/backoffice/services/product.service.ts
|
|
17162
|
+
import {
|
|
17163
|
+
addDoc as addDoc7,
|
|
17164
|
+
collection as collection35,
|
|
17165
|
+
doc as doc36,
|
|
17166
|
+
getDoc as getDoc38,
|
|
17167
|
+
getDocs as getDocs35,
|
|
17168
|
+
query as query35,
|
|
17169
|
+
updateDoc as updateDoc34,
|
|
17170
|
+
where as where35
|
|
17171
|
+
} from "firebase/firestore";
|
|
17172
|
+
|
|
17173
|
+
// src/backoffice/types/product.types.ts
|
|
17174
|
+
var PRODUCTS_COLLECTION = "products";
|
|
17175
|
+
|
|
17176
|
+
// src/backoffice/services/product.service.ts
|
|
17177
|
+
var ProductService = class extends BaseService {
|
|
17178
|
+
/**
|
|
17179
|
+
* Gets reference to products collection under a technology
|
|
17180
|
+
* @param technologyId - ID of the technology
|
|
17181
|
+
* @returns Firestore collection reference
|
|
17182
|
+
*/
|
|
17183
|
+
getProductsRef(technologyId) {
|
|
17184
|
+
return collection35(
|
|
17185
|
+
this.db,
|
|
17186
|
+
TECHNOLOGIES_COLLECTION,
|
|
17187
|
+
technologyId,
|
|
17188
|
+
PRODUCTS_COLLECTION
|
|
17189
|
+
);
|
|
17190
|
+
}
|
|
17191
|
+
/**
|
|
17192
|
+
* Creates a new product under technology
|
|
17193
|
+
*/
|
|
17194
|
+
async create(technologyId, brandId, product) {
|
|
17195
|
+
const now = /* @__PURE__ */ new Date();
|
|
17196
|
+
const newProduct = {
|
|
17197
|
+
...product,
|
|
17198
|
+
brandId,
|
|
17199
|
+
technologyId,
|
|
17200
|
+
createdAt: now,
|
|
17201
|
+
updatedAt: now,
|
|
17202
|
+
isActive: true
|
|
17203
|
+
};
|
|
17204
|
+
const productRef = await addDoc7(
|
|
17205
|
+
this.getProductsRef(technologyId),
|
|
17206
|
+
newProduct
|
|
17207
|
+
);
|
|
17208
|
+
return { id: productRef.id, ...newProduct };
|
|
17209
|
+
}
|
|
17210
|
+
/**
|
|
17211
|
+
* Gets all products for a technology
|
|
17212
|
+
*/
|
|
17213
|
+
async getAllByTechnology(technologyId) {
|
|
17214
|
+
const q = query35(
|
|
17215
|
+
this.getProductsRef(technologyId),
|
|
17216
|
+
where35("isActive", "==", true)
|
|
17217
|
+
);
|
|
17218
|
+
const snapshot = await getDocs35(q);
|
|
17219
|
+
return snapshot.docs.map(
|
|
17220
|
+
(doc37) => ({
|
|
17221
|
+
id: doc37.id,
|
|
17222
|
+
...doc37.data()
|
|
17223
|
+
})
|
|
17224
|
+
);
|
|
17225
|
+
}
|
|
17226
|
+
/**
|
|
17227
|
+
* Gets all products for a brand by filtering through all technologies
|
|
17228
|
+
*/
|
|
17229
|
+
async getAllByBrand(brandId) {
|
|
17230
|
+
const allTechnologiesRef = collection35(this.db, TECHNOLOGIES_COLLECTION);
|
|
17231
|
+
const technologiesSnapshot = await getDocs35(allTechnologiesRef);
|
|
17232
|
+
const products = [];
|
|
17233
|
+
for (const techDoc of technologiesSnapshot.docs) {
|
|
17234
|
+
const q = query35(
|
|
17235
|
+
this.getProductsRef(techDoc.id),
|
|
17236
|
+
where35("brandId", "==", brandId),
|
|
17237
|
+
where35("isActive", "==", true)
|
|
17238
|
+
);
|
|
17239
|
+
const snapshot = await getDocs35(q);
|
|
17240
|
+
products.push(
|
|
17241
|
+
...snapshot.docs.map(
|
|
17242
|
+
(doc37) => ({
|
|
17243
|
+
id: doc37.id,
|
|
17244
|
+
...doc37.data()
|
|
17245
|
+
})
|
|
17246
|
+
)
|
|
17247
|
+
);
|
|
17248
|
+
}
|
|
17249
|
+
return products;
|
|
17250
|
+
}
|
|
17251
|
+
/**
|
|
17252
|
+
* Updates a product
|
|
17253
|
+
*/
|
|
17254
|
+
async update(technologyId, productId, product) {
|
|
17255
|
+
const updateData = {
|
|
17256
|
+
...product,
|
|
17257
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
17258
|
+
};
|
|
17259
|
+
const docRef = doc36(this.getProductsRef(technologyId), productId);
|
|
17260
|
+
await updateDoc34(docRef, updateData);
|
|
17261
|
+
return this.getById(technologyId, productId);
|
|
17262
|
+
}
|
|
17263
|
+
/**
|
|
17264
|
+
* Soft deletes a product
|
|
17265
|
+
*/
|
|
17266
|
+
async delete(technologyId, productId) {
|
|
17267
|
+
await this.update(technologyId, productId, {
|
|
17268
|
+
isActive: false
|
|
17269
|
+
});
|
|
17270
|
+
}
|
|
17271
|
+
/**
|
|
17272
|
+
* Gets a product by ID
|
|
17273
|
+
*/
|
|
17274
|
+
async getById(technologyId, productId) {
|
|
17275
|
+
const docRef = doc36(this.getProductsRef(technologyId), productId);
|
|
17276
|
+
const docSnap = await getDoc38(docRef);
|
|
17277
|
+
if (!docSnap.exists()) return null;
|
|
17278
|
+
return {
|
|
17279
|
+
id: docSnap.id,
|
|
17280
|
+
...docSnap.data()
|
|
17281
|
+
};
|
|
17282
|
+
}
|
|
17283
|
+
};
|
|
16424
17284
|
export {
|
|
16425
17285
|
APPOINTMENTS_COLLECTION,
|
|
16426
17286
|
AdminTokenStatus,
|
|
@@ -16429,6 +17289,8 @@ export {
|
|
|
16429
17289
|
AppointmentStatus,
|
|
16430
17290
|
AuthService,
|
|
16431
17291
|
BaseService,
|
|
17292
|
+
BlockingCondition,
|
|
17293
|
+
BrandService,
|
|
16432
17294
|
CALENDAR_COLLECTION,
|
|
16433
17295
|
CLINICS_COLLECTION,
|
|
16434
17296
|
CLINIC_ADMINS_COLLECTION,
|
|
@@ -16438,12 +17300,17 @@ export {
|
|
|
16438
17300
|
CalendarServiceV2,
|
|
16439
17301
|
CalendarServiceV3,
|
|
16440
17302
|
CalendarSyncStatus,
|
|
17303
|
+
CategoryService,
|
|
17304
|
+
CertificationLevel,
|
|
17305
|
+
CertificationSpecialty,
|
|
16441
17306
|
ClinicAdminService,
|
|
16442
17307
|
ClinicGroupService,
|
|
16443
17308
|
ClinicPhotoTag,
|
|
16444
17309
|
ClinicService,
|
|
16445
17310
|
ClinicTag,
|
|
17311
|
+
Contraindication,
|
|
16446
17312
|
CosmeticAllergySubtype,
|
|
17313
|
+
Currency,
|
|
16447
17314
|
DEFAULT_MEDICAL_INFO,
|
|
16448
17315
|
DOCTOR_FORMS_SUBCOLLECTION,
|
|
16449
17316
|
DOCUMENTATION_TEMPLATES_COLLECTION,
|
|
@@ -16492,15 +17359,23 @@ export {
|
|
|
16492
17359
|
PractitionerService,
|
|
16493
17360
|
PractitionerStatus,
|
|
16494
17361
|
PractitionerTokenStatus,
|
|
17362
|
+
PricingMeasure,
|
|
17363
|
+
ProcedureFamily,
|
|
16495
17364
|
ProcedureService,
|
|
17365
|
+
ProductService,
|
|
16496
17366
|
REGISTER_TOKENS_COLLECTION,
|
|
16497
17367
|
REVIEWS_COLLECTION,
|
|
17368
|
+
RequirementType,
|
|
16498
17369
|
ReviewService,
|
|
16499
17370
|
SYNCED_CALENDARS_COLLECTION,
|
|
16500
17371
|
SearchLocationEnum,
|
|
17372
|
+
SubcategoryService,
|
|
16501
17373
|
SubscriptionModel,
|
|
16502
17374
|
SyncedCalendarProvider,
|
|
17375
|
+
TechnologyService,
|
|
17376
|
+
TimeUnit,
|
|
16503
17377
|
TimestampUtils,
|
|
17378
|
+
TreatmentBenefit,
|
|
16504
17379
|
USERS_COLLECTION,
|
|
16505
17380
|
USER_FORMS_SUBCOLLECTION,
|
|
16506
17381
|
UserRole,
|