@blackcode_sa/metaestetics-api 1.7.32 → 1.7.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/index.d.mts +161 -1
- package/dist/admin/index.d.ts +161 -1
- package/dist/admin/index.js +542 -114
- package/dist/admin/index.mjs +540 -114
- package/package.json +1 -1
- package/src/admin/aggregation/practitioner-invite/practitioner-invite.aggregation.service.ts +576 -0
- package/src/admin/index.ts +8 -0
- package/src/types/calendar/index.ts +2 -2
package/dist/admin/index.mjs
CHANGED
|
@@ -148,9 +148,9 @@ var Logger = class {
|
|
|
148
148
|
|
|
149
149
|
// src/admin/notifications/notifications.admin.ts
|
|
150
150
|
var NotificationsAdmin = class {
|
|
151
|
-
constructor(
|
|
151
|
+
constructor(firestore17) {
|
|
152
152
|
this.expo = new Expo();
|
|
153
|
-
this.db =
|
|
153
|
+
this.db = firestore17 || admin.firestore();
|
|
154
154
|
}
|
|
155
155
|
/**
|
|
156
156
|
* Dohvata notifikaciju po ID-u
|
|
@@ -854,6 +854,15 @@ var PractitionerTokenStatus = /* @__PURE__ */ ((PractitionerTokenStatus2) => {
|
|
|
854
854
|
// src/types/procedure/index.ts
|
|
855
855
|
var PROCEDURES_COLLECTION = "procedures";
|
|
856
856
|
|
|
857
|
+
// src/types/clinic/practitioner-invite.types.ts
|
|
858
|
+
var PractitionerInviteStatus = /* @__PURE__ */ ((PractitionerInviteStatus2) => {
|
|
859
|
+
PractitionerInviteStatus2["PENDING"] = "pending";
|
|
860
|
+
PractitionerInviteStatus2["ACCEPTED"] = "accepted";
|
|
861
|
+
PractitionerInviteStatus2["REJECTED"] = "rejected";
|
|
862
|
+
PractitionerInviteStatus2["CANCELLED"] = "cancelled";
|
|
863
|
+
return PractitionerInviteStatus2;
|
|
864
|
+
})(PractitionerInviteStatus || {});
|
|
865
|
+
|
|
857
866
|
// src/types/clinic/index.ts
|
|
858
867
|
var CLINIC_GROUPS_COLLECTION = "clinic_groups";
|
|
859
868
|
var CLINICS_COLLECTION = "clinics";
|
|
@@ -869,8 +878,8 @@ var ClinicAggregationService = class {
|
|
|
869
878
|
* Constructor for ClinicAggregationService.
|
|
870
879
|
* @param firestore Optional Firestore instance. If not provided, it uses the default admin SDK instance.
|
|
871
880
|
*/
|
|
872
|
-
constructor(
|
|
873
|
-
this.db =
|
|
881
|
+
constructor(firestore17) {
|
|
882
|
+
this.db = firestore17 || admin3.firestore();
|
|
874
883
|
}
|
|
875
884
|
/**
|
|
876
885
|
* Adds clinic information to a clinic group when a new clinic is created
|
|
@@ -1382,8 +1391,8 @@ var ClinicAggregationService = class {
|
|
|
1382
1391
|
import * as admin4 from "firebase-admin";
|
|
1383
1392
|
var CALENDAR_SUBCOLLECTION_ID2 = "calendar";
|
|
1384
1393
|
var PractitionerAggregationService = class {
|
|
1385
|
-
constructor(
|
|
1386
|
-
this.db =
|
|
1394
|
+
constructor(firestore17) {
|
|
1395
|
+
this.db = firestore17 || admin4.firestore();
|
|
1387
1396
|
}
|
|
1388
1397
|
/**
|
|
1389
1398
|
* Adds practitioner information to a clinic when a new practitioner is created
|
|
@@ -1714,12 +1723,427 @@ var PractitionerAggregationService = class {
|
|
|
1714
1723
|
}
|
|
1715
1724
|
};
|
|
1716
1725
|
|
|
1717
|
-
// src/admin/aggregation/
|
|
1726
|
+
// src/admin/aggregation/practitioner-invite/practitioner-invite.aggregation.service.ts
|
|
1718
1727
|
import * as admin5 from "firebase-admin";
|
|
1728
|
+
var PractitionerInviteAggregationService = class {
|
|
1729
|
+
/**
|
|
1730
|
+
* Constructor for PractitionerInviteAggregationService.
|
|
1731
|
+
* @param firestore Optional Firestore instance. If not provided, it uses the default admin SDK instance.
|
|
1732
|
+
*/
|
|
1733
|
+
constructor(firestore17) {
|
|
1734
|
+
this.db = firestore17 || admin5.firestore();
|
|
1735
|
+
Logger.info("[PractitionerInviteAggregationService] Initialized.");
|
|
1736
|
+
}
|
|
1737
|
+
/**
|
|
1738
|
+
* Handles side effects when a practitioner invite is first created.
|
|
1739
|
+
* This function would typically be called by a Firestore onCreate trigger.
|
|
1740
|
+
* @param {PractitionerInvite} invite - The newly created PractitionerInvite object.
|
|
1741
|
+
* @returns {Promise<void>}
|
|
1742
|
+
*/
|
|
1743
|
+
async handleInviteCreate(invite) {
|
|
1744
|
+
Logger.info(
|
|
1745
|
+
`[PractitionerInviteAggService] Handling CREATE for invite: ${invite.id}, practitioner: ${invite.practitionerId}, clinic: ${invite.clinicId}, status: ${invite.status}`
|
|
1746
|
+
);
|
|
1747
|
+
try {
|
|
1748
|
+
Logger.info(
|
|
1749
|
+
`[PractitionerInviteAggService] Successfully processed CREATE for invite: ${invite.id}`
|
|
1750
|
+
);
|
|
1751
|
+
} catch (error) {
|
|
1752
|
+
Logger.error(
|
|
1753
|
+
`[PractitionerInviteAggService] Error in handleInviteCreate for invite ${invite.id}:`,
|
|
1754
|
+
error
|
|
1755
|
+
);
|
|
1756
|
+
throw error;
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
/**
|
|
1760
|
+
* Handles side effects when a practitioner invite is updated.
|
|
1761
|
+
* This function would typically be called by a Firestore onUpdate trigger.
|
|
1762
|
+
* @param {PractitionerInvite} before - The PractitionerInvite object before the update.
|
|
1763
|
+
* @param {PractitionerInvite} after - The PractitionerInvite object after the update.
|
|
1764
|
+
* @returns {Promise<void>}
|
|
1765
|
+
*/
|
|
1766
|
+
async handleInviteUpdate(before, after) {
|
|
1767
|
+
Logger.info(
|
|
1768
|
+
`[PractitionerInviteAggService] Handling UPDATE for invite: ${after.id}. Status ${before.status} -> ${after.status}`
|
|
1769
|
+
);
|
|
1770
|
+
try {
|
|
1771
|
+
const statusChanged = before.status !== after.status;
|
|
1772
|
+
if (statusChanged) {
|
|
1773
|
+
Logger.info(
|
|
1774
|
+
`[PractitionerInviteAggService] Status changed for invite ${after.id}: ${before.status} -> ${after.status}`
|
|
1775
|
+
);
|
|
1776
|
+
if (before.status === "pending" /* PENDING */ && after.status === "accepted" /* ACCEPTED */) {
|
|
1777
|
+
Logger.info(
|
|
1778
|
+
`[PractitionerInviteAggService] Invite ${after.id} PENDING -> ACCEPTED. Adding practitioner to clinic.`
|
|
1779
|
+
);
|
|
1780
|
+
await this.handleInviteAccepted(after);
|
|
1781
|
+
} else if (before.status === "pending" /* PENDING */ && after.status === "rejected" /* REJECTED */) {
|
|
1782
|
+
Logger.info(
|
|
1783
|
+
`[PractitionerInviteAggService] Invite ${after.id} PENDING -> REJECTED.`
|
|
1784
|
+
);
|
|
1785
|
+
await this.handleInviteRejected(after);
|
|
1786
|
+
} else if (before.status === "pending" /* PENDING */ && after.status === "cancelled" /* CANCELLED */) {
|
|
1787
|
+
Logger.info(
|
|
1788
|
+
`[PractitionerInviteAggService] Invite ${after.id} PENDING -> CANCELLED.`
|
|
1789
|
+
);
|
|
1790
|
+
await this.handleInviteCancelled(after);
|
|
1791
|
+
}
|
|
1792
|
+
}
|
|
1793
|
+
Logger.info(
|
|
1794
|
+
`[PractitionerInviteAggService] Successfully processed UPDATE for invite: ${after.id}`
|
|
1795
|
+
);
|
|
1796
|
+
} catch (error) {
|
|
1797
|
+
Logger.error(
|
|
1798
|
+
`[PractitionerInviteAggService] Error in handleInviteUpdate for invite ${after.id}:`,
|
|
1799
|
+
error
|
|
1800
|
+
);
|
|
1801
|
+
throw error;
|
|
1802
|
+
}
|
|
1803
|
+
}
|
|
1804
|
+
/**
|
|
1805
|
+
* Handles side effects when a practitioner invite is deleted.
|
|
1806
|
+
* @param deletedInvite - The PractitionerInvite object that was deleted.
|
|
1807
|
+
* @returns {Promise<void>}
|
|
1808
|
+
*/
|
|
1809
|
+
async handleInviteDelete(deletedInvite) {
|
|
1810
|
+
Logger.info(
|
|
1811
|
+
`[PractitionerInviteAggService] Handling DELETE for invite: ${deletedInvite.id}`
|
|
1812
|
+
);
|
|
1813
|
+
try {
|
|
1814
|
+
Logger.info(
|
|
1815
|
+
`[PractitionerInviteAggService] Successfully processed DELETE for invite: ${deletedInvite.id}`
|
|
1816
|
+
);
|
|
1817
|
+
} catch (error) {
|
|
1818
|
+
Logger.error(
|
|
1819
|
+
`[PractitionerInviteAggService] Error in handleInviteDelete for invite ${deletedInvite.id}:`,
|
|
1820
|
+
error
|
|
1821
|
+
);
|
|
1822
|
+
throw error;
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
// --- Private Helper Methods ---
|
|
1826
|
+
/**
|
|
1827
|
+
* Handles the business logic when a practitioner accepts an invite.
|
|
1828
|
+
* This includes adding the practitioner to the clinic and the clinic to the practitioner.
|
|
1829
|
+
* @param {PractitionerInvite} invite - The accepted invite
|
|
1830
|
+
* @returns {Promise<void>}
|
|
1831
|
+
*/
|
|
1832
|
+
async handleInviteAccepted(invite) {
|
|
1833
|
+
var _a, _b, _c, _d;
|
|
1834
|
+
Logger.info(
|
|
1835
|
+
`[PractitionerInviteAggService] Processing accepted invite ${invite.id} for practitioner ${invite.practitionerId} and clinic ${invite.clinicId}`
|
|
1836
|
+
);
|
|
1837
|
+
try {
|
|
1838
|
+
const [practitioner, clinic] = await Promise.all([
|
|
1839
|
+
this.fetchPractitionerById(invite.practitionerId),
|
|
1840
|
+
this.fetchClinicById(invite.clinicId)
|
|
1841
|
+
]);
|
|
1842
|
+
if (!practitioner) {
|
|
1843
|
+
throw new Error(
|
|
1844
|
+
`Practitioner ${invite.practitionerId} not found during invite acceptance`
|
|
1845
|
+
);
|
|
1846
|
+
}
|
|
1847
|
+
if (!clinic) {
|
|
1848
|
+
throw new Error(
|
|
1849
|
+
`Clinic ${invite.clinicId} not found during invite acceptance`
|
|
1850
|
+
);
|
|
1851
|
+
}
|
|
1852
|
+
const doctorInfo = {
|
|
1853
|
+
id: practitioner.id,
|
|
1854
|
+
name: `${practitioner.basicInfo.firstName} ${practitioner.basicInfo.lastName}`,
|
|
1855
|
+
description: practitioner.basicInfo.bio || void 0,
|
|
1856
|
+
photo: typeof practitioner.basicInfo.profileImageUrl === "object" && practitioner.basicInfo.profileImageUrl !== null ? ((_a = practitioner.basicInfo.profileImageUrl) == null ? void 0 : _a.url) || null : typeof practitioner.basicInfo.profileImageUrl === "string" ? practitioner.basicInfo.profileImageUrl : null,
|
|
1857
|
+
rating: ((_b = practitioner.reviewInfo) == null ? void 0 : _b.averageRating) || 0,
|
|
1858
|
+
services: ((_c = practitioner.proceduresInfo) == null ? void 0 : _c.map((proc) => proc.name)) || []
|
|
1859
|
+
// Use procedure names as services
|
|
1860
|
+
};
|
|
1861
|
+
const clinicInfo = {
|
|
1862
|
+
id: clinic.id,
|
|
1863
|
+
featuredPhoto: typeof clinic.coverPhoto === "object" && clinic.coverPhoto !== null ? ((_d = clinic.coverPhoto) == null ? void 0 : _d.url) || "" : typeof clinic.coverPhoto === "string" ? clinic.coverPhoto : "",
|
|
1864
|
+
name: clinic.name,
|
|
1865
|
+
description: clinic.description || null,
|
|
1866
|
+
location: clinic.location,
|
|
1867
|
+
contactInfo: clinic.contactInfo
|
|
1868
|
+
};
|
|
1869
|
+
const isPractitionerInClinic = clinic.doctors.includes(practitioner.id);
|
|
1870
|
+
const isClinicInPractitioner = practitioner.clinics.includes(clinic.id);
|
|
1871
|
+
if (!isPractitionerInClinic) {
|
|
1872
|
+
Logger.info(
|
|
1873
|
+
`[PractitionerInviteAggService] Adding practitioner ${practitioner.id} to clinic ${clinic.id}`
|
|
1874
|
+
);
|
|
1875
|
+
await this.addPractitionerToClinic(clinic.id, doctorInfo);
|
|
1876
|
+
} else {
|
|
1877
|
+
Logger.info(
|
|
1878
|
+
`[PractitionerInviteAggService] Practitioner ${practitioner.id} already in clinic ${clinic.id}, updating info`
|
|
1879
|
+
);
|
|
1880
|
+
await this.updatePractitionerInfoInClinic(clinic.id, doctorInfo);
|
|
1881
|
+
}
|
|
1882
|
+
if (!isClinicInPractitioner) {
|
|
1883
|
+
Logger.info(
|
|
1884
|
+
`[PractitionerInviteAggService] Adding clinic ${clinic.id} to practitioner ${practitioner.id}`
|
|
1885
|
+
);
|
|
1886
|
+
await this.addClinicToPractitioner(practitioner.id, clinicInfo, invite);
|
|
1887
|
+
} else {
|
|
1888
|
+
Logger.info(
|
|
1889
|
+
`[PractitionerInviteAggService] Clinic ${clinic.id} already in practitioner ${practitioner.id}, updating working hours`
|
|
1890
|
+
);
|
|
1891
|
+
await this.updatePractitionerWorkingHours(practitioner.id, invite);
|
|
1892
|
+
}
|
|
1893
|
+
Logger.info(
|
|
1894
|
+
`[PractitionerInviteAggService] Successfully processed accepted invite ${invite.id}`
|
|
1895
|
+
);
|
|
1896
|
+
} catch (error) {
|
|
1897
|
+
Logger.error(
|
|
1898
|
+
`[PractitionerInviteAggService] Error processing accepted invite ${invite.id}:`,
|
|
1899
|
+
error
|
|
1900
|
+
);
|
|
1901
|
+
throw error;
|
|
1902
|
+
}
|
|
1903
|
+
}
|
|
1904
|
+
/**
|
|
1905
|
+
* Handles the business logic when a practitioner rejects an invite.
|
|
1906
|
+
* @param {PractitionerInvite} invite - The rejected invite
|
|
1907
|
+
* @returns {Promise<void>}
|
|
1908
|
+
*/
|
|
1909
|
+
async handleInviteRejected(invite) {
|
|
1910
|
+
Logger.info(
|
|
1911
|
+
`[PractitionerInviteAggService] Processing rejected invite ${invite.id}`
|
|
1912
|
+
);
|
|
1913
|
+
try {
|
|
1914
|
+
Logger.info(
|
|
1915
|
+
`[PractitionerInviteAggService] Successfully processed rejected invite ${invite.id}`
|
|
1916
|
+
);
|
|
1917
|
+
} catch (error) {
|
|
1918
|
+
Logger.error(
|
|
1919
|
+
`[PractitionerInviteAggService] Error processing rejected invite ${invite.id}:`,
|
|
1920
|
+
error
|
|
1921
|
+
);
|
|
1922
|
+
throw error;
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
/**
|
|
1926
|
+
* Handles the business logic when an invite is cancelled by admin.
|
|
1927
|
+
* @param {PractitionerInvite} invite - The cancelled invite
|
|
1928
|
+
* @returns {Promise<void>}
|
|
1929
|
+
*/
|
|
1930
|
+
async handleInviteCancelled(invite) {
|
|
1931
|
+
Logger.info(
|
|
1932
|
+
`[PractitionerInviteAggService] Processing cancelled invite ${invite.id}`
|
|
1933
|
+
);
|
|
1934
|
+
try {
|
|
1935
|
+
Logger.info(
|
|
1936
|
+
`[PractitionerInviteAggService] Successfully processed cancelled invite ${invite.id}`
|
|
1937
|
+
);
|
|
1938
|
+
} catch (error) {
|
|
1939
|
+
Logger.error(
|
|
1940
|
+
`[PractitionerInviteAggService] Error processing cancelled invite ${invite.id}:`,
|
|
1941
|
+
error
|
|
1942
|
+
);
|
|
1943
|
+
throw error;
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1946
|
+
/**
|
|
1947
|
+
* Adds practitioner information to a clinic when an invite is accepted.
|
|
1948
|
+
* @param clinicId - ID of the clinic to update
|
|
1949
|
+
* @param doctorInfo - Doctor information to add to the clinic
|
|
1950
|
+
* @returns {Promise<void>}
|
|
1951
|
+
*/
|
|
1952
|
+
async addPractitionerToClinic(clinicId, doctorInfo) {
|
|
1953
|
+
Logger.info(
|
|
1954
|
+
`[PractitionerInviteAggService] Adding practitioner ${doctorInfo.id} to clinic ${clinicId}`
|
|
1955
|
+
);
|
|
1956
|
+
try {
|
|
1957
|
+
const clinicRef = this.db.collection(CLINICS_COLLECTION).doc(clinicId);
|
|
1958
|
+
await clinicRef.update({
|
|
1959
|
+
doctors: admin5.firestore.FieldValue.arrayUnion(doctorInfo.id),
|
|
1960
|
+
doctorsInfo: admin5.firestore.FieldValue.arrayUnion(doctorInfo),
|
|
1961
|
+
updatedAt: admin5.firestore.FieldValue.serverTimestamp()
|
|
1962
|
+
});
|
|
1963
|
+
Logger.info(
|
|
1964
|
+
`[PractitionerInviteAggService] Successfully added practitioner ${doctorInfo.id} to clinic ${clinicId}`
|
|
1965
|
+
);
|
|
1966
|
+
} catch (error) {
|
|
1967
|
+
Logger.error(
|
|
1968
|
+
`[PractitionerInviteAggService] Error adding practitioner ${doctorInfo.id} to clinic ${clinicId}:`,
|
|
1969
|
+
error
|
|
1970
|
+
);
|
|
1971
|
+
throw error;
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
/**
|
|
1975
|
+
* Updates practitioner information in a clinic.
|
|
1976
|
+
* @param clinicId - ID of the clinic to update
|
|
1977
|
+
* @param doctorInfo - Updated doctor information
|
|
1978
|
+
* @returns {Promise<void>}
|
|
1979
|
+
*/
|
|
1980
|
+
async updatePractitionerInfoInClinic(clinicId, doctorInfo) {
|
|
1981
|
+
Logger.info(
|
|
1982
|
+
`[PractitionerInviteAggService] Updating practitioner ${doctorInfo.id} info in clinic ${clinicId}`
|
|
1983
|
+
);
|
|
1984
|
+
try {
|
|
1985
|
+
const clinicRef = this.db.collection(CLINICS_COLLECTION).doc(clinicId);
|
|
1986
|
+
const clinicDoc = await clinicRef.get();
|
|
1987
|
+
if (clinicDoc.exists) {
|
|
1988
|
+
const clinicData = clinicDoc.data();
|
|
1989
|
+
const currentDoctorsInfo = (clinicData == null ? void 0 : clinicData.doctorsInfo) || [];
|
|
1990
|
+
const filteredDoctorsInfo = currentDoctorsInfo.filter(
|
|
1991
|
+
(doctor) => doctor.id !== doctorInfo.id
|
|
1992
|
+
);
|
|
1993
|
+
const updatedDoctorsInfo = [...filteredDoctorsInfo, doctorInfo];
|
|
1994
|
+
await clinicRef.update({
|
|
1995
|
+
doctorsInfo: updatedDoctorsInfo,
|
|
1996
|
+
updatedAt: admin5.firestore.FieldValue.serverTimestamp()
|
|
1997
|
+
});
|
|
1998
|
+
Logger.info(
|
|
1999
|
+
`[PractitionerInviteAggService] Successfully updated practitioner ${doctorInfo.id} info in clinic ${clinicId}`
|
|
2000
|
+
);
|
|
2001
|
+
} else {
|
|
2002
|
+
Logger.warn(
|
|
2003
|
+
`[PractitionerInviteAggService] Clinic ${clinicId} not found for doctor info update`
|
|
2004
|
+
);
|
|
2005
|
+
}
|
|
2006
|
+
} catch (error) {
|
|
2007
|
+
Logger.error(
|
|
2008
|
+
`[PractitionerInviteAggService] Error updating practitioner ${doctorInfo.id} info in clinic ${clinicId}:`,
|
|
2009
|
+
error
|
|
2010
|
+
);
|
|
2011
|
+
throw error;
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
/**
|
|
2015
|
+
* Adds a clinic to a practitioner's profile with working hours from the invite.
|
|
2016
|
+
* @param {string} practitionerId - The practitioner ID
|
|
2017
|
+
* @param {ClinicInfo} clinicInfo - The clinic information
|
|
2018
|
+
* @param {PractitionerInvite} invite - The accepted invite containing working hours
|
|
2019
|
+
* @returns {Promise<void>}
|
|
2020
|
+
*/
|
|
2021
|
+
async addClinicToPractitioner(practitionerId, clinicInfo, invite) {
|
|
2022
|
+
Logger.info(
|
|
2023
|
+
`[PractitionerInviteAggService] Adding clinic ${clinicInfo.id} to practitioner ${practitionerId}`
|
|
2024
|
+
);
|
|
2025
|
+
try {
|
|
2026
|
+
const practitionerRef = this.db.collection(PRACTITIONERS_COLLECTION).doc(practitionerId);
|
|
2027
|
+
const workingHours = {
|
|
2028
|
+
clinicId: clinicInfo.id,
|
|
2029
|
+
workingHours: invite.proposedWorkingHours,
|
|
2030
|
+
isActive: true,
|
|
2031
|
+
createdAt: admin5.firestore.Timestamp.now(),
|
|
2032
|
+
updatedAt: admin5.firestore.Timestamp.now()
|
|
2033
|
+
};
|
|
2034
|
+
await practitionerRef.update({
|
|
2035
|
+
clinics: admin5.firestore.FieldValue.arrayUnion(clinicInfo.id),
|
|
2036
|
+
clinicsInfo: admin5.firestore.FieldValue.arrayUnion(clinicInfo),
|
|
2037
|
+
clinicWorkingHours: admin5.firestore.FieldValue.arrayUnion(workingHours),
|
|
2038
|
+
updatedAt: admin5.firestore.FieldValue.serverTimestamp()
|
|
2039
|
+
});
|
|
2040
|
+
Logger.info(
|
|
2041
|
+
`[PractitionerInviteAggService] Successfully added clinic ${clinicInfo.id} to practitioner ${practitionerId}`
|
|
2042
|
+
);
|
|
2043
|
+
} catch (error) {
|
|
2044
|
+
Logger.error(
|
|
2045
|
+
`[PractitionerInviteAggService] Error adding clinic to practitioner:`,
|
|
2046
|
+
error
|
|
2047
|
+
);
|
|
2048
|
+
throw error;
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
/**
|
|
2052
|
+
* Updates the working hours for an existing practitioner-clinic relationship.
|
|
2053
|
+
* @param {string} practitionerId - The practitioner ID
|
|
2054
|
+
* @param {PractitionerInvite} invite - The accepted invite containing new working hours
|
|
2055
|
+
* @returns {Promise<void>}
|
|
2056
|
+
*/
|
|
2057
|
+
async updatePractitionerWorkingHours(practitionerId, invite) {
|
|
2058
|
+
Logger.info(
|
|
2059
|
+
`[PractitionerInviteAggService] Updating working hours for practitioner ${practitionerId} at clinic ${invite.clinicId}`
|
|
2060
|
+
);
|
|
2061
|
+
try {
|
|
2062
|
+
const practitionerRef = this.db.collection(PRACTITIONERS_COLLECTION).doc(practitionerId);
|
|
2063
|
+
const practitionerDoc = await practitionerRef.get();
|
|
2064
|
+
if (!practitionerDoc.exists) {
|
|
2065
|
+
throw new Error(`Practitioner ${practitionerId} not found`);
|
|
2066
|
+
}
|
|
2067
|
+
const practitionerData = practitionerDoc.data();
|
|
2068
|
+
const currentWorkingHours = practitionerData.clinicWorkingHours || [];
|
|
2069
|
+
const updatedWorkingHours = currentWorkingHours.map((wh) => {
|
|
2070
|
+
if (wh.clinicId === invite.clinicId) {
|
|
2071
|
+
return {
|
|
2072
|
+
...wh,
|
|
2073
|
+
workingHours: invite.proposedWorkingHours,
|
|
2074
|
+
isActive: true,
|
|
2075
|
+
updatedAt: admin5.firestore.Timestamp.now()
|
|
2076
|
+
};
|
|
2077
|
+
}
|
|
2078
|
+
return wh;
|
|
2079
|
+
});
|
|
2080
|
+
if (!updatedWorkingHours.some((wh) => wh.clinicId === invite.clinicId)) {
|
|
2081
|
+
updatedWorkingHours.push({
|
|
2082
|
+
clinicId: invite.clinicId,
|
|
2083
|
+
workingHours: invite.proposedWorkingHours,
|
|
2084
|
+
isActive: true,
|
|
2085
|
+
createdAt: admin5.firestore.Timestamp.now(),
|
|
2086
|
+
updatedAt: admin5.firestore.Timestamp.now()
|
|
2087
|
+
});
|
|
2088
|
+
}
|
|
2089
|
+
await practitionerRef.update({
|
|
2090
|
+
clinicWorkingHours: updatedWorkingHours,
|
|
2091
|
+
updatedAt: admin5.firestore.FieldValue.serverTimestamp()
|
|
2092
|
+
});
|
|
2093
|
+
Logger.info(
|
|
2094
|
+
`[PractitionerInviteAggService] Successfully updated working hours for practitioner ${practitionerId} at clinic ${invite.clinicId}`
|
|
2095
|
+
);
|
|
2096
|
+
} catch (error) {
|
|
2097
|
+
Logger.error(
|
|
2098
|
+
`[PractitionerInviteAggService] Error updating practitioner working hours:`,
|
|
2099
|
+
error
|
|
2100
|
+
);
|
|
2101
|
+
throw error;
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
// --- Data Fetching Helpers ---
|
|
2105
|
+
/**
|
|
2106
|
+
* Fetches a practitioner by ID.
|
|
2107
|
+
* @param practitionerId The practitioner ID.
|
|
2108
|
+
* @returns {Promise<Practitioner | null>} The practitioner or null if not found.
|
|
2109
|
+
*/
|
|
2110
|
+
async fetchPractitionerById(practitionerId) {
|
|
2111
|
+
try {
|
|
2112
|
+
const doc = await this.db.collection(PRACTITIONERS_COLLECTION).doc(practitionerId).get();
|
|
2113
|
+
return doc.exists ? doc.data() : null;
|
|
2114
|
+
} catch (error) {
|
|
2115
|
+
Logger.error(
|
|
2116
|
+
`[PractitionerInviteAggService] Error fetching practitioner ${practitionerId}:`,
|
|
2117
|
+
error
|
|
2118
|
+
);
|
|
2119
|
+
return null;
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
/**
|
|
2123
|
+
* Fetches a clinic by ID.
|
|
2124
|
+
* @param clinicId The clinic ID.
|
|
2125
|
+
* @returns {Promise<Clinic | null>} The clinic or null if not found.
|
|
2126
|
+
*/
|
|
2127
|
+
async fetchClinicById(clinicId) {
|
|
2128
|
+
try {
|
|
2129
|
+
const doc = await this.db.collection(CLINICS_COLLECTION).doc(clinicId).get();
|
|
2130
|
+
return doc.exists ? doc.data() : null;
|
|
2131
|
+
} catch (error) {
|
|
2132
|
+
Logger.error(
|
|
2133
|
+
`[PractitionerInviteAggService] Error fetching clinic ${clinicId}:`,
|
|
2134
|
+
error
|
|
2135
|
+
);
|
|
2136
|
+
return null;
|
|
2137
|
+
}
|
|
2138
|
+
}
|
|
2139
|
+
};
|
|
2140
|
+
|
|
2141
|
+
// src/admin/aggregation/procedure/procedure.aggregation.service.ts
|
|
2142
|
+
import * as admin6 from "firebase-admin";
|
|
1719
2143
|
var CALENDAR_SUBCOLLECTION_ID3 = "calendar";
|
|
1720
2144
|
var ProcedureAggregationService = class {
|
|
1721
|
-
constructor(
|
|
1722
|
-
this.db =
|
|
2145
|
+
constructor(firestore17) {
|
|
2146
|
+
this.db = firestore17 || admin6.firestore();
|
|
1723
2147
|
}
|
|
1724
2148
|
/**
|
|
1725
2149
|
* Adds procedure information to a practitioner when a new procedure is created
|
|
@@ -1743,9 +2167,9 @@ var ProcedureAggregationService = class {
|
|
|
1743
2167
|
const practitionerRef = this.db.collection(PRACTITIONERS_COLLECTION).doc(practitionerId);
|
|
1744
2168
|
try {
|
|
1745
2169
|
const updateData = {
|
|
1746
|
-
procedureIds:
|
|
1747
|
-
proceduresInfo:
|
|
1748
|
-
updatedAt:
|
|
2170
|
+
procedureIds: admin6.firestore.FieldValue.arrayUnion(procedureId),
|
|
2171
|
+
proceduresInfo: admin6.firestore.FieldValue.arrayUnion(procedureSummary),
|
|
2172
|
+
updatedAt: admin6.firestore.FieldValue.serverTimestamp()
|
|
1749
2173
|
};
|
|
1750
2174
|
if (isFreeConsultation) {
|
|
1751
2175
|
await this.db.runTransaction(async (transaction) => {
|
|
@@ -1808,9 +2232,9 @@ var ProcedureAggregationService = class {
|
|
|
1808
2232
|
const clinicRef = this.db.collection(CLINICS_COLLECTION).doc(clinicId);
|
|
1809
2233
|
try {
|
|
1810
2234
|
await clinicRef.update({
|
|
1811
|
-
procedures:
|
|
1812
|
-
proceduresInfo:
|
|
1813
|
-
updatedAt:
|
|
2235
|
+
procedures: admin6.firestore.FieldValue.arrayUnion(procedureId),
|
|
2236
|
+
proceduresInfo: admin6.firestore.FieldValue.arrayUnion(procedureSummary),
|
|
2237
|
+
updatedAt: admin6.firestore.FieldValue.serverTimestamp()
|
|
1814
2238
|
});
|
|
1815
2239
|
console.log(
|
|
1816
2240
|
`[ProcedureAggregationService] Successfully added procedure ${procedureId} to clinic ${clinicId}.`
|
|
@@ -1862,7 +2286,7 @@ var ProcedureAggregationService = class {
|
|
|
1862
2286
|
updatedProceduresInfo.push(procedureSummary);
|
|
1863
2287
|
transaction.update(practitionerRef, {
|
|
1864
2288
|
proceduresInfo: updatedProceduresInfo,
|
|
1865
|
-
updatedAt:
|
|
2289
|
+
updatedAt: admin6.firestore.FieldValue.serverTimestamp()
|
|
1866
2290
|
});
|
|
1867
2291
|
});
|
|
1868
2292
|
console.log(
|
|
@@ -1915,7 +2339,7 @@ var ProcedureAggregationService = class {
|
|
|
1915
2339
|
updatedProceduresInfo.push(procedureSummary);
|
|
1916
2340
|
transaction.update(clinicRef, {
|
|
1917
2341
|
proceduresInfo: updatedProceduresInfo,
|
|
1918
|
-
updatedAt:
|
|
2342
|
+
updatedAt: admin6.firestore.FieldValue.serverTimestamp()
|
|
1919
2343
|
});
|
|
1920
2344
|
});
|
|
1921
2345
|
console.log(
|
|
@@ -1945,7 +2369,7 @@ var ProcedureAggregationService = class {
|
|
|
1945
2369
|
console.log(
|
|
1946
2370
|
`[ProcedureAggregationService] Querying upcoming calendar events for procedure ${procedureId} to update procedure info.`
|
|
1947
2371
|
);
|
|
1948
|
-
const now =
|
|
2372
|
+
const now = admin6.firestore.Timestamp.now();
|
|
1949
2373
|
const calendarEventsQuery = this.db.collectionGroup(CALENDAR_SUBCOLLECTION_ID3).where("procedureId", "==", procedureId).where("eventTime.start", ">", now);
|
|
1950
2374
|
try {
|
|
1951
2375
|
const snapshot = await calendarEventsQuery.get();
|
|
@@ -1962,7 +2386,7 @@ var ProcedureAggregationService = class {
|
|
|
1962
2386
|
);
|
|
1963
2387
|
batch.update(doc.ref, {
|
|
1964
2388
|
procedureInfo,
|
|
1965
|
-
updatedAt:
|
|
2389
|
+
updatedAt: admin6.firestore.FieldValue.serverTimestamp()
|
|
1966
2390
|
});
|
|
1967
2391
|
});
|
|
1968
2392
|
await batch.commit();
|
|
@@ -1992,7 +2416,7 @@ var ProcedureAggregationService = class {
|
|
|
1992
2416
|
console.log(
|
|
1993
2417
|
`[ProcedureAggregationService] Querying upcoming calendar events for procedure ${procedureId} to cancel.`
|
|
1994
2418
|
);
|
|
1995
|
-
const now =
|
|
2419
|
+
const now = admin6.firestore.Timestamp.now();
|
|
1996
2420
|
const calendarEventsQuery = this.db.collectionGroup(CALENDAR_SUBCOLLECTION_ID3).where("procedureId", "==", procedureId).where("eventTime.start", ">", now);
|
|
1997
2421
|
try {
|
|
1998
2422
|
const snapshot = await calendarEventsQuery.get();
|
|
@@ -2010,7 +2434,7 @@ var ProcedureAggregationService = class {
|
|
|
2010
2434
|
batch.update(doc.ref, {
|
|
2011
2435
|
status: "CANCELED",
|
|
2012
2436
|
cancelReason: "Procedure deleted or inactivated",
|
|
2013
|
-
updatedAt:
|
|
2437
|
+
updatedAt: admin6.firestore.FieldValue.serverTimestamp()
|
|
2014
2438
|
});
|
|
2015
2439
|
});
|
|
2016
2440
|
await batch.commit();
|
|
@@ -2067,9 +2491,9 @@ var ProcedureAggregationService = class {
|
|
|
2067
2491
|
(p) => p.id !== procedureId
|
|
2068
2492
|
);
|
|
2069
2493
|
const updateData = {
|
|
2070
|
-
procedureIds:
|
|
2494
|
+
procedureIds: admin6.firestore.FieldValue.arrayRemove(procedureId),
|
|
2071
2495
|
proceduresInfo: updatedProceduresInfo,
|
|
2072
|
-
updatedAt:
|
|
2496
|
+
updatedAt: admin6.firestore.FieldValue.serverTimestamp()
|
|
2073
2497
|
};
|
|
2074
2498
|
if (isFreeConsultation && procedureClinicId) {
|
|
2075
2499
|
const currentFreeConsultations = practitionerData.freeConsultations || {};
|
|
@@ -2135,9 +2559,9 @@ var ProcedureAggregationService = class {
|
|
|
2135
2559
|
(p) => p.id !== procedureId
|
|
2136
2560
|
);
|
|
2137
2561
|
transaction.update(clinicRef, {
|
|
2138
|
-
procedures:
|
|
2562
|
+
procedures: admin6.firestore.FieldValue.arrayRemove(procedureId),
|
|
2139
2563
|
proceduresInfo: updatedProceduresInfo,
|
|
2140
|
-
updatedAt:
|
|
2564
|
+
updatedAt: admin6.firestore.FieldValue.serverTimestamp()
|
|
2141
2565
|
});
|
|
2142
2566
|
});
|
|
2143
2567
|
console.log(
|
|
@@ -2214,7 +2638,7 @@ var ProcedureAggregationService = class {
|
|
|
2214
2638
|
}
|
|
2215
2639
|
transaction.update(practitionerRef, {
|
|
2216
2640
|
freeConsultations: updatedFreeConsultations,
|
|
2217
|
-
updatedAt:
|
|
2641
|
+
updatedAt: admin6.firestore.FieldValue.serverTimestamp()
|
|
2218
2642
|
});
|
|
2219
2643
|
});
|
|
2220
2644
|
console.log(
|
|
@@ -2231,11 +2655,11 @@ var ProcedureAggregationService = class {
|
|
|
2231
2655
|
};
|
|
2232
2656
|
|
|
2233
2657
|
// src/admin/aggregation/patient/patient.aggregation.service.ts
|
|
2234
|
-
import * as
|
|
2658
|
+
import * as admin7 from "firebase-admin";
|
|
2235
2659
|
var CALENDAR_SUBCOLLECTION_ID4 = "calendar";
|
|
2236
2660
|
var PatientAggregationService = class {
|
|
2237
|
-
constructor(
|
|
2238
|
-
this.db =
|
|
2661
|
+
constructor(firestore17) {
|
|
2662
|
+
this.db = firestore17 || admin7.firestore();
|
|
2239
2663
|
}
|
|
2240
2664
|
// --- Methods for Patient Creation --- >
|
|
2241
2665
|
// No specific aggregations defined for patient creation in the plan.
|
|
@@ -2256,7 +2680,7 @@ var PatientAggregationService = class {
|
|
|
2256
2680
|
console.log(
|
|
2257
2681
|
`[PatientAggregationService] Querying upcoming calendar events for patient ${patientId} to update patient info.`
|
|
2258
2682
|
);
|
|
2259
|
-
const now =
|
|
2683
|
+
const now = admin7.firestore.Timestamp.now();
|
|
2260
2684
|
const calendarEventsQuery = this.db.collectionGroup(CALENDAR_SUBCOLLECTION_ID4).where("patientId", "==", patientId).where("eventTime.start", ">", now);
|
|
2261
2685
|
try {
|
|
2262
2686
|
const snapshot = await calendarEventsQuery.get();
|
|
@@ -2273,7 +2697,7 @@ var PatientAggregationService = class {
|
|
|
2273
2697
|
);
|
|
2274
2698
|
batch.update(doc.ref, {
|
|
2275
2699
|
patientInfo,
|
|
2276
|
-
updatedAt:
|
|
2700
|
+
updatedAt: admin7.firestore.FieldValue.serverTimestamp()
|
|
2277
2701
|
});
|
|
2278
2702
|
});
|
|
2279
2703
|
await batch.commit();
|
|
@@ -2304,7 +2728,7 @@ var PatientAggregationService = class {
|
|
|
2304
2728
|
console.log(
|
|
2305
2729
|
`[PatientAggregationService] Querying upcoming calendar events for patient ${patientId} to cancel.`
|
|
2306
2730
|
);
|
|
2307
|
-
const now =
|
|
2731
|
+
const now = admin7.firestore.Timestamp.now();
|
|
2308
2732
|
const calendarEventsQuery = this.db.collectionGroup(CALENDAR_SUBCOLLECTION_ID4).where("patientId", "==", patientId).where("eventTime.start", ">", now);
|
|
2309
2733
|
try {
|
|
2310
2734
|
const snapshot = await calendarEventsQuery.get();
|
|
@@ -2322,7 +2746,7 @@ var PatientAggregationService = class {
|
|
|
2322
2746
|
batch.update(doc.ref, {
|
|
2323
2747
|
status: "CANCELED",
|
|
2324
2748
|
cancelReason: "Patient deleted",
|
|
2325
|
-
updatedAt:
|
|
2749
|
+
updatedAt: admin7.firestore.FieldValue.serverTimestamp()
|
|
2326
2750
|
});
|
|
2327
2751
|
});
|
|
2328
2752
|
await batch.commit();
|
|
@@ -2340,7 +2764,7 @@ var PatientAggregationService = class {
|
|
|
2340
2764
|
};
|
|
2341
2765
|
|
|
2342
2766
|
// src/admin/aggregation/appointment/appointment.aggregation.service.ts
|
|
2343
|
-
import * as
|
|
2767
|
+
import * as admin11 from "firebase-admin";
|
|
2344
2768
|
|
|
2345
2769
|
// src/types/patient/patient-requirements.ts
|
|
2346
2770
|
var PatientInstructionStatus = /* @__PURE__ */ ((PatientInstructionStatus2) => {
|
|
@@ -2365,10 +2789,10 @@ var PatientRequirementOverallStatus = /* @__PURE__ */ ((PatientRequirementOveral
|
|
|
2365
2789
|
var PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME = "patientRequirements";
|
|
2366
2790
|
|
|
2367
2791
|
// src/admin/requirements/patient-requirements.admin.service.ts
|
|
2368
|
-
import * as
|
|
2792
|
+
import * as admin8 from "firebase-admin";
|
|
2369
2793
|
var PatientRequirementsAdminService = class {
|
|
2370
|
-
constructor(
|
|
2371
|
-
this.db =
|
|
2794
|
+
constructor(firestore17) {
|
|
2795
|
+
this.db = firestore17 || admin8.firestore();
|
|
2372
2796
|
this.notificationsAdmin = new NotificationsAdmin(this.db);
|
|
2373
2797
|
}
|
|
2374
2798
|
/**
|
|
@@ -2411,7 +2835,7 @@ var PatientRequirementsAdminService = class {
|
|
|
2411
2835
|
const previousInstruction = previousInstanceData == null ? void 0 : previousInstanceData.instructions.find(
|
|
2412
2836
|
(pi) => pi.instructionId === currentInstruction.instructionId
|
|
2413
2837
|
);
|
|
2414
|
-
const adminTsNow =
|
|
2838
|
+
const adminTsNow = admin8.firestore.Timestamp.now();
|
|
2415
2839
|
if (instance.overallStatus === "cancelledAppointment" /* CANCELLED_APPOINTMENT */ || instance.overallStatus === "supersededReschedule" /* SUPERSEDED_RESCHEDULE */ || currentInstruction.status === "cancelled" /* CANCELLED */) {
|
|
2416
2840
|
if (currentInstruction.notificationId) {
|
|
2417
2841
|
console.log(
|
|
@@ -2503,7 +2927,7 @@ var PatientRequirementsAdminService = class {
|
|
|
2503
2927
|
`[PRA_Service] Updating instructions array for instance ${instance.id} on patient ${patientId}.`
|
|
2504
2928
|
);
|
|
2505
2929
|
const instanceDocRef = this.db.collection(PATIENTS_COLLECTION).doc(patientId).collection(PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME).doc(instance.id);
|
|
2506
|
-
const finalAdminTsNow =
|
|
2930
|
+
const finalAdminTsNow = admin8.firestore.Timestamp.now();
|
|
2507
2931
|
await instanceDocRef.update({
|
|
2508
2932
|
instructions: updatedInstructions,
|
|
2509
2933
|
// Array of instructions with actual Timestamps
|
|
@@ -2578,7 +3002,7 @@ var PatientRequirementsAdminService = class {
|
|
|
2578
3002
|
return;
|
|
2579
3003
|
}
|
|
2580
3004
|
const instance = instanceSnap.data();
|
|
2581
|
-
const adminNowForMissed =
|
|
3005
|
+
const adminNowForMissed = admin8.firestore.Timestamp.now();
|
|
2582
3006
|
const updatedInstructions = instance.instructions.map((instr) => ({ ...instr }));
|
|
2583
3007
|
let changesMade = false;
|
|
2584
3008
|
for (let i = 0; i < updatedInstructions.length; i++) {
|
|
@@ -2600,7 +3024,7 @@ var PatientRequirementsAdminService = class {
|
|
|
2600
3024
|
}
|
|
2601
3025
|
}
|
|
2602
3026
|
if (changesMade) {
|
|
2603
|
-
const finalAdminNowForMissedUpdate =
|
|
3027
|
+
const finalAdminNowForMissedUpdate = admin8.firestore.Timestamp.now();
|
|
2604
3028
|
await instanceRef.update({
|
|
2605
3029
|
instructions: updatedInstructions,
|
|
2606
3030
|
// Array of instructions with actual Timestamps
|
|
@@ -2648,7 +3072,7 @@ var PatientRequirementsAdminService = class {
|
|
|
2648
3072
|
await instanceRef.update({
|
|
2649
3073
|
overallStatus: "active" /* ACTIVE */,
|
|
2650
3074
|
updatedAt: TimestampUtils.adminToClient(
|
|
2651
|
-
|
|
3075
|
+
admin8.firestore.Timestamp.now()
|
|
2652
3076
|
)
|
|
2653
3077
|
});
|
|
2654
3078
|
}
|
|
@@ -2678,7 +3102,7 @@ var PatientRequirementsAdminService = class {
|
|
|
2678
3102
|
console.log(
|
|
2679
3103
|
`[PRA_Service] Updating overallStatus for instance ${instanceId} from ${instance.overallStatus} to ${newOverallStatus}.`
|
|
2680
3104
|
);
|
|
2681
|
-
const adminTsNow =
|
|
3105
|
+
const adminTsNow = admin8.firestore.Timestamp.now();
|
|
2682
3106
|
await instanceRef.update({
|
|
2683
3107
|
overallStatus: newOverallStatus,
|
|
2684
3108
|
updatedAt: TimestampUtils.adminToClient(
|
|
@@ -2694,10 +3118,10 @@ var PatientRequirementsAdminService = class {
|
|
|
2694
3118
|
};
|
|
2695
3119
|
|
|
2696
3120
|
// src/admin/calendar/calendar.admin.service.ts
|
|
2697
|
-
import * as
|
|
3121
|
+
import * as admin9 from "firebase-admin";
|
|
2698
3122
|
var CalendarAdminService = class {
|
|
2699
|
-
constructor(
|
|
2700
|
-
this.db =
|
|
3123
|
+
constructor(firestore17) {
|
|
3124
|
+
this.db = firestore17 || admin9.firestore();
|
|
2701
3125
|
Logger.info("[CalendarAdminService] Initialized.");
|
|
2702
3126
|
}
|
|
2703
3127
|
/**
|
|
@@ -2713,7 +3137,7 @@ var CalendarAdminService = class {
|
|
|
2713
3137
|
`[CalendarAdminService] Updating calendar event statuses for appointment ${appointment.id} to ${newStatus}`
|
|
2714
3138
|
);
|
|
2715
3139
|
const batch = this.db.batch();
|
|
2716
|
-
const serverTimestamp =
|
|
3140
|
+
const serverTimestamp = admin9.firestore.FieldValue.serverTimestamp();
|
|
2717
3141
|
let updatesAdded = 0;
|
|
2718
3142
|
const calendarEventId = appointment.calendarEventId;
|
|
2719
3143
|
if (!calendarEventId) {
|
|
@@ -2805,7 +3229,7 @@ var CalendarAdminService = class {
|
|
|
2805
3229
|
`[CalendarAdminService] Updating calendar event times for appointment ${appointment.id}`
|
|
2806
3230
|
);
|
|
2807
3231
|
const batch = this.db.batch();
|
|
2808
|
-
const serverTimestamp =
|
|
3232
|
+
const serverTimestamp = admin9.firestore.FieldValue.serverTimestamp();
|
|
2809
3233
|
let updatesAdded = 0;
|
|
2810
3234
|
const calendarEventId = appointment.calendarEventId;
|
|
2811
3235
|
if (!calendarEventId) {
|
|
@@ -2972,7 +3396,7 @@ var CalendarAdminService = class {
|
|
|
2972
3396
|
};
|
|
2973
3397
|
|
|
2974
3398
|
// src/admin/mailing/base.mailing.service.ts
|
|
2975
|
-
import * as
|
|
3399
|
+
import * as admin10 from "firebase-admin";
|
|
2976
3400
|
var BaseMailingService = class {
|
|
2977
3401
|
// Expecting the new mailgun.js client
|
|
2978
3402
|
/**
|
|
@@ -2980,9 +3404,9 @@ var BaseMailingService = class {
|
|
|
2980
3404
|
* @param firestore Firestore instance provided by the caller
|
|
2981
3405
|
* @param mailgunClient Mailgun client instance (mailgun.js v10+) provided by the caller
|
|
2982
3406
|
*/
|
|
2983
|
-
constructor(
|
|
3407
|
+
constructor(firestore17, mailgunClient) {
|
|
2984
3408
|
var _a;
|
|
2985
|
-
this.db =
|
|
3409
|
+
this.db = firestore17;
|
|
2986
3410
|
this.mailgunClient = mailgunClient;
|
|
2987
3411
|
if (!this.db) {
|
|
2988
3412
|
Logger.error("[BaseMailingService] No Firestore instance provided");
|
|
@@ -3082,7 +3506,7 @@ var BaseMailingService = class {
|
|
|
3082
3506
|
status: error.status,
|
|
3083
3507
|
stack: error.stack
|
|
3084
3508
|
} : null,
|
|
3085
|
-
sentAt:
|
|
3509
|
+
sentAt: admin10.firestore.FieldValue.serverTimestamp()
|
|
3086
3510
|
});
|
|
3087
3511
|
Logger.info(
|
|
3088
3512
|
`[BaseMailingService] Email log recorded. Success: ${success}`
|
|
@@ -3126,8 +3550,8 @@ var BaseMailingService = class {
|
|
|
3126
3550
|
var patientAppointmentConfirmedTemplate = "<h1>Appointment Confirmed</h1><p>Dear {{patientName}},</p><p>Your appointment for {{procedureName}} on {{appointmentDate}} at {{appointmentTime}} with {{practitionerName}} at {{clinicName}} has been confirmed.</p><p>Thank you!</p>";
|
|
3127
3551
|
var clinicAppointmentRequestedTemplate = "<h1>New Appointment Request</h1><p>Hello {{clinicName}} Admin,</p><p>A new appointment for {{procedureName}} has been requested by {{patientName}} for {{appointmentDate}} at {{appointmentTime}} with {{practitionerName}}.</p><p>Please review and confirm in the admin panel.</p>";
|
|
3128
3552
|
var AppointmentMailingService = class extends BaseMailingService {
|
|
3129
|
-
constructor(
|
|
3130
|
-
super(
|
|
3553
|
+
constructor(firestore17, mailgunClient) {
|
|
3554
|
+
super(firestore17, mailgunClient);
|
|
3131
3555
|
this.DEFAULT_MAILGUN_DOMAIN = "mg.metaesthetics.net";
|
|
3132
3556
|
Logger.info("[AppointmentMailingService] Initialized.");
|
|
3133
3557
|
}
|
|
@@ -3276,8 +3700,8 @@ var AppointmentAggregationService = class {
|
|
|
3276
3700
|
* @param mailgunClient - An initialized Mailgun client instance.
|
|
3277
3701
|
* @param firestore Optional Firestore instance. If not provided, it uses the default admin SDK instance.
|
|
3278
3702
|
*/
|
|
3279
|
-
constructor(mailgunClient,
|
|
3280
|
-
this.db =
|
|
3703
|
+
constructor(mailgunClient, firestore17) {
|
|
3704
|
+
this.db = firestore17 || admin11.firestore();
|
|
3281
3705
|
this.appointmentMailingService = new AppointmentMailingService(
|
|
3282
3706
|
this.db,
|
|
3283
3707
|
mailgunClient
|
|
@@ -3798,7 +4222,7 @@ var AppointmentAggregationService = class {
|
|
|
3798
4222
|
} else if (template.timeframe.unit === "hours" /* HOURS */) {
|
|
3799
4223
|
dueDateTime.setHours(dueDateTime.getHours() - notifyAtValue);
|
|
3800
4224
|
}
|
|
3801
|
-
dueTime =
|
|
4225
|
+
dueTime = admin11.firestore.Timestamp.fromDate(dueDateTime);
|
|
3802
4226
|
}
|
|
3803
4227
|
const actionableWindowHours = template.importance === "high" ? 1 : template.importance === "medium" ? 4 : 15;
|
|
3804
4228
|
const instructionObject = {
|
|
@@ -3813,7 +4237,7 @@ var AppointmentAggregationService = class {
|
|
|
3813
4237
|
status: "pendingNotification" /* PENDING_NOTIFICATION */,
|
|
3814
4238
|
originalNotifyAtValue: notifyAtValue,
|
|
3815
4239
|
originalTimeframeUnit: template.timeframe.unit,
|
|
3816
|
-
updatedAt:
|
|
4240
|
+
updatedAt: admin11.firestore.Timestamp.now()
|
|
3817
4241
|
// Use current server timestamp
|
|
3818
4242
|
};
|
|
3819
4243
|
return instructionObject;
|
|
@@ -3832,8 +4256,8 @@ var AppointmentAggregationService = class {
|
|
|
3832
4256
|
overallStatus: "active" /* ACTIVE */,
|
|
3833
4257
|
instructions,
|
|
3834
4258
|
// Timestamps - cast to any to satisfy client-side Timestamp type for now
|
|
3835
|
-
createdAt:
|
|
3836
|
-
updatedAt:
|
|
4259
|
+
createdAt: admin11.firestore.FieldValue.serverTimestamp(),
|
|
4260
|
+
updatedAt: admin11.firestore.FieldValue.serverTimestamp()
|
|
3837
4261
|
};
|
|
3838
4262
|
Logger.debug(
|
|
3839
4263
|
`[AggService] Setting data for requirement: ${JSON.stringify({
|
|
@@ -4046,7 +4470,7 @@ var AppointmentAggregationService = class {
|
|
|
4046
4470
|
} else if (template.timeframe.unit === "hours" /* HOURS */) {
|
|
4047
4471
|
dueDateTime.setHours(dueDateTime.getHours() + notifyAtValue);
|
|
4048
4472
|
}
|
|
4049
|
-
dueTime =
|
|
4473
|
+
dueTime = admin11.firestore.Timestamp.fromDate(dueDateTime);
|
|
4050
4474
|
}
|
|
4051
4475
|
const actionableWindowHours = template.importance === "high" ? 1 : template.importance === "medium" ? 4 : 15;
|
|
4052
4476
|
const instructionObject = {
|
|
@@ -4060,7 +4484,7 @@ var AppointmentAggregationService = class {
|
|
|
4060
4484
|
status: "pendingNotification" /* PENDING_NOTIFICATION */,
|
|
4061
4485
|
originalNotifyAtValue: notifyAtValue,
|
|
4062
4486
|
originalTimeframeUnit: template.timeframe.unit,
|
|
4063
|
-
updatedAt:
|
|
4487
|
+
updatedAt: admin11.firestore.Timestamp.now(),
|
|
4064
4488
|
notificationId: void 0,
|
|
4065
4489
|
actionTakenAt: void 0
|
|
4066
4490
|
};
|
|
@@ -4077,8 +4501,8 @@ var AppointmentAggregationService = class {
|
|
|
4077
4501
|
requirementImportance: template.importance,
|
|
4078
4502
|
overallStatus: "active" /* ACTIVE */,
|
|
4079
4503
|
instructions,
|
|
4080
|
-
createdAt:
|
|
4081
|
-
updatedAt:
|
|
4504
|
+
createdAt: admin11.firestore.FieldValue.serverTimestamp(),
|
|
4505
|
+
updatedAt: admin11.firestore.FieldValue.serverTimestamp()
|
|
4082
4506
|
};
|
|
4083
4507
|
Logger.debug(
|
|
4084
4508
|
`[AggService] Setting data for requirement: ${JSON.stringify({
|
|
@@ -4244,7 +4668,7 @@ var AppointmentAggregationService = class {
|
|
|
4244
4668
|
if (instance.overallStatus !== newOverallStatus && instance.overallStatus !== "failedToProcess" /* FAILED_TO_PROCESS */) {
|
|
4245
4669
|
batch.update(doc.ref, {
|
|
4246
4670
|
overallStatus: newOverallStatus,
|
|
4247
|
-
updatedAt:
|
|
4671
|
+
updatedAt: admin11.firestore.FieldValue.serverTimestamp()
|
|
4248
4672
|
// Cast for now
|
|
4249
4673
|
// Potentially also cancel individual instructions if not handled by another trigger
|
|
4250
4674
|
// instructions: instance.instructions.map(instr => ({ ...instr, status: PatientInstructionStatus.CANCELLED, updatedAt: admin.firestore.FieldValue.serverTimestamp() as any }))
|
|
@@ -4320,19 +4744,19 @@ var AppointmentAggregationService = class {
|
|
|
4320
4744
|
if (!hasDoctor || !hasClinic) {
|
|
4321
4745
|
const patientRef = this.db.collection(PATIENTS_COLLECTION).doc(patientProfile.id);
|
|
4322
4746
|
const updateData = {
|
|
4323
|
-
updatedAt:
|
|
4747
|
+
updatedAt: admin11.firestore.FieldValue.serverTimestamp()
|
|
4324
4748
|
};
|
|
4325
4749
|
if (!hasDoctor) {
|
|
4326
4750
|
Logger.debug(
|
|
4327
4751
|
`[AggService] Adding practitioner ${practitionerId} to patient ${patientProfile.id}`
|
|
4328
4752
|
);
|
|
4329
|
-
updateData.doctorIds =
|
|
4753
|
+
updateData.doctorIds = admin11.firestore.FieldValue.arrayUnion(practitionerId);
|
|
4330
4754
|
}
|
|
4331
4755
|
if (!hasClinic) {
|
|
4332
4756
|
Logger.debug(
|
|
4333
4757
|
`[AggService] Adding clinic ${clinicId} to patient ${patientProfile.id}`
|
|
4334
4758
|
);
|
|
4335
|
-
updateData.clinicIds =
|
|
4759
|
+
updateData.clinicIds = admin11.firestore.FieldValue.arrayUnion(clinicId);
|
|
4336
4760
|
}
|
|
4337
4761
|
await patientRef.update(updateData);
|
|
4338
4762
|
Logger.info(
|
|
@@ -4382,18 +4806,18 @@ var AppointmentAggregationService = class {
|
|
|
4382
4806
|
Logger.debug(
|
|
4383
4807
|
`[AggService] Removing practitioner ${practitionerId} from patient ${patientProfile.id}`
|
|
4384
4808
|
);
|
|
4385
|
-
updateData.doctorIds =
|
|
4809
|
+
updateData.doctorIds = admin11.firestore.FieldValue.arrayRemove(practitionerId);
|
|
4386
4810
|
updateNeeded = true;
|
|
4387
4811
|
}
|
|
4388
4812
|
if (activeClinicAppointments === 0 && ((_b = patientProfile.clinicIds) == null ? void 0 : _b.includes(clinicId))) {
|
|
4389
4813
|
Logger.debug(
|
|
4390
4814
|
`[AggService] Removing clinic ${clinicId} from patient ${patientProfile.id}`
|
|
4391
4815
|
);
|
|
4392
|
-
updateData.clinicIds =
|
|
4816
|
+
updateData.clinicIds = admin11.firestore.FieldValue.arrayRemove(clinicId);
|
|
4393
4817
|
updateNeeded = true;
|
|
4394
4818
|
}
|
|
4395
4819
|
if (updateNeeded) {
|
|
4396
|
-
updateData.updatedAt =
|
|
4820
|
+
updateData.updatedAt = admin11.firestore.FieldValue.serverTimestamp();
|
|
4397
4821
|
await patientRef.update(updateData);
|
|
4398
4822
|
Logger.info(
|
|
4399
4823
|
`[AggService] Successfully removed links from patient ${patientProfile.id}`
|
|
@@ -4527,14 +4951,14 @@ var AppointmentAggregationService = class {
|
|
|
4527
4951
|
};
|
|
4528
4952
|
|
|
4529
4953
|
// src/admin/aggregation/forms/filled-forms.aggregation.service.ts
|
|
4530
|
-
import * as
|
|
4954
|
+
import * as admin12 from "firebase-admin";
|
|
4531
4955
|
var FilledFormsAggregationService = class {
|
|
4532
4956
|
/**
|
|
4533
4957
|
* Constructor for FilledFormsAggregationService.
|
|
4534
4958
|
* @param firestore Optional Firestore instance. If not provided, it uses the default admin SDK instance.
|
|
4535
4959
|
*/
|
|
4536
|
-
constructor(
|
|
4537
|
-
this.db =
|
|
4960
|
+
constructor(firestore17) {
|
|
4961
|
+
this.db = firestore17 || admin12.firestore();
|
|
4538
4962
|
Logger.info("[FilledFormsAggregationService] Initialized");
|
|
4539
4963
|
}
|
|
4540
4964
|
/**
|
|
@@ -4570,12 +4994,12 @@ var FilledFormsAggregationService = class {
|
|
|
4570
4994
|
path: `${APPOINTMENTS_COLLECTION}/${filledDocument.appointmentId}/${formSubcollection}/${filledDocument.id}`
|
|
4571
4995
|
};
|
|
4572
4996
|
if (filledDocument.updatedAt) {
|
|
4573
|
-
linkedFormInfo.submittedAt =
|
|
4997
|
+
linkedFormInfo.submittedAt = admin12.firestore.Timestamp.fromMillis(
|
|
4574
4998
|
filledDocument.updatedAt
|
|
4575
4999
|
);
|
|
4576
5000
|
}
|
|
4577
5001
|
if (filledDocument.status === "completed" /* COMPLETED */ || filledDocument.status === "signed" /* SIGNED */) {
|
|
4578
|
-
linkedFormInfo.completedAt =
|
|
5002
|
+
linkedFormInfo.completedAt = admin12.firestore.Timestamp.fromMillis(
|
|
4579
5003
|
filledDocument.updatedAt
|
|
4580
5004
|
);
|
|
4581
5005
|
}
|
|
@@ -4589,7 +5013,7 @@ var FilledFormsAggregationService = class {
|
|
|
4589
5013
|
updatedLinkedForms.push(linkedFormInfo);
|
|
4590
5014
|
updateData = {
|
|
4591
5015
|
linkedForms: updatedLinkedForms,
|
|
4592
|
-
updatedAt:
|
|
5016
|
+
updatedAt: admin12.firestore.FieldValue.serverTimestamp()
|
|
4593
5017
|
};
|
|
4594
5018
|
let updatedLinkedFormIds = appointment.linkedFormIds || [];
|
|
4595
5019
|
if (!updatedLinkedFormIds.includes(filledDocument.id)) {
|
|
@@ -4598,7 +5022,7 @@ var FilledFormsAggregationService = class {
|
|
|
4598
5022
|
}
|
|
4599
5023
|
if (filledDocument.isUserForm && filledDocument.isRequired && (filledDocument.status === "completed" /* COMPLETED */ || filledDocument.status === "signed" /* SIGNED */)) {
|
|
4600
5024
|
if (appointment.pendingUserFormsIds && appointment.pendingUserFormsIds.includes(filledDocument.id)) {
|
|
4601
|
-
updateData.pendingUserFormsIds =
|
|
5025
|
+
updateData.pendingUserFormsIds = admin12.firestore.FieldValue.arrayRemove(filledDocument.id);
|
|
4602
5026
|
Logger.info(
|
|
4603
5027
|
`[FilledFormsAggregationService] Removing form ${filledDocument.id} from pendingUserFormsIds`
|
|
4604
5028
|
);
|
|
@@ -4642,23 +5066,23 @@ var FilledFormsAggregationService = class {
|
|
|
4642
5066
|
(form) => form.formId === filledDocument.id
|
|
4643
5067
|
);
|
|
4644
5068
|
if (formToRemove) {
|
|
4645
|
-
updateData.linkedForms =
|
|
5069
|
+
updateData.linkedForms = admin12.firestore.FieldValue.arrayRemove(formToRemove);
|
|
4646
5070
|
}
|
|
4647
5071
|
}
|
|
4648
5072
|
if (appointment.linkedFormIds && appointment.linkedFormIds.includes(filledDocument.id)) {
|
|
4649
|
-
updateData.linkedFormIds =
|
|
5073
|
+
updateData.linkedFormIds = admin12.firestore.FieldValue.arrayRemove(
|
|
4650
5074
|
filledDocument.id
|
|
4651
5075
|
);
|
|
4652
5076
|
}
|
|
4653
5077
|
if (filledDocument.isUserForm && filledDocument.isRequired) {
|
|
4654
5078
|
if (filledDocument.status !== "completed" /* COMPLETED */ && filledDocument.status !== "signed" /* SIGNED */) {
|
|
4655
5079
|
if (!appointment.pendingUserFormsIds || !appointment.pendingUserFormsIds.includes(filledDocument.id)) {
|
|
4656
|
-
updateData.pendingUserFormsIds = appointment.pendingUserFormsIds ?
|
|
5080
|
+
updateData.pendingUserFormsIds = appointment.pendingUserFormsIds ? admin12.firestore.FieldValue.arrayUnion(filledDocument.id) : [filledDocument.id];
|
|
4657
5081
|
}
|
|
4658
5082
|
}
|
|
4659
5083
|
}
|
|
4660
5084
|
if (Object.keys(updateData).length > 0) {
|
|
4661
|
-
updateData.updatedAt =
|
|
5085
|
+
updateData.updatedAt = admin12.firestore.FieldValue.serverTimestamp();
|
|
4662
5086
|
await appointmentRef.update(updateData);
|
|
4663
5087
|
Logger.info(
|
|
4664
5088
|
`[FilledFormsAggregationService] Successfully updated appointment ${filledDocument.appointmentId} after form deletion`
|
|
@@ -4698,10 +5122,10 @@ var FilledFormsAggregationService = class {
|
|
|
4698
5122
|
return;
|
|
4699
5123
|
}
|
|
4700
5124
|
await appointmentRef.update({
|
|
4701
|
-
pendingUserFormsIds:
|
|
5125
|
+
pendingUserFormsIds: admin12.firestore.FieldValue.arrayUnion(
|
|
4702
5126
|
filledDocument.id
|
|
4703
5127
|
),
|
|
4704
|
-
updatedAt:
|
|
5128
|
+
updatedAt: admin12.firestore.FieldValue.serverTimestamp()
|
|
4705
5129
|
});
|
|
4706
5130
|
Logger.info(
|
|
4707
5131
|
`[FilledFormsAggregationService] Successfully added form ${filledDocument.id} to pendingUserFormsIds for appointment ${filledDocument.appointmentId}`
|
|
@@ -4717,7 +5141,7 @@ var FilledFormsAggregationService = class {
|
|
|
4717
5141
|
};
|
|
4718
5142
|
|
|
4719
5143
|
// src/admin/aggregation/reviews/reviews.aggregation.service.ts
|
|
4720
|
-
import * as
|
|
5144
|
+
import * as admin13 from "firebase-admin";
|
|
4721
5145
|
|
|
4722
5146
|
// src/types/reviews/index.ts
|
|
4723
5147
|
var REVIEWS_COLLECTION = "reviews";
|
|
@@ -4728,8 +5152,8 @@ var ReviewsAggregationService = class {
|
|
|
4728
5152
|
* Constructor for ReviewsAggregationService.
|
|
4729
5153
|
* @param firestore Optional Firestore instance. If not provided, it uses the default admin SDK instance.
|
|
4730
5154
|
*/
|
|
4731
|
-
constructor(
|
|
4732
|
-
this.db =
|
|
5155
|
+
constructor(firestore17) {
|
|
5156
|
+
this.db = firestore17 || admin13.firestore();
|
|
4733
5157
|
}
|
|
4734
5158
|
/**
|
|
4735
5159
|
* Process a newly created review and update all related entities
|
|
@@ -4848,7 +5272,7 @@ var ReviewsAggregationService = class {
|
|
|
4848
5272
|
};
|
|
4849
5273
|
await this.db.collection(CLINICS_COLLECTION).doc(clinicId).update({
|
|
4850
5274
|
reviewInfo: updatedReviewInfo2,
|
|
4851
|
-
updatedAt:
|
|
5275
|
+
updatedAt: admin13.firestore.FieldValue.serverTimestamp()
|
|
4852
5276
|
});
|
|
4853
5277
|
console.log(
|
|
4854
5278
|
`[ReviewsAggregationService] Reset review info for clinic: ${clinicId}`
|
|
@@ -4887,7 +5311,7 @@ var ReviewsAggregationService = class {
|
|
|
4887
5311
|
};
|
|
4888
5312
|
await this.db.collection(CLINICS_COLLECTION).doc(clinicId).update({
|
|
4889
5313
|
reviewInfo: updatedReviewInfo,
|
|
4890
|
-
updatedAt:
|
|
5314
|
+
updatedAt: admin13.firestore.FieldValue.serverTimestamp()
|
|
4891
5315
|
});
|
|
4892
5316
|
console.log(
|
|
4893
5317
|
`[ReviewsAggregationService] Updated review info for clinic: ${clinicId}`
|
|
@@ -4937,7 +5361,7 @@ var ReviewsAggregationService = class {
|
|
|
4937
5361
|
};
|
|
4938
5362
|
await this.db.collection(PRACTITIONERS_COLLECTION).doc(practitionerId).update({
|
|
4939
5363
|
reviewInfo: updatedReviewInfo2,
|
|
4940
|
-
updatedAt:
|
|
5364
|
+
updatedAt: admin13.firestore.FieldValue.serverTimestamp()
|
|
4941
5365
|
});
|
|
4942
5366
|
await this.updateDoctorInfoInProcedures(practitionerId, 0);
|
|
4943
5367
|
console.log(
|
|
@@ -4977,7 +5401,7 @@ var ReviewsAggregationService = class {
|
|
|
4977
5401
|
};
|
|
4978
5402
|
await this.db.collection(PRACTITIONERS_COLLECTION).doc(practitionerId).update({
|
|
4979
5403
|
reviewInfo: updatedReviewInfo,
|
|
4980
|
-
updatedAt:
|
|
5404
|
+
updatedAt: admin13.firestore.FieldValue.serverTimestamp()
|
|
4981
5405
|
});
|
|
4982
5406
|
await this.updateDoctorInfoInProcedures(
|
|
4983
5407
|
practitionerId,
|
|
@@ -5031,7 +5455,7 @@ var ReviewsAggregationService = class {
|
|
|
5031
5455
|
};
|
|
5032
5456
|
await this.db.collection(PROCEDURES_COLLECTION).doc(procedureId).update({
|
|
5033
5457
|
reviewInfo: updatedReviewInfo2,
|
|
5034
|
-
updatedAt:
|
|
5458
|
+
updatedAt: admin13.firestore.FieldValue.serverTimestamp()
|
|
5035
5459
|
});
|
|
5036
5460
|
console.log(
|
|
5037
5461
|
`[ReviewsAggregationService] Reset review info for procedure: ${procedureId}`
|
|
@@ -5072,7 +5496,7 @@ var ReviewsAggregationService = class {
|
|
|
5072
5496
|
};
|
|
5073
5497
|
await this.db.collection(PROCEDURES_COLLECTION).doc(procedureId).update({
|
|
5074
5498
|
reviewInfo: updatedReviewInfo,
|
|
5075
|
-
updatedAt:
|
|
5499
|
+
updatedAt: admin13.firestore.FieldValue.serverTimestamp()
|
|
5076
5500
|
});
|
|
5077
5501
|
console.log(
|
|
5078
5502
|
`[ReviewsAggregationService] Updated review info for procedure: ${procedureId}`
|
|
@@ -5100,7 +5524,7 @@ var ReviewsAggregationService = class {
|
|
|
5100
5524
|
const procedureRef = this.db.collection(PROCEDURES_COLLECTION).doc(docSnapshot.id);
|
|
5101
5525
|
batch.update(procedureRef, {
|
|
5102
5526
|
"doctorInfo.rating": rating,
|
|
5103
|
-
updatedAt:
|
|
5527
|
+
updatedAt: admin13.firestore.FieldValue.serverTimestamp()
|
|
5104
5528
|
});
|
|
5105
5529
|
});
|
|
5106
5530
|
await batch.commit();
|
|
@@ -5137,7 +5561,7 @@ var ReviewsAggregationService = class {
|
|
|
5137
5561
|
clinicReview: review.clinicReview,
|
|
5138
5562
|
practitionerReview: review.practitionerReview,
|
|
5139
5563
|
procedureReview: review.procedureReview,
|
|
5140
|
-
updatedAt:
|
|
5564
|
+
updatedAt: admin13.firestore.FieldValue.serverTimestamp()
|
|
5141
5565
|
});
|
|
5142
5566
|
await batch.commit();
|
|
5143
5567
|
console.log(
|
|
@@ -5274,8 +5698,8 @@ var PractitionerInviteMailingService = class extends BaseMailingService {
|
|
|
5274
5698
|
* @param firestore Firestore instance provided by the caller
|
|
5275
5699
|
* @param mailgunClient Mailgun client instance (mailgun.js v10+) provided by the caller
|
|
5276
5700
|
*/
|
|
5277
|
-
constructor(
|
|
5278
|
-
super(
|
|
5701
|
+
constructor(firestore17, mailgunClient) {
|
|
5702
|
+
super(firestore17, mailgunClient);
|
|
5279
5703
|
this.DEFAULT_REGISTRATION_URL = "https://metaesthetics.net/register";
|
|
5280
5704
|
this.DEFAULT_SUBJECT = "You've Been Invited to Join as a Practitioner";
|
|
5281
5705
|
this.DEFAULT_MAILGUN_DOMAIN = "mg.metaesthetics.net";
|
|
@@ -5513,7 +5937,7 @@ var PractitionerInviteMailingService = class extends BaseMailingService {
|
|
|
5513
5937
|
};
|
|
5514
5938
|
|
|
5515
5939
|
// src/admin/booking/booking.admin.ts
|
|
5516
|
-
import * as
|
|
5940
|
+
import * as admin15 from "firebase-admin";
|
|
5517
5941
|
|
|
5518
5942
|
// src/admin/booking/booking.calculator.ts
|
|
5519
5943
|
import { Timestamp } from "firebase/firestore";
|
|
@@ -5947,10 +6371,10 @@ var BookingAvailabilityCalculator = class {
|
|
|
5947
6371
|
BookingAvailabilityCalculator.DEFAULT_INTERVAL_MINUTES = 15;
|
|
5948
6372
|
|
|
5949
6373
|
// src/admin/documentation-templates/document-manager.admin.ts
|
|
5950
|
-
import * as
|
|
6374
|
+
import * as admin14 from "firebase-admin";
|
|
5951
6375
|
var DocumentManagerAdminService = class {
|
|
5952
|
-
constructor(
|
|
5953
|
-
this.db =
|
|
6376
|
+
constructor(firestore17) {
|
|
6377
|
+
this.db = firestore17;
|
|
5954
6378
|
}
|
|
5955
6379
|
/**
|
|
5956
6380
|
* Adds operations to a Firestore batch to initialize all linked forms for a new appointment
|
|
@@ -6053,7 +6477,7 @@ var DocumentManagerAdminService = class {
|
|
|
6053
6477
|
};
|
|
6054
6478
|
}
|
|
6055
6479
|
const templateIds = technologyTemplates.map((t) => t.templateId);
|
|
6056
|
-
const templatesSnapshot = await this.db.collection(DOCUMENTATION_TEMPLATES_COLLECTION).where(
|
|
6480
|
+
const templatesSnapshot = await this.db.collection(DOCUMENTATION_TEMPLATES_COLLECTION).where(admin14.firestore.FieldPath.documentId(), "in", templateIds).get();
|
|
6057
6481
|
const templatesMap = /* @__PURE__ */ new Map();
|
|
6058
6482
|
templatesSnapshot.forEach((doc) => {
|
|
6059
6483
|
templatesMap.set(doc.id, doc.data());
|
|
@@ -6119,8 +6543,8 @@ var BookingAdmin = class {
|
|
|
6119
6543
|
* Creates a new BookingAdmin instance
|
|
6120
6544
|
* @param firestore - Firestore instance provided by the caller
|
|
6121
6545
|
*/
|
|
6122
|
-
constructor(
|
|
6123
|
-
this.db =
|
|
6546
|
+
constructor(firestore17) {
|
|
6547
|
+
this.db = firestore17 || admin15.firestore();
|
|
6124
6548
|
this.documentManagerAdmin = new DocumentManagerAdminService(this.db);
|
|
6125
6549
|
}
|
|
6126
6550
|
/**
|
|
@@ -6142,8 +6566,8 @@ var BookingAdmin = class {
|
|
|
6142
6566
|
timeframeStart: timeframe.start instanceof Date ? timeframe.start.toISOString() : timeframe.start.toDate().toISOString(),
|
|
6143
6567
|
timeframeEnd: timeframe.end instanceof Date ? timeframe.end.toISOString() : timeframe.end.toDate().toISOString()
|
|
6144
6568
|
});
|
|
6145
|
-
const start = timeframe.start instanceof Date ?
|
|
6146
|
-
const end = timeframe.end instanceof Date ?
|
|
6569
|
+
const start = timeframe.start instanceof Date ? admin15.firestore.Timestamp.fromDate(timeframe.start) : timeframe.start;
|
|
6570
|
+
const end = timeframe.end instanceof Date ? admin15.firestore.Timestamp.fromDate(timeframe.end) : timeframe.end;
|
|
6147
6571
|
Logger.debug("[BookingAdmin] Fetching clinic data", { clinicId });
|
|
6148
6572
|
const clinicDoc = await this.db.collection("clinics").doc(clinicId).get();
|
|
6149
6573
|
if (!clinicDoc.exists) {
|
|
@@ -6228,7 +6652,7 @@ var BookingAdmin = class {
|
|
|
6228
6652
|
const result = BookingAvailabilityCalculator.calculateSlots(request);
|
|
6229
6653
|
const availableSlotsResult = {
|
|
6230
6654
|
availableSlots: result.availableSlots.map((slot) => ({
|
|
6231
|
-
start:
|
|
6655
|
+
start: admin15.firestore.Timestamp.fromMillis(slot.start.toMillis())
|
|
6232
6656
|
}))
|
|
6233
6657
|
};
|
|
6234
6658
|
Logger.info(
|
|
@@ -6392,8 +6816,8 @@ var BookingAdmin = class {
|
|
|
6392
6816
|
`[BookingAdmin] Orchestrating appointment creation for patient ${data.patientId} by user ${authenticatedUserId}`
|
|
6393
6817
|
);
|
|
6394
6818
|
const batch = this.db.batch();
|
|
6395
|
-
const adminTsNow =
|
|
6396
|
-
const serverTimestampValue =
|
|
6819
|
+
const adminTsNow = admin15.firestore.Timestamp.now();
|
|
6820
|
+
const serverTimestampValue = admin15.firestore.FieldValue.serverTimestamp();
|
|
6397
6821
|
try {
|
|
6398
6822
|
if (!data.patientId || !data.procedureId || !data.appointmentStartTime || !data.appointmentEndTime) {
|
|
6399
6823
|
return {
|
|
@@ -6490,7 +6914,7 @@ var BookingAdmin = class {
|
|
|
6490
6914
|
fullName: `${(patientSensitiveData == null ? void 0 : patientSensitiveData.firstName) || ""} ${(patientSensitiveData == null ? void 0 : patientSensitiveData.lastName) || ""}`.trim() || patientProfileData.displayName,
|
|
6491
6915
|
email: (patientSensitiveData == null ? void 0 : patientSensitiveData.email) || "",
|
|
6492
6916
|
phone: (patientSensitiveData == null ? void 0 : patientSensitiveData.phoneNumber) || patientProfileData.phoneNumber || null,
|
|
6493
|
-
dateOfBirth: (patientSensitiveData == null ? void 0 : patientSensitiveData.dateOfBirth) || patientProfileData.dateOfBirth ||
|
|
6917
|
+
dateOfBirth: (patientSensitiveData == null ? void 0 : patientSensitiveData.dateOfBirth) || patientProfileData.dateOfBirth || admin15.firestore.Timestamp.now(),
|
|
6494
6918
|
gender: (patientSensitiveData == null ? void 0 : patientSensitiveData.gender) || "other" /* OTHER */
|
|
6495
6919
|
};
|
|
6496
6920
|
const newAppointmentId = this.db.collection(APPOINTMENTS_COLLECTION).doc().id;
|
|
@@ -6723,7 +7147,7 @@ var BookingAdmin = class {
|
|
|
6723
7147
|
};
|
|
6724
7148
|
|
|
6725
7149
|
// src/admin/free-consultation/free-consultation-utils.admin.ts
|
|
6726
|
-
import * as
|
|
7150
|
+
import * as admin16 from "firebase-admin";
|
|
6727
7151
|
|
|
6728
7152
|
// src/backoffice/types/category.types.ts
|
|
6729
7153
|
var CATEGORIES_COLLECTION = "backoffice_categories";
|
|
@@ -6736,12 +7160,12 @@ var TECHNOLOGIES_COLLECTION = "technologies";
|
|
|
6736
7160
|
|
|
6737
7161
|
// src/admin/free-consultation/free-consultation-utils.admin.ts
|
|
6738
7162
|
async function freeConsultationInfrastructure(db) {
|
|
6739
|
-
const
|
|
7163
|
+
const firestore17 = db || admin16.firestore();
|
|
6740
7164
|
try {
|
|
6741
7165
|
console.log(
|
|
6742
7166
|
"[freeConsultationInfrastructure] Checking free consultation infrastructure..."
|
|
6743
7167
|
);
|
|
6744
|
-
const technologyRef =
|
|
7168
|
+
const technologyRef = firestore17.collection(TECHNOLOGIES_COLLECTION).doc("free-consultation-tech");
|
|
6745
7169
|
const technologyDoc = await technologyRef.get();
|
|
6746
7170
|
if (technologyDoc.exists) {
|
|
6747
7171
|
console.log(
|
|
@@ -6752,7 +7176,7 @@ async function freeConsultationInfrastructure(db) {
|
|
|
6752
7176
|
console.log(
|
|
6753
7177
|
"[freeConsultationInfrastructure] Creating free consultation infrastructure..."
|
|
6754
7178
|
);
|
|
6755
|
-
await createFreeConsultationInfrastructure(
|
|
7179
|
+
await createFreeConsultationInfrastructure(firestore17);
|
|
6756
7180
|
console.log(
|
|
6757
7181
|
"[freeConsultationInfrastructure] Successfully created free consultation infrastructure"
|
|
6758
7182
|
);
|
|
@@ -6860,7 +7284,9 @@ export {
|
|
|
6860
7284
|
PatientRequirementsAdminService,
|
|
6861
7285
|
PaymentStatus,
|
|
6862
7286
|
PractitionerAggregationService,
|
|
7287
|
+
PractitionerInviteAggregationService,
|
|
6863
7288
|
PractitionerInviteMailingService,
|
|
7289
|
+
PractitionerInviteStatus,
|
|
6864
7290
|
PractitionerTokenStatus,
|
|
6865
7291
|
ProcedureAggregationService,
|
|
6866
7292
|
ReviewsAggregationService,
|