Saltearse al contenido

Microservicio de notificaciones

Arquitectura del microservicio de notificaciones

1. Descripción general del servicio

El microservicio de notificaciones es un servicio enfocado responsable de gestionar notificaciones por email y alertas en toda la plataforma Algesta.

Service Details:

  • Repositorio: algesta-ms-notifications-nestjs
  • Port: 3000 (configurable via PORT environment variable)
  • Database: MongoDB (notifications Base de datos)
  • Estado: ✅ Activo

Key Responsibilities:

  • Email notification management via SendGrid
  • Notification tracking and Estado management
  • Scheduled notification jobs (Documento expiration reminders)
  • Order-related notifications (reminders, quotes, approvals)
  • Template-based email generation with Handlebars

Reference Files:

  • Module configuration: algesta-ms-notifications-nestjs/src/app.module.ts
  • Domain model: algesta-ms-notifications-nestjs/src/domain/entities/notification.entity.ts
  • Controller: algesta-ms-notifications-nestjs/src/infrastructure/controllers/notification.controller.ts
  • Documentoation: algesta-ms-notifications-nestjs/README.md

2. Module Structure

The Notifications Microservicio follows NestJS modular Arquitectura with Clean Architecture principles.

Core Business Modules

ModuleLocationPurposeKey Componentes
NotificationModulesrc/infrastructure/modules/notification.module.tsNotification managementNotificationController, Notification handlers, Notification Repositorio

Shared Infrastructure Modules

ModulePurpose
Base de datosModuleMongoDB connection and configuration
RedisConfigModuleRedis/Kafka messaging configuration
HealthModuleHealth check Endpoints
WinstonModuleStructured logging
ScheduleModuleCron job scheduling via @nestjs/schedule

Note: CQRS is wired within the NotificationModule feature module, not at the root AppModule level. The NotificationModule imports CqrsModule internally to provide command/query bus functionality for notification Operaciones.

Reference: algesta-ms-notifications-nestjs/src/app.module.ts

3. CQRS Implementación

The Notifications Microservicio implements CQRS pattern using @nestjs/cqrs for separation of write and read Operaciones.

Commands (Write Operaciones)

Commands represent state-changing Operaciones on notifications.

CommandHandlerPurposeFile Path
CreateNotificationCommandCreateNotificationHandlerCreate notification recordsrc/application/commands/create-notification.command.ts
UpdateNotificationCommandUpdateNotificationHandlerUpdate notification Estadosrc/application/commands/update-notification.command.ts
DeleteNotificationCommandDeleteNotificationHandlerDelete notificationsrc/application/commands/delete-notification.command.ts
SendOrderReminderCommandSendOrderReminderHandlerSend order reminder emailsrc/application/commands/send-order-reminder.command.ts
SendQuotationApprovedNotificationCommandSendQuotationApprovedNotificationHandlerSend quotation approval emailsrc/application/commands/send-quotation-approved-notification.command.ts

Reference: algesta-ms-notifications-nestjs/src/application/commands/ and algesta-ms-notifications-nestjs/src/application/handlers/

Queries (Read Operaciones)

Queries represent read-only Operaciones for retrieving notification data.

QueryHandlerPurposeFile Path
GetNotificationByIdQueryGetNotificationByIdHandlerGet notification by IDsrc/application/queries/get-notification-by-id.query.ts
GetAllNotificationsQueryGetAllNotificationsHandlerList notifications with paginationsrc/application/queries/get-all-notifications.query.ts

Reference: algesta-ms-notifications-nestjs/src/application/queries/ and algesta-ms-notifications-nestjs/src/application/handlers/

4. Domain Models

The Notifications Microservicio implements focused domain models for notification management.

Notification Entity

The Notification entity represents a notification record with Status tracking.

File: algesta-ms-notifications-nestjs/src/domain/entities/notification.entity.ts

Schema Fields:

  • _id (ObjectId): MongoDB unique identifier
  • userId (string): User ID who receives the notification
  • title (string): Notification title/subject
  • message (string): Notification content/body
  • Estado (enum): Notification Estado
    • NOT_VIEWED: Notification not yet viewed by user
    • VIEWED: Notification viewed by user
  • createdAt (Date): Notification creation timestamp
  • updatedAt (Date): Last update timestamp

Collection: notifications

Propósito: Track notification history and user engagement

Supporting Entities

Order Entity (denormalized):

  • Order information for email templates
  • Used for context in order-related notifications

