@blackcode_sa/metaestetics-api 1.7.31 → 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.
@@ -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(firestore16) {
211
+ constructor(firestore17) {
210
212
  this.expo = new import_expo_server_sdk.Expo();
211
- this.db = firestore16 || admin.firestore();
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(firestore16) {
931
- this.db = firestore16 || admin3.firestore();
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(firestore16) {
1444
- this.db = firestore16 || admin4.firestore();
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/procedure/procedure.aggregation.service.ts
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(firestore16) {
1780
- this.db = firestore16 || admin5.firestore();
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: admin5.firestore.FieldValue.arrayUnion(procedureId),
1805
- proceduresInfo: admin5.firestore.FieldValue.arrayUnion(procedureSummary),
1806
- updatedAt: admin5.firestore.FieldValue.serverTimestamp()
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: admin5.firestore.FieldValue.arrayUnion(procedureId),
1870
- proceduresInfo: admin5.firestore.FieldValue.arrayUnion(procedureSummary),
1871
- updatedAt: admin5.firestore.FieldValue.serverTimestamp()
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: admin5.firestore.FieldValue.serverTimestamp()
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: admin5.firestore.FieldValue.serverTimestamp()
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 = admin5.firestore.Timestamp.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: admin5.firestore.FieldValue.serverTimestamp()
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 = admin5.firestore.Timestamp.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: admin5.firestore.FieldValue.serverTimestamp()
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: admin5.firestore.FieldValue.arrayRemove(procedureId),
2554
+ procedureIds: admin6.firestore.FieldValue.arrayRemove(procedureId),
2129
2555
  proceduresInfo: updatedProceduresInfo,
2130
- updatedAt: admin5.firestore.FieldValue.serverTimestamp()
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: admin5.firestore.FieldValue.arrayRemove(procedureId),
2622
+ procedures: admin6.firestore.FieldValue.arrayRemove(procedureId),
2197
2623
  proceduresInfo: updatedProceduresInfo,
2198
- updatedAt: admin5.firestore.FieldValue.serverTimestamp()
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: admin5.firestore.FieldValue.serverTimestamp()
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 admin6 = __toESM(require("firebase-admin"));
2718
+ var admin7 = __toESM(require("firebase-admin"));
2293
2719
  var CALENDAR_SUBCOLLECTION_ID4 = "calendar";
2294
2720
  var PatientAggregationService = class {
2295
- constructor(firestore16) {
2296
- this.db = firestore16 || admin6.firestore();
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 = admin6.firestore.Timestamp.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: admin6.firestore.FieldValue.serverTimestamp()
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 = admin6.firestore.Timestamp.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: admin6.firestore.FieldValue.serverTimestamp()
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 admin10 = __toESM(require("firebase-admin"));
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 admin7 = __toESM(require("firebase-admin"));
2852
+ var admin8 = __toESM(require("firebase-admin"));
2427
2853
  var PatientRequirementsAdminService = class {
2428
- constructor(firestore16) {
2429
- this.db = firestore16 || admin7.firestore();
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 = admin7.firestore.Timestamp.now();
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 = admin7.firestore.Timestamp.now();
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 = admin7.firestore.Timestamp.now();
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 = admin7.firestore.Timestamp.now();
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
- admin7.firestore.Timestamp.now()
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 = admin7.firestore.Timestamp.now();
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 admin8 = __toESM(require("firebase-admin"));
3181
+ var admin9 = __toESM(require("firebase-admin"));
2756
3182
  var CalendarAdminService = class {
2757
- constructor(firestore16) {
2758
- this.db = firestore16 || admin8.firestore();
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 = admin8.firestore.FieldValue.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 = admin8.firestore.FieldValue.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 admin9 = __toESM(require("firebase-admin"));
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(firestore16, mailgunClient) {
3467
+ constructor(firestore17, mailgunClient) {
3042
3468
  var _a;
3043
- this.db = firestore16;
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: admin9.firestore.FieldValue.serverTimestamp()
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(firestore16, mailgunClient) {
3188
- super(firestore16, mailgunClient);
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, firestore16) {
3338
- this.db = firestore16 || admin10.firestore();
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 = admin10.firestore.Timestamp.fromDate(dueDateTime);
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: admin10.firestore.Timestamp.now()
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: admin10.firestore.FieldValue.serverTimestamp(),
3894
- updatedAt: admin10.firestore.FieldValue.serverTimestamp()
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 = admin10.firestore.Timestamp.fromDate(dueDateTime);
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: admin10.firestore.Timestamp.now(),
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: admin10.firestore.FieldValue.serverTimestamp(),
4139
- updatedAt: admin10.firestore.FieldValue.serverTimestamp()
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: admin10.firestore.FieldValue.serverTimestamp()
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: admin10.firestore.FieldValue.serverTimestamp()
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 = admin10.firestore.FieldValue.arrayUnion(practitionerId);
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 = admin10.firestore.FieldValue.arrayUnion(clinicId);
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 = admin10.firestore.FieldValue.arrayRemove(practitionerId);
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 = admin10.firestore.FieldValue.arrayRemove(clinicId);
4876
+ updateData.clinicIds = admin11.firestore.FieldValue.arrayRemove(clinicId);
4451
4877
  updateNeeded = true;
4452
4878
  }
4453
4879
  if (updateNeeded) {
4454
- updateData.updatedAt = admin10.firestore.FieldValue.serverTimestamp();
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 admin11 = __toESM(require("firebase-admin"));
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(firestore16) {
4595
- this.db = firestore16 || admin11.firestore();
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 = admin11.firestore.Timestamp.fromMillis(
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 = admin11.firestore.Timestamp.fromMillis(
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: admin11.firestore.FieldValue.serverTimestamp()
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 = admin11.firestore.FieldValue.arrayRemove(filledDocument.id);
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 = admin11.firestore.FieldValue.arrayRemove(formToRemove);
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 = admin11.firestore.FieldValue.arrayRemove(
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 ? admin11.firestore.FieldValue.arrayUnion(filledDocument.id) : [filledDocument.id];
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 = admin11.firestore.FieldValue.serverTimestamp();
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: admin11.firestore.FieldValue.arrayUnion(
5185
+ pendingUserFormsIds: admin12.firestore.FieldValue.arrayUnion(
4760
5186
  filledDocument.id
4761
5187
  ),
4762
- updatedAt: admin11.firestore.FieldValue.serverTimestamp()
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 admin12 = __toESM(require("firebase-admin"));
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(firestore16) {
4790
- this.db = firestore16 || admin12.firestore();
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: admin12.firestore.FieldValue.serverTimestamp()
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: admin12.firestore.FieldValue.serverTimestamp()
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: admin12.firestore.FieldValue.serverTimestamp()
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: admin12.firestore.FieldValue.serverTimestamp()
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: admin12.firestore.FieldValue.serverTimestamp()
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: admin12.firestore.FieldValue.serverTimestamp()
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: admin12.firestore.FieldValue.serverTimestamp()
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: admin12.firestore.FieldValue.serverTimestamp()
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(firestore16, mailgunClient) {
5336
- super(firestore16, mailgunClient);
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 admin14 = __toESM(require("firebase-admin"));
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 admin13 = __toESM(require("firebase-admin"));
6434
+ var admin14 = __toESM(require("firebase-admin"));
6009
6435
  var DocumentManagerAdminService = class {
6010
- constructor(firestore16) {
6011
- this.db = firestore16;
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(admin13.firestore.FieldPath.documentId(), "in", templateIds).get();
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(firestore16) {
6181
- this.db = firestore16 || admin14.firestore();
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 ? admin14.firestore.Timestamp.fromDate(timeframe.start) : timeframe.start;
6204
- const end = timeframe.end instanceof Date ? admin14.firestore.Timestamp.fromDate(timeframe.end) : timeframe.end;
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: admin14.firestore.Timestamp.fromMillis(slot.start.toMillis())
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 = admin14.firestore.Timestamp.now();
6454
- const serverTimestampValue = admin14.firestore.FieldValue.serverTimestamp();
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 || admin14.firestore.Timestamp.now(),
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 admin15 = __toESM(require("firebase-admin"));
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 firestore16 = db || admin15.firestore();
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 = firestore16.collection(TECHNOLOGIES_COLLECTION).doc("free-consultation-tech");
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(firestore16);
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,