@blackcode_sa/metaestetics-api 1.7.14 → 1.7.16

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.
@@ -2417,6 +2417,12 @@ declare class BookingAdmin {
2417
2417
  * @returns Promise resolving to an array of calendar events
2418
2418
  */
2419
2419
  private getPractitionerCalendarEvents;
2420
+ /**
2421
+ * Summarizes event types for logging purposes
2422
+ * @param events Array of calendar events
2423
+ * @returns Object with counts of each event type
2424
+ */
2425
+ private summarizeEventTypes;
2420
2426
  private _generateCalendarProcedureInfo;
2421
2427
  /**
2422
2428
  * Orchestrates the creation of a new appointment, including data aggregation.
@@ -2430,9 +2436,7 @@ declare class BookingAdmin {
2430
2436
  success: boolean;
2431
2437
  appointmentId?: string;
2432
2438
  appointmentData?: Appointment;
2433
- practitionerCalendarEventId?: string;
2434
- patientCalendarEventId?: string;
2435
- clinicCalendarEventId?: string;
2439
+ calendarEventId?: string;
2436
2440
  error?: string;
2437
2441
  }>;
2438
2442
  private _generateProcedureSummaryInfo;
@@ -2417,6 +2417,12 @@ declare class BookingAdmin {
2417
2417
  * @returns Promise resolving to an array of calendar events
2418
2418
  */
2419
2419
  private getPractitionerCalendarEvents;
2420
+ /**
2421
+ * Summarizes event types for logging purposes
2422
+ * @param events Array of calendar events
2423
+ * @returns Object with counts of each event type
2424
+ */
2425
+ private summarizeEventTypes;
2420
2426
  private _generateCalendarProcedureInfo;
2421
2427
  /**
2422
2428
  * Orchestrates the creation of a new appointment, including data aggregation.
@@ -2430,9 +2436,7 @@ declare class BookingAdmin {
2430
2436
  success: boolean;
2431
2437
  appointmentId?: string;
2432
2438
  appointmentData?: Appointment;
2433
- practitionerCalendarEventId?: string;
2434
- patientCalendarEventId?: string;
2435
- clinicCalendarEventId?: string;
2439
+ calendarEventId?: string;
2436
2440
  error?: string;
2437
2441
  }>;
2438
2442
  private _generateProcedureSummaryInfo;
@@ -6032,33 +6032,76 @@ var BookingAdmin = class {
6032
6032
  * @returns Promise resolving to an array of available booking slots
6033
6033
  */
6034
6034
  async getAvailableBookingSlots(clinicId, practitionerId, procedureId, timeframe) {
6035
+ var _a;
6035
6036
  try {
6036
- console.log(
6037
- `[BookingAdmin] Getting available slots for clinic ${clinicId}, practitioner ${practitionerId}, procedure ${procedureId}`
6038
- );
6037
+ Logger.info("[BookingAdmin] Starting availability calculation", {
6038
+ clinicId,
6039
+ practitionerId,
6040
+ procedureId,
6041
+ timeframeStart: timeframe.start instanceof Date ? timeframe.start.toISOString() : timeframe.start.toDate().toISOString(),
6042
+ timeframeEnd: timeframe.end instanceof Date ? timeframe.end.toISOString() : timeframe.end.toDate().toISOString()
6043
+ });
6039
6044
  const start = timeframe.start instanceof Date ? admin14.firestore.Timestamp.fromDate(timeframe.start) : timeframe.start;
6040
6045
  const end = timeframe.end instanceof Date ? admin14.firestore.Timestamp.fromDate(timeframe.end) : timeframe.end;
6046
+ Logger.debug("[BookingAdmin] Fetching clinic data", { clinicId });
6041
6047
  const clinicDoc = await this.db.collection("clinics").doc(clinicId).get();
6042
6048
  if (!clinicDoc.exists) {
6049
+ Logger.error("[BookingAdmin] Clinic not found", { clinicId });
6043
6050
  throw new Error(`Clinic ${clinicId} not found`);
6044
6051
  }
6045
6052
  const clinic = clinicDoc.data();
6053
+ Logger.debug("[BookingAdmin] Retrieved clinic data", {
6054
+ clinicName: clinic.name,
6055
+ clinicHasWorkingHours: !!clinic.workingHours
6056
+ });
6057
+ Logger.debug("[BookingAdmin] Fetching practitioner data", {
6058
+ practitionerId
6059
+ });
6046
6060
  const practitionerDoc = await this.db.collection("practitioners").doc(practitionerId).get();
6047
6061
  if (!practitionerDoc.exists) {
6062
+ Logger.error("[BookingAdmin] Practitioner not found", {
6063
+ practitionerId
6064
+ });
6048
6065
  throw new Error(`Practitioner ${practitionerId} not found`);
6049
6066
  }
6050
6067
  const practitioner = practitionerDoc.data();
6068
+ Logger.debug("[BookingAdmin] Retrieved practitioner data", {
6069
+ practitionerName: `${practitioner.basicInfo.firstName} ${practitioner.basicInfo.lastName}`,
6070
+ pracWorkingHoursCount: ((_a = practitioner.clinicWorkingHours) == null ? void 0 : _a.length) || 0
6071
+ });
6072
+ Logger.debug("[BookingAdmin] Fetching procedure data", { procedureId });
6051
6073
  const procedureDoc = await this.db.collection("procedures").doc(procedureId).get();
6052
6074
  if (!procedureDoc.exists) {
6075
+ Logger.error("[BookingAdmin] Procedure not found", { procedureId });
6053
6076
  throw new Error(`Procedure ${procedureId} not found`);
6054
6077
  }
6055
6078
  const procedure = procedureDoc.data();
6079
+ Logger.debug("[BookingAdmin] Retrieved procedure data", {
6080
+ procedureName: procedure.name,
6081
+ procedureDuration: procedure.duration
6082
+ });
6083
+ Logger.debug("[BookingAdmin] Fetching clinic calendar events", {
6084
+ clinicId,
6085
+ startTime: start.toDate().toISOString(),
6086
+ endTime: end.toDate().toISOString()
6087
+ });
6056
6088
  const clinicCalendarEvents = await this.getClinicCalendarEvents(
6057
6089
  clinicId,
6058
6090
  start,
6059
6091
  end
6060
6092
  );
6093
+ Logger.debug("[BookingAdmin] Retrieved clinic calendar events", {
6094
+ count: clinicCalendarEvents.length
6095
+ });
6096
+ Logger.debug("[BookingAdmin] Fetching practitioner calendar events", {
6097
+ practitionerId,
6098
+ startTime: start.toDate().toISOString(),
6099
+ endTime: end.toDate().toISOString()
6100
+ });
6061
6101
  const practitionerCalendarEvents = await this.getPractitionerCalendarEvents(practitionerId, start, end);
6102
+ Logger.debug("[BookingAdmin] Retrieved practitioner calendar events", {
6103
+ count: practitionerCalendarEvents.length
6104
+ });
6062
6105
  const convertedTimeframe = {
6063
6106
  start: this.adminTimestampToClientTimestamp(start),
6064
6107
  end: this.adminTimestampToClientTimestamp(end)
@@ -6073,14 +6116,38 @@ var BookingAdmin = class {
6073
6116
  practitionerCalendarEvents
6074
6117
  )
6075
6118
  };
6119
+ Logger.info("[BookingAdmin] Calling availability calculator", {
6120
+ calculatorInputReady: true,
6121
+ timeframeDurationHours: Math.round(
6122
+ (end.toMillis() - start.toMillis()) / (1e3 * 60 * 60)
6123
+ ),
6124
+ clinicEventsCount: clinicCalendarEvents.length,
6125
+ practitionerEventsCount: practitionerCalendarEvents.length
6126
+ });
6076
6127
  const result = BookingAvailabilityCalculator.calculateSlots(request);
6077
- return {
6128
+ const availableSlotsResult = {
6078
6129
  availableSlots: result.availableSlots.map((slot) => ({
6079
6130
  start: admin14.firestore.Timestamp.fromMillis(slot.start.toMillis())
6080
6131
  }))
6081
6132
  };
6133
+ Logger.info(
6134
+ "[BookingAdmin] Availability calculation completed successfully",
6135
+ {
6136
+ availableSlotsCount: availableSlotsResult.availableSlots.length,
6137
+ firstSlotTime: availableSlotsResult.availableSlots.length > 0 ? availableSlotsResult.availableSlots[0].start.toDate().toISOString() : "none",
6138
+ lastSlotTime: availableSlotsResult.availableSlots.length > 0 ? availableSlotsResult.availableSlots[availableSlotsResult.availableSlots.length - 1].start.toDate().toISOString() : "none"
6139
+ }
6140
+ );
6141
+ return availableSlotsResult;
6082
6142
  } catch (error) {
6083
- console.error("[BookingAdmin] Error getting available slots:", error);
6143
+ const errorMessage = error instanceof Error ? error.message : String(error);
6144
+ Logger.error("[BookingAdmin] Error getting available slots", {
6145
+ errorMessage,
6146
+ clinicId,
6147
+ practitionerId,
6148
+ procedureId,
6149
+ stack: error instanceof Error ? error.stack : void 0
6150
+ });
6084
6151
  throw error;
6085
6152
  }
6086
6153
  }
@@ -6117,17 +6184,32 @@ var BookingAdmin = class {
6117
6184
  */
6118
6185
  async getClinicCalendarEvents(clinicId, start, end) {
6119
6186
  try {
6187
+ Logger.debug("[BookingAdmin] Querying clinic calendar events", {
6188
+ clinicId,
6189
+ startTime: start.toDate().toISOString(),
6190
+ endTime: end.toDate().toISOString()
6191
+ });
6120
6192
  const eventsRef = this.db.collection(`clinics/${clinicId}/calendar`).where("eventTime.start", ">=", start).where("eventTime.start", "<=", end);
6121
6193
  const snapshot = await eventsRef.get();
6122
- return snapshot.docs.map((doc) => ({
6194
+ const events = snapshot.docs.map((doc) => ({
6123
6195
  ...doc.data(),
6124
6196
  id: doc.id
6125
6197
  }));
6198
+ Logger.debug("[BookingAdmin] Retrieved clinic calendar events", {
6199
+ clinicId,
6200
+ eventsCount: events.length,
6201
+ eventsTypes: this.summarizeEventTypes(events)
6202
+ });
6203
+ return events;
6126
6204
  } catch (error) {
6127
- console.error(
6128
- `[BookingAdmin] Error fetching clinic calendar events:`,
6129
- error
6130
- );
6205
+ const errorMessage = error instanceof Error ? error.message : String(error);
6206
+ Logger.error("[BookingAdmin] Error fetching clinic calendar events", {
6207
+ errorMessage,
6208
+ clinicId,
6209
+ startTime: start.toDate().toISOString(),
6210
+ endTime: end.toDate().toISOString(),
6211
+ stack: error instanceof Error ? error.stack : void 0
6212
+ });
6131
6213
  return [];
6132
6214
  }
6133
6215
  }
@@ -6141,20 +6223,51 @@ var BookingAdmin = class {
6141
6223
  */
6142
6224
  async getPractitionerCalendarEvents(practitionerId, start, end) {
6143
6225
  try {
6226
+ Logger.debug("[BookingAdmin] Querying practitioner calendar events", {
6227
+ practitionerId,
6228
+ startTime: start.toDate().toISOString(),
6229
+ endTime: end.toDate().toISOString()
6230
+ });
6144
6231
  const eventsRef = this.db.collection(`practitioners/${practitionerId}/calendar`).where("eventTime.start", ">=", start).where("eventTime.start", "<=", end);
6145
6232
  const snapshot = await eventsRef.get();
6146
- return snapshot.docs.map((doc) => ({
6233
+ const events = snapshot.docs.map((doc) => ({
6147
6234
  ...doc.data(),
6148
6235
  id: doc.id
6149
6236
  }));
6237
+ Logger.debug("[BookingAdmin] Retrieved practitioner calendar events", {
6238
+ practitionerId,
6239
+ eventsCount: events.length,
6240
+ eventsTypes: this.summarizeEventTypes(events)
6241
+ });
6242
+ return events;
6150
6243
  } catch (error) {
6151
- console.error(
6152
- `[BookingAdmin] Error fetching practitioner calendar events:`,
6153
- error
6244
+ const errorMessage = error instanceof Error ? error.message : String(error);
6245
+ Logger.error(
6246
+ "[BookingAdmin] Error fetching practitioner calendar events",
6247
+ {
6248
+ errorMessage,
6249
+ practitionerId,
6250
+ startTime: start.toDate().toISOString(),
6251
+ endTime: end.toDate().toISOString(),
6252
+ stack: error instanceof Error ? error.stack : void 0
6253
+ }
6154
6254
  );
6155
6255
  return [];
6156
6256
  }
6157
6257
  }
6258
+ /**
6259
+ * Summarizes event types for logging purposes
6260
+ * @param events Array of calendar events
6261
+ * @returns Object with counts of each event type
6262
+ */
6263
+ summarizeEventTypes(events) {
6264
+ const typeCounts = {};
6265
+ events.forEach((event) => {
6266
+ const eventType = event.eventType || "unknown";
6267
+ typeCounts[eventType] = (typeCounts[eventType] || 0) + 1;
6268
+ });
6269
+ return typeCounts;
6270
+ }
6158
6271
  _generateCalendarProcedureInfo(procedure) {
6159
6272
  return {
6160
6273
  name: procedure.name,
@@ -6310,9 +6423,8 @@ var BookingAdmin = class {
6310
6423
  this.db.collection(PRACTITIONERS_COLLECTION).doc(practitionerData.id).collection(CALENDAR_COLLECTION).doc(practitionerCalendarEventId),
6311
6424
  practitionerCalendarEventData
6312
6425
  );
6313
- const patientCalendarEventId = this.db.collection(PATIENTS_COLLECTION).doc(patientProfileData.id).collection(CALENDAR_COLLECTION).doc().id;
6314
6426
  const patientCalendarEventData = {
6315
- id: patientCalendarEventId,
6427
+ id: practitionerCalendarEventId,
6316
6428
  appointmentId: newAppointmentId,
6317
6429
  clinicBranchId: clinicData.id,
6318
6430
  clinicBranchInfo: clinicInfo,
@@ -6331,12 +6443,11 @@ var BookingAdmin = class {
6331
6443
  updatedAt: serverTimestampValue
6332
6444
  };
6333
6445
  batch.set(
6334
- this.db.collection(PATIENTS_COLLECTION).doc(patientProfileData.id).collection(CALENDAR_COLLECTION).doc(patientCalendarEventId),
6446
+ this.db.collection(PATIENTS_COLLECTION).doc(patientProfileData.id).collection(CALENDAR_COLLECTION).doc(practitionerCalendarEventId),
6335
6447
  patientCalendarEventData
6336
6448
  );
6337
- const clinicCalendarEventId = this.db.collection(CLINICS_COLLECTION).doc(clinicData.id).collection(CALENDAR_COLLECTION).doc().id;
6338
6449
  const clinicCalendarEventData = {
6339
- id: clinicCalendarEventId,
6450
+ id: practitionerCalendarEventId,
6340
6451
  appointmentId: newAppointmentId,
6341
6452
  clinicBranchId: clinicData.id,
6342
6453
  clinicBranchInfo: clinicInfo,
@@ -6357,7 +6468,7 @@ var BookingAdmin = class {
6357
6468
  updatedAt: serverTimestampValue
6358
6469
  };
6359
6470
  batch.set(
6360
- this.db.collection(CLINICS_COLLECTION).doc(clinicData.id).collection(CALENDAR_COLLECTION).doc(clinicCalendarEventId),
6471
+ this.db.collection(CLINICS_COLLECTION).doc(clinicData.id).collection(CALENDAR_COLLECTION).doc(practitionerCalendarEventId),
6361
6472
  clinicCalendarEventData
6362
6473
  );
6363
6474
  let initializedFormsInfo = [];
@@ -6445,9 +6556,7 @@ var BookingAdmin = class {
6445
6556
  success: true,
6446
6557
  appointmentId: newAppointmentId,
6447
6558
  appointmentData: newAppointmentData,
6448
- practitionerCalendarEventId,
6449
- patientCalendarEventId,
6450
- clinicCalendarEventId
6559
+ calendarEventId: practitionerCalendarEventId
6451
6560
  };
6452
6561
  } catch (error) {
6453
6562
  console.error(
@@ -5975,33 +5975,76 @@ var BookingAdmin = class {
5975
5975
  * @returns Promise resolving to an array of available booking slots
5976
5976
  */
5977
5977
  async getAvailableBookingSlots(clinicId, practitionerId, procedureId, timeframe) {
5978
+ var _a;
5978
5979
  try {
5979
- console.log(
5980
- `[BookingAdmin] Getting available slots for clinic ${clinicId}, practitioner ${practitionerId}, procedure ${procedureId}`
5981
- );
5980
+ Logger.info("[BookingAdmin] Starting availability calculation", {
5981
+ clinicId,
5982
+ practitionerId,
5983
+ procedureId,
5984
+ timeframeStart: timeframe.start instanceof Date ? timeframe.start.toISOString() : timeframe.start.toDate().toISOString(),
5985
+ timeframeEnd: timeframe.end instanceof Date ? timeframe.end.toISOString() : timeframe.end.toDate().toISOString()
5986
+ });
5982
5987
  const start = timeframe.start instanceof Date ? admin14.firestore.Timestamp.fromDate(timeframe.start) : timeframe.start;
5983
5988
  const end = timeframe.end instanceof Date ? admin14.firestore.Timestamp.fromDate(timeframe.end) : timeframe.end;
5989
+ Logger.debug("[BookingAdmin] Fetching clinic data", { clinicId });
5984
5990
  const clinicDoc = await this.db.collection("clinics").doc(clinicId).get();
5985
5991
  if (!clinicDoc.exists) {
5992
+ Logger.error("[BookingAdmin] Clinic not found", { clinicId });
5986
5993
  throw new Error(`Clinic ${clinicId} not found`);
5987
5994
  }
5988
5995
  const clinic = clinicDoc.data();
5996
+ Logger.debug("[BookingAdmin] Retrieved clinic data", {
5997
+ clinicName: clinic.name,
5998
+ clinicHasWorkingHours: !!clinic.workingHours
5999
+ });
6000
+ Logger.debug("[BookingAdmin] Fetching practitioner data", {
6001
+ practitionerId
6002
+ });
5989
6003
  const practitionerDoc = await this.db.collection("practitioners").doc(practitionerId).get();
5990
6004
  if (!practitionerDoc.exists) {
6005
+ Logger.error("[BookingAdmin] Practitioner not found", {
6006
+ practitionerId
6007
+ });
5991
6008
  throw new Error(`Practitioner ${practitionerId} not found`);
5992
6009
  }
5993
6010
  const practitioner = practitionerDoc.data();
6011
+ Logger.debug("[BookingAdmin] Retrieved practitioner data", {
6012
+ practitionerName: `${practitioner.basicInfo.firstName} ${practitioner.basicInfo.lastName}`,
6013
+ pracWorkingHoursCount: ((_a = practitioner.clinicWorkingHours) == null ? void 0 : _a.length) || 0
6014
+ });
6015
+ Logger.debug("[BookingAdmin] Fetching procedure data", { procedureId });
5994
6016
  const procedureDoc = await this.db.collection("procedures").doc(procedureId).get();
5995
6017
  if (!procedureDoc.exists) {
6018
+ Logger.error("[BookingAdmin] Procedure not found", { procedureId });
5996
6019
  throw new Error(`Procedure ${procedureId} not found`);
5997
6020
  }
5998
6021
  const procedure = procedureDoc.data();
6022
+ Logger.debug("[BookingAdmin] Retrieved procedure data", {
6023
+ procedureName: procedure.name,
6024
+ procedureDuration: procedure.duration
6025
+ });
6026
+ Logger.debug("[BookingAdmin] Fetching clinic calendar events", {
6027
+ clinicId,
6028
+ startTime: start.toDate().toISOString(),
6029
+ endTime: end.toDate().toISOString()
6030
+ });
5999
6031
  const clinicCalendarEvents = await this.getClinicCalendarEvents(
6000
6032
  clinicId,
6001
6033
  start,
6002
6034
  end
6003
6035
  );
6036
+ Logger.debug("[BookingAdmin] Retrieved clinic calendar events", {
6037
+ count: clinicCalendarEvents.length
6038
+ });
6039
+ Logger.debug("[BookingAdmin] Fetching practitioner calendar events", {
6040
+ practitionerId,
6041
+ startTime: start.toDate().toISOString(),
6042
+ endTime: end.toDate().toISOString()
6043
+ });
6004
6044
  const practitionerCalendarEvents = await this.getPractitionerCalendarEvents(practitionerId, start, end);
6045
+ Logger.debug("[BookingAdmin] Retrieved practitioner calendar events", {
6046
+ count: practitionerCalendarEvents.length
6047
+ });
6005
6048
  const convertedTimeframe = {
6006
6049
  start: this.adminTimestampToClientTimestamp(start),
6007
6050
  end: this.adminTimestampToClientTimestamp(end)
@@ -6016,14 +6059,38 @@ var BookingAdmin = class {
6016
6059
  practitionerCalendarEvents
6017
6060
  )
6018
6061
  };
6062
+ Logger.info("[BookingAdmin] Calling availability calculator", {
6063
+ calculatorInputReady: true,
6064
+ timeframeDurationHours: Math.round(
6065
+ (end.toMillis() - start.toMillis()) / (1e3 * 60 * 60)
6066
+ ),
6067
+ clinicEventsCount: clinicCalendarEvents.length,
6068
+ practitionerEventsCount: practitionerCalendarEvents.length
6069
+ });
6019
6070
  const result = BookingAvailabilityCalculator.calculateSlots(request);
6020
- return {
6071
+ const availableSlotsResult = {
6021
6072
  availableSlots: result.availableSlots.map((slot) => ({
6022
6073
  start: admin14.firestore.Timestamp.fromMillis(slot.start.toMillis())
6023
6074
  }))
6024
6075
  };
6076
+ Logger.info(
6077
+ "[BookingAdmin] Availability calculation completed successfully",
6078
+ {
6079
+ availableSlotsCount: availableSlotsResult.availableSlots.length,
6080
+ firstSlotTime: availableSlotsResult.availableSlots.length > 0 ? availableSlotsResult.availableSlots[0].start.toDate().toISOString() : "none",
6081
+ lastSlotTime: availableSlotsResult.availableSlots.length > 0 ? availableSlotsResult.availableSlots[availableSlotsResult.availableSlots.length - 1].start.toDate().toISOString() : "none"
6082
+ }
6083
+ );
6084
+ return availableSlotsResult;
6025
6085
  } catch (error) {
6026
- console.error("[BookingAdmin] Error getting available slots:", error);
6086
+ const errorMessage = error instanceof Error ? error.message : String(error);
6087
+ Logger.error("[BookingAdmin] Error getting available slots", {
6088
+ errorMessage,
6089
+ clinicId,
6090
+ practitionerId,
6091
+ procedureId,
6092
+ stack: error instanceof Error ? error.stack : void 0
6093
+ });
6027
6094
  throw error;
6028
6095
  }
6029
6096
  }
@@ -6060,17 +6127,32 @@ var BookingAdmin = class {
6060
6127
  */
6061
6128
  async getClinicCalendarEvents(clinicId, start, end) {
6062
6129
  try {
6130
+ Logger.debug("[BookingAdmin] Querying clinic calendar events", {
6131
+ clinicId,
6132
+ startTime: start.toDate().toISOString(),
6133
+ endTime: end.toDate().toISOString()
6134
+ });
6063
6135
  const eventsRef = this.db.collection(`clinics/${clinicId}/calendar`).where("eventTime.start", ">=", start).where("eventTime.start", "<=", end);
6064
6136
  const snapshot = await eventsRef.get();
6065
- return snapshot.docs.map((doc) => ({
6137
+ const events = snapshot.docs.map((doc) => ({
6066
6138
  ...doc.data(),
6067
6139
  id: doc.id
6068
6140
  }));
6141
+ Logger.debug("[BookingAdmin] Retrieved clinic calendar events", {
6142
+ clinicId,
6143
+ eventsCount: events.length,
6144
+ eventsTypes: this.summarizeEventTypes(events)
6145
+ });
6146
+ return events;
6069
6147
  } catch (error) {
6070
- console.error(
6071
- `[BookingAdmin] Error fetching clinic calendar events:`,
6072
- error
6073
- );
6148
+ const errorMessage = error instanceof Error ? error.message : String(error);
6149
+ Logger.error("[BookingAdmin] Error fetching clinic calendar events", {
6150
+ errorMessage,
6151
+ clinicId,
6152
+ startTime: start.toDate().toISOString(),
6153
+ endTime: end.toDate().toISOString(),
6154
+ stack: error instanceof Error ? error.stack : void 0
6155
+ });
6074
6156
  return [];
6075
6157
  }
6076
6158
  }
@@ -6084,20 +6166,51 @@ var BookingAdmin = class {
6084
6166
  */
6085
6167
  async getPractitionerCalendarEvents(practitionerId, start, end) {
6086
6168
  try {
6169
+ Logger.debug("[BookingAdmin] Querying practitioner calendar events", {
6170
+ practitionerId,
6171
+ startTime: start.toDate().toISOString(),
6172
+ endTime: end.toDate().toISOString()
6173
+ });
6087
6174
  const eventsRef = this.db.collection(`practitioners/${practitionerId}/calendar`).where("eventTime.start", ">=", start).where("eventTime.start", "<=", end);
6088
6175
  const snapshot = await eventsRef.get();
6089
- return snapshot.docs.map((doc) => ({
6176
+ const events = snapshot.docs.map((doc) => ({
6090
6177
  ...doc.data(),
6091
6178
  id: doc.id
6092
6179
  }));
6180
+ Logger.debug("[BookingAdmin] Retrieved practitioner calendar events", {
6181
+ practitionerId,
6182
+ eventsCount: events.length,
6183
+ eventsTypes: this.summarizeEventTypes(events)
6184
+ });
6185
+ return events;
6093
6186
  } catch (error) {
6094
- console.error(
6095
- `[BookingAdmin] Error fetching practitioner calendar events:`,
6096
- error
6187
+ const errorMessage = error instanceof Error ? error.message : String(error);
6188
+ Logger.error(
6189
+ "[BookingAdmin] Error fetching practitioner calendar events",
6190
+ {
6191
+ errorMessage,
6192
+ practitionerId,
6193
+ startTime: start.toDate().toISOString(),
6194
+ endTime: end.toDate().toISOString(),
6195
+ stack: error instanceof Error ? error.stack : void 0
6196
+ }
6097
6197
  );
6098
6198
  return [];
6099
6199
  }
6100
6200
  }
6201
+ /**
6202
+ * Summarizes event types for logging purposes
6203
+ * @param events Array of calendar events
6204
+ * @returns Object with counts of each event type
6205
+ */
6206
+ summarizeEventTypes(events) {
6207
+ const typeCounts = {};
6208
+ events.forEach((event) => {
6209
+ const eventType = event.eventType || "unknown";
6210
+ typeCounts[eventType] = (typeCounts[eventType] || 0) + 1;
6211
+ });
6212
+ return typeCounts;
6213
+ }
6101
6214
  _generateCalendarProcedureInfo(procedure) {
6102
6215
  return {
6103
6216
  name: procedure.name,
@@ -6253,9 +6366,8 @@ var BookingAdmin = class {
6253
6366
  this.db.collection(PRACTITIONERS_COLLECTION).doc(practitionerData.id).collection(CALENDAR_COLLECTION).doc(practitionerCalendarEventId),
6254
6367
  practitionerCalendarEventData
6255
6368
  );
6256
- const patientCalendarEventId = this.db.collection(PATIENTS_COLLECTION).doc(patientProfileData.id).collection(CALENDAR_COLLECTION).doc().id;
6257
6369
  const patientCalendarEventData = {
6258
- id: patientCalendarEventId,
6370
+ id: practitionerCalendarEventId,
6259
6371
  appointmentId: newAppointmentId,
6260
6372
  clinicBranchId: clinicData.id,
6261
6373
  clinicBranchInfo: clinicInfo,
@@ -6274,12 +6386,11 @@ var BookingAdmin = class {
6274
6386
  updatedAt: serverTimestampValue
6275
6387
  };
6276
6388
  batch.set(
6277
- this.db.collection(PATIENTS_COLLECTION).doc(patientProfileData.id).collection(CALENDAR_COLLECTION).doc(patientCalendarEventId),
6389
+ this.db.collection(PATIENTS_COLLECTION).doc(patientProfileData.id).collection(CALENDAR_COLLECTION).doc(practitionerCalendarEventId),
6278
6390
  patientCalendarEventData
6279
6391
  );
6280
- const clinicCalendarEventId = this.db.collection(CLINICS_COLLECTION).doc(clinicData.id).collection(CALENDAR_COLLECTION).doc().id;
6281
6392
  const clinicCalendarEventData = {
6282
- id: clinicCalendarEventId,
6393
+ id: practitionerCalendarEventId,
6283
6394
  appointmentId: newAppointmentId,
6284
6395
  clinicBranchId: clinicData.id,
6285
6396
  clinicBranchInfo: clinicInfo,
@@ -6300,7 +6411,7 @@ var BookingAdmin = class {
6300
6411
  updatedAt: serverTimestampValue
6301
6412
  };
6302
6413
  batch.set(
6303
- this.db.collection(CLINICS_COLLECTION).doc(clinicData.id).collection(CALENDAR_COLLECTION).doc(clinicCalendarEventId),
6414
+ this.db.collection(CLINICS_COLLECTION).doc(clinicData.id).collection(CALENDAR_COLLECTION).doc(practitionerCalendarEventId),
6304
6415
  clinicCalendarEventData
6305
6416
  );
6306
6417
  let initializedFormsInfo = [];
@@ -6388,9 +6499,7 @@ var BookingAdmin = class {
6388
6499
  success: true,
6389
6500
  appointmentId: newAppointmentId,
6390
6501
  appointmentData: newAppointmentData,
6391
- practitionerCalendarEventId,
6392
- patientCalendarEventId,
6393
- clinicCalendarEventId
6502
+ calendarEventId: practitionerCalendarEventId
6394
6503
  };
6395
6504
  } catch (error) {
6396
6505
  console.error(
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@blackcode_sa/metaestetics-api",
3
3
  "private": false,
4
- "version": "1.7.14",
4
+ "version": "1.7.16",
5
5
  "description": "Firebase authentication service with anonymous upgrade support",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.mjs",
@@ -64,6 +64,7 @@ import {
64
64
  import { DocumentManagerAdminService } from "../documentation-templates/document-manager.admin";
65
65
  import { LinkedFormInfo } from "../../types/appointment";
66
66
  import { TimestampUtils } from "../../utils/TimestampUtils";
67
+ import { Logger } from "../logger";
67
68
 
68
69
  /**
69
70
  * Interface for the data required by orchestrateAppointmentCreation
@@ -112,9 +113,19 @@ export class BookingAdmin {
112
113
  }
113
114
  ): Promise<{ availableSlots: { start: admin.firestore.Timestamp }[] }> {
114
115
  try {
115
- console.log(
116
- `[BookingAdmin] Getting available slots for clinic ${clinicId}, practitioner ${practitionerId}, procedure ${procedureId}`
117
- );
116
+ Logger.info("[BookingAdmin] Starting availability calculation", {
117
+ clinicId,
118
+ practitionerId,
119
+ procedureId,
120
+ timeframeStart:
121
+ timeframe.start instanceof Date
122
+ ? timeframe.start.toISOString()
123
+ : timeframe.start.toDate().toISOString(),
124
+ timeframeEnd:
125
+ timeframe.end instanceof Date
126
+ ? timeframe.end.toISOString()
127
+ : timeframe.end.toDate().toISOString(),
128
+ });
118
129
 
119
130
  // Convert timeframe dates to Firestore Timestamps if needed
120
131
  const start =
@@ -128,42 +139,80 @@ export class BookingAdmin {
128
139
  : timeframe.end;
129
140
 
130
141
  // 1. Fetch clinic data
142
+ Logger.debug("[BookingAdmin] Fetching clinic data", { clinicId });
131
143
  const clinicDoc = await this.db.collection("clinics").doc(clinicId).get();
132
144
  if (!clinicDoc.exists) {
145
+ Logger.error("[BookingAdmin] Clinic not found", { clinicId });
133
146
  throw new Error(`Clinic ${clinicId} not found`);
134
147
  }
135
148
  const clinic = clinicDoc.data() as unknown as Clinic;
149
+ Logger.debug("[BookingAdmin] Retrieved clinic data", {
150
+ clinicName: clinic.name,
151
+ clinicHasWorkingHours: !!clinic.workingHours,
152
+ });
136
153
 
137
154
  // 2. Fetch practitioner data
155
+ Logger.debug("[BookingAdmin] Fetching practitioner data", {
156
+ practitionerId,
157
+ });
138
158
  const practitionerDoc = await this.db
139
159
  .collection("practitioners")
140
160
  .doc(practitionerId)
141
161
  .get();
142
162
  if (!practitionerDoc.exists) {
163
+ Logger.error("[BookingAdmin] Practitioner not found", {
164
+ practitionerId,
165
+ });
143
166
  throw new Error(`Practitioner ${practitionerId} not found`);
144
167
  }
145
168
  const practitioner = practitionerDoc.data() as unknown as Practitioner;
169
+ Logger.debug("[BookingAdmin] Retrieved practitioner data", {
170
+ practitionerName: `${practitioner.basicInfo.firstName} ${practitioner.basicInfo.lastName}`,
171
+ pracWorkingHoursCount: practitioner.clinicWorkingHours?.length || 0,
172
+ });
146
173
 
147
174
  // 3. Fetch procedure data
175
+ Logger.debug("[BookingAdmin] Fetching procedure data", { procedureId });
148
176
  const procedureDoc = await this.db
149
177
  .collection("procedures")
150
178
  .doc(procedureId)
151
179
  .get();
152
180
  if (!procedureDoc.exists) {
181
+ Logger.error("[BookingAdmin] Procedure not found", { procedureId });
153
182
  throw new Error(`Procedure ${procedureId} not found`);
154
183
  }
155
184
  const procedure = procedureDoc.data() as unknown as Procedure;
185
+ Logger.debug("[BookingAdmin] Retrieved procedure data", {
186
+ procedureName: procedure.name,
187
+ procedureDuration: procedure.duration,
188
+ });
156
189
 
157
190
  // 4. Fetch clinic calendar events
191
+ Logger.debug("[BookingAdmin] Fetching clinic calendar events", {
192
+ clinicId,
193
+ startTime: start.toDate().toISOString(),
194
+ endTime: end.toDate().toISOString(),
195
+ });
158
196
  const clinicCalendarEvents = await this.getClinicCalendarEvents(
159
197
  clinicId,
160
198
  start,
161
199
  end
162
200
  );
201
+ Logger.debug("[BookingAdmin] Retrieved clinic calendar events", {
202
+ count: clinicCalendarEvents.length,
203
+ });
163
204
 
164
205
  // 5. Fetch practitioner calendar events
206
+ Logger.debug("[BookingAdmin] Fetching practitioner calendar events", {
207
+ practitionerId,
208
+ startTime: start.toDate().toISOString(),
209
+ endTime: end.toDate().toISOString(),
210
+ });
165
211
  const practitionerCalendarEvents =
166
212
  await this.getPractitionerCalendarEvents(practitionerId, start, end);
213
+ Logger.debug("[BookingAdmin] Retrieved practitioner calendar events", {
214
+ count: practitionerCalendarEvents.length,
215
+ });
167
216
 
168
217
  // Since we're working with two different Timestamp implementations (admin vs client),
169
218
  // we need to convert our timestamps to the client-side format expected by the calculator
@@ -186,17 +235,57 @@ export class BookingAdmin {
186
235
  ),
187
236
  };
188
237
 
238
+ Logger.info("[BookingAdmin] Calling availability calculator", {
239
+ calculatorInputReady: true,
240
+ timeframeDurationHours: Math.round(
241
+ (end.toMillis() - start.toMillis()) / (1000 * 60 * 60)
242
+ ),
243
+ clinicEventsCount: clinicCalendarEvents.length,
244
+ practitionerEventsCount: practitionerCalendarEvents.length,
245
+ });
246
+
189
247
  // Use the calculator to compute available slots
190
248
  const result = BookingAvailabilityCalculator.calculateSlots(request);
191
249
 
192
250
  // Convert the client Timestamps to admin Timestamps before returning
193
- return {
251
+ const availableSlotsResult = {
194
252
  availableSlots: result.availableSlots.map((slot) => ({
195
253
  start: admin.firestore.Timestamp.fromMillis(slot.start.toMillis()),
196
254
  })),
197
255
  };
256
+
257
+ Logger.info(
258
+ "[BookingAdmin] Availability calculation completed successfully",
259
+ {
260
+ availableSlotsCount: availableSlotsResult.availableSlots.length,
261
+ firstSlotTime:
262
+ availableSlotsResult.availableSlots.length > 0
263
+ ? availableSlotsResult.availableSlots[0].start
264
+ .toDate()
265
+ .toISOString()
266
+ : "none",
267
+ lastSlotTime:
268
+ availableSlotsResult.availableSlots.length > 0
269
+ ? availableSlotsResult.availableSlots[
270
+ availableSlotsResult.availableSlots.length - 1
271
+ ].start
272
+ .toDate()
273
+ .toISOString()
274
+ : "none",
275
+ }
276
+ );
277
+
278
+ return availableSlotsResult;
198
279
  } catch (error) {
199
- console.error("[BookingAdmin] Error getting available slots:", error);
280
+ const errorMessage =
281
+ error instanceof Error ? error.message : String(error);
282
+ Logger.error("[BookingAdmin] Error getting available slots", {
283
+ errorMessage,
284
+ clinicId,
285
+ practitionerId,
286
+ procedureId,
287
+ stack: error instanceof Error ? error.stack : undefined,
288
+ });
200
289
  throw error;
201
290
  }
202
291
  }
@@ -243,6 +332,12 @@ export class BookingAdmin {
243
332
  end: admin.firestore.Timestamp
244
333
  ): Promise<any[]> {
245
334
  try {
335
+ Logger.debug("[BookingAdmin] Querying clinic calendar events", {
336
+ clinicId,
337
+ startTime: start.toDate().toISOString(),
338
+ endTime: end.toDate().toISOString(),
339
+ });
340
+
246
341
  const eventsRef = this.db
247
342
  .collection(`clinics/${clinicId}/calendar`)
248
343
  .where("eventTime.start", ">=", start)
@@ -250,15 +345,28 @@ export class BookingAdmin {
250
345
 
251
346
  const snapshot = await eventsRef.get();
252
347
 
253
- return snapshot.docs.map((doc) => ({
348
+ const events = snapshot.docs.map((doc) => ({
254
349
  ...doc.data(),
255
350
  id: doc.id,
256
351
  }));
352
+
353
+ Logger.debug("[BookingAdmin] Retrieved clinic calendar events", {
354
+ clinicId,
355
+ eventsCount: events.length,
356
+ eventsTypes: this.summarizeEventTypes(events),
357
+ });
358
+
359
+ return events;
257
360
  } catch (error) {
258
- console.error(
259
- `[BookingAdmin] Error fetching clinic calendar events:`,
260
- error
261
- );
361
+ const errorMessage =
362
+ error instanceof Error ? error.message : String(error);
363
+ Logger.error("[BookingAdmin] Error fetching clinic calendar events", {
364
+ errorMessage,
365
+ clinicId,
366
+ startTime: start.toDate().toISOString(),
367
+ endTime: end.toDate().toISOString(),
368
+ stack: error instanceof Error ? error.stack : undefined,
369
+ });
262
370
  return [];
263
371
  }
264
372
  }
@@ -277,6 +385,12 @@ export class BookingAdmin {
277
385
  end: admin.firestore.Timestamp
278
386
  ): Promise<any[]> {
279
387
  try {
388
+ Logger.debug("[BookingAdmin] Querying practitioner calendar events", {
389
+ practitionerId,
390
+ startTime: start.toDate().toISOString(),
391
+ endTime: end.toDate().toISOString(),
392
+ });
393
+
280
394
  const eventsRef = this.db
281
395
  .collection(`practitioners/${practitionerId}/calendar`)
282
396
  .where("eventTime.start", ">=", start)
@@ -284,19 +398,51 @@ export class BookingAdmin {
284
398
 
285
399
  const snapshot = await eventsRef.get();
286
400
 
287
- return snapshot.docs.map((doc) => ({
401
+ const events = snapshot.docs.map((doc) => ({
288
402
  ...doc.data(),
289
403
  id: doc.id,
290
404
  }));
405
+
406
+ Logger.debug("[BookingAdmin] Retrieved practitioner calendar events", {
407
+ practitionerId,
408
+ eventsCount: events.length,
409
+ eventsTypes: this.summarizeEventTypes(events),
410
+ });
411
+
412
+ return events;
291
413
  } catch (error) {
292
- console.error(
293
- `[BookingAdmin] Error fetching practitioner calendar events:`,
294
- error
414
+ const errorMessage =
415
+ error instanceof Error ? error.message : String(error);
416
+ Logger.error(
417
+ "[BookingAdmin] Error fetching practitioner calendar events",
418
+ {
419
+ errorMessage,
420
+ practitionerId,
421
+ startTime: start.toDate().toISOString(),
422
+ endTime: end.toDate().toISOString(),
423
+ stack: error instanceof Error ? error.stack : undefined,
424
+ }
295
425
  );
296
426
  return [];
297
427
  }
298
428
  }
299
429
 
430
+ /**
431
+ * Summarizes event types for logging purposes
432
+ * @param events Array of calendar events
433
+ * @returns Object with counts of each event type
434
+ */
435
+ private summarizeEventTypes(events: any[]): Record<string, number> {
436
+ const typeCounts: Record<string, number> = {};
437
+
438
+ events.forEach((event) => {
439
+ const eventType = event.eventType || "unknown";
440
+ typeCounts[eventType] = (typeCounts[eventType] || 0) + 1;
441
+ });
442
+
443
+ return typeCounts;
444
+ }
445
+
300
446
  private _generateCalendarProcedureInfo(
301
447
  procedure: Procedure
302
448
  ): CalendarProcedureInfo {
@@ -324,9 +470,7 @@ export class BookingAdmin {
324
470
  success: boolean;
325
471
  appointmentId?: string;
326
472
  appointmentData?: Appointment;
327
- practitionerCalendarEventId?: string;
328
- patientCalendarEventId?: string;
329
- clinicCalendarEventId?: string;
473
+ calendarEventId?: string;
330
474
  error?: string;
331
475
  }> {
332
476
  console.log(
@@ -583,13 +727,9 @@ export class BookingAdmin {
583
727
  );
584
728
 
585
729
  // Patient Calendar Event
586
- const patientCalendarEventId = this.db
587
- .collection(PATIENTS_COLLECTION)
588
- .doc(patientProfileData.id)
589
- .collection(CALENDAR_COLLECTION)
590
- .doc().id;
730
+ // Use same ID as practitionerCalendarEventId
591
731
  const patientCalendarEventData: CalendarEvent = {
592
- id: patientCalendarEventId,
732
+ id: practitionerCalendarEventId,
593
733
  appointmentId: newAppointmentId,
594
734
  clinicBranchId: clinicData.id,
595
735
  clinicBranchInfo: clinicInfo,
@@ -612,18 +752,14 @@ export class BookingAdmin {
612
752
  .collection(PATIENTS_COLLECTION)
613
753
  .doc(patientProfileData.id)
614
754
  .collection(CALENDAR_COLLECTION)
615
- .doc(patientCalendarEventId),
755
+ .doc(practitionerCalendarEventId),
616
756
  patientCalendarEventData
617
757
  );
618
758
 
619
759
  // Clinic Calendar Event
620
- const clinicCalendarEventId = this.db
621
- .collection(CLINICS_COLLECTION)
622
- .doc(clinicData.id)
623
- .collection(CALENDAR_COLLECTION)
624
- .doc().id;
760
+ // Use same ID as practitionerCalendarEventId
625
761
  const clinicCalendarEventData: CalendarEvent = {
626
- id: clinicCalendarEventId,
762
+ id: practitionerCalendarEventId,
627
763
  appointmentId: newAppointmentId,
628
764
  clinicBranchId: clinicData.id,
629
765
  clinicBranchInfo: clinicInfo,
@@ -648,7 +784,7 @@ export class BookingAdmin {
648
784
  .collection(CLINICS_COLLECTION)
649
785
  .doc(clinicData.id)
650
786
  .collection(CALENDAR_COLLECTION)
651
- .doc(clinicCalendarEventId),
787
+ .doc(practitionerCalendarEventId),
652
788
  clinicCalendarEventData
653
789
  );
654
790
 
@@ -755,9 +891,7 @@ export class BookingAdmin {
755
891
  success: true,
756
892
  appointmentId: newAppointmentId,
757
893
  appointmentData: newAppointmentData,
758
- practitionerCalendarEventId,
759
- patientCalendarEventId,
760
- clinicCalendarEventId,
894
+ calendarEventId: practitionerCalendarEventId,
761
895
  };
762
896
  } catch (error) {
763
897
  console.error(