Documento Entity (denormalized):

  • Documento information for expiration tracking
  • Used in Documento expiration reminder jobs

User Entity (denormalized):

  • User information for personalized notifications
  • Email addresses and user preferences

Reference: algesta-ms-notifications-nestjs/src/domain/entities/

5. Notification Strategies

The Notifications Microservicio implements the Strategy pattern for flexible notification delivery.

Email Notification Strategy

File: algesta-ms-notifications-nestjs/src/infrastructure/strategies/sendgrid.email.notification.ts

Provider: SendGrid (@sendgrid/mail 8.1.5)

Funcionalidades:

  • HTML email templates using Handlebars
  • Dynamic content injection
  • Attachment support (PDFs, images)
  • Template variables for personalization
  • Error handling and retry logic

Email Template Structure:

interface EmailTemplate {
to: string; // Recipient email
from: {
email: string; // Sender email
name: string; // Sender name
};
subject: string; // Email subject
html: string; // HTML content (rendered from Handlebars)
attachments?: Array<{ // Optional attachments
content: string; // Base64 encoded content
filename: string; // File name
type: string; // MIME type
}>;
}

Reference: algesta-ms-notifications-nestjs/src/infrastructure/strategies/sendgrid.email.notification.ts

Notification Factory

File: algesta-ms-notifications-nestjs/src/infrastructure/services/notification-factory.service.ts

Propósito: Create appropriate notification strategy based on type

Extensibility:

  • Easy to add new notification channels (SMS, Push, WhatsApp)
  • Strategy pattern allows swapping providers
  • Configuration-driven channel selection

Example:

class NotificationFactory {
createStrategy(type: NotificationType): INotificationStrategy {
switch (type) {
case NotificationType.EMAIL:
return new SendGridEmailStrategy();
case NotificationType.SMS:
return new TwilioSmsStrategy(); // Future
case NotificationType.PUSH:
return new FirebasePushStrategy(); // Future
}
}
}

Reference: algesta-ms-notifications-nestjs/src/infrastructure/services/notification-factory.service.ts

Quotation Notification Service

File: algesta-ms-notifications-nestjs/src/infrastructure/services/quotation-notification.service.ts

Propósito: Handle quotation-specific notifications

Funcionalidades:

  • Approval notifications to clients
  • Rejection notifications to providers
  • Reminder notifications for Pendiente approvals
  • Quote PDF attachment handling

Notification Types:

  • Quote Sent: Initial quote notification to client
  • Quote Approved: Approval confirmation to provider and client
  • Quote Rejected: Rejection notification to provider
  • Quote Reminder: Reminder for Pendiente approval

Reference: algesta-ms-notifications-nestjs/src/infrastructure/services/quotation-notification.service.ts

6. API Endpoints (MessagePatterns)

The Notifications Microservicio exposes its functionality via MessagePattern decorators for inter-service communication.

Controller: algesta-ms-notifications-nestjs/src/infrastructure/controllers/notification.controller.ts

Notification Management Patterns

PatternInput DTOOutput DTODescription
notification.create-notificationCreateNotificationDtoNotificationCreate notification record
notification.find-by-identification{id}NotificationGet notification by ID
notification.find-all-notificationsGetAllNotificationsDtoPaginatedNotificationsResponseList notifications with pagination
notification.update-notification{id, updateData}NotificationUpdate notification Estado
notification.delete-notification{id}{success, message}Delete notification

Email Notification Patterns

PatternInput DTOOutput DTODescription
notification.send-order-reminderSendOrderReminderDto{success, message, emailSent, remindersSent}Send order reminder email
quotation.approvedSendQuotationApprovedNotificationDto{success, message, emailSent}Send quotation approved email

CreateNotificationDto:

{
userId: string;
title: string;
message: string;
}

SendOrderReminderDto:

{
orderId: string;
service: string;
address: string;
phoneNumber: string;
emailContact: string;
nameContact: string;
}

SendQuotationApprovedNotificationDto:

{
orderId: string;
providerEmail: string;
providerName: string;
clientEmail: string;
clientName: string;
totalAmount: number;
}

PaginatedNotificationsResponse:

{
notifications: Notification[];
total: number;
page: number;
limit: number;
totalPages: number;
}

Reference: algesta-ms-notifications-nestjs/src/infrastructure/controllers/notification.controller.ts

7. Scheduled Jobs

The Notifications Microservicio implements cron jobs for automated notifications using @nestjs/schedule.

Documento Expiration Job

