Saltearse al contenido

Diagrama UML - Módulo AprobarCupo

Origin: produced by the original Mi Plante team. Received via the project repo (files-they-shareme/DIAGRAMA_APROBAR_CUPO_UML.md). This is the most authoritative source on the intended class structure, method signatures, and relationships for the AprobarCupo (credit approval) module.

How to use it: read this FIRST to understand architectural intent for credit approval. Then read docs/onboarding/02-codebase-tour/04-trace-a-credit-approval.md to see runtime behavior. The trace doc is grounded in audit findings, which validated the runtime against the code.

Confirmed by this diagram: 5 injected services (ClienteService, AprobarCupoService, LegalCheckService, IdentityValidationService, HDCValidationService), 8 controller endpoints, the ResultTrait pattern across 6 Result DTOs, the 7-value ProcessType enum, the 3-value EventType enum, the aprobar_cupo_eventos audit table.

DISCREPANCY ALERT — approval-rule wording: This UML states the rule as “requiere 3+ procesos exitosos en el mes” (3+ successful processes in the month).

The runtime in app/Services/AprobarCupoService::validarSiElClienteTieneSuCupoAprobado() (lines 17-38) enforces >= 5 distinct ProcessTypes whose latest event in the current calendar month is FINISH_SUCCESS — no order enforcement, no day-bucket. The audit (docs/audit/12-credit-approval-workflow-diagram.md) now reflects this same code-confirmed rule.

Treat the UML’s “3+” as stale wording from an earlier design. The code is the source of truth, and the audit aligns with the code. This is logged in docs/onboarding/04-the-landmines/01-known-bugs.md as L-30.

The “2 intentos diarios” claim in the UML IS code-confirmed (AprobarCupoService::haSuperadoLimiteIntentosDiarios).

Confirmed by code (no discrepancy):

  • LegalCheckServiceTransUnion (UML correct; LegalCheckService.php:37 calls Http::transunion()->post('/ws/LegalcheckWSRest/legalcheck/consulta')).
  • HDCValidationService is a real check, not a placeholder. It calls DataCreditoService::consultarHistorialPorTipoDocumento() and returns (int) responseCode === 13 from ReportHDCplus.productResult.responseCode. The UML’s “Actualmente devuelve true” line is outdated.

See also:

  • docs/audit/12-credit-approval-workflow-diagram.md (the 7-step pipeline, deeper)
  • docs/onboarding/02-codebase-tour/04-trace-a-credit-approval.md (runtime walk)
  • docs/onboarding/media/diagrams/credit-pipeline.mmd (pedagogical flowchart)
  • app/Http/Controllers/AprobarCliente/CLAUDE.md (per-domain AI context, includes the runtime rule)
  • docs/onboarding/04-the-landmines/01-known-bugs.md — landmines L-28 (OTP not enforced before questions), L-29 (score minimum not enforced), L-30 (rule mismatch)

