@blackcode_sa/metaestetics-api 1.5.16 → 1.5.18
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 +233 -40
- package/dist/index.d.ts +233 -40
- package/dist/index.js +748 -427
- package/dist/index.mjs +1073 -739
- package/package.json +1 -1
- package/src/index.ts +5 -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/patient/patient.service.ts +100 -127
- package/src/services/patient/utils/medical-stuff.utils.ts +69 -18
- package/src/services/patient/utils/profile.utils.ts +206 -94
- package/src/types/calendar/index.ts +41 -0
- package/src/types/patient/index.ts +31 -1
- package/src/types/practitioner/index.ts +13 -14
- 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,29 +111,35 @@ 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
|
+
var SearchLocationEnum = /* @__PURE__ */ ((SearchLocationEnum2) => {
|
|
138
|
+
SearchLocationEnum2["PRACTITIONER"] = "practitioner";
|
|
139
|
+
SearchLocationEnum2["PATIENT"] = "patient";
|
|
140
|
+
SearchLocationEnum2["CLINIC"] = "clinic";
|
|
141
|
+
return SearchLocationEnum2;
|
|
142
|
+
})(SearchLocationEnum || {});
|
|
137
143
|
|
|
138
144
|
// src/types/index.ts
|
|
139
145
|
var UserRole = /* @__PURE__ */ ((UserRole2) => {
|
|
@@ -577,12 +583,12 @@ var BaseService = class {
|
|
|
577
583
|
|
|
578
584
|
// src/services/user.service.ts
|
|
579
585
|
import {
|
|
580
|
-
collection as
|
|
581
|
-
doc as
|
|
586
|
+
collection as collection5,
|
|
587
|
+
doc as doc7,
|
|
582
588
|
getDoc as getDoc10,
|
|
583
|
-
getDocs as
|
|
584
|
-
query as
|
|
585
|
-
where as
|
|
589
|
+
getDocs as getDocs5,
|
|
590
|
+
query as query5,
|
|
591
|
+
where as where5,
|
|
586
592
|
updateDoc as updateDoc9,
|
|
587
593
|
deleteDoc as deleteDoc3,
|
|
588
594
|
Timestamp as Timestamp9,
|
|
@@ -687,7 +693,7 @@ import { z as z12 } from "zod";
|
|
|
687
693
|
|
|
688
694
|
// src/services/patient/patient.service.ts
|
|
689
695
|
import {
|
|
690
|
-
doc as
|
|
696
|
+
doc as doc4,
|
|
691
697
|
getDoc as getDoc7,
|
|
692
698
|
writeBatch
|
|
693
699
|
} from "firebase/firestore";
|
|
@@ -701,14 +707,16 @@ import {
|
|
|
701
707
|
arrayRemove as arrayRemove2,
|
|
702
708
|
serverTimestamp as serverTimestamp4,
|
|
703
709
|
increment,
|
|
704
|
-
Timestamp as Timestamp3
|
|
710
|
+
Timestamp as Timestamp3,
|
|
711
|
+
collection as collection2,
|
|
712
|
+
query as query2,
|
|
713
|
+
where as where2,
|
|
714
|
+
getDocs as getDocs2,
|
|
715
|
+
limit,
|
|
716
|
+
startAfter,
|
|
717
|
+
doc as doc3
|
|
705
718
|
} from "firebase/firestore";
|
|
706
|
-
import {
|
|
707
|
-
ref,
|
|
708
|
-
uploadBytes,
|
|
709
|
-
getDownloadURL,
|
|
710
|
-
deleteObject
|
|
711
|
-
} from "firebase/storage";
|
|
719
|
+
import { ref, uploadBytes, getDownloadURL, deleteObject } from "firebase/storage";
|
|
712
720
|
import { z as z7 } from "zod";
|
|
713
721
|
|
|
714
722
|
// src/types/patient/medical-info.types.ts
|
|
@@ -999,6 +1007,8 @@ var patientProfileSchema = z5.object({
|
|
|
999
1007
|
isVerified: z5.boolean(),
|
|
1000
1008
|
doctors: z5.array(patientDoctorSchema),
|
|
1001
1009
|
clinics: z5.array(patientClinicSchema),
|
|
1010
|
+
doctorIds: z5.array(z5.string()),
|
|
1011
|
+
clinicIds: z5.array(z5.string()),
|
|
1002
1012
|
createdAt: z5.instanceof(Timestamp),
|
|
1003
1013
|
updatedAt: z5.instanceof(Timestamp)
|
|
1004
1014
|
});
|
|
@@ -1011,7 +1021,9 @@ var createPatientProfileSchema = z5.object({
|
|
|
1011
1021
|
isActive: z5.boolean(),
|
|
1012
1022
|
isVerified: z5.boolean(),
|
|
1013
1023
|
doctors: z5.array(patientDoctorSchema).optional(),
|
|
1014
|
-
clinics: z5.array(patientClinicSchema).optional()
|
|
1024
|
+
clinics: z5.array(patientClinicSchema).optional(),
|
|
1025
|
+
doctorIds: z5.array(z5.string()).optional(),
|
|
1026
|
+
clinicIds: z5.array(z5.string()).optional()
|
|
1015
1027
|
});
|
|
1016
1028
|
var createPatientSensitiveInfoSchema = z5.object({
|
|
1017
1029
|
patientId: z5.string(),
|
|
@@ -1027,6 +1039,33 @@ var createPatientSensitiveInfoSchema = z5.object({
|
|
|
1027
1039
|
addressData: addressDataSchema.optional(),
|
|
1028
1040
|
emergencyContacts: z5.array(emergencyContactSchema).optional()
|
|
1029
1041
|
});
|
|
1042
|
+
var searchPatientsSchema = z5.object({
|
|
1043
|
+
clinicId: z5.string().optional(),
|
|
1044
|
+
practitionerId: z5.string().optional()
|
|
1045
|
+
}).refine((data) => data.clinicId || data.practitionerId, {
|
|
1046
|
+
message: "At least one of clinicId or practitionerId must be provided",
|
|
1047
|
+
path: []
|
|
1048
|
+
// Optional: specify a path like ['clinicId'] or ['practitionerId']
|
|
1049
|
+
});
|
|
1050
|
+
var requesterInfoSchema = z5.object({
|
|
1051
|
+
id: z5.string(),
|
|
1052
|
+
role: z5.enum(["clinic_admin", "practitioner"]),
|
|
1053
|
+
associatedClinicId: z5.string().optional(),
|
|
1054
|
+
associatedPractitionerId: z5.string().optional()
|
|
1055
|
+
}).refine(
|
|
1056
|
+
(data) => {
|
|
1057
|
+
if (data.role === "clinic_admin") {
|
|
1058
|
+
return !!data.associatedClinicId;
|
|
1059
|
+
} else if (data.role === "practitioner") {
|
|
1060
|
+
return !!data.associatedPractitionerId;
|
|
1061
|
+
}
|
|
1062
|
+
return false;
|
|
1063
|
+
},
|
|
1064
|
+
{
|
|
1065
|
+
message: "Associated ID (clinic or practitioner) is required based on role",
|
|
1066
|
+
path: ["associatedClinicId", "associatedPractitionerId"]
|
|
1067
|
+
}
|
|
1068
|
+
);
|
|
1030
1069
|
|
|
1031
1070
|
// src/services/patient/utils/docs.utils.ts
|
|
1032
1071
|
import {
|
|
@@ -1310,9 +1349,9 @@ var addAllergyUtil = async (db, patientId, data, userRef) => {
|
|
|
1310
1349
|
var updateAllergyUtil = async (db, patientId, data, userRef) => {
|
|
1311
1350
|
const validatedData = updateAllergySchema.parse(data);
|
|
1312
1351
|
const { allergyIndex, ...updateData } = validatedData;
|
|
1313
|
-
const
|
|
1314
|
-
if (!
|
|
1315
|
-
const medicalInfo =
|
|
1352
|
+
const doc28 = await getDoc3(getMedicalInfoDocRef(db, patientId));
|
|
1353
|
+
if (!doc28.exists()) throw new Error("Medical info not found");
|
|
1354
|
+
const medicalInfo = doc28.data();
|
|
1316
1355
|
if (allergyIndex >= medicalInfo.allergies.length) {
|
|
1317
1356
|
throw new Error("Invalid allergy index");
|
|
1318
1357
|
}
|
|
@@ -1328,9 +1367,9 @@ var updateAllergyUtil = async (db, patientId, data, userRef) => {
|
|
|
1328
1367
|
});
|
|
1329
1368
|
};
|
|
1330
1369
|
var removeAllergyUtil = async (db, patientId, allergyIndex, userRef) => {
|
|
1331
|
-
const
|
|
1332
|
-
if (!
|
|
1333
|
-
const medicalInfo =
|
|
1370
|
+
const doc28 = await getDoc3(getMedicalInfoDocRef(db, patientId));
|
|
1371
|
+
if (!doc28.exists()) throw new Error("Medical info not found");
|
|
1372
|
+
const medicalInfo = doc28.data();
|
|
1334
1373
|
if (allergyIndex >= medicalInfo.allergies.length) {
|
|
1335
1374
|
throw new Error("Invalid allergy index");
|
|
1336
1375
|
}
|
|
@@ -1355,9 +1394,9 @@ var addBlockingConditionUtil = async (db, patientId, data, userRef) => {
|
|
|
1355
1394
|
var updateBlockingConditionUtil = async (db, patientId, data, userRef) => {
|
|
1356
1395
|
const validatedData = updateBlockingConditionSchema.parse(data);
|
|
1357
1396
|
const { conditionIndex, ...updateData } = validatedData;
|
|
1358
|
-
const
|
|
1359
|
-
if (!
|
|
1360
|
-
const medicalInfo =
|
|
1397
|
+
const doc28 = await getDoc3(getMedicalInfoDocRef(db, patientId));
|
|
1398
|
+
if (!doc28.exists()) throw new Error("Medical info not found");
|
|
1399
|
+
const medicalInfo = doc28.data();
|
|
1361
1400
|
if (conditionIndex >= medicalInfo.blockingConditions.length) {
|
|
1362
1401
|
throw new Error("Invalid blocking condition index");
|
|
1363
1402
|
}
|
|
@@ -1373,9 +1412,9 @@ var updateBlockingConditionUtil = async (db, patientId, data, userRef) => {
|
|
|
1373
1412
|
});
|
|
1374
1413
|
};
|
|
1375
1414
|
var removeBlockingConditionUtil = async (db, patientId, conditionIndex, userRef) => {
|
|
1376
|
-
const
|
|
1377
|
-
if (!
|
|
1378
|
-
const medicalInfo =
|
|
1415
|
+
const doc28 = await getDoc3(getMedicalInfoDocRef(db, patientId));
|
|
1416
|
+
if (!doc28.exists()) throw new Error("Medical info not found");
|
|
1417
|
+
const medicalInfo = doc28.data();
|
|
1379
1418
|
if (conditionIndex >= medicalInfo.blockingConditions.length) {
|
|
1380
1419
|
throw new Error("Invalid blocking condition index");
|
|
1381
1420
|
}
|
|
@@ -1400,9 +1439,9 @@ var addContraindicationUtil = async (db, patientId, data, userRef) => {
|
|
|
1400
1439
|
var updateContraindicationUtil = async (db, patientId, data, userRef) => {
|
|
1401
1440
|
const validatedData = updateContraindicationSchema.parse(data);
|
|
1402
1441
|
const { contraindicationIndex, ...updateData } = validatedData;
|
|
1403
|
-
const
|
|
1404
|
-
if (!
|
|
1405
|
-
const medicalInfo =
|
|
1442
|
+
const doc28 = await getDoc3(getMedicalInfoDocRef(db, patientId));
|
|
1443
|
+
if (!doc28.exists()) throw new Error("Medical info not found");
|
|
1444
|
+
const medicalInfo = doc28.data();
|
|
1406
1445
|
if (contraindicationIndex >= medicalInfo.contraindications.length) {
|
|
1407
1446
|
throw new Error("Invalid contraindication index");
|
|
1408
1447
|
}
|
|
@@ -1418,9 +1457,9 @@ var updateContraindicationUtil = async (db, patientId, data, userRef) => {
|
|
|
1418
1457
|
});
|
|
1419
1458
|
};
|
|
1420
1459
|
var removeContraindicationUtil = async (db, patientId, contraindicationIndex, userRef) => {
|
|
1421
|
-
const
|
|
1422
|
-
if (!
|
|
1423
|
-
const medicalInfo =
|
|
1460
|
+
const doc28 = await getDoc3(getMedicalInfoDocRef(db, patientId));
|
|
1461
|
+
if (!doc28.exists()) throw new Error("Medical info not found");
|
|
1462
|
+
const medicalInfo = doc28.data();
|
|
1424
1463
|
if (contraindicationIndex >= medicalInfo.contraindications.length) {
|
|
1425
1464
|
throw new Error("Invalid contraindication index");
|
|
1426
1465
|
}
|
|
@@ -1445,9 +1484,9 @@ var addMedicationUtil = async (db, patientId, data, userRef) => {
|
|
|
1445
1484
|
var updateMedicationUtil = async (db, patientId, data, userRef) => {
|
|
1446
1485
|
const validatedData = updateMedicationSchema.parse(data);
|
|
1447
1486
|
const { medicationIndex, ...updateData } = validatedData;
|
|
1448
|
-
const
|
|
1449
|
-
if (!
|
|
1450
|
-
const medicalInfo =
|
|
1487
|
+
const doc28 = await getDoc3(getMedicalInfoDocRef(db, patientId));
|
|
1488
|
+
if (!doc28.exists()) throw new Error("Medical info not found");
|
|
1489
|
+
const medicalInfo = doc28.data();
|
|
1451
1490
|
if (medicationIndex >= medicalInfo.currentMedications.length) {
|
|
1452
1491
|
throw new Error("Invalid medication index");
|
|
1453
1492
|
}
|
|
@@ -1463,9 +1502,9 @@ var updateMedicationUtil = async (db, patientId, data, userRef) => {
|
|
|
1463
1502
|
});
|
|
1464
1503
|
};
|
|
1465
1504
|
var removeMedicationUtil = async (db, patientId, medicationIndex, userRef) => {
|
|
1466
|
-
const
|
|
1467
|
-
if (!
|
|
1468
|
-
const medicalInfo =
|
|
1505
|
+
const doc28 = await getDoc3(getMedicalInfoDocRef(db, patientId));
|
|
1506
|
+
if (!doc28.exists()) throw new Error("Medical info not found");
|
|
1507
|
+
const medicalInfo = doc28.data();
|
|
1469
1508
|
if (medicationIndex >= medicalInfo.currentMedications.length) {
|
|
1470
1509
|
throw new Error("Invalid medication index");
|
|
1471
1510
|
}
|
|
@@ -1481,6 +1520,7 @@ var removeMedicationUtil = async (db, patientId, medicationIndex, userRef) => {
|
|
|
1481
1520
|
|
|
1482
1521
|
// src/services/patient/utils/profile.utils.ts
|
|
1483
1522
|
var createPatientProfileUtil = async (db, data, generateId2) => {
|
|
1523
|
+
var _a, _b;
|
|
1484
1524
|
try {
|
|
1485
1525
|
console.log("[createPatientProfileUtil] Starting patient profile creation");
|
|
1486
1526
|
const validatedData = createPatientProfileSchema.parse(data);
|
|
@@ -1500,6 +1540,8 @@ var createPatientProfileUtil = async (db, data, generateId2) => {
|
|
|
1500
1540
|
isVerified: validatedData.isVerified,
|
|
1501
1541
|
doctors: validatedData.doctors || [],
|
|
1502
1542
|
clinics: validatedData.clinics || [],
|
|
1543
|
+
doctorIds: ((_a = validatedData.doctors) == null ? void 0 : _a.map((d) => d.userRef)) || [],
|
|
1544
|
+
clinicIds: ((_b = validatedData.clinics) == null ? void 0 : _b.map((c) => c.clinicId)) || [],
|
|
1503
1545
|
createdAt: serverTimestamp4(),
|
|
1504
1546
|
updatedAt: serverTimestamp4()
|
|
1505
1547
|
};
|
|
@@ -1522,58 +1564,36 @@ var createPatientProfileUtil = async (db, data, generateId2) => {
|
|
|
1522
1564
|
);
|
|
1523
1565
|
sensitiveInfoSuccess = true;
|
|
1524
1566
|
} catch (sensitiveError) {
|
|
1525
|
-
console.error(
|
|
1526
|
-
`[createPatientProfileUtil] Error creating sensitive info:`,
|
|
1527
|
-
sensitiveError
|
|
1528
|
-
);
|
|
1567
|
+
console.error(`[createPatientProfileUtil] Error creating sensitive info:`, sensitiveError);
|
|
1529
1568
|
}
|
|
1530
1569
|
console.log(`[createPatientProfileUtil] Creating medical info document`);
|
|
1531
1570
|
let medicalInfoSuccess = false;
|
|
1532
1571
|
try {
|
|
1533
1572
|
await ensureMedicalInfoExists(db, patientId, validatedData.userRef);
|
|
1534
|
-
console.log(
|
|
1535
|
-
`[createPatientProfileUtil] Medical info document created successfully`
|
|
1536
|
-
);
|
|
1573
|
+
console.log(`[createPatientProfileUtil] Medical info document created successfully`);
|
|
1537
1574
|
medicalInfoSuccess = true;
|
|
1538
1575
|
} catch (medicalError) {
|
|
1539
|
-
console.error(
|
|
1540
|
-
`[createPatientProfileUtil] Error creating medical info:`,
|
|
1541
|
-
medicalError
|
|
1542
|
-
);
|
|
1576
|
+
console.error(`[createPatientProfileUtil] Error creating medical info:`, medicalError);
|
|
1543
1577
|
}
|
|
1544
1578
|
if (!sensitiveInfoSuccess || !medicalInfoSuccess) {
|
|
1545
|
-
console.log(
|
|
1546
|
-
`[createPatientProfileUtil] Using fallback method to create documents`
|
|
1547
|
-
);
|
|
1579
|
+
console.log(`[createPatientProfileUtil] Using fallback method to create documents`);
|
|
1548
1580
|
try {
|
|
1549
1581
|
await testCreateSubDocuments(db, patientId, validatedData.userRef);
|
|
1550
|
-
console.log(
|
|
1551
|
-
`[createPatientProfileUtil] Fallback method completed successfully`
|
|
1552
|
-
);
|
|
1582
|
+
console.log(`[createPatientProfileUtil] Fallback method completed successfully`);
|
|
1553
1583
|
} catch (fallbackError) {
|
|
1554
|
-
console.error(
|
|
1555
|
-
`[createPatientProfileUtil] Fallback method failed:`,
|
|
1556
|
-
fallbackError
|
|
1557
|
-
);
|
|
1584
|
+
console.error(`[createPatientProfileUtil] Fallback method failed:`, fallbackError);
|
|
1558
1585
|
}
|
|
1559
1586
|
}
|
|
1560
1587
|
console.log(`[createPatientProfileUtil] Verifying patient document exists`);
|
|
1561
1588
|
const patientDoc = await getDoc4(getPatientDocRef(db, patientId));
|
|
1562
1589
|
if (!patientDoc.exists()) {
|
|
1563
|
-
console.error(
|
|
1564
|
-
`[createPatientProfileUtil] Patient document not found after creation`
|
|
1565
|
-
);
|
|
1590
|
+
console.error(`[createPatientProfileUtil] Patient document not found after creation`);
|
|
1566
1591
|
throw new Error("Failed to create patient profile");
|
|
1567
1592
|
}
|
|
1568
|
-
console.log(
|
|
1569
|
-
`[createPatientProfileUtil] Patient profile creation completed successfully`
|
|
1570
|
-
);
|
|
1593
|
+
console.log(`[createPatientProfileUtil] Patient profile creation completed successfully`);
|
|
1571
1594
|
return patientDoc.data();
|
|
1572
1595
|
} catch (error) {
|
|
1573
|
-
console.error(
|
|
1574
|
-
`[createPatientProfileUtil] Error in patient profile creation:`,
|
|
1575
|
-
error
|
|
1576
|
-
);
|
|
1596
|
+
console.error(`[createPatientProfileUtil] Error in patient profile creation:`, error);
|
|
1577
1597
|
if (error instanceof z7.ZodError) {
|
|
1578
1598
|
throw new Error("Invalid patient data: " + error.message);
|
|
1579
1599
|
}
|
|
@@ -1639,9 +1659,7 @@ var updatePatientProfileByUserRefUtil = async (db, userRef, data) => {
|
|
|
1639
1659
|
return updatePatientProfileUtil(db, patientData.id, data);
|
|
1640
1660
|
} catch (error) {
|
|
1641
1661
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1642
|
-
throw new Error(
|
|
1643
|
-
`Failed to update patient profile by user ref: ${errorMessage}`
|
|
1644
|
-
);
|
|
1662
|
+
throw new Error(`Failed to update patient profile by user ref: ${errorMessage}`);
|
|
1645
1663
|
}
|
|
1646
1664
|
};
|
|
1647
1665
|
var uploadProfilePhotoUtil = async (storage, patientId, file) => {
|
|
@@ -1692,9 +1710,7 @@ var testCreateSubDocuments = async (db, patientId, userRef) => {
|
|
|
1692
1710
|
try {
|
|
1693
1711
|
console.log(`[testCreateSubDocuments] Testing sensitive info creation`);
|
|
1694
1712
|
const sensitiveInfoRef = getSensitiveInfoDocRef(db, patientId);
|
|
1695
|
-
console.log(
|
|
1696
|
-
`[testCreateSubDocuments] Sensitive info path: ${sensitiveInfoRef.path}`
|
|
1697
|
-
);
|
|
1713
|
+
console.log(`[testCreateSubDocuments] Sensitive info path: ${sensitiveInfoRef.path}`);
|
|
1698
1714
|
const defaultSensitiveInfo = {
|
|
1699
1715
|
patientId,
|
|
1700
1716
|
userRef,
|
|
@@ -1709,14 +1725,10 @@ var testCreateSubDocuments = async (db, patientId, userRef) => {
|
|
|
1709
1725
|
updatedAt: Timestamp3.now()
|
|
1710
1726
|
};
|
|
1711
1727
|
await setDoc4(sensitiveInfoRef, defaultSensitiveInfo);
|
|
1712
|
-
console.log(
|
|
1713
|
-
`[testCreateSubDocuments] Sensitive info document created directly`
|
|
1714
|
-
);
|
|
1728
|
+
console.log(`[testCreateSubDocuments] Sensitive info document created directly`);
|
|
1715
1729
|
console.log(`[testCreateSubDocuments] Testing medical info creation`);
|
|
1716
1730
|
const medicalInfoRef = getMedicalInfoDocRef(db, patientId);
|
|
1717
|
-
console.log(
|
|
1718
|
-
`[testCreateSubDocuments] Medical info path: ${medicalInfoRef.path}`
|
|
1719
|
-
);
|
|
1731
|
+
console.log(`[testCreateSubDocuments] Medical info path: ${medicalInfoRef.path}`);
|
|
1720
1732
|
const defaultMedicalInfo = {
|
|
1721
1733
|
...DEFAULT_MEDICAL_INFO,
|
|
1722
1734
|
patientId,
|
|
@@ -1724,15 +1736,88 @@ var testCreateSubDocuments = async (db, patientId, userRef) => {
|
|
|
1724
1736
|
updatedBy: userRef
|
|
1725
1737
|
};
|
|
1726
1738
|
await setDoc4(medicalInfoRef, defaultMedicalInfo);
|
|
1727
|
-
console.log(
|
|
1728
|
-
`[testCreateSubDocuments] Medical info document created directly`
|
|
1729
|
-
);
|
|
1739
|
+
console.log(`[testCreateSubDocuments] Medical info document created directly`);
|
|
1730
1740
|
console.log(`[testCreateSubDocuments] Test completed successfully`);
|
|
1731
1741
|
} catch (error) {
|
|
1732
1742
|
console.error(`[testCreateSubDocuments] Error:`, error);
|
|
1733
1743
|
throw error;
|
|
1734
1744
|
}
|
|
1735
1745
|
};
|
|
1746
|
+
var searchPatientsUtil = async (db, params, requester) => {
|
|
1747
|
+
searchPatientsSchema.parse(params);
|
|
1748
|
+
requesterInfoSchema.parse(requester);
|
|
1749
|
+
const constraints = [];
|
|
1750
|
+
const patientsCollectionRef = collection2(db, PATIENTS_COLLECTION);
|
|
1751
|
+
if (requester.role === "clinic_admin") {
|
|
1752
|
+
if (!requester.associatedClinicId) {
|
|
1753
|
+
throw new Error("Associated clinic ID is required for clinic admin search.");
|
|
1754
|
+
}
|
|
1755
|
+
if (params.clinicId && params.clinicId !== requester.associatedClinicId) {
|
|
1756
|
+
console.warn(
|
|
1757
|
+
`Clinic admin (${requester.id}) attempted to search outside their associated clinic (${requester.associatedClinicId})`
|
|
1758
|
+
);
|
|
1759
|
+
return [];
|
|
1760
|
+
}
|
|
1761
|
+
constraints.push(where2("clinicIds", "array-contains", requester.associatedClinicId));
|
|
1762
|
+
if (params.practitionerId) {
|
|
1763
|
+
constraints.push(where2("doctorIds", "array-contains", params.practitionerId));
|
|
1764
|
+
}
|
|
1765
|
+
} else if (requester.role === "practitioner") {
|
|
1766
|
+
if (!requester.associatedPractitionerId) {
|
|
1767
|
+
throw new Error("Associated practitioner ID is required for practitioner search.");
|
|
1768
|
+
}
|
|
1769
|
+
if (params.practitionerId && params.practitionerId !== requester.associatedPractitionerId) {
|
|
1770
|
+
console.warn(
|
|
1771
|
+
`Practitioner (${requester.id}) attempted to search for patients of another practitioner (${params.practitionerId})`
|
|
1772
|
+
);
|
|
1773
|
+
return [];
|
|
1774
|
+
}
|
|
1775
|
+
constraints.push(where2("doctorIds", "array-contains", requester.associatedPractitionerId));
|
|
1776
|
+
if (params.clinicId) {
|
|
1777
|
+
constraints.push(where2("clinicIds", "array-contains", params.clinicId));
|
|
1778
|
+
}
|
|
1779
|
+
} else {
|
|
1780
|
+
throw new Error("Invalid requester role.");
|
|
1781
|
+
}
|
|
1782
|
+
try {
|
|
1783
|
+
const finalQuery = query2(patientsCollectionRef, ...constraints);
|
|
1784
|
+
const querySnapshot = await getDocs2(finalQuery);
|
|
1785
|
+
const patients = querySnapshot.docs.map((doc28) => doc28.data());
|
|
1786
|
+
console.log(`[searchPatientsUtil] Found ${patients.length} patients matching criteria.`);
|
|
1787
|
+
return patients;
|
|
1788
|
+
} catch (error) {
|
|
1789
|
+
console.error("[searchPatientsUtil] Error searching patients:", error);
|
|
1790
|
+
return [];
|
|
1791
|
+
}
|
|
1792
|
+
};
|
|
1793
|
+
var getAllPatientsUtil = async (db, options) => {
|
|
1794
|
+
try {
|
|
1795
|
+
console.log(`[getAllPatientsUtil] Fetching patients with options:`, options);
|
|
1796
|
+
const patientsCollection = collection2(db, PATIENTS_COLLECTION);
|
|
1797
|
+
let q = query2(patientsCollection);
|
|
1798
|
+
if (options == null ? void 0 : options.limit) {
|
|
1799
|
+
q = query2(q, limit(options.limit));
|
|
1800
|
+
}
|
|
1801
|
+
if (options == null ? void 0 : options.startAfter) {
|
|
1802
|
+
const startAfterDoc = await getDoc4(doc3(db, PATIENTS_COLLECTION, options.startAfter));
|
|
1803
|
+
if (startAfterDoc.exists()) {
|
|
1804
|
+
q = query2(q, startAfter(startAfterDoc));
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
const patientsSnapshot = await getDocs2(q);
|
|
1808
|
+
const patients = [];
|
|
1809
|
+
patientsSnapshot.forEach((doc28) => {
|
|
1810
|
+
patients.push(doc28.data());
|
|
1811
|
+
});
|
|
1812
|
+
console.log(`[getAllPatientsUtil] Found ${patients.length} patients`);
|
|
1813
|
+
return patients;
|
|
1814
|
+
} catch (error) {
|
|
1815
|
+
console.error(`[getAllPatientsUtil] Error fetching patients:`, error);
|
|
1816
|
+
throw new Error(
|
|
1817
|
+
`Failed to retrieve patients: ${error instanceof Error ? error.message : String(error)}`
|
|
1818
|
+
);
|
|
1819
|
+
}
|
|
1820
|
+
};
|
|
1736
1821
|
|
|
1737
1822
|
// src/services/patient/utils/location.utils.ts
|
|
1738
1823
|
import {
|
|
@@ -1821,54 +1906,101 @@ import {
|
|
|
1821
1906
|
getDoc as getDoc6,
|
|
1822
1907
|
updateDoc as updateDoc5,
|
|
1823
1908
|
arrayUnion as arrayUnion3,
|
|
1909
|
+
arrayRemove as arrayRemove3,
|
|
1824
1910
|
serverTimestamp as serverTimestamp6,
|
|
1825
1911
|
Timestamp as Timestamp4
|
|
1826
1912
|
} from "firebase/firestore";
|
|
1827
1913
|
var addDoctorUtil = async (db, patientId, doctorRef, assignedBy) => {
|
|
1914
|
+
var _a;
|
|
1828
1915
|
const newDoctor = {
|
|
1829
1916
|
userRef: doctorRef,
|
|
1830
1917
|
assignedAt: Timestamp4.now(),
|
|
1831
1918
|
assignedBy,
|
|
1832
1919
|
isActive: true
|
|
1833
1920
|
};
|
|
1834
|
-
await updateDoc5(getPatientDocRef(db, patientId), {
|
|
1835
|
-
doctors: arrayUnion3(newDoctor),
|
|
1836
|
-
updatedAt: serverTimestamp6()
|
|
1837
|
-
});
|
|
1838
|
-
};
|
|
1839
|
-
var removeDoctorUtil = async (db, patientId, doctorRef) => {
|
|
1840
1921
|
const patientDoc = await getDoc6(getPatientDocRef(db, patientId));
|
|
1841
1922
|
if (!patientDoc.exists()) throw new Error("Patient profile not found");
|
|
1842
1923
|
const patientData = patientDoc.data();
|
|
1843
|
-
const
|
|
1844
|
-
(
|
|
1924
|
+
const existingDoctorIndex = (_a = patientData.doctors) == null ? void 0 : _a.findIndex(
|
|
1925
|
+
(d) => d.userRef === doctorRef
|
|
1845
1926
|
);
|
|
1846
|
-
|
|
1927
|
+
const updates = {
|
|
1928
|
+
updatedAt: serverTimestamp6(),
|
|
1929
|
+
doctorIds: arrayUnion3(doctorRef)
|
|
1930
|
+
};
|
|
1931
|
+
if (existingDoctorIndex !== void 0 && existingDoctorIndex > -1) {
|
|
1932
|
+
const updatedDoctors = [...patientData.doctors];
|
|
1933
|
+
updatedDoctors[existingDoctorIndex] = {
|
|
1934
|
+
...updatedDoctors[existingDoctorIndex],
|
|
1935
|
+
isActive: true,
|
|
1936
|
+
assignedAt: Timestamp4.now(),
|
|
1937
|
+
assignedBy
|
|
1938
|
+
};
|
|
1939
|
+
updates.doctors = updatedDoctors;
|
|
1940
|
+
} else {
|
|
1941
|
+
updates.doctors = arrayUnion3(newDoctor);
|
|
1942
|
+
}
|
|
1943
|
+
await updateDoc5(getPatientDocRef(db, patientId), updates);
|
|
1944
|
+
};
|
|
1945
|
+
var removeDoctorUtil = async (db, patientId, doctorRef) => {
|
|
1946
|
+
var _a;
|
|
1947
|
+
const patientDocRef = getPatientDocRef(db, patientId);
|
|
1948
|
+
const patientDoc = await getDoc6(patientDocRef);
|
|
1949
|
+
if (!patientDoc.exists()) throw new Error("Patient profile not found");
|
|
1950
|
+
const patientData = patientDoc.data();
|
|
1951
|
+
const updatedDoctors = ((_a = patientData.doctors) == null ? void 0 : _a.filter((doctor) => doctor.userRef !== doctorRef)) || [];
|
|
1952
|
+
await updateDoc5(patientDocRef, {
|
|
1847
1953
|
doctors: updatedDoctors,
|
|
1954
|
+
// Set the filtered array
|
|
1955
|
+
doctorIds: arrayRemove3(doctorRef),
|
|
1956
|
+
// Remove ID from the denormalized list
|
|
1848
1957
|
updatedAt: serverTimestamp6()
|
|
1849
1958
|
});
|
|
1850
1959
|
};
|
|
1851
1960
|
var addClinicUtil = async (db, patientId, clinicId, assignedBy) => {
|
|
1961
|
+
var _a;
|
|
1852
1962
|
const newClinic = {
|
|
1853
1963
|
clinicId,
|
|
1854
1964
|
assignedAt: Timestamp4.now(),
|
|
1855
1965
|
assignedBy,
|
|
1856
1966
|
isActive: true
|
|
1857
1967
|
};
|
|
1858
|
-
await updateDoc5(getPatientDocRef(db, patientId), {
|
|
1859
|
-
clinics: arrayUnion3(newClinic),
|
|
1860
|
-
updatedAt: serverTimestamp6()
|
|
1861
|
-
});
|
|
1862
|
-
};
|
|
1863
|
-
var removeClinicUtil = async (db, patientId, clinicId) => {
|
|
1864
1968
|
const patientDoc = await getDoc6(getPatientDocRef(db, patientId));
|
|
1865
1969
|
if (!patientDoc.exists()) throw new Error("Patient profile not found");
|
|
1866
1970
|
const patientData = patientDoc.data();
|
|
1867
|
-
const
|
|
1868
|
-
(
|
|
1971
|
+
const existingClinicIndex = (_a = patientData.clinics) == null ? void 0 : _a.findIndex(
|
|
1972
|
+
(c) => c.clinicId === clinicId
|
|
1869
1973
|
);
|
|
1870
|
-
|
|
1974
|
+
const updates = {
|
|
1975
|
+
updatedAt: serverTimestamp6(),
|
|
1976
|
+
clinicIds: arrayUnion3(clinicId)
|
|
1977
|
+
};
|
|
1978
|
+
if (existingClinicIndex !== void 0 && existingClinicIndex > -1) {
|
|
1979
|
+
const updatedClinics = [...patientData.clinics];
|
|
1980
|
+
updatedClinics[existingClinicIndex] = {
|
|
1981
|
+
...updatedClinics[existingClinicIndex],
|
|
1982
|
+
isActive: true,
|
|
1983
|
+
assignedAt: Timestamp4.now(),
|
|
1984
|
+
assignedBy
|
|
1985
|
+
};
|
|
1986
|
+
updates.clinics = updatedClinics;
|
|
1987
|
+
} else {
|
|
1988
|
+
updates.clinics = arrayUnion3(newClinic);
|
|
1989
|
+
}
|
|
1990
|
+
await updateDoc5(getPatientDocRef(db, patientId), updates);
|
|
1991
|
+
};
|
|
1992
|
+
var removeClinicUtil = async (db, patientId, clinicId) => {
|
|
1993
|
+
var _a;
|
|
1994
|
+
const patientDocRef = getPatientDocRef(db, patientId);
|
|
1995
|
+
const patientDoc = await getDoc6(patientDocRef);
|
|
1996
|
+
if (!patientDoc.exists()) throw new Error("Patient profile not found");
|
|
1997
|
+
const patientData = patientDoc.data();
|
|
1998
|
+
const updatedClinics = ((_a = patientData.clinics) == null ? void 0 : _a.filter((clinic) => clinic.clinicId !== clinicId)) || [];
|
|
1999
|
+
await updateDoc5(patientDocRef, {
|
|
1871
2000
|
clinics: updatedClinics,
|
|
2001
|
+
// Set the filtered array
|
|
2002
|
+
clinicIds: arrayRemove3(clinicId),
|
|
2003
|
+
// Remove ID from the denormalized list
|
|
1872
2004
|
updatedAt: serverTimestamp6()
|
|
1873
2005
|
});
|
|
1874
2006
|
};
|
|
@@ -1929,22 +2061,11 @@ var PatientService = class extends BaseService {
|
|
|
1929
2061
|
// Metode za rad sa medicinskim informacijama
|
|
1930
2062
|
async createMedicalInfo(patientId, data) {
|
|
1931
2063
|
const currentUser = await this.getCurrentUser();
|
|
1932
|
-
await createMedicalInfoUtil(
|
|
1933
|
-
this.db,
|
|
1934
|
-
patientId,
|
|
1935
|
-
data,
|
|
1936
|
-
currentUser.uid,
|
|
1937
|
-
currentUser.roles
|
|
1938
|
-
);
|
|
2064
|
+
await createMedicalInfoUtil(this.db, patientId, data, currentUser.uid, currentUser.roles);
|
|
1939
2065
|
}
|
|
1940
2066
|
async getMedicalInfo(patientId) {
|
|
1941
2067
|
const currentUser = await this.getCurrentUser();
|
|
1942
|
-
return getMedicalInfoUtil(
|
|
1943
|
-
this.db,
|
|
1944
|
-
patientId,
|
|
1945
|
-
currentUser.uid,
|
|
1946
|
-
currentUser.roles
|
|
1947
|
-
);
|
|
2068
|
+
return getMedicalInfoUtil(this.db, patientId, currentUser.uid, currentUser.roles);
|
|
1948
2069
|
}
|
|
1949
2070
|
async getMedicalInfoByUserRef(userRef) {
|
|
1950
2071
|
const profile = await this.getPatientProfileByUserRef(userRef);
|
|
@@ -1976,21 +2097,11 @@ var PatientService = class extends BaseService {
|
|
|
1976
2097
|
}
|
|
1977
2098
|
async updateBlockingCondition(patientId, data) {
|
|
1978
2099
|
const currentUser = await this.getCurrentUser();
|
|
1979
|
-
await updateBlockingConditionUtil(
|
|
1980
|
-
this.db,
|
|
1981
|
-
patientId,
|
|
1982
|
-
data,
|
|
1983
|
-
currentUser.uid
|
|
1984
|
-
);
|
|
2100
|
+
await updateBlockingConditionUtil(this.db, patientId, data, currentUser.uid);
|
|
1985
2101
|
}
|
|
1986
2102
|
async removeBlockingCondition(patientId, conditionIndex) {
|
|
1987
2103
|
const currentUser = await this.getCurrentUser();
|
|
1988
|
-
await removeBlockingConditionUtil(
|
|
1989
|
-
this.db,
|
|
1990
|
-
patientId,
|
|
1991
|
-
conditionIndex,
|
|
1992
|
-
currentUser.uid
|
|
1993
|
-
);
|
|
2104
|
+
await removeBlockingConditionUtil(this.db, patientId, conditionIndex, currentUser.uid);
|
|
1994
2105
|
}
|
|
1995
2106
|
// Metode za rad sa kontraindikacijama
|
|
1996
2107
|
async addContraindication(patientId, data) {
|
|
@@ -2003,12 +2114,7 @@ var PatientService = class extends BaseService {
|
|
|
2003
2114
|
}
|
|
2004
2115
|
async removeContraindication(patientId, contraindicationIndex) {
|
|
2005
2116
|
const currentUser = await this.getCurrentUser();
|
|
2006
|
-
await removeContraindicationUtil(
|
|
2007
|
-
this.db,
|
|
2008
|
-
patientId,
|
|
2009
|
-
contraindicationIndex,
|
|
2010
|
-
currentUser.uid
|
|
2011
|
-
);
|
|
2117
|
+
await removeContraindicationUtil(this.db, patientId, contraindicationIndex, currentUser.uid);
|
|
2012
2118
|
}
|
|
2013
2119
|
// Metode za rad sa medikacijama
|
|
2014
2120
|
async addMedication(patientId, data) {
|
|
@@ -2021,12 +2127,7 @@ var PatientService = class extends BaseService {
|
|
|
2021
2127
|
}
|
|
2022
2128
|
async removeMedication(patientId, medicationIndex) {
|
|
2023
2129
|
const currentUser = await this.getCurrentUser();
|
|
2024
|
-
await removeMedicationUtil(
|
|
2025
|
-
this.db,
|
|
2026
|
-
patientId,
|
|
2027
|
-
medicationIndex,
|
|
2028
|
-
currentUser.uid
|
|
2029
|
-
);
|
|
2130
|
+
await removeMedicationUtil(this.db, patientId, medicationIndex, currentUser.uid);
|
|
2030
2131
|
}
|
|
2031
2132
|
// Pomoćne metode
|
|
2032
2133
|
async addExpoToken(patientId, token) {
|
|
@@ -2057,9 +2158,7 @@ var PatientService = class extends BaseService {
|
|
|
2057
2158
|
if (!this.auth.currentUser) {
|
|
2058
2159
|
throw new Error("No authenticated user");
|
|
2059
2160
|
}
|
|
2060
|
-
const userDoc = await getDoc7(
|
|
2061
|
-
doc3(this.db, "users", this.auth.currentUser.uid)
|
|
2062
|
-
);
|
|
2161
|
+
const userDoc = await getDoc7(doc4(this.db, "users", this.auth.currentUser.uid));
|
|
2063
2162
|
if (!userDoc.exists()) {
|
|
2064
2163
|
throw new Error("User not found");
|
|
2065
2164
|
}
|
|
@@ -2109,16 +2208,45 @@ var PatientService = class extends BaseService {
|
|
|
2109
2208
|
async updatePatientProfileByUserRef(userRef, data) {
|
|
2110
2209
|
return updatePatientProfileByUserRefUtil(this.db, userRef, data);
|
|
2111
2210
|
}
|
|
2211
|
+
/**
|
|
2212
|
+
* Searches for patient profiles based on clinic/practitioner association.
|
|
2213
|
+
* Requires information about the requester for security checks.
|
|
2214
|
+
*
|
|
2215
|
+
* @param {SearchPatientsParams} params - The search criteria (clinicId, practitionerId).
|
|
2216
|
+
* @param {RequesterInfo} requester - Information about the user performing the search (ID, role, associated IDs).
|
|
2217
|
+
* @returns {Promise<PatientProfile[]>} A promise resolving to an array of matching patient profiles.
|
|
2218
|
+
*/
|
|
2219
|
+
async searchPatients(params, requester) {
|
|
2220
|
+
console.log(
|
|
2221
|
+
`[PatientService.searchPatients] Initiating search with params:`,
|
|
2222
|
+
params,
|
|
2223
|
+
`by requester:`,
|
|
2224
|
+
requester
|
|
2225
|
+
);
|
|
2226
|
+
return searchPatientsUtil(this.db, params, requester);
|
|
2227
|
+
}
|
|
2228
|
+
/**
|
|
2229
|
+
* Gets all patient profiles.
|
|
2230
|
+
*
|
|
2231
|
+
* @param {Object} options - Optional parameters for pagination
|
|
2232
|
+
* @param {number} options.limit - Maximum number of profiles to return
|
|
2233
|
+
* @param {string} options.startAfter - The ID of the document to start after (for pagination)
|
|
2234
|
+
* @returns {Promise<PatientProfile[]>} A promise resolving to an array of all patient profiles.
|
|
2235
|
+
*/
|
|
2236
|
+
async getAllPatients(options) {
|
|
2237
|
+
console.log(`[PatientService.getAllPatients] Fetching patients with options:`, options);
|
|
2238
|
+
return getAllPatientsUtil(this.db, options);
|
|
2239
|
+
}
|
|
2112
2240
|
};
|
|
2113
2241
|
|
|
2114
2242
|
// src/services/clinic/utils/admin.utils.ts
|
|
2115
2243
|
import {
|
|
2116
|
-
collection as
|
|
2117
|
-
doc as
|
|
2244
|
+
collection as collection3,
|
|
2245
|
+
doc as doc5,
|
|
2118
2246
|
getDoc as getDoc8,
|
|
2119
|
-
getDocs as
|
|
2120
|
-
query as
|
|
2121
|
-
where as
|
|
2247
|
+
getDocs as getDocs3,
|
|
2248
|
+
query as query3,
|
|
2249
|
+
where as where3,
|
|
2122
2250
|
updateDoc as updateDoc7,
|
|
2123
2251
|
setDoc as setDoc6,
|
|
2124
2252
|
deleteDoc,
|
|
@@ -2676,7 +2804,7 @@ async function createClinicAdmin(db, data, clinicGroupService) {
|
|
|
2676
2804
|
}
|
|
2677
2805
|
console.log("[CLINIC_ADMIN] Preparing admin data object");
|
|
2678
2806
|
const adminData = {
|
|
2679
|
-
id:
|
|
2807
|
+
id: doc5(collection3(db, CLINIC_ADMINS_COLLECTION)).id,
|
|
2680
2808
|
// Generate a new ID for the admin document
|
|
2681
2809
|
userRef: validatedData.userRef,
|
|
2682
2810
|
clinicGroupId: clinicGroupId || "",
|
|
@@ -2711,7 +2839,7 @@ async function createClinicAdmin(db, data, clinicGroupService) {
|
|
|
2711
2839
|
adminId: adminData.id
|
|
2712
2840
|
});
|
|
2713
2841
|
try {
|
|
2714
|
-
await setDoc6(
|
|
2842
|
+
await setDoc6(doc5(db, CLINIC_ADMINS_COLLECTION, adminData.id), adminData);
|
|
2715
2843
|
console.log("[CLINIC_ADMIN] Admin saved successfully");
|
|
2716
2844
|
} catch (firestoreError) {
|
|
2717
2845
|
console.error(
|
|
@@ -2760,7 +2888,7 @@ async function checkClinicGroupExists(db, groupId, clinicGroupService) {
|
|
|
2760
2888
|
return !!group;
|
|
2761
2889
|
}
|
|
2762
2890
|
async function getClinicAdmin(db, adminId) {
|
|
2763
|
-
const docRef =
|
|
2891
|
+
const docRef = doc5(db, CLINIC_ADMINS_COLLECTION, adminId);
|
|
2764
2892
|
const docSnap = await getDoc8(docRef);
|
|
2765
2893
|
if (docSnap.exists()) {
|
|
2766
2894
|
return docSnap.data();
|
|
@@ -2768,23 +2896,23 @@ async function getClinicAdmin(db, adminId) {
|
|
|
2768
2896
|
return null;
|
|
2769
2897
|
}
|
|
2770
2898
|
async function getClinicAdminByUserRef(db, userRef) {
|
|
2771
|
-
const q =
|
|
2772
|
-
|
|
2773
|
-
|
|
2899
|
+
const q = query3(
|
|
2900
|
+
collection3(db, CLINIC_ADMINS_COLLECTION),
|
|
2901
|
+
where3("userRef", "==", userRef)
|
|
2774
2902
|
);
|
|
2775
|
-
const querySnapshot = await
|
|
2903
|
+
const querySnapshot = await getDocs3(q);
|
|
2776
2904
|
if (querySnapshot.empty) {
|
|
2777
2905
|
return null;
|
|
2778
2906
|
}
|
|
2779
2907
|
return querySnapshot.docs[0].data();
|
|
2780
2908
|
}
|
|
2781
2909
|
async function getClinicAdminsByGroup(db, clinicGroupId) {
|
|
2782
|
-
const q =
|
|
2783
|
-
|
|
2784
|
-
|
|
2910
|
+
const q = query3(
|
|
2911
|
+
collection3(db, CLINIC_ADMINS_COLLECTION),
|
|
2912
|
+
where3("clinicGroupId", "==", clinicGroupId)
|
|
2785
2913
|
);
|
|
2786
|
-
const querySnapshot = await
|
|
2787
|
-
return querySnapshot.docs.map((
|
|
2914
|
+
const querySnapshot = await getDocs3(q);
|
|
2915
|
+
return querySnapshot.docs.map((doc28) => doc28.data());
|
|
2788
2916
|
}
|
|
2789
2917
|
async function updateClinicAdmin(db, adminId, data) {
|
|
2790
2918
|
const admin = await getClinicAdmin(db, adminId);
|
|
@@ -2795,7 +2923,7 @@ async function updateClinicAdmin(db, adminId, data) {
|
|
|
2795
2923
|
...data,
|
|
2796
2924
|
updatedAt: serverTimestamp8()
|
|
2797
2925
|
};
|
|
2798
|
-
await updateDoc7(
|
|
2926
|
+
await updateDoc7(doc5(db, CLINIC_ADMINS_COLLECTION, adminId), updatedData);
|
|
2799
2927
|
const updatedAdmin = await getClinicAdmin(db, adminId);
|
|
2800
2928
|
if (!updatedAdmin) {
|
|
2801
2929
|
throw new Error("Failed to retrieve updated admin");
|
|
@@ -2807,7 +2935,7 @@ async function deleteClinicAdmin(db, adminId) {
|
|
|
2807
2935
|
if (!admin) {
|
|
2808
2936
|
throw new Error("Clinic admin not found");
|
|
2809
2937
|
}
|
|
2810
|
-
await deleteDoc(
|
|
2938
|
+
await deleteDoc(doc5(db, CLINIC_ADMINS_COLLECTION, adminId));
|
|
2811
2939
|
}
|
|
2812
2940
|
async function addClinicToManaged(db, adminId, clinicId, requesterId, clinicService) {
|
|
2813
2941
|
const admin = await getClinicAdmin(db, adminId);
|
|
@@ -3049,12 +3177,12 @@ var ClinicAdminService = class extends BaseService {
|
|
|
3049
3177
|
|
|
3050
3178
|
// src/services/practitioner/practitioner.service.ts
|
|
3051
3179
|
import {
|
|
3052
|
-
collection as
|
|
3053
|
-
doc as
|
|
3180
|
+
collection as collection4,
|
|
3181
|
+
doc as doc6,
|
|
3054
3182
|
getDoc as getDoc9,
|
|
3055
|
-
getDocs as
|
|
3056
|
-
query as
|
|
3057
|
-
where as
|
|
3183
|
+
getDocs as getDocs4,
|
|
3184
|
+
query as query4,
|
|
3185
|
+
where as where4,
|
|
3058
3186
|
updateDoc as updateDoc8,
|
|
3059
3187
|
setDoc as setDoc7,
|
|
3060
3188
|
deleteDoc as deleteDoc2,
|
|
@@ -3288,7 +3416,7 @@ var PractitionerService = class extends BaseService {
|
|
|
3288
3416
|
updatedAt: Timestamp8.now()
|
|
3289
3417
|
});
|
|
3290
3418
|
await setDoc7(
|
|
3291
|
-
|
|
3419
|
+
doc6(this.db, PRACTITIONERS_COLLECTION, practitionerData.id),
|
|
3292
3420
|
practitionerData
|
|
3293
3421
|
);
|
|
3294
3422
|
const savedPractitioner = await this.getPractitioner(practitionerData.id);
|
|
@@ -3351,7 +3479,7 @@ var PractitionerService = class extends BaseService {
|
|
|
3351
3479
|
updatedAt: Timestamp8.now()
|
|
3352
3480
|
});
|
|
3353
3481
|
await setDoc7(
|
|
3354
|
-
|
|
3482
|
+
doc6(this.db, PRACTITIONERS_COLLECTION, practitionerData.id),
|
|
3355
3483
|
practitionerData
|
|
3356
3484
|
);
|
|
3357
3485
|
const savedPractitioner = await this.getPractitioner(practitionerData.id);
|
|
@@ -3373,7 +3501,7 @@ var PractitionerService = class extends BaseService {
|
|
|
3373
3501
|
};
|
|
3374
3502
|
practitionerTokenSchema.parse(token);
|
|
3375
3503
|
const tokenPath = `${PRACTITIONERS_COLLECTION}/${practitionerId}/${REGISTER_TOKENS_COLLECTION}/${token.id}`;
|
|
3376
|
-
await setDoc7(
|
|
3504
|
+
await setDoc7(doc6(this.db, tokenPath), token);
|
|
3377
3505
|
return { practitioner: savedPractitioner, token };
|
|
3378
3506
|
} catch (error) {
|
|
3379
3507
|
if (error instanceof z11.ZodError) {
|
|
@@ -3426,7 +3554,7 @@ var PractitionerService = class extends BaseService {
|
|
|
3426
3554
|
};
|
|
3427
3555
|
practitionerTokenSchema.parse(token);
|
|
3428
3556
|
const tokenPath = `${PRACTITIONERS_COLLECTION}/${validatedData.practitionerId}/${REGISTER_TOKENS_COLLECTION}/${token.id}`;
|
|
3429
|
-
await setDoc7(
|
|
3557
|
+
await setDoc7(doc6(this.db, tokenPath), token);
|
|
3430
3558
|
return token;
|
|
3431
3559
|
} catch (error) {
|
|
3432
3560
|
if (error instanceof z11.ZodError) {
|
|
@@ -3441,17 +3569,17 @@ var PractitionerService = class extends BaseService {
|
|
|
3441
3569
|
* @returns Array of active tokens
|
|
3442
3570
|
*/
|
|
3443
3571
|
async getPractitionerActiveTokens(practitionerId) {
|
|
3444
|
-
const tokensRef =
|
|
3572
|
+
const tokensRef = collection4(
|
|
3445
3573
|
this.db,
|
|
3446
3574
|
`${PRACTITIONERS_COLLECTION}/${practitionerId}/${REGISTER_TOKENS_COLLECTION}`
|
|
3447
3575
|
);
|
|
3448
|
-
const q =
|
|
3576
|
+
const q = query4(
|
|
3449
3577
|
tokensRef,
|
|
3450
|
-
|
|
3451
|
-
|
|
3578
|
+
where4("status", "==", "active" /* ACTIVE */),
|
|
3579
|
+
where4("expiresAt", ">", Timestamp8.now())
|
|
3452
3580
|
);
|
|
3453
|
-
const querySnapshot = await
|
|
3454
|
-
return querySnapshot.docs.map((
|
|
3581
|
+
const querySnapshot = await getDocs4(q);
|
|
3582
|
+
return querySnapshot.docs.map((doc28) => doc28.data());
|
|
3455
3583
|
}
|
|
3456
3584
|
/**
|
|
3457
3585
|
* Gets a token by its string value and validates it
|
|
@@ -3459,21 +3587,21 @@ var PractitionerService = class extends BaseService {
|
|
|
3459
3587
|
* @returns The token if found and valid, null otherwise
|
|
3460
3588
|
*/
|
|
3461
3589
|
async validateToken(tokenString) {
|
|
3462
|
-
const practitionersRef =
|
|
3463
|
-
const practitionersSnapshot = await
|
|
3590
|
+
const practitionersRef = collection4(this.db, PRACTITIONERS_COLLECTION);
|
|
3591
|
+
const practitionersSnapshot = await getDocs4(practitionersRef);
|
|
3464
3592
|
for (const practitionerDoc of practitionersSnapshot.docs) {
|
|
3465
3593
|
const practitionerId = practitionerDoc.id;
|
|
3466
|
-
const tokensRef =
|
|
3594
|
+
const tokensRef = collection4(
|
|
3467
3595
|
this.db,
|
|
3468
3596
|
`${PRACTITIONERS_COLLECTION}/${practitionerId}/${REGISTER_TOKENS_COLLECTION}`
|
|
3469
3597
|
);
|
|
3470
|
-
const q =
|
|
3598
|
+
const q = query4(
|
|
3471
3599
|
tokensRef,
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3600
|
+
where4("token", "==", tokenString),
|
|
3601
|
+
where4("status", "==", "active" /* ACTIVE */),
|
|
3602
|
+
where4("expiresAt", ">", Timestamp8.now())
|
|
3475
3603
|
);
|
|
3476
|
-
const tokenSnapshot = await
|
|
3604
|
+
const tokenSnapshot = await getDocs4(q);
|
|
3477
3605
|
if (!tokenSnapshot.empty) {
|
|
3478
3606
|
return tokenSnapshot.docs[0].data();
|
|
3479
3607
|
}
|
|
@@ -3487,7 +3615,7 @@ var PractitionerService = class extends BaseService {
|
|
|
3487
3615
|
* @param userId ID of the user using the token
|
|
3488
3616
|
*/
|
|
3489
3617
|
async markTokenAsUsed(tokenId, practitionerId, userId) {
|
|
3490
|
-
const tokenRef =
|
|
3618
|
+
const tokenRef = doc6(
|
|
3491
3619
|
this.db,
|
|
3492
3620
|
`${PRACTITIONERS_COLLECTION}/${practitionerId}/${REGISTER_TOKENS_COLLECTION}/${tokenId}`
|
|
3493
3621
|
);
|
|
@@ -3502,7 +3630,7 @@ var PractitionerService = class extends BaseService {
|
|
|
3502
3630
|
*/
|
|
3503
3631
|
async getPractitioner(practitionerId) {
|
|
3504
3632
|
const practitionerDoc = await getDoc9(
|
|
3505
|
-
|
|
3633
|
+
doc6(this.db, PRACTITIONERS_COLLECTION, practitionerId)
|
|
3506
3634
|
);
|
|
3507
3635
|
if (!practitionerDoc.exists()) {
|
|
3508
3636
|
return null;
|
|
@@ -3513,11 +3641,11 @@ var PractitionerService = class extends BaseService {
|
|
|
3513
3641
|
* Dohvata zdravstvenog radnika po User ID-u
|
|
3514
3642
|
*/
|
|
3515
3643
|
async getPractitionerByUserRef(userRef) {
|
|
3516
|
-
const q =
|
|
3517
|
-
|
|
3518
|
-
|
|
3644
|
+
const q = query4(
|
|
3645
|
+
collection4(this.db, PRACTITIONERS_COLLECTION),
|
|
3646
|
+
where4("userRef", "==", userRef)
|
|
3519
3647
|
);
|
|
3520
|
-
const querySnapshot = await
|
|
3648
|
+
const querySnapshot = await getDocs4(q);
|
|
3521
3649
|
if (querySnapshot.empty) {
|
|
3522
3650
|
return null;
|
|
3523
3651
|
}
|
|
@@ -3527,44 +3655,44 @@ var PractitionerService = class extends BaseService {
|
|
|
3527
3655
|
* Dohvata sve zdravstvene radnike za određenu kliniku sa statusom ACTIVE
|
|
3528
3656
|
*/
|
|
3529
3657
|
async getPractitionersByClinic(clinicId) {
|
|
3530
|
-
const q =
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3658
|
+
const q = query4(
|
|
3659
|
+
collection4(this.db, PRACTITIONERS_COLLECTION),
|
|
3660
|
+
where4("clinics", "array-contains", clinicId),
|
|
3661
|
+
where4("isActive", "==", true),
|
|
3662
|
+
where4("status", "==", "active" /* ACTIVE */)
|
|
3535
3663
|
);
|
|
3536
|
-
const querySnapshot = await
|
|
3537
|
-
return querySnapshot.docs.map((
|
|
3664
|
+
const querySnapshot = await getDocs4(q);
|
|
3665
|
+
return querySnapshot.docs.map((doc28) => doc28.data());
|
|
3538
3666
|
}
|
|
3539
3667
|
/**
|
|
3540
3668
|
* Dohvata sve zdravstvene radnike za određenu kliniku
|
|
3541
3669
|
*/
|
|
3542
3670
|
async getAllPractitionersByClinic(clinicId) {
|
|
3543
|
-
const q =
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3671
|
+
const q = query4(
|
|
3672
|
+
collection4(this.db, PRACTITIONERS_COLLECTION),
|
|
3673
|
+
where4("clinics", "array-contains", clinicId),
|
|
3674
|
+
where4("isActive", "==", true)
|
|
3547
3675
|
);
|
|
3548
|
-
const querySnapshot = await
|
|
3549
|
-
return querySnapshot.docs.map((
|
|
3676
|
+
const querySnapshot = await getDocs4(q);
|
|
3677
|
+
return querySnapshot.docs.map((doc28) => doc28.data());
|
|
3550
3678
|
}
|
|
3551
3679
|
/**
|
|
3552
3680
|
* Dohvata sve draft zdravstvene radnike za određenu kliniku sa statusom DRAFT
|
|
3553
3681
|
*/
|
|
3554
3682
|
async getDraftPractitionersByClinic(clinicId) {
|
|
3555
|
-
const q =
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3683
|
+
const q = query4(
|
|
3684
|
+
collection4(this.db, PRACTITIONERS_COLLECTION),
|
|
3685
|
+
where4("clinics", "array-contains", clinicId),
|
|
3686
|
+
where4("status", "==", "draft" /* DRAFT */)
|
|
3559
3687
|
);
|
|
3560
|
-
const querySnapshot = await
|
|
3561
|
-
return querySnapshot.docs.map((
|
|
3688
|
+
const querySnapshot = await getDocs4(q);
|
|
3689
|
+
return querySnapshot.docs.map((doc28) => doc28.data());
|
|
3562
3690
|
}
|
|
3563
3691
|
/**
|
|
3564
3692
|
* Ažurira profil zdravstvenog radnika
|
|
3565
3693
|
*/
|
|
3566
3694
|
async updatePractitioner(practitionerId, data) {
|
|
3567
|
-
const practitionerRef =
|
|
3695
|
+
const practitionerRef = doc6(
|
|
3568
3696
|
this.db,
|
|
3569
3697
|
PRACTITIONERS_COLLECTION,
|
|
3570
3698
|
practitionerId
|
|
@@ -3662,7 +3790,7 @@ var PractitionerService = class extends BaseService {
|
|
|
3662
3790
|
if (!practitioner) {
|
|
3663
3791
|
throw new Error("Practitioner not found");
|
|
3664
3792
|
}
|
|
3665
|
-
await deleteDoc2(
|
|
3793
|
+
await deleteDoc2(doc6(this.db, PRACTITIONERS_COLLECTION, practitionerId));
|
|
3666
3794
|
}
|
|
3667
3795
|
/**
|
|
3668
3796
|
* Validates a registration token and claims the associated draft practitioner profile
|
|
@@ -3734,13 +3862,13 @@ var UserService = class extends BaseService {
|
|
|
3734
3862
|
updatedAt: serverTimestamp10(),
|
|
3735
3863
|
lastLoginAt: serverTimestamp10()
|
|
3736
3864
|
};
|
|
3737
|
-
await setDoc8(
|
|
3865
|
+
await setDoc8(doc7(this.db, USERS_COLLECTION, userData.uid), userData);
|
|
3738
3866
|
const profiles = await this.createProfilesForRoles(
|
|
3739
3867
|
userData.uid,
|
|
3740
3868
|
roles,
|
|
3741
3869
|
options
|
|
3742
3870
|
);
|
|
3743
|
-
await updateDoc9(
|
|
3871
|
+
await updateDoc9(doc7(this.db, USERS_COLLECTION, userData.uid), profiles);
|
|
3744
3872
|
return this.getUserById(userData.uid);
|
|
3745
3873
|
}
|
|
3746
3874
|
/**
|
|
@@ -3843,7 +3971,7 @@ var UserService = class extends BaseService {
|
|
|
3843
3971
|
* Dohvata korisnika po ID-u
|
|
3844
3972
|
*/
|
|
3845
3973
|
async getUserById(uid) {
|
|
3846
|
-
const userDoc = await getDoc10(
|
|
3974
|
+
const userDoc = await getDoc10(doc7(this.db, USERS_COLLECTION, uid));
|
|
3847
3975
|
if (!userDoc.exists()) {
|
|
3848
3976
|
throw USER_ERRORS.NOT_FOUND;
|
|
3849
3977
|
}
|
|
@@ -3854,27 +3982,27 @@ var UserService = class extends BaseService {
|
|
|
3854
3982
|
* Dohvata korisnika po email-u
|
|
3855
3983
|
*/
|
|
3856
3984
|
async getUserByEmail(email) {
|
|
3857
|
-
const usersRef =
|
|
3858
|
-
const q =
|
|
3859
|
-
const querySnapshot = await
|
|
3985
|
+
const usersRef = collection5(this.db, USERS_COLLECTION);
|
|
3986
|
+
const q = query5(usersRef, where5("email", "==", email));
|
|
3987
|
+
const querySnapshot = await getDocs5(q);
|
|
3860
3988
|
if (querySnapshot.empty) return null;
|
|
3861
3989
|
const userData = querySnapshot.docs[0].data();
|
|
3862
3990
|
return userSchema.parse(userData);
|
|
3863
3991
|
}
|
|
3864
3992
|
async getUsersByRole(role) {
|
|
3865
3993
|
const constraints = [
|
|
3866
|
-
|
|
3994
|
+
where5("roles", "array-contains", role)
|
|
3867
3995
|
];
|
|
3868
|
-
const q =
|
|
3869
|
-
const querySnapshot = await
|
|
3870
|
-
const users = querySnapshot.docs.map((
|
|
3996
|
+
const q = query5(collection5(this.db, USERS_COLLECTION), ...constraints);
|
|
3997
|
+
const querySnapshot = await getDocs5(q);
|
|
3998
|
+
const users = querySnapshot.docs.map((doc28) => doc28.data());
|
|
3871
3999
|
return Promise.all(users.map((userData) => userSchema.parse(userData)));
|
|
3872
4000
|
}
|
|
3873
4001
|
/**
|
|
3874
4002
|
* Ažurira timestamp poslednjeg logovanja
|
|
3875
4003
|
*/
|
|
3876
4004
|
async updateUserLoginTimestamp(uid) {
|
|
3877
|
-
const userRef =
|
|
4005
|
+
const userRef = doc7(this.db, USERS_COLLECTION, uid);
|
|
3878
4006
|
const userDoc = await getDoc10(userRef);
|
|
3879
4007
|
if (!userDoc.exists()) {
|
|
3880
4008
|
throw AUTH_ERRORS.USER_NOT_FOUND;
|
|
@@ -3886,7 +4014,7 @@ var UserService = class extends BaseService {
|
|
|
3886
4014
|
return this.getUserById(uid);
|
|
3887
4015
|
}
|
|
3888
4016
|
async upgradeAnonymousUser(uid, email) {
|
|
3889
|
-
const userRef =
|
|
4017
|
+
const userRef = doc7(this.db, USERS_COLLECTION, uid);
|
|
3890
4018
|
const userDoc = await getDoc10(userRef);
|
|
3891
4019
|
if (!userDoc.exists()) {
|
|
3892
4020
|
throw USER_ERRORS.NOT_FOUND;
|
|
@@ -3899,7 +4027,7 @@ var UserService = class extends BaseService {
|
|
|
3899
4027
|
return this.getUserById(uid);
|
|
3900
4028
|
}
|
|
3901
4029
|
async updateUser(uid, updates) {
|
|
3902
|
-
const userRef =
|
|
4030
|
+
const userRef = doc7(this.db, USERS_COLLECTION, uid);
|
|
3903
4031
|
const userDoc = await getDoc10(userRef);
|
|
3904
4032
|
if (!userDoc.exists()) {
|
|
3905
4033
|
throw USER_ERRORS.NOT_FOUND;
|
|
@@ -3931,7 +4059,7 @@ var UserService = class extends BaseService {
|
|
|
3931
4059
|
const user = await this.getUserById(uid);
|
|
3932
4060
|
if (user.roles.includes(role)) return;
|
|
3933
4061
|
const profiles = await this.createProfilesForRoles(uid, [role], options);
|
|
3934
|
-
await updateDoc9(
|
|
4062
|
+
await updateDoc9(doc7(this.db, USERS_COLLECTION, uid), {
|
|
3935
4063
|
roles: [...user.roles, role],
|
|
3936
4064
|
...profiles,
|
|
3937
4065
|
updatedAt: serverTimestamp10()
|
|
@@ -3966,14 +4094,14 @@ var UserService = class extends BaseService {
|
|
|
3966
4094
|
}
|
|
3967
4095
|
break;
|
|
3968
4096
|
}
|
|
3969
|
-
await updateDoc9(
|
|
4097
|
+
await updateDoc9(doc7(this.db, USERS_COLLECTION, uid), {
|
|
3970
4098
|
roles: user.roles.filter((r) => r !== role),
|
|
3971
4099
|
updatedAt: serverTimestamp10()
|
|
3972
4100
|
});
|
|
3973
4101
|
}
|
|
3974
4102
|
// Delete operations
|
|
3975
4103
|
async deleteUser(uid) {
|
|
3976
|
-
const userRef =
|
|
4104
|
+
const userRef = doc7(this.db, USERS_COLLECTION, uid);
|
|
3977
4105
|
const userDoc = await getDoc10(userRef);
|
|
3978
4106
|
if (!userDoc.exists()) {
|
|
3979
4107
|
throw USER_ERRORS.NOT_FOUND;
|
|
@@ -4004,12 +4132,12 @@ var UserService = class extends BaseService {
|
|
|
4004
4132
|
|
|
4005
4133
|
// src/services/clinic/utils/clinic-group.utils.ts
|
|
4006
4134
|
import {
|
|
4007
|
-
collection as
|
|
4008
|
-
doc as
|
|
4135
|
+
collection as collection6,
|
|
4136
|
+
doc as doc8,
|
|
4009
4137
|
getDoc as getDoc11,
|
|
4010
|
-
getDocs as
|
|
4011
|
-
query as
|
|
4012
|
-
where as
|
|
4138
|
+
getDocs as getDocs6,
|
|
4139
|
+
query as query6,
|
|
4140
|
+
where as where6,
|
|
4013
4141
|
updateDoc as updateDoc10,
|
|
4014
4142
|
setDoc as setDoc9,
|
|
4015
4143
|
Timestamp as Timestamp10
|
|
@@ -4138,7 +4266,7 @@ async function createClinicGroup(db, data, ownerId, isDefault = false, clinicAdm
|
|
|
4138
4266
|
}
|
|
4139
4267
|
const now = Timestamp10.now();
|
|
4140
4268
|
console.log("[CLINIC_GROUP] Preparing clinic group data object");
|
|
4141
|
-
const groupId =
|
|
4269
|
+
const groupId = doc8(collection6(db, CLINIC_GROUPS_COLLECTION)).id;
|
|
4142
4270
|
console.log("[CLINIC_GROUP] Logo value:", {
|
|
4143
4271
|
logoValue: validatedData.logo,
|
|
4144
4272
|
logoType: validatedData.logo === null ? "null" : typeof validatedData.logo
|
|
@@ -4188,7 +4316,7 @@ async function createClinicGroup(db, data, ownerId, isDefault = false, clinicAdm
|
|
|
4188
4316
|
groupId: groupData.id
|
|
4189
4317
|
});
|
|
4190
4318
|
try {
|
|
4191
|
-
await setDoc9(
|
|
4319
|
+
await setDoc9(doc8(db, CLINIC_GROUPS_COLLECTION, groupData.id), groupData);
|
|
4192
4320
|
console.log("[CLINIC_GROUP] Clinic group saved successfully");
|
|
4193
4321
|
} catch (firestoreError) {
|
|
4194
4322
|
console.error(
|
|
@@ -4234,7 +4362,7 @@ async function createClinicGroup(db, data, ownerId, isDefault = false, clinicAdm
|
|
|
4234
4362
|
}
|
|
4235
4363
|
}
|
|
4236
4364
|
async function getClinicGroup(db, groupId) {
|
|
4237
|
-
const docRef =
|
|
4365
|
+
const docRef = doc8(db, CLINIC_GROUPS_COLLECTION, groupId);
|
|
4238
4366
|
const docSnap = await getDoc11(docRef);
|
|
4239
4367
|
if (docSnap.exists()) {
|
|
4240
4368
|
return docSnap.data();
|
|
@@ -4242,12 +4370,12 @@ async function getClinicGroup(db, groupId) {
|
|
|
4242
4370
|
return null;
|
|
4243
4371
|
}
|
|
4244
4372
|
async function getAllActiveGroups(db) {
|
|
4245
|
-
const q =
|
|
4246
|
-
|
|
4247
|
-
|
|
4373
|
+
const q = query6(
|
|
4374
|
+
collection6(db, CLINIC_GROUPS_COLLECTION),
|
|
4375
|
+
where6("isActive", "==", true)
|
|
4248
4376
|
);
|
|
4249
|
-
const querySnapshot = await
|
|
4250
|
-
return querySnapshot.docs.map((
|
|
4377
|
+
const querySnapshot = await getDocs6(q);
|
|
4378
|
+
return querySnapshot.docs.map((doc28) => doc28.data());
|
|
4251
4379
|
}
|
|
4252
4380
|
async function updateClinicGroup(db, groupId, data, app) {
|
|
4253
4381
|
console.log("[CLINIC_GROUP] Updating clinic group", { groupId });
|
|
@@ -4278,7 +4406,7 @@ async function updateClinicGroup(db, groupId, data, app) {
|
|
|
4278
4406
|
updatedAt: Timestamp10.now()
|
|
4279
4407
|
};
|
|
4280
4408
|
console.log("[CLINIC_GROUP] Updating clinic group in Firestore");
|
|
4281
|
-
await updateDoc10(
|
|
4409
|
+
await updateDoc10(doc8(db, CLINIC_GROUPS_COLLECTION, groupId), updatedData);
|
|
4282
4410
|
console.log("[CLINIC_GROUP] Clinic group updated successfully");
|
|
4283
4411
|
const updatedGroup = await getClinicGroup(db, groupId);
|
|
4284
4412
|
if (!updatedGroup) {
|
|
@@ -4623,12 +4751,12 @@ var ClinicGroupService = class extends BaseService {
|
|
|
4623
4751
|
|
|
4624
4752
|
// src/services/clinic/utils/clinic.utils.ts
|
|
4625
4753
|
import {
|
|
4626
|
-
collection as
|
|
4627
|
-
doc as
|
|
4754
|
+
collection as collection7,
|
|
4755
|
+
doc as doc9,
|
|
4628
4756
|
getDoc as getDoc12,
|
|
4629
|
-
getDocs as
|
|
4630
|
-
query as
|
|
4631
|
-
where as
|
|
4757
|
+
getDocs as getDocs7,
|
|
4758
|
+
query as query7,
|
|
4759
|
+
where as where7,
|
|
4632
4760
|
updateDoc as updateDoc11,
|
|
4633
4761
|
setDoc as setDoc10,
|
|
4634
4762
|
Timestamp as Timestamp11
|
|
@@ -4697,7 +4825,7 @@ async function createClinic(db, data, creatorAdminId, clinicGroupService, clinic
|
|
|
4697
4825
|
throw geohashError;
|
|
4698
4826
|
}
|
|
4699
4827
|
}
|
|
4700
|
-
const clinicId =
|
|
4828
|
+
const clinicId = doc9(collection7(db, CLINICS_COLLECTION)).id;
|
|
4701
4829
|
console.log("[CLINIC] Generated clinic ID:", clinicId);
|
|
4702
4830
|
console.log("[CLINIC] Processing photos");
|
|
4703
4831
|
let logoUrl = null;
|
|
@@ -4849,7 +4977,7 @@ async function createClinic(db, data, creatorAdminId, clinicGroupService, clinic
|
|
|
4849
4977
|
clinicId: clinicData.id
|
|
4850
4978
|
});
|
|
4851
4979
|
try {
|
|
4852
|
-
await setDoc10(
|
|
4980
|
+
await setDoc10(doc9(db, CLINICS_COLLECTION, clinicData.id), clinicData);
|
|
4853
4981
|
console.log("[CLINIC] Clinic saved successfully");
|
|
4854
4982
|
} catch (firestoreError) {
|
|
4855
4983
|
console.error("[CLINIC] Error saving to Firestore:", firestoreError);
|
|
@@ -4905,7 +5033,7 @@ async function createClinic(db, data, creatorAdminId, clinicGroupService, clinic
|
|
|
4905
5033
|
}
|
|
4906
5034
|
}
|
|
4907
5035
|
async function getClinic(db, clinicId) {
|
|
4908
|
-
const docRef =
|
|
5036
|
+
const docRef = doc9(db, CLINICS_COLLECTION, clinicId);
|
|
4909
5037
|
const docSnap = await getDoc12(docRef);
|
|
4910
5038
|
if (docSnap.exists()) {
|
|
4911
5039
|
return docSnap.data();
|
|
@@ -4913,13 +5041,13 @@ async function getClinic(db, clinicId) {
|
|
|
4913
5041
|
return null;
|
|
4914
5042
|
}
|
|
4915
5043
|
async function getClinicsByGroup(db, groupId) {
|
|
4916
|
-
const q =
|
|
4917
|
-
|
|
4918
|
-
|
|
4919
|
-
|
|
5044
|
+
const q = query7(
|
|
5045
|
+
collection7(db, CLINICS_COLLECTION),
|
|
5046
|
+
where7("clinicGroupId", "==", groupId),
|
|
5047
|
+
where7("isActive", "==", true)
|
|
4920
5048
|
);
|
|
4921
|
-
const querySnapshot = await
|
|
4922
|
-
return querySnapshot.docs.map((
|
|
5049
|
+
const querySnapshot = await getDocs7(q);
|
|
5050
|
+
return querySnapshot.docs.map((doc28) => doc28.data());
|
|
4923
5051
|
}
|
|
4924
5052
|
async function updateClinic(db, clinicId, data, adminId, clinicAdminService, app) {
|
|
4925
5053
|
console.log("[CLINIC] Starting clinic update", { clinicId, adminId });
|
|
@@ -5078,7 +5206,7 @@ async function updateClinic(db, clinicId, data, adminId, clinicAdminService, app
|
|
|
5078
5206
|
};
|
|
5079
5207
|
console.log("[CLINIC] Updating clinic in Firestore");
|
|
5080
5208
|
try {
|
|
5081
|
-
await updateDoc11(
|
|
5209
|
+
await updateDoc11(doc9(db, CLINICS_COLLECTION, clinicId), updatedData);
|
|
5082
5210
|
console.log("[CLINIC] Clinic updated successfully");
|
|
5083
5211
|
} catch (updateError) {
|
|
5084
5212
|
console.error("[CLINIC] Error updating clinic in Firestore:", updateError);
|
|
@@ -5105,7 +5233,7 @@ async function deactivateClinic(db, clinicId, adminId, clinicAdminService) {
|
|
|
5105
5233
|
if (!hasPermission) {
|
|
5106
5234
|
throw new Error("Admin does not have permission to deactivate this clinic");
|
|
5107
5235
|
}
|
|
5108
|
-
await updateDoc11(
|
|
5236
|
+
await updateDoc11(doc9(db, CLINICS_COLLECTION, clinicId), {
|
|
5109
5237
|
isActive: false,
|
|
5110
5238
|
updatedAt: Timestamp11.now()
|
|
5111
5239
|
});
|
|
@@ -5125,13 +5253,13 @@ async function getClinicsByAdmin(db, adminId, options = {}, clinicAdminService,
|
|
|
5125
5253
|
if (clinicIds.length === 0) {
|
|
5126
5254
|
return [];
|
|
5127
5255
|
}
|
|
5128
|
-
const constraints = [
|
|
5256
|
+
const constraints = [where7("id", "in", clinicIds)];
|
|
5129
5257
|
if (options.isActive !== void 0) {
|
|
5130
|
-
constraints.push(
|
|
5258
|
+
constraints.push(where7("isActive", "==", options.isActive));
|
|
5131
5259
|
}
|
|
5132
|
-
const q =
|
|
5133
|
-
const querySnapshot = await
|
|
5134
|
-
return querySnapshot.docs.map((
|
|
5260
|
+
const q = query7(collection7(db, CLINICS_COLLECTION), ...constraints);
|
|
5261
|
+
const querySnapshot = await getDocs7(q);
|
|
5262
|
+
return querySnapshot.docs.map((doc28) => doc28.data());
|
|
5135
5263
|
}
|
|
5136
5264
|
async function getActiveClinicsByAdmin(db, adminId, clinicAdminService, clinicGroupService) {
|
|
5137
5265
|
return getClinicsByAdmin(
|
|
@@ -5145,14 +5273,14 @@ async function getActiveClinicsByAdmin(db, adminId, clinicAdminService, clinicGr
|
|
|
5145
5273
|
|
|
5146
5274
|
// src/services/clinic/utils/review.utils.ts
|
|
5147
5275
|
import {
|
|
5148
|
-
collection as
|
|
5149
|
-
doc as
|
|
5276
|
+
collection as collection8,
|
|
5277
|
+
doc as doc10,
|
|
5150
5278
|
Timestamp as Timestamp12,
|
|
5151
5279
|
getDoc as getDoc13,
|
|
5152
5280
|
addDoc as addDoc2
|
|
5153
5281
|
} from "firebase/firestore";
|
|
5154
5282
|
async function addReview(db, clinicId, review, app) {
|
|
5155
|
-
const clinicRef =
|
|
5283
|
+
const clinicRef = doc10(db, "clinics", clinicId);
|
|
5156
5284
|
const clinicSnap = await getDoc13(clinicRef);
|
|
5157
5285
|
if (!clinicSnap.exists()) {
|
|
5158
5286
|
throw new Error("Clinic not found");
|
|
@@ -5161,14 +5289,14 @@ async function addReview(db, clinicId, review, app) {
|
|
|
5161
5289
|
const now = Timestamp12.now();
|
|
5162
5290
|
const reviewData = {
|
|
5163
5291
|
...review,
|
|
5164
|
-
id:
|
|
5292
|
+
id: doc10(collection8(db, "clinic_reviews")).id,
|
|
5165
5293
|
clinicId,
|
|
5166
5294
|
createdAt: now,
|
|
5167
5295
|
updatedAt: now,
|
|
5168
5296
|
isVerified: false
|
|
5169
5297
|
};
|
|
5170
5298
|
clinicReviewSchema.parse(reviewData);
|
|
5171
|
-
await addDoc2(
|
|
5299
|
+
await addDoc2(collection8(db, "clinic_reviews"), reviewData);
|
|
5172
5300
|
const newRating = clinic.rating ? {
|
|
5173
5301
|
average: (clinic.rating.average * clinic.rating.count + review.rating) / (clinic.rating.count + 1),
|
|
5174
5302
|
count: clinic.rating.count + 1
|
|
@@ -5256,10 +5384,10 @@ async function removeTags(db, clinicId, adminId, tagsToRemove, clinicAdminServic
|
|
|
5256
5384
|
|
|
5257
5385
|
// src/services/clinic/utils/search.utils.ts
|
|
5258
5386
|
import {
|
|
5259
|
-
collection as
|
|
5260
|
-
query as
|
|
5261
|
-
where as
|
|
5262
|
-
getDocs as
|
|
5387
|
+
collection as collection9,
|
|
5388
|
+
query as query8,
|
|
5389
|
+
where as where8,
|
|
5390
|
+
getDocs as getDocs8
|
|
5263
5391
|
} from "firebase/firestore";
|
|
5264
5392
|
import { geohashQueryBounds, distanceBetween } from "geofire-common";
|
|
5265
5393
|
async function findClinicsInRadius(db, center, radiusInKm, filters) {
|
|
@@ -5270,22 +5398,22 @@ async function findClinicsInRadius(db, center, radiusInKm, filters) {
|
|
|
5270
5398
|
const matchingDocs = [];
|
|
5271
5399
|
for (const b of bounds) {
|
|
5272
5400
|
const constraints = [
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5401
|
+
where8("location.geohash", ">=", b[0]),
|
|
5402
|
+
where8("location.geohash", "<=", b[1]),
|
|
5403
|
+
where8("isActive", "==", true)
|
|
5276
5404
|
];
|
|
5277
5405
|
if (filters == null ? void 0 : filters.services) {
|
|
5278
5406
|
constraints.push(
|
|
5279
|
-
|
|
5407
|
+
where8("services", "array-contains-any", filters.services)
|
|
5280
5408
|
);
|
|
5281
5409
|
}
|
|
5282
5410
|
if ((filters == null ? void 0 : filters.tags) && filters.tags.length > 0) {
|
|
5283
|
-
constraints.push(
|
|
5411
|
+
constraints.push(where8("tags", "array-contains-any", filters.tags));
|
|
5284
5412
|
}
|
|
5285
|
-
const q =
|
|
5286
|
-
const querySnapshot = await
|
|
5287
|
-
for (const
|
|
5288
|
-
const clinic =
|
|
5413
|
+
const q = query8(collection9(db, CLINICS_COLLECTION), ...constraints);
|
|
5414
|
+
const querySnapshot = await getDocs8(q);
|
|
5415
|
+
for (const doc28 of querySnapshot.docs) {
|
|
5416
|
+
const clinic = doc28.data();
|
|
5289
5417
|
const distance = distanceBetween(
|
|
5290
5418
|
[center.latitude, center.longitude],
|
|
5291
5419
|
[clinic.location.latitude, clinic.location.longitude]
|
|
@@ -5699,9 +5827,9 @@ var AuthService = class extends BaseService {
|
|
|
5699
5827
|
token: data.inviteToken
|
|
5700
5828
|
});
|
|
5701
5829
|
console.log("[AUTH] Searching for token in clinic groups");
|
|
5702
|
-
const groupsRef =
|
|
5703
|
-
const q =
|
|
5704
|
-
const querySnapshot = await
|
|
5830
|
+
const groupsRef = collection10(this.db, CLINIC_GROUPS_COLLECTION);
|
|
5831
|
+
const q = query9(groupsRef);
|
|
5832
|
+
const querySnapshot = await getDocs9(q);
|
|
5705
5833
|
let foundGroup = null;
|
|
5706
5834
|
let foundToken = null;
|
|
5707
5835
|
console.log(
|
|
@@ -6148,12 +6276,12 @@ var AuthService = class extends BaseService {
|
|
|
6148
6276
|
|
|
6149
6277
|
// src/services/notifications/notification.service.ts
|
|
6150
6278
|
import {
|
|
6151
|
-
collection as
|
|
6152
|
-
doc as
|
|
6279
|
+
collection as collection11,
|
|
6280
|
+
doc as doc12,
|
|
6153
6281
|
getDoc as getDoc15,
|
|
6154
|
-
getDocs as
|
|
6155
|
-
query as
|
|
6156
|
-
where as
|
|
6282
|
+
getDocs as getDocs10,
|
|
6283
|
+
query as query10,
|
|
6284
|
+
where as where10,
|
|
6157
6285
|
updateDoc as updateDoc13,
|
|
6158
6286
|
deleteDoc as deleteDoc6,
|
|
6159
6287
|
orderBy,
|
|
@@ -6186,7 +6314,7 @@ var NotificationService = class extends BaseService {
|
|
|
6186
6314
|
* Kreira novu notifikaciju
|
|
6187
6315
|
*/
|
|
6188
6316
|
async createNotification(notification) {
|
|
6189
|
-
const notificationsRef =
|
|
6317
|
+
const notificationsRef = collection11(this.db, NOTIFICATIONS_COLLECTION);
|
|
6190
6318
|
const now = Timestamp14.now();
|
|
6191
6319
|
const notificationData = {
|
|
6192
6320
|
...notification,
|
|
@@ -6206,7 +6334,7 @@ var NotificationService = class extends BaseService {
|
|
|
6206
6334
|
* Dohvata notifikaciju po ID-u
|
|
6207
6335
|
*/
|
|
6208
6336
|
async getNotification(notificationId) {
|
|
6209
|
-
const notificationRef =
|
|
6337
|
+
const notificationRef = doc12(
|
|
6210
6338
|
this.db,
|
|
6211
6339
|
NOTIFICATIONS_COLLECTION,
|
|
6212
6340
|
notificationId
|
|
@@ -6224,38 +6352,38 @@ var NotificationService = class extends BaseService {
|
|
|
6224
6352
|
* Dohvata sve notifikacije za korisnika
|
|
6225
6353
|
*/
|
|
6226
6354
|
async getUserNotifications(userId) {
|
|
6227
|
-
const q =
|
|
6228
|
-
|
|
6229
|
-
|
|
6355
|
+
const q = query10(
|
|
6356
|
+
collection11(this.db, NOTIFICATIONS_COLLECTION),
|
|
6357
|
+
where10("userId", "==", userId),
|
|
6230
6358
|
orderBy("notificationTime", "desc")
|
|
6231
6359
|
);
|
|
6232
|
-
const querySnapshot = await
|
|
6233
|
-
return querySnapshot.docs.map((
|
|
6234
|
-
id:
|
|
6235
|
-
...
|
|
6360
|
+
const querySnapshot = await getDocs10(q);
|
|
6361
|
+
return querySnapshot.docs.map((doc28) => ({
|
|
6362
|
+
id: doc28.id,
|
|
6363
|
+
...doc28.data()
|
|
6236
6364
|
}));
|
|
6237
6365
|
}
|
|
6238
6366
|
/**
|
|
6239
6367
|
* Dohvata nepročitane notifikacije za korisnika
|
|
6240
6368
|
*/
|
|
6241
6369
|
async getUnreadNotifications(userId) {
|
|
6242
|
-
const q =
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6370
|
+
const q = query10(
|
|
6371
|
+
collection11(this.db, NOTIFICATIONS_COLLECTION),
|
|
6372
|
+
where10("userId", "==", userId),
|
|
6373
|
+
where10("isRead", "==", false),
|
|
6246
6374
|
orderBy("notificationTime", "desc")
|
|
6247
6375
|
);
|
|
6248
|
-
const querySnapshot = await
|
|
6249
|
-
return querySnapshot.docs.map((
|
|
6250
|
-
id:
|
|
6251
|
-
...
|
|
6376
|
+
const querySnapshot = await getDocs10(q);
|
|
6377
|
+
return querySnapshot.docs.map((doc28) => ({
|
|
6378
|
+
id: doc28.id,
|
|
6379
|
+
...doc28.data()
|
|
6252
6380
|
}));
|
|
6253
6381
|
}
|
|
6254
6382
|
/**
|
|
6255
6383
|
* Označava notifikaciju kao pročitanu
|
|
6256
6384
|
*/
|
|
6257
6385
|
async markAsRead(notificationId) {
|
|
6258
|
-
const notificationRef =
|
|
6386
|
+
const notificationRef = doc12(
|
|
6259
6387
|
this.db,
|
|
6260
6388
|
NOTIFICATIONS_COLLECTION,
|
|
6261
6389
|
notificationId
|
|
@@ -6272,7 +6400,7 @@ var NotificationService = class extends BaseService {
|
|
|
6272
6400
|
const notifications = await this.getUnreadNotifications(userId);
|
|
6273
6401
|
const batch = writeBatch3(this.db);
|
|
6274
6402
|
notifications.forEach((notification) => {
|
|
6275
|
-
const notificationRef =
|
|
6403
|
+
const notificationRef = doc12(
|
|
6276
6404
|
this.db,
|
|
6277
6405
|
NOTIFICATIONS_COLLECTION,
|
|
6278
6406
|
notification.id
|
|
@@ -6288,7 +6416,7 @@ var NotificationService = class extends BaseService {
|
|
|
6288
6416
|
* Ažurira status notifikacije
|
|
6289
6417
|
*/
|
|
6290
6418
|
async updateNotificationStatus(notificationId, status) {
|
|
6291
|
-
const notificationRef =
|
|
6419
|
+
const notificationRef = doc12(
|
|
6292
6420
|
this.db,
|
|
6293
6421
|
NOTIFICATIONS_COLLECTION,
|
|
6294
6422
|
notificationId
|
|
@@ -6302,7 +6430,7 @@ var NotificationService = class extends BaseService {
|
|
|
6302
6430
|
* Briše notifikaciju
|
|
6303
6431
|
*/
|
|
6304
6432
|
async deleteNotification(notificationId) {
|
|
6305
|
-
const notificationRef =
|
|
6433
|
+
const notificationRef = doc12(
|
|
6306
6434
|
this.db,
|
|
6307
6435
|
NOTIFICATIONS_COLLECTION,
|
|
6308
6436
|
notificationId
|
|
@@ -6313,43 +6441,43 @@ var NotificationService = class extends BaseService {
|
|
|
6313
6441
|
* Dohvata notifikacije po tipu
|
|
6314
6442
|
*/
|
|
6315
6443
|
async getNotificationsByType(userId, type) {
|
|
6316
|
-
const q =
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
|
|
6444
|
+
const q = query10(
|
|
6445
|
+
collection11(this.db, NOTIFICATIONS_COLLECTION),
|
|
6446
|
+
where10("userId", "==", userId),
|
|
6447
|
+
where10("notificationType", "==", type),
|
|
6320
6448
|
orderBy("notificationTime", "desc")
|
|
6321
6449
|
);
|
|
6322
|
-
const querySnapshot = await
|
|
6323
|
-
return querySnapshot.docs.map((
|
|
6324
|
-
id:
|
|
6325
|
-
...
|
|
6450
|
+
const querySnapshot = await getDocs10(q);
|
|
6451
|
+
return querySnapshot.docs.map((doc28) => ({
|
|
6452
|
+
id: doc28.id,
|
|
6453
|
+
...doc28.data()
|
|
6326
6454
|
}));
|
|
6327
6455
|
}
|
|
6328
6456
|
/**
|
|
6329
6457
|
* Dohvata notifikacije za određeni termin
|
|
6330
6458
|
*/
|
|
6331
6459
|
async getAppointmentNotifications(appointmentId) {
|
|
6332
|
-
const q =
|
|
6333
|
-
|
|
6334
|
-
|
|
6460
|
+
const q = query10(
|
|
6461
|
+
collection11(this.db, NOTIFICATIONS_COLLECTION),
|
|
6462
|
+
where10("appointmentId", "==", appointmentId),
|
|
6335
6463
|
orderBy("notificationTime", "desc")
|
|
6336
6464
|
);
|
|
6337
|
-
const querySnapshot = await
|
|
6338
|
-
return querySnapshot.docs.map((
|
|
6339
|
-
id:
|
|
6340
|
-
...
|
|
6465
|
+
const querySnapshot = await getDocs10(q);
|
|
6466
|
+
return querySnapshot.docs.map((doc28) => ({
|
|
6467
|
+
id: doc28.id,
|
|
6468
|
+
...doc28.data()
|
|
6341
6469
|
}));
|
|
6342
6470
|
}
|
|
6343
6471
|
};
|
|
6344
6472
|
|
|
6345
6473
|
// src/services/procedure/procedure.service.ts
|
|
6346
6474
|
import {
|
|
6347
|
-
collection as
|
|
6348
|
-
doc as
|
|
6475
|
+
collection as collection12,
|
|
6476
|
+
doc as doc13,
|
|
6349
6477
|
getDoc as getDoc16,
|
|
6350
|
-
getDocs as
|
|
6351
|
-
query as
|
|
6352
|
-
where as
|
|
6478
|
+
getDocs as getDocs11,
|
|
6479
|
+
query as query11,
|
|
6480
|
+
where as where11,
|
|
6353
6481
|
updateDoc as updateDoc14,
|
|
6354
6482
|
setDoc as setDoc13,
|
|
6355
6483
|
serverTimestamp as serverTimestamp13
|
|
@@ -6461,7 +6589,7 @@ var ProcedureService = class extends BaseService {
|
|
|
6461
6589
|
updatedAt: /* @__PURE__ */ new Date()
|
|
6462
6590
|
};
|
|
6463
6591
|
const id = this.generateId();
|
|
6464
|
-
const docRef =
|
|
6592
|
+
const docRef = doc13(this.db, PROCEDURES_COLLECTION, id);
|
|
6465
6593
|
await setDoc13(docRef, {
|
|
6466
6594
|
...procedure,
|
|
6467
6595
|
id,
|
|
@@ -6476,7 +6604,7 @@ var ProcedureService = class extends BaseService {
|
|
|
6476
6604
|
* @returns The procedure if found, null otherwise
|
|
6477
6605
|
*/
|
|
6478
6606
|
async getProcedure(id) {
|
|
6479
|
-
const docRef =
|
|
6607
|
+
const docRef = doc13(this.db, PROCEDURES_COLLECTION, id);
|
|
6480
6608
|
const docSnap = await getDoc16(docRef);
|
|
6481
6609
|
if (!docSnap.exists()) {
|
|
6482
6610
|
return null;
|
|
@@ -6489,13 +6617,13 @@ var ProcedureService = class extends BaseService {
|
|
|
6489
6617
|
* @returns List of procedures
|
|
6490
6618
|
*/
|
|
6491
6619
|
async getProceduresByClinicBranch(clinicBranchId) {
|
|
6492
|
-
const q =
|
|
6493
|
-
|
|
6494
|
-
|
|
6495
|
-
|
|
6620
|
+
const q = query11(
|
|
6621
|
+
collection12(this.db, PROCEDURES_COLLECTION),
|
|
6622
|
+
where11("clinicBranchId", "==", clinicBranchId),
|
|
6623
|
+
where11("isActive", "==", true)
|
|
6496
6624
|
);
|
|
6497
|
-
const snapshot = await
|
|
6498
|
-
return snapshot.docs.map((
|
|
6625
|
+
const snapshot = await getDocs11(q);
|
|
6626
|
+
return snapshot.docs.map((doc28) => doc28.data());
|
|
6499
6627
|
}
|
|
6500
6628
|
/**
|
|
6501
6629
|
* Gets all procedures for a practitioner
|
|
@@ -6503,13 +6631,13 @@ var ProcedureService = class extends BaseService {
|
|
|
6503
6631
|
* @returns List of procedures
|
|
6504
6632
|
*/
|
|
6505
6633
|
async getProceduresByPractitioner(practitionerId) {
|
|
6506
|
-
const q =
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
|
|
6634
|
+
const q = query11(
|
|
6635
|
+
collection12(this.db, PROCEDURES_COLLECTION),
|
|
6636
|
+
where11("practitionerId", "==", practitionerId),
|
|
6637
|
+
where11("isActive", "==", true)
|
|
6510
6638
|
);
|
|
6511
|
-
const snapshot = await
|
|
6512
|
-
return snapshot.docs.map((
|
|
6639
|
+
const snapshot = await getDocs11(q);
|
|
6640
|
+
return snapshot.docs.map((doc28) => doc28.data());
|
|
6513
6641
|
}
|
|
6514
6642
|
/**
|
|
6515
6643
|
* Updates a procedure
|
|
@@ -6523,7 +6651,7 @@ var ProcedureService = class extends BaseService {
|
|
|
6523
6651
|
if (!existingProcedure) {
|
|
6524
6652
|
throw new Error(`Procedure with ID ${id} not found`);
|
|
6525
6653
|
}
|
|
6526
|
-
const docRef =
|
|
6654
|
+
const docRef = doc13(this.db, PROCEDURES_COLLECTION, id);
|
|
6527
6655
|
await updateDoc14(docRef, {
|
|
6528
6656
|
...validatedData,
|
|
6529
6657
|
updatedAt: serverTimestamp13()
|
|
@@ -6539,7 +6667,7 @@ var ProcedureService = class extends BaseService {
|
|
|
6539
6667
|
* @param id - The ID of the procedure to deactivate
|
|
6540
6668
|
*/
|
|
6541
6669
|
async deactivateProcedure(id) {
|
|
6542
|
-
const docRef =
|
|
6670
|
+
const docRef = doc13(this.db, PROCEDURES_COLLECTION, id);
|
|
6543
6671
|
await updateDoc14(docRef, {
|
|
6544
6672
|
isActive: false,
|
|
6545
6673
|
updatedAt: serverTimestamp13()
|
|
@@ -6579,23 +6707,23 @@ var ProcedureService = class extends BaseService {
|
|
|
6579
6707
|
|
|
6580
6708
|
// src/services/documentation-templates/documentation-template.service.ts
|
|
6581
6709
|
import {
|
|
6582
|
-
collection as
|
|
6583
|
-
doc as
|
|
6710
|
+
collection as collection13,
|
|
6711
|
+
doc as doc14,
|
|
6584
6712
|
getDoc as getDoc17,
|
|
6585
|
-
getDocs as
|
|
6713
|
+
getDocs as getDocs12,
|
|
6586
6714
|
setDoc as setDoc14,
|
|
6587
6715
|
updateDoc as updateDoc15,
|
|
6588
6716
|
deleteDoc as deleteDoc8,
|
|
6589
|
-
query as
|
|
6590
|
-
where as
|
|
6717
|
+
query as query12,
|
|
6718
|
+
where as where12,
|
|
6591
6719
|
orderBy as orderBy2,
|
|
6592
|
-
limit,
|
|
6593
|
-
startAfter
|
|
6720
|
+
limit as limit2,
|
|
6721
|
+
startAfter as startAfter2
|
|
6594
6722
|
} from "firebase/firestore";
|
|
6595
6723
|
var DocumentationTemplateService = class extends BaseService {
|
|
6596
6724
|
constructor() {
|
|
6597
6725
|
super(...arguments);
|
|
6598
|
-
this.collectionRef =
|
|
6726
|
+
this.collectionRef = collection13(
|
|
6599
6727
|
this.db,
|
|
6600
6728
|
DOCUMENTATION_TEMPLATES_COLLECTION
|
|
6601
6729
|
);
|
|
@@ -6626,7 +6754,7 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
6626
6754
|
isActive: true,
|
|
6627
6755
|
tags: validatedData.tags || []
|
|
6628
6756
|
};
|
|
6629
|
-
const docRef =
|
|
6757
|
+
const docRef = doc14(this.collectionRef, templateId);
|
|
6630
6758
|
await setDoc14(docRef, template);
|
|
6631
6759
|
return template;
|
|
6632
6760
|
}
|
|
@@ -6636,7 +6764,7 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
6636
6764
|
* @returns The template or null if not found
|
|
6637
6765
|
*/
|
|
6638
6766
|
async getTemplateById(templateId) {
|
|
6639
|
-
const docRef =
|
|
6767
|
+
const docRef = doc14(this.collectionRef, templateId);
|
|
6640
6768
|
const docSnap = await getDoc17(docRef);
|
|
6641
6769
|
if (!docSnap.exists()) {
|
|
6642
6770
|
return null;
|
|
@@ -6668,7 +6796,7 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
6668
6796
|
updatedAt: Date.now(),
|
|
6669
6797
|
version: template.version + 1
|
|
6670
6798
|
};
|
|
6671
|
-
const docRef =
|
|
6799
|
+
const docRef = doc14(this.collectionRef, templateId);
|
|
6672
6800
|
await updateDoc15(docRef, updateData);
|
|
6673
6801
|
return {
|
|
6674
6802
|
...template,
|
|
@@ -6680,7 +6808,7 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
6680
6808
|
* @param templateId - ID of the template to delete
|
|
6681
6809
|
*/
|
|
6682
6810
|
async deleteTemplate(templateId) {
|
|
6683
|
-
const docRef =
|
|
6811
|
+
const docRef = doc14(this.collectionRef, templateId);
|
|
6684
6812
|
await deleteDoc8(docRef);
|
|
6685
6813
|
}
|
|
6686
6814
|
/**
|
|
@@ -6690,21 +6818,21 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
6690
6818
|
* @returns Array of templates and the last document for pagination
|
|
6691
6819
|
*/
|
|
6692
6820
|
async getActiveTemplates(pageSize = 20, lastDoc) {
|
|
6693
|
-
let q =
|
|
6821
|
+
let q = query12(
|
|
6694
6822
|
this.collectionRef,
|
|
6695
|
-
|
|
6823
|
+
where12("isActive", "==", true),
|
|
6696
6824
|
orderBy2("updatedAt", "desc"),
|
|
6697
|
-
|
|
6825
|
+
limit2(pageSize)
|
|
6698
6826
|
);
|
|
6699
6827
|
if (lastDoc) {
|
|
6700
|
-
q =
|
|
6828
|
+
q = query12(q, startAfter2(lastDoc));
|
|
6701
6829
|
}
|
|
6702
|
-
const querySnapshot = await
|
|
6830
|
+
const querySnapshot = await getDocs12(q);
|
|
6703
6831
|
const templates = [];
|
|
6704
6832
|
let lastVisible = null;
|
|
6705
|
-
querySnapshot.forEach((
|
|
6706
|
-
templates.push(
|
|
6707
|
-
lastVisible =
|
|
6833
|
+
querySnapshot.forEach((doc28) => {
|
|
6834
|
+
templates.push(doc28.data());
|
|
6835
|
+
lastVisible = doc28;
|
|
6708
6836
|
});
|
|
6709
6837
|
return {
|
|
6710
6838
|
templates,
|
|
@@ -6719,22 +6847,22 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
6719
6847
|
* @returns Array of templates and the last document for pagination
|
|
6720
6848
|
*/
|
|
6721
6849
|
async getTemplatesByTags(tags, pageSize = 20, lastDoc) {
|
|
6722
|
-
let q =
|
|
6850
|
+
let q = query12(
|
|
6723
6851
|
this.collectionRef,
|
|
6724
|
-
|
|
6725
|
-
|
|
6852
|
+
where12("isActive", "==", true),
|
|
6853
|
+
where12("tags", "array-contains-any", tags),
|
|
6726
6854
|
orderBy2("updatedAt", "desc"),
|
|
6727
|
-
|
|
6855
|
+
limit2(pageSize)
|
|
6728
6856
|
);
|
|
6729
6857
|
if (lastDoc) {
|
|
6730
|
-
q =
|
|
6858
|
+
q = query12(q, startAfter2(lastDoc));
|
|
6731
6859
|
}
|
|
6732
|
-
const querySnapshot = await
|
|
6860
|
+
const querySnapshot = await getDocs12(q);
|
|
6733
6861
|
const templates = [];
|
|
6734
6862
|
let lastVisible = null;
|
|
6735
|
-
querySnapshot.forEach((
|
|
6736
|
-
templates.push(
|
|
6737
|
-
lastVisible =
|
|
6863
|
+
querySnapshot.forEach((doc28) => {
|
|
6864
|
+
templates.push(doc28.data());
|
|
6865
|
+
lastVisible = doc28;
|
|
6738
6866
|
});
|
|
6739
6867
|
return {
|
|
6740
6868
|
templates,
|
|
@@ -6749,21 +6877,21 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
6749
6877
|
* @returns Array of templates and the last document for pagination
|
|
6750
6878
|
*/
|
|
6751
6879
|
async getTemplatesByCreator(userId, pageSize = 20, lastDoc) {
|
|
6752
|
-
let q =
|
|
6880
|
+
let q = query12(
|
|
6753
6881
|
this.collectionRef,
|
|
6754
|
-
|
|
6882
|
+
where12("createdBy", "==", userId),
|
|
6755
6883
|
orderBy2("updatedAt", "desc"),
|
|
6756
|
-
|
|
6884
|
+
limit2(pageSize)
|
|
6757
6885
|
);
|
|
6758
6886
|
if (lastDoc) {
|
|
6759
|
-
q =
|
|
6887
|
+
q = query12(q, startAfter2(lastDoc));
|
|
6760
6888
|
}
|
|
6761
|
-
const querySnapshot = await
|
|
6889
|
+
const querySnapshot = await getDocs12(q);
|
|
6762
6890
|
const templates = [];
|
|
6763
6891
|
let lastVisible = null;
|
|
6764
|
-
querySnapshot.forEach((
|
|
6765
|
-
templates.push(
|
|
6766
|
-
lastVisible =
|
|
6892
|
+
querySnapshot.forEach((doc28) => {
|
|
6893
|
+
templates.push(doc28.data());
|
|
6894
|
+
lastVisible = doc28;
|
|
6767
6895
|
});
|
|
6768
6896
|
return {
|
|
6769
6897
|
templates,
|
|
@@ -6774,22 +6902,22 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
6774
6902
|
|
|
6775
6903
|
// src/services/documentation-templates/filled-document.service.ts
|
|
6776
6904
|
import {
|
|
6777
|
-
collection as
|
|
6778
|
-
doc as
|
|
6905
|
+
collection as collection14,
|
|
6906
|
+
doc as doc15,
|
|
6779
6907
|
getDoc as getDoc18,
|
|
6780
|
-
getDocs as
|
|
6908
|
+
getDocs as getDocs13,
|
|
6781
6909
|
setDoc as setDoc15,
|
|
6782
6910
|
updateDoc as updateDoc16,
|
|
6783
|
-
query as
|
|
6784
|
-
where as
|
|
6911
|
+
query as query13,
|
|
6912
|
+
where as where13,
|
|
6785
6913
|
orderBy as orderBy3,
|
|
6786
|
-
limit as
|
|
6787
|
-
startAfter as
|
|
6914
|
+
limit as limit3,
|
|
6915
|
+
startAfter as startAfter3
|
|
6788
6916
|
} from "firebase/firestore";
|
|
6789
6917
|
var FilledDocumentService = class extends BaseService {
|
|
6790
6918
|
constructor(...args) {
|
|
6791
6919
|
super(...args);
|
|
6792
|
-
this.collectionRef =
|
|
6920
|
+
this.collectionRef = collection14(
|
|
6793
6921
|
this.db,
|
|
6794
6922
|
FILLED_DOCUMENTS_COLLECTION
|
|
6795
6923
|
);
|
|
@@ -6822,7 +6950,7 @@ var FilledDocumentService = class extends BaseService {
|
|
|
6822
6950
|
values: {},
|
|
6823
6951
|
status: "draft" /* DRAFT */
|
|
6824
6952
|
};
|
|
6825
|
-
const docRef =
|
|
6953
|
+
const docRef = doc15(this.collectionRef, documentId);
|
|
6826
6954
|
await setDoc15(docRef, filledDocument);
|
|
6827
6955
|
return filledDocument;
|
|
6828
6956
|
}
|
|
@@ -6832,7 +6960,7 @@ var FilledDocumentService = class extends BaseService {
|
|
|
6832
6960
|
* @returns The filled document or null if not found
|
|
6833
6961
|
*/
|
|
6834
6962
|
async getFilledDocumentById(documentId) {
|
|
6835
|
-
const docRef =
|
|
6963
|
+
const docRef = doc15(this.collectionRef, documentId);
|
|
6836
6964
|
const docSnap = await getDoc18(docRef);
|
|
6837
6965
|
if (!docSnap.exists()) {
|
|
6838
6966
|
return null;
|
|
@@ -6861,7 +6989,7 @@ var FilledDocumentService = class extends BaseService {
|
|
|
6861
6989
|
if (status) {
|
|
6862
6990
|
updateData.status = status;
|
|
6863
6991
|
}
|
|
6864
|
-
const docRef =
|
|
6992
|
+
const docRef = doc15(this.collectionRef, documentId);
|
|
6865
6993
|
await updateDoc16(docRef, updateData);
|
|
6866
6994
|
return {
|
|
6867
6995
|
...filledDocument,
|
|
@@ -6876,21 +7004,21 @@ var FilledDocumentService = class extends BaseService {
|
|
|
6876
7004
|
* @returns Array of filled documents and the last document for pagination
|
|
6877
7005
|
*/
|
|
6878
7006
|
async getFilledDocumentsByPatient(patientId, pageSize = 20, lastDoc) {
|
|
6879
|
-
let q =
|
|
7007
|
+
let q = query13(
|
|
6880
7008
|
this.collectionRef,
|
|
6881
|
-
|
|
7009
|
+
where13("patientId", "==", patientId),
|
|
6882
7010
|
orderBy3("updatedAt", "desc"),
|
|
6883
|
-
|
|
7011
|
+
limit3(pageSize)
|
|
6884
7012
|
);
|
|
6885
7013
|
if (lastDoc) {
|
|
6886
|
-
q =
|
|
7014
|
+
q = query13(q, startAfter3(lastDoc));
|
|
6887
7015
|
}
|
|
6888
|
-
const querySnapshot = await
|
|
7016
|
+
const querySnapshot = await getDocs13(q);
|
|
6889
7017
|
const documents = [];
|
|
6890
7018
|
let lastVisible = null;
|
|
6891
|
-
querySnapshot.forEach((
|
|
6892
|
-
documents.push(
|
|
6893
|
-
lastVisible =
|
|
7019
|
+
querySnapshot.forEach((doc28) => {
|
|
7020
|
+
documents.push(doc28.data());
|
|
7021
|
+
lastVisible = doc28;
|
|
6894
7022
|
});
|
|
6895
7023
|
return {
|
|
6896
7024
|
documents,
|
|
@@ -6905,21 +7033,21 @@ var FilledDocumentService = class extends BaseService {
|
|
|
6905
7033
|
* @returns Array of filled documents and the last document for pagination
|
|
6906
7034
|
*/
|
|
6907
7035
|
async getFilledDocumentsByPractitioner(practitionerId, pageSize = 20, lastDoc) {
|
|
6908
|
-
let q =
|
|
7036
|
+
let q = query13(
|
|
6909
7037
|
this.collectionRef,
|
|
6910
|
-
|
|
7038
|
+
where13("practitionerId", "==", practitionerId),
|
|
6911
7039
|
orderBy3("updatedAt", "desc"),
|
|
6912
|
-
|
|
7040
|
+
limit3(pageSize)
|
|
6913
7041
|
);
|
|
6914
7042
|
if (lastDoc) {
|
|
6915
|
-
q =
|
|
7043
|
+
q = query13(q, startAfter3(lastDoc));
|
|
6916
7044
|
}
|
|
6917
|
-
const querySnapshot = await
|
|
7045
|
+
const querySnapshot = await getDocs13(q);
|
|
6918
7046
|
const documents = [];
|
|
6919
7047
|
let lastVisible = null;
|
|
6920
|
-
querySnapshot.forEach((
|
|
6921
|
-
documents.push(
|
|
6922
|
-
lastVisible =
|
|
7048
|
+
querySnapshot.forEach((doc28) => {
|
|
7049
|
+
documents.push(doc28.data());
|
|
7050
|
+
lastVisible = doc28;
|
|
6923
7051
|
});
|
|
6924
7052
|
return {
|
|
6925
7053
|
documents,
|
|
@@ -6934,21 +7062,21 @@ var FilledDocumentService = class extends BaseService {
|
|
|
6934
7062
|
* @returns Array of filled documents and the last document for pagination
|
|
6935
7063
|
*/
|
|
6936
7064
|
async getFilledDocumentsByClinic(clinicId, pageSize = 20, lastDoc) {
|
|
6937
|
-
let q =
|
|
7065
|
+
let q = query13(
|
|
6938
7066
|
this.collectionRef,
|
|
6939
|
-
|
|
7067
|
+
where13("clinicId", "==", clinicId),
|
|
6940
7068
|
orderBy3("updatedAt", "desc"),
|
|
6941
|
-
|
|
7069
|
+
limit3(pageSize)
|
|
6942
7070
|
);
|
|
6943
7071
|
if (lastDoc) {
|
|
6944
|
-
q =
|
|
7072
|
+
q = query13(q, startAfter3(lastDoc));
|
|
6945
7073
|
}
|
|
6946
|
-
const querySnapshot = await
|
|
7074
|
+
const querySnapshot = await getDocs13(q);
|
|
6947
7075
|
const documents = [];
|
|
6948
7076
|
let lastVisible = null;
|
|
6949
|
-
querySnapshot.forEach((
|
|
6950
|
-
documents.push(
|
|
6951
|
-
lastVisible =
|
|
7077
|
+
querySnapshot.forEach((doc28) => {
|
|
7078
|
+
documents.push(doc28.data());
|
|
7079
|
+
lastVisible = doc28;
|
|
6952
7080
|
});
|
|
6953
7081
|
return {
|
|
6954
7082
|
documents,
|
|
@@ -6963,21 +7091,21 @@ var FilledDocumentService = class extends BaseService {
|
|
|
6963
7091
|
* @returns Array of filled documents and the last document for pagination
|
|
6964
7092
|
*/
|
|
6965
7093
|
async getFilledDocumentsByTemplate(templateId, pageSize = 20, lastDoc) {
|
|
6966
|
-
let q =
|
|
7094
|
+
let q = query13(
|
|
6967
7095
|
this.collectionRef,
|
|
6968
|
-
|
|
7096
|
+
where13("templateId", "==", templateId),
|
|
6969
7097
|
orderBy3("updatedAt", "desc"),
|
|
6970
|
-
|
|
7098
|
+
limit3(pageSize)
|
|
6971
7099
|
);
|
|
6972
7100
|
if (lastDoc) {
|
|
6973
|
-
q =
|
|
7101
|
+
q = query13(q, startAfter3(lastDoc));
|
|
6974
7102
|
}
|
|
6975
|
-
const querySnapshot = await
|
|
7103
|
+
const querySnapshot = await getDocs13(q);
|
|
6976
7104
|
const documents = [];
|
|
6977
7105
|
let lastVisible = null;
|
|
6978
|
-
querySnapshot.forEach((
|
|
6979
|
-
documents.push(
|
|
6980
|
-
lastVisible =
|
|
7106
|
+
querySnapshot.forEach((doc28) => {
|
|
7107
|
+
documents.push(doc28.data());
|
|
7108
|
+
lastVisible = doc28;
|
|
6981
7109
|
});
|
|
6982
7110
|
return {
|
|
6983
7111
|
documents,
|
|
@@ -6992,21 +7120,21 @@ var FilledDocumentService = class extends BaseService {
|
|
|
6992
7120
|
* @returns Array of filled documents and the last document for pagination
|
|
6993
7121
|
*/
|
|
6994
7122
|
async getFilledDocumentsByStatus(status, pageSize = 20, lastDoc) {
|
|
6995
|
-
let q =
|
|
7123
|
+
let q = query13(
|
|
6996
7124
|
this.collectionRef,
|
|
6997
|
-
|
|
7125
|
+
where13("status", "==", status),
|
|
6998
7126
|
orderBy3("updatedAt", "desc"),
|
|
6999
|
-
|
|
7127
|
+
limit3(pageSize)
|
|
7000
7128
|
);
|
|
7001
7129
|
if (lastDoc) {
|
|
7002
|
-
q =
|
|
7130
|
+
q = query13(q, startAfter3(lastDoc));
|
|
7003
7131
|
}
|
|
7004
|
-
const querySnapshot = await
|
|
7132
|
+
const querySnapshot = await getDocs13(q);
|
|
7005
7133
|
const documents = [];
|
|
7006
7134
|
let lastVisible = null;
|
|
7007
|
-
querySnapshot.forEach((
|
|
7008
|
-
documents.push(
|
|
7009
|
-
lastVisible =
|
|
7135
|
+
querySnapshot.forEach((doc28) => {
|
|
7136
|
+
documents.push(doc28.data());
|
|
7137
|
+
lastVisible = doc28;
|
|
7010
7138
|
});
|
|
7011
7139
|
return {
|
|
7012
7140
|
documents,
|
|
@@ -7016,7 +7144,7 @@ var FilledDocumentService = class extends BaseService {
|
|
|
7016
7144
|
};
|
|
7017
7145
|
|
|
7018
7146
|
// src/services/calendar/calendar-refactored.service.ts
|
|
7019
|
-
import { Timestamp as
|
|
7147
|
+
import { Timestamp as Timestamp25, serverTimestamp as serverTimestamp20 } from "firebase/firestore";
|
|
7020
7148
|
|
|
7021
7149
|
// src/types/calendar/synced-calendar.types.ts
|
|
7022
7150
|
var SyncedCalendarProvider = /* @__PURE__ */ ((SyncedCalendarProvider3) => {
|
|
@@ -7029,14 +7157,14 @@ var SYNCED_CALENDARS_COLLECTION = "syncedCalendars";
|
|
|
7029
7157
|
|
|
7030
7158
|
// src/services/calendar/calendar-refactored.service.ts
|
|
7031
7159
|
import {
|
|
7032
|
-
doc as
|
|
7033
|
-
getDoc as
|
|
7034
|
-
collection as
|
|
7035
|
-
query as
|
|
7036
|
-
where as
|
|
7037
|
-
getDocs as
|
|
7038
|
-
setDoc as
|
|
7039
|
-
updateDoc as
|
|
7160
|
+
doc as doc22,
|
|
7161
|
+
getDoc as getDoc24,
|
|
7162
|
+
collection as collection20,
|
|
7163
|
+
query as query19,
|
|
7164
|
+
where as where19,
|
|
7165
|
+
getDocs as getDocs19,
|
|
7166
|
+
setDoc as setDoc21,
|
|
7167
|
+
updateDoc as updateDoc22
|
|
7040
7168
|
} from "firebase/firestore";
|
|
7041
7169
|
|
|
7042
7170
|
// src/validations/calendar.schema.ts
|
|
@@ -7215,54 +7343,54 @@ var calendarEventSchema = z18.object({
|
|
|
7215
7343
|
|
|
7216
7344
|
// src/services/calendar/utils/clinic.utils.ts
|
|
7217
7345
|
import {
|
|
7218
|
-
collection as
|
|
7219
|
-
doc as
|
|
7346
|
+
collection as collection15,
|
|
7347
|
+
doc as doc17,
|
|
7220
7348
|
getDoc as getDoc19,
|
|
7221
|
-
getDocs as
|
|
7349
|
+
getDocs as getDocs14,
|
|
7222
7350
|
setDoc as setDoc16,
|
|
7223
7351
|
updateDoc as updateDoc17,
|
|
7224
7352
|
deleteDoc as deleteDoc9,
|
|
7225
|
-
query as
|
|
7226
|
-
where as
|
|
7353
|
+
query as query14,
|
|
7354
|
+
where as where14,
|
|
7227
7355
|
orderBy as orderBy4,
|
|
7228
7356
|
Timestamp as Timestamp19,
|
|
7229
7357
|
serverTimestamp as serverTimestamp15
|
|
7230
7358
|
} from "firebase/firestore";
|
|
7231
7359
|
|
|
7232
7360
|
// src/services/calendar/utils/docs.utils.ts
|
|
7233
|
-
import { doc as
|
|
7361
|
+
import { doc as doc16 } from "firebase/firestore";
|
|
7234
7362
|
function getPractitionerCalendarEventDocRef(db, practitionerId, eventId) {
|
|
7235
|
-
return
|
|
7363
|
+
return doc16(
|
|
7236
7364
|
db,
|
|
7237
7365
|
`${PRACTITIONERS_COLLECTION}/${practitionerId}/${CALENDAR_COLLECTION}/${eventId}`
|
|
7238
7366
|
);
|
|
7239
7367
|
}
|
|
7240
7368
|
function getPatientCalendarEventDocRef(db, patientId, eventId) {
|
|
7241
|
-
return
|
|
7369
|
+
return doc16(
|
|
7242
7370
|
db,
|
|
7243
7371
|
`${PATIENTS_COLLECTION}/${patientId}/${CALENDAR_COLLECTION}/${eventId}`
|
|
7244
7372
|
);
|
|
7245
7373
|
}
|
|
7246
7374
|
function getClinicCalendarEventDocRef(db, clinicId, eventId) {
|
|
7247
|
-
return
|
|
7375
|
+
return doc16(
|
|
7248
7376
|
db,
|
|
7249
7377
|
`${CLINICS_COLLECTION}/${clinicId}/${CALENDAR_COLLECTION}/${eventId}`
|
|
7250
7378
|
);
|
|
7251
7379
|
}
|
|
7252
7380
|
function getPractitionerSyncedCalendarDocRef(db, practitionerId, syncedCalendarId) {
|
|
7253
|
-
return
|
|
7381
|
+
return doc16(
|
|
7254
7382
|
db,
|
|
7255
7383
|
`${PRACTITIONERS_COLLECTION}/${practitionerId}/syncedCalendars/${syncedCalendarId}`
|
|
7256
7384
|
);
|
|
7257
7385
|
}
|
|
7258
7386
|
function getPatientSyncedCalendarDocRef(db, patientId, syncedCalendarId) {
|
|
7259
|
-
return
|
|
7387
|
+
return doc16(
|
|
7260
7388
|
db,
|
|
7261
7389
|
`${PATIENTS_COLLECTION}/${patientId}/syncedCalendars/${syncedCalendarId}`
|
|
7262
7390
|
);
|
|
7263
7391
|
}
|
|
7264
7392
|
function getClinicSyncedCalendarDocRef(db, clinicId, syncedCalendarId) {
|
|
7265
|
-
return
|
|
7393
|
+
return doc16(
|
|
7266
7394
|
db,
|
|
7267
7395
|
`${CLINICS_COLLECTION}/${clinicId}/syncedCalendars/${syncedCalendarId}`
|
|
7268
7396
|
);
|
|
@@ -7299,7 +7427,7 @@ async function updateClinicCalendarEventUtil(db, clinicId, eventId, updateData)
|
|
|
7299
7427
|
return updatedDoc.data();
|
|
7300
7428
|
}
|
|
7301
7429
|
async function checkAutoConfirmAppointmentsUtil(db, clinicId) {
|
|
7302
|
-
const clinicDoc = await getDoc19(
|
|
7430
|
+
const clinicDoc = await getDoc19(doc17(db, `clinics/${clinicId}`));
|
|
7303
7431
|
if (!clinicDoc.exists()) {
|
|
7304
7432
|
throw new Error(`Clinic with ID ${clinicId} not found`);
|
|
7305
7433
|
}
|
|
@@ -7309,7 +7437,7 @@ async function checkAutoConfirmAppointmentsUtil(db, clinicId) {
|
|
|
7309
7437
|
return false;
|
|
7310
7438
|
}
|
|
7311
7439
|
const clinicGroupDoc = await getDoc19(
|
|
7312
|
-
|
|
7440
|
+
doc17(db, `${CLINIC_GROUPS_COLLECTION}/${clinicGroupId}`)
|
|
7313
7441
|
);
|
|
7314
7442
|
if (!clinicGroupDoc.exists()) {
|
|
7315
7443
|
return false;
|
|
@@ -7320,14 +7448,14 @@ async function checkAutoConfirmAppointmentsUtil(db, clinicId) {
|
|
|
7320
7448
|
|
|
7321
7449
|
// src/services/calendar/utils/patient.utils.ts
|
|
7322
7450
|
import {
|
|
7323
|
-
collection as
|
|
7451
|
+
collection as collection16,
|
|
7324
7452
|
getDoc as getDoc20,
|
|
7325
|
-
getDocs as
|
|
7453
|
+
getDocs as getDocs15,
|
|
7326
7454
|
setDoc as setDoc17,
|
|
7327
7455
|
updateDoc as updateDoc18,
|
|
7328
7456
|
deleteDoc as deleteDoc10,
|
|
7329
|
-
query as
|
|
7330
|
-
where as
|
|
7457
|
+
query as query15,
|
|
7458
|
+
where as where15,
|
|
7331
7459
|
orderBy as orderBy5,
|
|
7332
7460
|
Timestamp as Timestamp20,
|
|
7333
7461
|
serverTimestamp as serverTimestamp16
|
|
@@ -7364,14 +7492,14 @@ async function updatePatientCalendarEventUtil(db, patientId, eventId, updateData
|
|
|
7364
7492
|
|
|
7365
7493
|
// src/services/calendar/utils/practitioner.utils.ts
|
|
7366
7494
|
import {
|
|
7367
|
-
collection as
|
|
7495
|
+
collection as collection17,
|
|
7368
7496
|
getDoc as getDoc21,
|
|
7369
|
-
getDocs as
|
|
7497
|
+
getDocs as getDocs16,
|
|
7370
7498
|
setDoc as setDoc18,
|
|
7371
7499
|
updateDoc as updateDoc19,
|
|
7372
7500
|
deleteDoc as deleteDoc11,
|
|
7373
|
-
query as
|
|
7374
|
-
where as
|
|
7501
|
+
query as query16,
|
|
7502
|
+
where as where16,
|
|
7375
7503
|
orderBy as orderBy6,
|
|
7376
7504
|
Timestamp as Timestamp21,
|
|
7377
7505
|
serverTimestamp as serverTimestamp17
|
|
@@ -7482,19 +7610,126 @@ async function updateAppointmentUtil(db, clinicId, practitionerId, patientId, ev
|
|
|
7482
7610
|
return clinicEvent;
|
|
7483
7611
|
}
|
|
7484
7612
|
|
|
7485
|
-
// src/services/calendar/utils/
|
|
7613
|
+
// src/services/calendar/utils/calendar-event.utils.ts
|
|
7486
7614
|
import {
|
|
7487
|
-
collection as
|
|
7615
|
+
collection as collection18,
|
|
7616
|
+
doc as doc20,
|
|
7488
7617
|
getDoc as getDoc22,
|
|
7489
|
-
getDocs as
|
|
7618
|
+
getDocs as getDocs17,
|
|
7490
7619
|
setDoc as setDoc19,
|
|
7491
7620
|
updateDoc as updateDoc20,
|
|
7492
7621
|
deleteDoc as deleteDoc12,
|
|
7493
|
-
query as
|
|
7622
|
+
query as query17,
|
|
7623
|
+
where as where17,
|
|
7494
7624
|
orderBy as orderBy7,
|
|
7495
7625
|
Timestamp as Timestamp22,
|
|
7496
7626
|
serverTimestamp as serverTimestamp18
|
|
7497
7627
|
} from "firebase/firestore";
|
|
7628
|
+
async function searchCalendarEventsUtil(db, params) {
|
|
7629
|
+
const { searchLocation, entityId, ...filters } = params;
|
|
7630
|
+
let baseCollectionPath;
|
|
7631
|
+
const constraints = [];
|
|
7632
|
+
switch (searchLocation) {
|
|
7633
|
+
case "practitioner" /* PRACTITIONER */:
|
|
7634
|
+
if (!entityId) {
|
|
7635
|
+
throw new Error(
|
|
7636
|
+
"Practitioner ID (entityId) is required when searching practitioner calendar."
|
|
7637
|
+
);
|
|
7638
|
+
}
|
|
7639
|
+
baseCollectionPath = `${PRACTITIONERS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}`;
|
|
7640
|
+
if (filters.practitionerId && filters.practitionerId !== entityId) {
|
|
7641
|
+
console.warn(
|
|
7642
|
+
`Provided practitionerId filter (${filters.practitionerId}) does not match search entityId (${entityId}). Returning empty results.`
|
|
7643
|
+
);
|
|
7644
|
+
return [];
|
|
7645
|
+
}
|
|
7646
|
+
filters.practitionerId = void 0;
|
|
7647
|
+
break;
|
|
7648
|
+
case "patient" /* PATIENT */:
|
|
7649
|
+
if (!entityId) {
|
|
7650
|
+
throw new Error(
|
|
7651
|
+
"Patient ID (entityId) is required when searching patient calendar."
|
|
7652
|
+
);
|
|
7653
|
+
}
|
|
7654
|
+
baseCollectionPath = `${PATIENTS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}`;
|
|
7655
|
+
if (filters.patientId && filters.patientId !== entityId) {
|
|
7656
|
+
console.warn(
|
|
7657
|
+
`Provided patientId filter (${filters.patientId}) does not match search entityId (${entityId}). Returning empty results.`
|
|
7658
|
+
);
|
|
7659
|
+
return [];
|
|
7660
|
+
}
|
|
7661
|
+
filters.patientId = void 0;
|
|
7662
|
+
break;
|
|
7663
|
+
case "clinic" /* CLINIC */:
|
|
7664
|
+
if (!entityId) {
|
|
7665
|
+
throw new Error(
|
|
7666
|
+
"Clinic ID (entityId) is required when searching clinic-related events."
|
|
7667
|
+
);
|
|
7668
|
+
}
|
|
7669
|
+
baseCollectionPath = CALENDAR_COLLECTION;
|
|
7670
|
+
constraints.push(where17("clinicBranchId", "==", entityId));
|
|
7671
|
+
if (filters.clinicId && filters.clinicId !== entityId) {
|
|
7672
|
+
console.warn(
|
|
7673
|
+
`Provided clinicId filter (${filters.clinicId}) does not match search entityId (${entityId}). Returning empty results.`
|
|
7674
|
+
);
|
|
7675
|
+
return [];
|
|
7676
|
+
}
|
|
7677
|
+
filters.clinicId = void 0;
|
|
7678
|
+
break;
|
|
7679
|
+
default:
|
|
7680
|
+
throw new Error(`Invalid search location: ${searchLocation}`);
|
|
7681
|
+
}
|
|
7682
|
+
const collectionRef = collection18(db, baseCollectionPath);
|
|
7683
|
+
if (filters.clinicId) {
|
|
7684
|
+
constraints.push(where17("clinicBranchId", "==", filters.clinicId));
|
|
7685
|
+
}
|
|
7686
|
+
if (filters.practitionerId) {
|
|
7687
|
+
constraints.push(
|
|
7688
|
+
where17("practitionerProfileId", "==", filters.practitionerId)
|
|
7689
|
+
);
|
|
7690
|
+
}
|
|
7691
|
+
if (filters.patientId) {
|
|
7692
|
+
constraints.push(where17("patientProfileId", "==", filters.patientId));
|
|
7693
|
+
}
|
|
7694
|
+
if (filters.procedureId) {
|
|
7695
|
+
constraints.push(where17("procedureId", "==", filters.procedureId));
|
|
7696
|
+
}
|
|
7697
|
+
if (filters.eventStatus) {
|
|
7698
|
+
constraints.push(where17("status", "==", filters.eventStatus));
|
|
7699
|
+
}
|
|
7700
|
+
if (filters.eventType) {
|
|
7701
|
+
constraints.push(where17("eventType", "==", filters.eventType));
|
|
7702
|
+
}
|
|
7703
|
+
if (filters.dateRange) {
|
|
7704
|
+
constraints.push(where17("eventTime.start", ">=", filters.dateRange.start));
|
|
7705
|
+
constraints.push(where17("eventTime.start", "<=", filters.dateRange.end));
|
|
7706
|
+
}
|
|
7707
|
+
try {
|
|
7708
|
+
const finalQuery = query17(collectionRef, ...constraints);
|
|
7709
|
+
const querySnapshot = await getDocs17(finalQuery);
|
|
7710
|
+
const events = querySnapshot.docs.map(
|
|
7711
|
+
(doc28) => ({ id: doc28.id, ...doc28.data() })
|
|
7712
|
+
);
|
|
7713
|
+
return events;
|
|
7714
|
+
} catch (error) {
|
|
7715
|
+
console.error("Error searching calendar events:", error);
|
|
7716
|
+
return [];
|
|
7717
|
+
}
|
|
7718
|
+
}
|
|
7719
|
+
|
|
7720
|
+
// src/services/calendar/utils/synced-calendar.utils.ts
|
|
7721
|
+
import {
|
|
7722
|
+
collection as collection19,
|
|
7723
|
+
getDoc as getDoc23,
|
|
7724
|
+
getDocs as getDocs18,
|
|
7725
|
+
setDoc as setDoc20,
|
|
7726
|
+
updateDoc as updateDoc21,
|
|
7727
|
+
deleteDoc as deleteDoc13,
|
|
7728
|
+
query as query18,
|
|
7729
|
+
orderBy as orderBy8,
|
|
7730
|
+
Timestamp as Timestamp23,
|
|
7731
|
+
serverTimestamp as serverTimestamp19
|
|
7732
|
+
} from "firebase/firestore";
|
|
7498
7733
|
async function createPractitionerSyncedCalendarUtil(db, practitionerId, calendarData, generateId2) {
|
|
7499
7734
|
const calendarId = generateId2();
|
|
7500
7735
|
const calendarRef = getPractitionerSyncedCalendarDocRef(
|
|
@@ -7505,14 +7740,14 @@ async function createPractitionerSyncedCalendarUtil(db, practitionerId, calendar
|
|
|
7505
7740
|
const newCalendar = {
|
|
7506
7741
|
id: calendarId,
|
|
7507
7742
|
...calendarData,
|
|
7508
|
-
createdAt:
|
|
7509
|
-
updatedAt:
|
|
7743
|
+
createdAt: serverTimestamp19(),
|
|
7744
|
+
updatedAt: serverTimestamp19()
|
|
7510
7745
|
};
|
|
7511
|
-
await
|
|
7746
|
+
await setDoc20(calendarRef, newCalendar);
|
|
7512
7747
|
return {
|
|
7513
7748
|
...newCalendar,
|
|
7514
|
-
createdAt:
|
|
7515
|
-
updatedAt:
|
|
7749
|
+
createdAt: Timestamp23.now(),
|
|
7750
|
+
updatedAt: Timestamp23.now()
|
|
7516
7751
|
};
|
|
7517
7752
|
}
|
|
7518
7753
|
async function createPatientSyncedCalendarUtil(db, patientId, calendarData, generateId2) {
|
|
@@ -7521,14 +7756,14 @@ async function createPatientSyncedCalendarUtil(db, patientId, calendarData, gene
|
|
|
7521
7756
|
const newCalendar = {
|
|
7522
7757
|
id: calendarId,
|
|
7523
7758
|
...calendarData,
|
|
7524
|
-
createdAt:
|
|
7525
|
-
updatedAt:
|
|
7759
|
+
createdAt: serverTimestamp19(),
|
|
7760
|
+
updatedAt: serverTimestamp19()
|
|
7526
7761
|
};
|
|
7527
|
-
await
|
|
7762
|
+
await setDoc20(calendarRef, newCalendar);
|
|
7528
7763
|
return {
|
|
7529
7764
|
...newCalendar,
|
|
7530
|
-
createdAt:
|
|
7531
|
-
updatedAt:
|
|
7765
|
+
createdAt: Timestamp23.now(),
|
|
7766
|
+
updatedAt: Timestamp23.now()
|
|
7532
7767
|
};
|
|
7533
7768
|
}
|
|
7534
7769
|
async function createClinicSyncedCalendarUtil(db, clinicId, calendarData, generateId2) {
|
|
@@ -7537,14 +7772,14 @@ async function createClinicSyncedCalendarUtil(db, clinicId, calendarData, genera
|
|
|
7537
7772
|
const newCalendar = {
|
|
7538
7773
|
id: calendarId,
|
|
7539
7774
|
...calendarData,
|
|
7540
|
-
createdAt:
|
|
7541
|
-
updatedAt:
|
|
7775
|
+
createdAt: serverTimestamp19(),
|
|
7776
|
+
updatedAt: serverTimestamp19()
|
|
7542
7777
|
};
|
|
7543
|
-
await
|
|
7778
|
+
await setDoc20(calendarRef, newCalendar);
|
|
7544
7779
|
return {
|
|
7545
7780
|
...newCalendar,
|
|
7546
|
-
createdAt:
|
|
7547
|
-
updatedAt:
|
|
7781
|
+
createdAt: Timestamp23.now(),
|
|
7782
|
+
updatedAt: Timestamp23.now()
|
|
7548
7783
|
};
|
|
7549
7784
|
}
|
|
7550
7785
|
async function getPractitionerSyncedCalendarUtil(db, practitionerId, calendarId) {
|
|
@@ -7553,54 +7788,54 @@ async function getPractitionerSyncedCalendarUtil(db, practitionerId, calendarId)
|
|
|
7553
7788
|
practitionerId,
|
|
7554
7789
|
calendarId
|
|
7555
7790
|
);
|
|
7556
|
-
const calendarDoc = await
|
|
7791
|
+
const calendarDoc = await getDoc23(calendarRef);
|
|
7557
7792
|
if (!calendarDoc.exists()) {
|
|
7558
7793
|
return null;
|
|
7559
7794
|
}
|
|
7560
7795
|
return calendarDoc.data();
|
|
7561
7796
|
}
|
|
7562
7797
|
async function getPractitionerSyncedCalendarsUtil(db, practitionerId) {
|
|
7563
|
-
const calendarsRef =
|
|
7798
|
+
const calendarsRef = collection19(
|
|
7564
7799
|
db,
|
|
7565
7800
|
`practitioners/${practitionerId}/${SYNCED_CALENDARS_COLLECTION}`
|
|
7566
7801
|
);
|
|
7567
|
-
const q =
|
|
7568
|
-
const querySnapshot = await
|
|
7569
|
-
return querySnapshot.docs.map((
|
|
7802
|
+
const q = query18(calendarsRef, orderBy8("createdAt", "desc"));
|
|
7803
|
+
const querySnapshot = await getDocs18(q);
|
|
7804
|
+
return querySnapshot.docs.map((doc28) => doc28.data());
|
|
7570
7805
|
}
|
|
7571
7806
|
async function getPatientSyncedCalendarUtil(db, patientId, calendarId) {
|
|
7572
7807
|
const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
|
|
7573
|
-
const calendarDoc = await
|
|
7808
|
+
const calendarDoc = await getDoc23(calendarRef);
|
|
7574
7809
|
if (!calendarDoc.exists()) {
|
|
7575
7810
|
return null;
|
|
7576
7811
|
}
|
|
7577
7812
|
return calendarDoc.data();
|
|
7578
7813
|
}
|
|
7579
7814
|
async function getPatientSyncedCalendarsUtil(db, patientId) {
|
|
7580
|
-
const calendarsRef =
|
|
7815
|
+
const calendarsRef = collection19(
|
|
7581
7816
|
db,
|
|
7582
7817
|
`patients/${patientId}/${SYNCED_CALENDARS_COLLECTION}`
|
|
7583
7818
|
);
|
|
7584
|
-
const q =
|
|
7585
|
-
const querySnapshot = await
|
|
7586
|
-
return querySnapshot.docs.map((
|
|
7819
|
+
const q = query18(calendarsRef, orderBy8("createdAt", "desc"));
|
|
7820
|
+
const querySnapshot = await getDocs18(q);
|
|
7821
|
+
return querySnapshot.docs.map((doc28) => doc28.data());
|
|
7587
7822
|
}
|
|
7588
7823
|
async function getClinicSyncedCalendarUtil(db, clinicId, calendarId) {
|
|
7589
7824
|
const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
|
|
7590
|
-
const calendarDoc = await
|
|
7825
|
+
const calendarDoc = await getDoc23(calendarRef);
|
|
7591
7826
|
if (!calendarDoc.exists()) {
|
|
7592
7827
|
return null;
|
|
7593
7828
|
}
|
|
7594
7829
|
return calendarDoc.data();
|
|
7595
7830
|
}
|
|
7596
7831
|
async function getClinicSyncedCalendarsUtil(db, clinicId) {
|
|
7597
|
-
const calendarsRef =
|
|
7832
|
+
const calendarsRef = collection19(
|
|
7598
7833
|
db,
|
|
7599
7834
|
`clinics/${clinicId}/${SYNCED_CALENDARS_COLLECTION}`
|
|
7600
7835
|
);
|
|
7601
|
-
const q =
|
|
7602
|
-
const querySnapshot = await
|
|
7603
|
-
return querySnapshot.docs.map((
|
|
7836
|
+
const q = query18(calendarsRef, orderBy8("createdAt", "desc"));
|
|
7837
|
+
const querySnapshot = await getDocs18(q);
|
|
7838
|
+
return querySnapshot.docs.map((doc28) => doc28.data());
|
|
7604
7839
|
}
|
|
7605
7840
|
async function updatePractitionerSyncedCalendarUtil(db, practitionerId, calendarId, updateData) {
|
|
7606
7841
|
const calendarRef = getPractitionerSyncedCalendarDocRef(
|
|
@@ -7610,10 +7845,10 @@ async function updatePractitionerSyncedCalendarUtil(db, practitionerId, calendar
|
|
|
7610
7845
|
);
|
|
7611
7846
|
const updates = {
|
|
7612
7847
|
...updateData,
|
|
7613
|
-
updatedAt:
|
|
7848
|
+
updatedAt: serverTimestamp19()
|
|
7614
7849
|
};
|
|
7615
|
-
await
|
|
7616
|
-
const updatedDoc = await
|
|
7850
|
+
await updateDoc21(calendarRef, updates);
|
|
7851
|
+
const updatedDoc = await getDoc23(calendarRef);
|
|
7617
7852
|
if (!updatedDoc.exists()) {
|
|
7618
7853
|
throw new Error("Synced calendar not found after update");
|
|
7619
7854
|
}
|
|
@@ -7623,10 +7858,10 @@ async function updatePatientSyncedCalendarUtil(db, patientId, calendarId, update
|
|
|
7623
7858
|
const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
|
|
7624
7859
|
const updates = {
|
|
7625
7860
|
...updateData,
|
|
7626
|
-
updatedAt:
|
|
7861
|
+
updatedAt: serverTimestamp19()
|
|
7627
7862
|
};
|
|
7628
|
-
await
|
|
7629
|
-
const updatedDoc = await
|
|
7863
|
+
await updateDoc21(calendarRef, updates);
|
|
7864
|
+
const updatedDoc = await getDoc23(calendarRef);
|
|
7630
7865
|
if (!updatedDoc.exists()) {
|
|
7631
7866
|
throw new Error("Synced calendar not found after update");
|
|
7632
7867
|
}
|
|
@@ -7636,10 +7871,10 @@ async function updateClinicSyncedCalendarUtil(db, clinicId, calendarId, updateDa
|
|
|
7636
7871
|
const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
|
|
7637
7872
|
const updates = {
|
|
7638
7873
|
...updateData,
|
|
7639
|
-
updatedAt:
|
|
7874
|
+
updatedAt: serverTimestamp19()
|
|
7640
7875
|
};
|
|
7641
|
-
await
|
|
7642
|
-
const updatedDoc = await
|
|
7876
|
+
await updateDoc21(calendarRef, updates);
|
|
7877
|
+
const updatedDoc = await getDoc23(calendarRef);
|
|
7643
7878
|
if (!updatedDoc.exists()) {
|
|
7644
7879
|
throw new Error("Synced calendar not found after update");
|
|
7645
7880
|
}
|
|
@@ -7651,19 +7886,19 @@ async function deletePractitionerSyncedCalendarUtil(db, practitionerId, calendar
|
|
|
7651
7886
|
practitionerId,
|
|
7652
7887
|
calendarId
|
|
7653
7888
|
);
|
|
7654
|
-
await
|
|
7889
|
+
await deleteDoc13(calendarRef);
|
|
7655
7890
|
}
|
|
7656
7891
|
async function deletePatientSyncedCalendarUtil(db, patientId, calendarId) {
|
|
7657
7892
|
const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
|
|
7658
|
-
await
|
|
7893
|
+
await deleteDoc13(calendarRef);
|
|
7659
7894
|
}
|
|
7660
7895
|
async function deleteClinicSyncedCalendarUtil(db, clinicId, calendarId) {
|
|
7661
7896
|
const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
|
|
7662
|
-
await
|
|
7897
|
+
await deleteDoc13(calendarRef);
|
|
7663
7898
|
}
|
|
7664
7899
|
async function updateLastSyncedTimestampUtil(db, entityType, entityId, calendarId) {
|
|
7665
7900
|
const updateData = {
|
|
7666
|
-
lastSyncedAt:
|
|
7901
|
+
lastSyncedAt: Timestamp23.now()
|
|
7667
7902
|
};
|
|
7668
7903
|
switch (entityType) {
|
|
7669
7904
|
case "practitioner":
|
|
@@ -7693,7 +7928,7 @@ async function updateLastSyncedTimestampUtil(db, entityType, entityId, calendarI
|
|
|
7693
7928
|
}
|
|
7694
7929
|
|
|
7695
7930
|
// src/services/calendar/utils/google-calendar.utils.ts
|
|
7696
|
-
import { Timestamp as
|
|
7931
|
+
import { Timestamp as Timestamp24 } from "firebase/firestore";
|
|
7697
7932
|
var GOOGLE_CALENDAR_API_URL = "https://www.googleapis.com/calendar/v3";
|
|
7698
7933
|
var GOOGLE_OAUTH_URL = "https://oauth2.googleapis.com/token";
|
|
7699
7934
|
var CLIENT_ID = "your-client-id";
|
|
@@ -7813,7 +8048,7 @@ async function ensureValidToken(db, entityType, entityId, syncedCalendar) {
|
|
|
7813
8048
|
tokenExpiry.setSeconds(tokenExpiry.getSeconds() + expiresIn);
|
|
7814
8049
|
const updateData = {
|
|
7815
8050
|
accessToken,
|
|
7816
|
-
tokenExpiry:
|
|
8051
|
+
tokenExpiry: Timestamp24.fromDate(tokenExpiry)
|
|
7817
8052
|
};
|
|
7818
8053
|
switch (entityType) {
|
|
7819
8054
|
case "practitioner":
|
|
@@ -7988,8 +8223,8 @@ function convertGoogleEventToCalendarEventUtil(googleEvent, entityId, entityType
|
|
|
7988
8223
|
eventName: googleEvent.summary || "External Event",
|
|
7989
8224
|
eventLocation: googleEvent.location,
|
|
7990
8225
|
eventTime: {
|
|
7991
|
-
start:
|
|
7992
|
-
end:
|
|
8226
|
+
start: Timestamp24.fromDate(start),
|
|
8227
|
+
end: Timestamp24.fromDate(end)
|
|
7993
8228
|
},
|
|
7994
8229
|
description: googleEvent.description || "",
|
|
7995
8230
|
// External events are always set as CONFIRMED - status updates will happen externally
|
|
@@ -8003,7 +8238,7 @@ function convertGoogleEventToCalendarEventUtil(googleEvent, entityId, entityType
|
|
|
8003
8238
|
{
|
|
8004
8239
|
eventId: googleEvent.id,
|
|
8005
8240
|
syncedCalendarProvider: "google" /* GOOGLE */,
|
|
8006
|
-
syncedAt:
|
|
8241
|
+
syncedAt: Timestamp24.now()
|
|
8007
8242
|
}
|
|
8008
8243
|
]
|
|
8009
8244
|
};
|
|
@@ -8781,7 +9016,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
8781
9016
|
return 0;
|
|
8782
9017
|
}
|
|
8783
9018
|
let importedEventsCount = 0;
|
|
8784
|
-
const currentTime =
|
|
9019
|
+
const currentTime = Timestamp25.now();
|
|
8785
9020
|
for (const calendar of activeCalendars) {
|
|
8786
9021
|
try {
|
|
8787
9022
|
let externalEvents = [];
|
|
@@ -8848,7 +9083,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
8848
9083
|
async createDoctorBlockingEvent(doctorId, eventData) {
|
|
8849
9084
|
try {
|
|
8850
9085
|
const eventId = this.generateId();
|
|
8851
|
-
const eventRef =
|
|
9086
|
+
const eventRef = doc22(
|
|
8852
9087
|
this.db,
|
|
8853
9088
|
PRACTITIONERS_COLLECTION,
|
|
8854
9089
|
doctorId,
|
|
@@ -8858,14 +9093,14 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
8858
9093
|
const newEvent = {
|
|
8859
9094
|
id: eventId,
|
|
8860
9095
|
...eventData,
|
|
8861
|
-
createdAt:
|
|
8862
|
-
updatedAt:
|
|
9096
|
+
createdAt: serverTimestamp20(),
|
|
9097
|
+
updatedAt: serverTimestamp20()
|
|
8863
9098
|
};
|
|
8864
|
-
await
|
|
9099
|
+
await setDoc21(eventRef, newEvent);
|
|
8865
9100
|
return {
|
|
8866
9101
|
...newEvent,
|
|
8867
|
-
createdAt:
|
|
8868
|
-
updatedAt:
|
|
9102
|
+
createdAt: Timestamp25.now(),
|
|
9103
|
+
updatedAt: Timestamp25.now()
|
|
8869
9104
|
};
|
|
8870
9105
|
} catch (error) {
|
|
8871
9106
|
console.error(
|
|
@@ -8883,8 +9118,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
8883
9118
|
*/
|
|
8884
9119
|
async synchronizeExternalCalendars(lookbackDays = 7, lookforwardDays = 30) {
|
|
8885
9120
|
try {
|
|
8886
|
-
const practitionersRef =
|
|
8887
|
-
const practitionersSnapshot = await
|
|
9121
|
+
const practitionersRef = collection20(this.db, PRACTITIONERS_COLLECTION);
|
|
9122
|
+
const practitionersSnapshot = await getDocs19(practitionersRef);
|
|
8888
9123
|
const startDate = /* @__PURE__ */ new Date();
|
|
8889
9124
|
startDate.setDate(startDate.getDate() - lookbackDays);
|
|
8890
9125
|
const endDate = /* @__PURE__ */ new Date();
|
|
@@ -8942,22 +9177,22 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
8942
9177
|
async updateExistingEventsFromExternalCalendars(doctorId, startDate, endDate) {
|
|
8943
9178
|
var _a;
|
|
8944
9179
|
try {
|
|
8945
|
-
const eventsRef =
|
|
9180
|
+
const eventsRef = collection20(
|
|
8946
9181
|
this.db,
|
|
8947
9182
|
PRACTITIONERS_COLLECTION,
|
|
8948
9183
|
doctorId,
|
|
8949
9184
|
CALENDAR_COLLECTION
|
|
8950
9185
|
);
|
|
8951
|
-
const q =
|
|
9186
|
+
const q = query19(
|
|
8952
9187
|
eventsRef,
|
|
8953
|
-
|
|
8954
|
-
|
|
8955
|
-
|
|
9188
|
+
where19("syncStatus", "==", "external" /* EXTERNAL */),
|
|
9189
|
+
where19("eventTime.start", ">=", Timestamp25.fromDate(startDate)),
|
|
9190
|
+
where19("eventTime.start", "<=", Timestamp25.fromDate(endDate))
|
|
8956
9191
|
);
|
|
8957
|
-
const eventsSnapshot = await
|
|
8958
|
-
const events = eventsSnapshot.docs.map((
|
|
8959
|
-
id:
|
|
8960
|
-
...
|
|
9192
|
+
const eventsSnapshot = await getDocs19(q);
|
|
9193
|
+
const events = eventsSnapshot.docs.map((doc28) => ({
|
|
9194
|
+
id: doc28.id,
|
|
9195
|
+
...doc28.data()
|
|
8961
9196
|
}));
|
|
8962
9197
|
const calendars = await this.syncedCalendarsService.getPractitionerSyncedCalendars(
|
|
8963
9198
|
doctorId
|
|
@@ -9061,21 +9296,21 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9061
9296
|
const endTime = new Date(
|
|
9062
9297
|
externalEvent.end.dateTime || externalEvent.end.date
|
|
9063
9298
|
);
|
|
9064
|
-
const eventRef =
|
|
9299
|
+
const eventRef = doc22(
|
|
9065
9300
|
this.db,
|
|
9066
9301
|
PRACTITIONERS_COLLECTION,
|
|
9067
9302
|
doctorId,
|
|
9068
9303
|
CALENDAR_COLLECTION,
|
|
9069
9304
|
eventId
|
|
9070
9305
|
);
|
|
9071
|
-
await
|
|
9306
|
+
await updateDoc22(eventRef, {
|
|
9072
9307
|
eventName: externalEvent.summary || "External Event",
|
|
9073
9308
|
eventTime: {
|
|
9074
|
-
start:
|
|
9075
|
-
end:
|
|
9309
|
+
start: Timestamp25.fromDate(startTime),
|
|
9310
|
+
end: Timestamp25.fromDate(endTime)
|
|
9076
9311
|
},
|
|
9077
9312
|
description: externalEvent.description || "",
|
|
9078
|
-
updatedAt:
|
|
9313
|
+
updatedAt: serverTimestamp20()
|
|
9079
9314
|
});
|
|
9080
9315
|
console.log(`Updated local event ${eventId} from external event`);
|
|
9081
9316
|
} catch (error) {
|
|
@@ -9093,16 +9328,16 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9093
9328
|
*/
|
|
9094
9329
|
async updateEventStatus(doctorId, eventId, status) {
|
|
9095
9330
|
try {
|
|
9096
|
-
const eventRef =
|
|
9331
|
+
const eventRef = doc22(
|
|
9097
9332
|
this.db,
|
|
9098
9333
|
PRACTITIONERS_COLLECTION,
|
|
9099
9334
|
doctorId,
|
|
9100
9335
|
CALENDAR_COLLECTION,
|
|
9101
9336
|
eventId
|
|
9102
9337
|
);
|
|
9103
|
-
await
|
|
9338
|
+
await updateDoc22(eventRef, {
|
|
9104
9339
|
status,
|
|
9105
|
-
updatedAt:
|
|
9340
|
+
updatedAt: serverTimestamp20()
|
|
9106
9341
|
});
|
|
9107
9342
|
console.log(`Updated event ${eventId} status to ${status}`);
|
|
9108
9343
|
} catch (error) {
|
|
@@ -9120,6 +9355,102 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9120
9355
|
`Setting up scheduled calendar sync job every ${interval} hours`
|
|
9121
9356
|
);
|
|
9122
9357
|
}
|
|
9358
|
+
/**
|
|
9359
|
+
* Searches for calendar events based on specified criteria.
|
|
9360
|
+
*
|
|
9361
|
+
* @param {SearchCalendarEventsParams} params - The search parameters.
|
|
9362
|
+
* @param {SearchLocationEnum} params.searchLocation - The primary location to search (practitioner, patient, or clinic).
|
|
9363
|
+
* @param {string} params.entityId - The ID of the entity (practitioner, patient, or clinic) to search within/for.
|
|
9364
|
+
* @param {string} [params.clinicId] - Optional clinic ID to filter by.
|
|
9365
|
+
* @param {string} [params.practitionerId] - Optional practitioner ID to filter by.
|
|
9366
|
+
* @param {string} [params.patientId] - Optional patient ID to filter by.
|
|
9367
|
+
* @param {string} [params.procedureId] - Optional procedure ID to filter by.
|
|
9368
|
+
* @param {DateRange} [params.dateRange] - Optional date range to filter by (event start time).
|
|
9369
|
+
* @param {CalendarEventStatus} [params.eventStatus] - Optional event status to filter by.
|
|
9370
|
+
* @param {CalendarEventType} [params.eventType] - Optional event type to filter by.
|
|
9371
|
+
* @returns {Promise<CalendarEvent[]>} A promise that resolves to an array of matching calendar events.
|
|
9372
|
+
* @throws {Error} If the search location requires an entity ID that is not provided.
|
|
9373
|
+
*/
|
|
9374
|
+
async searchCalendarEvents(params) {
|
|
9375
|
+
return searchCalendarEventsUtil(this.db, params);
|
|
9376
|
+
}
|
|
9377
|
+
/**
|
|
9378
|
+
* Gets a doctor's upcoming appointments for a specific date range
|
|
9379
|
+
*
|
|
9380
|
+
* @param {string} doctorId - ID of the practitioner
|
|
9381
|
+
* @param {Date} startDate - Start date of the range
|
|
9382
|
+
* @param {Date} endDate - End date of the range
|
|
9383
|
+
* @param {CalendarEventStatus} [status] - Optional status filter (defaults to CONFIRMED)
|
|
9384
|
+
* @returns {Promise<CalendarEvent[]>} A promise that resolves to an array of appointments
|
|
9385
|
+
*/
|
|
9386
|
+
async getPractitionerUpcomingAppointments(doctorId, startDate, endDate, status = "confirmed" /* CONFIRMED */) {
|
|
9387
|
+
const dateRange = {
|
|
9388
|
+
start: Timestamp25.fromDate(startDate),
|
|
9389
|
+
end: Timestamp25.fromDate(endDate)
|
|
9390
|
+
};
|
|
9391
|
+
const searchParams = {
|
|
9392
|
+
searchLocation: "practitioner" /* PRACTITIONER */,
|
|
9393
|
+
entityId: doctorId,
|
|
9394
|
+
dateRange,
|
|
9395
|
+
eventStatus: status,
|
|
9396
|
+
eventType: "appointment" /* APPOINTMENT */
|
|
9397
|
+
};
|
|
9398
|
+
return this.searchCalendarEvents(searchParams);
|
|
9399
|
+
}
|
|
9400
|
+
/**
|
|
9401
|
+
* Gets a patient's appointments for a specific date range
|
|
9402
|
+
*
|
|
9403
|
+
* @param {string} patientId - ID of the patient
|
|
9404
|
+
* @param {Date} startDate - Start date of the range
|
|
9405
|
+
* @param {Date} endDate - End date of the range
|
|
9406
|
+
* @param {CalendarEventStatus} [status] - Optional status filter (defaults to all non-canceled appointments)
|
|
9407
|
+
* @returns {Promise<CalendarEvent[]>} A promise that resolves to an array of appointments
|
|
9408
|
+
*/
|
|
9409
|
+
async getPatientAppointments(patientId, startDate, endDate, status) {
|
|
9410
|
+
const dateRange = {
|
|
9411
|
+
start: Timestamp25.fromDate(startDate),
|
|
9412
|
+
end: Timestamp25.fromDate(endDate)
|
|
9413
|
+
};
|
|
9414
|
+
const searchParams = {
|
|
9415
|
+
searchLocation: "patient" /* PATIENT */,
|
|
9416
|
+
entityId: patientId,
|
|
9417
|
+
dateRange,
|
|
9418
|
+
eventType: "appointment" /* APPOINTMENT */
|
|
9419
|
+
};
|
|
9420
|
+
if (status) {
|
|
9421
|
+
searchParams.eventStatus = status;
|
|
9422
|
+
}
|
|
9423
|
+
return this.searchCalendarEvents(searchParams);
|
|
9424
|
+
}
|
|
9425
|
+
/**
|
|
9426
|
+
* Gets all appointments for a clinic within a specific date range
|
|
9427
|
+
*
|
|
9428
|
+
* @param {string} clinicId - ID of the clinic
|
|
9429
|
+
* @param {Date} startDate - Start date of the range
|
|
9430
|
+
* @param {Date} endDate - End date of the range
|
|
9431
|
+
* @param {string} [doctorId] - Optional doctor ID to filter by
|
|
9432
|
+
* @param {CalendarEventStatus} [status] - Optional status filter
|
|
9433
|
+
* @returns {Promise<CalendarEvent[]>} A promise that resolves to an array of appointments
|
|
9434
|
+
*/
|
|
9435
|
+
async getClinicAppointments(clinicId, startDate, endDate, doctorId, status) {
|
|
9436
|
+
const dateRange = {
|
|
9437
|
+
start: Timestamp25.fromDate(startDate),
|
|
9438
|
+
end: Timestamp25.fromDate(endDate)
|
|
9439
|
+
};
|
|
9440
|
+
const searchParams = {
|
|
9441
|
+
searchLocation: "clinic" /* CLINIC */,
|
|
9442
|
+
entityId: clinicId,
|
|
9443
|
+
dateRange,
|
|
9444
|
+
eventType: "appointment" /* APPOINTMENT */
|
|
9445
|
+
};
|
|
9446
|
+
if (doctorId) {
|
|
9447
|
+
searchParams.practitionerId = doctorId;
|
|
9448
|
+
}
|
|
9449
|
+
if (status) {
|
|
9450
|
+
searchParams.eventStatus = status;
|
|
9451
|
+
}
|
|
9452
|
+
return this.searchCalendarEvents(searchParams);
|
|
9453
|
+
}
|
|
9123
9454
|
// #endregion
|
|
9124
9455
|
// #region Private Helper Methods
|
|
9125
9456
|
/**
|
|
@@ -9163,8 +9494,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9163
9494
|
const startDate = eventTime.start.toDate();
|
|
9164
9495
|
const startTime = startDate;
|
|
9165
9496
|
const endTime = eventTime.end.toDate();
|
|
9166
|
-
const practitionerRef =
|
|
9167
|
-
const practitionerDoc = await
|
|
9497
|
+
const practitionerRef = doc22(this.db, PRACTITIONERS_COLLECTION, doctorId);
|
|
9498
|
+
const practitionerDoc = await getDoc24(practitionerRef);
|
|
9168
9499
|
if (!practitionerDoc.exists()) {
|
|
9169
9500
|
throw new Error(`Doctor with ID ${doctorId} not found`);
|
|
9170
9501
|
}
|
|
@@ -9221,8 +9552,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9221
9552
|
* @returns Updated calendar event
|
|
9222
9553
|
*/
|
|
9223
9554
|
async updateAppointmentStatus(appointmentId, clinicId, status) {
|
|
9224
|
-
const appointmentRef =
|
|
9225
|
-
const appointmentDoc = await
|
|
9555
|
+
const appointmentRef = doc22(this.db, CALENDAR_COLLECTION, appointmentId);
|
|
9556
|
+
const appointmentDoc = await getDoc24(appointmentRef);
|
|
9226
9557
|
if (!appointmentDoc.exists()) {
|
|
9227
9558
|
throw new Error(`Appointment with ID ${appointmentId} not found`);
|
|
9228
9559
|
}
|
|
@@ -9353,7 +9684,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9353
9684
|
const newSyncEvent = {
|
|
9354
9685
|
eventId: result.eventIds[0],
|
|
9355
9686
|
syncedCalendarProvider: calendar.provider,
|
|
9356
|
-
syncedAt:
|
|
9687
|
+
syncedAt: Timestamp25.now()
|
|
9357
9688
|
};
|
|
9358
9689
|
await this.updateEventWithSyncId(
|
|
9359
9690
|
entityType === "doctor" ? appointment.practitionerProfileId : appointment.patientProfileId,
|
|
@@ -9377,8 +9708,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9377
9708
|
async updateEventWithSyncId(entityId, entityType, eventId, syncEvent) {
|
|
9378
9709
|
try {
|
|
9379
9710
|
const collectionPath = entityType === "doctor" ? `${PRACTITIONERS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}` : `${PATIENTS_COLLECTION}/${entityId}/${CALENDAR_COLLECTION}`;
|
|
9380
|
-
const eventRef =
|
|
9381
|
-
const eventDoc = await
|
|
9711
|
+
const eventRef = doc22(this.db, collectionPath, eventId);
|
|
9712
|
+
const eventDoc = await getDoc24(eventRef);
|
|
9382
9713
|
if (eventDoc.exists()) {
|
|
9383
9714
|
const event = eventDoc.data();
|
|
9384
9715
|
const syncIds = [...event.syncedCalendarEventId || []];
|
|
@@ -9390,9 +9721,9 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9390
9721
|
} else {
|
|
9391
9722
|
syncIds.push(syncEvent);
|
|
9392
9723
|
}
|
|
9393
|
-
await
|
|
9724
|
+
await updateDoc22(eventRef, {
|
|
9394
9725
|
syncedCalendarEventId: syncIds,
|
|
9395
|
-
updatedAt:
|
|
9726
|
+
updatedAt: serverTimestamp20()
|
|
9396
9727
|
});
|
|
9397
9728
|
console.log(
|
|
9398
9729
|
`Updated event ${eventId} with sync ID ${syncEvent.eventId}`
|
|
@@ -9416,8 +9747,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9416
9747
|
* @returns Working hours for the clinic
|
|
9417
9748
|
*/
|
|
9418
9749
|
async getClinicWorkingHours(clinicId, date) {
|
|
9419
|
-
const clinicRef =
|
|
9420
|
-
const clinicDoc = await
|
|
9750
|
+
const clinicRef = doc22(this.db, CLINICS_COLLECTION, clinicId);
|
|
9751
|
+
const clinicDoc = await getDoc24(clinicRef);
|
|
9421
9752
|
if (!clinicDoc.exists()) {
|
|
9422
9753
|
throw new Error(`Clinic with ID ${clinicId} not found`);
|
|
9423
9754
|
}
|
|
@@ -9445,8 +9776,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9445
9776
|
* @returns Doctor's schedule
|
|
9446
9777
|
*/
|
|
9447
9778
|
async getDoctorSchedule(doctorId, date) {
|
|
9448
|
-
const practitionerRef =
|
|
9449
|
-
const practitionerDoc = await
|
|
9779
|
+
const practitionerRef = doc22(this.db, PRACTITIONERS_COLLECTION, doctorId);
|
|
9780
|
+
const practitionerDoc = await getDoc24(practitionerRef);
|
|
9450
9781
|
if (!practitionerDoc.exists()) {
|
|
9451
9782
|
throw new Error(`Doctor with ID ${doctorId} not found`);
|
|
9452
9783
|
}
|
|
@@ -9478,19 +9809,19 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9478
9809
|
startOfDay.setHours(0, 0, 0, 0);
|
|
9479
9810
|
const endOfDay = new Date(date);
|
|
9480
9811
|
endOfDay.setHours(23, 59, 59, 999);
|
|
9481
|
-
const appointmentsRef =
|
|
9482
|
-
const q =
|
|
9812
|
+
const appointmentsRef = collection20(this.db, CALENDAR_COLLECTION);
|
|
9813
|
+
const q = query19(
|
|
9483
9814
|
appointmentsRef,
|
|
9484
|
-
|
|
9485
|
-
|
|
9486
|
-
|
|
9487
|
-
|
|
9815
|
+
where19("practitionerProfileId", "==", doctorId),
|
|
9816
|
+
where19("eventTime.start", ">=", Timestamp25.fromDate(startOfDay)),
|
|
9817
|
+
where19("eventTime.start", "<=", Timestamp25.fromDate(endOfDay)),
|
|
9818
|
+
where19("status", "in", [
|
|
9488
9819
|
"confirmed" /* CONFIRMED */,
|
|
9489
9820
|
"pending" /* PENDING */
|
|
9490
9821
|
])
|
|
9491
9822
|
);
|
|
9492
|
-
const querySnapshot = await
|
|
9493
|
-
return querySnapshot.docs.map((
|
|
9823
|
+
const querySnapshot = await getDocs19(q);
|
|
9824
|
+
return querySnapshot.docs.map((doc28) => doc28.data());
|
|
9494
9825
|
}
|
|
9495
9826
|
/**
|
|
9496
9827
|
* Calculates available time slots based on working hours, schedule and existing appointments
|
|
@@ -9547,11 +9878,11 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9547
9878
|
var _a;
|
|
9548
9879
|
try {
|
|
9549
9880
|
const [clinicDoc, practitionerDoc, patientDoc, patientSensitiveInfoDoc] = await Promise.all([
|
|
9550
|
-
|
|
9551
|
-
|
|
9552
|
-
|
|
9553
|
-
|
|
9554
|
-
|
|
9881
|
+
getDoc24(doc22(this.db, CLINICS_COLLECTION, clinicId)),
|
|
9882
|
+
getDoc24(doc22(this.db, PRACTITIONERS_COLLECTION, doctorId)),
|
|
9883
|
+
getDoc24(doc22(this.db, PATIENTS_COLLECTION, patientId)),
|
|
9884
|
+
getDoc24(
|
|
9885
|
+
doc22(
|
|
9555
9886
|
this.db,
|
|
9556
9887
|
PATIENTS_COLLECTION,
|
|
9557
9888
|
patientId,
|
|
@@ -9584,7 +9915,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9584
9915
|
fullName: `${sensitiveData.firstName} ${sensitiveData.lastName}`,
|
|
9585
9916
|
email: sensitiveData.email || "",
|
|
9586
9917
|
phone: sensitiveData.phoneNumber || null,
|
|
9587
|
-
dateOfBirth: sensitiveData.dateOfBirth ||
|
|
9918
|
+
dateOfBirth: sensitiveData.dateOfBirth || Timestamp25.now(),
|
|
9588
9919
|
gender: sensitiveData.gender || "other" /* OTHER */
|
|
9589
9920
|
};
|
|
9590
9921
|
} else if (patientDoc.exists()) {
|
|
@@ -9593,7 +9924,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9593
9924
|
fullName: patientDoc.data().displayName,
|
|
9594
9925
|
email: ((_a = patientDoc.data().contactInfo) == null ? void 0 : _a.email) || "",
|
|
9595
9926
|
phone: patientDoc.data().phoneNumber || null,
|
|
9596
|
-
dateOfBirth: patientDoc.data().dateOfBirth ||
|
|
9927
|
+
dateOfBirth: patientDoc.data().dateOfBirth || Timestamp25.now(),
|
|
9597
9928
|
gender: patientDoc.data().gender || "other" /* OTHER */
|
|
9598
9929
|
};
|
|
9599
9930
|
}
|
|
@@ -9617,13 +9948,13 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
9617
9948
|
// src/backoffice/services/brand.service.ts
|
|
9618
9949
|
import {
|
|
9619
9950
|
addDoc as addDoc4,
|
|
9620
|
-
collection as
|
|
9621
|
-
doc as
|
|
9622
|
-
getDoc as
|
|
9623
|
-
getDocs as
|
|
9624
|
-
query as
|
|
9625
|
-
updateDoc as
|
|
9626
|
-
where as
|
|
9951
|
+
collection as collection21,
|
|
9952
|
+
doc as doc23,
|
|
9953
|
+
getDoc as getDoc25,
|
|
9954
|
+
getDocs as getDocs20,
|
|
9955
|
+
query as query20,
|
|
9956
|
+
updateDoc as updateDoc23,
|
|
9957
|
+
where as where20
|
|
9627
9958
|
} from "firebase/firestore";
|
|
9628
9959
|
|
|
9629
9960
|
// src/backoffice/types/brand.types.ts
|
|
@@ -9635,7 +9966,7 @@ var BrandService = class extends BaseService {
|
|
|
9635
9966
|
* Gets reference to brands collection
|
|
9636
9967
|
*/
|
|
9637
9968
|
getBrandsRef() {
|
|
9638
|
-
return
|
|
9969
|
+
return collection21(this.db, BRANDS_COLLECTION);
|
|
9639
9970
|
}
|
|
9640
9971
|
/**
|
|
9641
9972
|
* Creates a new brand
|
|
@@ -9655,12 +9986,12 @@ var BrandService = class extends BaseService {
|
|
|
9655
9986
|
* Gets all active brands
|
|
9656
9987
|
*/
|
|
9657
9988
|
async getAll() {
|
|
9658
|
-
const q =
|
|
9659
|
-
const snapshot = await
|
|
9989
|
+
const q = query20(this.getBrandsRef(), where20("isActive", "==", true));
|
|
9990
|
+
const snapshot = await getDocs20(q);
|
|
9660
9991
|
return snapshot.docs.map(
|
|
9661
|
-
(
|
|
9662
|
-
id:
|
|
9663
|
-
...
|
|
9992
|
+
(doc28) => ({
|
|
9993
|
+
id: doc28.id,
|
|
9994
|
+
...doc28.data()
|
|
9664
9995
|
})
|
|
9665
9996
|
);
|
|
9666
9997
|
}
|
|
@@ -9672,8 +10003,8 @@ var BrandService = class extends BaseService {
|
|
|
9672
10003
|
...brand,
|
|
9673
10004
|
updatedAt: /* @__PURE__ */ new Date()
|
|
9674
10005
|
};
|
|
9675
|
-
const docRef =
|
|
9676
|
-
await
|
|
10006
|
+
const docRef = doc23(this.getBrandsRef(), brandId);
|
|
10007
|
+
await updateDoc23(docRef, updateData);
|
|
9677
10008
|
return this.getById(brandId);
|
|
9678
10009
|
}
|
|
9679
10010
|
/**
|
|
@@ -9688,8 +10019,8 @@ var BrandService = class extends BaseService {
|
|
|
9688
10019
|
* Gets a brand by ID
|
|
9689
10020
|
*/
|
|
9690
10021
|
async getById(brandId) {
|
|
9691
|
-
const docRef =
|
|
9692
|
-
const docSnap = await
|
|
10022
|
+
const docRef = doc23(this.getBrandsRef(), brandId);
|
|
10023
|
+
const docSnap = await getDoc25(docRef);
|
|
9693
10024
|
if (!docSnap.exists()) return null;
|
|
9694
10025
|
return {
|
|
9695
10026
|
id: docSnap.id,
|
|
@@ -9701,13 +10032,13 @@ var BrandService = class extends BaseService {
|
|
|
9701
10032
|
// src/backoffice/services/category.service.ts
|
|
9702
10033
|
import {
|
|
9703
10034
|
addDoc as addDoc5,
|
|
9704
|
-
collection as
|
|
9705
|
-
doc as
|
|
9706
|
-
getDoc as
|
|
9707
|
-
getDocs as
|
|
9708
|
-
query as
|
|
9709
|
-
updateDoc as
|
|
9710
|
-
where as
|
|
10035
|
+
collection as collection22,
|
|
10036
|
+
doc as doc24,
|
|
10037
|
+
getDoc as getDoc26,
|
|
10038
|
+
getDocs as getDocs21,
|
|
10039
|
+
query as query21,
|
|
10040
|
+
updateDoc as updateDoc24,
|
|
10041
|
+
where as where21
|
|
9711
10042
|
} from "firebase/firestore";
|
|
9712
10043
|
|
|
9713
10044
|
// src/backoffice/types/category.types.ts
|
|
@@ -9719,7 +10050,7 @@ var CategoryService = class extends BaseService {
|
|
|
9719
10050
|
* Referenca na Firestore kolekciju kategorija
|
|
9720
10051
|
*/
|
|
9721
10052
|
get categoriesRef() {
|
|
9722
|
-
return
|
|
10053
|
+
return collection22(this.db, CATEGORIES_COLLECTION);
|
|
9723
10054
|
}
|
|
9724
10055
|
/**
|
|
9725
10056
|
* Kreira novu kategoriju u sistemu
|
|
@@ -9742,12 +10073,12 @@ var CategoryService = class extends BaseService {
|
|
|
9742
10073
|
* @returns Lista aktivnih kategorija
|
|
9743
10074
|
*/
|
|
9744
10075
|
async getAll() {
|
|
9745
|
-
const q =
|
|
9746
|
-
const snapshot = await
|
|
10076
|
+
const q = query21(this.categoriesRef, where21("isActive", "==", true));
|
|
10077
|
+
const snapshot = await getDocs21(q);
|
|
9747
10078
|
return snapshot.docs.map(
|
|
9748
|
-
(
|
|
9749
|
-
id:
|
|
9750
|
-
...
|
|
10079
|
+
(doc28) => ({
|
|
10080
|
+
id: doc28.id,
|
|
10081
|
+
...doc28.data()
|
|
9751
10082
|
})
|
|
9752
10083
|
);
|
|
9753
10084
|
}
|
|
@@ -9757,16 +10088,16 @@ var CategoryService = class extends BaseService {
|
|
|
9757
10088
|
* @returns Lista kategorija koje pripadaju traženoj familiji
|
|
9758
10089
|
*/
|
|
9759
10090
|
async getAllByFamily(family) {
|
|
9760
|
-
const q =
|
|
10091
|
+
const q = query21(
|
|
9761
10092
|
this.categoriesRef,
|
|
9762
|
-
|
|
9763
|
-
|
|
10093
|
+
where21("family", "==", family),
|
|
10094
|
+
where21("isActive", "==", true)
|
|
9764
10095
|
);
|
|
9765
|
-
const snapshot = await
|
|
10096
|
+
const snapshot = await getDocs21(q);
|
|
9766
10097
|
return snapshot.docs.map(
|
|
9767
|
-
(
|
|
9768
|
-
id:
|
|
9769
|
-
...
|
|
10098
|
+
(doc28) => ({
|
|
10099
|
+
id: doc28.id,
|
|
10100
|
+
...doc28.data()
|
|
9770
10101
|
})
|
|
9771
10102
|
);
|
|
9772
10103
|
}
|
|
@@ -9781,8 +10112,8 @@ var CategoryService = class extends BaseService {
|
|
|
9781
10112
|
...category,
|
|
9782
10113
|
updatedAt: /* @__PURE__ */ new Date()
|
|
9783
10114
|
};
|
|
9784
|
-
const docRef =
|
|
9785
|
-
await
|
|
10115
|
+
const docRef = doc24(this.categoriesRef, id);
|
|
10116
|
+
await updateDoc24(docRef, updateData);
|
|
9786
10117
|
return this.getById(id);
|
|
9787
10118
|
}
|
|
9788
10119
|
/**
|
|
@@ -9798,8 +10129,8 @@ var CategoryService = class extends BaseService {
|
|
|
9798
10129
|
* @returns Kategorija ili null ako ne postoji
|
|
9799
10130
|
*/
|
|
9800
10131
|
async getById(id) {
|
|
9801
|
-
const docRef =
|
|
9802
|
-
const docSnap = await
|
|
10132
|
+
const docRef = doc24(this.categoriesRef, id);
|
|
10133
|
+
const docSnap = await getDoc26(docRef);
|
|
9803
10134
|
if (!docSnap.exists()) return null;
|
|
9804
10135
|
return {
|
|
9805
10136
|
id: docSnap.id,
|
|
@@ -9811,13 +10142,13 @@ var CategoryService = class extends BaseService {
|
|
|
9811
10142
|
// src/backoffice/services/subcategory.service.ts
|
|
9812
10143
|
import {
|
|
9813
10144
|
addDoc as addDoc6,
|
|
9814
|
-
collection as
|
|
9815
|
-
doc as
|
|
9816
|
-
getDoc as
|
|
9817
|
-
getDocs as
|
|
9818
|
-
query as
|
|
9819
|
-
updateDoc as
|
|
9820
|
-
where as
|
|
10145
|
+
collection as collection23,
|
|
10146
|
+
doc as doc25,
|
|
10147
|
+
getDoc as getDoc27,
|
|
10148
|
+
getDocs as getDocs22,
|
|
10149
|
+
query as query22,
|
|
10150
|
+
updateDoc as updateDoc25,
|
|
10151
|
+
where as where22
|
|
9821
10152
|
} from "firebase/firestore";
|
|
9822
10153
|
|
|
9823
10154
|
// src/backoffice/types/subcategory.types.ts
|
|
@@ -9830,7 +10161,7 @@ var SubcategoryService = class extends BaseService {
|
|
|
9830
10161
|
* @param categoryId - ID roditeljske kategorije
|
|
9831
10162
|
*/
|
|
9832
10163
|
getSubcategoriesRef(categoryId) {
|
|
9833
|
-
return
|
|
10164
|
+
return collection23(
|
|
9834
10165
|
this.db,
|
|
9835
10166
|
CATEGORIES_COLLECTION,
|
|
9836
10167
|
categoryId,
|
|
@@ -9864,15 +10195,15 @@ var SubcategoryService = class extends BaseService {
|
|
|
9864
10195
|
* @returns Lista aktivnih podkategorija
|
|
9865
10196
|
*/
|
|
9866
10197
|
async getAllByCategoryId(categoryId) {
|
|
9867
|
-
const q =
|
|
10198
|
+
const q = query22(
|
|
9868
10199
|
this.getSubcategoriesRef(categoryId),
|
|
9869
|
-
|
|
10200
|
+
where22("isActive", "==", true)
|
|
9870
10201
|
);
|
|
9871
|
-
const snapshot = await
|
|
10202
|
+
const snapshot = await getDocs22(q);
|
|
9872
10203
|
return snapshot.docs.map(
|
|
9873
|
-
(
|
|
9874
|
-
id:
|
|
9875
|
-
...
|
|
10204
|
+
(doc28) => ({
|
|
10205
|
+
id: doc28.id,
|
|
10206
|
+
...doc28.data()
|
|
9876
10207
|
})
|
|
9877
10208
|
);
|
|
9878
10209
|
}
|
|
@@ -9888,8 +10219,8 @@ var SubcategoryService = class extends BaseService {
|
|
|
9888
10219
|
...subcategory,
|
|
9889
10220
|
updatedAt: /* @__PURE__ */ new Date()
|
|
9890
10221
|
};
|
|
9891
|
-
const docRef =
|
|
9892
|
-
await
|
|
10222
|
+
const docRef = doc25(this.getSubcategoriesRef(categoryId), subcategoryId);
|
|
10223
|
+
await updateDoc25(docRef, updateData);
|
|
9893
10224
|
return this.getById(categoryId, subcategoryId);
|
|
9894
10225
|
}
|
|
9895
10226
|
/**
|
|
@@ -9907,8 +10238,8 @@ var SubcategoryService = class extends BaseService {
|
|
|
9907
10238
|
* @returns Podkategorija ili null ako ne postoji
|
|
9908
10239
|
*/
|
|
9909
10240
|
async getById(categoryId, subcategoryId) {
|
|
9910
|
-
const docRef =
|
|
9911
|
-
const docSnap = await
|
|
10241
|
+
const docRef = doc25(this.getSubcategoriesRef(categoryId), subcategoryId);
|
|
10242
|
+
const docSnap = await getDoc27(docRef);
|
|
9912
10243
|
if (!docSnap.exists()) return null;
|
|
9913
10244
|
return {
|
|
9914
10245
|
id: docSnap.id,
|
|
@@ -9920,15 +10251,15 @@ var SubcategoryService = class extends BaseService {
|
|
|
9920
10251
|
// src/backoffice/services/technology.service.ts
|
|
9921
10252
|
import {
|
|
9922
10253
|
addDoc as addDoc7,
|
|
9923
|
-
collection as
|
|
9924
|
-
doc as
|
|
9925
|
-
getDoc as
|
|
9926
|
-
getDocs as
|
|
9927
|
-
query as
|
|
9928
|
-
updateDoc as
|
|
9929
|
-
where as
|
|
10254
|
+
collection as collection24,
|
|
10255
|
+
doc as doc26,
|
|
10256
|
+
getDoc as getDoc28,
|
|
10257
|
+
getDocs as getDocs23,
|
|
10258
|
+
query as query23,
|
|
10259
|
+
updateDoc as updateDoc26,
|
|
10260
|
+
where as where23,
|
|
9930
10261
|
arrayUnion as arrayUnion5,
|
|
9931
|
-
arrayRemove as
|
|
10262
|
+
arrayRemove as arrayRemove4
|
|
9932
10263
|
} from "firebase/firestore";
|
|
9933
10264
|
|
|
9934
10265
|
// src/backoffice/types/technology.types.ts
|
|
@@ -9944,7 +10275,7 @@ var TechnologyService = class extends BaseService {
|
|
|
9944
10275
|
* Vraća referencu na Firestore kolekciju tehnologija
|
|
9945
10276
|
*/
|
|
9946
10277
|
getTechnologiesRef() {
|
|
9947
|
-
return
|
|
10278
|
+
return collection24(this.db, TECHNOLOGIES_COLLECTION);
|
|
9948
10279
|
}
|
|
9949
10280
|
/**
|
|
9950
10281
|
* Kreira novu tehnologiju
|
|
@@ -9975,12 +10306,12 @@ var TechnologyService = class extends BaseService {
|
|
|
9975
10306
|
* @returns Lista aktivnih tehnologija
|
|
9976
10307
|
*/
|
|
9977
10308
|
async getAll() {
|
|
9978
|
-
const q =
|
|
9979
|
-
const snapshot = await
|
|
10309
|
+
const q = query23(this.getTechnologiesRef(), where23("isActive", "==", true));
|
|
10310
|
+
const snapshot = await getDocs23(q);
|
|
9980
10311
|
return snapshot.docs.map(
|
|
9981
|
-
(
|
|
9982
|
-
id:
|
|
9983
|
-
...
|
|
10312
|
+
(doc28) => ({
|
|
10313
|
+
id: doc28.id,
|
|
10314
|
+
...doc28.data()
|
|
9984
10315
|
})
|
|
9985
10316
|
);
|
|
9986
10317
|
}
|
|
@@ -9990,16 +10321,16 @@ var TechnologyService = class extends BaseService {
|
|
|
9990
10321
|
* @returns Lista aktivnih tehnologija
|
|
9991
10322
|
*/
|
|
9992
10323
|
async getAllByFamily(family) {
|
|
9993
|
-
const q =
|
|
10324
|
+
const q = query23(
|
|
9994
10325
|
this.getTechnologiesRef(),
|
|
9995
|
-
|
|
9996
|
-
|
|
10326
|
+
where23("isActive", "==", true),
|
|
10327
|
+
where23("family", "==", family)
|
|
9997
10328
|
);
|
|
9998
|
-
const snapshot = await
|
|
10329
|
+
const snapshot = await getDocs23(q);
|
|
9999
10330
|
return snapshot.docs.map(
|
|
10000
|
-
(
|
|
10001
|
-
id:
|
|
10002
|
-
...
|
|
10331
|
+
(doc28) => ({
|
|
10332
|
+
id: doc28.id,
|
|
10333
|
+
...doc28.data()
|
|
10003
10334
|
})
|
|
10004
10335
|
);
|
|
10005
10336
|
}
|
|
@@ -10009,16 +10340,16 @@ var TechnologyService = class extends BaseService {
|
|
|
10009
10340
|
* @returns Lista aktivnih tehnologija
|
|
10010
10341
|
*/
|
|
10011
10342
|
async getAllByCategoryId(categoryId) {
|
|
10012
|
-
const q =
|
|
10343
|
+
const q = query23(
|
|
10013
10344
|
this.getTechnologiesRef(),
|
|
10014
|
-
|
|
10015
|
-
|
|
10345
|
+
where23("isActive", "==", true),
|
|
10346
|
+
where23("categoryId", "==", categoryId)
|
|
10016
10347
|
);
|
|
10017
|
-
const snapshot = await
|
|
10348
|
+
const snapshot = await getDocs23(q);
|
|
10018
10349
|
return snapshot.docs.map(
|
|
10019
|
-
(
|
|
10020
|
-
id:
|
|
10021
|
-
...
|
|
10350
|
+
(doc28) => ({
|
|
10351
|
+
id: doc28.id,
|
|
10352
|
+
...doc28.data()
|
|
10022
10353
|
})
|
|
10023
10354
|
);
|
|
10024
10355
|
}
|
|
@@ -10028,16 +10359,16 @@ var TechnologyService = class extends BaseService {
|
|
|
10028
10359
|
* @returns Lista aktivnih tehnologija
|
|
10029
10360
|
*/
|
|
10030
10361
|
async getAllBySubcategoryId(subcategoryId) {
|
|
10031
|
-
const q =
|
|
10362
|
+
const q = query23(
|
|
10032
10363
|
this.getTechnologiesRef(),
|
|
10033
|
-
|
|
10034
|
-
|
|
10364
|
+
where23("isActive", "==", true),
|
|
10365
|
+
where23("subcategoryId", "==", subcategoryId)
|
|
10035
10366
|
);
|
|
10036
|
-
const snapshot = await
|
|
10367
|
+
const snapshot = await getDocs23(q);
|
|
10037
10368
|
return snapshot.docs.map(
|
|
10038
|
-
(
|
|
10039
|
-
id:
|
|
10040
|
-
...
|
|
10369
|
+
(doc28) => ({
|
|
10370
|
+
id: doc28.id,
|
|
10371
|
+
...doc28.data()
|
|
10041
10372
|
})
|
|
10042
10373
|
);
|
|
10043
10374
|
}
|
|
@@ -10052,8 +10383,8 @@ var TechnologyService = class extends BaseService {
|
|
|
10052
10383
|
...technology,
|
|
10053
10384
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10054
10385
|
};
|
|
10055
|
-
const docRef =
|
|
10056
|
-
await
|
|
10386
|
+
const docRef = doc26(this.getTechnologiesRef(), technologyId);
|
|
10387
|
+
await updateDoc26(docRef, updateData);
|
|
10057
10388
|
return this.getById(technologyId);
|
|
10058
10389
|
}
|
|
10059
10390
|
/**
|
|
@@ -10071,8 +10402,8 @@ var TechnologyService = class extends BaseService {
|
|
|
10071
10402
|
* @returns Tehnologija ili null ako ne postoji
|
|
10072
10403
|
*/
|
|
10073
10404
|
async getById(technologyId) {
|
|
10074
|
-
const docRef =
|
|
10075
|
-
const docSnap = await
|
|
10405
|
+
const docRef = doc26(this.getTechnologiesRef(), technologyId);
|
|
10406
|
+
const docSnap = await getDoc28(docRef);
|
|
10076
10407
|
if (!docSnap.exists()) return null;
|
|
10077
10408
|
return {
|
|
10078
10409
|
id: docSnap.id,
|
|
@@ -10086,9 +10417,9 @@ var TechnologyService = class extends BaseService {
|
|
|
10086
10417
|
* @returns Ažurirana tehnologija sa novim zahtevom
|
|
10087
10418
|
*/
|
|
10088
10419
|
async addRequirement(technologyId, requirement) {
|
|
10089
|
-
const docRef =
|
|
10420
|
+
const docRef = doc26(this.getTechnologiesRef(), technologyId);
|
|
10090
10421
|
const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
|
|
10091
|
-
await
|
|
10422
|
+
await updateDoc26(docRef, {
|
|
10092
10423
|
[requirementType]: arrayUnion5(requirement),
|
|
10093
10424
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10094
10425
|
});
|
|
@@ -10101,10 +10432,10 @@ var TechnologyService = class extends BaseService {
|
|
|
10101
10432
|
* @returns Ažurirana tehnologija bez uklonjenog zahteva
|
|
10102
10433
|
*/
|
|
10103
10434
|
async removeRequirement(technologyId, requirement) {
|
|
10104
|
-
const docRef =
|
|
10435
|
+
const docRef = doc26(this.getTechnologiesRef(), technologyId);
|
|
10105
10436
|
const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
|
|
10106
|
-
await
|
|
10107
|
-
[requirementType]:
|
|
10437
|
+
await updateDoc26(docRef, {
|
|
10438
|
+
[requirementType]: arrayRemove4(requirement),
|
|
10108
10439
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10109
10440
|
});
|
|
10110
10441
|
return this.getById(technologyId);
|
|
@@ -10141,8 +10472,8 @@ var TechnologyService = class extends BaseService {
|
|
|
10141
10472
|
* @returns Ažurirana tehnologija
|
|
10142
10473
|
*/
|
|
10143
10474
|
async addBlockingCondition(technologyId, condition) {
|
|
10144
|
-
const docRef =
|
|
10145
|
-
await
|
|
10475
|
+
const docRef = doc26(this.getTechnologiesRef(), technologyId);
|
|
10476
|
+
await updateDoc26(docRef, {
|
|
10146
10477
|
blockingConditions: arrayUnion5(condition),
|
|
10147
10478
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10148
10479
|
});
|
|
@@ -10155,9 +10486,9 @@ var TechnologyService = class extends BaseService {
|
|
|
10155
10486
|
* @returns Ažurirana tehnologija
|
|
10156
10487
|
*/
|
|
10157
10488
|
async removeBlockingCondition(technologyId, condition) {
|
|
10158
|
-
const docRef =
|
|
10159
|
-
await
|
|
10160
|
-
blockingConditions:
|
|
10489
|
+
const docRef = doc26(this.getTechnologiesRef(), technologyId);
|
|
10490
|
+
await updateDoc26(docRef, {
|
|
10491
|
+
blockingConditions: arrayRemove4(condition),
|
|
10161
10492
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10162
10493
|
});
|
|
10163
10494
|
return this.getById(technologyId);
|
|
@@ -10169,8 +10500,8 @@ var TechnologyService = class extends BaseService {
|
|
|
10169
10500
|
* @returns Ažurirana tehnologija
|
|
10170
10501
|
*/
|
|
10171
10502
|
async addContraindication(technologyId, contraindication) {
|
|
10172
|
-
const docRef =
|
|
10173
|
-
await
|
|
10503
|
+
const docRef = doc26(this.getTechnologiesRef(), technologyId);
|
|
10504
|
+
await updateDoc26(docRef, {
|
|
10174
10505
|
contraindications: arrayUnion5(contraindication),
|
|
10175
10506
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10176
10507
|
});
|
|
@@ -10183,9 +10514,9 @@ var TechnologyService = class extends BaseService {
|
|
|
10183
10514
|
* @returns Ažurirana tehnologija
|
|
10184
10515
|
*/
|
|
10185
10516
|
async removeContraindication(technologyId, contraindication) {
|
|
10186
|
-
const docRef =
|
|
10187
|
-
await
|
|
10188
|
-
contraindications:
|
|
10517
|
+
const docRef = doc26(this.getTechnologiesRef(), technologyId);
|
|
10518
|
+
await updateDoc26(docRef, {
|
|
10519
|
+
contraindications: arrayRemove4(contraindication),
|
|
10189
10520
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10190
10521
|
});
|
|
10191
10522
|
return this.getById(technologyId);
|
|
@@ -10197,8 +10528,8 @@ var TechnologyService = class extends BaseService {
|
|
|
10197
10528
|
* @returns Ažurirana tehnologija
|
|
10198
10529
|
*/
|
|
10199
10530
|
async addBenefit(technologyId, benefit) {
|
|
10200
|
-
const docRef =
|
|
10201
|
-
await
|
|
10531
|
+
const docRef = doc26(this.getTechnologiesRef(), technologyId);
|
|
10532
|
+
await updateDoc26(docRef, {
|
|
10202
10533
|
benefits: arrayUnion5(benefit),
|
|
10203
10534
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10204
10535
|
});
|
|
@@ -10211,9 +10542,9 @@ var TechnologyService = class extends BaseService {
|
|
|
10211
10542
|
* @returns Ažurirana tehnologija
|
|
10212
10543
|
*/
|
|
10213
10544
|
async removeBenefit(technologyId, benefit) {
|
|
10214
|
-
const docRef =
|
|
10215
|
-
await
|
|
10216
|
-
benefits:
|
|
10545
|
+
const docRef = doc26(this.getTechnologiesRef(), technologyId);
|
|
10546
|
+
await updateDoc26(docRef, {
|
|
10547
|
+
benefits: arrayRemove4(benefit),
|
|
10217
10548
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10218
10549
|
});
|
|
10219
10550
|
return this.getById(technologyId);
|
|
@@ -10252,8 +10583,8 @@ var TechnologyService = class extends BaseService {
|
|
|
10252
10583
|
* @returns Ažurirana tehnologija
|
|
10253
10584
|
*/
|
|
10254
10585
|
async updateCertificationRequirement(technologyId, certificationRequirement) {
|
|
10255
|
-
const docRef =
|
|
10256
|
-
await
|
|
10586
|
+
const docRef = doc26(this.getTechnologiesRef(), technologyId);
|
|
10587
|
+
await updateDoc26(docRef, {
|
|
10257
10588
|
certificationRequirement,
|
|
10258
10589
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10259
10590
|
});
|
|
@@ -10355,13 +10686,13 @@ var TechnologyService = class extends BaseService {
|
|
|
10355
10686
|
// src/backoffice/services/product.service.ts
|
|
10356
10687
|
import {
|
|
10357
10688
|
addDoc as addDoc8,
|
|
10358
|
-
collection as
|
|
10359
|
-
doc as
|
|
10360
|
-
getDoc as
|
|
10361
|
-
getDocs as
|
|
10362
|
-
query as
|
|
10363
|
-
updateDoc as
|
|
10364
|
-
where as
|
|
10689
|
+
collection as collection25,
|
|
10690
|
+
doc as doc27,
|
|
10691
|
+
getDoc as getDoc29,
|
|
10692
|
+
getDocs as getDocs24,
|
|
10693
|
+
query as query24,
|
|
10694
|
+
updateDoc as updateDoc27,
|
|
10695
|
+
where as where24
|
|
10365
10696
|
} from "firebase/firestore";
|
|
10366
10697
|
|
|
10367
10698
|
// src/backoffice/types/product.types.ts
|
|
@@ -10375,7 +10706,7 @@ var ProductService = class extends BaseService {
|
|
|
10375
10706
|
* @returns Firestore collection reference
|
|
10376
10707
|
*/
|
|
10377
10708
|
getProductsRef(technologyId) {
|
|
10378
|
-
return
|
|
10709
|
+
return collection25(
|
|
10379
10710
|
this.db,
|
|
10380
10711
|
TECHNOLOGIES_COLLECTION,
|
|
10381
10712
|
technologyId,
|
|
@@ -10405,15 +10736,15 @@ var ProductService = class extends BaseService {
|
|
|
10405
10736
|
* Gets all products for a technology
|
|
10406
10737
|
*/
|
|
10407
10738
|
async getAllByTechnology(technologyId) {
|
|
10408
|
-
const q =
|
|
10739
|
+
const q = query24(
|
|
10409
10740
|
this.getProductsRef(technologyId),
|
|
10410
|
-
|
|
10741
|
+
where24("isActive", "==", true)
|
|
10411
10742
|
);
|
|
10412
|
-
const snapshot = await
|
|
10743
|
+
const snapshot = await getDocs24(q);
|
|
10413
10744
|
return snapshot.docs.map(
|
|
10414
|
-
(
|
|
10415
|
-
id:
|
|
10416
|
-
...
|
|
10745
|
+
(doc28) => ({
|
|
10746
|
+
id: doc28.id,
|
|
10747
|
+
...doc28.data()
|
|
10417
10748
|
})
|
|
10418
10749
|
);
|
|
10419
10750
|
}
|
|
@@ -10421,21 +10752,21 @@ var ProductService = class extends BaseService {
|
|
|
10421
10752
|
* Gets all products for a brand by filtering through all technologies
|
|
10422
10753
|
*/
|
|
10423
10754
|
async getAllByBrand(brandId) {
|
|
10424
|
-
const allTechnologiesRef =
|
|
10425
|
-
const technologiesSnapshot = await
|
|
10755
|
+
const allTechnologiesRef = collection25(this.db, TECHNOLOGIES_COLLECTION);
|
|
10756
|
+
const technologiesSnapshot = await getDocs24(allTechnologiesRef);
|
|
10426
10757
|
const products = [];
|
|
10427
10758
|
for (const techDoc of technologiesSnapshot.docs) {
|
|
10428
|
-
const q =
|
|
10759
|
+
const q = query24(
|
|
10429
10760
|
this.getProductsRef(techDoc.id),
|
|
10430
|
-
|
|
10431
|
-
|
|
10761
|
+
where24("brandId", "==", brandId),
|
|
10762
|
+
where24("isActive", "==", true)
|
|
10432
10763
|
);
|
|
10433
|
-
const snapshot = await
|
|
10764
|
+
const snapshot = await getDocs24(q);
|
|
10434
10765
|
products.push(
|
|
10435
10766
|
...snapshot.docs.map(
|
|
10436
|
-
(
|
|
10437
|
-
id:
|
|
10438
|
-
...
|
|
10767
|
+
(doc28) => ({
|
|
10768
|
+
id: doc28.id,
|
|
10769
|
+
...doc28.data()
|
|
10439
10770
|
})
|
|
10440
10771
|
)
|
|
10441
10772
|
);
|
|
@@ -10450,8 +10781,8 @@ var ProductService = class extends BaseService {
|
|
|
10450
10781
|
...product,
|
|
10451
10782
|
updatedAt: /* @__PURE__ */ new Date()
|
|
10452
10783
|
};
|
|
10453
|
-
const docRef =
|
|
10454
|
-
await
|
|
10784
|
+
const docRef = doc27(this.getProductsRef(technologyId), productId);
|
|
10785
|
+
await updateDoc27(docRef, updateData);
|
|
10455
10786
|
return this.getById(technologyId, productId);
|
|
10456
10787
|
}
|
|
10457
10788
|
/**
|
|
@@ -10466,8 +10797,8 @@ var ProductService = class extends BaseService {
|
|
|
10466
10797
|
* Gets a product by ID
|
|
10467
10798
|
*/
|
|
10468
10799
|
async getById(technologyId, productId) {
|
|
10469
|
-
const docRef =
|
|
10470
|
-
const docSnap = await
|
|
10800
|
+
const docRef = doc27(this.getProductsRef(technologyId), productId);
|
|
10801
|
+
const docSnap = await getDoc29(docRef);
|
|
10471
10802
|
if (!docSnap.exists()) return null;
|
|
10472
10803
|
return {
|
|
10473
10804
|
id: docSnap.id,
|
|
@@ -10593,6 +10924,7 @@ export {
|
|
|
10593
10924
|
ProductService,
|
|
10594
10925
|
REGISTER_TOKENS_COLLECTION,
|
|
10595
10926
|
SYNCED_CALENDARS_COLLECTION,
|
|
10927
|
+
SearchLocationEnum,
|
|
10596
10928
|
SubcategoryService,
|
|
10597
10929
|
SubscriptionModel,
|
|
10598
10930
|
SyncedCalendarProvider,
|
|
@@ -10682,7 +11014,9 @@ export {
|
|
|
10682
11014
|
preRequirementNotificationSchema,
|
|
10683
11015
|
procedureCategorizationSchema,
|
|
10684
11016
|
procedureInfoSchema,
|
|
11017
|
+
requesterInfoSchema,
|
|
10685
11018
|
reviewInfoSchema,
|
|
11019
|
+
searchPatientsSchema,
|
|
10686
11020
|
serviceInfoSchema,
|
|
10687
11021
|
syncedCalendarEventSchema,
|
|
10688
11022
|
timeSlotSchema2 as timeSlotSchema,
|