File: algesta-ms-notifications-nestjs/src/infrastructure/jobs/send-Documento-expire-notification.job.ts

Schedule: Daily check for expiring Documentos (configurable)

Propósito: Send reminder emails for Documentos about to expire

Configuration:

  • Days Before Expiration: Configurable (default: 7, 3, 1 days)
  • Cron Expression: 0 9 * * * (Every day at 9:00 AM)
  • Notification Recipients: Documento owner and administrators

Logic:

  1. Query Documentos expiring in configured days
  2. Filter Documentos not already notified
  3. Generate notification emails from template
  4. Send via SendGrid
  5. Mark Documentos as notified
  6. Log results

Example Cron Configuration:

@Cron('0 9 * * *', {
name: 'document-expiration-check',
timeZone: 'America/Bogota',
})
async handleDocumentExpirationCheck() {
const expiringDocuments = await this.getExpiringDocuments();
for (const doc of expiringDocuments) {
await this.sendExpirationNotification(doc);
}
}

Reference: algesta-ms-notifications-nestjs/src/infrastructure/jobs/send-Documento-expire-notification.job.ts

8. Email Templates

Email templates are stored as Handlebars (.hbs) files for dynamic content rendering.

Template Structure

Location: algesta-ms-notifications-nestjs/src/shared/assets/

Template Types:

  • order-reminder.hbs: Order reminder emails
  • quotation-approved.hbs: Quote approval notifications
  • Documento-expiration.hbs: Documento expiration reminders
  • welcome.hbs: Welcome emails for new users

Template Variables:

{{!-- order-reminder.hbs --}}
<html>
<body>
<h1>Recordatorio de Orden</h1>
<p>Hola {{nameContact}},</p>
<p>Le recordamos su orden de servicio:</p>
<ul>
<li><strong>Orden ID:</strong> {{orderId}}</li>
<li><strong>Servicio:</strong> {{service}}</li>
<li><strong>Dirección:</strong> {{address}}</li>
<li><strong>Teléfono:</strong> {{phoneNumber}}</li>
</ul>
<p>Por favor, confirme la fecha de servicio.</p>
</body>
</html>

Rendering Process:

  1. Load template file
  2. Inject variables using Handlebars.compile()
  3. Generate HTML string
  4. Send via SendGrid

Reference: algesta-ms-notifications-nestjs/src/shared/assets/README.md

9. Base de datos Schema

The Notifications Microservicio uses MongoDB with a simple schema.

notifications Collection

Schema: Notification entity

Fields:

  • _id: ObjectId (MongoDB primary key)
  • userId: string (indexed)
  • title: string
  • message: string
  • Estado: enum (NOT_VIEWED, VIEWED) - indexed
  • createdAt: Date (indexed)
  • updatedAt: Date

Indexes:

  • userId: For user-specific queries
  • Estado: For filtering by Estado
  • createdAt: For chronological sorting
  • userId + Estado (compound): For efficient user notification queries

Retention Policy: 90 days (configurable)

Reference: algesta-ms-notifications-nestjs/src/shared/infrastructure/Base de datos/

10. Integration Points

The Notifications Microservicio integrates with other services and external systems.

Internal Service Integration

Orders Microservicio:

  • Events Subscribed:
    • order.created: Send welcome notification
    • order.updated: Send Estado update notification
    • quote.sent: Send quote notification
    • quote.approved: Send approval confirmation
  • Propósito: Notify users of order lifecycle events

Provider Microservicio:

  • Events Subscribed:
    • auction.created: Notify eligible providers
    • provider.assigned: Notify assigned provider
    • provider.rated: Send rating notification
  • Propósito: Notify providers of auction and assignment events

External Services

SendGrid:

  • Propósito: Email delivery service
  • API Version: v3
  • Funcionalidades Used:
    • Transactional emails
    • Template emails
    • Attachment support
    • Delivery tracking
  • Rate Limits: Configured in SendGrid account

Reference: External service integrations in algesta-ms-notifications-nestjs/src/infrastructure/services/

11. Notification Flow Diagram

sequenceDiagram
    participant Orders as Orders MS
    participant Kafka
    participant Notifications as Notifications MS
    participant SendGrid
    participant Client

    Orders->>Kafka: Publish order.created event
    Kafka->>Notifications: order.created event
    Notifications->>Notifications: Load email template
    Notifications->>Notifications: Render with order data
    Notifications->>SendGrid: Send email (to: client email)
    SendGrid-->>Notifications: Email sent confirmation
    Notifications->>Notifications: Create notification record
    Notifications->>Notifications: Save to MongoDB
    SendGrid->>Client: Email delivered

    Note over Notifications: Track delivery status
    Notifications->>Notifications: Update notification status

