feat: implement collaborator reactivation logic, add access denied handling, and improve metric filtering

This commit is contained in:
2026-07-19 18:56:39 -03:00
parent af6c87acb6
commit 74d6ee6706
27 changed files with 3148 additions and 37 deletions
+16 -13
View File
@@ -1052,6 +1052,9 @@ class AppointmentManager implements IAppointmentsManager {
continue;
}
// Historical read: Employee lookup includes removed employees (historical reads allow them)
// No snapshot fallback needed here as employee.calendarColor is used directly
const clientName = joinStrings([client.firstName, client.lastName], " ");
const clientUserName = userClient
? joinStrings([userClient.firstName, userClient.lastName], clientName)
@@ -1251,9 +1254,17 @@ class AppointmentManager implements IAppointmentsManager {
_id: String(employee.userId),
});
if (!userEmployee) {
throw new Error("No se ha encontrado el usuario del colaborador");
}
// Historical read snapshot fallback: use Employee snapshot if User is deleted
const collaboratorFirstName = userEmployee
? isNull<string>(userEmployee.firstName, "")
: isNull<string>(employee.profileSnapshot?.firstName, "");
const collaboratorLastName = userEmployee
? isNull<string>(userEmployee.lastName, "")
: isNull<string>(employee.profileSnapshot?.lastName, "");
const collaboratorFullName = joinStrings([collaboratorFirstName, collaboratorLastName], " ");
const collaboratorAvatar = userEmployee
? getAvatar(employee.userId, userEmployee.avatar, collaboratorFullName)
: (employee.profileSnapshot?.avatar || collaboratorFullName);
const service = await ServiceList.services.findOne({
_id: String(appointment.serviceId),
@@ -1271,14 +1282,6 @@ class AppointmentManager implements IAppointmentsManager {
? getAvatar(client.userId, userClient.avatar, clientUserName)
: clientUserName;
const employeeFirstName = isNull<string>(userEmployee.firstName, "");
const employeeLastName = isNull<string>(userEmployee.lastName, "");
const employeeFullName = joinStrings([employeeFirstName, employeeLastName], " ");
const employeeAvatar = userEmployee
? getAvatar(employee.userId, userEmployee.avatar, employeeFullName)
: clientUserName;
const discountData = await Discounts.getDiscountData(appointment.discountId, appointment.companyId);
let ctaBalance = 0;
@@ -1300,8 +1303,8 @@ class AppointmentManager implements IAppointmentsManager {
serviceName: service.name,
serviceDescription: service.description,
collaboratorId: employee.id,
collaboratorName: employeeFullName,
collaboratorAvatar: employeeAvatar,
collaboratorName: collaboratorFullName,
collaboratorAvatar: collaboratorAvatar,
appointmentDate: dayjs(appointment.start).toISOString(),
startTime: appointment.startHour,
endTime: appointment.endHour,