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