Saltearse al contenido

Diagrama de Componentes - Microservicio de Órdenes

Descripción General

El Microservicio de Órdenes es el componente principal responsable de gestionar el ciclo de vida completo de las órdenes de mantenimiento en la plataforma Algesta. Implementa Clean Architecture con patrón CQRS, separando las responsabilidades de comando y consulta para mejor escalabilidad y mantenibilidad.

El microservicio maneja:

  • Creación de órdenes desde WhatsApp (Jelou) y dashboard
  • Gestión del ciclo de vida de órdenes (borrador, pendiente, asignado, aprobado, ejecución, cerrado)
  • Gestión de activos e historial (Hoja de Vida)
  • Gestión de cotizaciones (cotizaciones basadas en ítems)
  • Integración con sistemas externos (Asana, DocuSign, Qsystems, Sistema de Activos)
  • Publicación de eventos para comunicación entre servicios

Diagrama de Componentes

graph TB
    subgraph "Capa de Aplicación"
        OrdersController["OrdersController<br/>[REST Controller]<br/>Maneja solicitudes HTTP para gestión de órdenes"]

        CreateOrderHandler["CreateOrderHandler<br/>[Command Handler]<br/>Crea nuevas órdenes desde WhatsApp o dashboard"]
        UpdateOrderHandler["UpdateOrderHandler<br/>[Command Handler]<br/>Actualiza estado y detalles de orden"]
        PublishOrderHandler["PublishOrderHandler<br/>[Command Handler]<br/>Publica orden en subasta del marketplace"]
        CreateOrderItemsHandler["CreateOrderItemsHandler<br/>[Command Handler]<br/>Desglosa orden en ítems de cotización"]
        InflateQuotationHandler["InflateQuotationHandler<br/>[Command Handler]<br/>Aplica margen a cotización del proveedor"]
        SendQuotationHandler["SendQuotationHandler<br/>[Command Handler]<br/>Envía cotización al cliente para aprobación"]
        ProcessClientApprovalHandler["ProcessClientApprovalHandler<br/>[Command Handler]<br/>Maneja aprobación/rechazo del cliente"]
        ConfirmExecutionDateHandler["ConfirmExecutionDateHandler<br/>[Command Handler]<br/>Confirma calendario de ejecución"]
        CloseOrderHandler["CloseOrderHandler<br/>[Command Handler]<br/>Cierra órdenes completadas"]

        GetOrderByIdHandler["GetOrderByIdHandler<br/>[Query Handler]<br/>Recupera orden por ID"]
        GetAllOrdersHandler["GetAllOrdersHandler<br/>[Query Handler]<br/>Lista órdenes con filtros"]
        GetOrderHistoryHandler["GetOrderHistoryHandler<br/>[Query Handler]<br/>Recupera historial de eventos de orden"]

        OrderCreatedEventHandler["OrderCreatedEventHandler<br/>[Event Handler]<br/>Maneja evento OrderCreated"]
        OrderPublishedEventHandler["OrderPublishedEventHandler<br/>[Event Handler]<br/>Maneja evento OrderPublished"]
        ProviderSelectedEventHandler["ProviderSelectedEventHandler<br/>[Event Handler]<br/>Maneja evento ProviderSelected del MS de Proveedores"]
    end

    subgraph "Capa de Dominio"
        OrderEntity["Order Entity<br/>[Aggregate Root]<br/>Modelo de dominio de orden con reglas de negocio"]
        OrderEstadoEnum["OrderEstado<br/>[Enum]<br/>DRAFT, PENDING, ASSIGNED, APPROVED, EXECUTION_COMPLETED, CLOSED"]
        OrderItemVO["OrderItem<br/>[Objeto de Valor]<br/>Ítem individual de cotización"]
        QuotationVO["Quotation<br/>[Objeto de Valor]<br/>Cotización completa con ítems"]
        AssetEntity["Asset Entity<br/>[Aggregate Root]<br/>Modelo de dominio de activo"]
        AssetHistoryEventEntity["AssetHistoryEvent<br/>[Entity]<br/>Evento de mantenimiento de activo"]
        OrderRepositorio["OrderRepositorio<br/>[Interface]<br/>Abstracción de repositorio"]
        AssetRepositorio["AssetRepositorio<br/>[Interface]<br/>Abstracción de repositorio"]
    end

    subgraph "Capa de Infraestructura"
        OrderRepositorioImpl["OrderRepositorioImpl<br/>[Implementación Mongoose]<br/>Persistencia MongoDB usando Mongoose ODM"]
        AssetRepositorioImpl["AssetRepositorioImpl<br/>[Implementación Mongoose]<br/>Persistencia MongoDB para activos"]
        AsanaIntegrationService["AsanaIntegrationService<br/>[Servicio Externo]<br/>Crea tareas en Asana"]
        DocuSignIntegrationService["DocuSignIntegrationService<br/>[Servicio Externo]<br/>Solicita firmas digitales"]
        QsystemsIntegrationService["QsystemsIntegrationService<br/>[Servicio Externo]<br/>Sincroniza con sistema de cliente empresarial"]
        AssetsIntegrationService["AssetsIntegrationService<br/>[Servicio Externo]<br/>Sincroniza con sistema de activos legado"]
        MessageBrokerService["MessageBrokerService<br/>[Publicador de Eventos]<br/>Publica eventos a Redis/Kafka"]
        PdfGenerationService["PdfGenerationService<br/>[Servicio de Infraestructura]<br/>Genera PDFs de cotizaciones e informes usando Puppeteer"]
        BlobStorageService["BlobStorageService<br/>[Servicio de Infraestructura]<br/>Sube PDFs a Azure Blob Storage"]
    end

    subgraph "Dependencias Externas"
        MongoDB[("MongoDB<br/>[Base de datos]<br/>Base de datos de órdenes")]
        RedisKafka[("Redis/Kafka<br/>[Message Broker]<br/>Transmisión de eventos")]
        AsanaAPI["Asana API<br/>[Sistema Externo]"]
        DocuSignAPI["DocuSign API<br/>[Sistema Externo]"]
        QsystemsAPI["Qsystems API<br/>[Sistema Externo]"]
        AssetsAPI["Assets System API<br/>[Sistema Externo]"]
        BlobStorage[("Azure Blob Storage<br/>[Almacenamiento]<br/>Almacenamiento de PDFs")]
    end

    OrdersController --> CreateOrderHandler
    OrdersController --> UpdateOrderHandler
    OrdersController --> PublishOrderHandler
    OrdersController --> CreateOrderItemsHandler
    OrdersController --> InflateQuotationHandler
    OrdersController --> SendQuotationHandler
    OrdersController --> ProcessClientApprovalHandler
    OrdersController --> ConfirmExecutionDateHandler
    OrdersController --> CloseOrderHandler
    OrdersController --> GetOrderByIdHandler
    OrdersController --> GetAllOrdersHandler
    OrdersController --> GetOrderHistoryHandler

    CreateOrderHandler --> OrderEntity
    CreateOrderHandler --> OrderRepositorio
    CreateOrderHandler --> AssetsIntegrationService
    CreateOrderHandler --> MessageBrokerService
    UpdateOrderHandler --> OrderEntity
    UpdateOrderHandler --> OrderRepositorio
    PublishOrderHandler --> OrderEntity
    PublishOrderHandler --> OrderRepositorio
    PublishOrderHandler --> MessageBrokerService
    CreateOrderItemsHandler --> OrderEntity
    CreateOrderItemsHandler --> OrderItemVO
    CreateOrderItemsHandler --> OrderRepositorio
    InflateQuotationHandler --> QuotationVO
    InflateQuotationHandler --> OrderRepositorio
    SendQuotationHandler --> OrderRepositorio
    SendQuotationHandler --> PdfGenerationService
    SendQuotationHandler --> BlobStorageService
    SendQuotationHandler --> MessageBrokerService
    ProcessClientApprovalHandler --> OrderEntity
    ProcessClientApprovalHandler --> OrderRepositorio
    ProcessClientApprovalHandler --> MessageBrokerService

    GetOrderByIdHandler --> OrderRepositorio
    GetAllOrdersHandler --> OrderRepositorio

    OrderCreatedEventHandler --> AsanaIntegrationService
    OrderCreatedEventHandler --> QsystemsIntegrationService
    OrderPublishedEventHandler --> MessageBrokerService
    ProviderSelectedEventHandler --> OrderRepositorio

    OrderRepositorio --> OrderRepositorioImpl
    AssetRepositorio --> AssetRepositorioImpl
    OrderRepositorioImpl --> MongoDB
    AssetRepositorioImpl --> MongoDB

    AsanaIntegrationService --> AsanaAPI
    DocuSignIntegrationService --> DocuSignAPI
    QsystemsIntegrationService --> QsystemsAPI
    AssetsIntegrationService --> AssetsAPI
    MessageBrokerService --> RedisKafka
    BlobStorageService --> BlobStorage

    style OrdersController fill:#438dd5,stroke:#2e6295,color:#ffffff
    style CreateOrderHandler fill:#85bbf0,stroke:#5a8bc4,color:#000000
    style UpdateOrderHandler fill:#85bbf0,stroke:#5a8bc4,color:#000000
    style PublishOrderHandler fill:#85bbf0,stroke:#5a8bc4,color:#000000
    style CreateOrderItemsHandler fill:#85bbf0,stroke:#5a8bc4,color:#000000
    style InflateQuotationHandler fill:#85bbf0,stroke:#5a8bc4,color:#000000
    style SendQuotationHandler fill:#85bbf0,stroke:#5a8bc4,color:#000000
    style ProcessClientApprovalHandler fill:#85bbf0,stroke:#5a8bc4,color:#000000
    style ConfirmExecutionDateHandler fill:#85bbf0,stroke:#5a8bc4,color:#000000
    style CloseOrderHandler fill:#85bbf0,stroke:#5a8bc4,color:#000000
    style GetOrderByIdHandler fill:#a8d5ba,stroke:#7cb99a,color:#000000
    style GetAllOrdersHandler fill:#a8d5ba,stroke:#7cb99a,color:#000000
    style GetOrderHistoryHandler fill:#a8d5ba,stroke:#7cb99a,color:#000000
    style OrderCreatedEventHandler fill:#ffd93d,stroke:#ccad30,color:#000000
    style OrderPublishedEventHandler fill:#ffd93d,stroke:#ccad30,color:#000000
    style ProviderSelectedEventHandler fill:#ffd93d,stroke:#ccad30,color:#000000
    style OrderEntity fill:#6bcf7f,stroke:#56a466,color:#ffffff
    style AssetEntity fill:#6bcf7f,stroke:#56a466,color:#ffffff
    style OrderRepositorioImpl fill:#ff6b6b,stroke:#cc5555,color:#ffffff
    style AssetRepositorioImpl fill:#ff6b6b,stroke:#cc5555,color:#ffffff
    style MongoDB fill:#ff6b6b,stroke:#cc5555,color:#ffffff
    style RedisKafka fill:#48dbfb,stroke:#2e9cba,color:#000000
    style BlobStorage fill:#feca57,stroke:#cb9f46,color:#000000

