first commit

This commit is contained in:
2026-07-16 20:48:43 -03:00
commit 5696cee264
1111 changed files with 322270 additions and 0 deletions
@@ -0,0 +1,133 @@
import mongoose, { Document, FilterQuery, Model, Schema, model } from "mongoose";
import {
CreateSystemNotificationParams,
DeleteSystemNotificationsByConversation,
FindSystemNotificationsParams,
ISystemNotification,
ISystemNotificationsAdapter,
PaginateSystemNotificationsParams,
PaginateSystemNotificationsResults,
UpdateSystemNotificationParams,
} from "./SystemNotification.Interface";
export interface ISystemNotificationDocument extends Omit<ISystemNotification, "id">, Document {}
export class SystemNotificationsAdapterMongoose implements ISystemNotificationsAdapter {
schema: Schema;
notificationsList: Model<ISystemNotificationDocument>;
constructor() {
this.schema = new Schema({
userId: { type: Schema.Types.ObjectId, required: false, ref: "User" },
companyId: { type: Schema.Types.ObjectId, required: false, ref: "Companie" },
serviceId: { type: Schema.Types.ObjectId, required: false, ref: "Service" },
conversationId: {
type: Schema.Types.ObjectId,
required: false,
ref: "MessagesConversation",
},
subject: { type: String, required: true },
message: { type: String, required: true },
notificationDate: { type: Date, required: true },
readed: { type: Boolean, default: false },
});
this.notificationsList = model<ISystemNotificationDocument>("SystemNotification", this.schema);
}
public async create(data: CreateSystemNotificationParams): Promise<ISystemNotification> {
return await this.notificationsList.create(data);
}
public async update(data: UpdateSystemNotificationParams): Promise<void> {
const updateNotification = await this.notificationsList.findOne({ _id: data.id });
if (!updateNotification) {
throw new Error("Notificación invalida");
}
updateNotification.readed = data.readed;
await updateNotification.save();
}
public async delete(id: string): Promise<void> {
await this.notificationsList.findByIdAndDelete(id).exec();
}
public async deleteMany(
data: Omit<DeleteSystemNotificationsByConversation, "sessionUser">
): Promise<void> {
await this.notificationsList.deleteMany(data).exec();
}
public async deleteByQuery(data: FilterQuery<ISystemNotification>): Promise<void> {
await this.notificationsList.deleteMany(data).exec();
}
public async find(
filters: Omit<FindSystemNotificationsParams, "sessionUser">
): Promise<ISystemNotification[]> {
return this.notificationsList.find(filters).exec();
}
public async findOne(
filters: FindSystemNotificationsParams
): Promise<ISystemNotificationDocument | null> {
return this.notificationsList.findOne(filters).exec();
}
// Método para búsqueda con expresiones regulares y paginación
public async paginate(
data: PaginateSystemNotificationsParams
): Promise<PaginateSystemNotificationsResults> {
const skip = (data.page - 1) * data.limit;
// Construye los criterios de búsqueda
const searchCriteria: mongoose.FilterQuery<ISystemNotification> = {};
// Agrega filtro por query usando expresiones regulares para 'name' y 'description'
if (data.query) {
const regex = new RegExp(data.query, "i");
searchCriteria.$or = [{ subject: regex }, { message: regex }];
}
// Filtra por categoryId si está presente
if (data.userId !== undefined) {
searchCriteria.userId = data.userId;
}
if (data.companyId !== undefined) {
searchCriteria.companyId = data.companyId;
}
if (data.conversationId !== undefined) {
searchCriteria.conversationId = data.conversationId;
}
if (data.serviceId !== undefined) {
searchCriteria._id = data.serviceId;
}
if (data.readed) {
searchCriteria.readed = data.readed;
}
// Realiza la consulta con paginación
const results = await this.notificationsList
.find(searchCriteria)
.sort({ notificationDate: -1 })
.skip(skip)
.limit(data.limit)
.exec();
// Cuenta el total de documentos que coinciden con los criterios de búsqueda
const count = await this.notificationsList.countDocuments(searchCriteria).exec();
return {
data: results,
page: data.page,
pages: Math.ceil(count / data.limit),
};
}
}
@@ -0,0 +1,132 @@
import { FilterQuery } from "mongoose";
export type FindSystemNotificationsParams = {
id?: string;
userId?: string;
companyId?: string;
serviceId?: string;
conversationId?: string;
notificationDate?: Date;
readed?: boolean;
sessionUser: string;
};
export type ToggleStateSystemNotificationsParams = {
state: boolean;
sessionUser: string;
};
export type PaginateSystemNotificationsParams = {
query?: string;
userId?: string;
companyId?: string;
serviceId?: string;
conversationId?: string;
dateFrom?: Date;
dateTo?: Date;
readed?: boolean;
page: number;
limit: number;
sessionUser: string;
};
export type UnreadNotificationResults = {
count: number;
};
export type PaginateSystemNotificationsResults = {
data: ISystemNotification[];
page: number;
pages: number;
};
export enum NotificationType {
APPOINTMENT = 'APPOINTMENT',
COMPANY = 'COMPANY',
EMPLOYEE = 'EMPLOYEE',
SCHEDULE = 'SCHEDULE',
SCHEDULE_EXCEPTION = 'SCHEDULE_EXCEPTION',
SCHEDULE_RESTRICTION = 'SCHEDULE_RESTRICTION',
MESSAGE = 'MESSAGE',
BILLING = 'BILLING',
SYSTEM = 'SYSTEM'
}
export type CreateSystemNotificationParams = {
userId?: string;
companyId?: string;
serviceId?: number;
conversationId?: string;
subject: string;
message: string;
type?: string;
code?: string;
};
export type UpdateSystemNotificationParams = {
id: string;
readed: boolean;
sessionUser: string;
};
export type DeleteSystemNotificationParams = {
id: string;
sessionUser: string;
};
export type DeleteSystemNotificationsByConversation = {
conversationId: string;
userId: string;
sessionUser: string;
};
export type DeleteNotificationsByUserParams = {
userId: string;
};
export type DeleteNotificationsByDateParams = {
userId: string;
dateFrom?: Date;
dateTo?: Date;
sessionUser: string;
};
export interface ISystemNotification {
id?: string;
userId?: string;
companyId?: string;
serviceId?: string;
conversationId?: string;
subject: string;
message: string;
notificationDate: Date;
readed: boolean;
type?: string;
code?: string;
}
export interface ISystemNotificationsAdapter {
create(data: CreateSystemNotificationParams): Promise<ISystemNotification>;
update(data: UpdateSystemNotificationParams): Promise<void>;
delete(id: string): Promise<void>;
deleteMany(data: Omit<DeleteSystemNotificationsByConversation, "sessionUser">): Promise<void>;
find(filters: FindSystemNotificationsParams): Promise<ISystemNotification[]>;
findOne(filters: FindSystemNotificationsParams): Promise<ISystemNotification | null>;
paginate(filters: PaginateSystemNotificationsParams): Promise<PaginateSystemNotificationsResults>;
deleteByQuery(data: FilterQuery<ISystemNotification>): Promise<void>;
}
export interface ISystemNotificationsManager {
notifications: ISystemNotificationsAdapter;
createNotification(data: CreateSystemNotificationParams): Promise<ISystemNotification>;
updateNotification(data: UpdateSystemNotificationParams): Promise<void>;
deleteNotification(data: DeleteSystemNotificationParams): Promise<void>;
deleteConversationNotifications(data: DeleteSystemNotificationsByConversation): Promise<void>;
paginateNotifications(
data: PaginateSystemNotificationsParams
): Promise<PaginateSystemNotificationsResults>;
finUnreadNotifications(data: FindSystemNotificationsParams): Promise<UnreadNotificationResults>;
deleteNotificationsByUser(data: DeleteNotificationsByUserParams): Promise<void>;
setStateByUser(data: ToggleStateSystemNotificationsParams): Promise<void>;
deleteNotificationsByDate(data: DeleteNotificationsByDateParams): Promise<void>;
}
@@ -0,0 +1,227 @@
import CompaniesManager from "../Companies/Companies";
import {
CreateSystemNotificationParams,
DeleteNotificationsByDateParams,
DeleteNotificationsByUserParams,
DeleteSystemNotificationParams,
DeleteSystemNotificationsByConversation,
FindSystemNotificationsParams,
ISystemNotification,
ISystemNotificationsManager,
PaginateSystemNotificationsParams,
PaginateSystemNotificationsResults,
ToggleStateSystemNotificationsParams,
UnreadNotificationResults,
UpdateSystemNotificationParams,
} from "./SystemNotification.Interface";
import { SystemNotificationsAdapterMongoose } from "./SystemNotification.Adapter.Mongoose";
import { io } from "../../index";
import MessageConversationList from "../MessageConversations/MessagesConversations";
import { FilterQuery } from "mongoose";
import { validateSessionUser } from "../../helpers/check";
class SystemNotificationsManager implements ISystemNotificationsManager {
notifications: SystemNotificationsAdapterMongoose;
constructor() {
this.notifications = new SystemNotificationsAdapterMongoose();
}
public async setStateByUser(data: ToggleStateSystemNotificationsParams): Promise<void> {
await validateSessionUser({
sessionUser: data.sessionUser,
});
await this.notifications.notificationsList.updateMany(
{ userId: data.sessionUser },
{ $set: { readed: data.state } }
);
const countUnreadNotifications = await this.finUnreadNotifications({
userId: data.sessionUser,
sessionUser: data.sessionUser,
});
io.to(`user:${data.sessionUser}`).emit("new_system_notification", countUnreadNotifications);
}
public async deleteNotificationsByUser(data: DeleteNotificationsByUserParams): Promise<void> {
await this.notifications.notificationsList.deleteMany({ userId: data.userId });
}
public async deleteNotificationsByDate(data: DeleteNotificationsByDateParams): Promise<void> {
await validateSessionUser({
sessionUser: data.sessionUser,
});
if (data.sessionUser !== data.userId) {
throw new Error("No tienes permiso para eliminar estas notificaciones");
}
const deleteFilter: FilterQuery<ISystemNotification> = { userId: data.userId };
if (data.dateFrom || data.dateTo) {
deleteFilter.notificationDate = {};
}
if (data.dateFrom) {
deleteFilter.notificationDate.$gte = data.dateFrom;
}
if (data.dateTo) {
deleteFilter.notificationDate.$lte = data.dateTo;
}
await this.notifications.deleteByQuery(deleteFilter);
const countUnreadNotifications = await this.finUnreadNotifications({
userId: data.sessionUser,
sessionUser: data.sessionUser,
});
io.to(`user:${data.sessionUser}`).emit("new_system_notification", countUnreadNotifications);
}
public async createNotification(data: CreateSystemNotificationParams): Promise<ISystemNotification> {
if (data.userId) {
await validateSessionUser({
sessionUser: data.userId,
});
}
if (data.companyId) {
const companyCheck = await CompaniesManager.companies.findOne({ _id: data.companyId });
if (!companyCheck) {
throw new Error("La compañia no existe");
}
}
const newNotification = await this.notifications.create({
...data,
...{
notificationDate: new Date(),
readed: false,
},
});
return newNotification;
}
public async updateNotification(data: UpdateSystemNotificationParams): Promise<void> {
await validateSessionUser({
sessionUser: data.sessionUser,
});
const checkNotification = await this.notifications.notificationsList.findOne({
_id: data.id,
});
if (!checkNotification) {
throw new Error("Notificación invalida");
}
if (String(checkNotification.userId) !== data.sessionUser) {
throw new Error("No tienes permiso para modificar esta notificación");
}
await this.notifications.update(data);
const countUnreadNotifications = await this.finUnreadNotifications({
userId: data.sessionUser,
sessionUser: data.sessionUser,
});
io.to(`user:${data.sessionUser}`).emit("new_system_notification", countUnreadNotifications);
}
public async deleteNotification(data: DeleteSystemNotificationParams): Promise<void> {
await validateSessionUser({
sessionUser: data.sessionUser,
});
const checkNotification = await this.notifications.notificationsList.findOne({
_id: data.id,
});
if (!checkNotification) {
throw new Error("Notificación invalida");
}
if (String(checkNotification.userId) !== data.sessionUser) {
throw new Error("No tienes permiso para eliminar esta notificación");
}
await this.notifications.delete(data.id);
const countUnreadNotifications = await this.finUnreadNotifications({
userId: data.sessionUser,
sessionUser: data.sessionUser,
});
io.to(`user:${data.sessionUser}`).emit("new_system_notification", countUnreadNotifications);
}
public async deleteConversationNotifications(
data: DeleteSystemNotificationsByConversation
): Promise<void> {
await validateSessionUser({
sessionUser: data.sessionUser,
});
if (!data.conversationId) {
throw new Error("No se ha seleccionado una conversación");
}
const conversation = await MessageConversationList.conversations.findOne({
_id: data.conversationId,
});
if (!conversation) {
throw new Error("Conversación invalida");
}
await this.notifications.deleteMany({
conversationId: data.conversationId,
userId: data.sessionUser,
});
const countUnreadNotifications = await this.finUnreadNotifications({
userId: data.sessionUser,
sessionUser: data.sessionUser,
});
io.to(`user:${data.sessionUser}`).emit("new_system_notification", countUnreadNotifications);
}
public async paginateNotifications(
filters: PaginateSystemNotificationsParams
): Promise<PaginateSystemNotificationsResults> {
return await this.notifications.paginate(filters);
}
public async finUnreadNotifications(
data: FindSystemNotificationsParams
): Promise<UnreadNotificationResults> {
await validateSessionUser({
sessionUser: data.sessionUser,
});
const unread = await this.notifications.find({
userId: data.userId,
readed: false,
});
if (!unread) {
return { count: 0 };
}
return {
count: unread.length,
};
}
}
const SystemNoficationsList = new SystemNotificationsManager();
export default SystemNoficationsList;