Saltar a contenido

Autor: Yadilton Torres

Fecha creacion: 2026-10-21 Estado: desarrollo Tipo: servicio

Servicio: NotificacionesService

Ubicación: src/app/core/application/services/notificaciones/ Scope: providedIn: 'root'


¿Qué hace?

Maneja las notificaciones de la plataforma que se ven en la campana del header: las consulta cada cierto tiempo, las envía, cambia su estado (NUEVA → LEIDA → HECHA), le envía la respuesta a quien la creó y trae el historial.

Lo usan:

  • Exportación de datos: cuando el usuario necesita exportar más del límite, le escribe al equipo de desarrollo y el mensaje le llega a su campana. Cuando el equipo responde, la respuesta le llega a la campana de quien lo envió.
  • Accesos en LOGI: cuando una persona completa el formulario por primera vez, les llega a Comercial y COO; la respuesta le llega a la persona.

Archivos

Archivo Responsabilidad
notificacion.models.ts Tipos, estados, interfaz Notificacion y configuración por tipo (TIPOS_NOTIFICACION)
notificaciones.repository.ts Llamadas HTTP a la colección NotificacionesPlataforma (consultar, insertar, cambiar estado). No toca la vista
notificaciones.service.ts Estado con signals, revisión periódica, enviar, marcar leída, marcar hecha, responder e historial
aviso-notificacion.service.ts Aviso arriba a la derecha al enviar, responder o fallar una notificación

Colección NotificacionesPlataforma

La colección Notificaciones ya existe y es de la red social (Muro compartido). Por eso esta tiene nombre propio.

Campo Tipo Descripción
Tipo string SOLICITUD_EXPORTACION, SOLICITUD_RESUELTA, NUEVO_REGISTRO_ACCESOS o REGISTRO_RESPONDIDO
Mensaje string Texto que escribió el usuario (en una respuesta, la respuesta)
Contexto object Datos de la pantalla desde donde se envió, se llenan solos. En Exportación: Coleccion, Formato, Rango, Registros, Columnas, Limite. En Accesos en LOGI: Tienda, Nombre, Correo, Telefono, Ciudad, Tipo de negocio, Paquetes al mes
CreadoPor string Correo de quien la envió (sessionStorage['emailaddress'])
Roles string[] Roles que la ven; vacío si va a personas
Usuarios string[] Correos que la ven; vacío si va a roles
Estado string NUEVA al enviarse, LEIDA cuando alguien la abre, HECHA cuando la responden o la marcan como vista
FechaCreacion string Fecha ISO
IdOrigen string En una respuesta, el _id de la notificación que se responde
RespondidaPor string Correo de quien respondió
Respuesta string Mensaje de respuesta para quien la envió
FechaRealizada string Cuándo se atendió (fecha ISO)

El estado es común para todos los que la reciben: si un desarrollador la abre, queda LEIDA para todos.

Índices sugeridos (los crea el backend): { Roles: 1, Estado: 1, FechaCreacion: -1 } y { Usuarios: 1, Estado: 1, FechaCreacion: -1 }.


Tipos de notificación

Se configuran en TIPOS_NOTIFICACION. Para que un tipo le llegue a otros roles se cambia ahí.

Tipo Etiqueta Icono / tono Le llega a Acción Al atenderla
SOLICITUD_EXPORTACION Solicitud de exportación cilCloudDownload / naranja Rol Desarrollador responder (respuesta obligatoria) Queda HECHA y se crea una SOLICITUD_RESUELTA para quien la envió
SOLICITUD_RESUELTA Tu solicitud fue atendida cilTask / verde El correo de quien hizo la solicitud entendido Solo pasa al historial
NUEVO_REGISTRO_ACCESOS Nuevo registro en Accesos cilUser / naranja Roles Comercial y COO responder (respuesta obligatoria) Queda HECHA y se crea un REGISTRO_RESPONDIDO para la persona
REGISTRO_RESPONDIDO El equipo LOGI te respondió cilTask / verde El correo de la persona que llenó el formulario entendido Solo pasa al historial

La primera persona de Comercial o COO que responde un NUEVO_REGISTRO_ACCESOS lo cierra para todos.

Un tipo desconocido se muestra como "Notificación" que solo se puede quitar.


Signals expuestos

Signal Tipo Descripción
notificaciones Notificacion[] Pendientes (NUEVA y LEIDA): primero las nuevas, cada grupo de la más nueva a la más vieja
historial Notificacion[] Últimas HECHA (máximo LIMITE_HISTORIAL = 20); se consultan solo al abrir el historial
nuevas computed<number> Cuántas están en NUEVA (contador de la campana)
cargando / cargandoHistorial boolean Hay una consulta en curso
ultimaRevision Date \| null Cuándo se consultó por última vez
puedeRecibir boolean El usuario tiene correo o algún rol que recibe notificaciones

Métodos

