@blackcode_sa/metaestetics-api 1.7.2 → 1.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/index.d.mts +41 -8
- package/dist/admin/index.d.ts +41 -8
- package/dist/admin/index.js +621 -109
- package/dist/admin/index.mjs +621 -109
- package/dist/index.d.mts +281 -342
- package/dist/index.d.ts +281 -342
- package/dist/index.js +1178 -1124
- package/dist/index.mjs +388 -334
- package/package.json +1 -1
- package/src/admin/aggregation/appointment/appointment.aggregation.service.ts +553 -112
- package/src/admin/calendar/calendar.admin.service.ts +230 -65
- package/src/services/calendar/calendar-refactored.service.ts +2 -0
- package/src/services/patient/utils/medical.utils.ts +26 -23
- package/src/services/patient/utils/practitioner.utils.ts +102 -0
- package/src/types/calendar/index.ts +1 -0
- package/src/types/patient/medical-info.types.ts +2 -2
- package/src/validations/common.schema.ts +15 -4
package/dist/index.mjs
CHANGED
|
@@ -541,6 +541,7 @@ var CalendarEventStatus = /* @__PURE__ */ ((CalendarEventStatus4) => {
|
|
|
541
541
|
CalendarEventStatus4["CANCELED"] = "canceled";
|
|
542
542
|
CalendarEventStatus4["RESCHEDULED"] = "rescheduled";
|
|
543
543
|
CalendarEventStatus4["COMPLETED"] = "completed";
|
|
544
|
+
CalendarEventStatus4["NO_SHOW"] = "no_show";
|
|
544
545
|
return CalendarEventStatus4;
|
|
545
546
|
})(CalendarEventStatus || {});
|
|
546
547
|
var CalendarSyncStatus = /* @__PURE__ */ ((CalendarSyncStatus4) => {
|
|
@@ -884,7 +885,7 @@ import {
|
|
|
884
885
|
where as where7,
|
|
885
886
|
updateDoc as updateDoc9,
|
|
886
887
|
deleteDoc as deleteDoc3,
|
|
887
|
-
Timestamp as
|
|
888
|
+
Timestamp as Timestamp10,
|
|
888
889
|
setDoc as setDoc8,
|
|
889
890
|
serverTimestamp as serverTimestamp10
|
|
890
891
|
} from "firebase/firestore";
|
|
@@ -993,21 +994,21 @@ import {
|
|
|
993
994
|
|
|
994
995
|
// src/services/patient/utils/profile.utils.ts
|
|
995
996
|
import {
|
|
996
|
-
getDoc as
|
|
997
|
+
getDoc as getDoc5,
|
|
997
998
|
setDoc as setDoc4,
|
|
998
999
|
updateDoc as updateDoc3,
|
|
999
1000
|
arrayUnion as arrayUnion2,
|
|
1000
1001
|
arrayRemove as arrayRemove2,
|
|
1001
1002
|
serverTimestamp as serverTimestamp4,
|
|
1002
1003
|
increment,
|
|
1003
|
-
Timestamp as
|
|
1004
|
-
collection as
|
|
1005
|
-
query as
|
|
1006
|
-
where as
|
|
1007
|
-
getDocs as
|
|
1008
|
-
limit,
|
|
1009
|
-
startAfter,
|
|
1010
|
-
doc as
|
|
1004
|
+
Timestamp as Timestamp4,
|
|
1005
|
+
collection as collection3,
|
|
1006
|
+
query as query3,
|
|
1007
|
+
where as where3,
|
|
1008
|
+
getDocs as getDocs3,
|
|
1009
|
+
limit as limit2,
|
|
1010
|
+
startAfter as startAfter2,
|
|
1011
|
+
doc as doc4
|
|
1011
1012
|
} from "firebase/firestore";
|
|
1012
1013
|
import { ref, uploadBytes, getDownloadURL, deleteObject } from "firebase/storage";
|
|
1013
1014
|
import { z as z8 } from "zod";
|
|
@@ -1040,7 +1041,7 @@ var Gender = /* @__PURE__ */ ((Gender2) => {
|
|
|
1040
1041
|
|
|
1041
1042
|
// src/validations/patient.schema.ts
|
|
1042
1043
|
import { z as z6 } from "zod";
|
|
1043
|
-
import { Timestamp } from "firebase/firestore";
|
|
1044
|
+
import { Timestamp as Timestamp2 } from "firebase/firestore";
|
|
1044
1045
|
|
|
1045
1046
|
// src/validations/patient/medical-info.schema.ts
|
|
1046
1047
|
import { z as z5 } from "zod";
|
|
@@ -1133,9 +1134,18 @@ var Contraindication = /* @__PURE__ */ ((Contraindication2) => {
|
|
|
1133
1134
|
|
|
1134
1135
|
// src/validations/common.schema.ts
|
|
1135
1136
|
import { z as z4 } from "zod";
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1137
|
+
import { Timestamp } from "firebase/firestore";
|
|
1138
|
+
var timestampSchema2 = z4.union([
|
|
1139
|
+
z4.object({
|
|
1140
|
+
seconds: z4.number(),
|
|
1141
|
+
nanoseconds: z4.number()
|
|
1142
|
+
}),
|
|
1143
|
+
z4.instanceof(Timestamp)
|
|
1144
|
+
]).transform((data) => {
|
|
1145
|
+
if (data instanceof Timestamp) {
|
|
1146
|
+
return data;
|
|
1147
|
+
}
|
|
1148
|
+
return new Timestamp(data.seconds, data.nanoseconds);
|
|
1139
1149
|
});
|
|
1140
1150
|
|
|
1141
1151
|
// src/validations/patient/medical-info.schema.ts
|
|
@@ -1251,8 +1261,8 @@ var patientLocationInfoSchema = z6.object({
|
|
|
1251
1261
|
patientId: z6.string(),
|
|
1252
1262
|
userRef: z6.string(),
|
|
1253
1263
|
locationData: locationDataSchema,
|
|
1254
|
-
createdAt: z6.instanceof(
|
|
1255
|
-
updatedAt: z6.instanceof(
|
|
1264
|
+
createdAt: z6.instanceof(Timestamp2),
|
|
1265
|
+
updatedAt: z6.instanceof(Timestamp2)
|
|
1256
1266
|
});
|
|
1257
1267
|
var createPatientLocationInfoSchema = z6.object({
|
|
1258
1268
|
patientId: z6.string(),
|
|
@@ -1265,26 +1275,26 @@ var patientSensitiveInfoSchema = z6.object({
|
|
|
1265
1275
|
photoUrl: z6.string().optional(),
|
|
1266
1276
|
firstName: z6.string().min(2),
|
|
1267
1277
|
lastName: z6.string().min(2),
|
|
1268
|
-
dateOfBirth: z6.instanceof(
|
|
1278
|
+
dateOfBirth: z6.instanceof(Timestamp2).nullable(),
|
|
1269
1279
|
gender: z6.nativeEnum(Gender),
|
|
1270
1280
|
email: z6.string().email().optional(),
|
|
1271
1281
|
phoneNumber: z6.string().optional(),
|
|
1272
1282
|
alternativePhoneNumber: z6.string().optional(),
|
|
1273
1283
|
addressData: addressDataSchema.optional(),
|
|
1274
1284
|
emergencyContacts: z6.array(emergencyContactSchema).optional(),
|
|
1275
|
-
createdAt: z6.instanceof(
|
|
1276
|
-
updatedAt: z6.instanceof(
|
|
1285
|
+
createdAt: z6.instanceof(Timestamp2),
|
|
1286
|
+
updatedAt: z6.instanceof(Timestamp2)
|
|
1277
1287
|
});
|
|
1278
1288
|
var patientDoctorSchema = z6.object({
|
|
1279
1289
|
userRef: z6.string(),
|
|
1280
|
-
assignedAt: z6.instanceof(
|
|
1290
|
+
assignedAt: z6.instanceof(Timestamp2),
|
|
1281
1291
|
assignedBy: z6.string().optional(),
|
|
1282
1292
|
isActive: z6.boolean(),
|
|
1283
1293
|
notes: z6.string().optional()
|
|
1284
1294
|
});
|
|
1285
1295
|
var patientClinicSchema = z6.object({
|
|
1286
1296
|
clinicId: z6.string(),
|
|
1287
|
-
assignedAt: z6.instanceof(
|
|
1297
|
+
assignedAt: z6.instanceof(Timestamp2),
|
|
1288
1298
|
assignedBy: z6.string().optional(),
|
|
1289
1299
|
isActive: z6.boolean(),
|
|
1290
1300
|
notes: z6.string().optional()
|
|
@@ -1302,8 +1312,8 @@ var patientProfileSchema = z6.object({
|
|
|
1302
1312
|
clinics: z6.array(patientClinicSchema),
|
|
1303
1313
|
doctorIds: z6.array(z6.string()),
|
|
1304
1314
|
clinicIds: z6.array(z6.string()),
|
|
1305
|
-
createdAt: z6.instanceof(
|
|
1306
|
-
updatedAt: z6.instanceof(
|
|
1315
|
+
createdAt: z6.instanceof(Timestamp2),
|
|
1316
|
+
updatedAt: z6.instanceof(Timestamp2)
|
|
1307
1317
|
});
|
|
1308
1318
|
var createPatientProfileSchema = z6.object({
|
|
1309
1319
|
userRef: z6.string(),
|
|
@@ -1324,7 +1334,7 @@ var createPatientSensitiveInfoSchema = z6.object({
|
|
|
1324
1334
|
photoUrl: z6.string().optional(),
|
|
1325
1335
|
firstName: z6.string().min(2),
|
|
1326
1336
|
lastName: z6.string().min(2),
|
|
1327
|
-
dateOfBirth: z6.instanceof(
|
|
1337
|
+
dateOfBirth: z6.instanceof(Timestamp2).nullable(),
|
|
1328
1338
|
gender: z6.nativeEnum(Gender),
|
|
1329
1339
|
email: z6.string().email().optional(),
|
|
1330
1340
|
phoneNumber: z6.string().optional(),
|
|
@@ -1524,13 +1534,165 @@ var initSensitiveInfoDocIfNotExists = async (db, patientId, userRef) => {
|
|
|
1524
1534
|
|
|
1525
1535
|
// src/services/patient/utils/medical.utils.ts
|
|
1526
1536
|
import {
|
|
1527
|
-
getDoc as
|
|
1537
|
+
getDoc as getDoc4,
|
|
1528
1538
|
updateDoc as updateDoc2,
|
|
1529
1539
|
setDoc as setDoc3,
|
|
1530
1540
|
serverTimestamp as serverTimestamp3,
|
|
1531
1541
|
arrayUnion,
|
|
1532
|
-
Timestamp as
|
|
1542
|
+
Timestamp as Timestamp3
|
|
1533
1543
|
} from "firebase/firestore";
|
|
1544
|
+
|
|
1545
|
+
// src/services/patient/utils/practitioner.utils.ts
|
|
1546
|
+
import {
|
|
1547
|
+
collection as collection2,
|
|
1548
|
+
query as query2,
|
|
1549
|
+
where as where2,
|
|
1550
|
+
getDocs as getDocs2,
|
|
1551
|
+
limit,
|
|
1552
|
+
startAfter,
|
|
1553
|
+
doc as doc2,
|
|
1554
|
+
getDoc as getDoc3
|
|
1555
|
+
} from "firebase/firestore";
|
|
1556
|
+
|
|
1557
|
+
// src/types/practitioner/index.ts
|
|
1558
|
+
var PRACTITIONERS_COLLECTION = "practitioners";
|
|
1559
|
+
var REGISTER_TOKENS_COLLECTION = "register_tokens";
|
|
1560
|
+
var PractitionerStatus = /* @__PURE__ */ ((PractitionerStatus2) => {
|
|
1561
|
+
PractitionerStatus2["DRAFT"] = "draft";
|
|
1562
|
+
PractitionerStatus2["ACTIVE"] = "active";
|
|
1563
|
+
return PractitionerStatus2;
|
|
1564
|
+
})(PractitionerStatus || {});
|
|
1565
|
+
var PractitionerTokenStatus = /* @__PURE__ */ ((PractitionerTokenStatus2) => {
|
|
1566
|
+
PractitionerTokenStatus2["ACTIVE"] = "active";
|
|
1567
|
+
PractitionerTokenStatus2["USED"] = "used";
|
|
1568
|
+
PractitionerTokenStatus2["EXPIRED"] = "expired";
|
|
1569
|
+
PractitionerTokenStatus2["REVOKED"] = "revoked";
|
|
1570
|
+
return PractitionerTokenStatus2;
|
|
1571
|
+
})(PractitionerTokenStatus || {});
|
|
1572
|
+
|
|
1573
|
+
// src/services/patient/utils/practitioner.utils.ts
|
|
1574
|
+
var getPatientsByPractitionerUtil = async (db, practitionerId, options) => {
|
|
1575
|
+
try {
|
|
1576
|
+
console.log(
|
|
1577
|
+
`[getPatientsByPractitionerUtil] Fetching patients for practitioner ID: ${practitionerId} with options:`,
|
|
1578
|
+
options
|
|
1579
|
+
);
|
|
1580
|
+
const patientsCollection = collection2(db, PATIENTS_COLLECTION);
|
|
1581
|
+
const constraints = [
|
|
1582
|
+
where2("doctorIds", "array-contains", practitionerId)
|
|
1583
|
+
];
|
|
1584
|
+
let q = query2(patientsCollection, ...constraints);
|
|
1585
|
+
if (options == null ? void 0 : options.limit) {
|
|
1586
|
+
q = query2(q, limit(options.limit));
|
|
1587
|
+
}
|
|
1588
|
+
if (options == null ? void 0 : options.startAfter) {
|
|
1589
|
+
const startAfterDoc = await getDoc3(
|
|
1590
|
+
doc2(db, PATIENTS_COLLECTION, options.startAfter)
|
|
1591
|
+
);
|
|
1592
|
+
if (startAfterDoc.exists()) {
|
|
1593
|
+
q = query2(q, startAfter(startAfterDoc));
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
const patientsSnapshot = await getDocs2(q);
|
|
1597
|
+
const patients = [];
|
|
1598
|
+
patientsSnapshot.forEach((doc33) => {
|
|
1599
|
+
patients.push(doc33.data());
|
|
1600
|
+
});
|
|
1601
|
+
console.log(
|
|
1602
|
+
`[getPatientsByPractitionerUtil] Found ${patients.length} patients for practitioner ID: ${practitionerId}`
|
|
1603
|
+
);
|
|
1604
|
+
return patients;
|
|
1605
|
+
} catch (error) {
|
|
1606
|
+
console.error(
|
|
1607
|
+
`[getPatientsByPractitionerUtil] Error fetching patients for practitioner:`,
|
|
1608
|
+
error
|
|
1609
|
+
);
|
|
1610
|
+
throw new Error(
|
|
1611
|
+
`Failed to retrieve patients for practitioner: ${error instanceof Error ? error.message : String(error)}`
|
|
1612
|
+
);
|
|
1613
|
+
}
|
|
1614
|
+
};
|
|
1615
|
+
var getPatientsByPractitionerWithDetailsUtil = async (db, practitionerId, options) => {
|
|
1616
|
+
try {
|
|
1617
|
+
console.log(
|
|
1618
|
+
`[getPatientsByPractitionerWithDetailsUtil] Fetching detailed patient profiles for practitioner ID: ${practitionerId} with options:`,
|
|
1619
|
+
options
|
|
1620
|
+
);
|
|
1621
|
+
const patientProfiles = await getPatientsByPractitionerUtil(
|
|
1622
|
+
db,
|
|
1623
|
+
practitionerId,
|
|
1624
|
+
options
|
|
1625
|
+
);
|
|
1626
|
+
const patientProfilesWithDetails = await Promise.all(
|
|
1627
|
+
patientProfiles.map(async (profile) => {
|
|
1628
|
+
try {
|
|
1629
|
+
const sensitiveInfoDoc = await getDoc3(
|
|
1630
|
+
getSensitiveInfoDocRef(db, profile.id)
|
|
1631
|
+
);
|
|
1632
|
+
const sensitiveInfo = sensitiveInfoDoc.exists() ? sensitiveInfoDoc.data() : void 0;
|
|
1633
|
+
return {
|
|
1634
|
+
patientProfile: profile,
|
|
1635
|
+
patientSensitiveInfo: sensitiveInfo
|
|
1636
|
+
};
|
|
1637
|
+
} catch (error) {
|
|
1638
|
+
console.error(
|
|
1639
|
+
`[getPatientsByPractitionerWithDetailsUtil] Error fetching sensitive info for patient ${profile.id}:`,
|
|
1640
|
+
error
|
|
1641
|
+
);
|
|
1642
|
+
return { patientProfile: profile };
|
|
1643
|
+
}
|
|
1644
|
+
})
|
|
1645
|
+
);
|
|
1646
|
+
console.log(
|
|
1647
|
+
`[getPatientsByPractitionerWithDetailsUtil] Found ${patientProfilesWithDetails.length} detailed patient profiles for practitioner ID: ${practitionerId}`
|
|
1648
|
+
);
|
|
1649
|
+
return patientProfilesWithDetails;
|
|
1650
|
+
} catch (error) {
|
|
1651
|
+
console.error(
|
|
1652
|
+
`[getPatientsByPractitionerWithDetailsUtil] Error fetching detailed patient profiles:`,
|
|
1653
|
+
error
|
|
1654
|
+
);
|
|
1655
|
+
throw new Error(
|
|
1656
|
+
`Failed to retrieve detailed patient profiles: ${error instanceof Error ? error.message : String(error)}`
|
|
1657
|
+
);
|
|
1658
|
+
}
|
|
1659
|
+
};
|
|
1660
|
+
var getPractitionerProfileByUserRef = async (db, userRef) => {
|
|
1661
|
+
try {
|
|
1662
|
+
console.log(
|
|
1663
|
+
`[getPractitionerProfileByUserRef] Fetching practitioner with userRef: ${userRef}`
|
|
1664
|
+
);
|
|
1665
|
+
const practitionersCollection = collection2(db, PRACTITIONERS_COLLECTION);
|
|
1666
|
+
const q = query2(
|
|
1667
|
+
practitionersCollection,
|
|
1668
|
+
where2("userRef", "==", userRef),
|
|
1669
|
+
limit(1)
|
|
1670
|
+
);
|
|
1671
|
+
const querySnapshot = await getDocs2(q);
|
|
1672
|
+
if (querySnapshot.empty) {
|
|
1673
|
+
console.log(
|
|
1674
|
+
`[getPractitionerProfileByUserRef] No practitioner found with userRef: ${userRef}`
|
|
1675
|
+
);
|
|
1676
|
+
return null;
|
|
1677
|
+
}
|
|
1678
|
+
const practitionerDoc = querySnapshot.docs[0];
|
|
1679
|
+
const practitioner = practitionerDoc.data();
|
|
1680
|
+
console.log(
|
|
1681
|
+
`[getPractitionerProfileByUserRef] Successfully retrieved practitioner: ${practitioner.basicInfo.firstName} ${practitioner.basicInfo.lastName}`
|
|
1682
|
+
);
|
|
1683
|
+
return practitioner;
|
|
1684
|
+
} catch (error) {
|
|
1685
|
+
console.error(
|
|
1686
|
+
`[getPractitionerProfileByUserRef] Error fetching practitioner:`,
|
|
1687
|
+
error
|
|
1688
|
+
);
|
|
1689
|
+
throw new Error(
|
|
1690
|
+
`Failed to retrieve practitioner by userRef: ${error instanceof Error ? error.message : String(error)}`
|
|
1691
|
+
);
|
|
1692
|
+
}
|
|
1693
|
+
};
|
|
1694
|
+
|
|
1695
|
+
// src/services/patient/utils/medical.utils.ts
|
|
1534
1696
|
var ensureMedicalInfoExists = async (db, patientId, userRef) => {
|
|
1535
1697
|
console.log(
|
|
1536
1698
|
`[ensureMedicalInfoExists] Starting for patientId: ${patientId}, userRef: ${userRef}`
|
|
@@ -1540,7 +1702,7 @@ var ensureMedicalInfoExists = async (db, patientId, userRef) => {
|
|
|
1540
1702
|
console.log(
|
|
1541
1703
|
`[ensureMedicalInfoExists] Got document reference: ${medicalInfoRef.path}`
|
|
1542
1704
|
);
|
|
1543
|
-
const medicalInfoDoc = await
|
|
1705
|
+
const medicalInfoDoc = await getDoc4(medicalInfoRef);
|
|
1544
1706
|
console.log(
|
|
1545
1707
|
`[ensureMedicalInfoExists] Document exists: ${medicalInfoDoc.exists()}`
|
|
1546
1708
|
);
|
|
@@ -1560,7 +1722,7 @@ var ensureMedicalInfoExists = async (db, patientId, userRef) => {
|
|
|
1560
1722
|
);
|
|
1561
1723
|
await setDoc3(medicalInfoRef, defaultData);
|
|
1562
1724
|
console.log(`[ensureMedicalInfoExists] Document created successfully`);
|
|
1563
|
-
const verifyDoc = await
|
|
1725
|
+
const verifyDoc = await getDoc4(medicalInfoRef);
|
|
1564
1726
|
console.log(
|
|
1565
1727
|
`[ensureMedicalInfoExists] Verification - document exists: ${verifyDoc.exists()}`
|
|
1566
1728
|
);
|
|
@@ -1576,22 +1738,26 @@ var ensureMedicalInfoExists = async (db, patientId, userRef) => {
|
|
|
1576
1738
|
};
|
|
1577
1739
|
var checkMedicalAccessUtil = async (db, patientId, userRef, userRoles) => {
|
|
1578
1740
|
var _a;
|
|
1579
|
-
const patientDoc = await
|
|
1741
|
+
const patientDoc = await getDoc4(getPatientDocRef(db, patientId));
|
|
1580
1742
|
if (!patientDoc.exists()) {
|
|
1581
1743
|
throw new Error("Patient profile not found");
|
|
1582
1744
|
}
|
|
1583
1745
|
const patientData = patientDoc.data();
|
|
1584
1746
|
if (patientData.userRef === userRef) return;
|
|
1585
|
-
if (
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
403
|
|
1747
|
+
if (userRoles.includes("practitioner" /* PRACTITIONER */)) {
|
|
1748
|
+
const practitionerProfile = await getPractitionerProfileByUserRef(
|
|
1749
|
+
db,
|
|
1750
|
+
userRef
|
|
1590
1751
|
);
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1752
|
+
if (!practitionerProfile) {
|
|
1753
|
+
throw new AuthError(
|
|
1754
|
+
"Practitioner profile not found",
|
|
1755
|
+
"AUTH/UNAUTHORIZED_ACCESS",
|
|
1756
|
+
403
|
|
1757
|
+
);
|
|
1758
|
+
}
|
|
1759
|
+
const isAssignedDoctor = (_a = patientData.doctorIds) == null ? void 0 : _a.includes(
|
|
1760
|
+
practitionerProfile.id
|
|
1595
1761
|
);
|
|
1596
1762
|
if (!isAssignedDoctor) {
|
|
1597
1763
|
throw new AuthError(
|
|
@@ -1608,14 +1774,14 @@ var createMedicalInfoUtil = async (db, patientId, data, userRef, userRoles) => {
|
|
|
1608
1774
|
await setDoc3(getMedicalInfoDocRef(db, patientId), {
|
|
1609
1775
|
...validatedData,
|
|
1610
1776
|
patientId,
|
|
1611
|
-
lastUpdated:
|
|
1777
|
+
lastUpdated: Timestamp3.now(),
|
|
1612
1778
|
updatedBy: userRef
|
|
1613
1779
|
});
|
|
1614
1780
|
};
|
|
1615
1781
|
var getMedicalInfoUtil = async (db, patientId, userRef, userRoles) => {
|
|
1616
1782
|
await checkMedicalAccessUtil(db, patientId, userRef, userRoles);
|
|
1617
1783
|
const docRef = getMedicalInfoDocRef(db, patientId);
|
|
1618
|
-
const snapshot = await
|
|
1784
|
+
const snapshot = await getDoc4(docRef);
|
|
1619
1785
|
if (!snapshot.exists()) {
|
|
1620
1786
|
throw new Error("Medicinske informacije nisu prona\u0111ene");
|
|
1621
1787
|
}
|
|
@@ -1642,9 +1808,9 @@ var addAllergyUtil = async (db, patientId, data, userRef) => {
|
|
|
1642
1808
|
var updateAllergyUtil = async (db, patientId, data, userRef) => {
|
|
1643
1809
|
const validatedData = updateAllergySchema.parse(data);
|
|
1644
1810
|
const { allergyIndex, ...updateData } = validatedData;
|
|
1645
|
-
const
|
|
1646
|
-
if (!
|
|
1647
|
-
const medicalInfo =
|
|
1811
|
+
const docSnapshot = await getDoc4(getMedicalInfoDocRef(db, patientId));
|
|
1812
|
+
if (!docSnapshot.exists()) throw new Error("Medical info not found");
|
|
1813
|
+
const medicalInfo = patientMedicalInfoSchema.parse(docSnapshot.data());
|
|
1648
1814
|
if (allergyIndex >= medicalInfo.allergies.length) {
|
|
1649
1815
|
throw new Error("Invalid allergy index");
|
|
1650
1816
|
}
|
|
@@ -1660,7 +1826,7 @@ var updateAllergyUtil = async (db, patientId, data, userRef) => {
|
|
|
1660
1826
|
});
|
|
1661
1827
|
};
|
|
1662
1828
|
var removeAllergyUtil = async (db, patientId, allergyIndex, userRef) => {
|
|
1663
|
-
const doc33 = await
|
|
1829
|
+
const doc33 = await getDoc4(getMedicalInfoDocRef(db, patientId));
|
|
1664
1830
|
if (!doc33.exists()) throw new Error("Medical info not found");
|
|
1665
1831
|
const medicalInfo = doc33.data();
|
|
1666
1832
|
if (allergyIndex >= medicalInfo.allergies.length) {
|
|
@@ -1687,7 +1853,7 @@ var addBlockingConditionUtil = async (db, patientId, data, userRef) => {
|
|
|
1687
1853
|
var updateBlockingConditionUtil = async (db, patientId, data, userRef) => {
|
|
1688
1854
|
const validatedData = updateBlockingConditionSchema.parse(data);
|
|
1689
1855
|
const { conditionIndex, ...updateData } = validatedData;
|
|
1690
|
-
const doc33 = await
|
|
1856
|
+
const doc33 = await getDoc4(getMedicalInfoDocRef(db, patientId));
|
|
1691
1857
|
if (!doc33.exists()) throw new Error("Medical info not found");
|
|
1692
1858
|
const medicalInfo = doc33.data();
|
|
1693
1859
|
if (conditionIndex >= medicalInfo.blockingConditions.length) {
|
|
@@ -1705,7 +1871,7 @@ var updateBlockingConditionUtil = async (db, patientId, data, userRef) => {
|
|
|
1705
1871
|
});
|
|
1706
1872
|
};
|
|
1707
1873
|
var removeBlockingConditionUtil = async (db, patientId, conditionIndex, userRef) => {
|
|
1708
|
-
const doc33 = await
|
|
1874
|
+
const doc33 = await getDoc4(getMedicalInfoDocRef(db, patientId));
|
|
1709
1875
|
if (!doc33.exists()) throw new Error("Medical info not found");
|
|
1710
1876
|
const medicalInfo = doc33.data();
|
|
1711
1877
|
if (conditionIndex >= medicalInfo.blockingConditions.length) {
|
|
@@ -1732,7 +1898,7 @@ var addContraindicationUtil = async (db, patientId, data, userRef) => {
|
|
|
1732
1898
|
var updateContraindicationUtil = async (db, patientId, data, userRef) => {
|
|
1733
1899
|
const validatedData = updateContraindicationSchema.parse(data);
|
|
1734
1900
|
const { contraindicationIndex, ...updateData } = validatedData;
|
|
1735
|
-
const doc33 = await
|
|
1901
|
+
const doc33 = await getDoc4(getMedicalInfoDocRef(db, patientId));
|
|
1736
1902
|
if (!doc33.exists()) throw new Error("Medical info not found");
|
|
1737
1903
|
const medicalInfo = doc33.data();
|
|
1738
1904
|
if (contraindicationIndex >= medicalInfo.contraindications.length) {
|
|
@@ -1750,7 +1916,7 @@ var updateContraindicationUtil = async (db, patientId, data, userRef) => {
|
|
|
1750
1916
|
});
|
|
1751
1917
|
};
|
|
1752
1918
|
var removeContraindicationUtil = async (db, patientId, contraindicationIndex, userRef) => {
|
|
1753
|
-
const doc33 = await
|
|
1919
|
+
const doc33 = await getDoc4(getMedicalInfoDocRef(db, patientId));
|
|
1754
1920
|
if (!doc33.exists()) throw new Error("Medical info not found");
|
|
1755
1921
|
const medicalInfo = doc33.data();
|
|
1756
1922
|
if (contraindicationIndex >= medicalInfo.contraindications.length) {
|
|
@@ -1777,7 +1943,7 @@ var addMedicationUtil = async (db, patientId, data, userRef) => {
|
|
|
1777
1943
|
var updateMedicationUtil = async (db, patientId, data, userRef) => {
|
|
1778
1944
|
const validatedData = updateMedicationSchema.parse(data);
|
|
1779
1945
|
const { medicationIndex, ...updateData } = validatedData;
|
|
1780
|
-
const doc33 = await
|
|
1946
|
+
const doc33 = await getDoc4(getMedicalInfoDocRef(db, patientId));
|
|
1781
1947
|
if (!doc33.exists()) throw new Error("Medical info not found");
|
|
1782
1948
|
const medicalInfo = doc33.data();
|
|
1783
1949
|
if (medicationIndex >= medicalInfo.currentMedications.length) {
|
|
@@ -1795,7 +1961,7 @@ var updateMedicationUtil = async (db, patientId, data, userRef) => {
|
|
|
1795
1961
|
});
|
|
1796
1962
|
};
|
|
1797
1963
|
var removeMedicationUtil = async (db, patientId, medicationIndex, userRef) => {
|
|
1798
|
-
const doc33 = await
|
|
1964
|
+
const doc33 = await getDoc4(getMedicalInfoDocRef(db, patientId));
|
|
1799
1965
|
if (!doc33.exists()) throw new Error("Medical info not found");
|
|
1800
1966
|
const medicalInfo = doc33.data();
|
|
1801
1967
|
if (medicationIndex >= medicalInfo.currentMedications.length) {
|
|
@@ -1840,8 +2006,8 @@ var createPatientProfileUtil = async (db, data, generateId2) => {
|
|
|
1840
2006
|
};
|
|
1841
2007
|
patientProfileSchema.parse({
|
|
1842
2008
|
...patientData,
|
|
1843
|
-
createdAt:
|
|
1844
|
-
updatedAt:
|
|
2009
|
+
createdAt: Timestamp4.now(),
|
|
2010
|
+
updatedAt: Timestamp4.now()
|
|
1845
2011
|
});
|
|
1846
2012
|
await setDoc4(getPatientDocRef(db, patientId), patientData);
|
|
1847
2013
|
console.log(`[createPatientProfileUtil] Creating sensitive info document`);
|
|
@@ -1878,7 +2044,7 @@ var createPatientProfileUtil = async (db, data, generateId2) => {
|
|
|
1878
2044
|
}
|
|
1879
2045
|
}
|
|
1880
2046
|
console.log(`[createPatientProfileUtil] Verifying patient document exists`);
|
|
1881
|
-
const patientDoc = await
|
|
2047
|
+
const patientDoc = await getDoc5(getPatientDocRef(db, patientId));
|
|
1882
2048
|
if (!patientDoc.exists()) {
|
|
1883
2049
|
console.error(`[createPatientProfileUtil] Patient document not found after creation`);
|
|
1884
2050
|
throw new Error("Failed to create patient profile");
|
|
@@ -1894,13 +2060,13 @@ var createPatientProfileUtil = async (db, data, generateId2) => {
|
|
|
1894
2060
|
}
|
|
1895
2061
|
};
|
|
1896
2062
|
var getPatientProfileUtil = async (db, patientId) => {
|
|
1897
|
-
const patientDoc = await
|
|
2063
|
+
const patientDoc = await getDoc5(getPatientDocRef(db, patientId));
|
|
1898
2064
|
return patientDoc.exists() ? patientDoc.data() : null;
|
|
1899
2065
|
};
|
|
1900
2066
|
var getPatientProfileByUserRefUtil = async (db, userRef) => {
|
|
1901
2067
|
try {
|
|
1902
2068
|
const docRef = await getPatientDocRefByUserRef(db, userRef);
|
|
1903
|
-
const patientDoc = await
|
|
2069
|
+
const patientDoc = await getDoc5(docRef);
|
|
1904
2070
|
return patientDoc.exists() ? patientDoc.data() : null;
|
|
1905
2071
|
} catch (error) {
|
|
1906
2072
|
return null;
|
|
@@ -1931,7 +2097,7 @@ var updatePatientProfileUtil = async (db, patientId, data) => {
|
|
|
1931
2097
|
updatedAt: serverTimestamp4()
|
|
1932
2098
|
};
|
|
1933
2099
|
await updateDoc3(getPatientDocRef(db, patientId), updateData);
|
|
1934
|
-
const updatedDoc = await
|
|
2100
|
+
const updatedDoc = await getDoc5(getPatientDocRef(db, patientId));
|
|
1935
2101
|
if (!updatedDoc.exists()) {
|
|
1936
2102
|
throw new Error("Patient profile not found after update");
|
|
1937
2103
|
}
|
|
@@ -1944,7 +2110,7 @@ var updatePatientProfileUtil = async (db, patientId, data) => {
|
|
|
1944
2110
|
var updatePatientProfileByUserRefUtil = async (db, userRef, data) => {
|
|
1945
2111
|
try {
|
|
1946
2112
|
const docRef = await getPatientDocRefByUserRef(db, userRef);
|
|
1947
|
-
const patientDoc = await
|
|
2113
|
+
const patientDoc = await getDoc5(docRef);
|
|
1948
2114
|
if (!patientDoc.exists()) {
|
|
1949
2115
|
throw new Error("Patient profile not found");
|
|
1950
2116
|
}
|
|
@@ -1961,7 +2127,7 @@ var uploadProfilePhotoUtil = async (storage, patientId, file) => {
|
|
|
1961
2127
|
return getDownloadURL(photoRef);
|
|
1962
2128
|
};
|
|
1963
2129
|
var updateProfilePhotoUtil = async (storage, db, patientId, file) => {
|
|
1964
|
-
const patientDoc = await
|
|
2130
|
+
const patientDoc = await getDoc5(getPatientDocRef(db, patientId));
|
|
1965
2131
|
if (!patientDoc.exists()) throw new Error("Patient profile not found");
|
|
1966
2132
|
const patientData = patientDoc.data();
|
|
1967
2133
|
if (patientData.profilePhoto) {
|
|
@@ -1980,7 +2146,7 @@ var updateProfilePhotoUtil = async (storage, db, patientId, file) => {
|
|
|
1980
2146
|
return newPhotoUrl;
|
|
1981
2147
|
};
|
|
1982
2148
|
var deleteProfilePhotoUtil = async (storage, db, patientId) => {
|
|
1983
|
-
const patientDoc = await
|
|
2149
|
+
const patientDoc = await getDoc5(getPatientDocRef(db, patientId));
|
|
1984
2150
|
if (!patientDoc.exists()) throw new Error("Patient profile not found");
|
|
1985
2151
|
const patientData = patientDoc.data();
|
|
1986
2152
|
if (patientData.profilePhoto) {
|
|
@@ -2010,12 +2176,12 @@ var testCreateSubDocuments = async (db, patientId, userRef) => {
|
|
|
2010
2176
|
photoUrl: "",
|
|
2011
2177
|
firstName: "Name",
|
|
2012
2178
|
lastName: "Surname",
|
|
2013
|
-
dateOfBirth:
|
|
2179
|
+
dateOfBirth: Timestamp4.now(),
|
|
2014
2180
|
gender: "prefer_not_to_say" /* PREFER_NOT_TO_SAY */,
|
|
2015
2181
|
email: "test@example.com",
|
|
2016
2182
|
phoneNumber: "",
|
|
2017
|
-
createdAt:
|
|
2018
|
-
updatedAt:
|
|
2183
|
+
createdAt: Timestamp4.now(),
|
|
2184
|
+
updatedAt: Timestamp4.now()
|
|
2019
2185
|
};
|
|
2020
2186
|
await setDoc4(sensitiveInfoRef, defaultSensitiveInfo);
|
|
2021
2187
|
console.log(`[testCreateSubDocuments] Sensitive info document created directly`);
|
|
@@ -2025,7 +2191,7 @@ var testCreateSubDocuments = async (db, patientId, userRef) => {
|
|
|
2025
2191
|
const defaultMedicalInfo = {
|
|
2026
2192
|
...DEFAULT_MEDICAL_INFO,
|
|
2027
2193
|
patientId,
|
|
2028
|
-
lastUpdated:
|
|
2194
|
+
lastUpdated: Timestamp4.now(),
|
|
2029
2195
|
updatedBy: userRef
|
|
2030
2196
|
};
|
|
2031
2197
|
await setDoc4(medicalInfoRef, defaultMedicalInfo);
|
|
@@ -2040,7 +2206,7 @@ var searchPatientsUtil = async (db, params, requester) => {
|
|
|
2040
2206
|
searchPatientsSchema.parse(params);
|
|
2041
2207
|
requesterInfoSchema.parse(requester);
|
|
2042
2208
|
const constraints = [];
|
|
2043
|
-
const patientsCollectionRef =
|
|
2209
|
+
const patientsCollectionRef = collection3(db, PATIENTS_COLLECTION);
|
|
2044
2210
|
if (requester.role === "clinic_admin") {
|
|
2045
2211
|
if (!requester.associatedClinicId) {
|
|
2046
2212
|
throw new Error("Associated clinic ID is required for clinic admin search.");
|
|
@@ -2051,9 +2217,9 @@ var searchPatientsUtil = async (db, params, requester) => {
|
|
|
2051
2217
|
);
|
|
2052
2218
|
return [];
|
|
2053
2219
|
}
|
|
2054
|
-
constraints.push(
|
|
2220
|
+
constraints.push(where3("clinicIds", "array-contains", requester.associatedClinicId));
|
|
2055
2221
|
if (params.practitionerId) {
|
|
2056
|
-
constraints.push(
|
|
2222
|
+
constraints.push(where3("doctorIds", "array-contains", params.practitionerId));
|
|
2057
2223
|
}
|
|
2058
2224
|
} else if (requester.role === "practitioner") {
|
|
2059
2225
|
if (!requester.associatedPractitionerId) {
|
|
@@ -2065,16 +2231,16 @@ var searchPatientsUtil = async (db, params, requester) => {
|
|
|
2065
2231
|
);
|
|
2066
2232
|
return [];
|
|
2067
2233
|
}
|
|
2068
|
-
constraints.push(
|
|
2234
|
+
constraints.push(where3("doctorIds", "array-contains", requester.associatedPractitionerId));
|
|
2069
2235
|
if (params.clinicId) {
|
|
2070
|
-
constraints.push(
|
|
2236
|
+
constraints.push(where3("clinicIds", "array-contains", params.clinicId));
|
|
2071
2237
|
}
|
|
2072
2238
|
} else {
|
|
2073
2239
|
throw new Error("Invalid requester role.");
|
|
2074
2240
|
}
|
|
2075
2241
|
try {
|
|
2076
|
-
const finalQuery =
|
|
2077
|
-
const querySnapshot = await
|
|
2242
|
+
const finalQuery = query3(patientsCollectionRef, ...constraints);
|
|
2243
|
+
const querySnapshot = await getDocs3(finalQuery);
|
|
2078
2244
|
const patients = querySnapshot.docs.map((doc33) => doc33.data());
|
|
2079
2245
|
console.log(`[searchPatientsUtil] Found ${patients.length} patients matching criteria.`);
|
|
2080
2246
|
return patients;
|
|
@@ -2086,18 +2252,18 @@ var searchPatientsUtil = async (db, params, requester) => {
|
|
|
2086
2252
|
var getAllPatientsUtil = async (db, options) => {
|
|
2087
2253
|
try {
|
|
2088
2254
|
console.log(`[getAllPatientsUtil] Fetching patients with options:`, options);
|
|
2089
|
-
const patientsCollection =
|
|
2090
|
-
let q =
|
|
2255
|
+
const patientsCollection = collection3(db, PATIENTS_COLLECTION);
|
|
2256
|
+
let q = query3(patientsCollection);
|
|
2091
2257
|
if (options == null ? void 0 : options.limit) {
|
|
2092
|
-
q =
|
|
2258
|
+
q = query3(q, limit2(options.limit));
|
|
2093
2259
|
}
|
|
2094
2260
|
if (options == null ? void 0 : options.startAfter) {
|
|
2095
|
-
const startAfterDoc = await
|
|
2261
|
+
const startAfterDoc = await getDoc5(doc4(db, PATIENTS_COLLECTION, options.startAfter));
|
|
2096
2262
|
if (startAfterDoc.exists()) {
|
|
2097
|
-
q =
|
|
2263
|
+
q = query3(q, startAfter2(startAfterDoc));
|
|
2098
2264
|
}
|
|
2099
2265
|
}
|
|
2100
|
-
const patientsSnapshot = await
|
|
2266
|
+
const patientsSnapshot = await getDocs3(q);
|
|
2101
2267
|
const patients = [];
|
|
2102
2268
|
patientsSnapshot.forEach((doc33) => {
|
|
2103
2269
|
patients.push(doc33.data());
|
|
@@ -2114,7 +2280,7 @@ var getAllPatientsUtil = async (db, options) => {
|
|
|
2114
2280
|
|
|
2115
2281
|
// src/services/patient/utils/location.utils.ts
|
|
2116
2282
|
import {
|
|
2117
|
-
getDoc as
|
|
2283
|
+
getDoc as getDoc6,
|
|
2118
2284
|
updateDoc as updateDoc4,
|
|
2119
2285
|
setDoc as setDoc5,
|
|
2120
2286
|
serverTimestamp as serverTimestamp5
|
|
@@ -2152,7 +2318,7 @@ var createLocationInfoUtil = async (db, data, requesterId) => {
|
|
|
2152
2318
|
updatedAt: serverTimestamp5()
|
|
2153
2319
|
};
|
|
2154
2320
|
await setDoc5(getLocationInfoDocRef(db, data.patientId), locationData);
|
|
2155
|
-
const locationDoc = await
|
|
2321
|
+
const locationDoc = await getDoc6(getLocationInfoDocRef(db, data.patientId));
|
|
2156
2322
|
if (!locationDoc.exists()) {
|
|
2157
2323
|
throw new Error("Failed to create location information");
|
|
2158
2324
|
}
|
|
@@ -2168,7 +2334,7 @@ var getLocationInfoUtil = async (db, patientId, requesterId) => {
|
|
|
2168
2334
|
if (patientId !== requesterId) {
|
|
2169
2335
|
throw new Error("Unauthorized access to location information");
|
|
2170
2336
|
}
|
|
2171
|
-
const locationDoc = await
|
|
2337
|
+
const locationDoc = await getDoc6(getLocationInfoDocRef(db, patientId));
|
|
2172
2338
|
return locationDoc.exists() ? locationDoc.data() : null;
|
|
2173
2339
|
};
|
|
2174
2340
|
var updateLocationInfoUtil = async (db, patientId, data, requesterId) => {
|
|
@@ -2196,22 +2362,22 @@ var updateLocationInfoUtil = async (db, patientId, data, requesterId) => {
|
|
|
2196
2362
|
|
|
2197
2363
|
// src/services/patient/utils/medical-stuff.utils.ts
|
|
2198
2364
|
import {
|
|
2199
|
-
getDoc as
|
|
2365
|
+
getDoc as getDoc7,
|
|
2200
2366
|
updateDoc as updateDoc5,
|
|
2201
2367
|
arrayUnion as arrayUnion3,
|
|
2202
2368
|
arrayRemove as arrayRemove3,
|
|
2203
2369
|
serverTimestamp as serverTimestamp6,
|
|
2204
|
-
Timestamp as
|
|
2370
|
+
Timestamp as Timestamp5
|
|
2205
2371
|
} from "firebase/firestore";
|
|
2206
2372
|
var addDoctorUtil = async (db, patientId, doctorRef, assignedBy) => {
|
|
2207
2373
|
var _a;
|
|
2208
2374
|
const newDoctor = {
|
|
2209
2375
|
userRef: doctorRef,
|
|
2210
|
-
assignedAt:
|
|
2376
|
+
assignedAt: Timestamp5.now(),
|
|
2211
2377
|
assignedBy,
|
|
2212
2378
|
isActive: true
|
|
2213
2379
|
};
|
|
2214
|
-
const patientDoc = await
|
|
2380
|
+
const patientDoc = await getDoc7(getPatientDocRef(db, patientId));
|
|
2215
2381
|
if (!patientDoc.exists()) throw new Error("Patient profile not found");
|
|
2216
2382
|
const patientData = patientDoc.data();
|
|
2217
2383
|
const existingDoctorIndex = (_a = patientData.doctors) == null ? void 0 : _a.findIndex(
|
|
@@ -2226,7 +2392,7 @@ var addDoctorUtil = async (db, patientId, doctorRef, assignedBy) => {
|
|
|
2226
2392
|
updatedDoctors[existingDoctorIndex] = {
|
|
2227
2393
|
...updatedDoctors[existingDoctorIndex],
|
|
2228
2394
|
isActive: true,
|
|
2229
|
-
assignedAt:
|
|
2395
|
+
assignedAt: Timestamp5.now(),
|
|
2230
2396
|
assignedBy
|
|
2231
2397
|
};
|
|
2232
2398
|
updates.doctors = updatedDoctors;
|
|
@@ -2238,7 +2404,7 @@ var addDoctorUtil = async (db, patientId, doctorRef, assignedBy) => {
|
|
|
2238
2404
|
var removeDoctorUtil = async (db, patientId, doctorRef) => {
|
|
2239
2405
|
var _a;
|
|
2240
2406
|
const patientDocRef = getPatientDocRef(db, patientId);
|
|
2241
|
-
const patientDoc = await
|
|
2407
|
+
const patientDoc = await getDoc7(patientDocRef);
|
|
2242
2408
|
if (!patientDoc.exists()) throw new Error("Patient profile not found");
|
|
2243
2409
|
const patientData = patientDoc.data();
|
|
2244
2410
|
const updatedDoctors = ((_a = patientData.doctors) == null ? void 0 : _a.filter((doctor) => doctor.userRef !== doctorRef)) || [];
|
|
@@ -2254,11 +2420,11 @@ var addClinicUtil = async (db, patientId, clinicId, assignedBy) => {
|
|
|
2254
2420
|
var _a;
|
|
2255
2421
|
const newClinic = {
|
|
2256
2422
|
clinicId,
|
|
2257
|
-
assignedAt:
|
|
2423
|
+
assignedAt: Timestamp5.now(),
|
|
2258
2424
|
assignedBy,
|
|
2259
2425
|
isActive: true
|
|
2260
2426
|
};
|
|
2261
|
-
const patientDoc = await
|
|
2427
|
+
const patientDoc = await getDoc7(getPatientDocRef(db, patientId));
|
|
2262
2428
|
if (!patientDoc.exists()) throw new Error("Patient profile not found");
|
|
2263
2429
|
const patientData = patientDoc.data();
|
|
2264
2430
|
const existingClinicIndex = (_a = patientData.clinics) == null ? void 0 : _a.findIndex(
|
|
@@ -2273,7 +2439,7 @@ var addClinicUtil = async (db, patientId, clinicId, assignedBy) => {
|
|
|
2273
2439
|
updatedClinics[existingClinicIndex] = {
|
|
2274
2440
|
...updatedClinics[existingClinicIndex],
|
|
2275
2441
|
isActive: true,
|
|
2276
|
-
assignedAt:
|
|
2442
|
+
assignedAt: Timestamp5.now(),
|
|
2277
2443
|
assignedBy
|
|
2278
2444
|
};
|
|
2279
2445
|
updates.clinics = updatedClinics;
|
|
@@ -2285,7 +2451,7 @@ var addClinicUtil = async (db, patientId, clinicId, assignedBy) => {
|
|
|
2285
2451
|
var removeClinicUtil = async (db, patientId, clinicId) => {
|
|
2286
2452
|
var _a;
|
|
2287
2453
|
const patientDocRef = getPatientDocRef(db, patientId);
|
|
2288
|
-
const patientDoc = await
|
|
2454
|
+
const patientDoc = await getDoc7(patientDocRef);
|
|
2289
2455
|
if (!patientDoc.exists()) throw new Error("Patient profile not found");
|
|
2290
2456
|
const patientData = patientDoc.data();
|
|
2291
2457
|
const updatedClinics = ((_a = patientData.clinics) == null ? void 0 : _a.filter((clinic) => clinic.clinicId !== clinicId)) || [];
|
|
@@ -2298,104 +2464,6 @@ var removeClinicUtil = async (db, patientId, clinicId) => {
|
|
|
2298
2464
|
});
|
|
2299
2465
|
};
|
|
2300
2466
|
|
|
2301
|
-
// src/services/patient/utils/practitioner.utils.ts
|
|
2302
|
-
import {
|
|
2303
|
-
collection as collection3,
|
|
2304
|
-
query as query3,
|
|
2305
|
-
where as where3,
|
|
2306
|
-
getDocs as getDocs3,
|
|
2307
|
-
limit as limit2,
|
|
2308
|
-
startAfter as startAfter2,
|
|
2309
|
-
doc as doc4,
|
|
2310
|
-
getDoc as getDoc7
|
|
2311
|
-
} from "firebase/firestore";
|
|
2312
|
-
var getPatientsByPractitionerUtil = async (db, practitionerId, options) => {
|
|
2313
|
-
try {
|
|
2314
|
-
console.log(
|
|
2315
|
-
`[getPatientsByPractitionerUtil] Fetching patients for practitioner ID: ${practitionerId} with options:`,
|
|
2316
|
-
options
|
|
2317
|
-
);
|
|
2318
|
-
const patientsCollection = collection3(db, PATIENTS_COLLECTION);
|
|
2319
|
-
const constraints = [
|
|
2320
|
-
where3("doctorIds", "array-contains", practitionerId)
|
|
2321
|
-
];
|
|
2322
|
-
let q = query3(patientsCollection, ...constraints);
|
|
2323
|
-
if (options == null ? void 0 : options.limit) {
|
|
2324
|
-
q = query3(q, limit2(options.limit));
|
|
2325
|
-
}
|
|
2326
|
-
if (options == null ? void 0 : options.startAfter) {
|
|
2327
|
-
const startAfterDoc = await getDoc7(
|
|
2328
|
-
doc4(db, PATIENTS_COLLECTION, options.startAfter)
|
|
2329
|
-
);
|
|
2330
|
-
if (startAfterDoc.exists()) {
|
|
2331
|
-
q = query3(q, startAfter2(startAfterDoc));
|
|
2332
|
-
}
|
|
2333
|
-
}
|
|
2334
|
-
const patientsSnapshot = await getDocs3(q);
|
|
2335
|
-
const patients = [];
|
|
2336
|
-
patientsSnapshot.forEach((doc33) => {
|
|
2337
|
-
patients.push(doc33.data());
|
|
2338
|
-
});
|
|
2339
|
-
console.log(
|
|
2340
|
-
`[getPatientsByPractitionerUtil] Found ${patients.length} patients for practitioner ID: ${practitionerId}`
|
|
2341
|
-
);
|
|
2342
|
-
return patients;
|
|
2343
|
-
} catch (error) {
|
|
2344
|
-
console.error(
|
|
2345
|
-
`[getPatientsByPractitionerUtil] Error fetching patients for practitioner:`,
|
|
2346
|
-
error
|
|
2347
|
-
);
|
|
2348
|
-
throw new Error(
|
|
2349
|
-
`Failed to retrieve patients for practitioner: ${error instanceof Error ? error.message : String(error)}`
|
|
2350
|
-
);
|
|
2351
|
-
}
|
|
2352
|
-
};
|
|
2353
|
-
var getPatientsByPractitionerWithDetailsUtil = async (db, practitionerId, options) => {
|
|
2354
|
-
try {
|
|
2355
|
-
console.log(
|
|
2356
|
-
`[getPatientsByPractitionerWithDetailsUtil] Fetching detailed patient profiles for practitioner ID: ${practitionerId} with options:`,
|
|
2357
|
-
options
|
|
2358
|
-
);
|
|
2359
|
-
const patientProfiles = await getPatientsByPractitionerUtil(
|
|
2360
|
-
db,
|
|
2361
|
-
practitionerId,
|
|
2362
|
-
options
|
|
2363
|
-
);
|
|
2364
|
-
const patientProfilesWithDetails = await Promise.all(
|
|
2365
|
-
patientProfiles.map(async (profile) => {
|
|
2366
|
-
try {
|
|
2367
|
-
const sensitiveInfoDoc = await getDoc7(
|
|
2368
|
-
getSensitiveInfoDocRef(db, profile.id)
|
|
2369
|
-
);
|
|
2370
|
-
const sensitiveInfo = sensitiveInfoDoc.exists() ? sensitiveInfoDoc.data() : void 0;
|
|
2371
|
-
return {
|
|
2372
|
-
patientProfile: profile,
|
|
2373
|
-
patientSensitiveInfo: sensitiveInfo
|
|
2374
|
-
};
|
|
2375
|
-
} catch (error) {
|
|
2376
|
-
console.error(
|
|
2377
|
-
`[getPatientsByPractitionerWithDetailsUtil] Error fetching sensitive info for patient ${profile.id}:`,
|
|
2378
|
-
error
|
|
2379
|
-
);
|
|
2380
|
-
return { patientProfile: profile };
|
|
2381
|
-
}
|
|
2382
|
-
})
|
|
2383
|
-
);
|
|
2384
|
-
console.log(
|
|
2385
|
-
`[getPatientsByPractitionerWithDetailsUtil] Found ${patientProfilesWithDetails.length} detailed patient profiles for practitioner ID: ${practitionerId}`
|
|
2386
|
-
);
|
|
2387
|
-
return patientProfilesWithDetails;
|
|
2388
|
-
} catch (error) {
|
|
2389
|
-
console.error(
|
|
2390
|
-
`[getPatientsByPractitionerWithDetailsUtil] Error fetching detailed patient profiles:`,
|
|
2391
|
-
error
|
|
2392
|
-
);
|
|
2393
|
-
throw new Error(
|
|
2394
|
-
`Failed to retrieve detailed patient profiles: ${error instanceof Error ? error.message : String(error)}`
|
|
2395
|
-
);
|
|
2396
|
-
}
|
|
2397
|
-
};
|
|
2398
|
-
|
|
2399
2467
|
// src/services/patient/utils/clinic.utils.ts
|
|
2400
2468
|
import {
|
|
2401
2469
|
collection as collection4,
|
|
@@ -2779,7 +2847,7 @@ import {
|
|
|
2779
2847
|
updateDoc as updateDoc7,
|
|
2780
2848
|
setDoc as setDoc6,
|
|
2781
2849
|
deleteDoc,
|
|
2782
|
-
Timestamp as
|
|
2850
|
+
Timestamp as Timestamp7,
|
|
2783
2851
|
serverTimestamp as serverTimestamp8
|
|
2784
2852
|
} from "firebase/firestore";
|
|
2785
2853
|
|
|
@@ -2908,7 +2976,7 @@ var SubscriptionModel = /* @__PURE__ */ ((SubscriptionModel2) => {
|
|
|
2908
2976
|
|
|
2909
2977
|
// src/validations/clinic.schema.ts
|
|
2910
2978
|
import { z as z12 } from "zod";
|
|
2911
|
-
import { Timestamp as
|
|
2979
|
+
import { Timestamp as Timestamp6 } from "firebase/firestore";
|
|
2912
2980
|
|
|
2913
2981
|
// src/validations/reviews.schema.ts
|
|
2914
2982
|
import { z as z10 } from "zod";
|
|
@@ -3183,8 +3251,8 @@ var clinicAdminSchema = z12.object({
|
|
|
3183
3251
|
clinicsManagedInfo: z12.array(clinicInfoSchema),
|
|
3184
3252
|
contactInfo: contactPersonSchema,
|
|
3185
3253
|
roleTitle: z12.string(),
|
|
3186
|
-
createdAt: z12.instanceof(Date).or(z12.instanceof(
|
|
3187
|
-
updatedAt: z12.instanceof(Date).or(z12.instanceof(
|
|
3254
|
+
createdAt: z12.instanceof(Date).or(z12.instanceof(Timestamp6)),
|
|
3255
|
+
updatedAt: z12.instanceof(Date).or(z12.instanceof(Timestamp6)),
|
|
3188
3256
|
isActive: z12.boolean()
|
|
3189
3257
|
});
|
|
3190
3258
|
var adminTokenSchema = z12.object({
|
|
@@ -3193,9 +3261,9 @@ var adminTokenSchema = z12.object({
|
|
|
3193
3261
|
email: z12.string().email().optional().nullable(),
|
|
3194
3262
|
status: z12.nativeEnum(AdminTokenStatus),
|
|
3195
3263
|
usedByUserRef: z12.string().optional(),
|
|
3196
|
-
createdAt: z12.instanceof(Date).or(z12.instanceof(
|
|
3264
|
+
createdAt: z12.instanceof(Date).or(z12.instanceof(Timestamp6)),
|
|
3197
3265
|
// Timestamp
|
|
3198
|
-
expiresAt: z12.instanceof(Date).or(z12.instanceof(
|
|
3266
|
+
expiresAt: z12.instanceof(Date).or(z12.instanceof(Timestamp6))
|
|
3199
3267
|
// Timestamp
|
|
3200
3268
|
});
|
|
3201
3269
|
var createAdminTokenSchema = z12.object({
|
|
@@ -3215,9 +3283,9 @@ var clinicGroupSchema = z12.object({
|
|
|
3215
3283
|
adminsInfo: z12.array(adminInfoSchema),
|
|
3216
3284
|
adminTokens: z12.array(adminTokenSchema),
|
|
3217
3285
|
ownerId: z12.string().nullable(),
|
|
3218
|
-
createdAt: z12.instanceof(Date).or(z12.instanceof(
|
|
3286
|
+
createdAt: z12.instanceof(Date).or(z12.instanceof(Timestamp6)),
|
|
3219
3287
|
// Timestamp
|
|
3220
|
-
updatedAt: z12.instanceof(Date).or(z12.instanceof(
|
|
3288
|
+
updatedAt: z12.instanceof(Date).or(z12.instanceof(Timestamp6)),
|
|
3221
3289
|
// Timestamp
|
|
3222
3290
|
isActive: z12.boolean(),
|
|
3223
3291
|
logo: z12.string().optional().nullable(),
|
|
@@ -3257,9 +3325,9 @@ var clinicSchema = z12.object({
|
|
|
3257
3325
|
// servicesInfo: z.array(serviceInfoSchema), // Deprecated, use proceduresInfo
|
|
3258
3326
|
reviewInfo: clinicReviewInfoSchema,
|
|
3259
3327
|
admins: z12.array(z12.string()),
|
|
3260
|
-
createdAt: z12.instanceof(Date).or(z12.instanceof(
|
|
3328
|
+
createdAt: z12.instanceof(Date).or(z12.instanceof(Timestamp6)),
|
|
3261
3329
|
// Timestamp
|
|
3262
|
-
updatedAt: z12.instanceof(Date).or(z12.instanceof(
|
|
3330
|
+
updatedAt: z12.instanceof(Date).or(z12.instanceof(Timestamp6)),
|
|
3263
3331
|
// Timestamp
|
|
3264
3332
|
isActive: z12.boolean(),
|
|
3265
3333
|
isVerified: z12.boolean(),
|
|
@@ -3469,8 +3537,8 @@ async function createClinicAdmin(db, data, clinicGroupService) {
|
|
|
3469
3537
|
try {
|
|
3470
3538
|
clinicAdminSchema.parse({
|
|
3471
3539
|
...adminData,
|
|
3472
|
-
createdAt:
|
|
3473
|
-
updatedAt:
|
|
3540
|
+
createdAt: Timestamp7.now(),
|
|
3541
|
+
updatedAt: Timestamp7.now()
|
|
3474
3542
|
});
|
|
3475
3543
|
console.log("[CLINIC_ADMIN] Admin object validation passed");
|
|
3476
3544
|
} catch (schemaError) {
|
|
@@ -3833,7 +3901,7 @@ import {
|
|
|
3833
3901
|
updateDoc as updateDoc8,
|
|
3834
3902
|
setDoc as setDoc7,
|
|
3835
3903
|
deleteDoc as deleteDoc2,
|
|
3836
|
-
Timestamp as
|
|
3904
|
+
Timestamp as Timestamp9,
|
|
3837
3905
|
serverTimestamp as serverTimestamp9,
|
|
3838
3906
|
limit as limit4,
|
|
3839
3907
|
startAfter as startAfter4,
|
|
@@ -3842,25 +3910,9 @@ import {
|
|
|
3842
3910
|
arrayRemove as arrayRemove4
|
|
3843
3911
|
} from "firebase/firestore";
|
|
3844
3912
|
|
|
3845
|
-
// src/types/practitioner/index.ts
|
|
3846
|
-
var PRACTITIONERS_COLLECTION = "practitioners";
|
|
3847
|
-
var REGISTER_TOKENS_COLLECTION = "register_tokens";
|
|
3848
|
-
var PractitionerStatus = /* @__PURE__ */ ((PractitionerStatus2) => {
|
|
3849
|
-
PractitionerStatus2["DRAFT"] = "draft";
|
|
3850
|
-
PractitionerStatus2["ACTIVE"] = "active";
|
|
3851
|
-
return PractitionerStatus2;
|
|
3852
|
-
})(PractitionerStatus || {});
|
|
3853
|
-
var PractitionerTokenStatus = /* @__PURE__ */ ((PractitionerTokenStatus2) => {
|
|
3854
|
-
PractitionerTokenStatus2["ACTIVE"] = "active";
|
|
3855
|
-
PractitionerTokenStatus2["USED"] = "used";
|
|
3856
|
-
PractitionerTokenStatus2["EXPIRED"] = "expired";
|
|
3857
|
-
PractitionerTokenStatus2["REVOKED"] = "revoked";
|
|
3858
|
-
return PractitionerTokenStatus2;
|
|
3859
|
-
})(PractitionerTokenStatus || {});
|
|
3860
|
-
|
|
3861
3913
|
// src/validations/practitioner.schema.ts
|
|
3862
3914
|
import { z as z13 } from "zod";
|
|
3863
|
-
import { Timestamp as
|
|
3915
|
+
import { Timestamp as Timestamp8 } from "firebase/firestore";
|
|
3864
3916
|
|
|
3865
3917
|
// src/backoffice/types/static/certification.types.ts
|
|
3866
3918
|
var CertificationLevel = /* @__PURE__ */ ((CertificationLevel2) => {
|
|
@@ -3893,7 +3945,7 @@ var practitionerBasicInfoSchema = z13.object({
|
|
|
3893
3945
|
title: z13.string().min(2).max(100),
|
|
3894
3946
|
email: z13.string().email(),
|
|
3895
3947
|
phoneNumber: z13.string().regex(/^\+?[1-9]\d{1,14}$/, "Invalid phone number"),
|
|
3896
|
-
dateOfBirth: z13.instanceof(
|
|
3948
|
+
dateOfBirth: z13.instanceof(Timestamp8).or(z13.date()),
|
|
3897
3949
|
gender: z13.enum(["male", "female", "other"]),
|
|
3898
3950
|
profileImageUrl: z13.string().url().optional(),
|
|
3899
3951
|
bio: z13.string().max(1e3).optional(),
|
|
@@ -3904,8 +3956,8 @@ var practitionerCertificationSchema = z13.object({
|
|
|
3904
3956
|
specialties: z13.array(z13.nativeEnum(CertificationSpecialty)),
|
|
3905
3957
|
licenseNumber: z13.string().min(3).max(50),
|
|
3906
3958
|
issuingAuthority: z13.string().min(2).max(100),
|
|
3907
|
-
issueDate: z13.instanceof(
|
|
3908
|
-
expiryDate: z13.instanceof(
|
|
3959
|
+
issueDate: z13.instanceof(Timestamp8).or(z13.date()),
|
|
3960
|
+
expiryDate: z13.instanceof(Timestamp8).or(z13.date()).optional(),
|
|
3909
3961
|
verificationStatus: z13.enum(["pending", "verified", "rejected"])
|
|
3910
3962
|
});
|
|
3911
3963
|
var timeSlotSchema = z13.object({
|
|
@@ -3922,8 +3974,8 @@ var practitionerWorkingHoursSchema = z13.object({
|
|
|
3922
3974
|
friday: timeSlotSchema,
|
|
3923
3975
|
saturday: timeSlotSchema,
|
|
3924
3976
|
sunday: timeSlotSchema,
|
|
3925
|
-
createdAt: z13.instanceof(
|
|
3926
|
-
updatedAt: z13.instanceof(
|
|
3977
|
+
createdAt: z13.instanceof(Timestamp8).or(z13.date()),
|
|
3978
|
+
updatedAt: z13.instanceof(Timestamp8).or(z13.date())
|
|
3927
3979
|
});
|
|
3928
3980
|
var practitionerClinicWorkingHoursSchema = z13.object({
|
|
3929
3981
|
clinicId: z13.string().min(1),
|
|
@@ -3937,8 +3989,8 @@ var practitionerClinicWorkingHoursSchema = z13.object({
|
|
|
3937
3989
|
sunday: timeSlotSchema
|
|
3938
3990
|
}),
|
|
3939
3991
|
isActive: z13.boolean(),
|
|
3940
|
-
createdAt: z13.instanceof(
|
|
3941
|
-
updatedAt: z13.instanceof(
|
|
3992
|
+
createdAt: z13.instanceof(Timestamp8).or(z13.date()),
|
|
3993
|
+
updatedAt: z13.instanceof(Timestamp8).or(z13.date())
|
|
3942
3994
|
});
|
|
3943
3995
|
var practitionerSchema = z13.object({
|
|
3944
3996
|
id: z13.string().min(1),
|
|
@@ -3954,8 +4006,8 @@ var practitionerSchema = z13.object({
|
|
|
3954
4006
|
isActive: z13.boolean(),
|
|
3955
4007
|
isVerified: z13.boolean(),
|
|
3956
4008
|
status: z13.nativeEnum(PractitionerStatus),
|
|
3957
|
-
createdAt: z13.instanceof(
|
|
3958
|
-
updatedAt: z13.instanceof(
|
|
4009
|
+
createdAt: z13.instanceof(Timestamp8).or(z13.date()),
|
|
4010
|
+
updatedAt: z13.instanceof(Timestamp8).or(z13.date())
|
|
3959
4011
|
});
|
|
3960
4012
|
var createPractitionerSchema = z13.object({
|
|
3961
4013
|
userRef: z13.string().min(1),
|
|
@@ -3987,10 +4039,10 @@ var practitionerTokenSchema = z13.object({
|
|
|
3987
4039
|
clinicId: z13.string().min(1),
|
|
3988
4040
|
status: z13.nativeEnum(PractitionerTokenStatus),
|
|
3989
4041
|
createdBy: z13.string().min(1),
|
|
3990
|
-
createdAt: z13.instanceof(
|
|
3991
|
-
expiresAt: z13.instanceof(
|
|
4042
|
+
createdAt: z13.instanceof(Timestamp8).or(z13.date()),
|
|
4043
|
+
expiresAt: z13.instanceof(Timestamp8).or(z13.date()),
|
|
3992
4044
|
usedBy: z13.string().optional(),
|
|
3993
|
-
usedAt: z13.instanceof(
|
|
4045
|
+
usedAt: z13.instanceof(Timestamp8).or(z13.date()).optional()
|
|
3994
4046
|
});
|
|
3995
4047
|
var createPractitionerTokenSchema = z13.object({
|
|
3996
4048
|
practitionerId: z13.string().min(1),
|
|
@@ -4068,8 +4120,8 @@ var PractitionerService = class extends BaseService {
|
|
|
4068
4120
|
};
|
|
4069
4121
|
practitionerSchema.parse({
|
|
4070
4122
|
...practitioner,
|
|
4071
|
-
createdAt:
|
|
4072
|
-
updatedAt:
|
|
4123
|
+
createdAt: Timestamp9.now(),
|
|
4124
|
+
updatedAt: Timestamp9.now()
|
|
4073
4125
|
});
|
|
4074
4126
|
const practitionerRef = doc8(
|
|
4075
4127
|
this.db,
|
|
@@ -4169,8 +4221,8 @@ var PractitionerService = class extends BaseService {
|
|
|
4169
4221
|
practitionerSchema.parse({
|
|
4170
4222
|
...practitionerData,
|
|
4171
4223
|
userRef: "temp-for-validation",
|
|
4172
|
-
createdAt:
|
|
4173
|
-
updatedAt:
|
|
4224
|
+
createdAt: Timestamp9.now(),
|
|
4225
|
+
updatedAt: Timestamp9.now()
|
|
4174
4226
|
});
|
|
4175
4227
|
await setDoc7(
|
|
4176
4228
|
doc8(this.db, PRACTITIONERS_COLLECTION, practitionerData.id),
|
|
@@ -4190,8 +4242,8 @@ var PractitionerService = class extends BaseService {
|
|
|
4190
4242
|
clinicId,
|
|
4191
4243
|
status: "active" /* ACTIVE */,
|
|
4192
4244
|
createdBy,
|
|
4193
|
-
createdAt:
|
|
4194
|
-
expiresAt:
|
|
4245
|
+
createdAt: Timestamp9.now(),
|
|
4246
|
+
expiresAt: Timestamp9.fromDate(expiration)
|
|
4195
4247
|
};
|
|
4196
4248
|
practitionerTokenSchema.parse(token);
|
|
4197
4249
|
const tokenPath = `${PRACTITIONERS_COLLECTION}/${practitionerId}/${REGISTER_TOKENS_COLLECTION}/${token.id}`;
|
|
@@ -4243,8 +4295,8 @@ var PractitionerService = class extends BaseService {
|
|
|
4243
4295
|
clinicId: validatedData.clinicId,
|
|
4244
4296
|
status: "active" /* ACTIVE */,
|
|
4245
4297
|
createdBy,
|
|
4246
|
-
createdAt:
|
|
4247
|
-
expiresAt:
|
|
4298
|
+
createdAt: Timestamp9.now(),
|
|
4299
|
+
expiresAt: Timestamp9.fromDate(expiration)
|
|
4248
4300
|
};
|
|
4249
4301
|
practitionerTokenSchema.parse(token);
|
|
4250
4302
|
const tokenPath = `${PRACTITIONERS_COLLECTION}/${validatedData.practitionerId}/${REGISTER_TOKENS_COLLECTION}/${token.id}`;
|
|
@@ -4270,7 +4322,7 @@ var PractitionerService = class extends BaseService {
|
|
|
4270
4322
|
const q = query6(
|
|
4271
4323
|
tokensRef,
|
|
4272
4324
|
where6("status", "==", "active" /* ACTIVE */),
|
|
4273
|
-
where6("expiresAt", ">",
|
|
4325
|
+
where6("expiresAt", ">", Timestamp9.now())
|
|
4274
4326
|
);
|
|
4275
4327
|
const querySnapshot = await getDocs6(q);
|
|
4276
4328
|
return querySnapshot.docs.map((doc33) => doc33.data());
|
|
@@ -4293,7 +4345,7 @@ var PractitionerService = class extends BaseService {
|
|
|
4293
4345
|
tokensRef,
|
|
4294
4346
|
where6("token", "==", tokenString),
|
|
4295
4347
|
where6("status", "==", "active" /* ACTIVE */),
|
|
4296
|
-
where6("expiresAt", ">",
|
|
4348
|
+
where6("expiresAt", ">", Timestamp9.now())
|
|
4297
4349
|
);
|
|
4298
4350
|
const tokenSnapshot = await getDocs6(q);
|
|
4299
4351
|
if (!tokenSnapshot.empty) {
|
|
@@ -4316,7 +4368,7 @@ var PractitionerService = class extends BaseService {
|
|
|
4316
4368
|
await updateDoc8(tokenRef, {
|
|
4317
4369
|
status: "used" /* USED */,
|
|
4318
4370
|
usedBy: userId,
|
|
4319
|
-
usedAt:
|
|
4371
|
+
usedAt: Timestamp9.now()
|
|
4320
4372
|
});
|
|
4321
4373
|
}
|
|
4322
4374
|
/**
|
|
@@ -4839,7 +4891,7 @@ var UserService = class extends BaseService {
|
|
|
4839
4891
|
email: "",
|
|
4840
4892
|
phoneNumber: "",
|
|
4841
4893
|
title: "",
|
|
4842
|
-
dateOfBirth:
|
|
4894
|
+
dateOfBirth: Timestamp10.now(),
|
|
4843
4895
|
gender: "other",
|
|
4844
4896
|
languages: ["Serbian"]
|
|
4845
4897
|
},
|
|
@@ -4848,7 +4900,7 @@ var UserService = class extends BaseService {
|
|
|
4848
4900
|
specialties: [],
|
|
4849
4901
|
licenseNumber: "",
|
|
4850
4902
|
issuingAuthority: "",
|
|
4851
|
-
issueDate:
|
|
4903
|
+
issueDate: Timestamp10.now(),
|
|
4852
4904
|
verificationStatus: "pending"
|
|
4853
4905
|
},
|
|
4854
4906
|
isActive: true,
|
|
@@ -5033,7 +5085,7 @@ import {
|
|
|
5033
5085
|
where as where8,
|
|
5034
5086
|
updateDoc as updateDoc10,
|
|
5035
5087
|
setDoc as setDoc9,
|
|
5036
|
-
Timestamp as
|
|
5088
|
+
Timestamp as Timestamp11
|
|
5037
5089
|
} from "firebase/firestore";
|
|
5038
5090
|
import { geohashForLocation as geohashForLocation2 } from "geofire-common";
|
|
5039
5091
|
import { z as z16 } from "zod";
|
|
@@ -5157,7 +5209,7 @@ async function createClinicGroup(db, data, ownerId, isDefault = false, clinicAdm
|
|
|
5157
5209
|
throw geohashError;
|
|
5158
5210
|
}
|
|
5159
5211
|
}
|
|
5160
|
-
const now =
|
|
5212
|
+
const now = Timestamp11.now();
|
|
5161
5213
|
console.log("[CLINIC_GROUP] Preparing clinic group data object");
|
|
5162
5214
|
const groupId = doc10(collection8(db, CLINIC_GROUPS_COLLECTION)).id;
|
|
5163
5215
|
console.log("[CLINIC_GROUP] Logo value:", {
|
|
@@ -5296,7 +5348,7 @@ async function updateClinicGroup(db, groupId, data, app) {
|
|
|
5296
5348
|
}
|
|
5297
5349
|
updatedData = {
|
|
5298
5350
|
...updatedData,
|
|
5299
|
-
updatedAt:
|
|
5351
|
+
updatedAt: Timestamp11.now()
|
|
5300
5352
|
};
|
|
5301
5353
|
console.log("[CLINIC_GROUP] Updating clinic group in Firestore");
|
|
5302
5354
|
await updateDoc10(doc10(db, CLINIC_GROUPS_COLLECTION, groupId), updatedData);
|
|
@@ -5380,10 +5432,10 @@ async function createAdminToken(db, groupId, creatorAdminId, app, data) {
|
|
|
5380
5432
|
if (!group.admins.includes(creatorAdminId)) {
|
|
5381
5433
|
throw new Error("Admin does not belong to this clinic group");
|
|
5382
5434
|
}
|
|
5383
|
-
const now =
|
|
5435
|
+
const now = Timestamp11.now();
|
|
5384
5436
|
const expiresInDays = (data == null ? void 0 : data.expiresInDays) || 7;
|
|
5385
5437
|
const email = (data == null ? void 0 : data.email) || null;
|
|
5386
|
-
const expiresAt = new
|
|
5438
|
+
const expiresAt = new Timestamp11(
|
|
5387
5439
|
now.seconds + expiresInDays * 24 * 60 * 60,
|
|
5388
5440
|
now.nanoseconds
|
|
5389
5441
|
);
|
|
@@ -5417,7 +5469,7 @@ async function verifyAndUseAdminToken(db, groupId, token, userRef, app) {
|
|
|
5417
5469
|
if (adminToken.status !== "active" /* ACTIVE */) {
|
|
5418
5470
|
throw new Error("Admin token is not active");
|
|
5419
5471
|
}
|
|
5420
|
-
const now =
|
|
5472
|
+
const now = Timestamp11.now();
|
|
5421
5473
|
if (adminToken.expiresAt.seconds < now.seconds) {
|
|
5422
5474
|
const updatedTokens2 = group.adminTokens.map(
|
|
5423
5475
|
(t) => t.id === adminToken.id ? { ...t, status: "expired" /* EXPIRED */ } : t
|
|
@@ -5652,7 +5704,7 @@ import {
|
|
|
5652
5704
|
doc as doc12,
|
|
5653
5705
|
getDoc as getDoc15,
|
|
5654
5706
|
updateDoc as updateDoc12,
|
|
5655
|
-
Timestamp as
|
|
5707
|
+
Timestamp as Timestamp13,
|
|
5656
5708
|
serverTimestamp as serverTimestamp12,
|
|
5657
5709
|
writeBatch as writeBatch4,
|
|
5658
5710
|
arrayUnion as arrayUnion6
|
|
@@ -5672,7 +5724,7 @@ import {
|
|
|
5672
5724
|
where as where9,
|
|
5673
5725
|
updateDoc as updateDoc11,
|
|
5674
5726
|
setDoc as setDoc10,
|
|
5675
|
-
Timestamp as
|
|
5727
|
+
Timestamp as Timestamp12,
|
|
5676
5728
|
limit as limit5,
|
|
5677
5729
|
startAfter as startAfter5
|
|
5678
5730
|
} from "firebase/firestore";
|
|
@@ -5852,7 +5904,7 @@ async function updateClinic(db, clinicId, data, adminId, clinicAdminService, app
|
|
|
5852
5904
|
}
|
|
5853
5905
|
updatedData = {
|
|
5854
5906
|
...updatedData,
|
|
5855
|
-
updatedAt:
|
|
5907
|
+
updatedAt: Timestamp12.now()
|
|
5856
5908
|
};
|
|
5857
5909
|
console.log("[CLINIC] Updating clinic in Firestore");
|
|
5858
5910
|
try {
|
|
@@ -6350,8 +6402,8 @@ var ClinicService = class extends BaseService {
|
|
|
6350
6402
|
};
|
|
6351
6403
|
clinicSchema.parse({
|
|
6352
6404
|
...clinicData,
|
|
6353
|
-
createdAt:
|
|
6354
|
-
updatedAt:
|
|
6405
|
+
createdAt: Timestamp13.now(),
|
|
6406
|
+
updatedAt: Timestamp13.now()
|
|
6355
6407
|
});
|
|
6356
6408
|
const batch = writeBatch4(this.db);
|
|
6357
6409
|
const clinicRef = doc12(this.db, CLINICS_COLLECTION, clinicId);
|
|
@@ -6402,7 +6454,7 @@ var ClinicService = class extends BaseService {
|
|
|
6402
6454
|
};
|
|
6403
6455
|
clinicSchema.parse({
|
|
6404
6456
|
...finalStateForValidation,
|
|
6405
|
-
updatedAt:
|
|
6457
|
+
updatedAt: Timestamp13.now()
|
|
6406
6458
|
// Use current time for validation
|
|
6407
6459
|
});
|
|
6408
6460
|
const updateDataForFirestore = {
|
|
@@ -7463,7 +7515,7 @@ import {
|
|
|
7463
7515
|
updateDoc as updateDoc14,
|
|
7464
7516
|
deleteDoc as deleteDoc7,
|
|
7465
7517
|
orderBy as orderBy3,
|
|
7466
|
-
Timestamp as
|
|
7518
|
+
Timestamp as Timestamp15,
|
|
7467
7519
|
addDoc as addDoc2,
|
|
7468
7520
|
writeBatch as writeBatch5
|
|
7469
7521
|
} from "firebase/firestore";
|
|
@@ -7506,7 +7558,7 @@ var NotificationService = class extends BaseService {
|
|
|
7506
7558
|
*/
|
|
7507
7559
|
async createNotification(notification) {
|
|
7508
7560
|
const notificationsRef = collection14(this.db, NOTIFICATIONS_COLLECTION);
|
|
7509
|
-
const now =
|
|
7561
|
+
const now = Timestamp15.now();
|
|
7510
7562
|
const notificationData = {
|
|
7511
7563
|
...notification,
|
|
7512
7564
|
createdAt: now,
|
|
@@ -7581,7 +7633,7 @@ var NotificationService = class extends BaseService {
|
|
|
7581
7633
|
);
|
|
7582
7634
|
await updateDoc14(notificationRef, {
|
|
7583
7635
|
isRead: true,
|
|
7584
|
-
updatedAt:
|
|
7636
|
+
updatedAt: Timestamp15.now()
|
|
7585
7637
|
});
|
|
7586
7638
|
}
|
|
7587
7639
|
/**
|
|
@@ -7598,7 +7650,7 @@ var NotificationService = class extends BaseService {
|
|
|
7598
7650
|
);
|
|
7599
7651
|
batch.update(notificationRef, {
|
|
7600
7652
|
isRead: true,
|
|
7601
|
-
updatedAt:
|
|
7653
|
+
updatedAt: Timestamp15.now()
|
|
7602
7654
|
});
|
|
7603
7655
|
});
|
|
7604
7656
|
await batch.commit();
|
|
@@ -7614,7 +7666,7 @@ var NotificationService = class extends BaseService {
|
|
|
7614
7666
|
);
|
|
7615
7667
|
await updateDoc14(notificationRef, {
|
|
7616
7668
|
status,
|
|
7617
|
-
updatedAt:
|
|
7669
|
+
updatedAt: Timestamp15.now()
|
|
7618
7670
|
});
|
|
7619
7671
|
}
|
|
7620
7672
|
/**
|
|
@@ -8932,7 +8984,7 @@ var FilledDocumentService = class extends BaseService {
|
|
|
8932
8984
|
};
|
|
8933
8985
|
|
|
8934
8986
|
// src/services/calendar/calendar-refactored.service.ts
|
|
8935
|
-
import { Timestamp as
|
|
8987
|
+
import { Timestamp as Timestamp26, serverTimestamp as serverTimestamp21 } from "firebase/firestore";
|
|
8936
8988
|
|
|
8937
8989
|
// src/types/calendar/synced-calendar.types.ts
|
|
8938
8990
|
var SyncedCalendarProvider = /* @__PURE__ */ ((SyncedCalendarProvider3) => {
|
|
@@ -8957,11 +9009,11 @@ import {
|
|
|
8957
9009
|
|
|
8958
9010
|
// src/validations/calendar.schema.ts
|
|
8959
9011
|
import { z as z22 } from "zod";
|
|
8960
|
-
import { Timestamp as
|
|
9012
|
+
import { Timestamp as Timestamp19 } from "firebase/firestore";
|
|
8961
9013
|
|
|
8962
9014
|
// src/validations/profile-info.schema.ts
|
|
8963
9015
|
import { z as z21 } from "zod";
|
|
8964
|
-
import { Timestamp as
|
|
9016
|
+
import { Timestamp as Timestamp18 } from "firebase/firestore";
|
|
8965
9017
|
var clinicInfoSchema2 = z21.object({
|
|
8966
9018
|
id: z21.string(),
|
|
8967
9019
|
featuredPhoto: z21.string(),
|
|
@@ -8983,19 +9035,19 @@ var patientProfileInfoSchema = z21.object({
|
|
|
8983
9035
|
fullName: z21.string(),
|
|
8984
9036
|
email: z21.string().email(),
|
|
8985
9037
|
phone: z21.string().nullable(),
|
|
8986
|
-
dateOfBirth: z21.instanceof(
|
|
9038
|
+
dateOfBirth: z21.instanceof(Timestamp18),
|
|
8987
9039
|
gender: z21.nativeEnum(Gender)
|
|
8988
9040
|
});
|
|
8989
9041
|
|
|
8990
9042
|
// src/validations/calendar.schema.ts
|
|
8991
9043
|
var MIN_APPOINTMENT_DURATION = 15;
|
|
8992
9044
|
var calendarEventTimeSchema = z22.object({
|
|
8993
|
-
start: z22.instanceof(Date).or(z22.instanceof(
|
|
8994
|
-
end: z22.instanceof(Date).or(z22.instanceof(
|
|
9045
|
+
start: z22.instanceof(Date).or(z22.instanceof(Timestamp19)),
|
|
9046
|
+
end: z22.instanceof(Date).or(z22.instanceof(Timestamp19))
|
|
8995
9047
|
}).refine(
|
|
8996
9048
|
(data) => {
|
|
8997
|
-
const startDate = data.start instanceof
|
|
8998
|
-
const endDate = data.end instanceof
|
|
9049
|
+
const startDate = data.start instanceof Timestamp19 ? data.start.toDate() : data.start;
|
|
9050
|
+
const endDate = data.end instanceof Timestamp19 ? data.end.toDate() : data.end;
|
|
8999
9051
|
return startDate < endDate;
|
|
9000
9052
|
},
|
|
9001
9053
|
{
|
|
@@ -9004,7 +9056,7 @@ var calendarEventTimeSchema = z22.object({
|
|
|
9004
9056
|
}
|
|
9005
9057
|
).refine(
|
|
9006
9058
|
(data) => {
|
|
9007
|
-
const startDate = data.start instanceof
|
|
9059
|
+
const startDate = data.start instanceof Timestamp19 ? data.start.toDate() : data.start;
|
|
9008
9060
|
return startDate > /* @__PURE__ */ new Date();
|
|
9009
9061
|
},
|
|
9010
9062
|
{
|
|
@@ -9023,7 +9075,7 @@ var timeSlotSchema2 = z22.object({
|
|
|
9023
9075
|
var syncedCalendarEventSchema = z22.object({
|
|
9024
9076
|
eventId: z22.string(),
|
|
9025
9077
|
syncedCalendarProvider: z22.nativeEnum(SyncedCalendarProvider),
|
|
9026
|
-
syncedAt: z22.instanceof(Date).or(z22.instanceof(
|
|
9078
|
+
syncedAt: z22.instanceof(Date).or(z22.instanceof(Timestamp19))
|
|
9027
9079
|
});
|
|
9028
9080
|
var procedureInfoSchema = z22.object({
|
|
9029
9081
|
name: z22.string(),
|
|
@@ -9125,8 +9177,8 @@ var calendarEventSchema = z22.object({
|
|
|
9125
9177
|
status: z22.nativeEnum(CalendarEventStatus),
|
|
9126
9178
|
syncStatus: z22.nativeEnum(CalendarSyncStatus),
|
|
9127
9179
|
eventType: z22.nativeEnum(CalendarEventType),
|
|
9128
|
-
createdAt: z22.instanceof(Date).or(z22.instanceof(
|
|
9129
|
-
updatedAt: z22.instanceof(Date).or(z22.instanceof(
|
|
9180
|
+
createdAt: z22.instanceof(Date).or(z22.instanceof(Timestamp19)),
|
|
9181
|
+
updatedAt: z22.instanceof(Date).or(z22.instanceof(Timestamp19))
|
|
9130
9182
|
});
|
|
9131
9183
|
|
|
9132
9184
|
// src/services/calendar/utils/clinic.utils.ts
|
|
@@ -9141,7 +9193,7 @@ import {
|
|
|
9141
9193
|
query as query18,
|
|
9142
9194
|
where as where18,
|
|
9143
9195
|
orderBy as orderBy7,
|
|
9144
|
-
Timestamp as
|
|
9196
|
+
Timestamp as Timestamp20,
|
|
9145
9197
|
serverTimestamp as serverTimestamp16
|
|
9146
9198
|
} from "firebase/firestore";
|
|
9147
9199
|
|
|
@@ -9197,8 +9249,8 @@ async function createClinicCalendarEventUtil(db, clinicId, eventData, generateId
|
|
|
9197
9249
|
await setDoc16(eventRef, newEvent);
|
|
9198
9250
|
return {
|
|
9199
9251
|
...newEvent,
|
|
9200
|
-
createdAt:
|
|
9201
|
-
updatedAt:
|
|
9252
|
+
createdAt: Timestamp20.now(),
|
|
9253
|
+
updatedAt: Timestamp20.now()
|
|
9202
9254
|
};
|
|
9203
9255
|
}
|
|
9204
9256
|
async function updateClinicCalendarEventUtil(db, clinicId, eventId, updateData) {
|
|
@@ -9245,7 +9297,7 @@ import {
|
|
|
9245
9297
|
query as query19,
|
|
9246
9298
|
where as where19,
|
|
9247
9299
|
orderBy as orderBy8,
|
|
9248
|
-
Timestamp as
|
|
9300
|
+
Timestamp as Timestamp21,
|
|
9249
9301
|
serverTimestamp as serverTimestamp17
|
|
9250
9302
|
} from "firebase/firestore";
|
|
9251
9303
|
async function createPatientCalendarEventUtil(db, patientId, eventData, generateId2) {
|
|
@@ -9260,8 +9312,8 @@ async function createPatientCalendarEventUtil(db, patientId, eventData, generate
|
|
|
9260
9312
|
await setDoc17(eventRef, newEvent);
|
|
9261
9313
|
return {
|
|
9262
9314
|
...newEvent,
|
|
9263
|
-
createdAt:
|
|
9264
|
-
updatedAt:
|
|
9315
|
+
createdAt: Timestamp21.now(),
|
|
9316
|
+
updatedAt: Timestamp21.now()
|
|
9265
9317
|
};
|
|
9266
9318
|
}
|
|
9267
9319
|
async function updatePatientCalendarEventUtil(db, patientId, eventId, updateData) {
|
|
@@ -9289,7 +9341,7 @@ import {
|
|
|
9289
9341
|
query as query20,
|
|
9290
9342
|
where as where20,
|
|
9291
9343
|
orderBy as orderBy9,
|
|
9292
|
-
Timestamp as
|
|
9344
|
+
Timestamp as Timestamp22,
|
|
9293
9345
|
serverTimestamp as serverTimestamp18
|
|
9294
9346
|
} from "firebase/firestore";
|
|
9295
9347
|
async function createPractitionerCalendarEventUtil(db, practitionerId, eventData, generateId2) {
|
|
@@ -9308,8 +9360,8 @@ async function createPractitionerCalendarEventUtil(db, practitionerId, eventData
|
|
|
9308
9360
|
await setDoc18(eventRef, newEvent);
|
|
9309
9361
|
return {
|
|
9310
9362
|
...newEvent,
|
|
9311
|
-
createdAt:
|
|
9312
|
-
updatedAt:
|
|
9363
|
+
createdAt: Timestamp22.now(),
|
|
9364
|
+
updatedAt: Timestamp22.now()
|
|
9313
9365
|
};
|
|
9314
9366
|
}
|
|
9315
9367
|
async function updatePractitionerCalendarEventUtil(db, practitionerId, eventId, updateData) {
|
|
@@ -9392,7 +9444,7 @@ import {
|
|
|
9392
9444
|
query as query21,
|
|
9393
9445
|
where as where21,
|
|
9394
9446
|
orderBy as orderBy10,
|
|
9395
|
-
Timestamp as
|
|
9447
|
+
Timestamp as Timestamp23,
|
|
9396
9448
|
serverTimestamp as serverTimestamp19
|
|
9397
9449
|
} from "firebase/firestore";
|
|
9398
9450
|
async function searchCalendarEventsUtil(db, params) {
|
|
@@ -9497,7 +9549,7 @@ import {
|
|
|
9497
9549
|
deleteDoc as deleteDoc14,
|
|
9498
9550
|
query as query22,
|
|
9499
9551
|
orderBy as orderBy11,
|
|
9500
|
-
Timestamp as
|
|
9552
|
+
Timestamp as Timestamp24,
|
|
9501
9553
|
serverTimestamp as serverTimestamp20
|
|
9502
9554
|
} from "firebase/firestore";
|
|
9503
9555
|
async function createPractitionerSyncedCalendarUtil(db, practitionerId, calendarData, generateId2) {
|
|
@@ -9516,8 +9568,8 @@ async function createPractitionerSyncedCalendarUtil(db, practitionerId, calendar
|
|
|
9516
9568
|
await setDoc20(calendarRef, newCalendar);
|
|
9517
9569
|
return {
|
|
9518
9570
|
...newCalendar,
|
|
9519
|
-
createdAt:
|
|
9520
|
-
updatedAt:
|
|
9571
|
+
createdAt: Timestamp24.now(),
|
|
9572
|
+
updatedAt: Timestamp24.now()
|
|
9521
9573
|
};
|
|
9522
9574
|
}
|
|
9523
9575
|
async function createPatientSyncedCalendarUtil(db, patientId, calendarData, generateId2) {
|
|
@@ -9532,8 +9584,8 @@ async function createPatientSyncedCalendarUtil(db, patientId, calendarData, gene
|
|
|
9532
9584
|
await setDoc20(calendarRef, newCalendar);
|
|
9533
9585
|
return {
|
|
9534
9586
|
...newCalendar,
|
|
9535
|
-
createdAt:
|
|
9536
|
-
updatedAt:
|
|
9587
|
+
createdAt: Timestamp24.now(),
|
|
9588
|
+
updatedAt: Timestamp24.now()
|
|
9537
9589
|
};
|
|
9538
9590
|
}
|
|
9539
9591
|
async function createClinicSyncedCalendarUtil(db, clinicId, calendarData, generateId2) {
|
|
@@ -9548,8 +9600,8 @@ async function createClinicSyncedCalendarUtil(db, clinicId, calendarData, genera
|
|
|
9548
9600
|
await setDoc20(calendarRef, newCalendar);
|
|
9549
9601
|
return {
|
|
9550
9602
|
...newCalendar,
|
|
9551
|
-
createdAt:
|
|
9552
|
-
updatedAt:
|
|
9603
|
+
createdAt: Timestamp24.now(),
|
|
9604
|
+
updatedAt: Timestamp24.now()
|
|
9553
9605
|
};
|
|
9554
9606
|
}
|
|
9555
9607
|
async function getPractitionerSyncedCalendarUtil(db, practitionerId, calendarId) {
|
|
@@ -9668,7 +9720,7 @@ async function deleteClinicSyncedCalendarUtil(db, clinicId, calendarId) {
|
|
|
9668
9720
|
}
|
|
9669
9721
|
async function updateLastSyncedTimestampUtil(db, entityType, entityId, calendarId) {
|
|
9670
9722
|
const updateData = {
|
|
9671
|
-
lastSyncedAt:
|
|
9723
|
+
lastSyncedAt: Timestamp24.now()
|
|
9672
9724
|
};
|
|
9673
9725
|
switch (entityType) {
|
|
9674
9726
|
case "practitioner":
|
|
@@ -9698,7 +9750,7 @@ async function updateLastSyncedTimestampUtil(db, entityType, entityId, calendarI
|
|
|
9698
9750
|
}
|
|
9699
9751
|
|
|
9700
9752
|
// src/services/calendar/utils/google-calendar.utils.ts
|
|
9701
|
-
import { Timestamp as
|
|
9753
|
+
import { Timestamp as Timestamp25 } from "firebase/firestore";
|
|
9702
9754
|
var GOOGLE_CALENDAR_API_URL = "https://www.googleapis.com/calendar/v3";
|
|
9703
9755
|
var GOOGLE_OAUTH_URL = "https://oauth2.googleapis.com/token";
|
|
9704
9756
|
var CLIENT_ID = "your-client-id";
|
|
@@ -9818,7 +9870,7 @@ async function ensureValidToken(db, entityType, entityId, syncedCalendar) {
|
|
|
9818
9870
|
tokenExpiry.setSeconds(tokenExpiry.getSeconds() + expiresIn);
|
|
9819
9871
|
const updateData = {
|
|
9820
9872
|
accessToken,
|
|
9821
|
-
tokenExpiry:
|
|
9873
|
+
tokenExpiry: Timestamp25.fromDate(tokenExpiry)
|
|
9822
9874
|
};
|
|
9823
9875
|
switch (entityType) {
|
|
9824
9876
|
case "practitioner":
|
|
@@ -9993,8 +10045,8 @@ function convertGoogleEventToCalendarEventUtil(googleEvent, entityId, entityType
|
|
|
9993
10045
|
eventName: googleEvent.summary || "External Event",
|
|
9994
10046
|
eventLocation: googleEvent.location,
|
|
9995
10047
|
eventTime: {
|
|
9996
|
-
start:
|
|
9997
|
-
end:
|
|
10048
|
+
start: Timestamp25.fromDate(start),
|
|
10049
|
+
end: Timestamp25.fromDate(end)
|
|
9998
10050
|
},
|
|
9999
10051
|
description: googleEvent.description || "",
|
|
10000
10052
|
// External events are always set as CONFIRMED - status updates will happen externally
|
|
@@ -10008,7 +10060,7 @@ function convertGoogleEventToCalendarEventUtil(googleEvent, entityId, entityType
|
|
|
10008
10060
|
{
|
|
10009
10061
|
eventId: googleEvent.id,
|
|
10010
10062
|
syncedCalendarProvider: "google" /* GOOGLE */,
|
|
10011
|
-
syncedAt:
|
|
10063
|
+
syncedAt: Timestamp25.now()
|
|
10012
10064
|
}
|
|
10013
10065
|
]
|
|
10014
10066
|
};
|
|
@@ -10786,7 +10838,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
10786
10838
|
return 0;
|
|
10787
10839
|
}
|
|
10788
10840
|
let importedEventsCount = 0;
|
|
10789
|
-
const currentTime =
|
|
10841
|
+
const currentTime = Timestamp26.now();
|
|
10790
10842
|
for (const calendar of activeCalendars) {
|
|
10791
10843
|
try {
|
|
10792
10844
|
let externalEvents = [];
|
|
@@ -10869,8 +10921,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
10869
10921
|
await setDoc21(eventRef, newEvent);
|
|
10870
10922
|
return {
|
|
10871
10923
|
...newEvent,
|
|
10872
|
-
createdAt:
|
|
10873
|
-
updatedAt:
|
|
10924
|
+
createdAt: Timestamp26.now(),
|
|
10925
|
+
updatedAt: Timestamp26.now()
|
|
10874
10926
|
};
|
|
10875
10927
|
} catch (error) {
|
|
10876
10928
|
console.error(
|
|
@@ -10956,8 +11008,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
10956
11008
|
const q = query23(
|
|
10957
11009
|
eventsRef,
|
|
10958
11010
|
where23("syncStatus", "==", "external" /* EXTERNAL */),
|
|
10959
|
-
where23("eventTime.start", ">=",
|
|
10960
|
-
where23("eventTime.start", "<=",
|
|
11011
|
+
where23("eventTime.start", ">=", Timestamp26.fromDate(startDate)),
|
|
11012
|
+
where23("eventTime.start", "<=", Timestamp26.fromDate(endDate))
|
|
10961
11013
|
);
|
|
10962
11014
|
const eventsSnapshot = await getDocs23(q);
|
|
10963
11015
|
const events = eventsSnapshot.docs.map((doc33) => ({
|
|
@@ -11076,8 +11128,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
11076
11128
|
await updateDoc23(eventRef, {
|
|
11077
11129
|
eventName: externalEvent.summary || "External Event",
|
|
11078
11130
|
eventTime: {
|
|
11079
|
-
start:
|
|
11080
|
-
end:
|
|
11131
|
+
start: Timestamp26.fromDate(startTime),
|
|
11132
|
+
end: Timestamp26.fromDate(endTime)
|
|
11081
11133
|
},
|
|
11082
11134
|
description: externalEvent.description || "",
|
|
11083
11135
|
updatedAt: serverTimestamp21()
|
|
@@ -11155,8 +11207,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
11155
11207
|
*/
|
|
11156
11208
|
async getPractitionerUpcomingAppointments(doctorId, startDate, endDate, status = "confirmed" /* CONFIRMED */) {
|
|
11157
11209
|
const dateRange = {
|
|
11158
|
-
start:
|
|
11159
|
-
end:
|
|
11210
|
+
start: Timestamp26.fromDate(startDate),
|
|
11211
|
+
end: Timestamp26.fromDate(endDate)
|
|
11160
11212
|
};
|
|
11161
11213
|
const searchParams = {
|
|
11162
11214
|
searchLocation: "practitioner" /* PRACTITIONER */,
|
|
@@ -11178,8 +11230,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
11178
11230
|
*/
|
|
11179
11231
|
async getPatientAppointments(patientId, startDate, endDate, status) {
|
|
11180
11232
|
const dateRange = {
|
|
11181
|
-
start:
|
|
11182
|
-
end:
|
|
11233
|
+
start: Timestamp26.fromDate(startDate),
|
|
11234
|
+
end: Timestamp26.fromDate(endDate)
|
|
11183
11235
|
};
|
|
11184
11236
|
const searchParams = {
|
|
11185
11237
|
searchLocation: "patient" /* PATIENT */,
|
|
@@ -11204,8 +11256,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
11204
11256
|
*/
|
|
11205
11257
|
async getClinicAppointments(clinicId, startDate, endDate, doctorId, status) {
|
|
11206
11258
|
const dateRange = {
|
|
11207
|
-
start:
|
|
11208
|
-
end:
|
|
11259
|
+
start: Timestamp26.fromDate(startDate),
|
|
11260
|
+
end: Timestamp26.fromDate(endDate)
|
|
11209
11261
|
};
|
|
11210
11262
|
const searchParams = {
|
|
11211
11263
|
searchLocation: "clinic" /* CLINIC */,
|
|
@@ -11361,7 +11413,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
11361
11413
|
["confirmed" /* CONFIRMED */]: [
|
|
11362
11414
|
"canceled" /* CANCELED */,
|
|
11363
11415
|
"completed" /* COMPLETED */,
|
|
11364
|
-
"rescheduled" /* RESCHEDULED
|
|
11416
|
+
"rescheduled" /* RESCHEDULED */,
|
|
11417
|
+
"no_show" /* NO_SHOW */
|
|
11365
11418
|
],
|
|
11366
11419
|
["rejected" /* REJECTED */]: [],
|
|
11367
11420
|
["canceled" /* CANCELED */]: [],
|
|
@@ -11369,7 +11422,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
11369
11422
|
"confirmed" /* CONFIRMED */,
|
|
11370
11423
|
"canceled" /* CANCELED */
|
|
11371
11424
|
],
|
|
11372
|
-
["completed" /* COMPLETED */]: []
|
|
11425
|
+
["completed" /* COMPLETED */]: [],
|
|
11426
|
+
["no_show" /* NO_SHOW */]: []
|
|
11373
11427
|
};
|
|
11374
11428
|
if (!validTransitions[currentStatus].includes(newStatus)) {
|
|
11375
11429
|
throw new Error(
|
|
@@ -11457,7 +11511,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
11457
11511
|
const newSyncEvent = {
|
|
11458
11512
|
eventId: result.eventIds[0],
|
|
11459
11513
|
syncedCalendarProvider: calendar.provider,
|
|
11460
|
-
syncedAt:
|
|
11514
|
+
syncedAt: Timestamp26.now()
|
|
11461
11515
|
};
|
|
11462
11516
|
await this.updateEventWithSyncId(
|
|
11463
11517
|
entityType === "doctor" ? appointment.practitionerProfileId : appointment.patientProfileId,
|
|
@@ -11586,8 +11640,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
11586
11640
|
const q = query23(
|
|
11587
11641
|
appointmentsRef,
|
|
11588
11642
|
where23("practitionerProfileId", "==", doctorId),
|
|
11589
|
-
where23("eventTime.start", ">=",
|
|
11590
|
-
where23("eventTime.start", "<=",
|
|
11643
|
+
where23("eventTime.start", ">=", Timestamp26.fromDate(startOfDay)),
|
|
11644
|
+
where23("eventTime.start", "<=", Timestamp26.fromDate(endOfDay)),
|
|
11591
11645
|
where23("status", "in", [
|
|
11592
11646
|
"confirmed" /* CONFIRMED */,
|
|
11593
11647
|
"pending" /* PENDING */
|
|
@@ -11688,7 +11742,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
11688
11742
|
fullName: `${sensitiveData.firstName} ${sensitiveData.lastName}`,
|
|
11689
11743
|
email: sensitiveData.email || "",
|
|
11690
11744
|
phone: sensitiveData.phoneNumber || null,
|
|
11691
|
-
dateOfBirth: sensitiveData.dateOfBirth ||
|
|
11745
|
+
dateOfBirth: sensitiveData.dateOfBirth || Timestamp26.now(),
|
|
11692
11746
|
gender: sensitiveData.gender || "other" /* OTHER */
|
|
11693
11747
|
};
|
|
11694
11748
|
} else if (patientDoc.exists()) {
|
|
@@ -11697,7 +11751,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
11697
11751
|
fullName: patientDoc.data().displayName,
|
|
11698
11752
|
email: ((_a = patientDoc.data().contactInfo) == null ? void 0 : _a.email) || "",
|
|
11699
11753
|
phone: patientDoc.data().phoneNumber || null,
|
|
11700
|
-
dateOfBirth: patientDoc.data().dateOfBirth ||
|
|
11754
|
+
dateOfBirth: patientDoc.data().dateOfBirth || Timestamp26.now(),
|
|
11701
11755
|
gender: patientDoc.data().gender || "other" /* OTHER */
|
|
11702
11756
|
};
|
|
11703
11757
|
}
|
|
@@ -12341,7 +12395,7 @@ var ReviewService = class extends BaseService {
|
|
|
12341
12395
|
|
|
12342
12396
|
// src/services/appointment/appointment.service.ts
|
|
12343
12397
|
import {
|
|
12344
|
-
Timestamp as
|
|
12398
|
+
Timestamp as Timestamp29,
|
|
12345
12399
|
serverTimestamp as serverTimestamp24,
|
|
12346
12400
|
arrayUnion as arrayUnion8,
|
|
12347
12401
|
arrayRemove as arrayRemove7,
|
|
@@ -12366,7 +12420,7 @@ import {
|
|
|
12366
12420
|
setDoc as setDoc23,
|
|
12367
12421
|
updateDoc as updateDoc25,
|
|
12368
12422
|
serverTimestamp as serverTimestamp23,
|
|
12369
|
-
Timestamp as
|
|
12423
|
+
Timestamp as Timestamp28,
|
|
12370
12424
|
orderBy as orderBy12,
|
|
12371
12425
|
limit as limit10,
|
|
12372
12426
|
startAfter as startAfter10
|
|
@@ -12437,7 +12491,7 @@ async function updateAppointmentUtil2(db, appointmentId, data) {
|
|
|
12437
12491
|
});
|
|
12438
12492
|
if (data.status && data.status !== currentAppointment.status) {
|
|
12439
12493
|
if (data.status === "confirmed" /* CONFIRMED */ && !updateData.confirmationTime) {
|
|
12440
|
-
updateData.confirmationTime =
|
|
12494
|
+
updateData.confirmationTime = Timestamp28.now();
|
|
12441
12495
|
}
|
|
12442
12496
|
if (currentAppointment.calendarEventId) {
|
|
12443
12497
|
await updateCalendarEventStatus(
|
|
@@ -12525,13 +12579,13 @@ async function searchAppointmentsUtil(db, params) {
|
|
|
12525
12579
|
where25(
|
|
12526
12580
|
"appointmentStartTime",
|
|
12527
12581
|
">=",
|
|
12528
|
-
|
|
12582
|
+
Timestamp28.fromDate(params.startDate)
|
|
12529
12583
|
)
|
|
12530
12584
|
);
|
|
12531
12585
|
}
|
|
12532
12586
|
if (params.endDate) {
|
|
12533
12587
|
constraints.push(
|
|
12534
|
-
where25("appointmentStartTime", "<=",
|
|
12588
|
+
where25("appointmentStartTime", "<=", Timestamp28.fromDate(params.endDate))
|
|
12535
12589
|
);
|
|
12536
12590
|
}
|
|
12537
12591
|
if (params.status) {
|
|
@@ -12931,13 +12985,13 @@ var AppointmentService = class extends BaseService {
|
|
|
12931
12985
|
}
|
|
12932
12986
|
updateData.cancellationReason = details.cancellationReason;
|
|
12933
12987
|
updateData.canceledBy = details.canceledBy;
|
|
12934
|
-
updateData.cancellationTime =
|
|
12988
|
+
updateData.cancellationTime = Timestamp29.now();
|
|
12935
12989
|
}
|
|
12936
12990
|
if (newStatus === "confirmed" /* CONFIRMED */) {
|
|
12937
|
-
updateData.confirmationTime =
|
|
12991
|
+
updateData.confirmationTime = Timestamp29.now();
|
|
12938
12992
|
}
|
|
12939
12993
|
if (newStatus === "rescheduled_by_clinic" /* RESCHEDULED_BY_CLINIC */) {
|
|
12940
|
-
updateData.rescheduleTime =
|
|
12994
|
+
updateData.rescheduleTime = Timestamp29.now();
|
|
12941
12995
|
}
|
|
12942
12996
|
return this.updateAppointment(appointmentId, updateData);
|
|
12943
12997
|
}
|
|
@@ -13008,7 +13062,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13008
13062
|
status: "rescheduled_by_clinic" /* RESCHEDULED_BY_CLINIC */,
|
|
13009
13063
|
appointmentStartTime: newStartTime,
|
|
13010
13064
|
appointmentEndTime: newEndTime,
|
|
13011
|
-
rescheduleTime:
|
|
13065
|
+
rescheduleTime: Timestamp29.now(),
|
|
13012
13066
|
confirmationTime: null,
|
|
13013
13067
|
updatedAt: serverTimestamp24()
|
|
13014
13068
|
};
|
|
@@ -13105,7 +13159,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13105
13159
|
}
|
|
13106
13160
|
const updateData = {
|
|
13107
13161
|
status: "in_progress" /* IN_PROGRESS */,
|
|
13108
|
-
procedureActualStartTime:
|
|
13162
|
+
procedureActualStartTime: Timestamp29.now(),
|
|
13109
13163
|
// Set actual start time
|
|
13110
13164
|
updatedAt: serverTimestamp24()
|
|
13111
13165
|
};
|
|
@@ -13125,7 +13179,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13125
13179
|
if (!appointment)
|
|
13126
13180
|
throw new Error(`Appointment ${appointmentId} not found.`);
|
|
13127
13181
|
let calculatedDurationMinutes = actualDurationMinutesInput;
|
|
13128
|
-
const procedureCompletionTime =
|
|
13182
|
+
const procedureCompletionTime = Timestamp29.now();
|
|
13129
13183
|
if (calculatedDurationMinutes === void 0 && appointment.procedureActualStartTime) {
|
|
13130
13184
|
const startTimeMillis = appointment.procedureActualStartTime.toMillis();
|
|
13131
13185
|
const endTimeMillis = procedureCompletionTime.toMillis();
|
|
@@ -13162,7 +13216,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13162
13216
|
const appointment = await this.getAppointmentById(appointmentId);
|
|
13163
13217
|
if (!appointment)
|
|
13164
13218
|
throw new Error(`Appointment ${appointmentId} not found.`);
|
|
13165
|
-
if (
|
|
13219
|
+
if (Timestamp29.now().toMillis() < appointment.appointmentStartTime.toMillis()) {
|
|
13166
13220
|
throw new Error("Cannot mark no-show before appointment start time.");
|
|
13167
13221
|
}
|
|
13168
13222
|
return this.updateAppointmentStatus(
|
|
@@ -13186,7 +13240,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13186
13240
|
const newMediaItem = {
|
|
13187
13241
|
...mediaItemData,
|
|
13188
13242
|
id: this.generateId(),
|
|
13189
|
-
uploadedAt:
|
|
13243
|
+
uploadedAt: Timestamp29.now(),
|
|
13190
13244
|
uploadedBy: currentUser.uid
|
|
13191
13245
|
};
|
|
13192
13246
|
const updateData = {
|
|
@@ -13226,7 +13280,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13226
13280
|
const newReviewInfo = {
|
|
13227
13281
|
...reviewData,
|
|
13228
13282
|
reviewId: this.generateId(),
|
|
13229
|
-
reviewedAt:
|
|
13283
|
+
reviewedAt: Timestamp29.now()
|
|
13230
13284
|
};
|
|
13231
13285
|
const updateData = {
|
|
13232
13286
|
reviewInfo: newReviewInfo,
|
|
@@ -13292,7 +13346,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13292
13346
|
where26(
|
|
13293
13347
|
"appointmentStartTime",
|
|
13294
13348
|
">=",
|
|
13295
|
-
|
|
13349
|
+
Timestamp29.fromDate(effectiveStartDate)
|
|
13296
13350
|
)
|
|
13297
13351
|
);
|
|
13298
13352
|
if (options == null ? void 0 : options.endDate) {
|
|
@@ -13300,7 +13354,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13300
13354
|
where26(
|
|
13301
13355
|
"appointmentStartTime",
|
|
13302
13356
|
"<=",
|
|
13303
|
-
|
|
13357
|
+
Timestamp29.fromDate(options.endDate)
|
|
13304
13358
|
)
|
|
13305
13359
|
);
|
|
13306
13360
|
}
|
|
@@ -13366,7 +13420,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13366
13420
|
where26(
|
|
13367
13421
|
"appointmentStartTime",
|
|
13368
13422
|
">=",
|
|
13369
|
-
|
|
13423
|
+
Timestamp29.fromDate(options.startDate)
|
|
13370
13424
|
)
|
|
13371
13425
|
);
|
|
13372
13426
|
}
|
|
@@ -13374,7 +13428,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13374
13428
|
where26(
|
|
13375
13429
|
"appointmentStartTime",
|
|
13376
13430
|
"<=",
|
|
13377
|
-
|
|
13431
|
+
Timestamp29.fromDate(effectiveEndDate)
|
|
13378
13432
|
)
|
|
13379
13433
|
);
|
|
13380
13434
|
constraints.push(orderBy13("appointmentStartTime", "desc"));
|
|
@@ -13415,7 +13469,7 @@ import {
|
|
|
13415
13469
|
where as where27,
|
|
13416
13470
|
doc as doc27,
|
|
13417
13471
|
updateDoc as updateDoc26,
|
|
13418
|
-
Timestamp as
|
|
13472
|
+
Timestamp as Timestamp30,
|
|
13419
13473
|
orderBy as orderBy14,
|
|
13420
13474
|
limit as limit12,
|
|
13421
13475
|
startAfter as startAfter12,
|
|
@@ -13574,7 +13628,7 @@ var PatientRequirementsService = class extends BaseService {
|
|
|
13574
13628
|
`Instruction ${instructionId} is in status ${instructionToUpdate.status} and cannot be marked as completed.`
|
|
13575
13629
|
);
|
|
13576
13630
|
}
|
|
13577
|
-
const now =
|
|
13631
|
+
const now = Timestamp30.now();
|
|
13578
13632
|
const updatedInstructions = [...instance.instructions];
|
|
13579
13633
|
updatedInstructions[instructionIndex] = {
|
|
13580
13634
|
...instructionToUpdate,
|