@blackcode_sa/metaestetics-api 1.5.31 → 1.5.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/index.d.mts +337 -1
- package/dist/admin/index.d.ts +337 -1
- package/dist/admin/index.js +597 -14
- package/dist/admin/index.mjs +595 -14
- package/dist/backoffice/index.d.mts +2 -0
- package/dist/backoffice/index.d.ts +2 -0
- package/dist/index.d.mts +102 -1
- package/dist/index.d.ts +102 -1
- package/dist/index.js +945 -267
- package/dist/index.mjs +968 -283
- package/package.json +1 -1
- package/src/admin/booking/booking.admin.ts +234 -0
- package/src/admin/booking/booking.calculator.ts +686 -0
- package/src/admin/booking/booking.types.ts +56 -0
- package/src/admin/booking/index.ts +3 -0
- package/src/admin/index.ts +3 -0
- package/src/index.ts +5 -0
- package/src/services/appointment/appointment.service.ts +603 -0
- package/src/services/appointment/index.ts +2 -0
- package/src/services/appointment/utils/appointment.utils.ts +590 -0
- package/src/services/clinic/clinic.service.ts +6 -0
- package/src/services/clinic/utils/filter.utils.ts +27 -1
- package/src/services/procedure/procedure.service.ts +43 -5
- package/src/types/appointment/index.ts +161 -0
- package/src/types/procedure/index.ts +2 -0
- package/src/validations/appointment.schema.ts +125 -0
package/dist/index.js
CHANGED
|
@@ -92,6 +92,8 @@ __export(index_exports, {
|
|
|
92
92
|
ProductService: () => ProductService,
|
|
93
93
|
REGISTER_TOKENS_COLLECTION: () => REGISTER_TOKENS_COLLECTION,
|
|
94
94
|
REVIEWS_COLLECTION: () => REVIEWS_COLLECTION,
|
|
95
|
+
RequirementType: () => RequirementType,
|
|
96
|
+
ReviewService: () => ReviewService,
|
|
95
97
|
SYNCED_CALENDARS_COLLECTION: () => SYNCED_CALENDARS_COLLECTION,
|
|
96
98
|
SearchLocationEnum: () => SearchLocationEnum,
|
|
97
99
|
SubcategoryService: () => SubcategoryService,
|
|
@@ -99,6 +101,7 @@ __export(index_exports, {
|
|
|
99
101
|
SyncedCalendarProvider: () => SyncedCalendarProvider,
|
|
100
102
|
SyncedCalendarsService: () => SyncedCalendarsService,
|
|
101
103
|
TechnologyService: () => TechnologyService,
|
|
104
|
+
TimeUnit: () => TimeUnit,
|
|
102
105
|
TreatmentBenefit: () => TreatmentBenefit,
|
|
103
106
|
USER_ERRORS: () => USER_ERRORS,
|
|
104
107
|
UserService: () => UserService,
|
|
@@ -1498,9 +1501,9 @@ var addAllergyUtil = async (db, patientId, data, userRef) => {
|
|
|
1498
1501
|
var updateAllergyUtil = async (db, patientId, data, userRef) => {
|
|
1499
1502
|
const validatedData = updateAllergySchema.parse(data);
|
|
1500
1503
|
const { allergyIndex, ...updateData } = validatedData;
|
|
1501
|
-
const
|
|
1502
|
-
if (!
|
|
1503
|
-
const medicalInfo =
|
|
1504
|
+
const doc29 = await (0, import_firestore5.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
1505
|
+
if (!doc29.exists()) throw new Error("Medical info not found");
|
|
1506
|
+
const medicalInfo = doc29.data();
|
|
1504
1507
|
if (allergyIndex >= medicalInfo.allergies.length) {
|
|
1505
1508
|
throw new Error("Invalid allergy index");
|
|
1506
1509
|
}
|
|
@@ -1516,9 +1519,9 @@ var updateAllergyUtil = async (db, patientId, data, userRef) => {
|
|
|
1516
1519
|
});
|
|
1517
1520
|
};
|
|
1518
1521
|
var removeAllergyUtil = async (db, patientId, allergyIndex, userRef) => {
|
|
1519
|
-
const
|
|
1520
|
-
if (!
|
|
1521
|
-
const medicalInfo =
|
|
1522
|
+
const doc29 = await (0, import_firestore5.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
1523
|
+
if (!doc29.exists()) throw new Error("Medical info not found");
|
|
1524
|
+
const medicalInfo = doc29.data();
|
|
1522
1525
|
if (allergyIndex >= medicalInfo.allergies.length) {
|
|
1523
1526
|
throw new Error("Invalid allergy index");
|
|
1524
1527
|
}
|
|
@@ -1543,9 +1546,9 @@ var addBlockingConditionUtil = async (db, patientId, data, userRef) => {
|
|
|
1543
1546
|
var updateBlockingConditionUtil = async (db, patientId, data, userRef) => {
|
|
1544
1547
|
const validatedData = updateBlockingConditionSchema.parse(data);
|
|
1545
1548
|
const { conditionIndex, ...updateData } = validatedData;
|
|
1546
|
-
const
|
|
1547
|
-
if (!
|
|
1548
|
-
const medicalInfo =
|
|
1549
|
+
const doc29 = await (0, import_firestore5.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
1550
|
+
if (!doc29.exists()) throw new Error("Medical info not found");
|
|
1551
|
+
const medicalInfo = doc29.data();
|
|
1549
1552
|
if (conditionIndex >= medicalInfo.blockingConditions.length) {
|
|
1550
1553
|
throw new Error("Invalid blocking condition index");
|
|
1551
1554
|
}
|
|
@@ -1561,9 +1564,9 @@ var updateBlockingConditionUtil = async (db, patientId, data, userRef) => {
|
|
|
1561
1564
|
});
|
|
1562
1565
|
};
|
|
1563
1566
|
var removeBlockingConditionUtil = async (db, patientId, conditionIndex, userRef) => {
|
|
1564
|
-
const
|
|
1565
|
-
if (!
|
|
1566
|
-
const medicalInfo =
|
|
1567
|
+
const doc29 = await (0, import_firestore5.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
1568
|
+
if (!doc29.exists()) throw new Error("Medical info not found");
|
|
1569
|
+
const medicalInfo = doc29.data();
|
|
1567
1570
|
if (conditionIndex >= medicalInfo.blockingConditions.length) {
|
|
1568
1571
|
throw new Error("Invalid blocking condition index");
|
|
1569
1572
|
}
|
|
@@ -1588,9 +1591,9 @@ var addContraindicationUtil = async (db, patientId, data, userRef) => {
|
|
|
1588
1591
|
var updateContraindicationUtil = async (db, patientId, data, userRef) => {
|
|
1589
1592
|
const validatedData = updateContraindicationSchema.parse(data);
|
|
1590
1593
|
const { contraindicationIndex, ...updateData } = validatedData;
|
|
1591
|
-
const
|
|
1592
|
-
if (!
|
|
1593
|
-
const medicalInfo =
|
|
1594
|
+
const doc29 = await (0, import_firestore5.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
1595
|
+
if (!doc29.exists()) throw new Error("Medical info not found");
|
|
1596
|
+
const medicalInfo = doc29.data();
|
|
1594
1597
|
if (contraindicationIndex >= medicalInfo.contraindications.length) {
|
|
1595
1598
|
throw new Error("Invalid contraindication index");
|
|
1596
1599
|
}
|
|
@@ -1606,9 +1609,9 @@ var updateContraindicationUtil = async (db, patientId, data, userRef) => {
|
|
|
1606
1609
|
});
|
|
1607
1610
|
};
|
|
1608
1611
|
var removeContraindicationUtil = async (db, patientId, contraindicationIndex, userRef) => {
|
|
1609
|
-
const
|
|
1610
|
-
if (!
|
|
1611
|
-
const medicalInfo =
|
|
1612
|
+
const doc29 = await (0, import_firestore5.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
1613
|
+
if (!doc29.exists()) throw new Error("Medical info not found");
|
|
1614
|
+
const medicalInfo = doc29.data();
|
|
1612
1615
|
if (contraindicationIndex >= medicalInfo.contraindications.length) {
|
|
1613
1616
|
throw new Error("Invalid contraindication index");
|
|
1614
1617
|
}
|
|
@@ -1633,9 +1636,9 @@ var addMedicationUtil = async (db, patientId, data, userRef) => {
|
|
|
1633
1636
|
var updateMedicationUtil = async (db, patientId, data, userRef) => {
|
|
1634
1637
|
const validatedData = updateMedicationSchema.parse(data);
|
|
1635
1638
|
const { medicationIndex, ...updateData } = validatedData;
|
|
1636
|
-
const
|
|
1637
|
-
if (!
|
|
1638
|
-
const medicalInfo =
|
|
1639
|
+
const doc29 = await (0, import_firestore5.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
1640
|
+
if (!doc29.exists()) throw new Error("Medical info not found");
|
|
1641
|
+
const medicalInfo = doc29.data();
|
|
1639
1642
|
if (medicationIndex >= medicalInfo.currentMedications.length) {
|
|
1640
1643
|
throw new Error("Invalid medication index");
|
|
1641
1644
|
}
|
|
@@ -1651,9 +1654,9 @@ var updateMedicationUtil = async (db, patientId, data, userRef) => {
|
|
|
1651
1654
|
});
|
|
1652
1655
|
};
|
|
1653
1656
|
var removeMedicationUtil = async (db, patientId, medicationIndex, userRef) => {
|
|
1654
|
-
const
|
|
1655
|
-
if (!
|
|
1656
|
-
const medicalInfo =
|
|
1657
|
+
const doc29 = await (0, import_firestore5.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
1658
|
+
if (!doc29.exists()) throw new Error("Medical info not found");
|
|
1659
|
+
const medicalInfo = doc29.data();
|
|
1657
1660
|
if (medicationIndex >= medicalInfo.currentMedications.length) {
|
|
1658
1661
|
throw new Error("Invalid medication index");
|
|
1659
1662
|
}
|
|
@@ -1931,7 +1934,7 @@ var searchPatientsUtil = async (db, params, requester) => {
|
|
|
1931
1934
|
try {
|
|
1932
1935
|
const finalQuery = (0, import_firestore6.query)(patientsCollectionRef, ...constraints);
|
|
1933
1936
|
const querySnapshot = await (0, import_firestore6.getDocs)(finalQuery);
|
|
1934
|
-
const patients = querySnapshot.docs.map((
|
|
1937
|
+
const patients = querySnapshot.docs.map((doc29) => doc29.data());
|
|
1935
1938
|
console.log(`[searchPatientsUtil] Found ${patients.length} patients matching criteria.`);
|
|
1936
1939
|
return patients;
|
|
1937
1940
|
} catch (error) {
|
|
@@ -1955,8 +1958,8 @@ var getAllPatientsUtil = async (db, options) => {
|
|
|
1955
1958
|
}
|
|
1956
1959
|
const patientsSnapshot = await (0, import_firestore6.getDocs)(q);
|
|
1957
1960
|
const patients = [];
|
|
1958
|
-
patientsSnapshot.forEach((
|
|
1959
|
-
patients.push(
|
|
1961
|
+
patientsSnapshot.forEach((doc29) => {
|
|
1962
|
+
patients.push(doc29.data());
|
|
1960
1963
|
});
|
|
1961
1964
|
console.log(`[getAllPatientsUtil] Found ${patients.length} patients`);
|
|
1962
1965
|
return patients;
|
|
@@ -3290,7 +3293,7 @@ async function getClinicAdminsByGroup(db, clinicGroupId) {
|
|
|
3290
3293
|
(0, import_firestore12.where)("clinicGroupId", "==", clinicGroupId)
|
|
3291
3294
|
);
|
|
3292
3295
|
const querySnapshot = await (0, import_firestore12.getDocs)(q);
|
|
3293
|
-
return querySnapshot.docs.map((
|
|
3296
|
+
return querySnapshot.docs.map((doc29) => doc29.data());
|
|
3294
3297
|
}
|
|
3295
3298
|
async function updateClinicAdmin(db, adminId, data) {
|
|
3296
3299
|
const admin = await getClinicAdmin(db, adminId);
|
|
@@ -3795,7 +3798,7 @@ var PractitionerService = class extends BaseService {
|
|
|
3795
3798
|
(0, import_firestore13.where)("expiresAt", ">", import_firestore13.Timestamp.now())
|
|
3796
3799
|
);
|
|
3797
3800
|
const querySnapshot = await (0, import_firestore13.getDocs)(q);
|
|
3798
|
-
return querySnapshot.docs.map((
|
|
3801
|
+
return querySnapshot.docs.map((doc29) => doc29.data());
|
|
3799
3802
|
}
|
|
3800
3803
|
/**
|
|
3801
3804
|
* Gets a token by its string value and validates it
|
|
@@ -3878,7 +3881,7 @@ var PractitionerService = class extends BaseService {
|
|
|
3878
3881
|
(0, import_firestore13.where)("status", "==", "active" /* ACTIVE */)
|
|
3879
3882
|
);
|
|
3880
3883
|
const querySnapshot = await (0, import_firestore13.getDocs)(q);
|
|
3881
|
-
return querySnapshot.docs.map((
|
|
3884
|
+
return querySnapshot.docs.map((doc29) => doc29.data());
|
|
3882
3885
|
}
|
|
3883
3886
|
/**
|
|
3884
3887
|
* Dohvata sve zdravstvene radnike za određenu kliniku
|
|
@@ -3890,7 +3893,7 @@ var PractitionerService = class extends BaseService {
|
|
|
3890
3893
|
(0, import_firestore13.where)("isActive", "==", true)
|
|
3891
3894
|
);
|
|
3892
3895
|
const querySnapshot = await (0, import_firestore13.getDocs)(q);
|
|
3893
|
-
return querySnapshot.docs.map((
|
|
3896
|
+
return querySnapshot.docs.map((doc29) => doc29.data());
|
|
3894
3897
|
}
|
|
3895
3898
|
/**
|
|
3896
3899
|
* Dohvata sve draft zdravstvene radnike za određenu kliniku sa statusom DRAFT
|
|
@@ -3902,7 +3905,7 @@ var PractitionerService = class extends BaseService {
|
|
|
3902
3905
|
(0, import_firestore13.where)("status", "==", "draft" /* DRAFT */)
|
|
3903
3906
|
);
|
|
3904
3907
|
const querySnapshot = await (0, import_firestore13.getDocs)(q);
|
|
3905
|
-
return querySnapshot.docs.map((
|
|
3908
|
+
return querySnapshot.docs.map((doc29) => doc29.data());
|
|
3906
3909
|
}
|
|
3907
3910
|
/**
|
|
3908
3911
|
* Updates a practitioner
|
|
@@ -4084,7 +4087,7 @@ var PractitionerService = class extends BaseService {
|
|
|
4084
4087
|
);
|
|
4085
4088
|
const querySnapshot = await (0, import_firestore13.getDocs)(q);
|
|
4086
4089
|
const practitioners = querySnapshot.docs.map(
|
|
4087
|
-
(
|
|
4090
|
+
(doc29) => doc29.data()
|
|
4088
4091
|
);
|
|
4089
4092
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
4090
4093
|
return {
|
|
@@ -4155,8 +4158,8 @@ var PractitionerService = class extends BaseService {
|
|
|
4155
4158
|
console.log(
|
|
4156
4159
|
`[PRACTITIONER_SERVICE] Found ${querySnapshot.docs.length} practitioners with base query`
|
|
4157
4160
|
);
|
|
4158
|
-
let practitioners = querySnapshot.docs.map((
|
|
4159
|
-
return { ...
|
|
4161
|
+
let practitioners = querySnapshot.docs.map((doc29) => {
|
|
4162
|
+
return { ...doc29.data(), id: doc29.id };
|
|
4160
4163
|
});
|
|
4161
4164
|
const lastDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
4162
4165
|
if (filters.nameSearch && filters.nameSearch.trim() !== "") {
|
|
@@ -4410,7 +4413,7 @@ var UserService = class extends BaseService {
|
|
|
4410
4413
|
];
|
|
4411
4414
|
const q = (0, import_firestore14.query)((0, import_firestore14.collection)(this.db, USERS_COLLECTION), ...constraints);
|
|
4412
4415
|
const querySnapshot = await (0, import_firestore14.getDocs)(q);
|
|
4413
|
-
const users = querySnapshot.docs.map((
|
|
4416
|
+
const users = querySnapshot.docs.map((doc29) => doc29.data());
|
|
4414
4417
|
return Promise.all(users.map((userData) => userSchema.parse(userData)));
|
|
4415
4418
|
}
|
|
4416
4419
|
/**
|
|
@@ -4774,7 +4777,7 @@ async function getAllActiveGroups(db) {
|
|
|
4774
4777
|
(0, import_firestore15.where)("isActive", "==", true)
|
|
4775
4778
|
);
|
|
4776
4779
|
const querySnapshot = await (0, import_firestore15.getDocs)(q);
|
|
4777
|
-
return querySnapshot.docs.map((
|
|
4780
|
+
return querySnapshot.docs.map((doc29) => doc29.data());
|
|
4778
4781
|
}
|
|
4779
4782
|
async function updateClinicGroup(db, groupId, data, app) {
|
|
4780
4783
|
console.log("[CLINIC_GROUP] Updating clinic group", { groupId });
|
|
@@ -5172,7 +5175,7 @@ async function getClinicsByGroup(db, groupId) {
|
|
|
5172
5175
|
(0, import_firestore16.where)("isActive", "==", true)
|
|
5173
5176
|
);
|
|
5174
5177
|
const querySnapshot = await (0, import_firestore16.getDocs)(q);
|
|
5175
|
-
return querySnapshot.docs.map((
|
|
5178
|
+
return querySnapshot.docs.map((doc29) => doc29.data());
|
|
5176
5179
|
}
|
|
5177
5180
|
async function updateClinic(db, clinicId, data, adminId, clinicAdminService, app) {
|
|
5178
5181
|
console.log("[CLINIC] Starting clinic update", { clinicId, adminId });
|
|
@@ -5366,7 +5369,7 @@ async function getClinicsByAdmin(db, adminId, options = {}, clinicAdminService,
|
|
|
5366
5369
|
}
|
|
5367
5370
|
const q = (0, import_firestore16.query)((0, import_firestore16.collection)(db, CLINICS_COLLECTION), ...constraints);
|
|
5368
5371
|
const querySnapshot = await (0, import_firestore16.getDocs)(q);
|
|
5369
|
-
return querySnapshot.docs.map((
|
|
5372
|
+
return querySnapshot.docs.map((doc29) => doc29.data());
|
|
5370
5373
|
}
|
|
5371
5374
|
async function getActiveClinicsByAdmin(db, adminId, clinicAdminService, clinicGroupService) {
|
|
5372
5375
|
return getClinicsByAdmin(
|
|
@@ -5411,11 +5414,11 @@ async function getAllClinics(db, pagination, lastDoc) {
|
|
|
5411
5414
|
}
|
|
5412
5415
|
const clinicsSnapshot = await (0, import_firestore16.getDocs)(clinicsQuery);
|
|
5413
5416
|
const lastVisible = clinicsSnapshot.docs[clinicsSnapshot.docs.length - 1];
|
|
5414
|
-
const clinics = clinicsSnapshot.docs.map((
|
|
5415
|
-
const data =
|
|
5417
|
+
const clinics = clinicsSnapshot.docs.map((doc29) => {
|
|
5418
|
+
const data = doc29.data();
|
|
5416
5419
|
return {
|
|
5417
5420
|
...data,
|
|
5418
|
-
id:
|
|
5421
|
+
id: doc29.id
|
|
5419
5422
|
};
|
|
5420
5423
|
});
|
|
5421
5424
|
return {
|
|
@@ -5442,8 +5445,8 @@ async function getAllClinicsInRange(db, center, rangeInKm, pagination, lastDoc)
|
|
|
5442
5445
|
];
|
|
5443
5446
|
const q = (0, import_firestore16.query)((0, import_firestore16.collection)(db, CLINICS_COLLECTION), ...constraints);
|
|
5444
5447
|
const querySnapshot = await (0, import_firestore16.getDocs)(q);
|
|
5445
|
-
for (const
|
|
5446
|
-
const clinic =
|
|
5448
|
+
for (const doc29 of querySnapshot.docs) {
|
|
5449
|
+
const clinic = doc29.data();
|
|
5447
5450
|
const distance = (0, import_geofire_common4.distanceBetween)(
|
|
5448
5451
|
[center.latitude, center.longitude],
|
|
5449
5452
|
[clinic.location.latitude, clinic.location.longitude]
|
|
@@ -5560,8 +5563,8 @@ async function findClinicsInRadius(db, center, radiusInKm, filters) {
|
|
|
5560
5563
|
}
|
|
5561
5564
|
const q = (0, import_firestore17.query)((0, import_firestore17.collection)(db, CLINICS_COLLECTION), ...constraints);
|
|
5562
5565
|
const querySnapshot = await (0, import_firestore17.getDocs)(q);
|
|
5563
|
-
for (const
|
|
5564
|
-
const clinic =
|
|
5566
|
+
for (const doc29 of querySnapshot.docs) {
|
|
5567
|
+
const clinic = doc29.data();
|
|
5565
5568
|
const distance = (0, import_geofire_common5.distanceBetween)(
|
|
5566
5569
|
[center.latitude, center.longitude],
|
|
5567
5570
|
[clinic.location.latitude, clinic.location.longitude]
|
|
@@ -5626,7 +5629,7 @@ async function getClinicsByFilters(db, filters) {
|
|
|
5626
5629
|
} else if (filters.pagination && filters.pagination > 0) {
|
|
5627
5630
|
constraints.push((0, import_firestore18.limit)(filters.pagination));
|
|
5628
5631
|
}
|
|
5629
|
-
constraints.push((0, import_firestore18.orderBy)(
|
|
5632
|
+
constraints.push((0, import_firestore18.orderBy)("location.geohash"));
|
|
5630
5633
|
let clinicsResult = [];
|
|
5631
5634
|
let lastVisibleDoc = null;
|
|
5632
5635
|
if (isGeoQuery) {
|
|
@@ -5649,8 +5652,8 @@ async function getClinicsByFilters(db, filters) {
|
|
|
5649
5652
|
console.log(
|
|
5650
5653
|
`[FILTER_UTILS] Found ${querySnapshot.docs.length} clinics in geo bound`
|
|
5651
5654
|
);
|
|
5652
|
-
for (const
|
|
5653
|
-
const clinic = { ...
|
|
5655
|
+
for (const doc29 of querySnapshot.docs) {
|
|
5656
|
+
const clinic = { ...doc29.data(), id: doc29.id };
|
|
5654
5657
|
const distance = (0, import_geofire_common6.distanceBetween)(
|
|
5655
5658
|
[center.latitude, center.longitude],
|
|
5656
5659
|
[clinic.location.latitude, clinic.location.longitude]
|
|
@@ -5706,10 +5709,29 @@ async function getClinicsByFilters(db, filters) {
|
|
|
5706
5709
|
console.log(
|
|
5707
5710
|
`[FILTER_UTILS] Found ${querySnapshot.docs.length} clinics with regular query`
|
|
5708
5711
|
);
|
|
5709
|
-
const clinics = querySnapshot.docs.map((
|
|
5710
|
-
return { ...
|
|
5712
|
+
const clinics = querySnapshot.docs.map((doc29) => {
|
|
5713
|
+
return { ...doc29.data(), id: doc29.id };
|
|
5711
5714
|
});
|
|
5712
5715
|
let filteredClinics = clinics;
|
|
5716
|
+
if (filters.center) {
|
|
5717
|
+
const center = filters.center;
|
|
5718
|
+
const clinicsWithDistance = [];
|
|
5719
|
+
filteredClinics.forEach((clinic) => {
|
|
5720
|
+
const distance = (0, import_geofire_common6.distanceBetween)(
|
|
5721
|
+
[center.latitude, center.longitude],
|
|
5722
|
+
[clinic.location.latitude, clinic.location.longitude]
|
|
5723
|
+
);
|
|
5724
|
+
clinicsWithDistance.push({
|
|
5725
|
+
...clinic,
|
|
5726
|
+
distance: distance / 1e3
|
|
5727
|
+
// Convert to kilometers
|
|
5728
|
+
});
|
|
5729
|
+
});
|
|
5730
|
+
filteredClinics = clinicsWithDistance;
|
|
5731
|
+
filteredClinics.sort(
|
|
5732
|
+
(a, b) => a.distance - b.distance
|
|
5733
|
+
);
|
|
5734
|
+
}
|
|
5713
5735
|
if (filters.tags && filters.tags.length > 1) {
|
|
5714
5736
|
filteredClinics = filteredClinics.filter((clinic) => {
|
|
5715
5737
|
return filters.tags.every((tag) => clinic.tags.includes(tag));
|
|
@@ -5998,6 +6020,12 @@ var ClinicService = class extends BaseService {
|
|
|
5998
6020
|
lastDoc
|
|
5999
6021
|
);
|
|
6000
6022
|
}
|
|
6023
|
+
/**
|
|
6024
|
+
* Get clinics based on multiple filtering criteria
|
|
6025
|
+
*
|
|
6026
|
+
* @param filters - Various filters to apply
|
|
6027
|
+
* @returns Filtered clinics and the last document for pagination
|
|
6028
|
+
*/
|
|
6001
6029
|
async getClinicsByFilters(filters) {
|
|
6002
6030
|
return getClinicsByFilters(this.db, filters);
|
|
6003
6031
|
}
|
|
@@ -6732,9 +6760,9 @@ var NotificationService = class extends BaseService {
|
|
|
6732
6760
|
(0, import_firestore21.orderBy)("notificationTime", "desc")
|
|
6733
6761
|
);
|
|
6734
6762
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6735
|
-
return querySnapshot.docs.map((
|
|
6736
|
-
id:
|
|
6737
|
-
...
|
|
6763
|
+
return querySnapshot.docs.map((doc29) => ({
|
|
6764
|
+
id: doc29.id,
|
|
6765
|
+
...doc29.data()
|
|
6738
6766
|
}));
|
|
6739
6767
|
}
|
|
6740
6768
|
/**
|
|
@@ -6748,9 +6776,9 @@ var NotificationService = class extends BaseService {
|
|
|
6748
6776
|
(0, import_firestore21.orderBy)("notificationTime", "desc")
|
|
6749
6777
|
);
|
|
6750
6778
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6751
|
-
return querySnapshot.docs.map((
|
|
6752
|
-
id:
|
|
6753
|
-
...
|
|
6779
|
+
return querySnapshot.docs.map((doc29) => ({
|
|
6780
|
+
id: doc29.id,
|
|
6781
|
+
...doc29.data()
|
|
6754
6782
|
}));
|
|
6755
6783
|
}
|
|
6756
6784
|
/**
|
|
@@ -6822,9 +6850,9 @@ var NotificationService = class extends BaseService {
|
|
|
6822
6850
|
(0, import_firestore21.orderBy)("notificationTime", "desc")
|
|
6823
6851
|
);
|
|
6824
6852
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6825
|
-
return querySnapshot.docs.map((
|
|
6826
|
-
id:
|
|
6827
|
-
...
|
|
6853
|
+
return querySnapshot.docs.map((doc29) => ({
|
|
6854
|
+
id: doc29.id,
|
|
6855
|
+
...doc29.data()
|
|
6828
6856
|
}));
|
|
6829
6857
|
}
|
|
6830
6858
|
/**
|
|
@@ -6837,9 +6865,9 @@ var NotificationService = class extends BaseService {
|
|
|
6837
6865
|
(0, import_firestore21.orderBy)("notificationTime", "desc")
|
|
6838
6866
|
);
|
|
6839
6867
|
const querySnapshot = await (0, import_firestore21.getDocs)(q);
|
|
6840
|
-
return querySnapshot.docs.map((
|
|
6841
|
-
id:
|
|
6842
|
-
...
|
|
6868
|
+
return querySnapshot.docs.map((doc29) => ({
|
|
6869
|
+
id: doc29.id,
|
|
6870
|
+
...doc29.data()
|
|
6843
6871
|
}));
|
|
6844
6872
|
}
|
|
6845
6873
|
};
|
|
@@ -7056,7 +7084,7 @@ var ProcedureService = class extends BaseService {
|
|
|
7056
7084
|
(0, import_firestore22.where)("isActive", "==", true)
|
|
7057
7085
|
);
|
|
7058
7086
|
const snapshot = await (0, import_firestore22.getDocs)(q);
|
|
7059
|
-
return snapshot.docs.map((
|
|
7087
|
+
return snapshot.docs.map((doc29) => doc29.data());
|
|
7060
7088
|
}
|
|
7061
7089
|
/**
|
|
7062
7090
|
* Gets all procedures for a practitioner
|
|
@@ -7070,7 +7098,7 @@ var ProcedureService = class extends BaseService {
|
|
|
7070
7098
|
(0, import_firestore22.where)("isActive", "==", true)
|
|
7071
7099
|
);
|
|
7072
7100
|
const snapshot = await (0, import_firestore22.getDocs)(q);
|
|
7073
|
-
return snapshot.docs.map((
|
|
7101
|
+
return snapshot.docs.map((doc29) => doc29.data());
|
|
7074
7102
|
}
|
|
7075
7103
|
/**
|
|
7076
7104
|
* Updates a procedure
|
|
@@ -7274,11 +7302,11 @@ var ProcedureService = class extends BaseService {
|
|
|
7274
7302
|
}
|
|
7275
7303
|
const proceduresSnapshot = await (0, import_firestore22.getDocs)(proceduresQuery);
|
|
7276
7304
|
const lastVisible = proceduresSnapshot.docs[proceduresSnapshot.docs.length - 1];
|
|
7277
|
-
const procedures = proceduresSnapshot.docs.map((
|
|
7278
|
-
const data =
|
|
7305
|
+
const procedures = proceduresSnapshot.docs.map((doc29) => {
|
|
7306
|
+
const data = doc29.data();
|
|
7279
7307
|
return {
|
|
7280
7308
|
...data,
|
|
7281
|
-
id:
|
|
7309
|
+
id: doc29.id
|
|
7282
7310
|
// Ensure ID is present
|
|
7283
7311
|
};
|
|
7284
7312
|
});
|
|
@@ -7328,7 +7356,7 @@ var ProcedureService = class extends BaseService {
|
|
|
7328
7356
|
if (filters.procedureFamily) {
|
|
7329
7357
|
constraints.push((0, import_firestore22.where)("family", "==", filters.procedureFamily));
|
|
7330
7358
|
}
|
|
7331
|
-
constraints.push((0, import_firestore22.orderBy)(
|
|
7359
|
+
constraints.push((0, import_firestore22.orderBy)("clinicInfo.location.geohash"));
|
|
7332
7360
|
if (filters.pagination && filters.pagination > 0 && filters.lastDoc) {
|
|
7333
7361
|
constraints.push((0, import_firestore22.startAfter)(filters.lastDoc));
|
|
7334
7362
|
constraints.push((0, import_firestore22.limit)(filters.pagination));
|
|
@@ -7360,8 +7388,8 @@ var ProcedureService = class extends BaseService {
|
|
|
7360
7388
|
console.log(
|
|
7361
7389
|
`[PROCEDURE_SERVICE] Found ${querySnapshot.docs.length} procedures in geo bound`
|
|
7362
7390
|
);
|
|
7363
|
-
for (const
|
|
7364
|
-
const procedure = { ...
|
|
7391
|
+
for (const doc29 of querySnapshot.docs) {
|
|
7392
|
+
const procedure = { ...doc29.data(), id: doc29.id };
|
|
7365
7393
|
const distance = (0, import_geofire_common8.distanceBetween)(
|
|
7366
7394
|
[center.latitude, center.longitude],
|
|
7367
7395
|
[
|
|
@@ -7412,12 +7440,41 @@ var ProcedureService = class extends BaseService {
|
|
|
7412
7440
|
console.log(
|
|
7413
7441
|
`[PROCEDURE_SERVICE] Found ${querySnapshot.docs.length} procedures with regular query`
|
|
7414
7442
|
);
|
|
7415
|
-
const procedures = querySnapshot.docs.map((
|
|
7416
|
-
return { ...
|
|
7443
|
+
const procedures = querySnapshot.docs.map((doc29) => {
|
|
7444
|
+
return { ...doc29.data(), id: doc29.id };
|
|
7417
7445
|
});
|
|
7418
|
-
|
|
7446
|
+
if (filters.location) {
|
|
7447
|
+
const center = filters.location;
|
|
7448
|
+
const proceduresWithDistance = [];
|
|
7449
|
+
procedures.forEach((procedure) => {
|
|
7450
|
+
const distance = (0, import_geofire_common8.distanceBetween)(
|
|
7451
|
+
[center.latitude, center.longitude],
|
|
7452
|
+
[
|
|
7453
|
+
procedure.clinicInfo.location.latitude,
|
|
7454
|
+
procedure.clinicInfo.location.longitude
|
|
7455
|
+
]
|
|
7456
|
+
);
|
|
7457
|
+
proceduresWithDistance.push({
|
|
7458
|
+
...procedure,
|
|
7459
|
+
distance: distance / 1e3
|
|
7460
|
+
// Convert to kilometers
|
|
7461
|
+
});
|
|
7462
|
+
});
|
|
7463
|
+
let filteredProcedures = proceduresWithDistance;
|
|
7464
|
+
filteredProcedures = this.applyInMemoryFilters(
|
|
7465
|
+
filteredProcedures,
|
|
7466
|
+
filters
|
|
7467
|
+
);
|
|
7468
|
+
filteredProcedures.sort((a, b) => a.distance - b.distance);
|
|
7469
|
+
proceduresResult = filteredProcedures;
|
|
7470
|
+
} else {
|
|
7471
|
+
let filteredProcedures = this.applyInMemoryFilters(
|
|
7472
|
+
procedures,
|
|
7473
|
+
filters
|
|
7474
|
+
);
|
|
7475
|
+
proceduresResult = filteredProcedures;
|
|
7476
|
+
}
|
|
7419
7477
|
lastVisibleDoc = querySnapshot.docs.length > 0 ? querySnapshot.docs[querySnapshot.docs.length - 1] : null;
|
|
7420
|
-
proceduresResult = filteredProcedures;
|
|
7421
7478
|
}
|
|
7422
7479
|
return {
|
|
7423
7480
|
procedures: proceduresResult,
|
|
@@ -7602,9 +7659,9 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
7602
7659
|
const querySnapshot = await (0, import_firestore23.getDocs)(q);
|
|
7603
7660
|
const templates = [];
|
|
7604
7661
|
let lastVisible = null;
|
|
7605
|
-
querySnapshot.forEach((
|
|
7606
|
-
templates.push(
|
|
7607
|
-
lastVisible =
|
|
7662
|
+
querySnapshot.forEach((doc29) => {
|
|
7663
|
+
templates.push(doc29.data());
|
|
7664
|
+
lastVisible = doc29;
|
|
7608
7665
|
});
|
|
7609
7666
|
return {
|
|
7610
7667
|
templates,
|
|
@@ -7632,9 +7689,9 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
7632
7689
|
const querySnapshot = await (0, import_firestore23.getDocs)(q);
|
|
7633
7690
|
const templates = [];
|
|
7634
7691
|
let lastVisible = null;
|
|
7635
|
-
querySnapshot.forEach((
|
|
7636
|
-
templates.push(
|
|
7637
|
-
lastVisible =
|
|
7692
|
+
querySnapshot.forEach((doc29) => {
|
|
7693
|
+
templates.push(doc29.data());
|
|
7694
|
+
lastVisible = doc29;
|
|
7638
7695
|
});
|
|
7639
7696
|
return {
|
|
7640
7697
|
templates,
|
|
@@ -7661,9 +7718,9 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
7661
7718
|
const querySnapshot = await (0, import_firestore23.getDocs)(q);
|
|
7662
7719
|
const templates = [];
|
|
7663
7720
|
let lastVisible = null;
|
|
7664
|
-
querySnapshot.forEach((
|
|
7665
|
-
templates.push(
|
|
7666
|
-
lastVisible =
|
|
7721
|
+
querySnapshot.forEach((doc29) => {
|
|
7722
|
+
templates.push(doc29.data());
|
|
7723
|
+
lastVisible = doc29;
|
|
7667
7724
|
});
|
|
7668
7725
|
return {
|
|
7669
7726
|
templates,
|
|
@@ -7776,9 +7833,9 @@ var FilledDocumentService = class extends BaseService {
|
|
|
7776
7833
|
const querySnapshot = await (0, import_firestore24.getDocs)(q);
|
|
7777
7834
|
const documents = [];
|
|
7778
7835
|
let lastVisible = null;
|
|
7779
|
-
querySnapshot.forEach((
|
|
7780
|
-
documents.push(
|
|
7781
|
-
lastVisible =
|
|
7836
|
+
querySnapshot.forEach((doc29) => {
|
|
7837
|
+
documents.push(doc29.data());
|
|
7838
|
+
lastVisible = doc29;
|
|
7782
7839
|
});
|
|
7783
7840
|
return {
|
|
7784
7841
|
documents,
|
|
@@ -7805,9 +7862,9 @@ var FilledDocumentService = class extends BaseService {
|
|
|
7805
7862
|
const querySnapshot = await (0, import_firestore24.getDocs)(q);
|
|
7806
7863
|
const documents = [];
|
|
7807
7864
|
let lastVisible = null;
|
|
7808
|
-
querySnapshot.forEach((
|
|
7809
|
-
documents.push(
|
|
7810
|
-
lastVisible =
|
|
7865
|
+
querySnapshot.forEach((doc29) => {
|
|
7866
|
+
documents.push(doc29.data());
|
|
7867
|
+
lastVisible = doc29;
|
|
7811
7868
|
});
|
|
7812
7869
|
return {
|
|
7813
7870
|
documents,
|
|
@@ -7834,9 +7891,9 @@ var FilledDocumentService = class extends BaseService {
|
|
|
7834
7891
|
const querySnapshot = await (0, import_firestore24.getDocs)(q);
|
|
7835
7892
|
const documents = [];
|
|
7836
7893
|
let lastVisible = null;
|
|
7837
|
-
querySnapshot.forEach((
|
|
7838
|
-
documents.push(
|
|
7839
|
-
lastVisible =
|
|
7894
|
+
querySnapshot.forEach((doc29) => {
|
|
7895
|
+
documents.push(doc29.data());
|
|
7896
|
+
lastVisible = doc29;
|
|
7840
7897
|
});
|
|
7841
7898
|
return {
|
|
7842
7899
|
documents,
|
|
@@ -7863,9 +7920,9 @@ var FilledDocumentService = class extends BaseService {
|
|
|
7863
7920
|
const querySnapshot = await (0, import_firestore24.getDocs)(q);
|
|
7864
7921
|
const documents = [];
|
|
7865
7922
|
let lastVisible = null;
|
|
7866
|
-
querySnapshot.forEach((
|
|
7867
|
-
documents.push(
|
|
7868
|
-
lastVisible =
|
|
7923
|
+
querySnapshot.forEach((doc29) => {
|
|
7924
|
+
documents.push(doc29.data());
|
|
7925
|
+
lastVisible = doc29;
|
|
7869
7926
|
});
|
|
7870
7927
|
return {
|
|
7871
7928
|
documents,
|
|
@@ -7892,9 +7949,9 @@ var FilledDocumentService = class extends BaseService {
|
|
|
7892
7949
|
const querySnapshot = await (0, import_firestore24.getDocs)(q);
|
|
7893
7950
|
const documents = [];
|
|
7894
7951
|
let lastVisible = null;
|
|
7895
|
-
querySnapshot.forEach((
|
|
7896
|
-
documents.push(
|
|
7897
|
-
lastVisible =
|
|
7952
|
+
querySnapshot.forEach((doc29) => {
|
|
7953
|
+
documents.push(doc29.data());
|
|
7954
|
+
lastVisible = doc29;
|
|
7898
7955
|
});
|
|
7899
7956
|
return {
|
|
7900
7957
|
documents,
|
|
@@ -8391,7 +8448,7 @@ async function searchCalendarEventsUtil(db, params) {
|
|
|
8391
8448
|
const finalQuery = (0, import_firestore31.query)(collectionRef, ...constraints);
|
|
8392
8449
|
const querySnapshot = await (0, import_firestore31.getDocs)(finalQuery);
|
|
8393
8450
|
const events = querySnapshot.docs.map(
|
|
8394
|
-
(
|
|
8451
|
+
(doc29) => ({ id: doc29.id, ...doc29.data() })
|
|
8395
8452
|
);
|
|
8396
8453
|
return events;
|
|
8397
8454
|
} catch (error) {
|
|
@@ -8473,7 +8530,7 @@ async function getPractitionerSyncedCalendarsUtil(db, practitionerId) {
|
|
|
8473
8530
|
);
|
|
8474
8531
|
const q = (0, import_firestore32.query)(calendarsRef, (0, import_firestore32.orderBy)("createdAt", "desc"));
|
|
8475
8532
|
const querySnapshot = await (0, import_firestore32.getDocs)(q);
|
|
8476
|
-
return querySnapshot.docs.map((
|
|
8533
|
+
return querySnapshot.docs.map((doc29) => doc29.data());
|
|
8477
8534
|
}
|
|
8478
8535
|
async function getPatientSyncedCalendarUtil(db, patientId, calendarId) {
|
|
8479
8536
|
const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
|
|
@@ -8490,7 +8547,7 @@ async function getPatientSyncedCalendarsUtil(db, patientId) {
|
|
|
8490
8547
|
);
|
|
8491
8548
|
const q = (0, import_firestore32.query)(calendarsRef, (0, import_firestore32.orderBy)("createdAt", "desc"));
|
|
8492
8549
|
const querySnapshot = await (0, import_firestore32.getDocs)(q);
|
|
8493
|
-
return querySnapshot.docs.map((
|
|
8550
|
+
return querySnapshot.docs.map((doc29) => doc29.data());
|
|
8494
8551
|
}
|
|
8495
8552
|
async function getClinicSyncedCalendarUtil(db, clinicId, calendarId) {
|
|
8496
8553
|
const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
|
|
@@ -8507,7 +8564,7 @@ async function getClinicSyncedCalendarsUtil(db, clinicId) {
|
|
|
8507
8564
|
);
|
|
8508
8565
|
const q = (0, import_firestore32.query)(calendarsRef, (0, import_firestore32.orderBy)("createdAt", "desc"));
|
|
8509
8566
|
const querySnapshot = await (0, import_firestore32.getDocs)(q);
|
|
8510
|
-
return querySnapshot.docs.map((
|
|
8567
|
+
return querySnapshot.docs.map((doc29) => doc29.data());
|
|
8511
8568
|
}
|
|
8512
8569
|
async function updatePractitionerSyncedCalendarUtil(db, practitionerId, calendarId, updateData) {
|
|
8513
8570
|
const calendarRef = getPractitionerSyncedCalendarDocRef(
|
|
@@ -9862,9 +9919,9 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9862
9919
|
(0, import_firestore35.where)("eventTime.start", "<=", import_firestore34.Timestamp.fromDate(endDate))
|
|
9863
9920
|
);
|
|
9864
9921
|
const eventsSnapshot = await (0, import_firestore35.getDocs)(q);
|
|
9865
|
-
const events = eventsSnapshot.docs.map((
|
|
9866
|
-
id:
|
|
9867
|
-
...
|
|
9922
|
+
const events = eventsSnapshot.docs.map((doc29) => ({
|
|
9923
|
+
id: doc29.id,
|
|
9924
|
+
...doc29.data()
|
|
9868
9925
|
}));
|
|
9869
9926
|
const calendars = await this.syncedCalendarsService.getPractitionerSyncedCalendars(
|
|
9870
9927
|
doctorId
|
|
@@ -10496,7 +10553,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
10496
10553
|
])
|
|
10497
10554
|
);
|
|
10498
10555
|
const querySnapshot = await (0, import_firestore35.getDocs)(q);
|
|
10499
|
-
return querySnapshot.docs.map((
|
|
10556
|
+
return querySnapshot.docs.map((doc29) => doc29.data());
|
|
10500
10557
|
}
|
|
10501
10558
|
/**
|
|
10502
10559
|
* Calculates available time slots based on working hours, schedule and existing appointments
|
|
@@ -10620,9 +10677,618 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
10620
10677
|
// #endregion
|
|
10621
10678
|
};
|
|
10622
10679
|
|
|
10623
|
-
// src/
|
|
10680
|
+
// src/services/reviews/reviews.service.ts
|
|
10624
10681
|
var import_firestore36 = require("firebase/firestore");
|
|
10625
10682
|
|
|
10683
|
+
// src/types/reviews/index.ts
|
|
10684
|
+
var REVIEWS_COLLECTION = "reviews";
|
|
10685
|
+
|
|
10686
|
+
// src/services/reviews/reviews.service.ts
|
|
10687
|
+
var import_zod21 = require("zod");
|
|
10688
|
+
var ReviewService = class extends BaseService {
|
|
10689
|
+
constructor(db, auth, app) {
|
|
10690
|
+
super(db, auth, app);
|
|
10691
|
+
}
|
|
10692
|
+
/**
|
|
10693
|
+
* Creates a new review and updates related entities
|
|
10694
|
+
* @param data - The review data to create
|
|
10695
|
+
* @param appointmentId - ID of the completed appointment
|
|
10696
|
+
* @returns The created review
|
|
10697
|
+
*/
|
|
10698
|
+
async createReview(data, appointmentId) {
|
|
10699
|
+
try {
|
|
10700
|
+
const validatedData = createReviewSchema.parse(data);
|
|
10701
|
+
const ratings = [];
|
|
10702
|
+
if (data.clinicReview) {
|
|
10703
|
+
const clinicRatings = [
|
|
10704
|
+
data.clinicReview.cleanliness,
|
|
10705
|
+
data.clinicReview.facilities,
|
|
10706
|
+
data.clinicReview.staffFriendliness,
|
|
10707
|
+
data.clinicReview.waitingTime,
|
|
10708
|
+
data.clinicReview.accessibility
|
|
10709
|
+
];
|
|
10710
|
+
const clinicAverage = this.calculateAverage(clinicRatings);
|
|
10711
|
+
data.clinicReview.overallRating = clinicAverage;
|
|
10712
|
+
ratings.push(clinicAverage);
|
|
10713
|
+
}
|
|
10714
|
+
if (data.practitionerReview) {
|
|
10715
|
+
const practitionerRatings = [
|
|
10716
|
+
data.practitionerReview.knowledgeAndExpertise,
|
|
10717
|
+
data.practitionerReview.communicationSkills,
|
|
10718
|
+
data.practitionerReview.bedSideManner,
|
|
10719
|
+
data.practitionerReview.thoroughness,
|
|
10720
|
+
data.practitionerReview.trustworthiness
|
|
10721
|
+
];
|
|
10722
|
+
const practitionerAverage = this.calculateAverage(practitionerRatings);
|
|
10723
|
+
data.practitionerReview.overallRating = practitionerAverage;
|
|
10724
|
+
ratings.push(practitionerAverage);
|
|
10725
|
+
}
|
|
10726
|
+
if (data.procedureReview) {
|
|
10727
|
+
const procedureRatings = [
|
|
10728
|
+
data.procedureReview.effectivenessOfTreatment,
|
|
10729
|
+
data.procedureReview.outcomeExplanation,
|
|
10730
|
+
data.procedureReview.painManagement,
|
|
10731
|
+
data.procedureReview.followUpCare,
|
|
10732
|
+
data.procedureReview.valueForMoney
|
|
10733
|
+
];
|
|
10734
|
+
const procedureAverage = this.calculateAverage(procedureRatings);
|
|
10735
|
+
data.procedureReview.overallRating = procedureAverage;
|
|
10736
|
+
ratings.push(procedureAverage);
|
|
10737
|
+
}
|
|
10738
|
+
const overallRating = this.calculateAverage(ratings);
|
|
10739
|
+
const reviewId = this.generateId();
|
|
10740
|
+
if (data.clinicReview) {
|
|
10741
|
+
data.clinicReview.id = this.generateId();
|
|
10742
|
+
data.clinicReview.fullReviewId = reviewId;
|
|
10743
|
+
}
|
|
10744
|
+
if (data.practitionerReview) {
|
|
10745
|
+
data.practitionerReview.id = this.generateId();
|
|
10746
|
+
data.practitionerReview.fullReviewId = reviewId;
|
|
10747
|
+
}
|
|
10748
|
+
if (data.procedureReview) {
|
|
10749
|
+
data.procedureReview.id = this.generateId();
|
|
10750
|
+
data.procedureReview.fullReviewId = reviewId;
|
|
10751
|
+
}
|
|
10752
|
+
const now = /* @__PURE__ */ new Date();
|
|
10753
|
+
const review = {
|
|
10754
|
+
id: reviewId,
|
|
10755
|
+
appointmentId,
|
|
10756
|
+
patientId: data.patientId,
|
|
10757
|
+
clinicReview: data.clinicReview,
|
|
10758
|
+
practitionerReview: data.practitionerReview,
|
|
10759
|
+
procedureReview: data.procedureReview,
|
|
10760
|
+
overallComment: data.overallComment,
|
|
10761
|
+
overallRating,
|
|
10762
|
+
createdAt: now,
|
|
10763
|
+
updatedAt: now
|
|
10764
|
+
};
|
|
10765
|
+
reviewSchema.parse(review);
|
|
10766
|
+
const docRef = (0, import_firestore36.doc)(this.db, REVIEWS_COLLECTION, reviewId);
|
|
10767
|
+
await (0, import_firestore36.setDoc)(docRef, {
|
|
10768
|
+
...review,
|
|
10769
|
+
createdAt: (0, import_firestore36.serverTimestamp)(),
|
|
10770
|
+
updatedAt: (0, import_firestore36.serverTimestamp)()
|
|
10771
|
+
});
|
|
10772
|
+
const updatePromises = [];
|
|
10773
|
+
if (data.clinicReview) {
|
|
10774
|
+
updatePromises.push(
|
|
10775
|
+
this.updateClinicReviewInfo(data.clinicReview.clinicId)
|
|
10776
|
+
);
|
|
10777
|
+
}
|
|
10778
|
+
if (data.practitionerReview) {
|
|
10779
|
+
updatePromises.push(
|
|
10780
|
+
this.updatePractitionerReviewInfo(
|
|
10781
|
+
data.practitionerReview.practitionerId
|
|
10782
|
+
)
|
|
10783
|
+
);
|
|
10784
|
+
}
|
|
10785
|
+
if (data.procedureReview) {
|
|
10786
|
+
updatePromises.push(
|
|
10787
|
+
this.updateProcedureReviewInfo(data.procedureReview.procedureId)
|
|
10788
|
+
);
|
|
10789
|
+
}
|
|
10790
|
+
await Promise.all(updatePromises);
|
|
10791
|
+
return review;
|
|
10792
|
+
} catch (error) {
|
|
10793
|
+
if (error instanceof import_zod21.z.ZodError) {
|
|
10794
|
+
throw new Error(`Invalid review data: ${error.message}`);
|
|
10795
|
+
}
|
|
10796
|
+
throw error;
|
|
10797
|
+
}
|
|
10798
|
+
}
|
|
10799
|
+
/**
|
|
10800
|
+
* Gets a review by ID
|
|
10801
|
+
* @param reviewId The ID of the review to get
|
|
10802
|
+
* @returns The review if found, null otherwise
|
|
10803
|
+
*/
|
|
10804
|
+
async getReview(reviewId) {
|
|
10805
|
+
const docRef = (0, import_firestore36.doc)(this.db, REVIEWS_COLLECTION, reviewId);
|
|
10806
|
+
const docSnap = await (0, import_firestore36.getDoc)(docRef);
|
|
10807
|
+
if (!docSnap.exists()) {
|
|
10808
|
+
return null;
|
|
10809
|
+
}
|
|
10810
|
+
return docSnap.data();
|
|
10811
|
+
}
|
|
10812
|
+
/**
|
|
10813
|
+
* Gets all reviews for a specific patient
|
|
10814
|
+
* @param patientId The ID of the patient
|
|
10815
|
+
* @returns Array of reviews for the patient
|
|
10816
|
+
*/
|
|
10817
|
+
async getReviewsByPatient(patientId) {
|
|
10818
|
+
const q = (0, import_firestore36.query)(
|
|
10819
|
+
(0, import_firestore36.collection)(this.db, REVIEWS_COLLECTION),
|
|
10820
|
+
(0, import_firestore36.where)("patientId", "==", patientId)
|
|
10821
|
+
);
|
|
10822
|
+
const snapshot = await (0, import_firestore36.getDocs)(q);
|
|
10823
|
+
return snapshot.docs.map((doc29) => doc29.data());
|
|
10824
|
+
}
|
|
10825
|
+
/**
|
|
10826
|
+
* Gets all reviews for a specific clinic
|
|
10827
|
+
* @param clinicId The ID of the clinic
|
|
10828
|
+
* @returns Array of reviews containing clinic reviews
|
|
10829
|
+
*/
|
|
10830
|
+
async getReviewsByClinic(clinicId) {
|
|
10831
|
+
const q = (0, import_firestore36.query)(
|
|
10832
|
+
(0, import_firestore36.collection)(this.db, REVIEWS_COLLECTION),
|
|
10833
|
+
(0, import_firestore36.where)("clinicReview.clinicId", "==", clinicId)
|
|
10834
|
+
);
|
|
10835
|
+
const snapshot = await (0, import_firestore36.getDocs)(q);
|
|
10836
|
+
return snapshot.docs.map((doc29) => doc29.data());
|
|
10837
|
+
}
|
|
10838
|
+
/**
|
|
10839
|
+
* Gets all reviews for a specific practitioner
|
|
10840
|
+
* @param practitionerId The ID of the practitioner
|
|
10841
|
+
* @returns Array of reviews containing practitioner reviews
|
|
10842
|
+
*/
|
|
10843
|
+
async getReviewsByPractitioner(practitionerId) {
|
|
10844
|
+
const q = (0, import_firestore36.query)(
|
|
10845
|
+
(0, import_firestore36.collection)(this.db, REVIEWS_COLLECTION),
|
|
10846
|
+
(0, import_firestore36.where)("practitionerReview.practitionerId", "==", practitionerId)
|
|
10847
|
+
);
|
|
10848
|
+
const snapshot = await (0, import_firestore36.getDocs)(q);
|
|
10849
|
+
return snapshot.docs.map((doc29) => doc29.data());
|
|
10850
|
+
}
|
|
10851
|
+
/**
|
|
10852
|
+
* Gets all reviews for a specific procedure
|
|
10853
|
+
* @param procedureId The ID of the procedure
|
|
10854
|
+
* @returns Array of reviews containing procedure reviews
|
|
10855
|
+
*/
|
|
10856
|
+
async getReviewsByProcedure(procedureId) {
|
|
10857
|
+
const q = (0, import_firestore36.query)(
|
|
10858
|
+
(0, import_firestore36.collection)(this.db, REVIEWS_COLLECTION),
|
|
10859
|
+
(0, import_firestore36.where)("procedureReview.procedureId", "==", procedureId)
|
|
10860
|
+
);
|
|
10861
|
+
const snapshot = await (0, import_firestore36.getDocs)(q);
|
|
10862
|
+
return snapshot.docs.map((doc29) => doc29.data());
|
|
10863
|
+
}
|
|
10864
|
+
/**
|
|
10865
|
+
* Gets all reviews for a specific appointment
|
|
10866
|
+
* @param appointmentId The ID of the appointment
|
|
10867
|
+
* @returns The review for the appointment if found, null otherwise
|
|
10868
|
+
*/
|
|
10869
|
+
async getReviewByAppointment(appointmentId) {
|
|
10870
|
+
const q = (0, import_firestore36.query)(
|
|
10871
|
+
(0, import_firestore36.collection)(this.db, REVIEWS_COLLECTION),
|
|
10872
|
+
(0, import_firestore36.where)("appointmentId", "==", appointmentId)
|
|
10873
|
+
);
|
|
10874
|
+
const snapshot = await (0, import_firestore36.getDocs)(q);
|
|
10875
|
+
if (snapshot.empty) {
|
|
10876
|
+
return null;
|
|
10877
|
+
}
|
|
10878
|
+
return snapshot.docs[0].data();
|
|
10879
|
+
}
|
|
10880
|
+
/**
|
|
10881
|
+
* Deletes a review and updates related entities
|
|
10882
|
+
* @param reviewId The ID of the review to delete
|
|
10883
|
+
*/
|
|
10884
|
+
async deleteReview(reviewId) {
|
|
10885
|
+
const review = await this.getReview(reviewId);
|
|
10886
|
+
if (!review) {
|
|
10887
|
+
throw new Error(`Review with ID ${reviewId} not found`);
|
|
10888
|
+
}
|
|
10889
|
+
await (0, import_firestore36.deleteDoc)((0, import_firestore36.doc)(this.db, REVIEWS_COLLECTION, reviewId));
|
|
10890
|
+
const updatePromises = [];
|
|
10891
|
+
if (review.clinicReview) {
|
|
10892
|
+
updatePromises.push(
|
|
10893
|
+
this.updateClinicReviewInfo(
|
|
10894
|
+
review.clinicReview.clinicId,
|
|
10895
|
+
review.clinicReview,
|
|
10896
|
+
true
|
|
10897
|
+
)
|
|
10898
|
+
);
|
|
10899
|
+
}
|
|
10900
|
+
if (review.practitionerReview) {
|
|
10901
|
+
updatePromises.push(
|
|
10902
|
+
this.updatePractitionerReviewInfo(
|
|
10903
|
+
review.practitionerReview.practitionerId,
|
|
10904
|
+
review.practitionerReview,
|
|
10905
|
+
true
|
|
10906
|
+
)
|
|
10907
|
+
);
|
|
10908
|
+
}
|
|
10909
|
+
if (review.procedureReview) {
|
|
10910
|
+
updatePromises.push(
|
|
10911
|
+
this.updateProcedureReviewInfo(
|
|
10912
|
+
review.procedureReview.procedureId,
|
|
10913
|
+
review.procedureReview,
|
|
10914
|
+
true
|
|
10915
|
+
)
|
|
10916
|
+
);
|
|
10917
|
+
}
|
|
10918
|
+
await Promise.all(updatePromises);
|
|
10919
|
+
}
|
|
10920
|
+
/**
|
|
10921
|
+
* Updates the review info for a clinic
|
|
10922
|
+
* @param clinicId The ID of the clinic to update
|
|
10923
|
+
* @param newReview Optional new review being added or removed
|
|
10924
|
+
* @param isRemoval Whether this update is for a review removal
|
|
10925
|
+
* @returns The updated clinic review info
|
|
10926
|
+
*/
|
|
10927
|
+
async updateClinicReviewInfo(clinicId, newReview, isRemoval = false) {
|
|
10928
|
+
const clinicDoc = await (0, import_firestore36.getDoc)((0, import_firestore36.doc)(this.db, CLINICS_COLLECTION, clinicId));
|
|
10929
|
+
if (!clinicDoc.exists()) {
|
|
10930
|
+
throw new Error(`Clinic with ID ${clinicId} not found`);
|
|
10931
|
+
}
|
|
10932
|
+
const clinicData = clinicDoc.data();
|
|
10933
|
+
const currentReviewInfo = clinicData.reviewInfo || {
|
|
10934
|
+
totalReviews: 0,
|
|
10935
|
+
averageRating: 0,
|
|
10936
|
+
cleanliness: 0,
|
|
10937
|
+
facilities: 0,
|
|
10938
|
+
staffFriendliness: 0,
|
|
10939
|
+
waitingTime: 0,
|
|
10940
|
+
accessibility: 0,
|
|
10941
|
+
recommendationPercentage: 0
|
|
10942
|
+
};
|
|
10943
|
+
if (currentReviewInfo.totalReviews === 0 && !newReview) {
|
|
10944
|
+
await (0, import_firestore36.updateDoc)((0, import_firestore36.doc)(this.db, CLINICS_COLLECTION, clinicId), {
|
|
10945
|
+
reviewInfo: currentReviewInfo,
|
|
10946
|
+
updatedAt: (0, import_firestore36.serverTimestamp)()
|
|
10947
|
+
});
|
|
10948
|
+
return currentReviewInfo;
|
|
10949
|
+
}
|
|
10950
|
+
let updatedReviewInfo;
|
|
10951
|
+
if (newReview) {
|
|
10952
|
+
const oldTotal = currentReviewInfo.totalReviews;
|
|
10953
|
+
const newTotal = isRemoval ? oldTotal - 1 : oldTotal + 1;
|
|
10954
|
+
if (newTotal === 0) {
|
|
10955
|
+
updatedReviewInfo = {
|
|
10956
|
+
totalReviews: 0,
|
|
10957
|
+
averageRating: 0,
|
|
10958
|
+
cleanliness: 0,
|
|
10959
|
+
facilities: 0,
|
|
10960
|
+
staffFriendliness: 0,
|
|
10961
|
+
waitingTime: 0,
|
|
10962
|
+
accessibility: 0,
|
|
10963
|
+
recommendationPercentage: 0
|
|
10964
|
+
};
|
|
10965
|
+
} else {
|
|
10966
|
+
const updateAverage = (currentAvg, newValue) => {
|
|
10967
|
+
const currentSum = currentAvg * oldTotal;
|
|
10968
|
+
const newSum = isRemoval ? currentSum - newValue : currentSum + newValue;
|
|
10969
|
+
const newAvg = newSum / newTotal;
|
|
10970
|
+
return Math.round(newAvg * 10) / 10;
|
|
10971
|
+
};
|
|
10972
|
+
const currentRecommendations = currentReviewInfo.recommendationPercentage / 100 * oldTotal;
|
|
10973
|
+
const newRecommendations = isRemoval ? newReview.wouldRecommend ? currentRecommendations - 1 : currentRecommendations : newReview.wouldRecommend ? currentRecommendations + 1 : currentRecommendations;
|
|
10974
|
+
const newRecommendationPercentage = newRecommendations / newTotal * 100;
|
|
10975
|
+
updatedReviewInfo = {
|
|
10976
|
+
totalReviews: newTotal,
|
|
10977
|
+
averageRating: updateAverage(
|
|
10978
|
+
currentReviewInfo.averageRating,
|
|
10979
|
+
newReview.overallRating
|
|
10980
|
+
),
|
|
10981
|
+
cleanliness: updateAverage(
|
|
10982
|
+
currentReviewInfo.cleanliness,
|
|
10983
|
+
newReview.cleanliness
|
|
10984
|
+
),
|
|
10985
|
+
facilities: updateAverage(
|
|
10986
|
+
currentReviewInfo.facilities,
|
|
10987
|
+
newReview.facilities
|
|
10988
|
+
),
|
|
10989
|
+
staffFriendliness: updateAverage(
|
|
10990
|
+
currentReviewInfo.staffFriendliness,
|
|
10991
|
+
newReview.staffFriendliness
|
|
10992
|
+
),
|
|
10993
|
+
waitingTime: updateAverage(
|
|
10994
|
+
currentReviewInfo.waitingTime,
|
|
10995
|
+
newReview.waitingTime
|
|
10996
|
+
),
|
|
10997
|
+
accessibility: updateAverage(
|
|
10998
|
+
currentReviewInfo.accessibility,
|
|
10999
|
+
newReview.accessibility
|
|
11000
|
+
),
|
|
11001
|
+
recommendationPercentage: Math.round(newRecommendationPercentage * 10) / 10
|
|
11002
|
+
};
|
|
11003
|
+
}
|
|
11004
|
+
} else {
|
|
11005
|
+
updatedReviewInfo = { ...currentReviewInfo };
|
|
11006
|
+
}
|
|
11007
|
+
await (0, import_firestore36.updateDoc)((0, import_firestore36.doc)(this.db, CLINICS_COLLECTION, clinicId), {
|
|
11008
|
+
reviewInfo: updatedReviewInfo,
|
|
11009
|
+
updatedAt: (0, import_firestore36.serverTimestamp)()
|
|
11010
|
+
});
|
|
11011
|
+
return updatedReviewInfo;
|
|
11012
|
+
}
|
|
11013
|
+
/**
|
|
11014
|
+
* Updates the review info for a practitioner
|
|
11015
|
+
* @param practitionerId The ID of the practitioner to update
|
|
11016
|
+
* @param newReview Optional new review being added or removed
|
|
11017
|
+
* @param isRemoval Whether this update is for a review removal
|
|
11018
|
+
* @returns The updated practitioner review info
|
|
11019
|
+
*/
|
|
11020
|
+
async updatePractitionerReviewInfo(practitionerId, newReview, isRemoval = false) {
|
|
11021
|
+
const practitionerDoc = await (0, import_firestore36.getDoc)(
|
|
11022
|
+
(0, import_firestore36.doc)(this.db, PRACTITIONERS_COLLECTION, practitionerId)
|
|
11023
|
+
);
|
|
11024
|
+
if (!practitionerDoc.exists()) {
|
|
11025
|
+
throw new Error(`Practitioner with ID ${practitionerId} not found`);
|
|
11026
|
+
}
|
|
11027
|
+
const practitionerData = practitionerDoc.data();
|
|
11028
|
+
const currentReviewInfo = practitionerData.reviewInfo || {
|
|
11029
|
+
totalReviews: 0,
|
|
11030
|
+
averageRating: 0,
|
|
11031
|
+
knowledgeAndExpertise: 0,
|
|
11032
|
+
communicationSkills: 0,
|
|
11033
|
+
bedSideManner: 0,
|
|
11034
|
+
thoroughness: 0,
|
|
11035
|
+
trustworthiness: 0,
|
|
11036
|
+
recommendationPercentage: 0
|
|
11037
|
+
};
|
|
11038
|
+
if (currentReviewInfo.totalReviews === 0 && !newReview) {
|
|
11039
|
+
await (0, import_firestore36.updateDoc)((0, import_firestore36.doc)(this.db, PRACTITIONERS_COLLECTION, practitionerId), {
|
|
11040
|
+
reviewInfo: currentReviewInfo,
|
|
11041
|
+
updatedAt: (0, import_firestore36.serverTimestamp)()
|
|
11042
|
+
});
|
|
11043
|
+
return currentReviewInfo;
|
|
11044
|
+
}
|
|
11045
|
+
let updatedReviewInfo;
|
|
11046
|
+
if (newReview) {
|
|
11047
|
+
const oldTotal = currentReviewInfo.totalReviews;
|
|
11048
|
+
const newTotal = isRemoval ? oldTotal - 1 : oldTotal + 1;
|
|
11049
|
+
if (newTotal === 0) {
|
|
11050
|
+
updatedReviewInfo = {
|
|
11051
|
+
totalReviews: 0,
|
|
11052
|
+
averageRating: 0,
|
|
11053
|
+
knowledgeAndExpertise: 0,
|
|
11054
|
+
communicationSkills: 0,
|
|
11055
|
+
bedSideManner: 0,
|
|
11056
|
+
thoroughness: 0,
|
|
11057
|
+
trustworthiness: 0,
|
|
11058
|
+
recommendationPercentage: 0
|
|
11059
|
+
};
|
|
11060
|
+
} else {
|
|
11061
|
+
const updateAverage = (currentAvg, newValue) => {
|
|
11062
|
+
const currentSum = currentAvg * oldTotal;
|
|
11063
|
+
const newSum = isRemoval ? currentSum - newValue : currentSum + newValue;
|
|
11064
|
+
const newAvg = newSum / newTotal;
|
|
11065
|
+
return Math.round(newAvg * 10) / 10;
|
|
11066
|
+
};
|
|
11067
|
+
const currentRecommendations = currentReviewInfo.recommendationPercentage / 100 * oldTotal;
|
|
11068
|
+
const newRecommendations = isRemoval ? newReview.wouldRecommend ? currentRecommendations - 1 : currentRecommendations : newReview.wouldRecommend ? currentRecommendations + 1 : currentRecommendations;
|
|
11069
|
+
const newRecommendationPercentage = newRecommendations / newTotal * 100;
|
|
11070
|
+
updatedReviewInfo = {
|
|
11071
|
+
totalReviews: newTotal,
|
|
11072
|
+
averageRating: updateAverage(
|
|
11073
|
+
currentReviewInfo.averageRating,
|
|
11074
|
+
newReview.overallRating
|
|
11075
|
+
),
|
|
11076
|
+
knowledgeAndExpertise: updateAverage(
|
|
11077
|
+
currentReviewInfo.knowledgeAndExpertise,
|
|
11078
|
+
newReview.knowledgeAndExpertise
|
|
11079
|
+
),
|
|
11080
|
+
communicationSkills: updateAverage(
|
|
11081
|
+
currentReviewInfo.communicationSkills,
|
|
11082
|
+
newReview.communicationSkills
|
|
11083
|
+
),
|
|
11084
|
+
bedSideManner: updateAverage(
|
|
11085
|
+
currentReviewInfo.bedSideManner,
|
|
11086
|
+
newReview.bedSideManner
|
|
11087
|
+
),
|
|
11088
|
+
thoroughness: updateAverage(
|
|
11089
|
+
currentReviewInfo.thoroughness,
|
|
11090
|
+
newReview.thoroughness
|
|
11091
|
+
),
|
|
11092
|
+
trustworthiness: updateAverage(
|
|
11093
|
+
currentReviewInfo.trustworthiness,
|
|
11094
|
+
newReview.trustworthiness
|
|
11095
|
+
),
|
|
11096
|
+
recommendationPercentage: Math.round(newRecommendationPercentage * 10) / 10
|
|
11097
|
+
};
|
|
11098
|
+
}
|
|
11099
|
+
} else {
|
|
11100
|
+
updatedReviewInfo = { ...currentReviewInfo };
|
|
11101
|
+
}
|
|
11102
|
+
await (0, import_firestore36.updateDoc)((0, import_firestore36.doc)(this.db, PRACTITIONERS_COLLECTION, practitionerId), {
|
|
11103
|
+
reviewInfo: updatedReviewInfo,
|
|
11104
|
+
updatedAt: (0, import_firestore36.serverTimestamp)()
|
|
11105
|
+
});
|
|
11106
|
+
await this.updateDoctorInfoInProcedures(
|
|
11107
|
+
practitionerId,
|
|
11108
|
+
updatedReviewInfo.averageRating
|
|
11109
|
+
);
|
|
11110
|
+
return updatedReviewInfo;
|
|
11111
|
+
}
|
|
11112
|
+
/**
|
|
11113
|
+
* Updates the review info for a procedure
|
|
11114
|
+
* @param procedureId The ID of the procedure to update
|
|
11115
|
+
* @param newReview Optional new review being added or removed
|
|
11116
|
+
* @param isRemoval Whether this update is for a review removal
|
|
11117
|
+
* @returns The updated procedure review info
|
|
11118
|
+
*/
|
|
11119
|
+
async updateProcedureReviewInfo(procedureId, newReview, isRemoval = false) {
|
|
11120
|
+
const procedureDoc = await (0, import_firestore36.getDoc)(
|
|
11121
|
+
(0, import_firestore36.doc)(this.db, PROCEDURES_COLLECTION, procedureId)
|
|
11122
|
+
);
|
|
11123
|
+
if (!procedureDoc.exists()) {
|
|
11124
|
+
throw new Error(`Procedure with ID ${procedureId} not found`);
|
|
11125
|
+
}
|
|
11126
|
+
const procedureData = procedureDoc.data();
|
|
11127
|
+
const currentReviewInfo = procedureData.reviewInfo || {
|
|
11128
|
+
totalReviews: 0,
|
|
11129
|
+
averageRating: 0,
|
|
11130
|
+
effectivenessOfTreatment: 0,
|
|
11131
|
+
outcomeExplanation: 0,
|
|
11132
|
+
painManagement: 0,
|
|
11133
|
+
followUpCare: 0,
|
|
11134
|
+
valueForMoney: 0,
|
|
11135
|
+
recommendationPercentage: 0
|
|
11136
|
+
};
|
|
11137
|
+
if (currentReviewInfo.totalReviews === 0 && !newReview) {
|
|
11138
|
+
await (0, import_firestore36.updateDoc)((0, import_firestore36.doc)(this.db, PROCEDURES_COLLECTION, procedureId), {
|
|
11139
|
+
reviewInfo: currentReviewInfo,
|
|
11140
|
+
updatedAt: (0, import_firestore36.serverTimestamp)()
|
|
11141
|
+
});
|
|
11142
|
+
return currentReviewInfo;
|
|
11143
|
+
}
|
|
11144
|
+
let updatedReviewInfo;
|
|
11145
|
+
if (newReview) {
|
|
11146
|
+
const oldTotal = currentReviewInfo.totalReviews;
|
|
11147
|
+
const newTotal = isRemoval ? oldTotal - 1 : oldTotal + 1;
|
|
11148
|
+
if (newTotal === 0) {
|
|
11149
|
+
updatedReviewInfo = {
|
|
11150
|
+
totalReviews: 0,
|
|
11151
|
+
averageRating: 0,
|
|
11152
|
+
effectivenessOfTreatment: 0,
|
|
11153
|
+
outcomeExplanation: 0,
|
|
11154
|
+
painManagement: 0,
|
|
11155
|
+
followUpCare: 0,
|
|
11156
|
+
valueForMoney: 0,
|
|
11157
|
+
recommendationPercentage: 0
|
|
11158
|
+
};
|
|
11159
|
+
} else {
|
|
11160
|
+
const updateAverage = (currentAvg, newValue) => {
|
|
11161
|
+
const currentSum = currentAvg * oldTotal;
|
|
11162
|
+
const newSum = isRemoval ? currentSum - newValue : currentSum + newValue;
|
|
11163
|
+
const newAvg = newSum / newTotal;
|
|
11164
|
+
return Math.round(newAvg * 10) / 10;
|
|
11165
|
+
};
|
|
11166
|
+
const currentRecommendations = currentReviewInfo.recommendationPercentage / 100 * oldTotal;
|
|
11167
|
+
const newRecommendations = isRemoval ? newReview.wouldRecommend ? currentRecommendations - 1 : currentRecommendations : newReview.wouldRecommend ? currentRecommendations + 1 : currentRecommendations;
|
|
11168
|
+
const newRecommendationPercentage = newRecommendations / newTotal * 100;
|
|
11169
|
+
updatedReviewInfo = {
|
|
11170
|
+
totalReviews: newTotal,
|
|
11171
|
+
averageRating: updateAverage(
|
|
11172
|
+
currentReviewInfo.averageRating,
|
|
11173
|
+
newReview.overallRating
|
|
11174
|
+
),
|
|
11175
|
+
effectivenessOfTreatment: updateAverage(
|
|
11176
|
+
currentReviewInfo.effectivenessOfTreatment,
|
|
11177
|
+
newReview.effectivenessOfTreatment
|
|
11178
|
+
),
|
|
11179
|
+
outcomeExplanation: updateAverage(
|
|
11180
|
+
currentReviewInfo.outcomeExplanation,
|
|
11181
|
+
newReview.outcomeExplanation
|
|
11182
|
+
),
|
|
11183
|
+
painManagement: updateAverage(
|
|
11184
|
+
currentReviewInfo.painManagement,
|
|
11185
|
+
newReview.painManagement
|
|
11186
|
+
),
|
|
11187
|
+
followUpCare: updateAverage(
|
|
11188
|
+
currentReviewInfo.followUpCare,
|
|
11189
|
+
newReview.followUpCare
|
|
11190
|
+
),
|
|
11191
|
+
valueForMoney: updateAverage(
|
|
11192
|
+
currentReviewInfo.valueForMoney,
|
|
11193
|
+
newReview.valueForMoney
|
|
11194
|
+
),
|
|
11195
|
+
recommendationPercentage: Math.round(newRecommendationPercentage * 10) / 10
|
|
11196
|
+
};
|
|
11197
|
+
}
|
|
11198
|
+
} else {
|
|
11199
|
+
updatedReviewInfo = { ...currentReviewInfo };
|
|
11200
|
+
}
|
|
11201
|
+
await (0, import_firestore36.updateDoc)((0, import_firestore36.doc)(this.db, PROCEDURES_COLLECTION, procedureId), {
|
|
11202
|
+
reviewInfo: updatedReviewInfo,
|
|
11203
|
+
updatedAt: (0, import_firestore36.serverTimestamp)()
|
|
11204
|
+
});
|
|
11205
|
+
return updatedReviewInfo;
|
|
11206
|
+
}
|
|
11207
|
+
/**
|
|
11208
|
+
* Updates doctorInfo rating in all procedures for a practitioner
|
|
11209
|
+
* @param practitionerId The ID of the practitioner
|
|
11210
|
+
* @param rating The new rating to set
|
|
11211
|
+
*/
|
|
11212
|
+
async updateDoctorInfoInProcedures(practitionerId, rating) {
|
|
11213
|
+
const q = (0, import_firestore36.query)(
|
|
11214
|
+
(0, import_firestore36.collection)(this.db, PROCEDURES_COLLECTION),
|
|
11215
|
+
(0, import_firestore36.where)("practitionerId", "==", practitionerId)
|
|
11216
|
+
);
|
|
11217
|
+
const snapshot = await (0, import_firestore36.getDocs)(q);
|
|
11218
|
+
if (snapshot.empty) {
|
|
11219
|
+
return;
|
|
11220
|
+
}
|
|
11221
|
+
const batch = (0, import_firestore36.writeBatch)(this.db);
|
|
11222
|
+
snapshot.docs.forEach((docSnapshot) => {
|
|
11223
|
+
const procedureRef = (0, import_firestore36.doc)(this.db, PROCEDURES_COLLECTION, docSnapshot.id);
|
|
11224
|
+
batch.update(procedureRef, {
|
|
11225
|
+
"doctorInfo.rating": rating,
|
|
11226
|
+
updatedAt: (0, import_firestore36.serverTimestamp)()
|
|
11227
|
+
});
|
|
11228
|
+
});
|
|
11229
|
+
await batch.commit();
|
|
11230
|
+
}
|
|
11231
|
+
/**
|
|
11232
|
+
* Verifies a review as checked by admin/staff
|
|
11233
|
+
* @param reviewId The ID of the review to verify
|
|
11234
|
+
*/
|
|
11235
|
+
async verifyReview(reviewId) {
|
|
11236
|
+
const review = await this.getReview(reviewId);
|
|
11237
|
+
if (!review) {
|
|
11238
|
+
throw new Error(`Review with ID ${reviewId} not found`);
|
|
11239
|
+
}
|
|
11240
|
+
const batch = (0, import_firestore36.writeBatch)(this.db);
|
|
11241
|
+
batch.update((0, import_firestore36.doc)(this.db, REVIEWS_COLLECTION, reviewId), {
|
|
11242
|
+
updatedAt: (0, import_firestore36.serverTimestamp)()
|
|
11243
|
+
});
|
|
11244
|
+
if (review.clinicReview) {
|
|
11245
|
+
review.clinicReview.isVerified = true;
|
|
11246
|
+
}
|
|
11247
|
+
if (review.practitionerReview) {
|
|
11248
|
+
review.practitionerReview.isVerified = true;
|
|
11249
|
+
}
|
|
11250
|
+
if (review.procedureReview) {
|
|
11251
|
+
review.procedureReview.isVerified = true;
|
|
11252
|
+
}
|
|
11253
|
+
await batch.commit();
|
|
11254
|
+
const updatePromises = [];
|
|
11255
|
+
if (review.clinicReview) {
|
|
11256
|
+
updatePromises.push(
|
|
11257
|
+
this.updateClinicReviewInfo(review.clinicReview.clinicId)
|
|
11258
|
+
);
|
|
11259
|
+
}
|
|
11260
|
+
if (review.practitionerReview) {
|
|
11261
|
+
updatePromises.push(
|
|
11262
|
+
this.updatePractitionerReviewInfo(
|
|
11263
|
+
review.practitionerReview.practitionerId
|
|
11264
|
+
)
|
|
11265
|
+
);
|
|
11266
|
+
}
|
|
11267
|
+
if (review.procedureReview) {
|
|
11268
|
+
updatePromises.push(
|
|
11269
|
+
this.updateProcedureReviewInfo(review.procedureReview.procedureId)
|
|
11270
|
+
);
|
|
11271
|
+
}
|
|
11272
|
+
await Promise.all(updatePromises);
|
|
11273
|
+
}
|
|
11274
|
+
/**
|
|
11275
|
+
* Calculates the average of an array of numbers
|
|
11276
|
+
* @param numbers Array of numbers to average
|
|
11277
|
+
* @returns The average, or 0 if the array is empty
|
|
11278
|
+
*/
|
|
11279
|
+
calculateAverage(numbers) {
|
|
11280
|
+
if (numbers.length === 0) {
|
|
11281
|
+
return 0;
|
|
11282
|
+
}
|
|
11283
|
+
const sum = numbers.reduce((a, b) => a + b, 0);
|
|
11284
|
+
const avg = sum / numbers.length;
|
|
11285
|
+
return Math.round(avg * 10) / 10;
|
|
11286
|
+
}
|
|
11287
|
+
};
|
|
11288
|
+
|
|
11289
|
+
// src/backoffice/services/brand.service.ts
|
|
11290
|
+
var import_firestore37 = require("firebase/firestore");
|
|
11291
|
+
|
|
10626
11292
|
// src/backoffice/types/brand.types.ts
|
|
10627
11293
|
var BRANDS_COLLECTION = "brands";
|
|
10628
11294
|
|
|
@@ -10632,7 +11298,7 @@ var BrandService = class extends BaseService {
|
|
|
10632
11298
|
* Gets reference to brands collection
|
|
10633
11299
|
*/
|
|
10634
11300
|
getBrandsRef() {
|
|
10635
|
-
return (0,
|
|
11301
|
+
return (0, import_firestore37.collection)(this.db, BRANDS_COLLECTION);
|
|
10636
11302
|
}
|
|
10637
11303
|
/**
|
|
10638
11304
|
* Creates a new brand
|
|
@@ -10645,19 +11311,19 @@ var BrandService = class extends BaseService {
|
|
|
10645
11311
|
updatedAt: now,
|
|
10646
11312
|
isActive: true
|
|
10647
11313
|
};
|
|
10648
|
-
const docRef = await (0,
|
|
11314
|
+
const docRef = await (0, import_firestore37.addDoc)(this.getBrandsRef(), newBrand);
|
|
10649
11315
|
return { id: docRef.id, ...newBrand };
|
|
10650
11316
|
}
|
|
10651
11317
|
/**
|
|
10652
11318
|
* Gets all active brands
|
|
10653
11319
|
*/
|
|
10654
11320
|
async getAll() {
|
|
10655
|
-
const q = (0,
|
|
10656
|
-
const snapshot = await (0,
|
|
11321
|
+
const q = (0, import_firestore37.query)(this.getBrandsRef(), (0, import_firestore37.where)("isActive", "==", true));
|
|
11322
|
+
const snapshot = await (0, import_firestore37.getDocs)(q);
|
|
10657
11323
|
return snapshot.docs.map(
|
|
10658
|
-
(
|
|
10659
|
-
id:
|
|
10660
|
-
...
|
|
11324
|
+
(doc29) => ({
|
|
11325
|
+
id: doc29.id,
|
|
11326
|
+
...doc29.data()
|
|
10661
11327
|
})
|
|
10662
11328
|
);
|
|
10663
11329
|
}
|
|
@@ -10669,8 +11335,8 @@ var BrandService = class extends BaseService {
|
|
|
10669
11335
|
...brand,
|
|
10670
11336
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10671
11337
|
};
|
|
10672
|
-
const docRef = (0,
|
|
10673
|
-
await (0,
|
|
11338
|
+
const docRef = (0, import_firestore37.doc)(this.getBrandsRef(), brandId);
|
|
11339
|
+
await (0, import_firestore37.updateDoc)(docRef, updateData);
|
|
10674
11340
|
return this.getById(brandId);
|
|
10675
11341
|
}
|
|
10676
11342
|
/**
|
|
@@ -10685,8 +11351,8 @@ var BrandService = class extends BaseService {
|
|
|
10685
11351
|
* Gets a brand by ID
|
|
10686
11352
|
*/
|
|
10687
11353
|
async getById(brandId) {
|
|
10688
|
-
const docRef = (0,
|
|
10689
|
-
const docSnap = await (0,
|
|
11354
|
+
const docRef = (0, import_firestore37.doc)(this.getBrandsRef(), brandId);
|
|
11355
|
+
const docSnap = await (0, import_firestore37.getDoc)(docRef);
|
|
10690
11356
|
if (!docSnap.exists()) return null;
|
|
10691
11357
|
return {
|
|
10692
11358
|
id: docSnap.id,
|
|
@@ -10696,7 +11362,7 @@ var BrandService = class extends BaseService {
|
|
|
10696
11362
|
};
|
|
10697
11363
|
|
|
10698
11364
|
// src/backoffice/services/category.service.ts
|
|
10699
|
-
var
|
|
11365
|
+
var import_firestore38 = require("firebase/firestore");
|
|
10700
11366
|
|
|
10701
11367
|
// src/backoffice/types/category.types.ts
|
|
10702
11368
|
var CATEGORIES_COLLECTION = "backoffice_categories";
|
|
@@ -10707,7 +11373,7 @@ var CategoryService = class extends BaseService {
|
|
|
10707
11373
|
* Referenca na Firestore kolekciju kategorija
|
|
10708
11374
|
*/
|
|
10709
11375
|
get categoriesRef() {
|
|
10710
|
-
return (0,
|
|
11376
|
+
return (0, import_firestore38.collection)(this.db, CATEGORIES_COLLECTION);
|
|
10711
11377
|
}
|
|
10712
11378
|
/**
|
|
10713
11379
|
* Kreira novu kategoriju u sistemu
|
|
@@ -10722,7 +11388,7 @@ var CategoryService = class extends BaseService {
|
|
|
10722
11388
|
updatedAt: now,
|
|
10723
11389
|
isActive: true
|
|
10724
11390
|
};
|
|
10725
|
-
const docRef = await (0,
|
|
11391
|
+
const docRef = await (0, import_firestore38.addDoc)(this.categoriesRef, newCategory);
|
|
10726
11392
|
return { id: docRef.id, ...newCategory };
|
|
10727
11393
|
}
|
|
10728
11394
|
/**
|
|
@@ -10730,12 +11396,12 @@ var CategoryService = class extends BaseService {
|
|
|
10730
11396
|
* @returns Lista aktivnih kategorija
|
|
10731
11397
|
*/
|
|
10732
11398
|
async getAll() {
|
|
10733
|
-
const q = (0,
|
|
10734
|
-
const snapshot = await (0,
|
|
11399
|
+
const q = (0, import_firestore38.query)(this.categoriesRef, (0, import_firestore38.where)("isActive", "==", true));
|
|
11400
|
+
const snapshot = await (0, import_firestore38.getDocs)(q);
|
|
10735
11401
|
return snapshot.docs.map(
|
|
10736
|
-
(
|
|
10737
|
-
id:
|
|
10738
|
-
...
|
|
11402
|
+
(doc29) => ({
|
|
11403
|
+
id: doc29.id,
|
|
11404
|
+
...doc29.data()
|
|
10739
11405
|
})
|
|
10740
11406
|
);
|
|
10741
11407
|
}
|
|
@@ -10745,16 +11411,16 @@ var CategoryService = class extends BaseService {
|
|
|
10745
11411
|
* @returns Lista kategorija koje pripadaju traženoj familiji
|
|
10746
11412
|
*/
|
|
10747
11413
|
async getAllByFamily(family) {
|
|
10748
|
-
const q = (0,
|
|
11414
|
+
const q = (0, import_firestore38.query)(
|
|
10749
11415
|
this.categoriesRef,
|
|
10750
|
-
(0,
|
|
10751
|
-
(0,
|
|
11416
|
+
(0, import_firestore38.where)("family", "==", family),
|
|
11417
|
+
(0, import_firestore38.where)("isActive", "==", true)
|
|
10752
11418
|
);
|
|
10753
|
-
const snapshot = await (0,
|
|
11419
|
+
const snapshot = await (0, import_firestore38.getDocs)(q);
|
|
10754
11420
|
return snapshot.docs.map(
|
|
10755
|
-
(
|
|
10756
|
-
id:
|
|
10757
|
-
...
|
|
11421
|
+
(doc29) => ({
|
|
11422
|
+
id: doc29.id,
|
|
11423
|
+
...doc29.data()
|
|
10758
11424
|
})
|
|
10759
11425
|
);
|
|
10760
11426
|
}
|
|
@@ -10769,8 +11435,8 @@ var CategoryService = class extends BaseService {
|
|
|
10769
11435
|
...category,
|
|
10770
11436
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10771
11437
|
};
|
|
10772
|
-
const docRef = (0,
|
|
10773
|
-
await (0,
|
|
11438
|
+
const docRef = (0, import_firestore38.doc)(this.categoriesRef, id);
|
|
11439
|
+
await (0, import_firestore38.updateDoc)(docRef, updateData);
|
|
10774
11440
|
return this.getById(id);
|
|
10775
11441
|
}
|
|
10776
11442
|
/**
|
|
@@ -10786,8 +11452,8 @@ var CategoryService = class extends BaseService {
|
|
|
10786
11452
|
* @returns Kategorija ili null ako ne postoji
|
|
10787
11453
|
*/
|
|
10788
11454
|
async getById(id) {
|
|
10789
|
-
const docRef = (0,
|
|
10790
|
-
const docSnap = await (0,
|
|
11455
|
+
const docRef = (0, import_firestore38.doc)(this.categoriesRef, id);
|
|
11456
|
+
const docSnap = await (0, import_firestore38.getDoc)(docRef);
|
|
10791
11457
|
if (!docSnap.exists()) return null;
|
|
10792
11458
|
return {
|
|
10793
11459
|
id: docSnap.id,
|
|
@@ -10797,7 +11463,7 @@ var CategoryService = class extends BaseService {
|
|
|
10797
11463
|
};
|
|
10798
11464
|
|
|
10799
11465
|
// src/backoffice/services/subcategory.service.ts
|
|
10800
|
-
var
|
|
11466
|
+
var import_firestore39 = require("firebase/firestore");
|
|
10801
11467
|
|
|
10802
11468
|
// src/backoffice/types/subcategory.types.ts
|
|
10803
11469
|
var SUBCATEGORIES_COLLECTION = "subcategories";
|
|
@@ -10809,7 +11475,7 @@ var SubcategoryService = class extends BaseService {
|
|
|
10809
11475
|
* @param categoryId - ID roditeljske kategorije
|
|
10810
11476
|
*/
|
|
10811
11477
|
getSubcategoriesRef(categoryId) {
|
|
10812
|
-
return (0,
|
|
11478
|
+
return (0, import_firestore39.collection)(
|
|
10813
11479
|
this.db,
|
|
10814
11480
|
CATEGORIES_COLLECTION,
|
|
10815
11481
|
categoryId,
|
|
@@ -10831,7 +11497,7 @@ var SubcategoryService = class extends BaseService {
|
|
|
10831
11497
|
updatedAt: now,
|
|
10832
11498
|
isActive: true
|
|
10833
11499
|
};
|
|
10834
|
-
const docRef = await (0,
|
|
11500
|
+
const docRef = await (0, import_firestore39.addDoc)(
|
|
10835
11501
|
this.getSubcategoriesRef(categoryId),
|
|
10836
11502
|
newSubcategory
|
|
10837
11503
|
);
|
|
@@ -10843,15 +11509,15 @@ var SubcategoryService = class extends BaseService {
|
|
|
10843
11509
|
* @returns Lista aktivnih podkategorija
|
|
10844
11510
|
*/
|
|
10845
11511
|
async getAllByCategoryId(categoryId) {
|
|
10846
|
-
const q = (0,
|
|
11512
|
+
const q = (0, import_firestore39.query)(
|
|
10847
11513
|
this.getSubcategoriesRef(categoryId),
|
|
10848
|
-
(0,
|
|
11514
|
+
(0, import_firestore39.where)("isActive", "==", true)
|
|
10849
11515
|
);
|
|
10850
|
-
const snapshot = await (0,
|
|
11516
|
+
const snapshot = await (0, import_firestore39.getDocs)(q);
|
|
10851
11517
|
return snapshot.docs.map(
|
|
10852
|
-
(
|
|
10853
|
-
id:
|
|
10854
|
-
...
|
|
11518
|
+
(doc29) => ({
|
|
11519
|
+
id: doc29.id,
|
|
11520
|
+
...doc29.data()
|
|
10855
11521
|
})
|
|
10856
11522
|
);
|
|
10857
11523
|
}
|
|
@@ -10867,8 +11533,8 @@ var SubcategoryService = class extends BaseService {
|
|
|
10867
11533
|
...subcategory,
|
|
10868
11534
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10869
11535
|
};
|
|
10870
|
-
const docRef = (0,
|
|
10871
|
-
await (0,
|
|
11536
|
+
const docRef = (0, import_firestore39.doc)(this.getSubcategoriesRef(categoryId), subcategoryId);
|
|
11537
|
+
await (0, import_firestore39.updateDoc)(docRef, updateData);
|
|
10872
11538
|
return this.getById(categoryId, subcategoryId);
|
|
10873
11539
|
}
|
|
10874
11540
|
/**
|
|
@@ -10886,8 +11552,8 @@ var SubcategoryService = class extends BaseService {
|
|
|
10886
11552
|
* @returns Podkategorija ili null ako ne postoji
|
|
10887
11553
|
*/
|
|
10888
11554
|
async getById(categoryId, subcategoryId) {
|
|
10889
|
-
const docRef = (0,
|
|
10890
|
-
const docSnap = await (0,
|
|
11555
|
+
const docRef = (0, import_firestore39.doc)(this.getSubcategoriesRef(categoryId), subcategoryId);
|
|
11556
|
+
const docSnap = await (0, import_firestore39.getDoc)(docRef);
|
|
10891
11557
|
if (!docSnap.exists()) return null;
|
|
10892
11558
|
return {
|
|
10893
11559
|
id: docSnap.id,
|
|
@@ -10897,7 +11563,7 @@ var SubcategoryService = class extends BaseService {
|
|
|
10897
11563
|
};
|
|
10898
11564
|
|
|
10899
11565
|
// src/backoffice/services/technology.service.ts
|
|
10900
|
-
var
|
|
11566
|
+
var import_firestore40 = require("firebase/firestore");
|
|
10901
11567
|
|
|
10902
11568
|
// src/backoffice/types/technology.types.ts
|
|
10903
11569
|
var TECHNOLOGIES_COLLECTION = "technologies";
|
|
@@ -10912,7 +11578,7 @@ var TechnologyService = class extends BaseService {
|
|
|
10912
11578
|
* Vraća referencu na Firestore kolekciju tehnologija
|
|
10913
11579
|
*/
|
|
10914
11580
|
getTechnologiesRef() {
|
|
10915
|
-
return (0,
|
|
11581
|
+
return (0, import_firestore40.collection)(this.db, TECHNOLOGIES_COLLECTION);
|
|
10916
11582
|
}
|
|
10917
11583
|
/**
|
|
10918
11584
|
* Kreira novu tehnologiju
|
|
@@ -10935,7 +11601,7 @@ var TechnologyService = class extends BaseService {
|
|
|
10935
11601
|
benefits: technology.benefits || [],
|
|
10936
11602
|
certificationRequirement: technology.certificationRequirement || DEFAULT_CERTIFICATION_REQUIREMENT
|
|
10937
11603
|
};
|
|
10938
|
-
const docRef = await (0,
|
|
11604
|
+
const docRef = await (0, import_firestore40.addDoc)(this.getTechnologiesRef(), newTechnology);
|
|
10939
11605
|
return { id: docRef.id, ...newTechnology };
|
|
10940
11606
|
}
|
|
10941
11607
|
/**
|
|
@@ -10943,12 +11609,12 @@ var TechnologyService = class extends BaseService {
|
|
|
10943
11609
|
* @returns Lista aktivnih tehnologija
|
|
10944
11610
|
*/
|
|
10945
11611
|
async getAll() {
|
|
10946
|
-
const q = (0,
|
|
10947
|
-
const snapshot = await (0,
|
|
11612
|
+
const q = (0, import_firestore40.query)(this.getTechnologiesRef(), (0, import_firestore40.where)("isActive", "==", true));
|
|
11613
|
+
const snapshot = await (0, import_firestore40.getDocs)(q);
|
|
10948
11614
|
return snapshot.docs.map(
|
|
10949
|
-
(
|
|
10950
|
-
id:
|
|
10951
|
-
...
|
|
11615
|
+
(doc29) => ({
|
|
11616
|
+
id: doc29.id,
|
|
11617
|
+
...doc29.data()
|
|
10952
11618
|
})
|
|
10953
11619
|
);
|
|
10954
11620
|
}
|
|
@@ -10958,16 +11624,16 @@ var TechnologyService = class extends BaseService {
|
|
|
10958
11624
|
* @returns Lista aktivnih tehnologija
|
|
10959
11625
|
*/
|
|
10960
11626
|
async getAllByFamily(family) {
|
|
10961
|
-
const q = (0,
|
|
11627
|
+
const q = (0, import_firestore40.query)(
|
|
10962
11628
|
this.getTechnologiesRef(),
|
|
10963
|
-
(0,
|
|
10964
|
-
(0,
|
|
11629
|
+
(0, import_firestore40.where)("isActive", "==", true),
|
|
11630
|
+
(0, import_firestore40.where)("family", "==", family)
|
|
10965
11631
|
);
|
|
10966
|
-
const snapshot = await (0,
|
|
11632
|
+
const snapshot = await (0, import_firestore40.getDocs)(q);
|
|
10967
11633
|
return snapshot.docs.map(
|
|
10968
|
-
(
|
|
10969
|
-
id:
|
|
10970
|
-
...
|
|
11634
|
+
(doc29) => ({
|
|
11635
|
+
id: doc29.id,
|
|
11636
|
+
...doc29.data()
|
|
10971
11637
|
})
|
|
10972
11638
|
);
|
|
10973
11639
|
}
|
|
@@ -10977,16 +11643,16 @@ var TechnologyService = class extends BaseService {
|
|
|
10977
11643
|
* @returns Lista aktivnih tehnologija
|
|
10978
11644
|
*/
|
|
10979
11645
|
async getAllByCategoryId(categoryId) {
|
|
10980
|
-
const q = (0,
|
|
11646
|
+
const q = (0, import_firestore40.query)(
|
|
10981
11647
|
this.getTechnologiesRef(),
|
|
10982
|
-
(0,
|
|
10983
|
-
(0,
|
|
11648
|
+
(0, import_firestore40.where)("isActive", "==", true),
|
|
11649
|
+
(0, import_firestore40.where)("categoryId", "==", categoryId)
|
|
10984
11650
|
);
|
|
10985
|
-
const snapshot = await (0,
|
|
11651
|
+
const snapshot = await (0, import_firestore40.getDocs)(q);
|
|
10986
11652
|
return snapshot.docs.map(
|
|
10987
|
-
(
|
|
10988
|
-
id:
|
|
10989
|
-
...
|
|
11653
|
+
(doc29) => ({
|
|
11654
|
+
id: doc29.id,
|
|
11655
|
+
...doc29.data()
|
|
10990
11656
|
})
|
|
10991
11657
|
);
|
|
10992
11658
|
}
|
|
@@ -10996,16 +11662,16 @@ var TechnologyService = class extends BaseService {
|
|
|
10996
11662
|
* @returns Lista aktivnih tehnologija
|
|
10997
11663
|
*/
|
|
10998
11664
|
async getAllBySubcategoryId(subcategoryId) {
|
|
10999
|
-
const q = (0,
|
|
11665
|
+
const q = (0, import_firestore40.query)(
|
|
11000
11666
|
this.getTechnologiesRef(),
|
|
11001
|
-
(0,
|
|
11002
|
-
(0,
|
|
11667
|
+
(0, import_firestore40.where)("isActive", "==", true),
|
|
11668
|
+
(0, import_firestore40.where)("subcategoryId", "==", subcategoryId)
|
|
11003
11669
|
);
|
|
11004
|
-
const snapshot = await (0,
|
|
11670
|
+
const snapshot = await (0, import_firestore40.getDocs)(q);
|
|
11005
11671
|
return snapshot.docs.map(
|
|
11006
|
-
(
|
|
11007
|
-
id:
|
|
11008
|
-
...
|
|
11672
|
+
(doc29) => ({
|
|
11673
|
+
id: doc29.id,
|
|
11674
|
+
...doc29.data()
|
|
11009
11675
|
})
|
|
11010
11676
|
);
|
|
11011
11677
|
}
|
|
@@ -11020,8 +11686,8 @@ var TechnologyService = class extends BaseService {
|
|
|
11020
11686
|
...technology,
|
|
11021
11687
|
updatedAt: /* @__PURE__ */ new Date()
|
|
11022
11688
|
};
|
|
11023
|
-
const docRef = (0,
|
|
11024
|
-
await (0,
|
|
11689
|
+
const docRef = (0, import_firestore40.doc)(this.getTechnologiesRef(), technologyId);
|
|
11690
|
+
await (0, import_firestore40.updateDoc)(docRef, updateData);
|
|
11025
11691
|
return this.getById(technologyId);
|
|
11026
11692
|
}
|
|
11027
11693
|
/**
|
|
@@ -11039,8 +11705,8 @@ var TechnologyService = class extends BaseService {
|
|
|
11039
11705
|
* @returns Tehnologija ili null ako ne postoji
|
|
11040
11706
|
*/
|
|
11041
11707
|
async getById(technologyId) {
|
|
11042
|
-
const docRef = (0,
|
|
11043
|
-
const docSnap = await (0,
|
|
11708
|
+
const docRef = (0, import_firestore40.doc)(this.getTechnologiesRef(), technologyId);
|
|
11709
|
+
const docSnap = await (0, import_firestore40.getDoc)(docRef);
|
|
11044
11710
|
if (!docSnap.exists()) return null;
|
|
11045
11711
|
return {
|
|
11046
11712
|
id: docSnap.id,
|
|
@@ -11054,10 +11720,10 @@ var TechnologyService = class extends BaseService {
|
|
|
11054
11720
|
* @returns Ažurirana tehnologija sa novim zahtevom
|
|
11055
11721
|
*/
|
|
11056
11722
|
async addRequirement(technologyId, requirement) {
|
|
11057
|
-
const docRef = (0,
|
|
11723
|
+
const docRef = (0, import_firestore40.doc)(this.getTechnologiesRef(), technologyId);
|
|
11058
11724
|
const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
|
|
11059
|
-
await (0,
|
|
11060
|
-
[requirementType]: (0,
|
|
11725
|
+
await (0, import_firestore40.updateDoc)(docRef, {
|
|
11726
|
+
[requirementType]: (0, import_firestore40.arrayUnion)(requirement),
|
|
11061
11727
|
updatedAt: /* @__PURE__ */ new Date()
|
|
11062
11728
|
});
|
|
11063
11729
|
return this.getById(technologyId);
|
|
@@ -11069,10 +11735,10 @@ var TechnologyService = class extends BaseService {
|
|
|
11069
11735
|
* @returns Ažurirana tehnologija bez uklonjenog zahteva
|
|
11070
11736
|
*/
|
|
11071
11737
|
async removeRequirement(technologyId, requirement) {
|
|
11072
|
-
const docRef = (0,
|
|
11738
|
+
const docRef = (0, import_firestore40.doc)(this.getTechnologiesRef(), technologyId);
|
|
11073
11739
|
const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
|
|
11074
|
-
await (0,
|
|
11075
|
-
[requirementType]: (0,
|
|
11740
|
+
await (0, import_firestore40.updateDoc)(docRef, {
|
|
11741
|
+
[requirementType]: (0, import_firestore40.arrayRemove)(requirement),
|
|
11076
11742
|
updatedAt: /* @__PURE__ */ new Date()
|
|
11077
11743
|
});
|
|
11078
11744
|
return this.getById(technologyId);
|
|
@@ -11109,9 +11775,9 @@ var TechnologyService = class extends BaseService {
|
|
|
11109
11775
|
* @returns Ažurirana tehnologija
|
|
11110
11776
|
*/
|
|
11111
11777
|
async addBlockingCondition(technologyId, condition) {
|
|
11112
|
-
const docRef = (0,
|
|
11113
|
-
await (0,
|
|
11114
|
-
blockingConditions: (0,
|
|
11778
|
+
const docRef = (0, import_firestore40.doc)(this.getTechnologiesRef(), technologyId);
|
|
11779
|
+
await (0, import_firestore40.updateDoc)(docRef, {
|
|
11780
|
+
blockingConditions: (0, import_firestore40.arrayUnion)(condition),
|
|
11115
11781
|
updatedAt: /* @__PURE__ */ new Date()
|
|
11116
11782
|
});
|
|
11117
11783
|
return this.getById(technologyId);
|
|
@@ -11123,9 +11789,9 @@ var TechnologyService = class extends BaseService {
|
|
|
11123
11789
|
* @returns Ažurirana tehnologija
|
|
11124
11790
|
*/
|
|
11125
11791
|
async removeBlockingCondition(technologyId, condition) {
|
|
11126
|
-
const docRef = (0,
|
|
11127
|
-
await (0,
|
|
11128
|
-
blockingConditions: (0,
|
|
11792
|
+
const docRef = (0, import_firestore40.doc)(this.getTechnologiesRef(), technologyId);
|
|
11793
|
+
await (0, import_firestore40.updateDoc)(docRef, {
|
|
11794
|
+
blockingConditions: (0, import_firestore40.arrayRemove)(condition),
|
|
11129
11795
|
updatedAt: /* @__PURE__ */ new Date()
|
|
11130
11796
|
});
|
|
11131
11797
|
return this.getById(technologyId);
|
|
@@ -11137,9 +11803,9 @@ var TechnologyService = class extends BaseService {
|
|
|
11137
11803
|
* @returns Ažurirana tehnologija
|
|
11138
11804
|
*/
|
|
11139
11805
|
async addContraindication(technologyId, contraindication) {
|
|
11140
|
-
const docRef = (0,
|
|
11141
|
-
await (0,
|
|
11142
|
-
contraindications: (0,
|
|
11806
|
+
const docRef = (0, import_firestore40.doc)(this.getTechnologiesRef(), technologyId);
|
|
11807
|
+
await (0, import_firestore40.updateDoc)(docRef, {
|
|
11808
|
+
contraindications: (0, import_firestore40.arrayUnion)(contraindication),
|
|
11143
11809
|
updatedAt: /* @__PURE__ */ new Date()
|
|
11144
11810
|
});
|
|
11145
11811
|
return this.getById(technologyId);
|
|
@@ -11151,9 +11817,9 @@ var TechnologyService = class extends BaseService {
|
|
|
11151
11817
|
* @returns Ažurirana tehnologija
|
|
11152
11818
|
*/
|
|
11153
11819
|
async removeContraindication(technologyId, contraindication) {
|
|
11154
|
-
const docRef = (0,
|
|
11155
|
-
await (0,
|
|
11156
|
-
contraindications: (0,
|
|
11820
|
+
const docRef = (0, import_firestore40.doc)(this.getTechnologiesRef(), technologyId);
|
|
11821
|
+
await (0, import_firestore40.updateDoc)(docRef, {
|
|
11822
|
+
contraindications: (0, import_firestore40.arrayRemove)(contraindication),
|
|
11157
11823
|
updatedAt: /* @__PURE__ */ new Date()
|
|
11158
11824
|
});
|
|
11159
11825
|
return this.getById(technologyId);
|
|
@@ -11165,9 +11831,9 @@ var TechnologyService = class extends BaseService {
|
|
|
11165
11831
|
* @returns Ažurirana tehnologija
|
|
11166
11832
|
*/
|
|
11167
11833
|
async addBenefit(technologyId, benefit) {
|
|
11168
|
-
const docRef = (0,
|
|
11169
|
-
await (0,
|
|
11170
|
-
benefits: (0,
|
|
11834
|
+
const docRef = (0, import_firestore40.doc)(this.getTechnologiesRef(), technologyId);
|
|
11835
|
+
await (0, import_firestore40.updateDoc)(docRef, {
|
|
11836
|
+
benefits: (0, import_firestore40.arrayUnion)(benefit),
|
|
11171
11837
|
updatedAt: /* @__PURE__ */ new Date()
|
|
11172
11838
|
});
|
|
11173
11839
|
return this.getById(technologyId);
|
|
@@ -11179,9 +11845,9 @@ var TechnologyService = class extends BaseService {
|
|
|
11179
11845
|
* @returns Ažurirana tehnologija
|
|
11180
11846
|
*/
|
|
11181
11847
|
async removeBenefit(technologyId, benefit) {
|
|
11182
|
-
const docRef = (0,
|
|
11183
|
-
await (0,
|
|
11184
|
-
benefits: (0,
|
|
11848
|
+
const docRef = (0, import_firestore40.doc)(this.getTechnologiesRef(), technologyId);
|
|
11849
|
+
await (0, import_firestore40.updateDoc)(docRef, {
|
|
11850
|
+
benefits: (0, import_firestore40.arrayRemove)(benefit),
|
|
11185
11851
|
updatedAt: /* @__PURE__ */ new Date()
|
|
11186
11852
|
});
|
|
11187
11853
|
return this.getById(technologyId);
|
|
@@ -11220,8 +11886,8 @@ var TechnologyService = class extends BaseService {
|
|
|
11220
11886
|
* @returns Ažurirana tehnologija
|
|
11221
11887
|
*/
|
|
11222
11888
|
async updateCertificationRequirement(technologyId, certificationRequirement) {
|
|
11223
|
-
const docRef = (0,
|
|
11224
|
-
await (0,
|
|
11889
|
+
const docRef = (0, import_firestore40.doc)(this.getTechnologiesRef(), technologyId);
|
|
11890
|
+
await (0, import_firestore40.updateDoc)(docRef, {
|
|
11225
11891
|
certificationRequirement,
|
|
11226
11892
|
updatedAt: /* @__PURE__ */ new Date()
|
|
11227
11893
|
});
|
|
@@ -11321,7 +11987,7 @@ var TechnologyService = class extends BaseService {
|
|
|
11321
11987
|
};
|
|
11322
11988
|
|
|
11323
11989
|
// src/backoffice/services/product.service.ts
|
|
11324
|
-
var
|
|
11990
|
+
var import_firestore41 = require("firebase/firestore");
|
|
11325
11991
|
|
|
11326
11992
|
// src/backoffice/types/product.types.ts
|
|
11327
11993
|
var PRODUCTS_COLLECTION = "products";
|
|
@@ -11334,7 +12000,7 @@ var ProductService = class extends BaseService {
|
|
|
11334
12000
|
* @returns Firestore collection reference
|
|
11335
12001
|
*/
|
|
11336
12002
|
getProductsRef(technologyId) {
|
|
11337
|
-
return (0,
|
|
12003
|
+
return (0, import_firestore41.collection)(
|
|
11338
12004
|
this.db,
|
|
11339
12005
|
TECHNOLOGIES_COLLECTION,
|
|
11340
12006
|
technologyId,
|
|
@@ -11354,7 +12020,7 @@ var ProductService = class extends BaseService {
|
|
|
11354
12020
|
updatedAt: now,
|
|
11355
12021
|
isActive: true
|
|
11356
12022
|
};
|
|
11357
|
-
const productRef = await (0,
|
|
12023
|
+
const productRef = await (0, import_firestore41.addDoc)(
|
|
11358
12024
|
this.getProductsRef(technologyId),
|
|
11359
12025
|
newProduct
|
|
11360
12026
|
);
|
|
@@ -11364,15 +12030,15 @@ var ProductService = class extends BaseService {
|
|
|
11364
12030
|
* Gets all products for a technology
|
|
11365
12031
|
*/
|
|
11366
12032
|
async getAllByTechnology(technologyId) {
|
|
11367
|
-
const q = (0,
|
|
12033
|
+
const q = (0, import_firestore41.query)(
|
|
11368
12034
|
this.getProductsRef(technologyId),
|
|
11369
|
-
(0,
|
|
12035
|
+
(0, import_firestore41.where)("isActive", "==", true)
|
|
11370
12036
|
);
|
|
11371
|
-
const snapshot = await (0,
|
|
12037
|
+
const snapshot = await (0, import_firestore41.getDocs)(q);
|
|
11372
12038
|
return snapshot.docs.map(
|
|
11373
|
-
(
|
|
11374
|
-
id:
|
|
11375
|
-
...
|
|
12039
|
+
(doc29) => ({
|
|
12040
|
+
id: doc29.id,
|
|
12041
|
+
...doc29.data()
|
|
11376
12042
|
})
|
|
11377
12043
|
);
|
|
11378
12044
|
}
|
|
@@ -11380,21 +12046,21 @@ var ProductService = class extends BaseService {
|
|
|
11380
12046
|
* Gets all products for a brand by filtering through all technologies
|
|
11381
12047
|
*/
|
|
11382
12048
|
async getAllByBrand(brandId) {
|
|
11383
|
-
const allTechnologiesRef = (0,
|
|
11384
|
-
const technologiesSnapshot = await (0,
|
|
12049
|
+
const allTechnologiesRef = (0, import_firestore41.collection)(this.db, TECHNOLOGIES_COLLECTION);
|
|
12050
|
+
const technologiesSnapshot = await (0, import_firestore41.getDocs)(allTechnologiesRef);
|
|
11385
12051
|
const products = [];
|
|
11386
12052
|
for (const techDoc of technologiesSnapshot.docs) {
|
|
11387
|
-
const q = (0,
|
|
12053
|
+
const q = (0, import_firestore41.query)(
|
|
11388
12054
|
this.getProductsRef(techDoc.id),
|
|
11389
|
-
(0,
|
|
11390
|
-
(0,
|
|
12055
|
+
(0, import_firestore41.where)("brandId", "==", brandId),
|
|
12056
|
+
(0, import_firestore41.where)("isActive", "==", true)
|
|
11391
12057
|
);
|
|
11392
|
-
const snapshot = await (0,
|
|
12058
|
+
const snapshot = await (0, import_firestore41.getDocs)(q);
|
|
11393
12059
|
products.push(
|
|
11394
12060
|
...snapshot.docs.map(
|
|
11395
|
-
(
|
|
11396
|
-
id:
|
|
11397
|
-
...
|
|
12061
|
+
(doc29) => ({
|
|
12062
|
+
id: doc29.id,
|
|
12063
|
+
...doc29.data()
|
|
11398
12064
|
})
|
|
11399
12065
|
)
|
|
11400
12066
|
);
|
|
@@ -11409,8 +12075,8 @@ var ProductService = class extends BaseService {
|
|
|
11409
12075
|
...product,
|
|
11410
12076
|
updatedAt: /* @__PURE__ */ new Date()
|
|
11411
12077
|
};
|
|
11412
|
-
const docRef = (0,
|
|
11413
|
-
await (0,
|
|
12078
|
+
const docRef = (0, import_firestore41.doc)(this.getProductsRef(technologyId), productId);
|
|
12079
|
+
await (0, import_firestore41.updateDoc)(docRef, updateData);
|
|
11414
12080
|
return this.getById(technologyId, productId);
|
|
11415
12081
|
}
|
|
11416
12082
|
/**
|
|
@@ -11425,8 +12091,8 @@ var ProductService = class extends BaseService {
|
|
|
11425
12091
|
* Gets a product by ID
|
|
11426
12092
|
*/
|
|
11427
12093
|
async getById(technologyId, productId) {
|
|
11428
|
-
const docRef = (0,
|
|
11429
|
-
const docSnap = await (0,
|
|
12094
|
+
const docRef = (0, import_firestore41.doc)(this.getProductsRef(technologyId), productId);
|
|
12095
|
+
const docSnap = await (0, import_firestore41.getDoc)(docRef);
|
|
11430
12096
|
if (!docSnap.exists()) return null;
|
|
11431
12097
|
return {
|
|
11432
12098
|
id: docSnap.id,
|
|
@@ -11436,54 +12102,54 @@ var ProductService = class extends BaseService {
|
|
|
11436
12102
|
};
|
|
11437
12103
|
|
|
11438
12104
|
// src/validations/notification.schema.ts
|
|
11439
|
-
var
|
|
11440
|
-
var baseNotificationSchema =
|
|
11441
|
-
id:
|
|
11442
|
-
userId:
|
|
11443
|
-
notificationTime:
|
|
12105
|
+
var import_zod22 = require("zod");
|
|
12106
|
+
var baseNotificationSchema = import_zod22.z.object({
|
|
12107
|
+
id: import_zod22.z.string().optional(),
|
|
12108
|
+
userId: import_zod22.z.string(),
|
|
12109
|
+
notificationTime: import_zod22.z.any(),
|
|
11444
12110
|
// Timestamp
|
|
11445
|
-
notificationType:
|
|
11446
|
-
notificationTokens:
|
|
11447
|
-
status:
|
|
11448
|
-
createdAt:
|
|
12111
|
+
notificationType: import_zod22.z.nativeEnum(NotificationType),
|
|
12112
|
+
notificationTokens: import_zod22.z.array(import_zod22.z.string()),
|
|
12113
|
+
status: import_zod22.z.nativeEnum(NotificationStatus),
|
|
12114
|
+
createdAt: import_zod22.z.any().optional(),
|
|
11449
12115
|
// Timestamp
|
|
11450
|
-
updatedAt:
|
|
12116
|
+
updatedAt: import_zod22.z.any().optional(),
|
|
11451
12117
|
// Timestamp
|
|
11452
|
-
title:
|
|
11453
|
-
body:
|
|
11454
|
-
isRead:
|
|
11455
|
-
userRole:
|
|
12118
|
+
title: import_zod22.z.string(),
|
|
12119
|
+
body: import_zod22.z.string(),
|
|
12120
|
+
isRead: import_zod22.z.boolean(),
|
|
12121
|
+
userRole: import_zod22.z.nativeEnum(UserRole)
|
|
11456
12122
|
});
|
|
11457
12123
|
var preRequirementNotificationSchema = baseNotificationSchema.extend({
|
|
11458
|
-
notificationType:
|
|
11459
|
-
treatmentId:
|
|
11460
|
-
requirements:
|
|
11461
|
-
deadline:
|
|
12124
|
+
notificationType: import_zod22.z.literal("preRequirement" /* PRE_REQUIREMENT */),
|
|
12125
|
+
treatmentId: import_zod22.z.string(),
|
|
12126
|
+
requirements: import_zod22.z.array(import_zod22.z.string()),
|
|
12127
|
+
deadline: import_zod22.z.any()
|
|
11462
12128
|
// Timestamp
|
|
11463
12129
|
});
|
|
11464
12130
|
var postRequirementNotificationSchema = baseNotificationSchema.extend({
|
|
11465
|
-
notificationType:
|
|
11466
|
-
treatmentId:
|
|
11467
|
-
requirements:
|
|
11468
|
-
deadline:
|
|
12131
|
+
notificationType: import_zod22.z.literal("postRequirement" /* POST_REQUIREMENT */),
|
|
12132
|
+
treatmentId: import_zod22.z.string(),
|
|
12133
|
+
requirements: import_zod22.z.array(import_zod22.z.string()),
|
|
12134
|
+
deadline: import_zod22.z.any()
|
|
11469
12135
|
// Timestamp
|
|
11470
12136
|
});
|
|
11471
12137
|
var appointmentReminderNotificationSchema = baseNotificationSchema.extend({
|
|
11472
|
-
notificationType:
|
|
11473
|
-
appointmentId:
|
|
11474
|
-
appointmentTime:
|
|
12138
|
+
notificationType: import_zod22.z.literal("appointmentReminder" /* APPOINTMENT_REMINDER */),
|
|
12139
|
+
appointmentId: import_zod22.z.string(),
|
|
12140
|
+
appointmentTime: import_zod22.z.any(),
|
|
11475
12141
|
// Timestamp
|
|
11476
|
-
treatmentType:
|
|
11477
|
-
doctorName:
|
|
12142
|
+
treatmentType: import_zod22.z.string(),
|
|
12143
|
+
doctorName: import_zod22.z.string()
|
|
11478
12144
|
});
|
|
11479
12145
|
var appointmentNotificationSchema = baseNotificationSchema.extend({
|
|
11480
|
-
notificationType:
|
|
11481
|
-
appointmentId:
|
|
11482
|
-
appointmentStatus:
|
|
11483
|
-
previousStatus:
|
|
11484
|
-
reason:
|
|
12146
|
+
notificationType: import_zod22.z.literal("appointmentNotification" /* APPOINTMENT_NOTIFICATION */),
|
|
12147
|
+
appointmentId: import_zod22.z.string(),
|
|
12148
|
+
appointmentStatus: import_zod22.z.string(),
|
|
12149
|
+
previousStatus: import_zod22.z.string(),
|
|
12150
|
+
reason: import_zod22.z.string().optional()
|
|
11485
12151
|
});
|
|
11486
|
-
var notificationSchema =
|
|
12152
|
+
var notificationSchema = import_zod22.z.discriminatedUnion("notificationType", [
|
|
11487
12153
|
preRequirementNotificationSchema,
|
|
11488
12154
|
postRequirementNotificationSchema,
|
|
11489
12155
|
appointmentReminderNotificationSchema,
|
|
@@ -11510,8 +12176,17 @@ var TreatmentBenefit = /* @__PURE__ */ ((TreatmentBenefit2) => {
|
|
|
11510
12176
|
return TreatmentBenefit2;
|
|
11511
12177
|
})(TreatmentBenefit || {});
|
|
11512
12178
|
|
|
11513
|
-
// src/types/
|
|
11514
|
-
var
|
|
12179
|
+
// src/backoffice/types/requirement.types.ts
|
|
12180
|
+
var TimeUnit = /* @__PURE__ */ ((TimeUnit2) => {
|
|
12181
|
+
TimeUnit2["HOURS"] = "hours";
|
|
12182
|
+
TimeUnit2["DAYS"] = "days";
|
|
12183
|
+
return TimeUnit2;
|
|
12184
|
+
})(TimeUnit || {});
|
|
12185
|
+
var RequirementType = /* @__PURE__ */ ((RequirementType2) => {
|
|
12186
|
+
RequirementType2["PRE"] = "pre";
|
|
12187
|
+
RequirementType2["POST"] = "post";
|
|
12188
|
+
return RequirementType2;
|
|
12189
|
+
})(RequirementType || {});
|
|
11515
12190
|
// Annotate the CommonJS export names for ESM import in node:
|
|
11516
12191
|
0 && (module.exports = {
|
|
11517
12192
|
AUTH_ERRORS,
|
|
@@ -11576,6 +12251,8 @@ var REVIEWS_COLLECTION = "reviews";
|
|
|
11576
12251
|
ProductService,
|
|
11577
12252
|
REGISTER_TOKENS_COLLECTION,
|
|
11578
12253
|
REVIEWS_COLLECTION,
|
|
12254
|
+
RequirementType,
|
|
12255
|
+
ReviewService,
|
|
11579
12256
|
SYNCED_CALENDARS_COLLECTION,
|
|
11580
12257
|
SearchLocationEnum,
|
|
11581
12258
|
SubcategoryService,
|
|
@@ -11583,6 +12260,7 @@ var REVIEWS_COLLECTION = "reviews";
|
|
|
11583
12260
|
SyncedCalendarProvider,
|
|
11584
12261
|
SyncedCalendarsService,
|
|
11585
12262
|
TechnologyService,
|
|
12263
|
+
TimeUnit,
|
|
11586
12264
|
TreatmentBenefit,
|
|
11587
12265
|
USER_ERRORS,
|
|
11588
12266
|
UserService,
|