ums

ApprovalRequest — Arquitectura de Agregados

Contexto Delimitado: Aprobaciones
Raíz de Agregado: ApprovalRequest
Módulo: Ums.Domain.Approvals.ApprovalRequest
Estado: Producción


1. Visión General del Agregado

Propósito

El agregado ApprovalRequest representa una ejecucion concreta en tiempo de ejecucion de un proceso de aprobacion. Cuando un usuario solicita una accion sensible, como asignacion de perfil, promocion de perfil o modificacion de configuracion de seguridad, UMS instancia una ApprovalRequest vinculada a un ApprovalWorkflow especifico para rastrear el estado y los detalles de auditoria de esa decision operativa.

Responsabilidad de Negocio

Raíz de Agregado

ApprovalRequest es la raíz del agregado. Todas las transiciones de estado (Aprobación, Rechazo) deben fluir a través de él para garantizar el cumplimiento de las restricciones.

Invariantes y Reglas de Consistencia

  1. Una solicitud nace en el estado Pending (Pendiente).
  2. El estado solo puede pasar de Pending a Approved (Aprobado) o Rejected (Rechazado). Una vez que una solicitud se ha finalizado, su estado se bloquea permanentemente y no se puede editar.
  3. Debe contener referencias válidas a WorkflowId y TargetUserId.
  4. Un usuario no puede aprobar su propia solicitud de promoción (aplicado en la barrera de comandos de la aplicación/dominio para evitar colusión).

Entidades Relacionadas / Objetos de Valor

| Entidad / VO | Tipo | Propietario | |—|—|—| | ApprovalRequestId | Objeto de Valor | Identificador de raíz de agregado basado en Guid | | ApprovalStatus | Enumerado | Pending · Approved · Rejected | | SystemSuiteId | Objeto de Valor | Alcance del sistema solicitado | | BranchId | Objeto de Valor | Alcance de la sucursal solicitada, cuando aplica | | RoleId | Objeto de Valor | Identificador del rol solicitado u otorgado | | AuditValueObject | Objeto de Valor | Rastrea metadatos de creación y modificación |

Eventos de Dominio

| Evento | Desencadenante | |—|—| | ApprovalRequestCreatedEvent | Se registra una nueva solicitud de aprobación y se establece en Pendiente | | ApprovalRequestApprovedEvent | La solicitud se marca como Aprobada, activando despliegues aguas abajo | | ApprovalRequestRejectedEvent | La solicitud se marca como Rejected. En solicitudes de perfil EP-09 se expone al usuario como Denegado |

Comandos / Casos de Uso

| Comando | Descripción | |—|—| | CreateApprovalRequestCommand | Instanciar una solicitud de acceso a perfil con sistema, sucursal, rol y justificación solicitados | | ApproveRequestCommand | Aprobar una solicitud pendiente con el identificador del actor autorizado | | RejectRequestCommand | Rechazar una solicitud pendiente. Los flujos de onboarding exponen este resultado final como Denegado |

Límites de Repositorio / Servicio


2. Modelo de Dominio

Clases / Entidades / Objetos de Valor

ApprovalRequest (Raíz de Agregado)
└── Props: ApprovalRequestProps
    ├── Id: ApprovalRequestId
    ├── WorkflowId: ApprovalWorkflowId
    ├── TargetUserId: UserId
    ├── TargetProfileId?: ProfileId
    ├── RequestedSystemId: SystemSuiteId
    ├── RequestedBranchId?: BranchId
    ├── RequestedRoleId: RoleId
    ├── Justification?: string
    ├── Status: ApprovalStatus
    ├── GrantedRoleId?: RoleId
    ├── DecisionReason?: string
    └── Audit: AuditValueObject

3. Diagramas de Modelo de Objetos

classDiagram
    direction LR
    class ApprovalRequest {
        +Guid Id
        +Guid WorkflowId
        +Guid TargetUserId
        +Guid? TargetProfileId
        +Guid RequestedSystemId
        +Guid? RequestedBranchId
        +Guid RequestedRoleId
        +string? Justification
        +ApprovalStatus Status
        +Guid? GrantedRoleId
        +string? DecisionReason
        +Create()
        +Approve()
        +Reject()
    }
    class ApprovalStatus {
        <<enumeration>>
        Pending
        Approved
        Rejected
    }
    ApprovalRequest "1" *-- "1" ApprovalStatus