Método Qué hace
iniciar() Empieza a revisar. Espera los roles del usuario (hasta 1 minuto, cada 3 s), consulta ya y luego cada 2 min si tiene un rol que recibe solicitudes o cada 5 min si no. Solo revisa con la pestaña visible y vuelve a consultar al regresar a la pestaña. Se puede llamar varias veces: solo arranca una
detener() Deja de revisar (al salir del layout)
revisar() Consulta las pendientes de los roles y del correo del usuario
revisarHistorial() Consulta las últimas 20 HECHA
enviar(tipo, mensaje, contexto) Crea una notificación NUEVA para los roles configurados del tipo
marcarLeida(notificacion) NUEVA → LEIDA. Se ve de inmediato; si falla vuelve a como estaba
marcarHecha(notificacion, respuesta) Pasa a HECHA (al historial). Ver flujo abajo

Flujo al marcar como hecha

marcarHecha(notificacion, respuesta)
  -> si el tipo es "responder" y no hay respuesta → Error('La respuesta es obligatoria')
  -> la quita de pendientes
  -> repositorio.cambiarEstado(HECHA, { RespondidaPor, Respuesta, FechaRealizada })
       // con "entendido" solo se guarda FechaRealizada (nadie respondió)
       // si falla → vuelve a pendientes y lanza el error
  -> la pone de primera en el historial
  -> si el tipo tiene tipoRespuesta:
       repositorio.insertar({ Tipo: tipoRespuesta, Usuarios: [CreadoPor], IdOrigen, Mensaje: respuesta, ... })
       // SOLICITUD_EXPORTACION → SOLICITUD_RESUELTA; NUEVO_REGISTRO_ACCESOS → REGISTRO_RESPONDIDO
       // si solo falla esto → queda HECHA y lanza RespuestaNoEnviadaError(destinatario)

Repositorio: NotificacionesRepository

Método Endpoint Descripción
consultar(roles, correo, estados, limite?) GET /metodoGenerico?coleccion=NotificacionesPlataforma&Roles=...&Estado=...&mcomp=2&lote=30 y ...&Usuarios=<correo>&lote=10 El método genérico no hace "o" entre campos: hace una consulta por Roles y otra por Usuarios en paralelo, las junta sin repetidas y las ordena de la más nueva a la más vieja. Con limite (historial) cada consulta pide solo esa cantidad
insertar(notificacion) insertarGenerico en metodoGenerico?coleccion=NotificacionesPlataforma Guarda una notificación nueva
cambiarEstado(notificacion, estado, extra) actualizarGenericoSinAuditoria (LEIDA) o actualizarGenerico (HECHA) Envía el registro completo con el nuevo estado. LEIDA va sin auditoría porque no es una acción de negocio; HECHA sí queda en LogAuditoria

Las respuestas llegan comprimidas en Zstd. El _id puede llegar como texto o como { $oid } y se deja siempre como texto.

Interruptor de escritura

NotificacionesRepository.ESCRITURA_ACTIVA (hoy true). En false, insertar y cambiarEstado lanzan EscrituraDesactivadaError sin llamar al backend; Exportación muestra "Envío en preparación" y la campana "Por ahora los cambios no se guardan".


Errores

Error Cuándo
EscrituraDesactivadaError Se intenta guardar con ESCRITURA_ACTIVA = false
RespuestaNoEnviadaError La notificación quedó HECHA pero no se pudo crear la respuesta para quien la envió. Trae destinatario

AvisoNotificacionService

mostrar(tipo, titulo, texto?) muestra un aviso arriba a la derecha (SweetAlert en modo toast): tarjeta blanca, icono en círculo de color, título, texto, X para cerrar y barra de tiempo. Dura 4,5 s y se pausa con el mouse encima. En celular ocupa todo el ancho.

Tipo Color Uso
exito Verde Mensaje enviado, respuesta enviada
error Rojo No se pudo enviar o guardar
info Azul Espera entre mensajes, escritura apagada
advertencia Naranja Quedó hecha pero no se pudo avisar a quien la envió

Los estilos son globales en src/scss/_aviso-notificacion.scss (importado en styles.scss) porque SweetAlert pinta fuera de los componentes. Escapa el título y el texto antes de ponerlos en el HTML. El AvisoToastService de Pauta no se cambió.


Pruebas

Archivo Pruebas
notificaciones.service.spec.ts 17
notificaciones.repository.spec.ts 8
aviso-notificacion.service.spec.ts 3

Historial de cambios

Fecha Autor Cambio
2026-10-21 Yadilton Torres Creación del servicio, repositorio y modelos de notificaciones (colección NotificacionesPlataforma)
2026-10-21 Yadilton Torres Respuestas: SOLICITUD_RESUELTA le llega a quien envió la solicitud; campos Usuarios, IdOrigen, RespondidaPor, Respuesta y FechaRealizada
2026-10-21 Yadilton Torres Historial con las últimas 20 HECHA y AvisoNotificacionService
2026-11-11 Yadilton Torres Tipos NUEVO_REGISTRO_ACCESOS (a Comercial y COO) y REGISTRO_RESPONDIDO para el formulario Accesos en LOGI

Observaciones

  • La colección la debe crear el backend con los índices sugeridos, y el filtro por rol debe hacerse en el servidor: hoy el frontend pide por Roles y Usuarios, pero cualquiera podría pedir otras desde el navegador.
  • Localhost apunta a producción: enviar desde localhost crea registros reales.
  • El historial es por fecha de creación: "últimas 20" se cuenta por _id, no por FechaRealizada.
  • Los roles se comparan escritos como en la configuración (ej. Desarrollador, Comercial, COO), porque la base compara mayúsculas exactas.