Figura: Arquitectura de Componentes del Microservicio de Órdenes - Capas de Clean Architecture con implementación del patrón CQRS


CQRS Pattern Visualization

Command Flow

sequenceDiagram
    participant Client as API Gateway
    participant Controller as OrdersController
    participant CommandBus as CommandBus
    participant Handler as CreateOrderHandler
    participant Domain as Order Entity
    participant Repo as OrderRepositorio
    participant DB as MongoDB
    participant Events as MessageBroker

    Client->>Controller: POST /api/orders (CreateOrderDto)
    Controller->>CommandBus: execute(CreateOrderCommand)
    CommandBus->>Handler: handle(command)
    Handler->>Domain: new Order(data)
    Domain-->>Handler: Order entity
    Handler->>Repo: save(order)
    Repo->>DB: insert Documento
    DB-->>Repo: saved Documento
    Repo-->>Handler: order
    Handler->>Events: publish(OrderCreatedEvent)
    Events-->>Handler: event published
    Handler-->>CommandBus: order
    CommandBus-->>Controller: order
    Controller-->>Client: 201 Created

Figura: CQRS Command Flow - Write operation flow from API Gateway to MongoDB

Query Flow

sequenceDiagram
    participant Client as API Gateway
    participant Controller as OrdersController
    participant QueryBus as QueryBus
    participant Handler as GetOrderByIdHandler
    participant Repo as OrderRepositorio
    participant DB as MongoDB

    Client->>Controller: GET /api/orders/:id
    Controller->>QueryBus: execute(GetOrderByIdQuery)
    QueryBus->>Handler: handle(query)
    Handler->>Repo: findById(id)
    Repo->>DB: findOne({_id: id})
    DB-->>Repo: Documento
    Repo-->>Handler: order
    Handler-->>QueryBus: order
    QueryBus-->>Controller: order
    Controller-->>Client: 200 OK (order data)

