@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.js
CHANGED
|
@@ -54,7 +54,9 @@ __export(index_exports, {
|
|
|
54
54
|
PatientRequirementsAdminService: () => PatientRequirementsAdminService,
|
|
55
55
|
PaymentStatus: () => PaymentStatus,
|
|
56
56
|
PractitionerAggregationService: () => PractitionerAggregationService,
|
|
57
|
+
PractitionerInviteAggregationService: () => PractitionerInviteAggregationService,
|
|
57
58
|
PractitionerInviteMailingService: () => PractitionerInviteMailingService,
|
|
59
|
+
PractitionerInviteStatus: () => PractitionerInviteStatus,
|
|
58
60
|
PractitionerTokenStatus: () => PractitionerTokenStatus,
|
|
59
61
|
ProcedureAggregationService: () => ProcedureAggregationService,
|
|
60
62
|
ReviewsAggregationService: () => ReviewsAggregationService,
|
|
@@ -206,9 +208,9 @@ var Logger = class {
|
|
|
206
208
|
|
|
207
209
|
// src/admin/notifications/notifications.admin.ts
|
|
208
210
|
var NotificationsAdmin = class {
|
|
209
|
-
constructor(
|
|
211
|
+
constructor(firestore17) {
|
|
210
212
|
this.expo = new import_expo_server_sdk.Expo();
|
|
211
|
-
this.db =
|
|
213
|
+
this.db = firestore17 || admin.firestore();
|
|
212
214
|
}
|
|
213
215
|
/**
|
|
214
216
|
* Dohvata notifikaciju po ID-u
|
|
@@ -912,6 +914,15 @@ var PractitionerTokenStatus = /* @__PURE__ */ ((PractitionerTokenStatus2) => {
|
|
|
912
914
|
// src/types/procedure/index.ts
|
|
913
915
|
var PROCEDURES_COLLECTION = "procedures";
|
|
914
916
|
|
|
917
|
+
// src/types/clinic/practitioner-invite.types.ts
|
|
918
|
+
var PractitionerInviteStatus = /* @__PURE__ */ ((PractitionerInviteStatus2) => {
|
|
919
|
+
PractitionerInviteStatus2["PENDING"] = "pending";
|
|
920
|
+
PractitionerInviteStatus2["ACCEPTED"] = "accepted";
|
|
921
|
+
PractitionerInviteStatus2["REJECTED"] = "rejected";
|
|
922
|
+
PractitionerInviteStatus2["CANCELLED"] = "cancelled";
|
|
923
|
+
return PractitionerInviteStatus2;
|
|
924
|
+
})(PractitionerInviteStatus || {});
|
|
925
|
+
|
|
915
926
|
// src/types/clinic/index.ts
|
|
916
927
|
var CLINIC_GROUPS_COLLECTION = "clinic_groups";
|
|
917
928
|
var CLINICS_COLLECTION = "clinics";
|
|
@@ -927,8 +938,8 @@ var ClinicAggregationService = class {
|
|
|
927
938
|
* Constructor for ClinicAggregationService.
|
|
928
939
|
* @param firestore Optional Firestore instance. If not provided, it uses the default admin SDK instance.
|
|
929
940
|
*/
|
|
930
|
-
constructor(
|
|
931
|
-
this.db =
|
|
941
|
+
constructor(firestore17) {
|
|
942
|
+
this.db = firestore17 || admin3.firestore();
|
|
932
943
|
}
|
|
933
944
|
/**
|
|
934
945
|
* Adds clinic information to a clinic group when a new clinic is created
|
|
@@ -1440,8 +1451,8 @@ var ClinicAggregationService = class {
|
|
|
1440
1451
|
var admin4 = __toESM(require("firebase-admin"));
|
|
1441
1452
|
var CALENDAR_SUBCOLLECTION_ID2 = "calendar";
|
|
1442
1453
|
var PractitionerAggregationService = class {
|
|
1443
|
-
constructor(
|
|
1444
|
-
this.db =
|
|
1454
|
+
constructor(firestore17) {
|
|
1455
|
+
this.db = firestore17 || admin4.firestore();
|
|
1445
1456
|
}
|
|
1446
1457
|
/**
|
|
1447
1458
|
* Adds practitioner information to a clinic when a new practitioner is created
|
|
@@ -1772,12 +1783,427 @@ var PractitionerAggregationService = class {
|
|
|
1772
1783
|
}
|
|
1773
1784
|
};
|
|
1774
1785
|
|
|
1775
|
-
// src/admin/aggregation/
|
|
1786
|
+
// src/admin/aggregation/practitioner-invite/practitioner-invite.aggregation.service.ts
|
|
1776
1787
|
var admin5 = __toESM(require("firebase-admin"));
|
|
1788
|
+
var PractitionerInviteAggregationService = class {
|
|
1789
|
+
/**
|
|
1790
|
+
* Constructor for PractitionerInviteAggregationService.
|
|
1791
|
+
* @param firestore Optional Firestore instance. If not provided, it uses the default admin SDK instance.
|
|
1792
|
+
*/
|
|
1793
|
+
constructor(firestore17) {
|
|
1794
|
+
this.db = firestore17 || admin5.firestore();
|
|
1795
|
+
Logger.info("[PractitionerInviteAggregationService] Initialized.");
|
|
1796
|
+
}
|
|
1797
|
+
/**
|
|
1798
|
+
* Handles side effects when a practitioner invite is first created.
|
|
1799
|
+
* This function would typically be called by a Firestore onCreate trigger.
|
|
1800
|
+
* @param {PractitionerInvite} invite - The newly created PractitionerInvite object.
|
|
1801
|
+
* @returns {Promise<void>}
|
|
1802
|
+
*/
|
|
1803
|
+
async handleInviteCreate(invite) {
|
|
1804
|
+
Logger.info(
|
|
1805
|
+
`[PractitionerInviteAggService] Handling CREATE for invite: ${invite.id}, practitioner: ${invite.practitionerId}, clinic: ${invite.clinicId}, status: ${invite.status}`
|
|
1806
|
+
);
|
|
1807
|
+
try {
|
|
1808
|
+
Logger.info(
|
|
1809
|
+
`[PractitionerInviteAggService] Successfully processed CREATE for invite: ${invite.id}`
|
|
1810
|
+
);
|
|
1811
|
+
} catch (error) {
|
|
1812
|
+
Logger.error(
|
|
1813
|
+
`[PractitionerInviteAggService] Error in handleInviteCreate for invite ${invite.id}:`,
|
|
1814
|
+
error
|
|
1815
|
+
);
|
|
1816
|
+
throw error;
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
/**
|
|
1820
|
+
* Handles side effects when a practitioner invite is updated.
|
|
1821
|
+
* This function would typically be called by a Firestore onUpdate trigger.
|
|
1822
|
+
* @param {PractitionerInvite} before - The PractitionerInvite object before the update.
|
|
1823
|
+
* @param {PractitionerInvite} after - The PractitionerInvite object after the update.
|
|
1824
|
+
* @returns {Promise<void>}
|
|
1825
|
+
*/
|
|
1826
|
+
async handleInviteUpdate(before, after) {
|
|
1827
|
+
Logger.info(
|
|
1828
|
+
`[PractitionerInviteAggService] Handling UPDATE for invite: ${after.id}. Status ${before.status} -> ${after.status}`
|
|
1829
|
+
);
|
|
1830
|
+
try {
|
|
1831
|
+
const statusChanged = before.status !== after.status;
|
|
1832
|
+
if (statusChanged) {
|
|
1833
|
+
Logger.info(
|
|
1834
|
+
`[PractitionerInviteAggService] Status changed for invite ${after.id}: ${before.status} -> ${after.status}`
|
|
1835
|
+
);
|
|
1836
|
+
if (before.status === "pending" /* PENDING */ && after.status === "accepted" /* ACCEPTED */) {
|
|
1837
|
+
Logger.info(
|
|
1838
|
+
`[PractitionerInviteAggService] Invite ${after.id} PENDING -> ACCEPTED. Adding practitioner to clinic.`
|
|
1839
|
+
);
|
|
1840
|
+
await this.handleInviteAccepted(after);
|
|
1841
|
+
} else if (before.status === "pending" /* PENDING */ && after.status === "rejected" /* REJECTED */) {
|
|
1842
|
+
Logger.info(
|
|
1843
|
+
`[PractitionerInviteAggService] Invite ${after.id} PENDING -> REJECTED.`
|
|
1844
|
+
);
|
|
1845
|
+
await this.handleInviteRejected(after);
|
|
1846
|
+
} else if (before.status === "pending" /* PENDING */ && after.status === "cancelled" /* CANCELLED */) {
|
|
1847
|
+
Logger.info(
|
|
1848
|
+
`[PractitionerInviteAggService] Invite ${after.id} PENDING -> CANCELLED.`
|
|
1849
|
+
);
|
|
1850
|
+
await this.handleInviteCancelled(after);
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1853
|
+
Logger.info(
|
|
1854
|
+
`[PractitionerInviteAggService] Successfully processed UPDATE for invite: ${after.id}`
|
|
1855
|
+
);
|
|
1856
|
+
} catch (error) {
|
|
1857
|
+
Logger.error(
|
|
1858
|
+
`[PractitionerInviteAggService] Error in handleInviteUpdate for invite ${after.id}:`,
|
|
1859
|
+
error
|
|
1860
|
+
);
|
|
1861
|
+
throw error;
|
|
1862
|
+
}
|
|
1863
|
+
}
|
|
1864
|
+
/**
|
|
1865
|
+
* Handles side effects when a practitioner invite is deleted.
|
|
1866
|
+
* @param deletedInvite - The PractitionerInvite object that was deleted.
|
|
1867
|
+
* @returns {Promise<void>}
|
|
1868
|
+
*/
|
|
1869
|
+
async handleInviteDelete(deletedInvite) {
|
|
1870
|
+
Logger.info(
|
|
1871
|
+
`[PractitionerInviteAggService] Handling DELETE for invite: ${deletedInvite.id}`
|
|
1872
|
+
);
|
|
1873
|
+
try {
|
|
1874
|
+
Logger.info(
|
|
1875
|
+
`[PractitionerInviteAggService] Successfully processed DELETE for invite: ${deletedInvite.id}`
|
|
1876
|
+
);
|
|
1877
|
+
} catch (error) {
|
|
1878
|
+
Logger.error(
|
|
1879
|
+
`[PractitionerInviteAggService] Error in handleInviteDelete for invite ${deletedInvite.id}:`,
|
|
1880
|
+
error
|
|
1881
|
+
);
|
|
1882
|
+
throw error;
|
|
1883
|
+
}
|
|
1884
|
+
}
|
|
1885
|
+
// --- Private Helper Methods ---
|
|
1886
|
+
/**
|
|
1887
|
+
* Handles the business logic when a practitioner accepts an invite.
|
|
1888
|
+
* This includes adding the practitioner to the clinic and the clinic to the practitioner.
|
|
1889
|
+
* @param {PractitionerInvite} invite - The accepted invite
|
|
1890
|
+
* @returns {Promise<void>}
|
|
1891
|
+
*/
|
|
1892
|
+
async handleInviteAccepted(invite) {
|
|
1893
|
+
var _a, _b, _c, _d;
|
|
1894
|
+
Logger.info(
|
|
1895
|
+
`[PractitionerInviteAggService] Processing accepted invite ${invite.id} for practitioner ${invite.practitionerId} and clinic ${invite.clinicId}`
|
|
1896
|
+
);
|
|
1897
|
+
try {
|
|
1898
|
+
const [practitioner, clinic] = await Promise.all([
|
|
1899
|
+
this.fetchPractitionerById(invite.practitionerId),
|
|
1900
|
+
this.fetchClinicById(invite.clinicId)
|
|
1901
|
+
]);
|
|
1902
|
+
if (!practitioner) {
|
|
1903
|
+
throw new Error(
|
|
1904
|
+
`Practitioner ${invite.practitionerId} not found during invite acceptance`
|
|
1905
|
+
);
|
|
1906
|
+
}
|
|
1907
|
+
if (!clinic) {
|
|
1908
|
+
throw new Error(
|
|
1909
|
+
`Clinic ${invite.clinicId} not found during invite acceptance`
|
|
1910
|
+
);
|
|
1911
|
+
}
|
|
1912
|
+
const doctorInfo = {
|
|
1913
|
+
id: practitioner.id,
|
|
1914
|
+
name: `${practitioner.basicInfo.firstName} ${practitioner.basicInfo.lastName}`,
|
|
1915
|
+
description: practitioner.basicInfo.bio || void 0,
|
|
1916
|
+
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,
|
|
1917
|
+
rating: ((_b = practitioner.reviewInfo) == null ? void 0 : _b.averageRating) || 0,
|
|
1918
|
+
services: ((_c = practitioner.proceduresInfo) == null ? void 0 : _c.map((proc) => proc.name)) || []
|
|
1919
|
+
// Use procedure names as services
|
|
1920
|
+
};
|
|
1921
|
+
const clinicInfo = {
|
|
1922
|
+
id: clinic.id,
|
|
1923
|
+
featuredPhoto: typeof clinic.coverPhoto === "object" && clinic.coverPhoto !== null ? ((_d = clinic.coverPhoto) == null ? void 0 : _d.url) || "" : typeof clinic.coverPhoto === "string" ? clinic.coverPhoto : "",
|
|
1924
|
+
name: clinic.name,
|
|
1925
|
+
description: clinic.description || null,
|
|
1926
|
+
location: clinic.location,
|
|
1927
|
+
contactInfo: clinic.contactInfo
|
|
1928
|
+
};
|
|
1929
|
+
const isPractitionerInClinic = clinic.doctors.includes(practitioner.id);
|
|
1930
|
+
const isClinicInPractitioner = practitioner.clinics.includes(clinic.id);
|
|
1931
|
+
if (!isPractitionerInClinic) {
|
|
1932
|
+
Logger.info(
|
|
1933
|
+
`[PractitionerInviteAggService] Adding practitioner ${practitioner.id} to clinic ${clinic.id}`
|
|
1934
|
+
);
|
|
1935
|
+
await this.addPractitionerToClinic(clinic.id, doctorInfo);
|
|
1936
|
+
} else {
|
|
1937
|
+
Logger.info(
|
|
1938
|
+
`[PractitionerInviteAggService] Practitioner ${practitioner.id} already in clinic ${clinic.id}, updating info`
|
|
1939
|
+
);
|
|
1940
|
+
await this.updatePractitionerInfoInClinic(clinic.id, doctorInfo);
|
|
1941
|
+
}
|
|
1942
|
+
if (!isClinicInPractitioner) {
|
|
1943
|
+
Logger.info(
|
|
1944
|
+
`[PractitionerInviteAggService] Adding clinic ${clinic.id} to practitioner ${practitioner.id}`
|
|
1945
|
+
);
|
|
1946
|
+
await this.addClinicToPractitioner(practitioner.id, clinicInfo, invite);
|
|
1947
|
+
} else {
|
|
1948
|
+
Logger.info(
|
|
1949
|
+
`[PractitionerInviteAggService] Clinic ${clinic.id} already in practitioner ${practitioner.id}, updating working hours`
|
|
1950
|
+
);
|
|
1951
|
+
await this.updatePractitionerWorkingHours(practitioner.id, invite);
|
|
1952
|
+
}
|
|
1953
|
+
Logger.info(
|
|
1954
|
+
`[PractitionerInviteAggService] Successfully processed accepted invite ${invite.id}`
|
|
1955
|
+
);
|
|
1956
|
+
} catch (error) {
|
|
1957
|
+
Logger.error(
|
|
1958
|
+
`[PractitionerInviteAggService] Error processing accepted invite ${invite.id}:`,
|
|
1959
|
+
error
|
|
1960
|
+
);
|
|
1961
|
+
throw error;
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
/**
|
|
1965
|
+
* Handles the business logic when a practitioner rejects an invite.
|
|
1966
|
+
* @param {PractitionerInvite} invite - The rejected invite
|
|
1967
|
+
* @returns {Promise<void>}
|
|
1968
|
+
*/
|
|
1969
|
+
async handleInviteRejected(invite) {
|
|
1970
|
+
Logger.info(
|
|
1971
|
+
`[PractitionerInviteAggService] Processing rejected invite ${invite.id}`
|
|
1972
|
+
);
|
|
1973
|
+
try {
|
|
1974
|
+
Logger.info(
|
|
1975
|
+
`[PractitionerInviteAggService] Successfully processed rejected invite ${invite.id}`
|
|
1976
|
+
);
|
|
1977
|
+
} catch (error) {
|
|
1978
|
+
Logger.error(
|
|
1979
|
+
`[PractitionerInviteAggService] Error processing rejected invite ${invite.id}:`,
|
|
1980
|
+
error
|
|
1981
|
+
);
|
|
1982
|
+
throw error;
|
|
1983
|
+
}
|
|
1984
|
+
}
|
|
1985
|
+
/**
|
|
1986
|
+
* Handles the business logic when an invite is cancelled by admin.
|
|
1987
|
+
* @param {PractitionerInvite} invite - The cancelled invite
|
|
1988
|
+
* @returns {Promise<void>}
|
|
1989
|
+
*/
|
|
1990
|
+
async handleInviteCancelled(invite) {
|
|
1991
|
+
Logger.info(
|
|
1992
|
+
`[PractitionerInviteAggService] Processing cancelled invite ${invite.id}`
|
|
1993
|
+
);
|
|
1994
|
+
try {
|
|
1995
|
+
Logger.info(
|
|
1996
|
+
`[PractitionerInviteAggService] Successfully processed cancelled invite ${invite.id}`
|
|
1997
|
+
);
|
|
1998
|
+
} catch (error) {
|
|
1999
|
+
Logger.error(
|
|
2000
|
+
`[PractitionerInviteAggService] Error processing cancelled invite ${invite.id}:`,
|
|
2001
|
+
error
|
|
2002
|
+
);
|
|
2003
|
+
throw error;
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
/**
|
|
2007
|
+
* Adds practitioner information to a clinic when an invite is accepted.
|
|
2008
|
+
* @param clinicId - ID of the clinic to update
|
|
2009
|
+
* @param doctorInfo - Doctor information to add to the clinic
|
|
2010
|
+
* @returns {Promise<void>}
|
|
2011
|
+
*/
|
|
2012
|
+
async addPractitionerToClinic(clinicId, doctorInfo) {
|
|
2013
|
+
Logger.info(
|
|
2014
|
+
`[PractitionerInviteAggService] Adding practitioner ${doctorInfo.id} to clinic ${clinicId}`
|
|
2015
|
+
);
|
|
2016
|
+
try {
|
|
2017
|
+
const clinicRef = this.db.collection(CLINICS_COLLECTION).doc(clinicId);
|
|
2018
|
+
await clinicRef.update({
|
|
2019
|
+
doctors: admin5.firestore.FieldValue.arrayUnion(doctorInfo.id),
|
|
2020
|
+
doctorsInfo: admin5.firestore.FieldValue.arrayUnion(doctorInfo),
|
|
2021
|
+
updatedAt: admin5.firestore.FieldValue.serverTimestamp()
|
|
2022
|
+
});
|
|
2023
|
+
Logger.info(
|
|
2024
|
+
`[PractitionerInviteAggService] Successfully added practitioner ${doctorInfo.id} to clinic ${clinicId}`
|
|
2025
|
+
);
|
|
2026
|
+
} catch (error) {
|
|
2027
|
+
Logger.error(
|
|
2028
|
+
`[PractitionerInviteAggService] Error adding practitioner ${doctorInfo.id} to clinic ${clinicId}:`,
|
|
2029
|
+
error
|
|
2030
|
+
);
|
|
2031
|
+
throw error;
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
/**
|
|
2035
|
+
* Updates practitioner information in a clinic.
|
|
2036
|
+
* @param clinicId - ID of the clinic to update
|
|
2037
|
+
* @param doctorInfo - Updated doctor information
|
|
2038
|
+
* @returns {Promise<void>}
|
|
2039
|
+
*/
|
|
2040
|
+
async updatePractitionerInfoInClinic(clinicId, doctorInfo) {
|
|
2041
|
+
Logger.info(
|
|
2042
|
+
`[PractitionerInviteAggService] Updating practitioner ${doctorInfo.id} info in clinic ${clinicId}`
|
|
2043
|
+
);
|
|
2044
|
+
try {
|
|
2045
|
+
const clinicRef = this.db.collection(CLINICS_COLLECTION).doc(clinicId);
|
|
2046
|
+
const clinicDoc = await clinicRef.get();
|
|
2047
|
+
if (clinicDoc.exists) {
|
|
2048
|
+
const clinicData = clinicDoc.data();
|
|
2049
|
+
const currentDoctorsInfo = (clinicData == null ? void 0 : clinicData.doctorsInfo) || [];
|
|
2050
|
+
const filteredDoctorsInfo = currentDoctorsInfo.filter(
|
|
2051
|
+
(doctor) => doctor.id !== doctorInfo.id
|
|
2052
|
+
);
|
|
2053
|
+
const updatedDoctorsInfo = [...filteredDoctorsInfo, doctorInfo];
|
|
2054
|
+
await clinicRef.update({
|
|
2055
|
+
doctorsInfo: updatedDoctorsInfo,
|
|
2056
|
+
updatedAt: admin5.firestore.FieldValue.serverTimestamp()
|
|
2057
|
+
});
|
|
2058
|
+
Logger.info(
|
|
2059
|
+
`[PractitionerInviteAggService] Successfully updated practitioner ${doctorInfo.id} info in clinic ${clinicId}`
|
|
2060
|
+
);
|
|
2061
|
+
} else {
|
|
2062
|
+
Logger.warn(
|
|
2063
|
+
`[PractitionerInviteAggService] Clinic ${clinicId} not found for doctor info update`
|
|
2064
|
+
);
|
|
2065
|
+
}
|
|
2066
|
+
} catch (error) {
|
|
2067
|
+
Logger.error(
|
|
2068
|
+
`[PractitionerInviteAggService] Error updating practitioner ${doctorInfo.id} info in clinic ${clinicId}:`,
|
|
2069
|
+
error
|
|
2070
|
+
);
|
|
2071
|
+
throw error;
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
/**
|
|
2075
|
+
* Adds a clinic to a practitioner's profile with working hours from the invite.
|
|
2076
|
+
* @param {string} practitionerId - The practitioner ID
|
|
2077
|
+
* @param {ClinicInfo} clinicInfo - The clinic information
|
|
2078
|
+
* @param {PractitionerInvite} invite - The accepted invite containing working hours
|
|
2079
|
+
* @returns {Promise<void>}
|
|
2080
|
+
*/
|
|
2081
|
+
async addClinicToPractitioner(practitionerId, clinicInfo, invite) {
|
|
2082
|
+
Logger.info(
|
|
2083
|
+
`[PractitionerInviteAggService] Adding clinic ${clinicInfo.id} to practitioner ${practitionerId}`
|
|
2084
|
+
);
|
|
2085
|
+
try {
|
|
2086
|
+
const practitionerRef = this.db.collection(PRACTITIONERS_COLLECTION).doc(practitionerId);
|
|
2087
|
+
const workingHours = {
|
|
2088
|
+
clinicId: clinicInfo.id,
|
|
2089
|
+
workingHours: invite.proposedWorkingHours,
|
|
2090
|
+
isActive: true,
|
|
2091
|
+
createdAt: admin5.firestore.Timestamp.now(),
|
|
2092
|
+
updatedAt: admin5.firestore.Timestamp.now()
|
|
2093
|
+
};
|
|
2094
|
+
await practitionerRef.update({
|
|
2095
|
+
clinics: admin5.firestore.FieldValue.arrayUnion(clinicInfo.id),
|
|
2096
|
+
clinicsInfo: admin5.firestore.FieldValue.arrayUnion(clinicInfo),
|
|
2097
|
+
clinicWorkingHours: admin5.firestore.FieldValue.arrayUnion(workingHours),
|
|
2098
|
+
updatedAt: admin5.firestore.FieldValue.serverTimestamp()
|
|
2099
|
+
});
|
|
2100
|
+
Logger.info(
|
|
2101
|
+
`[PractitionerInviteAggService] Successfully added clinic ${clinicInfo.id} to practitioner ${practitionerId}`
|
|
2102
|
+
);
|
|
2103
|
+
} catch (error) {
|
|
2104
|
+
Logger.error(
|
|
2105
|
+
`[PractitionerInviteAggService] Error adding clinic to practitioner:`,
|
|
2106
|
+
error
|
|
2107
|
+
);
|
|
2108
|
+
throw error;
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
/**
|
|
2112
|
+
* Updates the working hours for an existing practitioner-clinic relationship.
|
|
2113
|
+
* @param {string} practitionerId - The practitioner ID
|
|
2114
|
+
* @param {PractitionerInvite} invite - The accepted invite containing new working hours
|
|
2115
|
+
* @returns {Promise<void>}
|
|
2116
|
+
*/
|
|
2117
|
+
async updatePractitionerWorkingHours(practitionerId, invite) {
|
|
2118
|
+
Logger.info(
|
|
2119
|
+
`[PractitionerInviteAggService] Updating working hours for practitioner ${practitionerId} at clinic ${invite.clinicId}`
|
|
2120
|
+
);
|
|
2121
|
+
try {
|
|
2122
|
+
const practitionerRef = this.db.collection(PRACTITIONERS_COLLECTION).doc(practitionerId);
|
|
2123
|
+
const practitionerDoc = await practitionerRef.get();
|
|
2124
|
+
if (!practitionerDoc.exists) {
|
|
2125
|
+
throw new Error(`Practitioner ${practitionerId} not found`);
|
|
2126
|
+
}
|
|
2127
|
+
const practitionerData = practitionerDoc.data();
|
|
2128
|
+
const currentWorkingHours = practitionerData.clinicWorkingHours || [];
|
|
2129
|
+
const updatedWorkingHours = currentWorkingHours.map((wh) => {
|
|
2130
|
+
if (wh.clinicId === invite.clinicId) {
|
|
2131
|
+
return {
|
|
2132
|
+
...wh,
|
|
2133
|
+
workingHours: invite.proposedWorkingHours,
|
|
2134
|
+
isActive: true,
|
|
2135
|
+
updatedAt: admin5.firestore.Timestamp.now()
|
|
2136
|
+
};
|
|
2137
|
+
}
|
|
2138
|
+
return wh;
|
|
2139
|
+
});
|
|
2140
|
+
if (!updatedWorkingHours.some((wh) => wh.clinicId === invite.clinicId)) {
|
|
2141
|
+
updatedWorkingHours.push({
|
|
2142
|
+
clinicId: invite.clinicId,
|
|
2143
|
+
workingHours: invite.proposedWorkingHours,
|
|
2144
|
+
isActive: true,
|
|
2145
|
+
createdAt: admin5.firestore.Timestamp.now(),
|
|
2146
|
+
updatedAt: admin5.firestore.Timestamp.now()
|
|
2147
|
+
});
|
|
2148
|
+
}
|
|
2149
|
+
await practitionerRef.update({
|
|
2150
|
+
clinicWorkingHours: updatedWorkingHours,
|
|
2151
|
+
updatedAt: admin5.firestore.FieldValue.serverTimestamp()
|
|
2152
|
+
});
|
|
2153
|
+
Logger.info(
|
|
2154
|
+
`[PractitionerInviteAggService] Successfully updated working hours for practitioner ${practitionerId} at clinic ${invite.clinicId}`
|
|
2155
|
+
);
|
|
2156
|
+
} catch (error) {
|
|
2157
|
+
Logger.error(
|
|
2158
|
+
`[PractitionerInviteAggService] Error updating practitioner working hours:`,
|
|
2159
|
+
error
|
|
2160
|
+
);
|
|
2161
|
+
throw error;
|
|
2162
|
+
}
|
|
2163
|
+
}
|
|
2164
|
+
// --- Data Fetching Helpers ---
|
|
2165
|
+
/**
|
|
2166
|
+
* Fetches a practitioner by ID.
|
|
2167
|
+
* @param practitionerId The practitioner ID.
|
|
2168
|
+
* @returns {Promise<Practitioner | null>} The practitioner or null if not found.
|
|
2169
|
+
*/
|
|
2170
|
+
async fetchPractitionerById(practitionerId) {
|
|
2171
|
+
try {
|
|
2172
|
+
const doc = await this.db.collection(PRACTITIONERS_COLLECTION).doc(practitionerId).get();
|
|
2173
|
+
return doc.exists ? doc.data() : null;
|
|
2174
|
+
} catch (error) {
|
|
2175
|
+
Logger.error(
|
|
2176
|
+
`[PractitionerInviteAggService] Error fetching practitioner ${practitionerId}:`,
|
|
2177
|
+
error
|
|
2178
|
+
);
|
|
2179
|
+
return null;
|
|
2180
|
+
}
|
|
2181
|
+
}
|
|
2182
|
+
/**
|
|
2183
|
+
* Fetches a clinic by ID.
|
|
2184
|
+
* @param clinicId The clinic ID.
|
|
2185
|
+
* @returns {Promise<Clinic | null>} The clinic or null if not found.
|
|
2186
|
+
*/
|
|
2187
|
+
async fetchClinicById(clinicId) {
|
|
2188
|
+
try {
|
|
2189
|
+
const doc = await this.db.collection(CLINICS_COLLECTION).doc(clinicId).get();
|
|
2190
|
+
return doc.exists ? doc.data() : null;
|
|
2191
|
+
} catch (error) {
|
|
2192
|
+
Logger.error(
|
|
2193
|
+
`[PractitionerInviteAggService] Error fetching clinic ${clinicId}:`,
|
|
2194
|
+
error
|
|
2195
|
+
);
|
|
2196
|
+
return null;
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
};
|
|
2200
|
+
|
|
2201
|
+
// src/admin/aggregation/procedure/procedure.aggregation.service.ts
|
|
2202
|
+
var admin6 = __toESM(require("firebase-admin"));
|
|
1777
2203
|
var CALENDAR_SUBCOLLECTION_ID3 = "calendar";
|
|
1778
2204
|
var ProcedureAggregationService = class {
|
|
1779
|
-
constructor(
|
|
1780
|
-
this.db =
|
|
2205
|
+
constructor(firestore17) {
|
|
2206
|
+
this.db = firestore17 || admin6.firestore();
|
|
1781
2207
|
}
|
|
1782
2208
|
/**
|
|
1783
2209
|
* Adds procedure information to a practitioner when a new procedure is created
|
|
@@ -1801,9 +2227,9 @@ var ProcedureAggregationService = class {
|
|
|
1801
2227
|
const practitionerRef = this.db.collection(PRACTITIONERS_COLLECTION).doc(practitionerId);
|
|
1802
2228
|
try {
|
|
1803
2229
|
const updateData = {
|
|
1804
|
-
procedureIds:
|
|
1805
|
-
proceduresInfo:
|
|
1806
|
-
updatedAt:
|
|
2230
|
+
procedureIds: admin6.firestore.FieldValue.arrayUnion(procedureId),
|
|
2231
|
+
proceduresInfo: admin6.firestore.FieldValue.arrayUnion(procedureSummary),
|
|
2232
|
+
updatedAt: admin6.firestore.FieldValue.serverTimestamp()
|
|
1807
2233
|
};
|
|
1808
2234
|
if (isFreeConsultation) {
|
|
1809
2235
|
await this.db.runTransaction(async (transaction) => {
|
|
@@ -1866,9 +2292,9 @@ var ProcedureAggregationService = class {
|
|
|
1866
2292
|
const clinicRef = this.db.collection(CLINICS_COLLECTION).doc(clinicId);
|
|
1867
2293
|
try {
|
|
1868
2294
|
await clinicRef.update({
|
|
1869
|
-
procedures:
|
|
1870
|
-
proceduresInfo:
|
|
1871
|
-
updatedAt:
|
|
2295
|
+
procedures: admin6.firestore.FieldValue.arrayUnion(procedureId),
|
|
2296
|
+
proceduresInfo: admin6.firestore.FieldValue.arrayUnion(procedureSummary),
|
|
2297
|
+
updatedAt: admin6.firestore.FieldValue.serverTimestamp()
|
|
1872
2298
|
});
|
|
1873
2299
|
console.log(
|
|
1874
2300
|
`[ProcedureAggregationService] Successfully added procedure ${procedureId} to clinic ${clinicId}.`
|
|
@@ -1920,7 +2346,7 @@ var ProcedureAggregationService = class {
|
|
|
1920
2346
|
updatedProceduresInfo.push(procedureSummary);
|
|
1921
2347
|
transaction.update(practitionerRef, {
|
|
1922
2348
|
proceduresInfo: updatedProceduresInfo,
|
|
1923
|
-
updatedAt:
|
|
2349
|
+
updatedAt: admin6.firestore.FieldValue.serverTimestamp()
|
|
1924
2350
|
});
|
|
1925
2351
|
});
|
|
1926
2352
|
console.log(
|
|
@@ -1973,7 +2399,7 @@ var ProcedureAggregationService = class {
|
|
|
1973
2399
|
updatedProceduresInfo.push(procedureSummary);
|
|
1974
2400
|
transaction.update(clinicRef, {
|
|
1975
2401
|
proceduresInfo: updatedProceduresInfo,
|
|
1976
|
-
updatedAt:
|
|
2402
|
+
updatedAt: admin6.firestore.FieldValue.serverTimestamp()
|
|
1977
2403
|
});
|
|
1978
2404
|
});
|
|
1979
2405
|
console.log(
|
|
@@ -2003,7 +2429,7 @@ var ProcedureAggregationService = class {
|
|
|
2003
2429
|
console.log(
|
|
2004
2430
|
`[ProcedureAggregationService] Querying upcoming calendar events for procedure ${procedureId} to update procedure info.`
|
|
2005
2431
|
);
|
|
2006
|
-
const now =
|
|
2432
|
+
const now = admin6.firestore.Timestamp.now();
|
|
2007
2433
|
const calendarEventsQuery = this.db.collectionGroup(CALENDAR_SUBCOLLECTION_ID3).where("procedureId", "==", procedureId).where("eventTime.start", ">", now);
|
|
2008
2434
|
try {
|
|
2009
2435
|
const snapshot = await calendarEventsQuery.get();
|
|
@@ -2020,7 +2446,7 @@ var ProcedureAggregationService = class {
|
|
|
2020
2446
|
);
|
|
2021
2447
|
batch.update(doc.ref, {
|
|
2022
2448
|
procedureInfo,
|
|
2023
|
-
updatedAt:
|
|
2449
|
+
updatedAt: admin6.firestore.FieldValue.serverTimestamp()
|
|
2024
2450
|
});
|
|
2025
2451
|
});
|
|
2026
2452
|
await batch.commit();
|
|
@@ -2050,7 +2476,7 @@ var ProcedureAggregationService = class {
|
|
|
2050
2476
|
console.log(
|
|
2051
2477
|
`[ProcedureAggregationService] Querying upcoming calendar events for procedure ${procedureId} to cancel.`
|
|
2052
2478
|
);
|
|
2053
|
-
const now =
|
|
2479
|
+
const now = admin6.firestore.Timestamp.now();
|
|
2054
2480
|
const calendarEventsQuery = this.db.collectionGroup(CALENDAR_SUBCOLLECTION_ID3).where("procedureId", "==", procedureId).where("eventTime.start", ">", now);
|
|
2055
2481
|
try {
|
|
2056
2482
|
const snapshot = await calendarEventsQuery.get();
|
|
@@ -2068,7 +2494,7 @@ var ProcedureAggregationService = class {
|
|
|
2068
2494
|
batch.update(doc.ref, {
|
|
2069
2495
|
status: "CANCELED",
|
|
2070
2496
|
cancelReason: "Procedure deleted or inactivated",
|
|
2071
|
-
updatedAt:
|
|
2497
|
+
updatedAt: admin6.firestore.FieldValue.serverTimestamp()
|
|
2072
2498
|
});
|
|
2073
2499
|
});
|
|
2074
2500
|
await batch.commit();
|
|
@@ -2125,9 +2551,9 @@ var ProcedureAggregationService = class {
|
|
|
2125
2551
|
(p) => p.id !== procedureId
|
|
2126
2552
|
);
|
|
2127
2553
|
const updateData = {
|
|
2128
|
-
procedureIds:
|
|
2554
|
+
procedureIds: admin6.firestore.FieldValue.arrayRemove(procedureId),
|
|
2129
2555
|
proceduresInfo: updatedProceduresInfo,
|
|
2130
|
-
updatedAt:
|
|
2556
|
+
updatedAt: admin6.firestore.FieldValue.serverTimestamp()
|
|
2131
2557
|
};
|
|
2132
2558
|
if (isFreeConsultation && procedureClinicId) {
|
|
2133
2559
|
const currentFreeConsultations = practitionerData.freeConsultations || {};
|
|
@@ -2193,9 +2619,9 @@ var ProcedureAggregationService = class {
|
|
|
2193
2619
|
(p) => p.id !== procedureId
|
|
2194
2620
|
);
|
|
2195
2621
|
transaction.update(clinicRef, {
|
|
2196
|
-
procedures:
|
|
2622
|
+
procedures: admin6.firestore.FieldValue.arrayRemove(procedureId),
|
|
2197
2623
|
proceduresInfo: updatedProceduresInfo,
|
|
2198
|
-
updatedAt:
|
|
2624
|
+
updatedAt: admin6.firestore.FieldValue.serverTimestamp()
|
|
2199
2625
|
});
|
|
2200
2626
|
});
|
|
2201
2627
|
console.log(
|
|
@@ -2272,7 +2698,7 @@ var ProcedureAggregationService = class {
|
|
|
2272
2698
|
}
|
|
2273
2699
|
transaction.update(practitionerRef, {
|
|
2274
2700
|
freeConsultations: updatedFreeConsultations,
|
|
2275
|
-
updatedAt:
|
|
2701
|
+
updatedAt: admin6.firestore.FieldValue.serverTimestamp()
|
|
2276
2702
|
});
|
|
2277
2703
|
});
|
|
2278
2704
|
console.log(
|
|
@@ -2289,11 +2715,11 @@ var ProcedureAggregationService = class {
|
|
|
2289
2715
|
};
|
|
2290
2716
|
|
|
2291
2717
|
// src/admin/aggregation/patient/patient.aggregation.service.ts
|
|
2292
|
-
var
|
|
2718
|
+
var admin7 = __toESM(require("firebase-admin"));
|
|
2293
2719
|
var CALENDAR_SUBCOLLECTION_ID4 = "calendar";
|
|
2294
2720
|
var PatientAggregationService = class {
|
|
2295
|
-
constructor(
|
|
2296
|
-
this.db =
|
|
2721
|
+
constructor(firestore17) {
|
|
2722
|
+
this.db = firestore17 || admin7.firestore();
|
|
2297
2723
|
}
|
|
2298
2724
|
// --- Methods for Patient Creation --- >
|
|
2299
2725
|
// No specific aggregations defined for patient creation in the plan.
|
|
@@ -2314,7 +2740,7 @@ var PatientAggregationService = class {
|
|
|
2314
2740
|
console.log(
|
|
2315
2741
|
`[PatientAggregationService] Querying upcoming calendar events for patient ${patientId} to update patient info.`
|
|
2316
2742
|
);
|
|
2317
|
-
const now =
|
|
2743
|
+
const now = admin7.firestore.Timestamp.now();
|
|
2318
2744
|
const calendarEventsQuery = this.db.collectionGroup(CALENDAR_SUBCOLLECTION_ID4).where("patientId", "==", patientId).where("eventTime.start", ">", now);
|
|
2319
2745
|
try {
|
|
2320
2746
|
const snapshot = await calendarEventsQuery.get();
|
|
@@ -2331,7 +2757,7 @@ var PatientAggregationService = class {
|
|
|
2331
2757
|
);
|
|
2332
2758
|
batch.update(doc.ref, {
|
|
2333
2759
|
patientInfo,
|
|
2334
|
-
updatedAt:
|
|
2760
|
+
updatedAt: admin7.firestore.FieldValue.serverTimestamp()
|
|
2335
2761
|
});
|
|
2336
2762
|
});
|
|
2337
2763
|
await batch.commit();
|
|
@@ -2362,7 +2788,7 @@ var PatientAggregationService = class {
|
|
|
2362
2788
|
console.log(
|
|
2363
2789
|
`[PatientAggregationService] Querying upcoming calendar events for patient ${patientId} to cancel.`
|
|
2364
2790
|
);
|
|
2365
|
-
const now =
|
|
2791
|
+
const now = admin7.firestore.Timestamp.now();
|
|
2366
2792
|
const calendarEventsQuery = this.db.collectionGroup(CALENDAR_SUBCOLLECTION_ID4).where("patientId", "==", patientId).where("eventTime.start", ">", now);
|
|
2367
2793
|
try {
|
|
2368
2794
|
const snapshot = await calendarEventsQuery.get();
|
|
@@ -2380,7 +2806,7 @@ var PatientAggregationService = class {
|
|
|
2380
2806
|
batch.update(doc.ref, {
|
|
2381
2807
|
status: "CANCELED",
|
|
2382
2808
|
cancelReason: "Patient deleted",
|
|
2383
|
-
updatedAt:
|
|
2809
|
+
updatedAt: admin7.firestore.FieldValue.serverTimestamp()
|
|
2384
2810
|
});
|
|
2385
2811
|
});
|
|
2386
2812
|
await batch.commit();
|
|
@@ -2398,7 +2824,7 @@ var PatientAggregationService = class {
|
|
|
2398
2824
|
};
|
|
2399
2825
|
|
|
2400
2826
|
// src/admin/aggregation/appointment/appointment.aggregation.service.ts
|
|
2401
|
-
var
|
|
2827
|
+
var admin11 = __toESM(require("firebase-admin"));
|
|
2402
2828
|
|
|
2403
2829
|
// src/types/patient/patient-requirements.ts
|
|
2404
2830
|
var PatientInstructionStatus = /* @__PURE__ */ ((PatientInstructionStatus2) => {
|
|
@@ -2423,10 +2849,10 @@ var PatientRequirementOverallStatus = /* @__PURE__ */ ((PatientRequirementOveral
|
|
|
2423
2849
|
var PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME = "patientRequirements";
|
|
2424
2850
|
|
|
2425
2851
|
// src/admin/requirements/patient-requirements.admin.service.ts
|
|
2426
|
-
var
|
|
2852
|
+
var admin8 = __toESM(require("firebase-admin"));
|
|
2427
2853
|
var PatientRequirementsAdminService = class {
|
|
2428
|
-
constructor(
|
|
2429
|
-
this.db =
|
|
2854
|
+
constructor(firestore17) {
|
|
2855
|
+
this.db = firestore17 || admin8.firestore();
|
|
2430
2856
|
this.notificationsAdmin = new NotificationsAdmin(this.db);
|
|
2431
2857
|
}
|
|
2432
2858
|
/**
|
|
@@ -2469,7 +2895,7 @@ var PatientRequirementsAdminService = class {
|
|
|
2469
2895
|
const previousInstruction = previousInstanceData == null ? void 0 : previousInstanceData.instructions.find(
|
|
2470
2896
|
(pi) => pi.instructionId === currentInstruction.instructionId
|
|
2471
2897
|
);
|
|
2472
|
-
const adminTsNow =
|
|
2898
|
+
const adminTsNow = admin8.firestore.Timestamp.now();
|
|
2473
2899
|
if (instance.overallStatus === "cancelledAppointment" /* CANCELLED_APPOINTMENT */ || instance.overallStatus === "supersededReschedule" /* SUPERSEDED_RESCHEDULE */ || currentInstruction.status === "cancelled" /* CANCELLED */) {
|
|
2474
2900
|
if (currentInstruction.notificationId) {
|
|
2475
2901
|
console.log(
|
|
@@ -2561,7 +2987,7 @@ var PatientRequirementsAdminService = class {
|
|
|
2561
2987
|
`[PRA_Service] Updating instructions array for instance ${instance.id} on patient ${patientId}.`
|
|
2562
2988
|
);
|
|
2563
2989
|
const instanceDocRef = this.db.collection(PATIENTS_COLLECTION).doc(patientId).collection(PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME).doc(instance.id);
|
|
2564
|
-
const finalAdminTsNow =
|
|
2990
|
+
const finalAdminTsNow = admin8.firestore.Timestamp.now();
|
|
2565
2991
|
await instanceDocRef.update({
|
|
2566
2992
|
instructions: updatedInstructions,
|
|
2567
2993
|
// Array of instructions with actual Timestamps
|
|
@@ -2636,7 +3062,7 @@ var PatientRequirementsAdminService = class {
|
|
|
2636
3062
|
return;
|
|
2637
3063
|
}
|
|
2638
3064
|
const instance = instanceSnap.data();
|
|
2639
|
-
const adminNowForMissed =
|
|
3065
|
+
const adminNowForMissed = admin8.firestore.Timestamp.now();
|
|
2640
3066
|
const updatedInstructions = instance.instructions.map((instr) => ({ ...instr }));
|
|
2641
3067
|
let changesMade = false;
|
|
2642
3068
|
for (let i = 0; i < updatedInstructions.length; i++) {
|
|
@@ -2658,7 +3084,7 @@ var PatientRequirementsAdminService = class {
|
|
|
2658
3084
|
}
|
|
2659
3085
|
}
|
|
2660
3086
|
if (changesMade) {
|
|
2661
|
-
const finalAdminNowForMissedUpdate =
|
|
3087
|
+
const finalAdminNowForMissedUpdate = admin8.firestore.Timestamp.now();
|
|
2662
3088
|
await instanceRef.update({
|
|
2663
3089
|
instructions: updatedInstructions,
|
|
2664
3090
|
// Array of instructions with actual Timestamps
|
|
@@ -2706,7 +3132,7 @@ var PatientRequirementsAdminService = class {
|
|
|
2706
3132
|
await instanceRef.update({
|
|
2707
3133
|
overallStatus: "active" /* ACTIVE */,
|
|
2708
3134
|
updatedAt: TimestampUtils.adminToClient(
|
|
2709
|
-
|
|
3135
|
+
admin8.firestore.Timestamp.now()
|
|
2710
3136
|
)
|
|
2711
3137
|
});
|
|
2712
3138
|
}
|
|
@@ -2736,7 +3162,7 @@ var PatientRequirementsAdminService = class {
|
|
|
2736
3162
|
console.log(
|
|
2737
3163
|
`[PRA_Service] Updating overallStatus for instance ${instanceId} from ${instance.overallStatus} to ${newOverallStatus}.`
|
|
2738
3164
|
);
|
|
2739
|
-
const adminTsNow =
|
|
3165
|
+
const adminTsNow = admin8.firestore.Timestamp.now();
|
|
2740
3166
|
await instanceRef.update({
|
|
2741
3167
|
overallStatus: newOverallStatus,
|
|
2742
3168
|
updatedAt: TimestampUtils.adminToClient(
|
|
@@ -2752,10 +3178,10 @@ var PatientRequirementsAdminService = class {
|
|
|
2752
3178
|
};
|
|
2753
3179
|
|
|
2754
3180
|
// src/admin/calendar/calendar.admin.service.ts
|
|
2755
|
-
var
|
|
3181
|
+
var admin9 = __toESM(require("firebase-admin"));
|
|
2756
3182
|
var CalendarAdminService = class {
|
|
2757
|
-
constructor(
|
|
2758
|
-
this.db =
|
|
3183
|
+
constructor(firestore17) {
|
|
3184
|
+
this.db = firestore17 || admin9.firestore();
|
|
2759
3185
|
Logger.info("[CalendarAdminService] Initialized.");
|
|
2760
3186
|
}
|
|
2761
3187
|
/**
|
|
@@ -2771,7 +3197,7 @@ var CalendarAdminService = class {
|
|
|
2771
3197
|
`[CalendarAdminService] Updating calendar event statuses for appointment ${appointment.id} to ${newStatus}`
|
|
2772
3198
|
);
|
|
2773
3199
|
const batch = this.db.batch();
|
|
2774
|
-
const serverTimestamp =
|
|
3200
|
+
const serverTimestamp = admin9.firestore.FieldValue.serverTimestamp();
|
|
2775
3201
|
let updatesAdded = 0;
|
|
2776
3202
|
const calendarEventId = appointment.calendarEventId;
|
|
2777
3203
|
if (!calendarEventId) {
|
|
@@ -2863,7 +3289,7 @@ var CalendarAdminService = class {
|
|
|
2863
3289
|
`[CalendarAdminService] Updating calendar event times for appointment ${appointment.id}`
|
|
2864
3290
|
);
|
|
2865
3291
|
const batch = this.db.batch();
|
|
2866
|
-
const serverTimestamp =
|
|
3292
|
+
const serverTimestamp = admin9.firestore.FieldValue.serverTimestamp();
|
|
2867
3293
|
let updatesAdded = 0;
|
|
2868
3294
|
const calendarEventId = appointment.calendarEventId;
|
|
2869
3295
|
if (!calendarEventId) {
|
|
@@ -3030,7 +3456,7 @@ var CalendarAdminService = class {
|
|
|
3030
3456
|
};
|
|
3031
3457
|
|
|
3032
3458
|
// src/admin/mailing/base.mailing.service.ts
|
|
3033
|
-
var
|
|
3459
|
+
var admin10 = __toESM(require("firebase-admin"));
|
|
3034
3460
|
var BaseMailingService = class {
|
|
3035
3461
|
// Expecting the new mailgun.js client
|
|
3036
3462
|
/**
|
|
@@ -3038,9 +3464,9 @@ var BaseMailingService = class {
|
|
|
3038
3464
|
* @param firestore Firestore instance provided by the caller
|
|
3039
3465
|
* @param mailgunClient Mailgun client instance (mailgun.js v10+) provided by the caller
|
|
3040
3466
|
*/
|
|
3041
|
-
constructor(
|
|
3467
|
+
constructor(firestore17, mailgunClient) {
|
|
3042
3468
|
var _a;
|
|
3043
|
-
this.db =
|
|
3469
|
+
this.db = firestore17;
|
|
3044
3470
|
this.mailgunClient = mailgunClient;
|
|
3045
3471
|
if (!this.db) {
|
|
3046
3472
|
Logger.error("[BaseMailingService] No Firestore instance provided");
|
|
@@ -3140,7 +3566,7 @@ var BaseMailingService = class {
|
|
|
3140
3566
|
status: error.status,
|
|
3141
3567
|
stack: error.stack
|
|
3142
3568
|
} : null,
|
|
3143
|
-
sentAt:
|
|
3569
|
+
sentAt: admin10.firestore.FieldValue.serverTimestamp()
|
|
3144
3570
|
});
|
|
3145
3571
|
Logger.info(
|
|
3146
3572
|
`[BaseMailingService] Email log recorded. Success: ${success}`
|
|
@@ -3184,8 +3610,8 @@ var BaseMailingService = class {
|
|
|
3184
3610
|
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>";
|
|
3185
3611
|
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>";
|
|
3186
3612
|
var AppointmentMailingService = class extends BaseMailingService {
|
|
3187
|
-
constructor(
|
|
3188
|
-
super(
|
|
3613
|
+
constructor(firestore17, mailgunClient) {
|
|
3614
|
+
super(firestore17, mailgunClient);
|
|
3189
3615
|
this.DEFAULT_MAILGUN_DOMAIN = "mg.metaesthetics.net";
|
|
3190
3616
|
Logger.info("[AppointmentMailingService] Initialized.");
|
|
3191
3617
|
}
|
|
@@ -3334,8 +3760,8 @@ var AppointmentAggregationService = class {
|
|
|
3334
3760
|
* @param mailgunClient - An initialized Mailgun client instance.
|
|
3335
3761
|
* @param firestore Optional Firestore instance. If not provided, it uses the default admin SDK instance.
|
|
3336
3762
|
*/
|
|
3337
|
-
constructor(mailgunClient,
|
|
3338
|
-
this.db =
|
|
3763
|
+
constructor(mailgunClient, firestore17) {
|
|
3764
|
+
this.db = firestore17 || admin11.firestore();
|
|
3339
3765
|
this.appointmentMailingService = new AppointmentMailingService(
|
|
3340
3766
|
this.db,
|
|
3341
3767
|
mailgunClient
|
|
@@ -3856,7 +4282,7 @@ var AppointmentAggregationService = class {
|
|
|
3856
4282
|
} else if (template.timeframe.unit === "hours" /* HOURS */) {
|
|
3857
4283
|
dueDateTime.setHours(dueDateTime.getHours() - notifyAtValue);
|
|
3858
4284
|
}
|
|
3859
|
-
dueTime =
|
|
4285
|
+
dueTime = admin11.firestore.Timestamp.fromDate(dueDateTime);
|
|
3860
4286
|
}
|
|
3861
4287
|
const actionableWindowHours = template.importance === "high" ? 1 : template.importance === "medium" ? 4 : 15;
|
|
3862
4288
|
const instructionObject = {
|
|
@@ -3871,7 +4297,7 @@ var AppointmentAggregationService = class {
|
|
|
3871
4297
|
status: "pendingNotification" /* PENDING_NOTIFICATION */,
|
|
3872
4298
|
originalNotifyAtValue: notifyAtValue,
|
|
3873
4299
|
originalTimeframeUnit: template.timeframe.unit,
|
|
3874
|
-
updatedAt:
|
|
4300
|
+
updatedAt: admin11.firestore.Timestamp.now()
|
|
3875
4301
|
// Use current server timestamp
|
|
3876
4302
|
};
|
|
3877
4303
|
return instructionObject;
|
|
@@ -3890,8 +4316,8 @@ var AppointmentAggregationService = class {
|
|
|
3890
4316
|
overallStatus: "active" /* ACTIVE */,
|
|
3891
4317
|
instructions,
|
|
3892
4318
|
// Timestamps - cast to any to satisfy client-side Timestamp type for now
|
|
3893
|
-
createdAt:
|
|
3894
|
-
updatedAt:
|
|
4319
|
+
createdAt: admin11.firestore.FieldValue.serverTimestamp(),
|
|
4320
|
+
updatedAt: admin11.firestore.FieldValue.serverTimestamp()
|
|
3895
4321
|
};
|
|
3896
4322
|
Logger.debug(
|
|
3897
4323
|
`[AggService] Setting data for requirement: ${JSON.stringify({
|
|
@@ -4104,7 +4530,7 @@ var AppointmentAggregationService = class {
|
|
|
4104
4530
|
} else if (template.timeframe.unit === "hours" /* HOURS */) {
|
|
4105
4531
|
dueDateTime.setHours(dueDateTime.getHours() + notifyAtValue);
|
|
4106
4532
|
}
|
|
4107
|
-
dueTime =
|
|
4533
|
+
dueTime = admin11.firestore.Timestamp.fromDate(dueDateTime);
|
|
4108
4534
|
}
|
|
4109
4535
|
const actionableWindowHours = template.importance === "high" ? 1 : template.importance === "medium" ? 4 : 15;
|
|
4110
4536
|
const instructionObject = {
|
|
@@ -4118,7 +4544,7 @@ var AppointmentAggregationService = class {
|
|
|
4118
4544
|
status: "pendingNotification" /* PENDING_NOTIFICATION */,
|
|
4119
4545
|
originalNotifyAtValue: notifyAtValue,
|
|
4120
4546
|
originalTimeframeUnit: template.timeframe.unit,
|
|
4121
|
-
updatedAt:
|
|
4547
|
+
updatedAt: admin11.firestore.Timestamp.now(),
|
|
4122
4548
|
notificationId: void 0,
|
|
4123
4549
|
actionTakenAt: void 0
|
|
4124
4550
|
};
|
|
@@ -4135,8 +4561,8 @@ var AppointmentAggregationService = class {
|
|
|
4135
4561
|
requirementImportance: template.importance,
|
|
4136
4562
|
overallStatus: "active" /* ACTIVE */,
|
|
4137
4563
|
instructions,
|
|
4138
|
-
createdAt:
|
|
4139
|
-
updatedAt:
|
|
4564
|
+
createdAt: admin11.firestore.FieldValue.serverTimestamp(),
|
|
4565
|
+
updatedAt: admin11.firestore.FieldValue.serverTimestamp()
|
|
4140
4566
|
};
|
|
4141
4567
|
Logger.debug(
|
|
4142
4568
|
`[AggService] Setting data for requirement: ${JSON.stringify({
|
|
@@ -4302,7 +4728,7 @@ var AppointmentAggregationService = class {
|
|
|
4302
4728
|
if (instance.overallStatus !== newOverallStatus && instance.overallStatus !== "failedToProcess" /* FAILED_TO_PROCESS */) {
|
|
4303
4729
|
batch.update(doc.ref, {
|
|
4304
4730
|
overallStatus: newOverallStatus,
|
|
4305
|
-
updatedAt:
|
|
4731
|
+
updatedAt: admin11.firestore.FieldValue.serverTimestamp()
|
|
4306
4732
|
// Cast for now
|
|
4307
4733
|
// Potentially also cancel individual instructions if not handled by another trigger
|
|
4308
4734
|
// instructions: instance.instructions.map(instr => ({ ...instr, status: PatientInstructionStatus.CANCELLED, updatedAt: admin.firestore.FieldValue.serverTimestamp() as any }))
|
|
@@ -4378,19 +4804,19 @@ var AppointmentAggregationService = class {
|
|
|
4378
4804
|
if (!hasDoctor || !hasClinic) {
|
|
4379
4805
|
const patientRef = this.db.collection(PATIENTS_COLLECTION).doc(patientProfile.id);
|
|
4380
4806
|
const updateData = {
|
|
4381
|
-
updatedAt:
|
|
4807
|
+
updatedAt: admin11.firestore.FieldValue.serverTimestamp()
|
|
4382
4808
|
};
|
|
4383
4809
|
if (!hasDoctor) {
|
|
4384
4810
|
Logger.debug(
|
|
4385
4811
|
`[AggService] Adding practitioner ${practitionerId} to patient ${patientProfile.id}`
|
|
4386
4812
|
);
|
|
4387
|
-
updateData.doctorIds =
|
|
4813
|
+
updateData.doctorIds = admin11.firestore.FieldValue.arrayUnion(practitionerId);
|
|
4388
4814
|
}
|
|
4389
4815
|
if (!hasClinic) {
|
|
4390
4816
|
Logger.debug(
|
|
4391
4817
|
`[AggService] Adding clinic ${clinicId} to patient ${patientProfile.id}`
|
|
4392
4818
|
);
|
|
4393
|
-
updateData.clinicIds =
|
|
4819
|
+
updateData.clinicIds = admin11.firestore.FieldValue.arrayUnion(clinicId);
|
|
4394
4820
|
}
|
|
4395
4821
|
await patientRef.update(updateData);
|
|
4396
4822
|
Logger.info(
|
|
@@ -4440,18 +4866,18 @@ var AppointmentAggregationService = class {
|
|
|
4440
4866
|
Logger.debug(
|
|
4441
4867
|
`[AggService] Removing practitioner ${practitionerId} from patient ${patientProfile.id}`
|
|
4442
4868
|
);
|
|
4443
|
-
updateData.doctorIds =
|
|
4869
|
+
updateData.doctorIds = admin11.firestore.FieldValue.arrayRemove(practitionerId);
|
|
4444
4870
|
updateNeeded = true;
|
|
4445
4871
|
}
|
|
4446
4872
|
if (activeClinicAppointments === 0 && ((_b = patientProfile.clinicIds) == null ? void 0 : _b.includes(clinicId))) {
|
|
4447
4873
|
Logger.debug(
|
|
4448
4874
|
`[AggService] Removing clinic ${clinicId} from patient ${patientProfile.id}`
|
|
4449
4875
|
);
|
|
4450
|
-
updateData.clinicIds =
|
|
4876
|
+
updateData.clinicIds = admin11.firestore.FieldValue.arrayRemove(clinicId);
|
|
4451
4877
|
updateNeeded = true;
|
|
4452
4878
|
}
|
|
4453
4879
|
if (updateNeeded) {
|
|
4454
|
-
updateData.updatedAt =
|
|
4880
|
+
updateData.updatedAt = admin11.firestore.FieldValue.serverTimestamp();
|
|
4455
4881
|
await patientRef.update(updateData);
|
|
4456
4882
|
Logger.info(
|
|
4457
4883
|
`[AggService] Successfully removed links from patient ${patientProfile.id}`
|
|
@@ -4585,14 +5011,14 @@ var AppointmentAggregationService = class {
|
|
|
4585
5011
|
};
|
|
4586
5012
|
|
|
4587
5013
|
// src/admin/aggregation/forms/filled-forms.aggregation.service.ts
|
|
4588
|
-
var
|
|
5014
|
+
var admin12 = __toESM(require("firebase-admin"));
|
|
4589
5015
|
var FilledFormsAggregationService = class {
|
|
4590
5016
|
/**
|
|
4591
5017
|
* Constructor for FilledFormsAggregationService.
|
|
4592
5018
|
* @param firestore Optional Firestore instance. If not provided, it uses the default admin SDK instance.
|
|
4593
5019
|
*/
|
|
4594
|
-
constructor(
|
|
4595
|
-
this.db =
|
|
5020
|
+
constructor(firestore17) {
|
|
5021
|
+
this.db = firestore17 || admin12.firestore();
|
|
4596
5022
|
Logger.info("[FilledFormsAggregationService] Initialized");
|
|
4597
5023
|
}
|
|
4598
5024
|
/**
|
|
@@ -4628,12 +5054,12 @@ var FilledFormsAggregationService = class {
|
|
|
4628
5054
|
path: `${APPOINTMENTS_COLLECTION}/${filledDocument.appointmentId}/${formSubcollection}/${filledDocument.id}`
|
|
4629
5055
|
};
|
|
4630
5056
|
if (filledDocument.updatedAt) {
|
|
4631
|
-
linkedFormInfo.submittedAt =
|
|
5057
|
+
linkedFormInfo.submittedAt = admin12.firestore.Timestamp.fromMillis(
|
|
4632
5058
|
filledDocument.updatedAt
|
|
4633
5059
|
);
|
|
4634
5060
|
}
|
|
4635
5061
|
if (filledDocument.status === "completed" /* COMPLETED */ || filledDocument.status === "signed" /* SIGNED */) {
|
|
4636
|
-
linkedFormInfo.completedAt =
|
|
5062
|
+
linkedFormInfo.completedAt = admin12.firestore.Timestamp.fromMillis(
|
|
4637
5063
|
filledDocument.updatedAt
|
|
4638
5064
|
);
|
|
4639
5065
|
}
|
|
@@ -4647,7 +5073,7 @@ var FilledFormsAggregationService = class {
|
|
|
4647
5073
|
updatedLinkedForms.push(linkedFormInfo);
|
|
4648
5074
|
updateData = {
|
|
4649
5075
|
linkedForms: updatedLinkedForms,
|
|
4650
|
-
updatedAt:
|
|
5076
|
+
updatedAt: admin12.firestore.FieldValue.serverTimestamp()
|
|
4651
5077
|
};
|
|
4652
5078
|
let updatedLinkedFormIds = appointment.linkedFormIds || [];
|
|
4653
5079
|
if (!updatedLinkedFormIds.includes(filledDocument.id)) {
|
|
@@ -4656,7 +5082,7 @@ var FilledFormsAggregationService = class {
|
|
|
4656
5082
|
}
|
|
4657
5083
|
if (filledDocument.isUserForm && filledDocument.isRequired && (filledDocument.status === "completed" /* COMPLETED */ || filledDocument.status === "signed" /* SIGNED */)) {
|
|
4658
5084
|
if (appointment.pendingUserFormsIds && appointment.pendingUserFormsIds.includes(filledDocument.id)) {
|
|
4659
|
-
updateData.pendingUserFormsIds =
|
|
5085
|
+
updateData.pendingUserFormsIds = admin12.firestore.FieldValue.arrayRemove(filledDocument.id);
|
|
4660
5086
|
Logger.info(
|
|
4661
5087
|
`[FilledFormsAggregationService] Removing form ${filledDocument.id} from pendingUserFormsIds`
|
|
4662
5088
|
);
|
|
@@ -4700,23 +5126,23 @@ var FilledFormsAggregationService = class {
|
|
|
4700
5126
|
(form) => form.formId === filledDocument.id
|
|
4701
5127
|
);
|
|
4702
5128
|
if (formToRemove) {
|
|
4703
|
-
updateData.linkedForms =
|
|
5129
|
+
updateData.linkedForms = admin12.firestore.FieldValue.arrayRemove(formToRemove);
|
|
4704
5130
|
}
|
|
4705
5131
|
}
|
|
4706
5132
|
if (appointment.linkedFormIds && appointment.linkedFormIds.includes(filledDocument.id)) {
|
|
4707
|
-
updateData.linkedFormIds =
|
|
5133
|
+
updateData.linkedFormIds = admin12.firestore.FieldValue.arrayRemove(
|
|
4708
5134
|
filledDocument.id
|
|
4709
5135
|
);
|
|
4710
5136
|
}
|
|
4711
5137
|
if (filledDocument.isUserForm && filledDocument.isRequired) {
|
|
4712
5138
|
if (filledDocument.status !== "completed" /* COMPLETED */ && filledDocument.status !== "signed" /* SIGNED */) {
|
|
4713
5139
|
if (!appointment.pendingUserFormsIds || !appointment.pendingUserFormsIds.includes(filledDocument.id)) {
|
|
4714
|
-
updateData.pendingUserFormsIds = appointment.pendingUserFormsIds ?
|
|
5140
|
+
updateData.pendingUserFormsIds = appointment.pendingUserFormsIds ? admin12.firestore.FieldValue.arrayUnion(filledDocument.id) : [filledDocument.id];
|
|
4715
5141
|
}
|
|
4716
5142
|
}
|
|
4717
5143
|
}
|
|
4718
5144
|
if (Object.keys(updateData).length > 0) {
|
|
4719
|
-
updateData.updatedAt =
|
|
5145
|
+
updateData.updatedAt = admin12.firestore.FieldValue.serverTimestamp();
|
|
4720
5146
|
await appointmentRef.update(updateData);
|
|
4721
5147
|
Logger.info(
|
|
4722
5148
|
`[FilledFormsAggregationService] Successfully updated appointment ${filledDocument.appointmentId} after form deletion`
|
|
@@ -4756,10 +5182,10 @@ var FilledFormsAggregationService = class {
|
|
|
4756
5182
|
return;
|
|
4757
5183
|
}
|
|
4758
5184
|
await appointmentRef.update({
|
|
4759
|
-
pendingUserFormsIds:
|
|
5185
|
+
pendingUserFormsIds: admin12.firestore.FieldValue.arrayUnion(
|
|
4760
5186
|
filledDocument.id
|
|
4761
5187
|
),
|
|
4762
|
-
updatedAt:
|
|
5188
|
+
updatedAt: admin12.firestore.FieldValue.serverTimestamp()
|
|
4763
5189
|
});
|
|
4764
5190
|
Logger.info(
|
|
4765
5191
|
`[FilledFormsAggregationService] Successfully added form ${filledDocument.id} to pendingUserFormsIds for appointment ${filledDocument.appointmentId}`
|
|
@@ -4775,7 +5201,7 @@ var FilledFormsAggregationService = class {
|
|
|
4775
5201
|
};
|
|
4776
5202
|
|
|
4777
5203
|
// src/admin/aggregation/reviews/reviews.aggregation.service.ts
|
|
4778
|
-
var
|
|
5204
|
+
var admin13 = __toESM(require("firebase-admin"));
|
|
4779
5205
|
|
|
4780
5206
|
// src/types/reviews/index.ts
|
|
4781
5207
|
var REVIEWS_COLLECTION = "reviews";
|
|
@@ -4786,8 +5212,8 @@ var ReviewsAggregationService = class {
|
|
|
4786
5212
|
* Constructor for ReviewsAggregationService.
|
|
4787
5213
|
* @param firestore Optional Firestore instance. If not provided, it uses the default admin SDK instance.
|
|
4788
5214
|
*/
|
|
4789
|
-
constructor(
|
|
4790
|
-
this.db =
|
|
5215
|
+
constructor(firestore17) {
|
|
5216
|
+
this.db = firestore17 || admin13.firestore();
|
|
4791
5217
|
}
|
|
4792
5218
|
/**
|
|
4793
5219
|
* Process a newly created review and update all related entities
|
|
@@ -4906,7 +5332,7 @@ var ReviewsAggregationService = class {
|
|
|
4906
5332
|
};
|
|
4907
5333
|
await this.db.collection(CLINICS_COLLECTION).doc(clinicId).update({
|
|
4908
5334
|
reviewInfo: updatedReviewInfo2,
|
|
4909
|
-
updatedAt:
|
|
5335
|
+
updatedAt: admin13.firestore.FieldValue.serverTimestamp()
|
|
4910
5336
|
});
|
|
4911
5337
|
console.log(
|
|
4912
5338
|
`[ReviewsAggregationService] Reset review info for clinic: ${clinicId}`
|
|
@@ -4945,7 +5371,7 @@ var ReviewsAggregationService = class {
|
|
|
4945
5371
|
};
|
|
4946
5372
|
await this.db.collection(CLINICS_COLLECTION).doc(clinicId).update({
|
|
4947
5373
|
reviewInfo: updatedReviewInfo,
|
|
4948
|
-
updatedAt:
|
|
5374
|
+
updatedAt: admin13.firestore.FieldValue.serverTimestamp()
|
|
4949
5375
|
});
|
|
4950
5376
|
console.log(
|
|
4951
5377
|
`[ReviewsAggregationService] Updated review info for clinic: ${clinicId}`
|
|
@@ -4995,7 +5421,7 @@ var ReviewsAggregationService = class {
|
|
|
4995
5421
|
};
|
|
4996
5422
|
await this.db.collection(PRACTITIONERS_COLLECTION).doc(practitionerId).update({
|
|
4997
5423
|
reviewInfo: updatedReviewInfo2,
|
|
4998
|
-
updatedAt:
|
|
5424
|
+
updatedAt: admin13.firestore.FieldValue.serverTimestamp()
|
|
4999
5425
|
});
|
|
5000
5426
|
await this.updateDoctorInfoInProcedures(practitionerId, 0);
|
|
5001
5427
|
console.log(
|
|
@@ -5035,7 +5461,7 @@ var ReviewsAggregationService = class {
|
|
|
5035
5461
|
};
|
|
5036
5462
|
await this.db.collection(PRACTITIONERS_COLLECTION).doc(practitionerId).update({
|
|
5037
5463
|
reviewInfo: updatedReviewInfo,
|
|
5038
|
-
updatedAt:
|
|
5464
|
+
updatedAt: admin13.firestore.FieldValue.serverTimestamp()
|
|
5039
5465
|
});
|
|
5040
5466
|
await this.updateDoctorInfoInProcedures(
|
|
5041
5467
|
practitionerId,
|
|
@@ -5089,7 +5515,7 @@ var ReviewsAggregationService = class {
|
|
|
5089
5515
|
};
|
|
5090
5516
|
await this.db.collection(PROCEDURES_COLLECTION).doc(procedureId).update({
|
|
5091
5517
|
reviewInfo: updatedReviewInfo2,
|
|
5092
|
-
updatedAt:
|
|
5518
|
+
updatedAt: admin13.firestore.FieldValue.serverTimestamp()
|
|
5093
5519
|
});
|
|
5094
5520
|
console.log(
|
|
5095
5521
|
`[ReviewsAggregationService] Reset review info for procedure: ${procedureId}`
|
|
@@ -5130,7 +5556,7 @@ var ReviewsAggregationService = class {
|
|
|
5130
5556
|
};
|
|
5131
5557
|
await this.db.collection(PROCEDURES_COLLECTION).doc(procedureId).update({
|
|
5132
5558
|
reviewInfo: updatedReviewInfo,
|
|
5133
|
-
updatedAt:
|
|
5559
|
+
updatedAt: admin13.firestore.FieldValue.serverTimestamp()
|
|
5134
5560
|
});
|
|
5135
5561
|
console.log(
|
|
5136
5562
|
`[ReviewsAggregationService] Updated review info for procedure: ${procedureId}`
|
|
@@ -5158,7 +5584,7 @@ var ReviewsAggregationService = class {
|
|
|
5158
5584
|
const procedureRef = this.db.collection(PROCEDURES_COLLECTION).doc(docSnapshot.id);
|
|
5159
5585
|
batch.update(procedureRef, {
|
|
5160
5586
|
"doctorInfo.rating": rating,
|
|
5161
|
-
updatedAt:
|
|
5587
|
+
updatedAt: admin13.firestore.FieldValue.serverTimestamp()
|
|
5162
5588
|
});
|
|
5163
5589
|
});
|
|
5164
5590
|
await batch.commit();
|
|
@@ -5195,7 +5621,7 @@ var ReviewsAggregationService = class {
|
|
|
5195
5621
|
clinicReview: review.clinicReview,
|
|
5196
5622
|
practitionerReview: review.practitionerReview,
|
|
5197
5623
|
procedureReview: review.procedureReview,
|
|
5198
|
-
updatedAt:
|
|
5624
|
+
updatedAt: admin13.firestore.FieldValue.serverTimestamp()
|
|
5199
5625
|
});
|
|
5200
5626
|
await batch.commit();
|
|
5201
5627
|
console.log(
|
|
@@ -5332,8 +5758,8 @@ var PractitionerInviteMailingService = class extends BaseMailingService {
|
|
|
5332
5758
|
* @param firestore Firestore instance provided by the caller
|
|
5333
5759
|
* @param mailgunClient Mailgun client instance (mailgun.js v10+) provided by the caller
|
|
5334
5760
|
*/
|
|
5335
|
-
constructor(
|
|
5336
|
-
super(
|
|
5761
|
+
constructor(firestore17, mailgunClient) {
|
|
5762
|
+
super(firestore17, mailgunClient);
|
|
5337
5763
|
this.DEFAULT_REGISTRATION_URL = "https://metaesthetics.net/register";
|
|
5338
5764
|
this.DEFAULT_SUBJECT = "You've Been Invited to Join as a Practitioner";
|
|
5339
5765
|
this.DEFAULT_MAILGUN_DOMAIN = "mg.metaesthetics.net";
|
|
@@ -5571,7 +5997,7 @@ var PractitionerInviteMailingService = class extends BaseMailingService {
|
|
|
5571
5997
|
};
|
|
5572
5998
|
|
|
5573
5999
|
// src/admin/booking/booking.admin.ts
|
|
5574
|
-
var
|
|
6000
|
+
var admin15 = __toESM(require("firebase-admin"));
|
|
5575
6001
|
|
|
5576
6002
|
// src/admin/booking/booking.calculator.ts
|
|
5577
6003
|
var import_firestore2 = require("firebase/firestore");
|
|
@@ -6005,10 +6431,10 @@ var BookingAvailabilityCalculator = class {
|
|
|
6005
6431
|
BookingAvailabilityCalculator.DEFAULT_INTERVAL_MINUTES = 15;
|
|
6006
6432
|
|
|
6007
6433
|
// src/admin/documentation-templates/document-manager.admin.ts
|
|
6008
|
-
var
|
|
6434
|
+
var admin14 = __toESM(require("firebase-admin"));
|
|
6009
6435
|
var DocumentManagerAdminService = class {
|
|
6010
|
-
constructor(
|
|
6011
|
-
this.db =
|
|
6436
|
+
constructor(firestore17) {
|
|
6437
|
+
this.db = firestore17;
|
|
6012
6438
|
}
|
|
6013
6439
|
/**
|
|
6014
6440
|
* Adds operations to a Firestore batch to initialize all linked forms for a new appointment
|
|
@@ -6111,7 +6537,7 @@ var DocumentManagerAdminService = class {
|
|
|
6111
6537
|
};
|
|
6112
6538
|
}
|
|
6113
6539
|
const templateIds = technologyTemplates.map((t) => t.templateId);
|
|
6114
|
-
const templatesSnapshot = await this.db.collection(DOCUMENTATION_TEMPLATES_COLLECTION).where(
|
|
6540
|
+
const templatesSnapshot = await this.db.collection(DOCUMENTATION_TEMPLATES_COLLECTION).where(admin14.firestore.FieldPath.documentId(), "in", templateIds).get();
|
|
6115
6541
|
const templatesMap = /* @__PURE__ */ new Map();
|
|
6116
6542
|
templatesSnapshot.forEach((doc) => {
|
|
6117
6543
|
templatesMap.set(doc.id, doc.data());
|
|
@@ -6177,8 +6603,8 @@ var BookingAdmin = class {
|
|
|
6177
6603
|
* Creates a new BookingAdmin instance
|
|
6178
6604
|
* @param firestore - Firestore instance provided by the caller
|
|
6179
6605
|
*/
|
|
6180
|
-
constructor(
|
|
6181
|
-
this.db =
|
|
6606
|
+
constructor(firestore17) {
|
|
6607
|
+
this.db = firestore17 || admin15.firestore();
|
|
6182
6608
|
this.documentManagerAdmin = new DocumentManagerAdminService(this.db);
|
|
6183
6609
|
}
|
|
6184
6610
|
/**
|
|
@@ -6200,8 +6626,8 @@ var BookingAdmin = class {
|
|
|
6200
6626
|
timeframeStart: timeframe.start instanceof Date ? timeframe.start.toISOString() : timeframe.start.toDate().toISOString(),
|
|
6201
6627
|
timeframeEnd: timeframe.end instanceof Date ? timeframe.end.toISOString() : timeframe.end.toDate().toISOString()
|
|
6202
6628
|
});
|
|
6203
|
-
const start = timeframe.start instanceof Date ?
|
|
6204
|
-
const end = timeframe.end instanceof Date ?
|
|
6629
|
+
const start = timeframe.start instanceof Date ? admin15.firestore.Timestamp.fromDate(timeframe.start) : timeframe.start;
|
|
6630
|
+
const end = timeframe.end instanceof Date ? admin15.firestore.Timestamp.fromDate(timeframe.end) : timeframe.end;
|
|
6205
6631
|
Logger.debug("[BookingAdmin] Fetching clinic data", { clinicId });
|
|
6206
6632
|
const clinicDoc = await this.db.collection("clinics").doc(clinicId).get();
|
|
6207
6633
|
if (!clinicDoc.exists) {
|
|
@@ -6286,7 +6712,7 @@ var BookingAdmin = class {
|
|
|
6286
6712
|
const result = BookingAvailabilityCalculator.calculateSlots(request);
|
|
6287
6713
|
const availableSlotsResult = {
|
|
6288
6714
|
availableSlots: result.availableSlots.map((slot) => ({
|
|
6289
|
-
start:
|
|
6715
|
+
start: admin15.firestore.Timestamp.fromMillis(slot.start.toMillis())
|
|
6290
6716
|
}))
|
|
6291
6717
|
};
|
|
6292
6718
|
Logger.info(
|
|
@@ -6450,8 +6876,8 @@ var BookingAdmin = class {
|
|
|
6450
6876
|
`[BookingAdmin] Orchestrating appointment creation for patient ${data.patientId} by user ${authenticatedUserId}`
|
|
6451
6877
|
);
|
|
6452
6878
|
const batch = this.db.batch();
|
|
6453
|
-
const adminTsNow =
|
|
6454
|
-
const serverTimestampValue =
|
|
6879
|
+
const adminTsNow = admin15.firestore.Timestamp.now();
|
|
6880
|
+
const serverTimestampValue = admin15.firestore.FieldValue.serverTimestamp();
|
|
6455
6881
|
try {
|
|
6456
6882
|
if (!data.patientId || !data.procedureId || !data.appointmentStartTime || !data.appointmentEndTime) {
|
|
6457
6883
|
return {
|
|
@@ -6548,7 +6974,7 @@ var BookingAdmin = class {
|
|
|
6548
6974
|
fullName: `${(patientSensitiveData == null ? void 0 : patientSensitiveData.firstName) || ""} ${(patientSensitiveData == null ? void 0 : patientSensitiveData.lastName) || ""}`.trim() || patientProfileData.displayName,
|
|
6549
6975
|
email: (patientSensitiveData == null ? void 0 : patientSensitiveData.email) || "",
|
|
6550
6976
|
phone: (patientSensitiveData == null ? void 0 : patientSensitiveData.phoneNumber) || patientProfileData.phoneNumber || null,
|
|
6551
|
-
dateOfBirth: (patientSensitiveData == null ? void 0 : patientSensitiveData.dateOfBirth) || patientProfileData.dateOfBirth ||
|
|
6977
|
+
dateOfBirth: (patientSensitiveData == null ? void 0 : patientSensitiveData.dateOfBirth) || patientProfileData.dateOfBirth || admin15.firestore.Timestamp.now(),
|
|
6552
6978
|
gender: (patientSensitiveData == null ? void 0 : patientSensitiveData.gender) || "other" /* OTHER */
|
|
6553
6979
|
};
|
|
6554
6980
|
const newAppointmentId = this.db.collection(APPOINTMENTS_COLLECTION).doc().id;
|
|
@@ -6781,7 +7207,7 @@ var BookingAdmin = class {
|
|
|
6781
7207
|
};
|
|
6782
7208
|
|
|
6783
7209
|
// src/admin/free-consultation/free-consultation-utils.admin.ts
|
|
6784
|
-
var
|
|
7210
|
+
var admin16 = __toESM(require("firebase-admin"));
|
|
6785
7211
|
|
|
6786
7212
|
// src/backoffice/types/category.types.ts
|
|
6787
7213
|
var CATEGORIES_COLLECTION = "backoffice_categories";
|
|
@@ -6794,12 +7220,12 @@ var TECHNOLOGIES_COLLECTION = "technologies";
|
|
|
6794
7220
|
|
|
6795
7221
|
// src/admin/free-consultation/free-consultation-utils.admin.ts
|
|
6796
7222
|
async function freeConsultationInfrastructure(db) {
|
|
6797
|
-
const
|
|
7223
|
+
const firestore17 = db || admin16.firestore();
|
|
6798
7224
|
try {
|
|
6799
7225
|
console.log(
|
|
6800
7226
|
"[freeConsultationInfrastructure] Checking free consultation infrastructure..."
|
|
6801
7227
|
);
|
|
6802
|
-
const technologyRef =
|
|
7228
|
+
const technologyRef = firestore17.collection(TECHNOLOGIES_COLLECTION).doc("free-consultation-tech");
|
|
6803
7229
|
const technologyDoc = await technologyRef.get();
|
|
6804
7230
|
if (technologyDoc.exists) {
|
|
6805
7231
|
console.log(
|
|
@@ -6810,7 +7236,7 @@ async function freeConsultationInfrastructure(db) {
|
|
|
6810
7236
|
console.log(
|
|
6811
7237
|
"[freeConsultationInfrastructure] Creating free consultation infrastructure..."
|
|
6812
7238
|
);
|
|
6813
|
-
await createFreeConsultationInfrastructure(
|
|
7239
|
+
await createFreeConsultationInfrastructure(firestore17);
|
|
6814
7240
|
console.log(
|
|
6815
7241
|
"[freeConsultationInfrastructure] Successfully created free consultation infrastructure"
|
|
6816
7242
|
);
|
|
@@ -6919,7 +7345,9 @@ TimestampUtils.enableServerMode();
|
|
|
6919
7345
|
PatientRequirementsAdminService,
|
|
6920
7346
|
PaymentStatus,
|
|
6921
7347
|
PractitionerAggregationService,
|
|
7348
|
+
PractitionerInviteAggregationService,
|
|
6922
7349
|
PractitionerInviteMailingService,
|
|
7350
|
+
PractitionerInviteStatus,
|
|
6923
7351
|
PractitionerTokenStatus,
|
|
6924
7352
|
ProcedureAggregationService,
|
|
6925
7353
|
ReviewsAggregationService,
|