4. Diagramas de Secuencia

Ciclo de Vida Completo de la Solicitud de Aprobación

sequenceDiagram
    participant U as Solicitante
    participant H as RequestHandler
    participant R as IApprovalRequestRepository
    participant A as ApprovalRequest (AR)
    participant E as EventPublisher
    participant Admin as Aprobador

    U->>H: CreateApprovalRequestCommand(workflowId, targetUserId, targetProfileId, requestedSystemId, requestedBranchId, requestedRoleId, justification)
    H->>A: ApprovalRequest.Create(workflowId, targetUserId, targetProfileId, requestedSystemId, requestedBranchId, requestedRoleId, justification, actorId)
    A->>A: Establecer Estado = Pendiente
    A->>A: Levantar ApprovalRequestCreatedEvent
    H->>R: Save(request)
    R-->>H: ok
    H-->>U: RequestId

    Note over U,A: Revisión Administrativa
    Admin->>H: ApproveRequestCommand(requestId)
    H->>R: GetById(requestId)
    R-->>H: ApprovalRequest (AR)
    H->>A: Approve(adminActorId)
    A->>A: Transición Estado -> Aprobado
    A->>A: Levantar ApprovalRequestApprovedEvent
    H->>R: Save(request)
    R-->>H: ok
    H->>E: Publicar ApprovalRequestApprovedEvent

Mapeo de Onboarding de Solicitud de Perfil

sequenceDiagram
    participant Usuario as Usuario en Lobby
    participant H as ProfileRequestHandler
    participant R as IApprovalRequestRepository
    participant A as ApprovalRequest (AR)
    participant Admin as Aprobador de Tenant o Sucursal
    participant Notify as Servicio de Notificacion

    Usuario->>H: Solicitar acceso a perfil
    H->>A: ApprovalRequest.Create(workflowId, userId, targetProfileId, requestedSystemId, requestedBranchId, requestedRoleId, justification)
    A->>A: Asignar Status = Pending
    H->>R: Guardar solicitud
    R-->>Admin: Solicitud pendiente disponible en bandeja con alcance
    Admin->>H: Aprobar o denegar resultado final
    H->>A: Approve() o Reject()
    A->>A: Guardar Approved o Rejected
    H->>Notify: Notificar al usuario con resultado Aprobado o Denegado

5. Modelo ER

erDiagram
    APPROVAL_WORKFLOW ||--o{ APPROVAL_REQUEST : "enruta"
    USER_ACCOUNT ||--o{ APPROVAL_REQUEST : "apunta-a"
    PROFILE ||--o{ APPROVAL_REQUEST : "eleva-a"

    APPROVAL_REQUEST {
        uniqueidentifier Id PK
        uniqueidentifier WorkflowId FK
        uniqueidentifier TargetUserId FK
        uniqueidentifier TargetProfileId FK "Nullable"
        uniqueidentifier RequestedSystemId FK
        uniqueidentifier RequestedBranchId FK "Nullable"
        uniqueidentifier RequestedRoleId FK
        nvarchar Justification "Nullable"
        int StatusId "1=Pending, 2=Approved, 3=Rejected"
        uniqueidentifier GrantedRoleId FK "Nullable"
        nvarchar DecisionReason "Nullable"
        nvarchar CreatedBy
        datetime2 CreatedAtUtc
        nvarchar UpdatedBy "Nullable"
        datetime2 UpdatedAtUtc "Nullable"
        nvarchar AuditTimeSpan
        rowversion RowVersion
    }

Reglas de Aislamiento de Inquilinos

Extension Requerida por EP-09

El record ApprovalRequest implementado ya guarda el sistema solicitado, la sucursal, el rol solicitado, la justificacion, el rol otorgado y el motivo de decision. La entrega final de notificacion se maneja en la canalizacion de notificaciones, por lo que el seguimiento restante de FS-24 solo sera necesario si el diseno exige un campo persistido de resultado de notificacion.


6. Integración de Contexto Delimitado


7. Capa de Aplicación


8. Infraestructura/Persistencia


9. Seguridad y Cumplimiento


10. Decisiones Técnicas


Volver al Índice de Aprobaciones