Figura: CQRS Query Flow - Read operation flow with direct Base de datos access


Stack Tecnológico

DependencyVersionPurpose
@nestjs/core11.xNestJS framework core
@nestjs/cqrs11.xCQRS pattern Implementación
@nestjs/mongoose11.xMongoDB integration via Mongoose
@nestjs/Microservicios11.xRedis/Kafka client for messaging
mongoose8.xMongoDB ODM
class-validator0.14.xDTO validation
class-transformer0.5.xDTO transformation
puppeteer23.xPDF generation for quotations
@azure/storage-blob12.xAzure Blob Storage SDK
axios1.xHTTP client for external APIs

Key Design Patterns

Clean Architecture Layers

The Orders Microservicio follows Clean Architecture with clear separation:

  1. Domain Layer (innermost)

    • Pure business logic
    • No dependencies on external frameworks
    • Entities: Order, Asset, AssetHistoryEvent
    • Valor Objects: OrderItem, Quotation
    • Repositorio interfaces
  2. Application Layer

    • Use cases Implementación
    • Command Handlers: CreateOrder, UpdateOrder, PublishOrder, etc.
    • Query Handlers: GetOrderById, GetAllOrders, etc.
    • Event Handlers: OrderCreated, OrderPublished, etc.
    • DTOs for input/output
  3. Infrastructure Layer (outermost)

    • Framework-specific code
    • Mongoose Repositorio Implementacións
    • External service integrations
    • Message broker publisher
    • PDF generation service