classDiagram
    class AprobarCupoController {
        -ClienteService clienteService
        -AprobarCupoService aprobarCupoService
        -LegalCheckService legalCheckService
        -IdentityValidationService identityValidationService
        -HDCValidationService hdcValidationService
        +legalCheck() JsonResponse
        +identityValidation() JsonResponse
        +identityValidationGenerateOTPCode() JsonResponse
        +identityValidationVerifyOTPCode(Request) JsonResponse
        +identityValidationGenerateQuestions() JsonResponse
        +identityValidationVerifyQuestions(Request) JsonResponse
        +hdcValidation(Request) JsonResponse
        +aprobarCupo() JsonResponse
    }

    class ClienteService {
        +crearCliente(CrearClienteDTO) Cliente
        +actualizar(clienteId, ActualizarClienteDTO) Cliente
        +completarRegistroConUsuarioId(usuarioId, CompletarRegistroClienteDTO) bool
        +validarFacturasDeUltimoSeisMeses(insertadas, facturasObtenidas) bool
        +validarSimilitudDeDirecciones(direccionInsertada, direccionObtenida) bool
    }

    class AprobarCupoService {
        +crear(CrearCupoEventoDTO) AprobarCupoEvento
        +validarSiElClienteTieneSuCupoAprobado(clienteId) bool
        +haSuperadoLimiteIntentosDiarios(clienteId) bool
    }

    class LegalCheckService {
        +manejar(User) LegalCheckResult
        -tieneHallazgosLegales(data) bool
    }

    class IdentityValidationService {
        +generateToken() string
        +validarIdentidad(User) IdentityValidationResult
        +generarOTP(User) GenerateOTPResult
        +verificarOTP(User, otpCode) VerifyOTPResult
        +generarCuestionario(User) GenerateQuestionnarieResult
        +verificarCuestionario(User, respuestas) VerifyQuestionnarieResult
    }

    class HDCValidationService {
        +manejar() bool
    }

    class LegalCheckResult {
        <<Result DTO>>
        -bool hasError
        -string error
        -array data
        +hasError() bool
        +getError() string
        +getData() array
        +toArray() array
    }

    class IdentityValidationResult {
        <<Result DTO>>
        -bool hasError
        -string error
        -array data
        +hasError() bool
        +getError() string
        +getData() array
        +toArray() array
    }

    class GenerateOTPResult {
        <<Result DTO>>
        -bool hasError
        -string error
        -array data
        +hasError() bool
        +getError() string
        +getData() array
        +toArray() array
    }

    class VerifyOTPResult {
        <<Result DTO>>
        -bool hasError
        -string error
        -array data
        +hasError() bool
        +getError() string
        +getData() array
        +toArray() array
    }

    class GenerateQuestionnarieResult {
        <<Result DTO>>
        -bool hasError
        -string error
        -array data
        +hasError() bool
        +getError() string
        +getData() array
        +toArray() array
    }

    class VerifyQuestionnarieResult {
        <<Result DTO>>
        -bool hasError
        -string error
        -array data
        +hasError() bool
        +getError() string
        +getData() array
        +toArray() array
    }

    class ActualizarClienteDTO {
        <<DTO>>
        +cupo_vence_en: datetime
        +toArray() array
    }

    class CrearCupoEventoDTO {
        <<DTO>>
        +cliente_id: int
        +tipo_proceso: ProcessType
        +evento: EventType
        +contexto: ?array
        +toArray() array
    }

    class User {
        -int id
        -int persona_id
        -string nombres
        -string apellidos
        -string email
        +persona() BelongsTo
        +cliente() HasOne
    }

    class Cliente {
        -int id
        -int user_id
        -string barrio
        -string ciudad
        -decimal cupo_disponible
        -string estado_cuenta
        +user() BelongsTo
    }

    class Persona {
        -int id
        -string tipo_dni
        -string dni
        -string lugar_expedicion
        -timestamp expedido_en
    }

    class AprobarCupoEvento {
        -int id
        -int cliente_id
        -ProcessType tipo_proceso
        -EventType evento
        -json contexto
        -timestamp creado_en
    }

    class EventType {
        <<enumeration>>
        START
        FINISH_SUCCESS
        FINISH_UNSUCCESS
    }

    class ProcessType {
        <<enumeration>>
        LEGAL_CHECK
        IDENTITY_VALIDATION
        IV_OTP_GENERATION
        IV_OTP_VERIFICATION
        IV_QUESTION_GENERATION
        IV_QUESTION_VERIFICATION
        HDC_VALIDATION
    }

    class ResultTrait {
        <<trait>>
        -bool hasError
        -string error
        -array data
        +static success(array) self
        +static error(string, array) self
        +hasError() bool
        +getError() string
        +getData() array
        +toArray() array
    }

    AprobarCupoController "1" --> "1" ClienteService : usa
    AprobarCupoController "1" --> "1" AprobarCupoService : usa
    AprobarCupoController "1" --> "1" LegalCheckService : usa
    AprobarCupoController "1" --> "1" IdentityValidationService : usa
    AprobarCupoController "1" --> "1" HDCValidationService : usa

    ClienteService --> Cliente : manipula
    ClienteService --> ActualizarClienteDTO : recibe
    
    AprobarCupoService --> AprobarCupoEvento : crea/consulta
    AprobarCupoService --> CrearCupoEventoDTO : recibe
    AprobarCupoService --> ProcessType : utiliza
    AprobarCupoService --> EventType : utiliza

    LegalCheckService --> User : valida
    LegalCheckService --> LegalCheckResult : retorna
    LegalCheckService --> ProcessType : utiliza
    LegalCheckService --> EventType : utiliza

    IdentityValidationService --> User : valida
    IdentityValidationService --> IdentityValidationResult : retorna
    IdentityValidationService --> GenerateOTPResult : retorna
    IdentityValidationService --> VerifyOTPResult : retorna
    IdentityValidationService --> GenerateQuestionnarieResult : retorna
    IdentityValidationService --> VerifyQuestionnarieResult : retorna
    IdentityValidationService --> ProcessType : utiliza
    IdentityValidationService --> EventType : utiliza

    LegalCheckResult --|> ResultTrait : usa
    IdentityValidationResult --|> ResultTrait : usa
    GenerateOTPResult --|> ResultTrait : usa
    VerifyOTPResult --|> ResultTrait : usa
    GenerateQuestionnarieResult --|> ResultTrait : usa
    VerifyQuestionnarieResult --|> ResultTrait : usa

    User "1" --> "1" Persona : persona_id
    User "1" --> "1" Cliente : cliente
    Cliente "1" --> "1" User : user_id
    
    AprobarCupoEvento "1" --> "1" Cliente : cliente_id
    AprobarCupoEvento "1" --|> ProcessType : tipo_proceso
    AprobarCupoEvento "1" --|> EventType : evento

