Repositorio de NotificationOutbox
Overview
El archivo services/api/src/modules/notifications/notification.repository.js centraliza la persistencia del outbox de notificaciones. Expone helpers asíncronos para crear registros y cambiar su estado dentro de NotificationOutbox .
Este módulo no envía correos ni coordina proveedores. La propia fuente aclara que la entrega vive en notification.service.js, y que este repositorio no conoce proveedores, reintentos ni workers .
[!NOTE] El repositorio es una capa de escritura pura. Solo opera sobre
NotificationOutboxy devuelve el resultado crudo decreateoupdateOne.
How it works
El flujo es corto y determinista:
createOutboxEntry(...)inserta un documento nuevo enNotificationOutboxcon los datos del evento.markOutboxEntrySending(outboxEntryId)marca el documento comosendingy suma un intento.markOutboxEntrySent(outboxEntryId, providerMessageId)lo marca comosenty guarda la marca temporal del envío.markOutboxEntryFailed(outboxEntryId, errorCode)lo marca comofailedy guarda el código de error.
Estas funciones trabajan por _id, sin cargar el documento antes de actualizarlo. Tampoco interpretan la respuesta de updateOne; solo la reenvían al llamador .
Key components
{
"title": "createOutboxEntry",
"content": "Persiste un nuevo documento en NotificationOutbox con eventType, recipientUserId, recipientChannel y payload.",
"type": "function",
"filePath": "services/api/src/modules/notifications/notification.repository.js",
"badges": [
"public"
]
}
{
"title": "markOutboxEntrySending",
"content": "Actualiza un outbox entry por _id, lo pasa a sending, limpia lastError y aumenta attempts.",
"type": "function",
"filePath": "services/api/src/modules/notifications/notification.repository.js",
"badges": [
"public"
]
}
{
"title": "markOutboxEntrySent",
"content": "Actualiza un outbox entry por _id, lo pasa a sent, guarda sentAt, limpia lastError y opcionalmente persiste providerMessageId.",
"type": "function",
"filePath": "services/api/src/modules/notifications/notification.repository.js",
"badges": [
"public"
]
}
{
"title": "markOutboxEntryFailed",
"content": "Actualiza un outbox entry por _id, lo pasa a failed y almacena el errorCode en lastError.",
"type": "function",
"filePath": "services/api/src/modules/notifications/notification.repository.js",
"badges": [
"public"
]
}
Data & fields
El archivo no define el esquema, pero sí usa estos campos en NotificationOutbox. El comportamiento observado en la fuente depende de ellos.
[
{
"name": "eventType",
"type": "string",
"required": true,
"description": "Tipo de evento que se persiste en el outbox."
},
{
"name": "recipientUserId",
"type": "string | null",
"description": "Identificador del usuario destinatario. En createOutboxEntry tiene valor por defecto null."
},
{
"name": "recipientChannel",
"type": "string",
"required": true,
"description": "Canal de destino guardado en el registro del outbox."
},
{
"name": "payload",
"type": "object",
"description": "Carga útil asociada al evento. En createOutboxEntry tiene valor por defecto {}."
}
]
[
{
"name": "status",
"type": "string",
"required": true,
"description": "Se fija en sending, sent o failed según la operación."
},
{
"name": "attempts",
"type": "number",
"description": "Se incrementa en markOutboxEntrySending."
},
{
"name": "lastError",
"type": "string",
"description": "Se limpia al marcar sending o sent, y se llena con errorCode al fallar."
},
{
"name": "sentAt",
"type": "Date",
"description": "Se establece en markOutboxEntrySent con la fecha actual."
},
{
"name": "providerMessageId",
"type": "string | null",
"description": "Se guarda solo en markOutboxEntrySent. La fuente indica que es un dato interno."
}
]
[!IMPORTANT] La fuente comenta que
providerMessageIdes opcional y debe venir solo del caller interno. No debe originarse en input externo .
Behaviors
createOutboxEntry[badge:public] crea un documento nuevo enNotificationOutboxy devuelve el resultado deNotificationOutbox.create(...).markOutboxEntrySending[badge:public] actualiza un documento por_id, fijastatus: 'sending', limpialastErrory sumaattemptscon$inc.markOutboxEntrySent[badge:public] actualiza un documento por_id, fijastatus: 'sent', escribesentAt, limpialastErrory guardaproviderMessageIdsi existe .markOutboxEntryFailed[badge:public] actualiza un documento por_id, fijastatus: 'failed'y escribelastErrorcon el código recibido .
Workflows
notification.events.jsusacreateOutboxEntrypara registrar eventos de dominio en el outbox antes de intentar su entrega síncrona .notification.service.jsusamarkOutboxEntrySending,markOutboxEntrySentymarkOutboxEntryFaileddurantedeliverOutboxEntry.notification.service.jstambién resuelve el destinatario y envía el mensaje, mientras este repositorio solo persiste estado .
Gotchas & edge cases
[!WARNING] Este módulo no valida la existencia del documento ni transforma el resultado de
updateOne. Si_idno coincide, la llamada sigue devolviendo el resultado crudo de la operación de base de datos .
[!WARNING] El repositorio no maneja entrega, reintentos ni workers. Esa responsabilidad pertenece a
notification.service.js, según el comentario de la fuente .
[!NOTE] El modelo relacionado
NotificationOutboxtiene un TTL de 90 días sobrecreatedAt, yproviderMessageIdexiste con defaultnull, según sus pruebas de esquema .
Related
services/api/src/modules/notifications/notification.service.jscoordina la entrega real y usa este repositorio para cambiar estados del outbox .services/api/src/modules/notifications/notification.events.jsregistra eventos de dominio y crea entradas de outbox antes de la entrega .services/api/src/models/NotificationOutbox.jses el modelo persistente sobre el que opera este archivo; sus pruebas confirman el TTL y el campoproviderMessageId.