@blackcode_sa/metaestetics-api 1.7.13 → 1.7.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/index.d.mts +12 -6
- package/dist/admin/index.d.ts +12 -6
- package/dist/admin/index.js +127 -14
- package/dist/admin/index.mjs +127 -14
- package/dist/index.d.mts +130 -113
- package/dist/index.d.ts +130 -113
- package/dist/index.js +69 -4
- package/dist/index.mjs +69 -4
- package/package.json +1 -1
- package/src/admin/booking/booking.admin.ts +160 -14
- package/src/services/procedure/procedure.service.ts +94 -2
- package/src/types/procedure/index.ts +4 -3
- package/src/validations/procedure.schema.ts +3 -3
package/dist/admin/index.d.mts
CHANGED
|
@@ -661,6 +661,11 @@ declare enum Currency {
|
|
|
661
661
|
AUD = "AUD"
|
|
662
662
|
}
|
|
663
663
|
|
|
664
|
+
/**
|
|
665
|
+
* Type that allows a field to be either a URL string or a File object
|
|
666
|
+
*/
|
|
667
|
+
type MediaResource = string | File | Blob;
|
|
668
|
+
|
|
664
669
|
/**
|
|
665
670
|
* Procedure represents a specific medical procedure that can be performed by a practitioner in a clinic
|
|
666
671
|
* It inherits properties from technology and adds clinic/practitioner specific details
|
|
@@ -671,7 +676,7 @@ interface Procedure {
|
|
|
671
676
|
/** Name of the procedure */
|
|
672
677
|
name: string;
|
|
673
678
|
/** Photos of the procedure */
|
|
674
|
-
photos?:
|
|
679
|
+
photos?: MediaResource[];
|
|
675
680
|
/** Detailed description of the procedure */
|
|
676
681
|
description: string;
|
|
677
682
|
/** Family of procedures this belongs to (aesthetics/surgery) */
|
|
@@ -1019,11 +1024,6 @@ declare enum ClinicTag {
|
|
|
1019
1024
|
HOLIDAY_HOURS = "holiday_hours"
|
|
1020
1025
|
}
|
|
1021
1026
|
|
|
1022
|
-
/**
|
|
1023
|
-
* Type that allows a field to be either a URL string or a File object
|
|
1024
|
-
*/
|
|
1025
|
-
type MediaResource = string | File | Blob;
|
|
1026
|
-
|
|
1027
1027
|
/**
|
|
1028
1028
|
* Interface for clinic contact information
|
|
1029
1029
|
*/
|
|
@@ -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.
|
package/dist/admin/index.d.ts
CHANGED
|
@@ -661,6 +661,11 @@ declare enum Currency {
|
|
|
661
661
|
AUD = "AUD"
|
|
662
662
|
}
|
|
663
663
|
|
|
664
|
+
/**
|
|
665
|
+
* Type that allows a field to be either a URL string or a File object
|
|
666
|
+
*/
|
|
667
|
+
type MediaResource = string | File | Blob;
|
|
668
|
+
|
|
664
669
|
/**
|
|
665
670
|
* Procedure represents a specific medical procedure that can be performed by a practitioner in a clinic
|
|
666
671
|
* It inherits properties from technology and adds clinic/practitioner specific details
|
|
@@ -671,7 +676,7 @@ interface Procedure {
|
|
|
671
676
|
/** Name of the procedure */
|
|
672
677
|
name: string;
|
|
673
678
|
/** Photos of the procedure */
|
|
674
|
-
photos?:
|
|
679
|
+
photos?: MediaResource[];
|
|
675
680
|
/** Detailed description of the procedure */
|
|
676
681
|
description: string;
|
|
677
682
|
/** Family of procedures this belongs to (aesthetics/surgery) */
|
|
@@ -1019,11 +1024,6 @@ declare enum ClinicTag {
|
|
|
1019
1024
|
HOLIDAY_HOURS = "holiday_hours"
|
|
1020
1025
|
}
|
|
1021
1026
|
|
|
1022
|
-
/**
|
|
1023
|
-
* Type that allows a field to be either a URL string or a File object
|
|
1024
|
-
*/
|
|
1025
|
-
type MediaResource = string | File | Blob;
|
|
1026
|
-
|
|
1027
1027
|
/**
|
|
1028
1028
|
* Interface for clinic contact information
|
|
1029
1029
|
*/
|
|
@@ -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.
|
package/dist/admin/index.js
CHANGED
|
@@ -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
|
-
|
|
6037
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
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
|
-
|
|
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
|
-
|
|
6152
|
-
|
|
6153
|
-
|
|
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,
|
package/dist/admin/index.mjs
CHANGED
|
@@ -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
|
-
|
|
5980
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
6071
|
-
|
|
6072
|
-
|
|
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
|
-
|
|
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
|
-
|
|
6095
|
-
|
|
6096
|
-
|
|
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,
|