CQRS Implementación

Commands (write Operaciones):

  • CreateOrderCommand - Creates new order
  • UpdateOrderCommand - Updates order details
  • PublishOrderCommand - Publishes order to auction
  • CreateOrderItemsCommand - Creates quotation items
  • InflateQuotationCommand - Applies markup to quotation
  • SendQuotationToClientCommand - Sends quotation for approval
  • ProcessClientApprovalCommand - Handles client approval/rejection
  • ConfirmExecutionDateCommand - Confirms execution schedule
  • CloseOrderCommand - Closes Completod order

Queries (read Operaciones):

  • GetOrderByIdQuery - Retrieves single order
  • GetAllOrdersQuery - Lists orders with filters
  • GetOrderHistoryQuery - Retrieves order event history
  • GetAssetByIdQuery - Retrieves asset details
  • GetAssetHistoryQuery - Retrieves asset maintenance history

Events (domain events):

  • OrderCreatedEvent - Triggered when order is created
  • OrderPublishedEvent - Triggered when order is published to auction
  • OrderItemsCreatedEvent - Triggered when quotation items are created
  • QuotationInflatedEvent - Triggered when markup is applied
  • QuotationSentToClientEvent - Triggered when quotation is sent
  • OrderApprovedEvent - Triggered when client approves quotation
  • OrderRejectedEvent - Triggered when client rejects quotation
  • ExecutionDateConfirmedEvent - Triggered when execution date is set
  • OrderClosedEvent - Triggered when order is closed

Repositorio Pattern

The Repositorio pattern provides abstraction over data access:

// Domain layer - interface
interface OrderRepositorio {
findById(id: string): Promise<Order>;
findAll(filters: OrderFilters): Promise<Order[]>;
save(order: Order): Promise<Order>;
update(id: string, order: Order): Promise<Order>;
delete(id: string): Promise<void>;
}
// Infrastructure layer - Implementación
class OrderRepositorioImpl implements OrderRepositorio {
constructor(
@InjectModel(Order.name) private orderModel: Model<OrderDocumento>
) {}
async findById(id: string): Promise<Order> {
const doc = await this.orderModel.findById(id).exec();
return this.toDomain(doc);
}
// ... other Métodos
}

Event Sourcing (Partial)

While full event sourcing is not implemented, the Microservicio maintains an event history for orders and assets:

  • All state changes publish domain events
  • Events are stored in MongoDB for audit trail
  • Events are published to message broker for inter-service communication
  • Asset history is built from maintenance events

Referencias Cruzadas