12. Configuration and Environment Variables

Required Environment Variables

Ventana de terminal
# Application
NODE_ENV=development|production
PORT=3000
# Database
MONGODB_URI=mongodb://localhost:27017/notifications
DB_POOL_MAX=20
DB_POOL_MIN=5
# Messaging
MESSAGING_TYPE=REDIS|KAFKA
REDIS_HOST=localhost
REDIS_PORT=6379
KAFKA_BROKERS=localhost:9092
# SendGrid
SENDGRID_API_KEY=your_sendgrid_api_key
SENDGRID_FROM_EMAIL=noreply@algesta.com
SENDGRID_FROM_NAME=Algesta
# Notification Configuration
NOTIFICATION_RETRY_ATTEMPTS=3
NOTIFICATION_RETRY_DELAY=5000
NOTIFICATION_RETENTION_DAYS=90
# Logging
LOG_LEVEL=info|debug|error

13. Error Handling and Retry Logic

Notification Reliability

The Notifications Microservicio implements robust error handling and retry mechanisms.

Retry Strategy:

  • Max Attempts: 3 (configurable via NOTIFICATION_RETRY_ATTEMPTS)
  • Delay: 5 seconds between retries (configurable via NOTIFICATION_RETRY_DELAY)
  • Backoff: Exponential backoff (5s, 10s, 20s)

Error Types:

  • SendGrid API Errors:
    • Rate limit exceeded → Retry with backoff
    • Invalid email address → Don’t retry, log error
    • API key invalid → Don’t retry, alert admin
  • Template Rendering Errors:
    • Missing variables → Use default Valors, log warning
    • Template not found → Don’t retry, alert admin
  • Base de datos Errors:
    • Connection timeout → Retry
    • Duplicate key → Don’t retry, log error

Dead Letter Queue:

  • Failed notifications after max retries go to DLQ
  • DLQ monitored for persistent failures
  • Manual intervention required for DLQ items

Notification Estado Tracking:

enum NotificationDeliveryStatus {
PENDING = 'PENDING',
SENT = 'SENT',
FAILED = 'FAILED',
RETRY = 'RETRY',
}

Logging and Monitoring

Log Events:

  • Notification creation
  • Email sending attempts
  • SendGrid API responses
  • Template rendering errors
  • Retry attempts

Métricas:

  • Notifications sent per hour
  • Email delivery rate
  • Average delivery time
  • Failure rate by type
  • Template rendering time

14. Pruebas Strategy

Unit Pruebas

Command Handler Pruebas:

describe('SendOrderReminderHandler', () => {
it('should send order reminder email', async () => {
const command = new SendOrderReminderCommand(reminderDto);
const result = await handler.execute(command);
expect(result.success).toBe(true);
expect(result.emailSent).toBe(true);
});
it('should handle SendGrid errors gracefully', async () => {
mockSendGrid.send.mockRejectedValue(new Error('API Error'));
const command = new SendOrderReminderCommand(reminderDto);
const result = await handler.execute(command);
expect(result.success).toBe(false);
});
});

Integration Pruebas

SendGrid Mock Pruebas:

  • Mock SendGrid API responses
  • Test template rendering with various data
  • Test attachment handling
  • Test error scenarios

Example:

describe('SendGrid Integration', () => {
beforeEach(() => {
mockSendGridClient = {
send: jest.fn().mockResolvedValue([{ statusCode: 202 }]),
};
});
it('should send email with template', async () => {
await emailService.sendTemplateEmail('order-reminder', data);
expect(mockSendGridClient.send).toHaveBeenCalledWith({
to: 'client@example.com',
from: { email: 'noreply@algesta.com', name: 'Algesta' },
subject: expect.any(String),
html: expect.stringContaining('Recordatorio de Orden'),
});
});
});

E2E Pruebas

Notification Flow Pruebas:

  • Test Completo notification flow from event to email
  • Test scheduled job execution
  • Test notification Estado updates
  • Test retry logic

Test Coverage Targets:

  • Statements: >90%
  • Branches: >85%
  • Functions: >90%
  • Lines: >90%

Reference: algesta-ms-notifications-nestjs/README.md and algesta-ms-notifications-nestjs/package.json