Descripción de Componentes

Controlador

AprobarCupoController

  • Orquesta el flujo de aprobación de cupo del cliente
  • Inyecta 5 servicios principales
  • Expone 8 endpoints para diferentes validaciones
  • Maneja la autenticación del usuario mediante auth()->user()

Servicios

ClienteService

  • Gestiona operaciones CRUD sobre clientes
  • Valida direcciones con similitud textual
  • Valida facturas de últimos 6 meses

AprobarCupoService

  • Crea eventos de aprobación de cupo
  • Valida si el cliente tiene su cupo aprobado (requiere 3+ procesos exitosos en el mes)
  • Verifica límite de 2 intentos diarios por cliente

LegalCheckService

  • Integración con API Transunion para verificación legal
  • Valida documento vigente
  • Verifica hallazgos legales en listas de restricción
  • Validación de similitud de nombres

IdentityValidationService

  • Integración con API Expirian CrossCore
  • Genera y valida OTP (One-Time Password)
  • Genera cuestionario de seguridad
  • Verifica respuestas del cuestionario
  • Maneja token de autenticación con Expirian

HDCValidationService

  • Validación de historial de crédito
  • Actualmente devuelve true (placeholder para implementación futura)

DTOs de Resultado (Traits)

Todas las clases Result heredan del trait ResultTrait:

  • LegalCheckResult: Resultado de validación legal
  • IdentityValidationResult: Resultado de validación de identidad
  • GenerateOTPResult: Resultado de generación de OTP
  • VerifyOTPResult: Resultado de verificación de OTP
  • GenerateQuestionnarieResult: Resultado de generación de cuestionario
  • VerifyQuestionnarieResult: Resultado de verificación de cuestionario

Métodos comunes:

  • hasError(): Indica si hubo error
  • getError(): Obtiene mensaje de error
  • getData(): Obtiene datos del resultado
  • toArray(): Convierte a array

DTOs de Entrada

ActualizarClienteDTO

  • cupo_vence_en: Fecha de vencimiento del cupo
  • Utilizado para actualizar cliente tras aprobación

CrearCupoEventoDTO

  • cliente_id: ID del cliente
  • tipo_proceso: Tipo de validación (ProcessType enum)
  • evento: Tipo de evento (EventType enum)
  • contexto: Datos adicionales del proceso

Modelos

User

  • Usuario del sistema autenticado
  • Relación 1-a-1 con Persona (datos personales)
  • Relación 1-a-1 con Cliente (datos de cliente)

Cliente

  • Datos específicos del cliente (cupo, estado, ubicación)
  • Vinculado a User

Persona

  • Información personal y documento de identidad
  • Tipo DNI, número, lugar de expedición

AprobarCupoEvento

  • Registro de auditoría de validaciones
  • Almacena tipo de proceso, evento y contexto
  • Permite validar límite de intentos diarios

Enumeraciones

ProcessType - Tipos de validación:

  • LEGAL_CHECK
  • IDENTITY_VALIDATION
  • IV_OTP_GENERATION / IV_OTP_VERIFICATION
  • IV_QUESTION_GENERATION / IV_QUESTION_VERIFICATION
  • HDC_VALIDATION

EventType - Estados de eventos:

  • START
  • FINISH_SUCCESS
  • FINISH_UNSUCCESS

Flujo de Aprobación de Cupo

1. Legal Check (LegalCheckService)
└─> Valida documento en Transunion
└─> Verifica documento vigente
└─> Valida hallazgos legales
2. Identity Validation (IdentityValidationService)
└─> Genera OTP y lo envía
└─> Usuario verifica OTP
└─> Genera cuestionario de seguridad
└─> Usuario responde cuestionario
3. HDC Validation (HDCValidationService)
└─> Valida historial de crédito
4. Aprobar Cupo (AprobarCupoService)
└─> Verifica 3+ procesos exitosos en el mes
└─> Asigna cupo y fecha de vencimiento
└─> Registra en AprobarCupoEvento

Integraciones Externas

  1. Transunion - Validación legal y verificación de documento
  2. Expirian CrossCore - Validación de identidad, OTP y cuestionario
  3. Event System - Dispara ValidationLog para auditoría de cada proceso