@blackcode_sa/metaestetics-api 1.5.15 → 1.5.17
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/backoffice/index.d.mts +2 -2
- package/dist/backoffice/index.d.ts +2 -2
- package/dist/index.d.mts +232 -38
- package/dist/index.d.ts +232 -38
- package/dist/index.js +698 -342
- package/dist/index.mjs +942 -570
- package/package.json +1 -1
- package/src/index.ts +2 -0
- package/src/services/calendar/calendar-refactored.service.ts +147 -0
- package/src/services/calendar/utils/calendar-event.utils.ts +136 -0
- package/src/services/calendar/utils/index.ts +5 -5
- package/src/services/clinic/utils/clinic-group.utils.ts +3 -0
- package/src/services/patient/patient.service.ts +29 -0
- package/src/services/patient/utils/medical-stuff.utils.ts +69 -18
- package/src/services/patient/utils/profile.utils.ts +116 -0
- package/src/types/calendar/index.ts +41 -0
- package/src/types/clinic/index.ts +2 -0
- package/src/types/patient/index.ts +31 -1
- package/src/types/practitioner/index.ts +13 -14
- package/src/validations/clinic.schema.ts +2 -0
- package/src/validations/patient.schema.ts +43 -0
package/dist/index.mjs
CHANGED
|
@@ -57,9 +57,9 @@ import {
|
|
|
57
57
|
confirmPasswordReset
|
|
58
58
|
} from "firebase/auth";
|
|
59
59
|
import {
|
|
60
|
-
collection as
|
|
61
|
-
query as
|
|
62
|
-
getDocs as
|
|
60
|
+
collection as collection10,
|
|
61
|
+
query as query9,
|
|
62
|
+
getDocs as getDocs9
|
|
63
63
|
} from "firebase/firestore";
|
|
64
64
|
|
|
65
65
|
// src/types/documentation-templates/index.ts
|
|
@@ -111,27 +111,27 @@ var FilledDocumentStatus = /* @__PURE__ */ ((FilledDocumentStatus2) => {
|
|
|
111
111
|
})(FilledDocumentStatus || {});
|
|
112
112
|
|
|
113
113
|
// src/types/calendar/index.ts
|
|
114
|
-
var CalendarEventStatus = /* @__PURE__ */ ((
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return
|
|
114
|
+
var CalendarEventStatus = /* @__PURE__ */ ((CalendarEventStatus4) => {
|
|
115
|
+
CalendarEventStatus4["PENDING"] = "pending";
|
|
116
|
+
CalendarEventStatus4["CONFIRMED"] = "confirmed";
|
|
117
|
+
CalendarEventStatus4["REJECTED"] = "rejected";
|
|
118
|
+
CalendarEventStatus4["CANCELED"] = "canceled";
|
|
119
|
+
CalendarEventStatus4["RESCHEDULED"] = "rescheduled";
|
|
120
|
+
CalendarEventStatus4["COMPLETED"] = "completed";
|
|
121
|
+
return CalendarEventStatus4;
|
|
122
122
|
})(CalendarEventStatus || {});
|
|
123
|
-
var CalendarSyncStatus = /* @__PURE__ */ ((
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
return
|
|
123
|
+
var CalendarSyncStatus = /* @__PURE__ */ ((CalendarSyncStatus4) => {
|
|
124
|
+
CalendarSyncStatus4["INTERNAL"] = "internal";
|
|
125
|
+
CalendarSyncStatus4["EXTERNAL"] = "external";
|
|
126
|
+
return CalendarSyncStatus4;
|
|
127
127
|
})(CalendarSyncStatus || {});
|
|
128
|
-
var CalendarEventType = /* @__PURE__ */ ((
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
return
|
|
128
|
+
var CalendarEventType = /* @__PURE__ */ ((CalendarEventType3) => {
|
|
129
|
+
CalendarEventType3["APPOINTMENT"] = "appointment";
|
|
130
|
+
CalendarEventType3["BLOCKING"] = "blocking";
|
|
131
|
+
CalendarEventType3["BREAK"] = "break";
|
|
132
|
+
CalendarEventType3["FREE_DAY"] = "free_day";
|
|
133
|
+
CalendarEventType3["OTHER"] = "other";
|
|
134
|
+
return CalendarEventType3;
|
|
135
135
|
})(CalendarEventType || {});
|
|
136
136
|
var CALENDAR_COLLECTION = "calendar";
|
|
137
137
|
|
|
@@ -577,12 +577,12 @@ var BaseService = class {
|
|
|
577
577
|
|
|
578
578
|
// src/services/user.service.ts
|
|
579
579
|
import {
|
|
580
|
-
collection as
|
|
580
|
+
collection as collection5,
|
|
581
581
|
doc as doc6,
|
|
582
582
|
getDoc as getDoc10,
|
|
583
|
-
getDocs as
|
|
584
|
-
query as
|
|
585
|
-
where as
|
|
583
|
+
getDocs as getDocs5,
|
|
584
|
+
query as query5,
|
|
585
|
+
where as where5,
|
|
586
586
|
updateDoc as updateDoc9,
|
|
587
587
|
deleteDoc as deleteDoc3,
|
|
588
588
|
Timestamp as Timestamp9,
|
|
@@ -701,7 +701,11 @@ import {
|
|
|
701
701
|
arrayRemove as arrayRemove2,
|
|
702
702
|
serverTimestamp as serverTimestamp4,
|
|
703
703
|
increment,
|
|
704
|
-
Timestamp as Timestamp3
|
|
704
|
+
Timestamp as Timestamp3,
|
|
705
|
+
collection as collection2,
|
|
706
|
+
query as query2,
|
|
707
|
+
where as where2,
|
|
708
|
+
getDocs as getDocs2
|
|
705
709
|
} from "firebase/firestore";
|
|
706
710
|
import {
|
|
707
711
|
ref,
|
|
@@ -999,6 +1003,8 @@ var patientProfileSchema = z5.object({
|
|
|
999
1003
|
isVerified: z5.boolean(),
|
|
1000
1004
|
doctors: z5.array(patientDoctorSchema),
|
|
1001
1005
|
clinics: z5.array(patientClinicSchema),
|
|
1006
|
+
doctorIds: z5.array(z5.string()),
|
|
1007
|
+
clinicIds: z5.array(z5.string()),
|
|
1002
1008
|
createdAt: z5.instanceof(Timestamp),
|
|
1003
1009
|
updatedAt: z5.instanceof(Timestamp)
|
|
1004
1010
|
});
|
|
@@ -1011,7 +1017,9 @@ var createPatientProfileSchema = z5.object({
|
|
|
1011
1017
|
isActive: z5.boolean(),
|
|
1012
1018
|
isVerified: z5.boolean(),
|
|
1013
1019
|
doctors: z5.array(patientDoctorSchema).optional(),
|
|
1014
|
-
clinics: z5.array(patientClinicSchema).optional()
|
|
1020
|
+
clinics: z5.array(patientClinicSchema).optional(),
|
|
1021
|
+
doctorIds: z5.array(z5.string()).optional(),
|
|
1022
|
+
clinicIds: z5.array(z5.string()).optional()
|
|
1015
1023
|
});
|
|
1016
1024
|
var createPatientSensitiveInfoSchema = z5.object({
|
|
1017
1025
|
patientId: z5.string(),
|
|
@@ -1027,6 +1035,33 @@ var createPatientSensitiveInfoSchema = z5.object({
|
|
|
1027
1035
|
addressData: addressDataSchema.optional(),
|
|
1028
1036
|
emergencyContacts: z5.array(emergencyContactSchema).optional()
|
|
1029
1037
|
});
|
|
1038
|
+
var searchPatientsSchema = z5.object({
|
|
1039
|
+
clinicId: z5.string().optional(),
|
|
1040
|
+
practitionerId: z5.string().optional()
|
|
1041
|
+
}).refine((data) => data.clinicId || data.practitionerId, {
|
|
1042
|
+
message: "At least one of clinicId or practitionerId must be provided",
|
|
1043
|
+
path: []
|
|
1044
|
+
// Optional: specify a path like ['clinicId'] or ['practitionerId']
|
|
1045
|
+
});
|
|
1046
|
+
var requesterInfoSchema = z5.object({
|
|
1047
|
+
id: z5.string(),
|
|
1048
|
+
role: z5.enum(["clinic_admin", "practitioner"]),
|
|
1049
|
+
associatedClinicId: z5.string().optional(),
|
|
1050
|
+
associatedPractitionerId: z5.string().optional()
|
|
1051
|
+
}).refine(
|
|
1052
|
+
(data) => {
|
|
1053
|
+
if (data.role === "clinic_admin") {
|
|
1054
|
+
return !!data.associatedClinicId;
|
|
1055
|
+
} else if (data.role === "practitioner") {
|
|
1056
|
+
return !!data.associatedPractitionerId;
|
|
1057
|
+
}
|
|
1058
|
+
return false;
|
|
1059
|
+
},
|
|
1060
|
+
{
|
|
1061
|
+
message: "Associated ID (clinic or practitioner) is required based on role",
|
|
1062
|
+
path: ["associatedClinicId", "associatedPractitionerId"]
|
|
1063
|
+
}
|
|
1064
|
+
);
|
|
1030
1065
|
|
|
1031
1066
|
// src/services/patient/utils/docs.utils.ts
|
|
1032
1067
|
import {
|
|
@@ -1310,9 +1345,9 @@ var addAllergyUtil = async (db, patientId, data, userRef) => {
|
|
|
1310
1345
|
var updateAllergyUtil = async (db, patientId, data, userRef) => {
|
|
1311
1346
|
const validatedData = updateAllergySchema.parse(data);
|
|
1312
1347
|
const { allergyIndex, ...updateData } = validatedData;
|
|
1313
|
-
const
|
|
1314
|
-
if (!
|
|
1315
|
-
const medicalInfo =
|
|
1348
|
+
const doc27 = await getDoc3(getMedicalInfoDocRef(db, patientId));
|
|
1349
|
+
if (!doc27.exists()) throw new Error("Medical info not found");
|
|
1350
|
+
const medicalInfo = doc27.data();
|
|
1316
1351
|
if (allergyIndex >= medicalInfo.allergies.length) {
|
|
1317
1352
|
throw new Error("Invalid allergy index");
|
|
1318
1353
|
}
|
|
@@ -1328,9 +1363,9 @@ var updateAllergyUtil = async (db, patientId, data, userRef) => {
|
|
|
1328
1363
|
});
|
|
1329
1364
|
};
|
|
1330
1365
|
var removeAllergyUtil = async (db, patientId, allergyIndex, userRef) => {
|
|
1331
|
-
const
|
|
1332
|
-
if (!
|
|
1333
|
-
const medicalInfo =
|
|
1366
|
+
const doc27 = await getDoc3(getMedicalInfoDocRef(db, patientId));
|
|
1367
|
+
if (!doc27.exists()) throw new Error("Medical info not found");
|
|
1368
|
+
const medicalInfo = doc27.data();
|
|
1334
1369
|
if (allergyIndex >= medicalInfo.allergies.length) {
|
|
1335
1370
|
throw new Error("Invalid allergy index");
|
|
1336
1371
|
}
|
|
@@ -1355,9 +1390,9 @@ var addBlockingConditionUtil = async (db, patientId, data, userRef) => {
|
|
|
1355
1390
|
var updateBlockingConditionUtil = async (db, patientId, data, userRef) => {
|
|
1356
1391
|
const validatedData = updateBlockingConditionSchema.parse(data);
|
|
1357
1392
|
const { conditionIndex, ...updateData } = validatedData;
|
|
1358
|
-
const
|
|
1359
|
-
if (!
|
|
1360
|
-
const medicalInfo =
|
|
1393
|
+
const doc27 = await getDoc3(getMedicalInfoDocRef(db, patientId));
|
|
1394
|
+
if (!doc27.exists()) throw new Error("Medical info not found");
|
|
1395
|
+
const medicalInfo = doc27.data();
|
|
1361
1396
|
if (conditionIndex >= medicalInfo.blockingConditions.length) {
|
|
1362
1397
|
throw new Error("Invalid blocking condition index");
|
|
1363
1398
|
}
|
|
@@ -1373,9 +1408,9 @@ var updateBlockingConditionUtil = async (db, patientId, data, userRef) => {
|
|
|
1373
1408
|
});
|
|
1374
1409
|
};
|
|
1375
1410
|
var removeBlockingConditionUtil = async (db, patientId, conditionIndex, userRef) => {
|
|
1376
|
-
const
|
|
1377
|
-
if (!
|
|
1378
|
-
const medicalInfo =
|
|
1411
|
+
const doc27 = await getDoc3(getMedicalInfoDocRef(db, patientId));
|
|
1412
|
+
if (!doc27.exists()) throw new Error("Medical info not found");
|
|
1413
|
+
const medicalInfo = doc27.data();
|
|
1379
1414
|
if (conditionIndex >= medicalInfo.blockingConditions.length) {
|
|
1380
1415
|
throw new Error("Invalid blocking condition index");
|
|
1381
1416
|
}
|
|
@@ -1400,9 +1435,9 @@ var addContraindicationUtil = async (db, patientId, data, userRef) => {
|
|
|
1400
1435
|
var updateContraindicationUtil = async (db, patientId, data, userRef) => {
|
|
1401
1436
|
const validatedData = updateContraindicationSchema.parse(data);
|
|
1402
1437
|
const { contraindicationIndex, ...updateData } = validatedData;
|
|
1403
|
-
const
|
|
1404
|
-
if (!
|
|
1405
|
-
const medicalInfo =
|
|
1438
|
+
const doc27 = await getDoc3(getMedicalInfoDocRef(db, patientId));
|
|
1439
|
+
if (!doc27.exists()) throw new Error("Medical info not found");
|
|
1440
|
+
const medicalInfo = doc27.data();
|
|
1406
1441
|
if (contraindicationIndex >= medicalInfo.contraindications.length) {
|
|
1407
1442
|
throw new Error("Invalid contraindication index");
|
|
1408
1443
|
}
|
|
@@ -1418,9 +1453,9 @@ var updateContraindicationUtil = async (db, patientId, data, userRef) => {
|
|
|
1418
1453
|
});
|
|
1419
1454
|
};
|
|
1420
1455
|
var removeContraindicationUtil = async (db, patientId, contraindicationIndex, userRef) => {
|
|
1421
|
-
const
|
|
1422
|
-
if (!
|
|
1423
|
-
const medicalInfo =
|
|
1456
|
+
const doc27 = await getDoc3(getMedicalInfoDocRef(db, patientId));
|
|
1457
|
+
if (!doc27.exists()) throw new Error("Medical info not found");
|
|
1458
|
+
const medicalInfo = doc27.data();
|
|
1424
1459
|
if (contraindicationIndex >= medicalInfo.contraindications.length) {
|
|
1425
1460
|
throw new Error("Invalid contraindication index");
|
|
1426
1461
|
}
|
|
@@ -1445,9 +1480,9 @@ var addMedicationUtil = async (db, patientId, data, userRef) => {
|
|
|
1445
1480
|
var updateMedicationUtil = async (db, patientId, data, userRef) => {
|
|
1446
1481
|
const validatedData = updateMedicationSchema.parse(data);
|
|
1447
1482
|
const { medicationIndex, ...updateData } = validatedData;
|
|
1448
|
-
const
|
|
1449
|
-
if (!
|
|
1450
|
-
const medicalInfo =
|
|
1483
|
+
const doc27 = await getDoc3(getMedicalInfoDocRef(db, patientId));
|
|
1484
|
+
if (!doc27.exists()) throw new Error("Medical info not found");
|
|
1485
|
+
const medicalInfo = doc27.data();
|
|
1451
1486
|
if (medicationIndex >= medicalInfo.currentMedications.length) {
|
|
1452
1487
|
throw new Error("Invalid medication index");
|
|
1453
1488
|
}
|
|
@@ -1463,9 +1498,9 @@ var updateMedicationUtil = async (db, patientId, data, userRef) => {
|
|
|
1463
1498
|
});
|
|
1464
1499
|
};
|
|
1465
1500
|
var removeMedicationUtil = async (db, patientId, medicationIndex, userRef) => {
|
|
1466
|
-
const
|
|
1467
|
-
if (!
|
|
1468
|
-
const medicalInfo =
|
|
1501
|
+
const doc27 = await getDoc3(getMedicalInfoDocRef(db, patientId));
|
|
1502
|
+
if (!doc27.exists()) throw new Error("Medical info not found");
|
|
1503
|
+
const medicalInfo = doc27.data();
|
|
1469
1504
|
if (medicationIndex >= medicalInfo.currentMedications.length) {
|
|
1470
1505
|
throw new Error("Invalid medication index");
|
|
1471
1506
|
}
|
|
@@ -1481,6 +1516,7 @@ var removeMedicationUtil = async (db, patientId, medicationIndex, userRef) => {
|
|
|
1481
1516
|
|
|
1482
1517
|
// src/services/patient/utils/profile.utils.ts
|
|
1483
1518
|
var createPatientProfileUtil = async (db, data, generateId2) => {
|
|
1519
|
+
var _a, _b;
|
|
1484
1520
|
try {
|
|
1485
1521
|
console.log("[createPatientProfileUtil] Starting patient profile creation");
|
|
1486
1522
|
const validatedData = createPatientProfileSchema.parse(data);
|
|
@@ -1500,6 +1536,8 @@ var createPatientProfileUtil = async (db, data, generateId2) => {
|
|
|
1500
1536
|
isVerified: validatedData.isVerified,
|
|
1501
1537
|
doctors: validatedData.doctors || [],
|
|
1502
1538
|
clinics: validatedData.clinics || [],
|
|
1539
|
+
doctorIds: ((_a = validatedData.doctors) == null ? void 0 : _a.map((d) => d.userRef)) || [],
|
|
1540
|
+
clinicIds: ((_b = validatedData.clinics) == null ? void 0 : _b.map((c) => c.clinicId)) || [],
|
|
1503
1541
|
createdAt: serverTimestamp4(),
|
|
1504
1542
|
updatedAt: serverTimestamp4()
|
|
1505
1543
|
};
|
|
@@ -1733,6 +1771,67 @@ var testCreateSubDocuments = async (db, patientId, userRef) => {
|
|
|
1733
1771
|
throw error;
|
|
1734
1772
|
}
|
|
1735
1773
|
};
|
|
1774
|
+
var searchPatientsUtil = async (db, params, requester) => {
|
|
1775
|
+
searchPatientsSchema.parse(params);
|
|
1776
|
+
requesterInfoSchema.parse(requester);
|
|
1777
|
+
const constraints = [];
|
|
1778
|
+
const patientsCollectionRef = collection2(db, PATIENTS_COLLECTION);
|
|
1779
|
+
if (requester.role === "clinic_admin") {
|
|
1780
|
+
if (!requester.associatedClinicId) {
|
|
1781
|
+
throw new Error(
|
|
1782
|
+
"Associated clinic ID is required for clinic admin search."
|
|
1783
|
+
);
|
|
1784
|
+
}
|
|
1785
|
+
if (params.clinicId && params.clinicId !== requester.associatedClinicId) {
|
|
1786
|
+
console.warn(
|
|
1787
|
+
`Clinic admin (${requester.id}) attempted to search outside their associated clinic (${requester.associatedClinicId})`
|
|
1788
|
+
);
|
|
1789
|
+
return [];
|
|
1790
|
+
}
|
|
1791
|
+
constraints.push(
|
|
1792
|
+
where2("clinicIds", "array-contains", requester.associatedClinicId)
|
|
1793
|
+
);
|
|
1794
|
+
if (params.practitionerId) {
|
|
1795
|
+
constraints.push(
|
|
1796
|
+
where2("doctorIds", "array-contains", params.practitionerId)
|
|
1797
|
+
);
|
|
1798
|
+
}
|
|
1799
|
+
} else if (requester.role === "practitioner") {
|
|
1800
|
+
if (!requester.associatedPractitionerId) {
|
|
1801
|
+
throw new Error(
|
|
1802
|
+
"Associated practitioner ID is required for practitioner search."
|
|
1803
|
+
);
|
|
1804
|
+
}
|
|
1805
|
+
if (params.practitionerId && params.practitionerId !== requester.associatedPractitionerId) {
|
|
1806
|
+
console.warn(
|
|
1807
|
+
`Practitioner (${requester.id}) attempted to search for patients of another practitioner (${params.practitionerId})`
|
|
1808
|
+
);
|
|
1809
|
+
return [];
|
|
1810
|
+
}
|
|
1811
|
+
constraints.push(
|
|
1812
|
+
where2("doctorIds", "array-contains", requester.associatedPractitionerId)
|
|
1813
|
+
);
|
|
1814
|
+
if (params.clinicId) {
|
|
1815
|
+
constraints.push(where2("clinicIds", "array-contains", params.clinicId));
|
|
1816
|
+
}
|
|
1817
|
+
} else {
|
|
1818
|
+
throw new Error("Invalid requester role.");
|
|
1819
|
+
}
|
|
1820
|
+
try {
|
|
1821
|
+
const finalQuery = query2(patientsCollectionRef, ...constraints);
|
|
1822
|
+
const querySnapshot = await getDocs2(finalQuery);
|
|
1823
|
+
const patients = querySnapshot.docs.map(
|
|
1824
|
+
(doc27) => doc27.data()
|
|
1825
|
+
);
|
|
1826
|
+
console.log(
|
|
1827
|
+
`[searchPatientsUtil] Found ${patients.length} patients matching criteria.`
|
|
1828
|
+
);
|
|
1829
|
+
return patients;
|
|
1830
|
+
} catch (error) {
|
|
1831
|
+
console.error("[searchPatientsUtil] Error searching patients:", error);
|
|
1832
|
+
return [];
|
|
1833
|
+
}
|
|
1834
|
+
};
|
|
1736
1835
|
|
|
1737
1836
|
// src/services/patient/utils/location.utils.ts
|
|
1738
1837
|
import {
|
|
@@ -1821,54 +1920,101 @@ import {
|
|
|
1821
1920
|
getDoc as getDoc6,
|
|
1822
1921
|
updateDoc as updateDoc5,
|
|
1823
1922
|
arrayUnion as arrayUnion3,
|
|
1923
|
+
arrayRemove as arrayRemove3,
|
|
1824
1924
|
serverTimestamp as serverTimestamp6,
|
|
1825
1925
|
Timestamp as Timestamp4
|
|
1826
1926
|
} from "firebase/firestore";
|
|
1827
1927
|
var addDoctorUtil = async (db, patientId, doctorRef, assignedBy) => {
|
|
1928
|
+
var _a;
|
|
1828
1929
|
const newDoctor = {
|
|
1829
1930
|
userRef: doctorRef,
|
|
1830
1931
|
assignedAt: Timestamp4.now(),
|
|
1831
1932
|
assignedBy,
|
|
1832
1933
|
isActive: true
|
|
1833
1934
|
};
|
|
1834
|
-
await updateDoc5(getPatientDocRef(db, patientId), {
|
|
1835
|
-
doctors: arrayUnion3(newDoctor),
|
|
1836
|
-
updatedAt: serverTimestamp6()
|
|
1837
|
-
});
|
|
1838
|
-
};
|
|
1839
|
-
var removeDoctorUtil = async (db, patientId, doctorRef) => {
|
|
1840
1935
|
const patientDoc = await getDoc6(getPatientDocRef(db, patientId));
|
|
1841
1936
|
if (!patientDoc.exists()) throw new Error("Patient profile not found");
|
|
1842
1937
|
const patientData = patientDoc.data();
|
|
1843
|
-
const
|
|
1844
|
-
(
|
|
1938
|
+
const existingDoctorIndex = (_a = patientData.doctors) == null ? void 0 : _a.findIndex(
|
|
1939
|
+
(d) => d.userRef === doctorRef
|
|
1845
1940
|
);
|
|
1846
|
-
|
|
1941
|
+
const updates = {
|
|
1942
|
+
updatedAt: serverTimestamp6(),
|
|
1943
|
+
doctorIds: arrayUnion3(doctorRef)
|
|
1944
|
+
};
|
|
1945
|
+
if (existingDoctorIndex !== void 0 && existingDoctorIndex > -1) {
|
|
1946
|
+
const updatedDoctors = [...patientData.doctors];
|
|
1947
|
+
updatedDoctors[existingDoctorIndex] = {
|
|
1948
|
+
...updatedDoctors[existingDoctorIndex],
|
|
1949
|
+
isActive: true,
|
|
1950
|
+
assignedAt: Timestamp4.now(),
|
|
1951
|
+
assignedBy
|
|
1952
|
+
};
|
|
1953
|
+
updates.doctors = updatedDoctors;
|
|
1954
|
+
} else {
|
|
1955
|
+
updates.doctors = arrayUnion3(newDoctor);
|
|
1956
|
+
}
|
|
1957
|
+
await updateDoc5(getPatientDocRef(db, patientId), updates);
|
|
1958
|
+
};
|
|
1959
|
+
var removeDoctorUtil = async (db, patientId, doctorRef) => {
|
|
1960
|
+
var _a;
|
|
1961
|
+
const patientDocRef = getPatientDocRef(db, patientId);
|
|
1962
|
+
const patientDoc = await getDoc6(patientDocRef);
|
|
1963
|
+
if (!patientDoc.exists()) throw new Error("Patient profile not found");
|
|
1964
|
+
const patientData = patientDoc.data();
|
|
1965
|
+
const updatedDoctors = ((_a = patientData.doctors) == null ? void 0 : _a.filter((doctor) => doctor.userRef !== doctorRef)) || [];
|
|
1966
|
+
await updateDoc5(patientDocRef, {
|
|
1847
1967
|
doctors: updatedDoctors,
|
|
1968
|
+
// Set the filtered array
|
|
1969
|
+
doctorIds: arrayRemove3(doctorRef),
|
|
1970
|
+
// Remove ID from the denormalized list
|
|
1848
1971
|
updatedAt: serverTimestamp6()
|
|
1849
1972
|
});
|
|
1850
1973
|
};
|
|
1851
1974
|
var addClinicUtil = async (db, patientId, clinicId, assignedBy) => {
|
|
1975
|
+
var _a;
|
|
1852
1976
|
const newClinic = {
|
|
1853
1977
|
clinicId,
|
|
1854
1978
|
assignedAt: Timestamp4.now(),
|
|
1855
1979
|
assignedBy,
|
|
1856
1980
|
isActive: true
|
|
1857
1981
|
};
|
|
1858
|
-
await updateDoc5(getPatientDocRef(db, patientId), {
|
|
1859
|
-
clinics: arrayUnion3(newClinic),
|
|
1860
|
-
updatedAt: serverTimestamp6()
|
|
1861
|
-
});
|
|
1862
|
-
};
|
|
1863
|
-
var removeClinicUtil = async (db, patientId, clinicId) => {
|
|
1864
1982
|
const patientDoc = await getDoc6(getPatientDocRef(db, patientId));
|
|
1865
1983
|
if (!patientDoc.exists()) throw new Error("Patient profile not found");
|
|
1866
1984
|
const patientData = patientDoc.data();
|
|
1867
|
-
const
|
|
1868
|
-
(
|
|
1985
|
+
const existingClinicIndex = (_a = patientData.clinics) == null ? void 0 : _a.findIndex(
|
|
1986
|
+
(c) => c.clinicId === clinicId
|
|
1869
1987
|
);
|
|
1870
|
-
|
|
1988
|
+
const updates = {
|
|
1989
|
+
updatedAt: serverTimestamp6(),
|
|
1990
|
+
clinicIds: arrayUnion3(clinicId)
|
|
1991
|
+
};
|
|
1992
|
+
if (existingClinicIndex !== void 0 && existingClinicIndex > -1) {
|
|
1993
|
+
const updatedClinics = [...patientData.clinics];
|
|
1994
|
+
updatedClinics[existingClinicIndex] = {
|
|
1995
|
+
...updatedClinics[existingClinicIndex],
|
|
1996
|
+
isActive: true,
|
|
1997
|
+
assignedAt: Timestamp4.now(),
|
|
1998
|
+
assignedBy
|
|
1999
|
+
};
|
|
2000
|
+
updates.clinics = updatedClinics;
|
|
2001
|
+
} else {
|
|
2002
|
+
updates.clinics = arrayUnion3(newClinic);
|
|
2003
|
+
}
|
|
2004
|
+
await updateDoc5(getPatientDocRef(db, patientId), updates);
|
|
2005
|
+
};
|
|
2006
|
+
var removeClinicUtil = async (db, patientId, clinicId) => {
|
|
2007
|
+
var _a;
|
|
2008
|
+
const patientDocRef = getPatientDocRef(db, patientId);
|
|
2009
|
+
const patientDoc = await getDoc6(patientDocRef);
|
|
2010
|
+
if (!patientDoc.exists()) throw new Error("Patient profile not found");
|
|
2011
|
+
const patientData = patientDoc.data();
|
|
2012
|
+
const updatedClinics = ((_a = patientData.clinics) == null ? void 0 : _a.filter((clinic) => clinic.clinicId !== clinicId)) || [];
|
|
2013
|
+
await updateDoc5(patientDocRef, {
|
|
1871
2014
|
clinics: updatedClinics,
|
|
2015
|
+
// Set the filtered array
|
|
2016
|
+
clinicIds: arrayRemove3(clinicId),
|
|
2017
|
+
// Remove ID from the denormalized list
|
|
1872
2018
|
updatedAt: serverTimestamp6()
|
|
1873
2019
|
});
|
|
1874
2020
|
};
|
|
@@ -2109,16 +2255,33 @@ var PatientService = class extends BaseService {
|
|
|
2109
2255
|
async updatePatientProfileByUserRef(userRef, data) {
|
|
2110
2256
|
return updatePatientProfileByUserRefUtil(this.db, userRef, data);
|
|
2111
2257
|
}
|
|
2258
|
+
/**
|
|
2259
|
+
* Searches for patient profiles based on clinic/practitioner association.
|
|
2260
|
+
* Requires information about the requester for security checks.
|
|
2261
|
+
*
|
|
2262
|
+
* @param {SearchPatientsParams} params - The search criteria (clinicId, practitionerId).
|
|
2263
|
+
* @param {RequesterInfo} requester - Information about the user performing the search (ID, role, associated IDs).
|
|
2264
|
+
* @returns {Promise<PatientProfile[]>} A promise resolving to an array of matching patient profiles.
|
|
2265
|
+
*/
|
|
2266
|
+
async searchPatients(params, requester) {
|
|
2267
|
+
console.log(
|
|
2268
|
+
`[PatientService.searchPatients] Initiating search with params:`,
|
|
2269
|
+
params,
|
|
2270
|
+
`by requester:`,
|
|
2271
|
+
requester
|
|
2272
|
+
);
|
|
2273
|
+
return searchPatientsUtil(this.db, params, requester);
|
|
2274
|
+
}
|
|
2112
2275
|
};
|
|
2113
2276
|
|
|
2114
2277
|
// src/services/clinic/utils/admin.utils.ts
|
|
2115
2278
|
import {
|
|
2116
|
-
collection as
|
|
2279
|
+
collection as collection3,
|
|
2117
2280
|
doc as doc4,
|
|
2118
2281
|
getDoc as getDoc8,
|
|
2119
|
-
getDocs as
|
|
2120
|
-
query as
|
|
2121
|
-
where as
|
|
2282
|
+
getDocs as getDocs3,
|
|
2283
|
+
query as query3,
|
|
2284
|
+
where as where3,
|
|
2122
2285
|
updateDoc as updateDoc7,
|
|
2123
2286
|
setDoc as setDoc6,
|
|
2124
2287
|
deleteDoc,
|
|
@@ -2410,6 +2573,7 @@ var clinicAdminSchema = z9.object({
|
|
|
2410
2573
|
var adminTokenSchema = z9.object({
|
|
2411
2574
|
id: z9.string(),
|
|
2412
2575
|
token: z9.string(),
|
|
2576
|
+
email: z9.string().email().optional().nullable(),
|
|
2413
2577
|
status: z9.nativeEnum(AdminTokenStatus),
|
|
2414
2578
|
usedByUserRef: z9.string().optional(),
|
|
2415
2579
|
createdAt: z9.instanceof(Date).or(z9.instanceof(Timestamp5)),
|
|
@@ -2418,7 +2582,8 @@ var adminTokenSchema = z9.object({
|
|
|
2418
2582
|
// Timestamp
|
|
2419
2583
|
});
|
|
2420
2584
|
var createAdminTokenSchema = z9.object({
|
|
2421
|
-
expiresInDays: z9.number().min(1).max(30).optional()
|
|
2585
|
+
expiresInDays: z9.number().min(1).max(30).optional(),
|
|
2586
|
+
email: z9.string().email().optional().nullable()
|
|
2422
2587
|
});
|
|
2423
2588
|
var clinicGroupSchema = z9.object({
|
|
2424
2589
|
id: z9.string(),
|
|
@@ -2674,7 +2839,7 @@ async function createClinicAdmin(db, data, clinicGroupService) {
|
|
|
2674
2839
|
}
|
|
2675
2840
|
console.log("[CLINIC_ADMIN] Preparing admin data object");
|
|
2676
2841
|
const adminData = {
|
|
2677
|
-
id: doc4(
|
|
2842
|
+
id: doc4(collection3(db, CLINIC_ADMINS_COLLECTION)).id,
|
|
2678
2843
|
// Generate a new ID for the admin document
|
|
2679
2844
|
userRef: validatedData.userRef,
|
|
2680
2845
|
clinicGroupId: clinicGroupId || "",
|
|
@@ -2766,23 +2931,23 @@ async function getClinicAdmin(db, adminId) {
|
|
|
2766
2931
|
return null;
|
|
2767
2932
|
}
|
|
2768
2933
|
async function getClinicAdminByUserRef(db, userRef) {
|
|
2769
|
-
const q =
|
|
2770
|
-
|
|
2771
|
-
|
|
2934
|
+
const q = query3(
|
|
2935
|
+
collection3(db, CLINIC_ADMINS_COLLECTION),
|
|
2936
|
+
where3("userRef", "==", userRef)
|
|
2772
2937
|
);
|
|
2773
|
-
const querySnapshot = await
|
|
2938
|
+
const querySnapshot = await getDocs3(q);
|
|
2774
2939
|
if (querySnapshot.empty) {
|
|
2775
2940
|
return null;
|
|
2776
2941
|
}
|
|
2777
2942
|
return querySnapshot.docs[0].data();
|
|
2778
2943
|
}
|
|
2779
2944
|
async function getClinicAdminsByGroup(db, clinicGroupId) {
|
|
2780
|
-
const q =
|
|
2781
|
-
|
|
2782
|
-
|
|
2945
|
+
const q = query3(
|
|
2946
|
+
collection3(db, CLINIC_ADMINS_COLLECTION),
|
|
2947
|
+
where3("clinicGroupId", "==", clinicGroupId)
|
|
2783
2948
|
);
|
|
2784
|
-
const querySnapshot = await
|
|
2785
|
-
return querySnapshot.docs.map((
|
|
2949
|
+
const querySnapshot = await getDocs3(q);
|
|
2950
|
+
return querySnapshot.docs.map((doc27) => doc27.data());
|
|
2786
2951
|
}
|
|
2787
2952
|
async function updateClinicAdmin(db, adminId, data) {
|
|
2788
2953
|
const admin = await getClinicAdmin(db, adminId);
|
|
@@ -3047,12 +3212,12 @@ var ClinicAdminService = class extends BaseService {
|
|
|
3047
3212
|
|
|
3048
3213
|
// src/services/practitioner/practitioner.service.ts
|
|
3049
3214
|
import {
|
|
3050
|
-
collection as
|
|
3215
|
+
collection as collection4,
|
|
3051
3216
|
doc as doc5,
|
|
3052
3217
|
getDoc as getDoc9,
|
|
3053
|
-
getDocs as
|
|
3054
|
-
query as
|
|
3055
|
-
where as
|
|
3218
|
+
getDocs as getDocs4,
|
|
3219
|
+
query as query4,
|
|
3220
|
+
where as where4,
|
|
3056
3221
|
updateDoc as updateDoc8,
|
|
3057
3222
|
setDoc as setDoc7,
|
|
3058
3223
|
deleteDoc as deleteDoc2,
|
|
@@ -3439,17 +3604,17 @@ var PractitionerService = class extends BaseService {
|
|
|
3439
3604
|
* @returns Array of active tokens
|
|
3440
3605
|
*/
|
|
3441
3606
|
async getPractitionerActiveTokens(practitionerId) {
|
|
3442
|
-
const tokensRef =
|
|
3607
|
+
const tokensRef = collection4(
|
|
3443
3608
|
this.db,
|
|
3444
3609
|
`${PRACTITIONERS_COLLECTION}/${practitionerId}/${REGISTER_TOKENS_COLLECTION}`
|
|
3445
3610
|
);
|
|
3446
|
-
const q =
|
|
3611
|
+
const q = query4(
|
|
3447
3612
|
tokensRef,
|
|
3448
|
-
|
|
3449
|
-
|
|
3613
|
+
where4("status", "==", "active" /* ACTIVE */),
|
|
3614
|
+
where4("expiresAt", ">", Timestamp8.now())
|
|
3450
3615
|
);
|
|
3451
|
-
const querySnapshot = await
|
|
3452
|
-
return querySnapshot.docs.map((
|
|
3616
|
+
const querySnapshot = await getDocs4(q);
|
|
3617
|
+
return querySnapshot.docs.map((doc27) => doc27.data());
|
|
3453
3618
|
}
|
|
3454
3619
|
/**
|
|
3455
3620
|
* Gets a token by its string value and validates it
|
|
@@ -3457,21 +3622,21 @@ var PractitionerService = class extends BaseService {
|
|
|
3457
3622
|
* @returns The token if found and valid, null otherwise
|
|
3458
3623
|
*/
|
|
3459
3624
|
async validateToken(tokenString) {
|
|
3460
|
-
const practitionersRef =
|
|
3461
|
-
const practitionersSnapshot = await
|
|
3625
|
+
const practitionersRef = collection4(this.db, PRACTITIONERS_COLLECTION);
|
|
3626
|
+
const practitionersSnapshot = await getDocs4(practitionersRef);
|
|
3462
3627
|
for (const practitionerDoc of practitionersSnapshot.docs) {
|
|
3463
3628
|
const practitionerId = practitionerDoc.id;
|
|
3464
|
-
const tokensRef =
|
|
3629
|
+
const tokensRef = collection4(
|
|
3465
3630
|
this.db,
|
|
3466
3631
|
`${PRACTITIONERS_COLLECTION}/${practitionerId}/${REGISTER_TOKENS_COLLECTION}`
|
|
3467
3632
|
);
|
|
3468
|
-
const q =
|
|
3633
|
+
const q = query4(
|
|
3469
3634
|
tokensRef,
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3635
|
+
where4("token", "==", tokenString),
|
|
3636
|
+
where4("status", "==", "active" /* ACTIVE */),
|
|
3637
|
+
where4("expiresAt", ">", Timestamp8.now())
|
|
3473
3638
|
);
|
|
3474
|
-
const tokenSnapshot = await
|
|
3639
|
+
const tokenSnapshot = await getDocs4(q);
|
|
3475
3640
|
if (!tokenSnapshot.empty) {
|
|
3476
3641
|
return tokenSnapshot.docs[0].data();
|
|
3477
3642
|
}
|
|
@@ -3511,11 +3676,11 @@ var PractitionerService = class extends BaseService {
|
|
|
3511
3676
|
* Dohvata zdravstvenog radnika po User ID-u
|
|
3512
3677
|
*/
|
|
3513
3678
|
async getPractitionerByUserRef(userRef) {
|
|
3514
|
-
const q =
|
|
3515
|
-
|
|
3516
|
-
|
|
3679
|
+
const q = query4(
|
|
3680
|
+
collection4(this.db, PRACTITIONERS_COLLECTION),
|
|
3681
|
+
where4("userRef", "==", userRef)
|
|
3517
3682
|
);
|
|
3518
|
-
const querySnapshot = await
|
|
3683
|
+
const querySnapshot = await getDocs4(q);
|
|
3519
3684
|
if (querySnapshot.empty) {
|
|
3520
3685
|
return null;
|
|
3521
3686
|
}
|
|
@@ -3525,38 +3690,38 @@ var PractitionerService = class extends BaseService {
|
|
|
3525
3690
|
* Dohvata sve zdravstvene radnike za određenu kliniku sa statusom ACTIVE
|
|
3526
3691
|
*/
|
|
3527
3692
|
async getPractitionersByClinic(clinicId) {
|
|
3528
|
-
const q =
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3693
|
+
const q = query4(
|
|
3694
|
+
collection4(this.db, PRACTITIONERS_COLLECTION),
|
|
3695
|
+
where4("clinics", "array-contains", clinicId),
|
|
3696
|
+
where4("isActive", "==", true),
|
|
3697
|
+
where4("status", "==", "active" /* ACTIVE */)
|
|
3533
3698
|
);
|
|
3534
|
-
const querySnapshot = await
|
|
3535
|
-
return querySnapshot.docs.map((
|
|
3699
|
+
const querySnapshot = await getDocs4(q);
|
|
3700
|
+
return querySnapshot.docs.map((doc27) => doc27.data());
|
|
3536
3701
|
}
|
|
3537
3702
|
/**
|
|
3538
3703
|
* Dohvata sve zdravstvene radnike za određenu kliniku
|
|
3539
3704
|
*/
|
|
3540
3705
|
async getAllPractitionersByClinic(clinicId) {
|
|
3541
|
-
const q =
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3706
|
+
const q = query4(
|
|
3707
|
+
collection4(this.db, PRACTITIONERS_COLLECTION),
|
|
3708
|
+
where4("clinics", "array-contains", clinicId),
|
|
3709
|
+
where4("isActive", "==", true)
|
|
3545
3710
|
);
|
|
3546
|
-
const querySnapshot = await
|
|
3547
|
-
return querySnapshot.docs.map((
|
|
3711
|
+
const querySnapshot = await getDocs4(q);
|
|
3712
|
+
return querySnapshot.docs.map((doc27) => doc27.data());
|
|
3548
3713
|
}
|
|
3549
3714
|
/**
|
|
3550
3715
|
* Dohvata sve draft zdravstvene radnike za određenu kliniku sa statusom DRAFT
|
|
3551
3716
|
*/
|
|
3552
3717
|
async getDraftPractitionersByClinic(clinicId) {
|
|
3553
|
-
const q =
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3718
|
+
const q = query4(
|
|
3719
|
+
collection4(this.db, PRACTITIONERS_COLLECTION),
|
|
3720
|
+
where4("clinics", "array-contains", clinicId),
|
|
3721
|
+
where4("status", "==", "draft" /* DRAFT */)
|
|
3557
3722
|
);
|
|
3558
|
-
const querySnapshot = await
|
|
3559
|
-
return querySnapshot.docs.map((
|
|
3723
|
+
const querySnapshot = await getDocs4(q);
|
|
3724
|
+
return querySnapshot.docs.map((doc27) => doc27.data());
|
|
3560
3725
|
}
|
|
3561
3726
|
/**
|
|
3562
3727
|
* Ažurira profil zdravstvenog radnika
|
|
@@ -3852,20 +4017,20 @@ var UserService = class extends BaseService {
|
|
|
3852
4017
|
* Dohvata korisnika po email-u
|
|
3853
4018
|
*/
|
|
3854
4019
|
async getUserByEmail(email) {
|
|
3855
|
-
const usersRef =
|
|
3856
|
-
const q =
|
|
3857
|
-
const querySnapshot = await
|
|
4020
|
+
const usersRef = collection5(this.db, USERS_COLLECTION);
|
|
4021
|
+
const q = query5(usersRef, where5("email", "==", email));
|
|
4022
|
+
const querySnapshot = await getDocs5(q);
|
|
3858
4023
|
if (querySnapshot.empty) return null;
|
|
3859
4024
|
const userData = querySnapshot.docs[0].data();
|
|
3860
4025
|
return userSchema.parse(userData);
|
|
3861
4026
|
}
|
|
3862
4027
|
async getUsersByRole(role) {
|
|
3863
4028
|
const constraints = [
|
|
3864
|
-
|
|
4029
|
+
where5("roles", "array-contains", role)
|
|
3865
4030
|
];
|
|
3866
|
-
const q =
|
|
3867
|
-
const querySnapshot = await
|
|
3868
|
-
const users = querySnapshot.docs.map((
|
|
4031
|
+
const q = query5(collection5(this.db, USERS_COLLECTION), ...constraints);
|
|
4032
|
+
const querySnapshot = await getDocs5(q);
|
|
4033
|
+
const users = querySnapshot.docs.map((doc27) => doc27.data());
|
|
3869
4034
|
return Promise.all(users.map((userData) => userSchema.parse(userData)));
|
|
3870
4035
|
}
|
|
3871
4036
|
/**
|
|
@@ -4002,12 +4167,12 @@ var UserService = class extends BaseService {
|
|
|
4002
4167
|
|
|
4003
4168
|
// src/services/clinic/utils/clinic-group.utils.ts
|
|
4004
4169
|
import {
|
|
4005
|
-
collection as
|
|
4170
|
+
collection as collection6,
|
|
4006
4171
|
doc as doc7,
|
|
4007
4172
|
getDoc as getDoc11,
|
|
4008
|
-
getDocs as
|
|
4009
|
-
query as
|
|
4010
|
-
where as
|
|
4173
|
+
getDocs as getDocs6,
|
|
4174
|
+
query as query6,
|
|
4175
|
+
where as where6,
|
|
4011
4176
|
updateDoc as updateDoc10,
|
|
4012
4177
|
setDoc as setDoc9,
|
|
4013
4178
|
Timestamp as Timestamp10
|
|
@@ -4136,7 +4301,7 @@ async function createClinicGroup(db, data, ownerId, isDefault = false, clinicAdm
|
|
|
4136
4301
|
}
|
|
4137
4302
|
const now = Timestamp10.now();
|
|
4138
4303
|
console.log("[CLINIC_GROUP] Preparing clinic group data object");
|
|
4139
|
-
const groupId = doc7(
|
|
4304
|
+
const groupId = doc7(collection6(db, CLINIC_GROUPS_COLLECTION)).id;
|
|
4140
4305
|
console.log("[CLINIC_GROUP] Logo value:", {
|
|
4141
4306
|
logoValue: validatedData.logo,
|
|
4142
4307
|
logoType: validatedData.logo === null ? "null" : typeof validatedData.logo
|
|
@@ -4240,12 +4405,12 @@ async function getClinicGroup(db, groupId) {
|
|
|
4240
4405
|
return null;
|
|
4241
4406
|
}
|
|
4242
4407
|
async function getAllActiveGroups(db) {
|
|
4243
|
-
const q =
|
|
4244
|
-
|
|
4245
|
-
|
|
4408
|
+
const q = query6(
|
|
4409
|
+
collection6(db, CLINIC_GROUPS_COLLECTION),
|
|
4410
|
+
where6("isActive", "==", true)
|
|
4246
4411
|
);
|
|
4247
|
-
const querySnapshot = await
|
|
4248
|
-
return querySnapshot.docs.map((
|
|
4412
|
+
const querySnapshot = await getDocs6(q);
|
|
4413
|
+
return querySnapshot.docs.map((doc27) => doc27.data());
|
|
4249
4414
|
}
|
|
4250
4415
|
async function updateClinicGroup(db, groupId, data, app) {
|
|
4251
4416
|
console.log("[CLINIC_GROUP] Updating clinic group", { groupId });
|
|
@@ -4359,6 +4524,7 @@ async function createAdminToken(db, groupId, creatorAdminId, app, data) {
|
|
|
4359
4524
|
}
|
|
4360
4525
|
const now = Timestamp10.now();
|
|
4361
4526
|
const expiresInDays = (data == null ? void 0 : data.expiresInDays) || 7;
|
|
4527
|
+
const email = (data == null ? void 0 : data.email) || null;
|
|
4362
4528
|
const expiresAt = new Timestamp10(
|
|
4363
4529
|
now.seconds + expiresInDays * 24 * 60 * 60,
|
|
4364
4530
|
now.nanoseconds
|
|
@@ -4367,6 +4533,7 @@ async function createAdminToken(db, groupId, creatorAdminId, app, data) {
|
|
|
4367
4533
|
id: generateId(),
|
|
4368
4534
|
token: generateId(),
|
|
4369
4535
|
status: "active" /* ACTIVE */,
|
|
4536
|
+
email,
|
|
4370
4537
|
createdAt: now,
|
|
4371
4538
|
expiresAt
|
|
4372
4539
|
};
|
|
@@ -4619,12 +4786,12 @@ var ClinicGroupService = class extends BaseService {
|
|
|
4619
4786
|
|
|
4620
4787
|
// src/services/clinic/utils/clinic.utils.ts
|
|
4621
4788
|
import {
|
|
4622
|
-
collection as
|
|
4789
|
+
collection as collection7,
|
|
4623
4790
|
doc as doc8,
|
|
4624
4791
|
getDoc as getDoc12,
|
|
4625
|
-
getDocs as
|
|
4626
|
-
query as
|
|
4627
|
-
where as
|
|
4792
|
+
getDocs as getDocs7,
|
|
4793
|
+
query as query7,
|
|
4794
|
+
where as where7,
|
|
4628
4795
|
updateDoc as updateDoc11,
|
|
4629
4796
|
setDoc as setDoc10,
|
|
4630
4797
|
Timestamp as Timestamp11
|
|
@@ -4693,7 +4860,7 @@ async function createClinic(db, data, creatorAdminId, clinicGroupService, clinic
|
|
|
4693
4860
|
throw geohashError;
|
|
4694
4861
|
}
|
|
4695
4862
|
}
|
|
4696
|
-
const clinicId = doc8(
|
|
4863
|
+
const clinicId = doc8(collection7(db, CLINICS_COLLECTION)).id;
|
|
4697
4864
|
console.log("[CLINIC] Generated clinic ID:", clinicId);
|
|
4698
4865
|
console.log("[CLINIC] Processing photos");
|
|
4699
4866
|
let logoUrl = null;
|
|
@@ -4909,13 +5076,13 @@ async function getClinic(db, clinicId) {
|
|
|
4909
5076
|
return null;
|
|
4910
5077
|
}
|
|
4911
5078
|
async function getClinicsByGroup(db, groupId) {
|
|
4912
|
-
const q =
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
|
|
5079
|
+
const q = query7(
|
|
5080
|
+
collection7(db, CLINICS_COLLECTION),
|
|
5081
|
+
where7("clinicGroupId", "==", groupId),
|
|
5082
|
+
where7("isActive", "==", true)
|
|
4916
5083
|
);
|
|
4917
|
-
const querySnapshot = await
|
|
4918
|
-
return querySnapshot.docs.map((
|
|
5084
|
+
const querySnapshot = await getDocs7(q);
|
|
5085
|
+
return querySnapshot.docs.map((doc27) => doc27.data());
|
|
4919
5086
|
}
|
|
4920
5087
|
async function updateClinic(db, clinicId, data, adminId, clinicAdminService, app) {
|
|
4921
5088
|
console.log("[CLINIC] Starting clinic update", { clinicId, adminId });
|
|
@@ -5121,13 +5288,13 @@ async function getClinicsByAdmin(db, adminId, options = {}, clinicAdminService,
|
|
|
5121
5288
|
if (clinicIds.length === 0) {
|
|
5122
5289
|
return [];
|
|
5123
5290
|
}
|
|
5124
|
-
const constraints = [
|
|
5291
|
+
const constraints = [where7("id", "in", clinicIds)];
|
|
5125
5292
|
if (options.isActive !== void 0) {
|
|
5126
|
-
constraints.push(
|
|
5293
|
+
constraints.push(where7("isActive", "==", options.isActive));
|
|
5127
5294
|
}
|
|
5128
|
-
const q =
|
|
5129
|
-
const querySnapshot = await
|
|
5130
|
-
return querySnapshot.docs.map((
|
|
5295
|
+
const q = query7(collection7(db, CLINICS_COLLECTION), ...constraints);
|
|
5296
|
+
const querySnapshot = await getDocs7(q);
|
|
5297
|
+
return querySnapshot.docs.map((doc27) => doc27.data());
|
|
5131
5298
|
}
|
|
5132
5299
|
async function getActiveClinicsByAdmin(db, adminId, clinicAdminService, clinicGroupService) {
|
|
5133
5300
|
return getClinicsByAdmin(
|
|
@@ -5141,7 +5308,7 @@ async function getActiveClinicsByAdmin(db, adminId, clinicAdminService, clinicGr
|
|
|
5141
5308
|
|
|
5142
5309
|
// src/services/clinic/utils/review.utils.ts
|
|
5143
5310
|
import {
|
|
5144
|
-
collection as
|
|
5311
|
+
collection as collection8,
|
|
5145
5312
|
doc as doc9,
|
|
5146
5313
|
Timestamp as Timestamp12,
|
|
5147
5314
|
getDoc as getDoc13,
|
|
@@ -5157,14 +5324,14 @@ async function addReview(db, clinicId, review, app) {
|
|
|
5157
5324
|
const now = Timestamp12.now();
|
|
5158
5325
|
const reviewData = {
|
|
5159
5326
|
...review,
|
|
5160
|
-
id: doc9(
|
|
5327
|
+
id: doc9(collection8(db, "clinic_reviews")).id,
|
|
5161
5328
|
clinicId,
|
|
5162
5329
|
createdAt: now,
|
|
5163
5330
|
updatedAt: now,
|
|
5164
5331
|
isVerified: false
|
|
5165
5332
|
};
|
|
5166
5333
|
clinicReviewSchema.parse(reviewData);
|
|
5167
|
-
await addDoc2(
|
|
5334
|
+
await addDoc2(collection8(db, "clinic_reviews"), reviewData);
|
|
5168
5335
|
const newRating = clinic.rating ? {
|
|
5169
5336
|
average: (clinic.rating.average * clinic.rating.count + review.rating) / (clinic.rating.count + 1),
|
|
5170
5337
|
count: clinic.rating.count + 1
|
|
@@ -5252,10 +5419,10 @@ async function removeTags(db, clinicId, adminId, tagsToRemove, clinicAdminServic
|
|
|
5252
5419
|
|
|
5253
5420
|
// src/services/clinic/utils/search.utils.ts
|
|
5254
5421
|
import {
|
|
5255
|
-
collection as
|
|
5256
|
-
query as
|
|
5257
|
-
where as
|
|
5258
|
-
getDocs as
|
|
5422
|
+
collection as collection9,
|
|
5423
|
+
query as query8,
|
|
5424
|
+
where as where8,
|
|
5425
|
+
getDocs as getDocs8
|
|
5259
5426
|
} from "firebase/firestore";
|
|
5260
5427
|
import { geohashQueryBounds, distanceBetween } from "geofire-common";
|
|
5261
5428
|
async function findClinicsInRadius(db, center, radiusInKm, filters) {
|
|
@@ -5266,22 +5433,22 @@ async function findClinicsInRadius(db, center, radiusInKm, filters) {
|
|
|
5266
5433
|
const matchingDocs = [];
|
|
5267
5434
|
for (const b of bounds) {
|
|
5268
5435
|
const constraints = [
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5436
|
+
where8("location.geohash", ">=", b[0]),
|
|
5437
|
+
where8("location.geohash", "<=", b[1]),
|
|
5438
|
+
where8("isActive", "==", true)
|
|
5272
5439
|
];
|
|
5273
5440
|
if (filters == null ? void 0 : filters.services) {
|
|
5274
5441
|
constraints.push(
|
|
5275
|
-
|
|
5442
|
+
where8("services", "array-contains-any", filters.services)
|
|
5276
5443
|
);
|
|
5277
5444
|
}
|
|
5278
5445
|
if ((filters == null ? void 0 : filters.tags) && filters.tags.length > 0) {
|
|
5279
|
-
constraints.push(
|
|
5446
|
+
constraints.push(where8("tags", "array-contains-any", filters.tags));
|
|
5280
5447
|
}
|
|
5281
|
-
const q =
|
|
5282
|
-
const querySnapshot = await
|
|
5283
|
-
for (const
|
|
5284
|
-
const clinic =
|
|
5448
|
+
const q = query8(collection9(db, CLINICS_COLLECTION), ...constraints);
|
|
5449
|
+
const querySnapshot = await getDocs8(q);
|
|
5450
|
+
for (const doc27 of querySnapshot.docs) {
|
|
5451
|
+
const clinic = doc27.data();
|
|
5285
5452
|
const distance = distanceBetween(
|
|
5286
5453
|
[center.latitude, center.longitude],
|
|
5287
5454
|
[clinic.location.latitude, clinic.location.longitude]
|
|
@@ -5695,9 +5862,9 @@ var AuthService = class extends BaseService {
|
|
|
5695
5862
|
token: data.inviteToken
|
|
5696
5863
|
});
|
|
5697
5864
|
console.log("[AUTH] Searching for token in clinic groups");
|
|
5698
|
-
const groupsRef =
|
|
5699
|
-
const q =
|
|
5700
|
-
const querySnapshot = await
|
|
5865
|
+
const groupsRef = collection10(this.db, CLINIC_GROUPS_COLLECTION);
|
|
5866
|
+
const q = query9(groupsRef);
|
|
5867
|
+
const querySnapshot = await getDocs9(q);
|
|
5701
5868
|
let foundGroup = null;
|
|
5702
5869
|
let foundToken = null;
|
|
5703
5870
|
console.log(
|
|
@@ -6144,12 +6311,12 @@ var AuthService = class extends BaseService {
|
|
|
6144
6311
|
|
|
6145
6312
|
// src/services/notifications/notification.service.ts
|
|
6146
6313
|
import {
|
|
6147
|
-
collection as
|
|
6314
|
+
collection as collection11,
|
|
6148
6315
|
doc as doc11,
|
|
6149
6316
|
getDoc as getDoc15,
|
|
6150
|
-
getDocs as
|
|
6151
|
-
query as
|
|
6152
|
-
where as
|
|
6317
|
+
getDocs as getDocs10,
|
|
6318
|
+
query as query10,
|
|
6319
|
+
where as where10,
|
|
6153
6320
|
updateDoc as updateDoc13,
|
|
6154
6321
|
deleteDoc as deleteDoc6,
|
|
6155
6322
|
orderBy,
|
|
@@ -6182,7 +6349,7 @@ var NotificationService = class extends BaseService {
|
|
|
6182
6349
|
* Kreira novu notifikaciju
|
|
6183
6350
|
*/
|
|
6184
6351
|
async createNotification(notification) {
|
|
6185
|
-
const notificationsRef =
|
|
6352
|
+
const notificationsRef = collection11(this.db, NOTIFICATIONS_COLLECTION);
|
|
6186
6353
|
const now = Timestamp14.now();
|
|
6187
6354
|
const notificationData = {
|
|
6188
6355
|
...notification,
|
|
@@ -6220,31 +6387,31 @@ var NotificationService = class extends BaseService {
|
|
|
6220
6387
|
* Dohvata sve notifikacije za korisnika
|
|
6221
6388
|
*/
|
|
6222
6389
|
async getUserNotifications(userId) {
|
|
6223
|
-
const q =
|
|
6224
|
-
|
|
6225
|
-
|
|
6390
|
+
const q = query10(
|
|
6391
|
+
collection11(this.db, NOTIFICATIONS_COLLECTION),
|
|
6392
|
+
where10("userId", "==", userId),
|
|
6226
6393
|
orderBy("notificationTime", "desc")
|
|
6227
6394
|
);
|
|
6228
|
-
const querySnapshot = await
|
|
6229
|
-
return querySnapshot.docs.map((
|
|
6230
|
-
id:
|
|
6231
|
-
...
|
|
6395
|
+
const querySnapshot = await getDocs10(q);
|
|
6396
|
+
return querySnapshot.docs.map((doc27) => ({
|
|
6397
|
+
id: doc27.id,
|
|
6398
|
+
...doc27.data()
|
|
6232
6399
|
}));
|
|
6233
6400
|
}
|
|
6234
6401
|
/**
|
|
6235
6402
|
* Dohvata nepročitane notifikacije za korisnika
|
|
6236
6403
|
*/
|
|
6237
6404
|
async getUnreadNotifications(userId) {
|
|
6238
|
-
const q =
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6405
|
+
const q = query10(
|
|
6406
|
+
collection11(this.db, NOTIFICATIONS_COLLECTION),
|
|
6407
|
+
where10("userId", "==", userId),
|
|
6408
|
+
where10("isRead", "==", false),
|
|
6242
6409
|
orderBy("notificationTime", "desc")
|
|
6243
6410
|
);
|
|
6244
|
-
const querySnapshot = await
|
|
6245
|
-
return querySnapshot.docs.map((
|
|
6246
|
-
id:
|
|
6247
|
-
...
|
|
6411
|
+
const querySnapshot = await getDocs10(q);
|
|
6412
|
+
return querySnapshot.docs.map((doc27) => ({
|
|
6413
|
+
id: doc27.id,
|
|
6414
|
+
...doc27.data()
|
|
6248
6415
|
}));
|
|
6249
6416
|
}
|
|
6250
6417
|
/**
|
|
@@ -6309,43 +6476,43 @@ var NotificationService = class extends BaseService {
|
|
|
6309
6476
|
* Dohvata notifikacije po tipu
|
|
6310
6477
|
*/
|
|
6311
6478
|
async getNotificationsByType(userId, type) {
|
|
6312
|
-
const q =
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
|
|
6479
|
+
const q = query10(
|
|
6480
|
+
collection11(this.db, NOTIFICATIONS_COLLECTION),
|
|
6481
|
+
where10("userId", "==", userId),
|
|
6482
|
+
where10("notificationType", "==", type),
|
|
6316
6483
|
orderBy("notificationTime", "desc")
|
|
6317
6484
|
);
|
|
6318
|
-
const querySnapshot = await
|
|
6319
|
-
return querySnapshot.docs.map((
|
|
6320
|
-
id:
|
|
6321
|
-
...
|
|
6485
|
+
const querySnapshot = await getDocs10(q);
|
|
6486
|
+
return querySnapshot.docs.map((doc27) => ({
|
|
6487
|
+
id: doc27.id,
|
|
6488
|
+
...doc27.data()
|
|
6322
6489
|
}));
|
|
6323
6490
|
}
|
|
6324
6491
|
/**
|
|
6325
6492
|
* Dohvata notifikacije za određeni termin
|
|
6326
6493
|
*/
|
|
6327
6494
|
async getAppointmentNotifications(appointmentId) {
|
|
6328
|
-
const q =
|
|
6329
|
-
|
|
6330
|
-
|
|
6495
|
+
const q = query10(
|
|
6496
|
+
collection11(this.db, NOTIFICATIONS_COLLECTION),
|
|
6497
|
+
where10("appointmentId", "==", appointmentId),
|
|
6331
6498
|
orderBy("notificationTime", "desc")
|
|
6332
6499
|
);
|
|
6333
|
-
const querySnapshot = await
|
|
6334
|
-
return querySnapshot.docs.map((
|
|
6335
|
-
id:
|
|
6336
|
-
...
|
|
6500
|
+
const querySnapshot = await getDocs10(q);
|
|
6501
|
+
return querySnapshot.docs.map((doc27) => ({
|
|
6502
|
+
id: doc27.id,
|
|
6503
|
+
...doc27.data()
|
|
6337
6504
|
}));
|
|
6338
6505
|
}
|
|
6339
6506
|
};
|
|
6340
6507
|
|
|
6341
6508
|
// src/services/procedure/procedure.service.ts
|
|
6342
6509
|
import {
|
|
6343
|
-
collection as
|
|
6510
|
+
collection as collection12,
|
|
6344
6511
|
doc as doc12,
|
|
6345
6512
|
getDoc as getDoc16,
|
|
6346
|
-
getDocs as
|
|
6347
|
-
query as
|
|
6348
|
-
where as
|
|
6513
|
+
getDocs as getDocs11,
|
|
6514
|
+
query as query11,
|
|
6515
|
+
where as where11,
|
|
6349
6516
|
updateDoc as updateDoc14,
|
|
6350
6517
|
setDoc as setDoc13,
|
|
6351
6518
|
serverTimestamp as serverTimestamp13
|
|
@@ -6485,13 +6652,13 @@ var ProcedureService = class extends BaseService {
|
|
|
6485
6652
|
* @returns List of procedures
|
|
6486
6653
|
*/
|
|
6487
6654
|
async getProceduresByClinicBranch(clinicBranchId) {
|
|
6488
|
-
const q =
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6655
|
+
const q = query11(
|
|
6656
|
+
collection12(this.db, PROCEDURES_COLLECTION),
|
|
6657
|
+
where11("clinicBranchId", "==", clinicBranchId),
|
|
6658
|
+
where11("isActive", "==", true)
|
|
6492
6659
|
);
|
|
6493
|
-
const snapshot = await
|
|
6494
|
-
return snapshot.docs.map((
|
|
6660
|
+
const snapshot = await getDocs11(q);
|
|
6661
|
+
return snapshot.docs.map((doc27) => doc27.data());
|
|
6495
6662
|
}
|
|
6496
6663
|
/**
|
|
6497
6664
|
* Gets all procedures for a practitioner
|
|
@@ -6499,13 +6666,13 @@ var ProcedureService = class extends BaseService {
|
|
|
6499
6666
|
* @returns List of procedures
|
|
6500
6667
|
*/
|
|
6501
6668
|
async getProceduresByPractitioner(practitionerId) {
|
|
6502
|
-
const q =
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
|
|
6669
|
+
const q = query11(
|
|
6670
|
+
collection12(this.db, PROCEDURES_COLLECTION),
|
|
6671
|
+
where11("practitionerId", "==", practitionerId),
|
|
6672
|
+
where11("isActive", "==", true)
|
|
6506
6673
|
);
|
|
6507
|
-
const snapshot = await
|
|
6508
|
-
return snapshot.docs.map((
|
|
6674
|
+
const snapshot = await getDocs11(q);
|
|
6675
|
+
return snapshot.docs.map((doc27) => doc27.data());
|
|
6509
6676
|
}
|
|
6510
6677
|
/**
|
|
6511
6678
|
* Updates a procedure
|
|
@@ -6575,15 +6742,15 @@ var ProcedureService = class extends BaseService {
|
|
|
6575
6742
|
|
|
6576
6743
|
// src/services/documentation-templates/documentation-template.service.ts
|
|
6577
6744
|
import {
|
|
6578
|
-
collection as
|
|
6745
|
+
collection as collection13,
|
|
6579
6746
|
doc as doc13,
|
|
6580
6747
|
getDoc as getDoc17,
|
|
6581
|
-
getDocs as
|
|
6748
|
+
getDocs as getDocs12,
|
|
6582
6749
|
setDoc as setDoc14,
|
|
6583
6750
|
updateDoc as updateDoc15,
|
|
6584
6751
|
deleteDoc as deleteDoc8,
|
|
6585
|
-
query as
|
|
6586
|
-
where as
|
|
6752
|
+
query as query12,
|
|
6753
|
+
where as where12,
|
|
6587
6754
|
orderBy as orderBy2,
|
|
6588
6755
|
limit,
|
|
6589
6756
|
startAfter
|
|
@@ -6591,7 +6758,7 @@ import {
|
|
|
6591
6758
|
var DocumentationTemplateService = class extends BaseService {
|
|
6592
6759
|
constructor() {
|
|
6593
6760
|
super(...arguments);
|
|
6594
|
-
this.collectionRef =
|
|
6761
|
+
this.collectionRef = collection13(
|
|
6595
6762
|
this.db,
|
|
6596
6763
|
DOCUMENTATION_TEMPLATES_COLLECTION
|
|
6597
6764
|
);
|
|
@@ -6686,21 +6853,21 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
6686
6853
|
* @returns Array of templates and the last document for pagination
|
|
6687
6854
|
*/
|
|
6688
6855
|
async getActiveTemplates(pageSize = 20, lastDoc) {
|
|
6689
|
-
let q =
|
|
6856
|
+
let q = query12(
|
|
6690
6857
|
this.collectionRef,
|
|
6691
|
-
|
|
6858
|
+
where12("isActive", "==", true),
|
|
6692
6859
|
orderBy2("updatedAt", "desc"),
|
|
6693
6860
|
limit(pageSize)
|
|
6694
6861
|
);
|
|
6695
6862
|
if (lastDoc) {
|
|
6696
|
-
q =
|
|
6863
|
+
q = query12(q, startAfter(lastDoc));
|
|
6697
6864
|
}
|
|
6698
|
-
const querySnapshot = await
|
|
6865
|
+
const querySnapshot = await getDocs12(q);
|
|
6699
6866
|
const templates = [];
|
|
6700
6867
|
let lastVisible = null;
|
|
6701
|
-
querySnapshot.forEach((
|
|
6702
|
-
templates.push(
|
|
6703
|
-
lastVisible =
|
|
6868
|
+
querySnapshot.forEach((doc27) => {
|
|
6869
|
+
templates.push(doc27.data());
|
|
6870
|
+
lastVisible = doc27;
|
|
6704
6871
|
});
|
|
6705
6872
|
return {
|
|
6706
6873
|
templates,
|
|
@@ -6715,22 +6882,22 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
6715
6882
|
* @returns Array of templates and the last document for pagination
|
|
6716
6883
|
*/
|
|
6717
6884
|
async getTemplatesByTags(tags, pageSize = 20, lastDoc) {
|
|
6718
|
-
let q =
|
|
6885
|
+
let q = query12(
|
|
6719
6886
|
this.collectionRef,
|
|
6720
|
-
|
|
6721
|
-
|
|
6887
|
+
where12("isActive", "==", true),
|
|
6888
|
+
where12("tags", "array-contains-any", tags),
|
|
6722
6889
|
orderBy2("updatedAt", "desc"),
|
|
6723
6890
|
limit(pageSize)
|
|
6724
6891
|
);
|
|
6725
6892
|
if (lastDoc) {
|
|
6726
|
-
q =
|
|
6893
|
+
q = query12(q, startAfter(lastDoc));
|
|
6727
6894
|
}
|
|
6728
|
-
const querySnapshot = await
|
|
6895
|
+
const querySnapshot = await getDocs12(q);
|
|
6729
6896
|
const templates = [];
|
|
6730
6897
|
let lastVisible = null;
|
|
6731
|
-
querySnapshot.forEach((
|
|
6732
|
-
templates.push(
|
|
6733
|
-
lastVisible =
|
|
6898
|
+
querySnapshot.forEach((doc27) => {
|
|
6899
|
+
templates.push(doc27.data());
|
|
6900
|
+
lastVisible = doc27;
|
|
6734
6901
|
});
|
|
6735
6902
|
return {
|
|
6736
6903
|
templates,
|
|
@@ -6745,21 +6912,21 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
6745
6912
|
* @returns Array of templates and the last document for pagination
|
|
6746
6913
|
*/
|
|
6747
6914
|
async getTemplatesByCreator(userId, pageSize = 20, lastDoc) {
|
|
6748
|
-
let q =
|
|
6915
|
+
let q = query12(
|
|
6749
6916
|
this.collectionRef,
|
|
6750
|
-
|
|
6917
|
+
where12("createdBy", "==", userId),
|
|
6751
6918
|
orderBy2("updatedAt", "desc"),
|
|
6752
6919
|
limit(pageSize)
|
|
6753
6920
|
);
|
|
6754
6921
|
if (lastDoc) {
|
|
6755
|
-
q =
|
|
6922
|
+
q = query12(q, startAfter(lastDoc));
|
|
6756
6923
|
}
|
|
6757
|
-
const querySnapshot = await
|
|
6924
|
+
const querySnapshot = await getDocs12(q);
|
|
6758
6925
|
const templates = [];
|
|
6759
6926
|
let lastVisible = null;
|
|
6760
|
-
querySnapshot.forEach((
|
|
6761
|
-
templates.push(
|
|
6762
|
-
lastVisible =
|
|
6927
|
+
querySnapshot.forEach((doc27) => {
|
|
6928
|
+
templates.push(doc27.data());
|
|
6929
|
+
lastVisible = doc27;
|
|
6763
6930
|
});
|
|
6764
6931
|
return {
|
|
6765
6932
|
templates,
|
|
@@ -6770,14 +6937,14 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
6770
6937
|
|
|
6771
6938
|
// src/services/documentation-templates/filled-document.service.ts
|
|
6772
6939
|
import {
|
|
6773
|
-
collection as
|
|
6940
|
+
collection as collection14,
|
|
6774
6941
|
doc as doc14,
|
|
6775
6942
|
getDoc as getDoc18,
|
|
6776
|
-
getDocs as
|
|
6943
|
+
getDocs as getDocs13,
|
|
6777
6944
|
setDoc as setDoc15,
|
|
6778
6945
|
updateDoc as updateDoc16,
|
|
6779
|
-
query as
|
|
6780
|
-
where as
|
|
6946
|
+
query as query13,
|
|
6947
|
+
where as where13,
|
|
6781
6948
|
orderBy as orderBy3,
|
|
6782
6949
|
limit as limit2,
|
|
6783
6950
|
startAfter as startAfter2
|
|
@@ -6785,7 +6952,7 @@ import {
|
|
|
6785
6952
|
var FilledDocumentService = class extends BaseService {
|
|
6786
6953
|
constructor(...args) {
|
|
6787
6954
|
super(...args);
|
|
6788
|
-
this.collectionRef =
|
|
6955
|
+
this.collectionRef = collection14(
|
|
6789
6956
|
this.db,
|
|
6790
6957
|
FILLED_DOCUMENTS_COLLECTION
|
|
6791
6958
|
);
|
|
@@ -6872,21 +7039,21 @@ var FilledDocumentService = class extends BaseService {
|
|
|
6872
7039
|
* @returns Array of filled documents and the last document for pagination
|
|
6873
7040
|
*/
|
|
6874
7041
|
async getFilledDocumentsByPatient(patientId, pageSize = 20, lastDoc) {
|
|
6875
|
-
let q =
|
|
7042
|
+
let q = query13(
|
|
6876
7043
|
this.collectionRef,
|
|
6877
|
-
|
|
7044
|
+
where13("patientId", "==", patientId),
|
|
6878
7045
|
orderBy3("updatedAt", "desc"),
|
|
6879
7046
|
limit2(pageSize)
|
|
6880
7047
|
);
|
|
6881
7048
|
if (lastDoc) {
|
|
6882
|
-
q =
|
|
7049
|
+
q = query13(q, startAfter2(lastDoc));
|
|
6883
7050
|
}
|
|
6884
|
-
const querySnapshot = await
|
|
7051
|
+
const querySnapshot = await getDocs13(q);
|
|
6885
7052
|
const documents = [];
|
|
6886
7053
|
let lastVisible = null;
|
|
6887
|
-
querySnapshot.forEach((
|
|
6888
|
-
documents.push(
|
|
6889
|
-
lastVisible =
|
|
7054
|
+
querySnapshot.forEach((doc27) => {
|
|
7055
|
+
documents.push(doc27.data());
|
|
7056
|
+
lastVisible = doc27;
|
|
6890
7057
|
});
|
|
6891
7058
|
return {
|
|
6892
7059
|
documents,
|
|
@@ -6901,21 +7068,21 @@ var FilledDocumentService = class extends BaseService {
|
|
|
6901
7068
|
* @returns Array of filled documents and the last document for pagination
|
|
6902
7069
|
*/
|
|
6903
7070
|
async getFilledDocumentsByPractitioner(practitionerId, pageSize = 20, lastDoc) {
|
|
6904
|
-
let q =
|
|
7071
|
+
let q = query13(
|
|
6905
7072
|
this.collectionRef,
|
|
6906
|
-
|
|
7073
|
+
where13("practitionerId", "==", practitionerId),
|
|
6907
7074
|
orderBy3("updatedAt", "desc"),
|
|
6908
7075
|
limit2(pageSize)
|
|
6909
7076
|
);
|
|
6910
7077
|
if (lastDoc) {
|
|
6911
|
-
q =
|
|
7078
|
+
q = query13(q, startAfter2(lastDoc));
|
|
6912
7079
|
}
|
|
6913
|
-
const querySnapshot = await
|
|
7080
|
+
const querySnapshot = await getDocs13(q);
|
|
6914
7081
|
const documents = [];
|
|
6915
7082
|
let lastVisible = null;
|
|
6916
|
-
querySnapshot.forEach((
|
|
6917
|
-
documents.push(
|
|
6918
|
-
lastVisible =
|
|
7083
|
+
querySnapshot.forEach((doc27) => {
|
|
7084
|
+
documents.push(doc27.data());
|
|
7085
|
+
lastVisible = doc27;
|
|
6919
7086
|
});
|
|
6920
7087
|
return {
|
|
6921
7088
|
documents,
|
|
@@ -6930,21 +7097,21 @@ var FilledDocumentService = class extends BaseService {
|
|
|
6930
7097
|
* @returns Array of filled documents and the last document for pagination
|
|
6931
7098
|
*/
|
|
6932
7099
|
async getFilledDocumentsByClinic(clinicId, pageSize = 20, lastDoc) {
|
|
6933
|
-
let q =
|
|
7100
|
+
let q = query13(
|
|
6934
7101
|
this.collectionRef,
|
|
6935
|
-
|
|
7102
|
+
where13("clinicId", "==", clinicId),
|
|
6936
7103
|
orderBy3("updatedAt", "desc"),
|
|
6937
7104
|
limit2(pageSize)
|
|
6938
7105
|
);
|
|
6939
7106
|
if (lastDoc) {
|
|
6940
|
-
q =
|
|
7107
|
+
q = query13(q, startAfter2(lastDoc));
|
|
6941
7108
|
}
|
|
6942
|
-
const querySnapshot = await
|
|
7109
|
+
const querySnapshot = await getDocs13(q);
|
|
6943
7110
|
const documents = [];
|
|
6944
7111
|
let lastVisible = null;
|
|
6945
|
-
querySnapshot.forEach((
|
|
6946
|
-
documents.push(
|
|
6947
|
-
lastVisible =
|
|
7112
|
+
querySnapshot.forEach((doc27) => {
|
|
7113
|
+
documents.push(doc27.data());
|
|
7114
|
+
lastVisible = doc27;
|
|
6948
7115
|
});
|
|
6949
7116
|
return {
|
|
6950
7117
|
documents,
|
|
@@ -6959,21 +7126,21 @@ var FilledDocumentService = class extends BaseService {
|
|
|
6959
7126
|
* @returns Array of filled documents and the last document for pagination
|
|
6960
7127
|
*/
|
|
6961
7128
|
async getFilledDocumentsByTemplate(templateId, pageSize = 20, lastDoc) {
|
|
6962
|
-
let q =
|
|
7129
|
+
let q = query13(
|
|
6963
7130
|
this.collectionRef,
|
|
6964
|
-
|
|
7131
|
+
where13("templateId", "==", templateId),
|
|
6965
7132
|
orderBy3("updatedAt", "desc"),
|
|
6966
7133
|
limit2(pageSize)
|
|
6967
7134
|
);
|
|
6968
7135
|
if (lastDoc) {
|
|
6969
|
-
q =
|
|
7136
|
+
q = query13(q, startAfter2(lastDoc));
|
|
6970
7137
|
}
|
|
6971
|
-
const querySnapshot = await
|
|
7138
|
+
const querySnapshot = await getDocs13(q);
|
|
6972
7139
|
const documents = [];
|
|
6973
7140
|
let lastVisible = null;
|
|
6974
|
-
querySnapshot.forEach((
|
|
6975
|
-
documents.push(
|
|
6976
|
-
lastVisible =
|
|
7141
|
+
querySnapshot.forEach((doc27) => {
|
|
7142
|
+
documents.push(doc27.data());
|
|
7143
|
+
lastVisible = doc27;
|
|
6977
7144
|
});
|
|
6978
7145
|
return {
|
|
6979
7146
|
documents,
|
|
@@ -6988,21 +7155,21 @@ var FilledDocumentService = class extends BaseService {
|
|
|
6988
7155
|
* @returns Array of filled documents and the last document for pagination
|
|
6989
7156
|
*/
|
|
6990
7157
|
async getFilledDocumentsByStatus(status, pageSize = 20, lastDoc) {
|
|
6991
|
-
let q =
|
|
7158
|
+
let q = query13(
|
|
6992
7159
|
this.collectionRef,
|
|
6993
|
-
|
|
7160
|
+
where13("status", "==", status),
|
|
6994
7161
|
orderBy3("updatedAt", "desc"),
|
|
6995
7162
|
limit2(pageSize)
|
|
6996
7163
|
);
|
|
6997
7164
|
if (lastDoc) {
|
|
6998
|
-
q =
|
|
7165
|
+
q = query13(q, startAfter2(lastDoc));
|
|
6999
7166
|
}
|
|
7000
|
-
const querySnapshot = await
|
|
7167
|
+
const querySnapshot = await getDocs13(q);
|
|
7001
7168
|
const documents = [];
|
|
7002
7169
|
let lastVisible = null;
|
|
7003
|
-
querySnapshot.forEach((
|
|
7004
|
-
documents.push(
|
|
7005
|
-
lastVisible =
|
|
7170
|
+
querySnapshot.forEach((doc27) => {
|
|
7171
|
+
documents.push(doc27.data());
|
|
7172
|
+
lastVisible = doc27;
|
|
7006
7173
|
});
|
|
7007
7174
|
return {
|
|
7008
7175
|
documents,
|
|
@@ -7012,7 +7179,7 @@ var FilledDocumentService = class extends BaseService {
|
|
|
7012
7179
|
};
|
|
7013
7180
|
|
|
7014
7181
|
// src/services/calendar/calendar-refactored.service.ts
|
|
7015
|
-
import { Timestamp as
|
|
7182
|
+
import { Timestamp as Timestamp25, serverTimestamp as serverTimestamp20 } from "firebase/firestore";
|
|
7016
7183
|
|
|
7017
7184
|
// src/types/calendar/synced-calendar.types.ts
|
|
7018
7185
|
var SyncedCalendarProvider = /* @__PURE__ */ ((SyncedCalendarProvider3) => {
|
|
@@ -7025,14 +7192,14 @@ var SYNCED_CALENDARS_COLLECTION = "syncedCalendars";
|
|
|
7025
7192
|
|
|
7026
7193
|
// src/services/calendar/calendar-refactored.service.ts
|
|
7027
7194
|
import {
|
|
7028
|
-
doc as
|
|
7029
|
-
getDoc as
|
|
7030
|
-
collection as
|
|
7031
|
-
query as
|
|
7032
|
-
where as
|
|
7033
|
-
getDocs as
|
|
7034
|
-
setDoc as
|
|
7035
|
-
updateDoc as
|
|
7195
|
+
doc as doc21,
|
|
7196
|
+
getDoc as getDoc24,
|
|
7197
|
+
collection as collection20,
|
|
7198
|
+
query as query19,
|
|
7199
|
+
where as where19,
|
|
7200
|
+
getDocs as getDocs19,
|
|
7201
|
+
setDoc as setDoc21,
|
|
7202
|
+
updateDoc as updateDoc22
|
|
7036
7203
|
} from "firebase/firestore";
|
|
7037
7204
|
|
|
7038
7205
|
// src/validations/calendar.schema.ts
|
|
@@ -7211,15 +7378,15 @@ var calendarEventSchema = z18.object({
|
|
|
7211
7378
|
|
|
7212
7379
|
// src/services/calendar/utils/clinic.utils.ts
|
|
7213
7380
|
import {
|
|
7214
|
-
collection as
|
|
7381
|
+
collection as collection15,
|
|
7215
7382
|
doc as doc16,
|
|
7216
7383
|
getDoc as getDoc19,
|
|
7217
|
-
getDocs as
|
|
7384
|
+
getDocs as getDocs14,
|
|
7218
7385
|
setDoc as setDoc16,
|
|
7219
7386
|
updateDoc as updateDoc17,
|
|
7220
7387
|
deleteDoc as deleteDoc9,
|
|
7221
|
-
query as
|
|
7222
|
-
where as
|
|
7388
|
+
query as query14,
|
|
7389
|
+
where as where14,
|
|
7223
7390
|
orderBy as orderBy4,
|
|
7224
7391
|
Timestamp as Timestamp19,
|
|
7225
7392
|
serverTimestamp as serverTimestamp15
|
|
@@ -7316,14 +7483,14 @@ async function checkAutoConfirmAppointmentsUtil(db, clinicId) {
|
|
|
7316
7483
|
|
|
7317
7484
|
// src/services/calendar/utils/patient.utils.ts
|
|
7318
7485
|
import {
|
|
7319
|
-
collection as
|
|
7486
|
+
collection as collection16,
|
|
7320
7487
|
getDoc as getDoc20,
|
|
7321
|
-
getDocs as
|
|
7488
|
+
getDocs as getDocs15,
|
|
7322
7489
|
setDoc as setDoc17,
|
|
7323
7490
|
updateDoc as updateDoc18,
|
|
7324
7491
|
deleteDoc as deleteDoc10,
|
|
7325
|
-
query as
|
|
7326
|
-
where as
|
|
7492
|
+
query as query15,
|
|
7493
|
+
where as where15,
|
|
7327
7494
|
orderBy as orderBy5,
|
|
7328
7495
|
Timestamp as Timestamp20,
|
|
7329
7496
|
serverTimestamp as serverTimestamp16
|
|
@@ -7360,14 +7527,14 @@ async function updatePatientCalendarEventUtil(db, patientId, eventId, updateData
|
|
|
7360
7527
|
|
|
7361
7528
|
// src/services/calendar/utils/practitioner.utils.ts
|
|
7362
7529
|
import {
|
|
7363
|
-
collection as
|
|
7530
|
+
collection as collection17,
|
|
7364
7531
|
getDoc as getDoc21,
|
|
7365
|
-
getDocs as
|
|
7532
|
+
getDocs as getDocs16,
|
|
7366
7533
|
setDoc as setDoc18,
|
|
7367
7534
|
updateDoc as updateDoc19,
|
|
7368
7535
|
deleteDoc as deleteDoc11,
|
|
7369
|
-
query as
|
|
7370
|
-
where as
|
|
7536
|
+
query as query16,
|
|
7537
|
+
where as where16,
|
|
7371
7538
|
orderBy as orderBy6,
|
|
7372
7539
|
Timestamp as Timestamp21,
|
|
7373
7540
|
serverTimestamp as serverTimestamp17
|
|
@@ -7478,19 +7645,126 @@ async function updateAppointmentUtil(db, clinicId, practitionerId, patientId, ev
|
|
|
7478
7645
|
return clinicEvent;
|
|
7479
7646
|
}
|
|
7480
7647
|
|
|
7481
|
-
// src/services/calendar/utils/
|
|
7648
|
+
// src/services/calendar/utils/calendar-event.utils.ts
|
|
7482
7649
|
import {
|
|
7483
|
-
collection as
|
|
7650
|
+
collection as collection18,
|
|
7651
|
+
doc as doc19,
|
|
7484
7652
|
getDoc as getDoc22,
|
|
7485
|
-
getDocs as
|
|
7653
|
+
getDocs as getDocs17,
|
|
7486
7654
|
setDoc as setDoc19,
|
|
7487
7655
|
updateDoc as updateDoc20,
|
|
7488
7656
|
deleteDoc as deleteDoc12,
|
|
7489
|
-
query as
|
|
7657
|
+
query as query17,
|
|
7658
|
+
where as where17,
|
|
7490
7659
|
orderBy as orderBy7,
|
|
7491
7660
|
Timestamp as Timestamp22,
|
|
7492
7661
|
serverTimestamp as serverTimestamp18
|
|
7493
7662
|
} from "firebase/firestore";
|
|
7663
|
+
async function searchCalendarEventsUtil(db, params) {
|
|
7664
|
+
const { searchLocation, entityId, ...filters } = params;
|
|
7665
|
+
let baseCollectionPath;
|
|
7666
|
+
const constraints = [];
|
|
7667
|
+
switch (searchLocation) {
|
|
7668
|
+
case "practitioner" /* PRACTITIONER */:
|
|
7669
|
+
if (!entityId) {
|
|
7670
|
+
throw new Error(
|
|
7671
|
+
"Practitioner ID (entityId) is required when searching practitioner calendar."
|
|
7672
|
+
);
|
|
7673
|
+
}
|
|
7674
|
+
baseCollectionPath = `${PRACTITIONERS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}`;
|
|
7675
|
+
if (filters.practitionerId && filters.practitionerId !== entityId) {
|
|
7676
|
+
console.warn(
|
|
7677
|
+
`Provided practitionerId filter (${filters.practitionerId}) does not match search entityId (${entityId}). Returning empty results.`
|
|
7678
|
+
);
|
|
7679
|
+
return [];
|
|
7680
|
+
}
|
|
7681
|
+
filters.practitionerId = void 0;
|
|
7682
|
+
break;
|
|
7683
|
+
case "patient" /* PATIENT */:
|
|
7684
|
+
if (!entityId) {
|
|
7685
|
+
throw new Error(
|
|
7686
|
+
"Patient ID (entityId) is required when searching patient calendar."
|
|
7687
|
+
);
|
|
7688
|
+
}
|
|
7689
|
+
baseCollectionPath = `${PATIENTS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}`;
|
|
7690
|
+
if (filters.patientId && filters.patientId !== entityId) {
|
|
7691
|
+
console.warn(
|
|
7692
|
+
`Provided patientId filter (${filters.patientId}) does not match search entityId (${entityId}). Returning empty results.`
|
|
7693
|
+
);
|
|
7694
|
+
return [];
|
|
7695
|
+
}
|
|
7696
|
+
filters.patientId = void 0;
|
|
7697
|
+
break;
|
|
7698
|
+
case "clinic" /* CLINIC */:
|
|
7699
|
+
if (!entityId) {
|
|
7700
|
+
throw new Error(
|
|
7701
|
+
"Clinic ID (entityId) is required when searching clinic-related events."
|
|
7702
|
+
);
|
|
7703
|
+
}
|
|
7704
|
+
baseCollectionPath = CALENDAR_COLLECTION;
|
|
7705
|
+
constraints.push(where17("clinicBranchId", "==", entityId));
|
|
7706
|
+
if (filters.clinicId && filters.clinicId !== entityId) {
|
|
7707
|
+
console.warn(
|
|
7708
|
+
`Provided clinicId filter (${filters.clinicId}) does not match search entityId (${entityId}). Returning empty results.`
|
|
7709
|
+
);
|
|
7710
|
+
return [];
|
|
7711
|
+
}
|
|
7712
|
+
filters.clinicId = void 0;
|
|
7713
|
+
break;
|
|
7714
|
+
default:
|
|
7715
|
+
throw new Error(`Invalid search location: ${searchLocation}`);
|
|
7716
|
+
}
|
|
7717
|
+
const collectionRef = collection18(db, baseCollectionPath);
|
|
7718
|
+
if (filters.clinicId) {
|
|
7719
|
+
constraints.push(where17("clinicBranchId", "==", filters.clinicId));
|
|
7720
|
+
}
|
|
7721
|
+
if (filters.practitionerId) {
|
|
7722
|
+
constraints.push(
|
|
7723
|
+
where17("practitionerProfileId", "==", filters.practitionerId)
|
|
7724
|
+
);
|
|
7725
|
+
}
|
|
7726
|
+
if (filters.patientId) {
|
|
7727
|
+
constraints.push(where17("patientProfileId", "==", filters.patientId));
|
|
7728
|
+
}
|
|
7729
|
+
if (filters.procedureId) {
|
|
7730
|
+
constraints.push(where17("procedureId", "==", filters.procedureId));
|
|
7731
|
+
}
|
|
7732
|
+
if (filters.eventStatus) {
|
|
7733
|
+
constraints.push(where17("status", "==", filters.eventStatus));
|
|
7734
|
+
}
|
|
7735
|
+
if (filters.eventType) {
|
|
7736
|
+
constraints.push(where17("eventType", "==", filters.eventType));
|
|
7737
|
+
}
|
|
7738
|
+
if (filters.dateRange) {
|
|
7739
|
+
constraints.push(where17("eventTime.start", ">=", filters.dateRange.start));
|
|
7740
|
+
constraints.push(where17("eventTime.start", "<=", filters.dateRange.end));
|
|
7741
|
+
}
|
|
7742
|
+
try {
|
|
7743
|
+
const finalQuery = query17(collectionRef, ...constraints);
|
|
7744
|
+
const querySnapshot = await getDocs17(finalQuery);
|
|
7745
|
+
const events = querySnapshot.docs.map(
|
|
7746
|
+
(doc27) => ({ id: doc27.id, ...doc27.data() })
|
|
7747
|
+
);
|
|
7748
|
+
return events;
|
|
7749
|
+
} catch (error) {
|
|
7750
|
+
console.error("Error searching calendar events:", error);
|
|
7751
|
+
return [];
|
|
7752
|
+
}
|
|
7753
|
+
}
|
|
7754
|
+
|
|
7755
|
+
// src/services/calendar/utils/synced-calendar.utils.ts
|
|
7756
|
+
import {
|
|
7757
|
+
collection as collection19,
|
|
7758
|
+
getDoc as getDoc23,
|
|
7759
|
+
getDocs as getDocs18,
|
|
7760
|
+
setDoc as setDoc20,
|
|
7761
|
+
updateDoc as updateDoc21,
|
|
7762
|
+
deleteDoc as deleteDoc13,
|
|
7763
|
+
query as query18,
|
|
7764
|
+
orderBy as orderBy8,
|
|
7765
|
+
Timestamp as Timestamp23,
|
|
7766
|
+
serverTimestamp as serverTimestamp19
|
|
7767
|
+
} from "firebase/firestore";
|
|
7494
7768
|
async function createPractitionerSyncedCalendarUtil(db, practitionerId, calendarData, generateId2) {
|
|
7495
7769
|
const calendarId = generateId2();
|
|
7496
7770
|
const calendarRef = getPractitionerSyncedCalendarDocRef(
|
|
@@ -7501,14 +7775,14 @@ async function createPractitionerSyncedCalendarUtil(db, practitionerId, calendar
|
|
|
7501
7775
|
const newCalendar = {
|
|
7502
7776
|
id: calendarId,
|
|
7503
7777
|
...calendarData,
|
|
7504
|
-
createdAt:
|
|
7505
|
-
updatedAt:
|
|
7778
|
+
createdAt: serverTimestamp19(),
|
|
7779
|
+
updatedAt: serverTimestamp19()
|
|
7506
7780
|
};
|
|
7507
|
-
await
|
|
7781
|
+
await setDoc20(calendarRef, newCalendar);
|
|
7508
7782
|
return {
|
|
7509
7783
|
...newCalendar,
|
|
7510
|
-
createdAt:
|
|
7511
|
-
updatedAt:
|
|
7784
|
+
createdAt: Timestamp23.now(),
|
|
7785
|
+
updatedAt: Timestamp23.now()
|
|
7512
7786
|
};
|
|
7513
7787
|
}
|
|
7514
7788
|
async function createPatientSyncedCalendarUtil(db, patientId, calendarData, generateId2) {
|
|
@@ -7517,14 +7791,14 @@ async function createPatientSyncedCalendarUtil(db, patientId, calendarData, gene
|
|
|
7517
7791
|
const newCalendar = {
|
|
7518
7792
|
id: calendarId,
|
|
7519
7793
|
...calendarData,
|
|
7520
|
-
createdAt:
|
|
7521
|
-
updatedAt:
|
|
7794
|
+
createdAt: serverTimestamp19(),
|
|
7795
|
+
updatedAt: serverTimestamp19()
|
|
7522
7796
|
};
|
|
7523
|
-
await
|
|
7797
|
+
await setDoc20(calendarRef, newCalendar);
|
|
7524
7798
|
return {
|
|
7525
7799
|
...newCalendar,
|
|
7526
|
-
createdAt:
|
|
7527
|
-
updatedAt:
|
|
7800
|
+
createdAt: Timestamp23.now(),
|
|
7801
|
+
updatedAt: Timestamp23.now()
|
|
7528
7802
|
};
|
|
7529
7803
|
}
|
|
7530
7804
|
async function createClinicSyncedCalendarUtil(db, clinicId, calendarData, generateId2) {
|
|
@@ -7533,14 +7807,14 @@ async function createClinicSyncedCalendarUtil(db, clinicId, calendarData, genera
|
|
|
7533
7807
|
const newCalendar = {
|
|
7534
7808
|
id: calendarId,
|
|
7535
7809
|
...calendarData,
|
|
7536
|
-
createdAt:
|
|
7537
|
-
updatedAt:
|
|
7810
|
+
createdAt: serverTimestamp19(),
|
|
7811
|
+
updatedAt: serverTimestamp19()
|
|
7538
7812
|
};
|
|
7539
|
-
await
|
|
7813
|
+
await setDoc20(calendarRef, newCalendar);
|
|
7540
7814
|
return {
|
|
7541
7815
|
...newCalendar,
|
|
7542
|
-
createdAt:
|
|
7543
|
-
updatedAt:
|
|
7816
|
+
createdAt: Timestamp23.now(),
|
|
7817
|
+
updatedAt: Timestamp23.now()
|
|
7544
7818
|
};
|
|
7545
7819
|
}
|
|
7546
7820
|
async function getPractitionerSyncedCalendarUtil(db, practitionerId, calendarId) {
|
|
@@ -7549,54 +7823,54 @@ async function getPractitionerSyncedCalendarUtil(db, practitionerId, calendarId)
|
|
|
7549
7823
|
practitionerId,
|
|
7550
7824
|
calendarId
|
|
7551
7825
|
);
|
|
7552
|
-
const calendarDoc = await
|
|
7826
|
+
const calendarDoc = await getDoc23(calendarRef);
|
|
7553
7827
|
if (!calendarDoc.exists()) {
|
|
7554
7828
|
return null;
|
|
7555
7829
|
}
|
|
7556
7830
|
return calendarDoc.data();
|
|
7557
7831
|
}
|
|
7558
7832
|
async function getPractitionerSyncedCalendarsUtil(db, practitionerId) {
|
|
7559
|
-
const calendarsRef =
|
|
7833
|
+
const calendarsRef = collection19(
|
|
7560
7834
|
db,
|
|
7561
7835
|
`practitioners/${practitionerId}/${SYNCED_CALENDARS_COLLECTION}`
|
|
7562
7836
|
);
|
|
7563
|
-
const q =
|
|
7564
|
-
const querySnapshot = await
|
|
7565
|
-
return querySnapshot.docs.map((
|
|
7837
|
+
const q = query18(calendarsRef, orderBy8("createdAt", "desc"));
|
|
7838
|
+
const querySnapshot = await getDocs18(q);
|
|
7839
|
+
return querySnapshot.docs.map((doc27) => doc27.data());
|
|
7566
7840
|
}
|
|
7567
7841
|
async function getPatientSyncedCalendarUtil(db, patientId, calendarId) {
|
|
7568
7842
|
const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
|
|
7569
|
-
const calendarDoc = await
|
|
7843
|
+
const calendarDoc = await getDoc23(calendarRef);
|
|
7570
7844
|
if (!calendarDoc.exists()) {
|
|
7571
7845
|
return null;
|
|
7572
7846
|
}
|
|
7573
7847
|
return calendarDoc.data();
|
|
7574
7848
|
}
|
|
7575
7849
|
async function getPatientSyncedCalendarsUtil(db, patientId) {
|
|
7576
|
-
const calendarsRef =
|
|
7850
|
+
const calendarsRef = collection19(
|
|
7577
7851
|
db,
|
|
7578
7852
|
`patients/${patientId}/${SYNCED_CALENDARS_COLLECTION}`
|
|
7579
7853
|
);
|
|
7580
|
-
const q =
|
|
7581
|
-
const querySnapshot = await
|
|
7582
|
-
return querySnapshot.docs.map((
|
|
7854
|
+
const q = query18(calendarsRef, orderBy8("createdAt", "desc"));
|
|
7855
|
+
const querySnapshot = await getDocs18(q);
|
|
7856
|
+
return querySnapshot.docs.map((doc27) => doc27.data());
|
|
7583
7857
|
}
|
|
7584
7858
|
async function getClinicSyncedCalendarUtil(db, clinicId, calendarId) {
|
|
7585
7859
|
const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
|
|
7586
|
-
const calendarDoc = await
|
|
7860
|
+
const calendarDoc = await getDoc23(calendarRef);
|
|
7587
7861
|
if (!calendarDoc.exists()) {
|
|
7588
7862
|
return null;
|
|
7589
7863
|
}
|
|
7590
7864
|
return calendarDoc.data();
|
|
7591
7865
|
}
|
|
7592
7866
|
async function getClinicSyncedCalendarsUtil(db, clinicId) {
|
|
7593
|
-
const calendarsRef =
|
|
7867
|
+
const calendarsRef = collection19(
|
|
7594
7868
|
db,
|
|
7595
7869
|
`clinics/${clinicId}/${SYNCED_CALENDARS_COLLECTION}`
|
|
7596
7870
|
);
|
|
7597
|
-
const q =
|
|
7598
|
-
const querySnapshot = await
|
|
7599
|
-
return querySnapshot.docs.map((
|
|
7871
|
+
const q = query18(calendarsRef, orderBy8("createdAt", "desc"));
|
|
7872
|
+
const querySnapshot = await getDocs18(q);
|
|
7873
|
+
return querySnapshot.docs.map((doc27) => doc27.data());
|
|
7600
7874
|
}
|
|
7601
7875
|
async function updatePractitionerSyncedCalendarUtil(db, practitionerId, calendarId, updateData) {
|
|
7602
7876
|
const calendarRef = getPractitionerSyncedCalendarDocRef(
|
|
@@ -7606,10 +7880,10 @@ async function updatePractitionerSyncedCalendarUtil(db, practitionerId, calendar
|
|
|
7606
7880
|
);
|
|
7607
7881
|
const updates = {
|
|
7608
7882
|
...updateData,
|
|
7609
|
-
updatedAt:
|
|
7883
|
+
updatedAt: serverTimestamp19()
|
|
7610
7884
|
};
|
|
7611
|
-
await
|
|
7612
|
-
const updatedDoc = await
|
|
7885
|
+
await updateDoc21(calendarRef, updates);
|
|
7886
|
+
const updatedDoc = await getDoc23(calendarRef);
|
|
7613
7887
|
if (!updatedDoc.exists()) {
|
|
7614
7888
|
throw new Error("Synced calendar not found after update");
|
|
7615
7889
|
}
|
|
@@ -7619,10 +7893,10 @@ async function updatePatientSyncedCalendarUtil(db, patientId, calendarId, update
|
|
|
7619
7893
|
const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
|
|
7620
7894
|
const updates = {
|
|
7621
7895
|
...updateData,
|
|
7622
|
-
updatedAt:
|
|
7896
|
+
updatedAt: serverTimestamp19()
|
|
7623
7897
|
};
|
|
7624
|
-
await
|
|
7625
|
-
const updatedDoc = await
|
|
7898
|
+
await updateDoc21(calendarRef, updates);
|
|
7899
|
+
const updatedDoc = await getDoc23(calendarRef);
|
|
7626
7900
|
if (!updatedDoc.exists()) {
|
|
7627
7901
|
throw new Error("Synced calendar not found after update");
|
|
7628
7902
|
}
|
|
@@ -7632,10 +7906,10 @@ async function updateClinicSyncedCalendarUtil(db, clinicId, calendarId, updateDa
|
|
|
7632
7906
|
const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
|
|
7633
7907
|
const updates = {
|
|
7634
7908
|
...updateData,
|
|
7635
|
-
updatedAt:
|
|
7909
|
+
updatedAt: serverTimestamp19()
|
|
7636
7910
|
};
|
|
7637
|
-
await
|
|
7638
|
-
const updatedDoc = await
|
|
7911
|
+
await updateDoc21(calendarRef, updates);
|
|
7912
|
+
const updatedDoc = await getDoc23(calendarRef);
|
|
7639
7913
|
if (!updatedDoc.exists()) {
|
|
7640
7914
|
throw new Error("Synced calendar not found after update");
|
|
7641
7915
|
}
|
|
@@ -7647,19 +7921,19 @@ async function deletePractitionerSyncedCalendarUtil(db, practitionerId, calendar
|
|
|
7647
7921
|
practitionerId,
|
|
7648
7922
|
calendarId
|
|
7649
7923
|
);
|
|
7650
|
-
await
|
|
7924
|
+
await deleteDoc13(calendarRef);
|
|
7651
7925
|
}
|
|
7652
7926
|
async function deletePatientSyncedCalendarUtil(db, patientId, calendarId) {
|
|
7653
7927
|
const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
|
|
7654
|
-
await
|
|
7928
|
+
await deleteDoc13(calendarRef);
|
|
7655
7929
|
}
|
|
7656
7930
|
async function deleteClinicSyncedCalendarUtil(db, clinicId, calendarId) {
|
|
7657
7931
|
const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
|
|
7658
|
-
await
|
|
7932
|
+
await deleteDoc13(calendarRef);
|
|
7659
7933
|
}
|
|
7660
7934
|
async function updateLastSyncedTimestampUtil(db, entityType, entityId, calendarId) {
|
|
7661
7935
|
const updateData = {
|
|
7662
|
-
lastSyncedAt:
|
|
7936
|
+
lastSyncedAt: Timestamp23.now()
|
|
7663
7937
|
};
|
|
7664
7938
|
switch (entityType) {
|
|
7665
7939
|
case "practitioner":
|
|
@@ -7689,7 +7963,7 @@ async function updateLastSyncedTimestampUtil(db, entityType, entityId, calendarI
|
|
|
7689
7963
|
}
|
|
7690
7964
|
|
|
7691
7965
|
// src/services/calendar/utils/google-calendar.utils.ts
|
|
7692
|
-
import { Timestamp as
|
|
7966
|
+
import { Timestamp as Timestamp24 } from "firebase/firestore";
|
|
7693
7967
|
var GOOGLE_CALENDAR_API_URL = "https://www.googleapis.com/calendar/v3";
|
|
7694
7968
|
var GOOGLE_OAUTH_URL = "https://oauth2.googleapis.com/token";
|
|
7695
7969
|
var CLIENT_ID = "your-client-id";
|
|
@@ -7809,7 +8083,7 @@ async function ensureValidToken(db, entityType, entityId, syncedCalendar) {
|
|
|
7809
8083
|
tokenExpiry.setSeconds(tokenExpiry.getSeconds() + expiresIn);
|
|
7810
8084
|
const updateData = {
|
|
7811
8085
|
accessToken,
|
|
7812
|
-
tokenExpiry:
|
|
8086
|
+
tokenExpiry: Timestamp24.fromDate(tokenExpiry)
|
|
7813
8087
|
};
|
|
7814
8088
|
switch (entityType) {
|
|
7815
8089
|
case "practitioner":
|
|
@@ -7984,8 +8258,8 @@ function convertGoogleEventToCalendarEventUtil(googleEvent, entityId, entityType
|
|
|
7984
8258
|
eventName: googleEvent.summary || "External Event",
|
|
7985
8259
|
eventLocation: googleEvent.location,
|
|
7986
8260
|
eventTime: {
|
|
7987
|
-
start:
|
|
7988
|
-
end:
|
|
8261
|
+
start: Timestamp24.fromDate(start),
|
|
8262
|
+
end: Timestamp24.fromDate(end)
|
|
7989
8263
|
},
|
|
7990
8264
|
description: googleEvent.description || "",
|
|
7991
8265
|
// External events are always set as CONFIRMED - status updates will happen externally
|
|
@@ -7999,7 +8273,7 @@ function convertGoogleEventToCalendarEventUtil(googleEvent, entityId, entityType
|
|
|
7999
8273
|
{
|
|
8000
8274
|
eventId: googleEvent.id,
|
|
8001
8275
|
syncedCalendarProvider: "google" /* GOOGLE */,
|
|
8002
|
-
syncedAt:
|
|
8276
|
+
syncedAt: Timestamp24.now()
|
|
8003
8277
|
}
|
|
8004
8278
|
]
|
|
8005
8279
|
};
|
|
@@ -8777,7 +9051,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
8777
9051
|
return 0;
|
|
8778
9052
|
}
|
|
8779
9053
|
let importedEventsCount = 0;
|
|
8780
|
-
const currentTime =
|
|
9054
|
+
const currentTime = Timestamp25.now();
|
|
8781
9055
|
for (const calendar of activeCalendars) {
|
|
8782
9056
|
try {
|
|
8783
9057
|
let externalEvents = [];
|
|
@@ -8844,7 +9118,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
8844
9118
|
async createDoctorBlockingEvent(doctorId, eventData) {
|
|
8845
9119
|
try {
|
|
8846
9120
|
const eventId = this.generateId();
|
|
8847
|
-
const eventRef =
|
|
9121
|
+
const eventRef = doc21(
|
|
8848
9122
|
this.db,
|
|
8849
9123
|
PRACTITIONERS_COLLECTION,
|
|
8850
9124
|
doctorId,
|
|
@@ -8854,14 +9128,14 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
8854
9128
|
const newEvent = {
|
|
8855
9129
|
id: eventId,
|
|
8856
9130
|
...eventData,
|
|
8857
|
-
createdAt:
|
|
8858
|
-
updatedAt:
|
|
9131
|
+
createdAt: serverTimestamp20(),
|
|
9132
|
+
updatedAt: serverTimestamp20()
|
|
8859
9133
|
};
|
|
8860
|
-
await
|
|
9134
|
+
await setDoc21(eventRef, newEvent);
|
|
8861
9135
|
return {
|
|
8862
9136
|
...newEvent,
|
|
8863
|
-
createdAt:
|
|
8864
|
-
updatedAt:
|
|
9137
|
+
createdAt: Timestamp25.now(),
|
|
9138
|
+
updatedAt: Timestamp25.now()
|
|
8865
9139
|
};
|
|
8866
9140
|
} catch (error) {
|
|
8867
9141
|
console.error(
|
|
@@ -8879,8 +9153,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
8879
9153
|
*/
|
|
8880
9154
|
async synchronizeExternalCalendars(lookbackDays = 7, lookforwardDays = 30) {
|
|
8881
9155
|
try {
|
|
8882
|
-
const practitionersRef =
|
|
8883
|
-
const practitionersSnapshot = await
|
|
9156
|
+
const practitionersRef = collection20(this.db, PRACTITIONERS_COLLECTION);
|
|
9157
|
+
const practitionersSnapshot = await getDocs19(practitionersRef);
|
|
8884
9158
|
const startDate = /* @__PURE__ */ new Date();
|
|
8885
9159
|
startDate.setDate(startDate.getDate() - lookbackDays);
|
|
8886
9160
|
const endDate = /* @__PURE__ */ new Date();
|
|
@@ -8938,22 +9212,22 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
8938
9212
|
async updateExistingEventsFromExternalCalendars(doctorId, startDate, endDate) {
|
|
8939
9213
|
var _a;
|
|
8940
9214
|
try {
|
|
8941
|
-
const eventsRef =
|
|
9215
|
+
const eventsRef = collection20(
|
|
8942
9216
|
this.db,
|
|
8943
9217
|
PRACTITIONERS_COLLECTION,
|
|
8944
9218
|
doctorId,
|
|
8945
9219
|
CALENDAR_COLLECTION
|
|
8946
9220
|
);
|
|
8947
|
-
const q =
|
|
9221
|
+
const q = query19(
|
|
8948
9222
|
eventsRef,
|
|
8949
|
-
|
|
8950
|
-
|
|
8951
|
-
|
|
9223
|
+
where19("syncStatus", "==", "external" /* EXTERNAL */),
|
|
9224
|
+
where19("eventTime.start", ">=", Timestamp25.fromDate(startDate)),
|
|
9225
|
+
where19("eventTime.start", "<=", Timestamp25.fromDate(endDate))
|
|
8952
9226
|
);
|
|
8953
|
-
const eventsSnapshot = await
|
|
8954
|
-
const events = eventsSnapshot.docs.map((
|
|
8955
|
-
id:
|
|
8956
|
-
...
|
|
9227
|
+
const eventsSnapshot = await getDocs19(q);
|
|
9228
|
+
const events = eventsSnapshot.docs.map((doc27) => ({
|
|
9229
|
+
id: doc27.id,
|
|
9230
|
+
...doc27.data()
|
|
8957
9231
|
}));
|
|
8958
9232
|
const calendars = await this.syncedCalendarsService.getPractitionerSyncedCalendars(
|
|
8959
9233
|
doctorId
|
|
@@ -9057,21 +9331,21 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9057
9331
|
const endTime = new Date(
|
|
9058
9332
|
externalEvent.end.dateTime || externalEvent.end.date
|
|
9059
9333
|
);
|
|
9060
|
-
const eventRef =
|
|
9334
|
+
const eventRef = doc21(
|
|
9061
9335
|
this.db,
|
|
9062
9336
|
PRACTITIONERS_COLLECTION,
|
|
9063
9337
|
doctorId,
|
|
9064
9338
|
CALENDAR_COLLECTION,
|
|
9065
9339
|
eventId
|
|
9066
9340
|
);
|
|
9067
|
-
await
|
|
9341
|
+
await updateDoc22(eventRef, {
|
|
9068
9342
|
eventName: externalEvent.summary || "External Event",
|
|
9069
9343
|
eventTime: {
|
|
9070
|
-
start:
|
|
9071
|
-
end:
|
|
9344
|
+
start: Timestamp25.fromDate(startTime),
|
|
9345
|
+
end: Timestamp25.fromDate(endTime)
|
|
9072
9346
|
},
|
|
9073
9347
|
description: externalEvent.description || "",
|
|
9074
|
-
updatedAt:
|
|
9348
|
+
updatedAt: serverTimestamp20()
|
|
9075
9349
|
});
|
|
9076
9350
|
console.log(`Updated local event ${eventId} from external event`);
|
|
9077
9351
|
} catch (error) {
|
|
@@ -9089,16 +9363,16 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9089
9363
|
*/
|
|
9090
9364
|
async updateEventStatus(doctorId, eventId, status) {
|
|
9091
9365
|
try {
|
|
9092
|
-
const eventRef =
|
|
9366
|
+
const eventRef = doc21(
|
|
9093
9367
|
this.db,
|
|
9094
9368
|
PRACTITIONERS_COLLECTION,
|
|
9095
9369
|
doctorId,
|
|
9096
9370
|
CALENDAR_COLLECTION,
|
|
9097
9371
|
eventId
|
|
9098
9372
|
);
|
|
9099
|
-
await
|
|
9373
|
+
await updateDoc22(eventRef, {
|
|
9100
9374
|
status,
|
|
9101
|
-
updatedAt:
|
|
9375
|
+
updatedAt: serverTimestamp20()
|
|
9102
9376
|
});
|
|
9103
9377
|
console.log(`Updated event ${eventId} status to ${status}`);
|
|
9104
9378
|
} catch (error) {
|
|
@@ -9116,6 +9390,102 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9116
9390
|
`Setting up scheduled calendar sync job every ${interval} hours`
|
|
9117
9391
|
);
|
|
9118
9392
|
}
|
|
9393
|
+
/**
|
|
9394
|
+
* Searches for calendar events based on specified criteria.
|
|
9395
|
+
*
|
|
9396
|
+
* @param {SearchCalendarEventsParams} params - The search parameters.
|
|
9397
|
+
* @param {SearchLocationEnum} params.searchLocation - The primary location to search (practitioner, patient, or clinic).
|
|
9398
|
+
* @param {string} params.entityId - The ID of the entity (practitioner, patient, or clinic) to search within/for.
|
|
9399
|
+
* @param {string} [params.clinicId] - Optional clinic ID to filter by.
|
|
9400
|
+
* @param {string} [params.practitionerId] - Optional practitioner ID to filter by.
|
|
9401
|
+
* @param {string} [params.patientId] - Optional patient ID to filter by.
|
|
9402
|
+
* @param {string} [params.procedureId] - Optional procedure ID to filter by.
|
|
9403
|
+
* @param {DateRange} [params.dateRange] - Optional date range to filter by (event start time).
|
|
9404
|
+
* @param {CalendarEventStatus} [params.eventStatus] - Optional event status to filter by.
|
|
9405
|
+
* @param {CalendarEventType} [params.eventType] - Optional event type to filter by.
|
|
9406
|
+
* @returns {Promise<CalendarEvent[]>} A promise that resolves to an array of matching calendar events.
|
|
9407
|
+
* @throws {Error} If the search location requires an entity ID that is not provided.
|
|
9408
|
+
*/
|
|
9409
|
+
async searchCalendarEvents(params) {
|
|
9410
|
+
return searchCalendarEventsUtil(this.db, params);
|
|
9411
|
+
}
|
|
9412
|
+
/**
|
|
9413
|
+
* Gets a doctor's upcoming appointments for a specific date range
|
|
9414
|
+
*
|
|
9415
|
+
* @param {string} doctorId - ID of the practitioner
|
|
9416
|
+
* @param {Date} startDate - Start date of the range
|
|
9417
|
+
* @param {Date} endDate - End date of the range
|
|
9418
|
+
* @param {CalendarEventStatus} [status] - Optional status filter (defaults to CONFIRMED)
|
|
9419
|
+
* @returns {Promise<CalendarEvent[]>} A promise that resolves to an array of appointments
|
|
9420
|
+
*/
|
|
9421
|
+
async getPractitionerUpcomingAppointments(doctorId, startDate, endDate, status = "confirmed" /* CONFIRMED */) {
|
|
9422
|
+
const dateRange = {
|
|
9423
|
+
start: Timestamp25.fromDate(startDate),
|
|
9424
|
+
end: Timestamp25.fromDate(endDate)
|
|
9425
|
+
};
|
|
9426
|
+
const searchParams = {
|
|
9427
|
+
searchLocation: "practitioner" /* PRACTITIONER */,
|
|
9428
|
+
entityId: doctorId,
|
|
9429
|
+
dateRange,
|
|
9430
|
+
eventStatus: status,
|
|
9431
|
+
eventType: "appointment" /* APPOINTMENT */
|
|
9432
|
+
};
|
|
9433
|
+
return this.searchCalendarEvents(searchParams);
|
|
9434
|
+
}
|
|
9435
|
+
/**
|
|
9436
|
+
* Gets a patient's appointments for a specific date range
|
|
9437
|
+
*
|
|
9438
|
+
* @param {string} patientId - ID of the patient
|
|
9439
|
+
* @param {Date} startDate - Start date of the range
|
|
9440
|
+
* @param {Date} endDate - End date of the range
|
|
9441
|
+
* @param {CalendarEventStatus} [status] - Optional status filter (defaults to all non-canceled appointments)
|
|
9442
|
+
* @returns {Promise<CalendarEvent[]>} A promise that resolves to an array of appointments
|
|
9443
|
+
*/
|
|
9444
|
+
async getPatientAppointments(patientId, startDate, endDate, status) {
|
|
9445
|
+
const dateRange = {
|
|
9446
|
+
start: Timestamp25.fromDate(startDate),
|
|
9447
|
+
end: Timestamp25.fromDate(endDate)
|
|
9448
|
+
};
|
|
9449
|
+
const searchParams = {
|
|
9450
|
+
searchLocation: "patient" /* PATIENT */,
|
|
9451
|
+
entityId: patientId,
|
|
9452
|
+
dateRange,
|
|
9453
|
+
eventType: "appointment" /* APPOINTMENT */
|
|
9454
|
+
};
|
|
9455
|
+
if (status) {
|
|
9456
|
+
searchParams.eventStatus = status;
|
|
9457
|
+
}
|
|
9458
|
+
return this.searchCalendarEvents(searchParams);
|
|
9459
|
+
}
|
|
9460
|
+
/**
|
|
9461
|
+
* Gets all appointments for a clinic within a specific date range
|
|
9462
|
+
*
|
|
9463
|
+
* @param {string} clinicId - ID of the clinic
|
|
9464
|
+
* @param {Date} startDate - Start date of the range
|
|
9465
|
+
* @param {Date} endDate - End date of the range
|
|
9466
|
+
* @param {string} [doctorId] - Optional doctor ID to filter by
|
|
9467
|
+
* @param {CalendarEventStatus} [status] - Optional status filter
|
|
9468
|
+
* @returns {Promise<CalendarEvent[]>} A promise that resolves to an array of appointments
|
|
9469
|
+
*/
|
|
9470
|
+
async getClinicAppointments(clinicId, startDate, endDate, doctorId, status) {
|
|
9471
|
+
const dateRange = {
|
|
9472
|
+
start: Timestamp25.fromDate(startDate),
|
|
9473
|
+
end: Timestamp25.fromDate(endDate)
|
|
9474
|
+
};
|
|
9475
|
+
const searchParams = {
|
|
9476
|
+
searchLocation: "clinic" /* CLINIC */,
|
|
9477
|
+
entityId: clinicId,
|
|
9478
|
+
dateRange,
|
|
9479
|
+
eventType: "appointment" /* APPOINTMENT */
|
|
9480
|
+
};
|
|
9481
|
+
if (doctorId) {
|
|
9482
|
+
searchParams.practitionerId = doctorId;
|
|
9483
|
+
}
|
|
9484
|
+
if (status) {
|
|
9485
|
+
searchParams.eventStatus = status;
|
|
9486
|
+
}
|
|
9487
|
+
return this.searchCalendarEvents(searchParams);
|
|
9488
|
+
}
|
|
9119
9489
|
// #endregion
|
|
9120
9490
|
// #region Private Helper Methods
|
|
9121
9491
|
/**
|
|
@@ -9159,8 +9529,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9159
9529
|
const startDate = eventTime.start.toDate();
|
|
9160
9530
|
const startTime = startDate;
|
|
9161
9531
|
const endTime = eventTime.end.toDate();
|
|
9162
|
-
const practitionerRef =
|
|
9163
|
-
const practitionerDoc = await
|
|
9532
|
+
const practitionerRef = doc21(this.db, PRACTITIONERS_COLLECTION, doctorId);
|
|
9533
|
+
const practitionerDoc = await getDoc24(practitionerRef);
|
|
9164
9534
|
if (!practitionerDoc.exists()) {
|
|
9165
9535
|
throw new Error(`Doctor with ID ${doctorId} not found`);
|
|
9166
9536
|
}
|
|
@@ -9217,8 +9587,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9217
9587
|
* @returns Updated calendar event
|
|
9218
9588
|
*/
|
|
9219
9589
|
async updateAppointmentStatus(appointmentId, clinicId, status) {
|
|
9220
|
-
const appointmentRef =
|
|
9221
|
-
const appointmentDoc = await
|
|
9590
|
+
const appointmentRef = doc21(this.db, CALENDAR_COLLECTION, appointmentId);
|
|
9591
|
+
const appointmentDoc = await getDoc24(appointmentRef);
|
|
9222
9592
|
if (!appointmentDoc.exists()) {
|
|
9223
9593
|
throw new Error(`Appointment with ID ${appointmentId} not found`);
|
|
9224
9594
|
}
|
|
@@ -9349,7 +9719,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9349
9719
|
const newSyncEvent = {
|
|
9350
9720
|
eventId: result.eventIds[0],
|
|
9351
9721
|
syncedCalendarProvider: calendar.provider,
|
|
9352
|
-
syncedAt:
|
|
9722
|
+
syncedAt: Timestamp25.now()
|
|
9353
9723
|
};
|
|
9354
9724
|
await this.updateEventWithSyncId(
|
|
9355
9725
|
entityType === "doctor" ? appointment.practitionerProfileId : appointment.patientProfileId,
|
|
@@ -9373,8 +9743,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9373
9743
|
async updateEventWithSyncId(entityId, entityType, eventId, syncEvent) {
|
|
9374
9744
|
try {
|
|
9375
9745
|
const collectionPath = entityType === "doctor" ? `${PRACTITIONERS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}` : `${PATIENTS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}`;
|
|
9376
|
-
const eventRef =
|
|
9377
|
-
const eventDoc = await
|
|
9746
|
+
const eventRef = doc21(this.db, collectionPath, eventId);
|
|
9747
|
+
const eventDoc = await getDoc24(eventRef);
|
|
9378
9748
|
if (eventDoc.exists()) {
|
|
9379
9749
|
const event = eventDoc.data();
|
|
9380
9750
|
const syncIds = [...event.syncedCalendarEventId || []];
|
|
@@ -9386,9 +9756,9 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9386
9756
|
} else {
|
|
9387
9757
|
syncIds.push(syncEvent);
|
|
9388
9758
|
}
|
|
9389
|
-
await
|
|
9759
|
+
await updateDoc22(eventRef, {
|
|
9390
9760
|
syncedCalendarEventId: syncIds,
|
|
9391
|
-
updatedAt:
|
|
9761
|
+
updatedAt: serverTimestamp20()
|
|
9392
9762
|
});
|
|
9393
9763
|
console.log(
|
|
9394
9764
|
`Updated event ${eventId} with sync ID ${syncEvent.eventId}`
|
|
@@ -9412,8 +9782,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9412
9782
|
* @returns Working hours for the clinic
|
|
9413
9783
|
*/
|
|
9414
9784
|
async getClinicWorkingHours(clinicId, date) {
|
|
9415
|
-
const clinicRef =
|
|
9416
|
-
const clinicDoc = await
|
|
9785
|
+
const clinicRef = doc21(this.db, CLINICS_COLLECTION, clinicId);
|
|
9786
|
+
const clinicDoc = await getDoc24(clinicRef);
|
|
9417
9787
|
if (!clinicDoc.exists()) {
|
|
9418
9788
|
throw new Error(`Clinic with ID ${clinicId} not found`);
|
|
9419
9789
|
}
|
|
@@ -9441,8 +9811,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9441
9811
|
* @returns Doctor's schedule
|
|
9442
9812
|
*/
|
|
9443
9813
|
async getDoctorSchedule(doctorId, date) {
|
|
9444
|
-
const practitionerRef =
|
|
9445
|
-
const practitionerDoc = await
|
|
9814
|
+
const practitionerRef = doc21(this.db, PRACTITIONERS_COLLECTION, doctorId);
|
|
9815
|
+
const practitionerDoc = await getDoc24(practitionerRef);
|
|
9446
9816
|
if (!practitionerDoc.exists()) {
|
|
9447
9817
|
throw new Error(`Doctor with ID ${doctorId} not found`);
|
|
9448
9818
|
}
|
|
@@ -9474,19 +9844,19 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9474
9844
|
startOfDay.setHours(0, 0, 0, 0);
|
|
9475
9845
|
const endOfDay = new Date(date);
|
|
9476
9846
|
endOfDay.setHours(23, 59, 59, 999);
|
|
9477
|
-
const appointmentsRef =
|
|
9478
|
-
const q =
|
|
9847
|
+
const appointmentsRef = collection20(this.db, CALENDAR_COLLECTION);
|
|
9848
|
+
const q = query19(
|
|
9479
9849
|
appointmentsRef,
|
|
9480
|
-
|
|
9481
|
-
|
|
9482
|
-
|
|
9483
|
-
|
|
9850
|
+
where19("practitionerProfileId", "==", doctorId),
|
|
9851
|
+
where19("eventTime.start", ">=", Timestamp25.fromDate(startOfDay)),
|
|
9852
|
+
where19("eventTime.start", "<=", Timestamp25.fromDate(endOfDay)),
|
|
9853
|
+
where19("status", "in", [
|
|
9484
9854
|
"confirmed" /* CONFIRMED */,
|
|
9485
9855
|
"pending" /* PENDING */
|
|
9486
9856
|
])
|
|
9487
9857
|
);
|
|
9488
|
-
const querySnapshot = await
|
|
9489
|
-
return querySnapshot.docs.map((
|
|
9858
|
+
const querySnapshot = await getDocs19(q);
|
|
9859
|
+
return querySnapshot.docs.map((doc27) => doc27.data());
|
|
9490
9860
|
}
|
|
9491
9861
|
/**
|
|
9492
9862
|
* Calculates available time slots based on working hours, schedule and existing appointments
|
|
@@ -9543,11 +9913,11 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9543
9913
|
var _a;
|
|
9544
9914
|
try {
|
|
9545
9915
|
const [clinicDoc, practitionerDoc, patientDoc, patientSensitiveInfoDoc] = await Promise.all([
|
|
9546
|
-
|
|
9547
|
-
|
|
9548
|
-
|
|
9549
|
-
|
|
9550
|
-
|
|
9916
|
+
getDoc24(doc21(this.db, CLINICS_COLLECTION, clinicId)),
|
|
9917
|
+
getDoc24(doc21(this.db, PRACTITIONERS_COLLECTION, doctorId)),
|
|
9918
|
+
getDoc24(doc21(this.db, PATIENTS_COLLECTION, patientId)),
|
|
9919
|
+
getDoc24(
|
|
9920
|
+
doc21(
|
|
9551
9921
|
this.db,
|
|
9552
9922
|
PATIENTS_COLLECTION,
|
|
9553
9923
|
patientId,
|
|
@@ -9580,7 +9950,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9580
9950
|
fullName: `${sensitiveData.firstName} ${sensitiveData.lastName}`,
|
|
9581
9951
|
email: sensitiveData.email || "",
|
|
9582
9952
|
phone: sensitiveData.phoneNumber || null,
|
|
9583
|
-
dateOfBirth: sensitiveData.dateOfBirth ||
|
|
9953
|
+
dateOfBirth: sensitiveData.dateOfBirth || Timestamp25.now(),
|
|
9584
9954
|
gender: sensitiveData.gender || "other" /* OTHER */
|
|
9585
9955
|
};
|
|
9586
9956
|
} else if (patientDoc.exists()) {
|
|
@@ -9589,7 +9959,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9589
9959
|
fullName: patientDoc.data().displayName,
|
|
9590
9960
|
email: ((_a = patientDoc.data().contactInfo) == null ? void 0 : _a.email) || "",
|
|
9591
9961
|
phone: patientDoc.data().phoneNumber || null,
|
|
9592
|
-
dateOfBirth: patientDoc.data().dateOfBirth ||
|
|
9962
|
+
dateOfBirth: patientDoc.data().dateOfBirth || Timestamp25.now(),
|
|
9593
9963
|
gender: patientDoc.data().gender || "other" /* OTHER */
|
|
9594
9964
|
};
|
|
9595
9965
|
}
|
|
@@ -9613,13 +9983,13 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9613
9983
|
// src/backoffice/services/brand.service.ts
|
|
9614
9984
|
import {
|
|
9615
9985
|
addDoc as addDoc4,
|
|
9616
|
-
collection as
|
|
9617
|
-
doc as
|
|
9618
|
-
getDoc as
|
|
9619
|
-
getDocs as
|
|
9620
|
-
query as
|
|
9621
|
-
updateDoc as
|
|
9622
|
-
where as
|
|
9986
|
+
collection as collection21,
|
|
9987
|
+
doc as doc22,
|
|
9988
|
+
getDoc as getDoc25,
|
|
9989
|
+
getDocs as getDocs20,
|
|
9990
|
+
query as query20,
|
|
9991
|
+
updateDoc as updateDoc23,
|
|
9992
|
+
where as where20
|
|
9623
9993
|
} from "firebase/firestore";
|
|
9624
9994
|
|
|
9625
9995
|
// src/backoffice/types/brand.types.ts
|
|
@@ -9631,7 +10001,7 @@ var BrandService = class extends BaseService {
|
|
|
9631
10001
|
* Gets reference to brands collection
|
|
9632
10002
|
*/
|
|
9633
10003
|
getBrandsRef() {
|
|
9634
|
-
return
|
|
10004
|
+
return collection21(this.db, BRANDS_COLLECTION);
|
|
9635
10005
|
}
|
|
9636
10006
|
/**
|
|
9637
10007
|
* Creates a new brand
|
|
@@ -9651,12 +10021,12 @@ var BrandService = class extends BaseService {
|
|
|
9651
10021
|
* Gets all active brands
|
|
9652
10022
|
*/
|
|
9653
10023
|
async getAll() {
|
|
9654
|
-
const q =
|
|
9655
|
-
const snapshot = await
|
|
10024
|
+
const q = query20(this.getBrandsRef(), where20("isActive", "==", true));
|
|
10025
|
+
const snapshot = await getDocs20(q);
|
|
9656
10026
|
return snapshot.docs.map(
|
|
9657
|
-
(
|
|
9658
|
-
id:
|
|
9659
|
-
...
|
|
10027
|
+
(doc27) => ({
|
|
10028
|
+
id: doc27.id,
|
|
10029
|
+
...doc27.data()
|
|
9660
10030
|
})
|
|
9661
10031
|
);
|
|
9662
10032
|
}
|
|
@@ -9668,8 +10038,8 @@ var BrandService = class extends BaseService {
|
|
|
9668
10038
|
...brand,
|
|
9669
10039
|
updatedAt: /* @__PURE__ */ new Date()
|
|
9670
10040
|
};
|
|
9671
|
-
const docRef =
|
|
9672
|
-
await
|
|
10041
|
+
const docRef = doc22(this.getBrandsRef(), brandId);
|
|
10042
|
+
await updateDoc23(docRef, updateData);
|
|
9673
10043
|
return this.getById(brandId);
|
|
9674
10044
|
}
|
|
9675
10045
|
/**
|
|
@@ -9684,8 +10054,8 @@ var BrandService = class extends BaseService {
|
|
|
9684
10054
|
* Gets a brand by ID
|
|
9685
10055
|
*/
|
|
9686
10056
|
async getById(brandId) {
|
|
9687
|
-
const docRef =
|
|
9688
|
-
const docSnap = await
|
|
10057
|
+
const docRef = doc22(this.getBrandsRef(), brandId);
|
|
10058
|
+
const docSnap = await getDoc25(docRef);
|
|
9689
10059
|
if (!docSnap.exists()) return null;
|
|
9690
10060
|
return {
|
|
9691
10061
|
id: docSnap.id,
|
|
@@ -9697,13 +10067,13 @@ var BrandService = class extends BaseService {
|
|
|
9697
10067
|
// src/backoffice/services/category.service.ts
|
|
9698
10068
|
import {
|
|
9699
10069
|
addDoc as addDoc5,
|
|
9700
|
-
collection as
|
|
9701
|
-
doc as
|
|
9702
|
-
getDoc as
|
|
9703
|
-
getDocs as
|
|
9704
|
-
query as
|
|
9705
|
-
updateDoc as
|
|
9706
|
-
where as
|
|
10070
|
+
collection as collection22,
|
|
10071
|
+
doc as doc23,
|
|
10072
|
+
getDoc as getDoc26,
|
|
10073
|
+
getDocs as getDocs21,
|
|
10074
|
+
query as query21,
|
|
10075
|
+
updateDoc as updateDoc24,
|
|
10076
|
+
where as where21
|
|
9707
10077
|
} from "firebase/firestore";
|
|
9708
10078
|
|
|
9709
10079
|
// src/backoffice/types/category.types.ts
|
|
@@ -9715,7 +10085,7 @@ var CategoryService = class extends BaseService {
|
|
|
9715
10085
|
* Referenca na Firestore kolekciju kategorija
|
|
9716
10086
|
*/
|
|
9717
10087
|
get categoriesRef() {
|
|
9718
|
-
return
|
|
10088
|
+
return collection22(this.db, CATEGORIES_COLLECTION);
|
|
9719
10089
|
}
|
|
9720
10090
|
/**
|
|
9721
10091
|
* Kreira novu kategoriju u sistemu
|
|
@@ -9738,12 +10108,12 @@ var CategoryService = class extends BaseService {
|
|
|
9738
10108
|
* @returns Lista aktivnih kategorija
|
|
9739
10109
|
*/
|
|
9740
10110
|
async getAll() {
|
|
9741
|
-
const q =
|
|
9742
|
-
const snapshot = await
|
|
10111
|
+
const q = query21(this.categoriesRef, where21("isActive", "==", true));
|
|
10112
|
+
const snapshot = await getDocs21(q);
|
|
9743
10113
|
return snapshot.docs.map(
|
|
9744
|
-
(
|
|
9745
|
-
id:
|
|
9746
|
-
...
|
|
10114
|
+
(doc27) => ({
|
|
10115
|
+
id: doc27.id,
|
|
10116
|
+
...doc27.data()
|
|
9747
10117
|
})
|
|
9748
10118
|
);
|
|
9749
10119
|
}
|
|
@@ -9753,16 +10123,16 @@ var CategoryService = class extends BaseService {
|
|
|
9753
10123
|
* @returns Lista kategorija koje pripadaju traženoj familiji
|
|
9754
10124
|
*/
|
|
9755
10125
|
async getAllByFamily(family) {
|
|
9756
|
-
const q =
|
|
10126
|
+
const q = query21(
|
|
9757
10127
|
this.categoriesRef,
|
|
9758
|
-
|
|
9759
|
-
|
|
10128
|
+
where21("family", "==", family),
|
|
10129
|
+
where21("isActive", "==", true)
|
|
9760
10130
|
);
|
|
9761
|
-
const snapshot = await
|
|
10131
|
+
const snapshot = await getDocs21(q);
|
|
9762
10132
|
return snapshot.docs.map(
|
|
9763
|
-
(
|
|
9764
|
-
id:
|
|
9765
|
-
...
|
|
10133
|
+
(doc27) => ({
|
|
10134
|
+
id: doc27.id,
|
|
10135
|
+
...doc27.data()
|
|
9766
10136
|
})
|
|
9767
10137
|
);
|
|
9768
10138
|
}
|
|
@@ -9777,8 +10147,8 @@ var CategoryService = class extends BaseService {
|
|
|
9777
10147
|
...category,
|
|
9778
10148
|
updatedAt: /* @__PURE__ */ new Date()
|
|
9779
10149
|
};
|
|
9780
|
-
const docRef =
|
|
9781
|
-
await
|
|
10150
|
+
const docRef = doc23(this.categoriesRef, id);
|
|
10151
|
+
await updateDoc24(docRef, updateData);
|
|
9782
10152
|
return this.getById(id);
|
|
9783
10153
|
}
|
|
9784
10154
|
/**
|
|
@@ -9794,8 +10164,8 @@ var CategoryService = class extends BaseService {
|
|
|
9794
10164
|
* @returns Kategorija ili null ako ne postoji
|
|
9795
10165
|
*/
|
|
9796
10166
|
async getById(id) {
|
|
9797
|
-
const docRef =
|
|
9798
|
-
const docSnap = await
|
|
10167
|
+
const docRef = doc23(this.categoriesRef, id);
|
|
10168
|
+
const docSnap = await getDoc26(docRef);
|
|
9799
10169
|
if (!docSnap.exists()) return null;
|
|
9800
10170
|
return {
|
|
9801
10171
|
id: docSnap.id,
|
|
@@ -9807,13 +10177,13 @@ var CategoryService = class extends BaseService {
|
|
|
9807
10177
|
// src/backoffice/services/subcategory.service.ts
|
|
9808
10178
|
import {
|
|
9809
10179
|
addDoc as addDoc6,
|
|
9810
|
-
collection as
|
|
9811
|
-
doc as
|
|
9812
|
-
getDoc as
|
|
9813
|
-
getDocs as
|
|
9814
|
-
query as
|
|
9815
|
-
updateDoc as
|
|
9816
|
-
where as
|
|
10180
|
+
collection as collection23,
|
|
10181
|
+
doc as doc24,
|
|
10182
|
+
getDoc as getDoc27,
|
|
10183
|
+
getDocs as getDocs22,
|
|
10184
|
+
query as query22,
|
|
10185
|
+
updateDoc as updateDoc25,
|
|
10186
|
+
where as where22
|
|
9817
10187
|
} from "firebase/firestore";
|
|
9818
10188
|
|
|
9819
10189
|
// src/backoffice/types/subcategory.types.ts
|
|
@@ -9826,7 +10196,7 @@ var SubcategoryService = class extends BaseService {
|
|
|
9826
10196
|
* @param categoryId - ID roditeljske kategorije
|
|
9827
10197
|
*/
|
|
9828
10198
|
getSubcategoriesRef(categoryId) {
|
|
9829
|
-
return
|
|
10199
|
+
return collection23(
|
|
9830
10200
|
this.db,
|
|
9831
10201
|
CATEGORIES_COLLECTION,
|
|
9832
10202
|
categoryId,
|
|
@@ -9860,15 +10230,15 @@ var SubcategoryService = class extends BaseService {
|
|
|
9860
10230
|
* @returns Lista aktivnih podkategorija
|
|
9861
10231
|
*/
|
|
9862
10232
|
async getAllByCategoryId(categoryId) {
|
|
9863
|
-
const q =
|
|
10233
|
+
const q = query22(
|
|
9864
10234
|
this.getSubcategoriesRef(categoryId),
|
|
9865
|
-
|
|
10235
|
+
where22("isActive", "==", true)
|
|
9866
10236
|
);
|
|
9867
|
-
const snapshot = await
|
|
10237
|
+
const snapshot = await getDocs22(q);
|
|
9868
10238
|
return snapshot.docs.map(
|
|
9869
|
-
(
|
|
9870
|
-
id:
|
|
9871
|
-
...
|
|
10239
|
+
(doc27) => ({
|
|
10240
|
+
id: doc27.id,
|
|
10241
|
+
...doc27.data()
|
|
9872
10242
|
})
|
|
9873
10243
|
);
|
|
9874
10244
|
}
|
|
@@ -9884,8 +10254,8 @@ var SubcategoryService = class extends BaseService {
|
|
|
9884
10254
|
...subcategory,
|
|
9885
10255
|
updatedAt: /* @__PURE__ */ new Date()
|
|
9886
10256
|
};
|
|
9887
|
-
const docRef =
|
|
9888
|
-
await
|
|
10257
|
+
const docRef = doc24(this.getSubcategoriesRef(categoryId), subcategoryId);
|
|
10258
|
+
await updateDoc25(docRef, updateData);
|
|
9889
10259
|
return this.getById(categoryId, subcategoryId);
|
|
9890
10260
|
}
|
|
9891
10261
|
/**
|
|
@@ -9903,8 +10273,8 @@ var SubcategoryService = class extends BaseService {
|
|
|
9903
10273
|
* @returns Podkategorija ili null ako ne postoji
|
|
9904
10274
|
*/
|
|
9905
10275
|
async getById(categoryId, subcategoryId) {
|
|
9906
|
-
const docRef =
|
|
9907
|
-
const docSnap = await
|
|
10276
|
+
const docRef = doc24(this.getSubcategoriesRef(categoryId), subcategoryId);
|
|
10277
|
+
const docSnap = await getDoc27(docRef);
|
|
9908
10278
|
if (!docSnap.exists()) return null;
|
|
9909
10279
|
return {
|
|
9910
10280
|
id: docSnap.id,
|
|
@@ -9916,15 +10286,15 @@ var SubcategoryService = class extends BaseService {
|
|
|
9916
10286
|
// src/backoffice/services/technology.service.ts
|
|
9917
10287
|
import {
|
|
9918
10288
|
addDoc as addDoc7,
|
|
9919
|
-
collection as
|
|
9920
|
-
doc as
|
|
9921
|
-
getDoc as
|
|
9922
|
-
getDocs as
|
|
9923
|
-
query as
|
|
9924
|
-
updateDoc as
|
|
9925
|
-
where as
|
|
10289
|
+
collection as collection24,
|
|
10290
|
+
doc as doc25,
|
|
10291
|
+
getDoc as getDoc28,
|
|
10292
|
+
getDocs as getDocs23,
|
|
10293
|
+
query as query23,
|
|
10294
|
+
updateDoc as updateDoc26,
|
|
10295
|
+
where as where23,
|
|
9926
10296
|
arrayUnion as arrayUnion5,
|
|
9927
|
-
arrayRemove as
|
|
10297
|
+
arrayRemove as arrayRemove4
|
|
9928
10298
|
} from "firebase/firestore";
|
|
9929
10299
|
|
|
9930
10300
|
// src/backoffice/types/technology.types.ts
|
|
@@ -9940,7 +10310,7 @@ var TechnologyService = class extends BaseService {
|
|
|
9940
10310
|
* Vraća referencu na Firestore kolekciju tehnologija
|
|
9941
10311
|
*/
|
|
9942
10312
|
getTechnologiesRef() {
|
|
9943
|
-
return
|
|
10313
|
+
return collection24(this.db, TECHNOLOGIES_COLLECTION);
|
|
9944
10314
|
}
|
|
9945
10315
|
/**
|
|
9946
10316
|
* Kreira novu tehnologiju
|
|
@@ -9971,12 +10341,12 @@ var TechnologyService = class extends BaseService {
|
|
|
9971
10341
|
* @returns Lista aktivnih tehnologija
|
|
9972
10342
|
*/
|
|
9973
10343
|
async getAll() {
|
|
9974
|
-
const q =
|
|
9975
|
-
const snapshot = await
|
|
10344
|
+
const q = query23(this.getTechnologiesRef(), where23("isActive", "==", true));
|
|
10345
|
+
const snapshot = await getDocs23(q);
|
|
9976
10346
|
return snapshot.docs.map(
|
|
9977
|
-
(
|
|
9978
|
-
id:
|
|
9979
|
-
...
|
|
10347
|
+
(doc27) => ({
|
|
10348
|
+
id: doc27.id,
|
|
10349
|
+
...doc27.data()
|
|
9980
10350
|
})
|
|
9981
10351
|
);
|
|
9982
10352
|
}
|
|
@@ -9986,16 +10356,16 @@ var TechnologyService = class extends BaseService {
|
|
|
9986
10356
|
* @returns Lista aktivnih tehnologija
|
|
9987
10357
|
*/
|
|
9988
10358
|
async getAllByFamily(family) {
|
|
9989
|
-
const q =
|
|
10359
|
+
const q = query23(
|
|
9990
10360
|
this.getTechnologiesRef(),
|
|
9991
|
-
|
|
9992
|
-
|
|
10361
|
+
where23("isActive", "==", true),
|
|
10362
|
+
where23("family", "==", family)
|
|
9993
10363
|
);
|
|
9994
|
-
const snapshot = await
|
|
10364
|
+
const snapshot = await getDocs23(q);
|
|
9995
10365
|
return snapshot.docs.map(
|
|
9996
|
-
(
|
|
9997
|
-
id:
|
|
9998
|
-
...
|
|
10366
|
+
(doc27) => ({
|
|
10367
|
+
id: doc27.id,
|
|
10368
|
+
...doc27.data()
|
|
9999
10369
|
})
|
|
10000
10370
|
);
|
|
10001
10371
|
}
|
|
@@ -10005,16 +10375,16 @@ var TechnologyService = class extends BaseService {
|
|
|
10005
10375
|
* @returns Lista aktivnih tehnologija
|
|
10006
10376
|
*/
|
|
10007
10377
|
async getAllByCategoryId(categoryId) {
|
|
10008
|
-
const q =
|
|
10378
|
+
const q = query23(
|
|
10009
10379
|
this.getTechnologiesRef(),
|
|
10010
|
-
|
|
10011
|
-
|
|
10380
|
+
where23("isActive", "==", true),
|
|
10381
|
+
where23("categoryId", "==", categoryId)
|
|
10012
10382
|
);
|
|
10013
|
-
const snapshot = await
|
|
10383
|
+
const snapshot = await getDocs23(q);
|
|
10014
10384
|
return snapshot.docs.map(
|
|
10015
|
-
(
|
|
10016
|
-
id:
|
|
10017
|
-
...
|
|
10385
|
+
(doc27) => ({
|
|
10386
|
+
id: doc27.id,
|
|
10387
|
+
...doc27.data()
|
|
10018
10388
|
})
|
|
10019
10389
|
);
|
|
10020
10390
|
}
|
|
@@ -10024,16 +10394,16 @@ var TechnologyService = class extends BaseService {
|
|
|
10024
10394
|
* @returns Lista aktivnih tehnologija
|
|
10025
10395
|
*/
|
|
10026
10396
|
async getAllBySubcategoryId(subcategoryId) {
|
|
10027
|
-
const q =
|
|
10397
|
+
const q = query23(
|
|
10028
10398
|
this.getTechnologiesRef(),
|
|
10029
|
-
|
|
10030
|
-
|
|
10399
|
+
where23("isActive", "==", true),
|
|
10400
|
+
where23("subcategoryId", "==", subcategoryId)
|
|
10031
10401
|
);
|
|
10032
|
-
const snapshot = await
|
|
10402
|
+
const snapshot = await getDocs23(q);
|
|
10033
10403
|
return snapshot.docs.map(
|
|
10034
|
-
(
|
|
10035
|
-
id:
|
|
10036
|
-
...
|
|
10404
|
+
(doc27) => ({
|
|
10405
|
+
id: doc27.id,
|
|
10406
|
+
...doc27.data()
|
|
10037
10407
|
})
|
|
10038
10408
|
);
|
|
10039
10409
|
}
|
|
@@ -10048,8 +10418,8 @@ var TechnologyService = class extends BaseService {
|
|
|
10048
10418
|
...technology,
|
|
10049
10419
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10050
10420
|
};
|
|
10051
|
-
const docRef =
|
|
10052
|
-
await
|
|
10421
|
+
const docRef = doc25(this.getTechnologiesRef(), technologyId);
|
|
10422
|
+
await updateDoc26(docRef, updateData);
|
|
10053
10423
|
return this.getById(technologyId);
|
|
10054
10424
|
}
|
|
10055
10425
|
/**
|
|
@@ -10067,8 +10437,8 @@ var TechnologyService = class extends BaseService {
|
|
|
10067
10437
|
* @returns Tehnologija ili null ako ne postoji
|
|
10068
10438
|
*/
|
|
10069
10439
|
async getById(technologyId) {
|
|
10070
|
-
const docRef =
|
|
10071
|
-
const docSnap = await
|
|
10440
|
+
const docRef = doc25(this.getTechnologiesRef(), technologyId);
|
|
10441
|
+
const docSnap = await getDoc28(docRef);
|
|
10072
10442
|
if (!docSnap.exists()) return null;
|
|
10073
10443
|
return {
|
|
10074
10444
|
id: docSnap.id,
|
|
@@ -10082,9 +10452,9 @@ var TechnologyService = class extends BaseService {
|
|
|
10082
10452
|
* @returns Ažurirana tehnologija sa novim zahtevom
|
|
10083
10453
|
*/
|
|
10084
10454
|
async addRequirement(technologyId, requirement) {
|
|
10085
|
-
const docRef =
|
|
10455
|
+
const docRef = doc25(this.getTechnologiesRef(), technologyId);
|
|
10086
10456
|
const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
|
|
10087
|
-
await
|
|
10457
|
+
await updateDoc26(docRef, {
|
|
10088
10458
|
[requirementType]: arrayUnion5(requirement),
|
|
10089
10459
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10090
10460
|
});
|
|
@@ -10097,10 +10467,10 @@ var TechnologyService = class extends BaseService {
|
|
|
10097
10467
|
* @returns Ažurirana tehnologija bez uklonjenog zahteva
|
|
10098
10468
|
*/
|
|
10099
10469
|
async removeRequirement(technologyId, requirement) {
|
|
10100
|
-
const docRef =
|
|
10470
|
+
const docRef = doc25(this.getTechnologiesRef(), technologyId);
|
|
10101
10471
|
const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
|
|
10102
|
-
await
|
|
10103
|
-
[requirementType]:
|
|
10472
|
+
await updateDoc26(docRef, {
|
|
10473
|
+
[requirementType]: arrayRemove4(requirement),
|
|
10104
10474
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10105
10475
|
});
|
|
10106
10476
|
return this.getById(technologyId);
|
|
@@ -10137,8 +10507,8 @@ var TechnologyService = class extends BaseService {
|
|
|
10137
10507
|
* @returns Ažurirana tehnologija
|
|
10138
10508
|
*/
|
|
10139
10509
|
async addBlockingCondition(technologyId, condition) {
|
|
10140
|
-
const docRef =
|
|
10141
|
-
await
|
|
10510
|
+
const docRef = doc25(this.getTechnologiesRef(), technologyId);
|
|
10511
|
+
await updateDoc26(docRef, {
|
|
10142
10512
|
blockingConditions: arrayUnion5(condition),
|
|
10143
10513
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10144
10514
|
});
|
|
@@ -10151,9 +10521,9 @@ var TechnologyService = class extends BaseService {
|
|
|
10151
10521
|
* @returns Ažurirana tehnologija
|
|
10152
10522
|
*/
|
|
10153
10523
|
async removeBlockingCondition(technologyId, condition) {
|
|
10154
|
-
const docRef =
|
|
10155
|
-
await
|
|
10156
|
-
blockingConditions:
|
|
10524
|
+
const docRef = doc25(this.getTechnologiesRef(), technologyId);
|
|
10525
|
+
await updateDoc26(docRef, {
|
|
10526
|
+
blockingConditions: arrayRemove4(condition),
|
|
10157
10527
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10158
10528
|
});
|
|
10159
10529
|
return this.getById(technologyId);
|
|
@@ -10165,8 +10535,8 @@ var TechnologyService = class extends BaseService {
|
|
|
10165
10535
|
* @returns Ažurirana tehnologija
|
|
10166
10536
|
*/
|
|
10167
10537
|
async addContraindication(technologyId, contraindication) {
|
|
10168
|
-
const docRef =
|
|
10169
|
-
await
|
|
10538
|
+
const docRef = doc25(this.getTechnologiesRef(), technologyId);
|
|
10539
|
+
await updateDoc26(docRef, {
|
|
10170
10540
|
contraindications: arrayUnion5(contraindication),
|
|
10171
10541
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10172
10542
|
});
|
|
@@ -10179,9 +10549,9 @@ var TechnologyService = class extends BaseService {
|
|
|
10179
10549
|
* @returns Ažurirana tehnologija
|
|
10180
10550
|
*/
|
|
10181
10551
|
async removeContraindication(technologyId, contraindication) {
|
|
10182
|
-
const docRef =
|
|
10183
|
-
await
|
|
10184
|
-
contraindications:
|
|
10552
|
+
const docRef = doc25(this.getTechnologiesRef(), technologyId);
|
|
10553
|
+
await updateDoc26(docRef, {
|
|
10554
|
+
contraindications: arrayRemove4(contraindication),
|
|
10185
10555
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10186
10556
|
});
|
|
10187
10557
|
return this.getById(technologyId);
|
|
@@ -10193,8 +10563,8 @@ var TechnologyService = class extends BaseService {
|
|
|
10193
10563
|
* @returns Ažurirana tehnologija
|
|
10194
10564
|
*/
|
|
10195
10565
|
async addBenefit(technologyId, benefit) {
|
|
10196
|
-
const docRef =
|
|
10197
|
-
await
|
|
10566
|
+
const docRef = doc25(this.getTechnologiesRef(), technologyId);
|
|
10567
|
+
await updateDoc26(docRef, {
|
|
10198
10568
|
benefits: arrayUnion5(benefit),
|
|
10199
10569
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10200
10570
|
});
|
|
@@ -10207,9 +10577,9 @@ var TechnologyService = class extends BaseService {
|
|
|
10207
10577
|
* @returns Ažurirana tehnologija
|
|
10208
10578
|
*/
|
|
10209
10579
|
async removeBenefit(technologyId, benefit) {
|
|
10210
|
-
const docRef =
|
|
10211
|
-
await
|
|
10212
|
-
benefits:
|
|
10580
|
+
const docRef = doc25(this.getTechnologiesRef(), technologyId);
|
|
10581
|
+
await updateDoc26(docRef, {
|
|
10582
|
+
benefits: arrayRemove4(benefit),
|
|
10213
10583
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10214
10584
|
});
|
|
10215
10585
|
return this.getById(technologyId);
|
|
@@ -10248,8 +10618,8 @@ var TechnologyService = class extends BaseService {
|
|
|
10248
10618
|
* @returns Ažurirana tehnologija
|
|
10249
10619
|
*/
|
|
10250
10620
|
async updateCertificationRequirement(technologyId, certificationRequirement) {
|
|
10251
|
-
const docRef =
|
|
10252
|
-
await
|
|
10621
|
+
const docRef = doc25(this.getTechnologiesRef(), technologyId);
|
|
10622
|
+
await updateDoc26(docRef, {
|
|
10253
10623
|
certificationRequirement,
|
|
10254
10624
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10255
10625
|
});
|
|
@@ -10351,13 +10721,13 @@ var TechnologyService = class extends BaseService {
|
|
|
10351
10721
|
// src/backoffice/services/product.service.ts
|
|
10352
10722
|
import {
|
|
10353
10723
|
addDoc as addDoc8,
|
|
10354
|
-
collection as
|
|
10355
|
-
doc as
|
|
10356
|
-
getDoc as
|
|
10357
|
-
getDocs as
|
|
10358
|
-
query as
|
|
10359
|
-
updateDoc as
|
|
10360
|
-
where as
|
|
10724
|
+
collection as collection25,
|
|
10725
|
+
doc as doc26,
|
|
10726
|
+
getDoc as getDoc29,
|
|
10727
|
+
getDocs as getDocs24,
|
|
10728
|
+
query as query24,
|
|
10729
|
+
updateDoc as updateDoc27,
|
|
10730
|
+
where as where24
|
|
10361
10731
|
} from "firebase/firestore";
|
|
10362
10732
|
|
|
10363
10733
|
// src/backoffice/types/product.types.ts
|
|
@@ -10371,7 +10741,7 @@ var ProductService = class extends BaseService {
|
|
|
10371
10741
|
* @returns Firestore collection reference
|
|
10372
10742
|
*/
|
|
10373
10743
|
getProductsRef(technologyId) {
|
|
10374
|
-
return
|
|
10744
|
+
return collection25(
|
|
10375
10745
|
this.db,
|
|
10376
10746
|
TECHNOLOGIES_COLLECTION,
|
|
10377
10747
|
technologyId,
|
|
@@ -10401,15 +10771,15 @@ var ProductService = class extends BaseService {
|
|
|
10401
10771
|
* Gets all products for a technology
|
|
10402
10772
|
*/
|
|
10403
10773
|
async getAllByTechnology(technologyId) {
|
|
10404
|
-
const q =
|
|
10774
|
+
const q = query24(
|
|
10405
10775
|
this.getProductsRef(technologyId),
|
|
10406
|
-
|
|
10776
|
+
where24("isActive", "==", true)
|
|
10407
10777
|
);
|
|
10408
|
-
const snapshot = await
|
|
10778
|
+
const snapshot = await getDocs24(q);
|
|
10409
10779
|
return snapshot.docs.map(
|
|
10410
|
-
(
|
|
10411
|
-
id:
|
|
10412
|
-
...
|
|
10780
|
+
(doc27) => ({
|
|
10781
|
+
id: doc27.id,
|
|
10782
|
+
...doc27.data()
|
|
10413
10783
|
})
|
|
10414
10784
|
);
|
|
10415
10785
|
}
|
|
@@ -10417,21 +10787,21 @@ var ProductService = class extends BaseService {
|
|
|
10417
10787
|
* Gets all products for a brand by filtering through all technologies
|
|
10418
10788
|
*/
|
|
10419
10789
|
async getAllByBrand(brandId) {
|
|
10420
|
-
const allTechnologiesRef =
|
|
10421
|
-
const technologiesSnapshot = await
|
|
10790
|
+
const allTechnologiesRef = collection25(this.db, TECHNOLOGIES_COLLECTION);
|
|
10791
|
+
const technologiesSnapshot = await getDocs24(allTechnologiesRef);
|
|
10422
10792
|
const products = [];
|
|
10423
10793
|
for (const techDoc of technologiesSnapshot.docs) {
|
|
10424
|
-
const q =
|
|
10794
|
+
const q = query24(
|
|
10425
10795
|
this.getProductsRef(techDoc.id),
|
|
10426
|
-
|
|
10427
|
-
|
|
10796
|
+
where24("brandId", "==", brandId),
|
|
10797
|
+
where24("isActive", "==", true)
|
|
10428
10798
|
);
|
|
10429
|
-
const snapshot = await
|
|
10799
|
+
const snapshot = await getDocs24(q);
|
|
10430
10800
|
products.push(
|
|
10431
10801
|
...snapshot.docs.map(
|
|
10432
|
-
(
|
|
10433
|
-
id:
|
|
10434
|
-
...
|
|
10802
|
+
(doc27) => ({
|
|
10803
|
+
id: doc27.id,
|
|
10804
|
+
...doc27.data()
|
|
10435
10805
|
})
|
|
10436
10806
|
)
|
|
10437
10807
|
);
|
|
@@ -10446,8 +10816,8 @@ var ProductService = class extends BaseService {
|
|
|
10446
10816
|
...product,
|
|
10447
10817
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10448
10818
|
};
|
|
10449
|
-
const docRef =
|
|
10450
|
-
await
|
|
10819
|
+
const docRef = doc26(this.getProductsRef(technologyId), productId);
|
|
10820
|
+
await updateDoc27(docRef, updateData);
|
|
10451
10821
|
return this.getById(technologyId, productId);
|
|
10452
10822
|
}
|
|
10453
10823
|
/**
|
|
@@ -10462,8 +10832,8 @@ var ProductService = class extends BaseService {
|
|
|
10462
10832
|
* Gets a product by ID
|
|
10463
10833
|
*/
|
|
10464
10834
|
async getById(technologyId, productId) {
|
|
10465
|
-
const docRef =
|
|
10466
|
-
const docSnap = await
|
|
10835
|
+
const docRef = doc26(this.getProductsRef(technologyId), productId);
|
|
10836
|
+
const docSnap = await getDoc29(docRef);
|
|
10467
10837
|
if (!docSnap.exists()) return null;
|
|
10468
10838
|
return {
|
|
10469
10839
|
id: docSnap.id,
|
|
@@ -10678,7 +11048,9 @@ export {
|
|
|
10678
11048
|
preRequirementNotificationSchema,
|
|
10679
11049
|
procedureCategorizationSchema,
|
|
10680
11050
|
procedureInfoSchema,
|
|
11051
|
+
requesterInfoSchema,
|
|
10681
11052
|
reviewInfoSchema,
|
|
11053
|
+
searchPatientsSchema,
|
|
10682
11054
|
serviceInfoSchema,
|
|
10683
11055
|
syncedCalendarEventSchema,
|
|
10684
11056
|
timeSlotSchema2 as timeSlotSchema,
|