Skip to content

Instantly share code, notes, and snippets.

@jluisflo
Created December 20, 2025 00:22
Show Gist options
  • Select an option

  • Save jluisflo/415c28b8d020bfe5645577d5a7de23c2 to your computer and use it in GitHub Desktop.

Select an option

Save jluisflo/415c28b8d020bfe5645577d5a7de23c2 to your computer and use it in GitHub Desktop.
Análisis Arquitectónico Completo: Plataforma MPAY - C4 Model + Event Storming

Análisis Arquitectónico Completo: Plataforma MPAY

Resumen Ejecutivo

MPAY (Mercandu Pay / n1co) es una plataforma Buy Now Pay Later (BNPL) completa para El Salvador y Honduras. Es un monorepo con 5 proyectos independientes que trabajan en conjunto mediante una arquitectura orientada a eventos.

Aspecto Detalle
Tipo Plataforma BNPL (Compra Ahora, Paga Después)
Stack Principal Laravel 10 (PHP 8.2), Next.js 14, Python 3.13
Base de Datos MySQL 8.0 + Redis
Países El Salvador, Honduras
Arquitectura Event-Driven + Clean Architecture

PARTE 1: C4 MODEL

Nivel 1: Context Diagram (Sistema y Actores)

                                    ┌─────────────────────────────────────────────────────────────────┐
                                    │                      ACTORES EXTERNOS                           │
                                    └─────────────────────────────────────────────────────────────────┘

     ┌──────────────┐        ┌──────────────┐        ┌──────────────┐        ┌──────────────┐
     │   CLIENTE    │        │   COMERCIO   │        │ ADMINISTRADOR│        │   SISTEMAS   │
     │   (Usuario)  │        │  (Merchant)  │        │   (Admin)    │        │   EXTERNOS   │
     └──────┬───────┘        └──────┬───────┘        └──────┬───────┘        └──────┬───────┘
            │                       │                       │                       │
            │ Solicita crédito      │ Integra API           │ Gestiona              │
            │ Realiza pagos         │ Recibe webhooks       │ operaciones           │
            │                       │                       │                       │
            ▼                       ▼                       ▼                       ▼
    ┌───────────────────────────────────────────────────────────────────────────────────────┐
    │                                                                                       │
    │                              PLATAFORMA MPAY                                          │
    │                                                                                       │
    │   ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐                 │
    │   │ ONBOARDING  │  │ API-LARAVEL │  │ BACK-OFFICE │  │DOCUMENTS-OCR│                 │
    │   │  (Next.js)  │  │  (Laravel)  │  │  (Nova)     │  │  (Python)   │                 │
    │   └─────────────┘  └─────────────┘  └─────────────┘  └─────────────┘                 │
    │                                                                                       │
    └───────────────────────────────────────────────────────────────────────────────────────┘
            │                       │                       │                       │
            ▼                       ▼                       ▼                       ▼
    ┌──────────────┐        ┌──────────────┐        ┌──────────────┐        ┌──────────────┐
    │   EQUIFAX    │        │   TWILIO     │        │  KEYCLOAK    │        │GOOGLE GEMINI │
    │ (Buro Créd.) │        │   (SMS)      │        │   (SSO)      │        │   (AI/OCR)   │
    └──────────────┘        └──────────────┘        └──────────────┘        └──────────────┘

Actores del Sistema

Actor Rol Interacción
Cliente (Usuario) Solicitante de crédito BNPL Solicita crédito, sube documentos, realiza pagos
Comercio (Merchant) Tienda integrada Crea órdenes vía API, recibe webhooks de estado
Administrador Operador interno Aprueba créditos, gestiona mora, ajusta órdenes
Equifax Buró de crédito Evalúa riesgo crediticio del cliente
Twilio/Tigo/ConceptoMóvil SMS Gateway Envía códigos OTP y recordatorios
Keycloak Identity Provider Autenticación SSO para administradores
Google Gemini AI Servicio de IA OCR inteligente de documentos DUI
H4B Payment Gateway Procesa pagos de clientes

Nivel 2: Container Diagram (Servicios)

┌────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                    PLATAFORMA MPAY                                                 │
├────────────────────────────────────────────────────────────────────────────────────────────────────┤
│                                                                                                    │
│  ┌─────────────────────────────────────────────────────────────────────────────────────────────┐  │
│  │                                    FRONTEND LAYER                                            │  │
│  │                                                                                              │  │
│  │   ┌───────────────────────────────────┐                                                     │  │
│  │   │         ONBOARDING                │  Next.js 14 + React 18 + TypeScript                 │  │
│  │   │         Puerto: 3000              │  Flujo de solicitud de crédito (10 pasos)           │  │
│  │   │         /onboarding/*             │  Validación con Zod, UI con Radix + Tailwind        │  │
│  │   └───────────────────────────────────┘                                                     │  │
│  │                      │                                                                       │  │
│  └──────────────────────┼──────────────────────────────────────────────────────────────────────┘  │
│                         │ HTTP REST                                                               │
│                         ▼                                                                         │
│  ┌─────────────────────────────────────────────────────────────────────────────────────────────┐  │
│  │                                    BACKEND LAYER                                             │  │
│  │                                                                                              │  │
│  │   ┌───────────────────────────────────┐    ┌───────────────────────────────────┐            │  │
│  │   │         API-LARAVEL               │    │         BACK-OFFICE               │            │  │
│  │   │         Puerto: 8051              │    │         Puerto: 80                │            │  │
│  │   │         /api/v1/*                 │    │         /api/v1/equifax/*         │            │  │
│  │   │                                   │    │         /nova/*                   │            │  │
│  │   │  • API principal para comercios   │    │  • Panel administrativo Nova      │            │  │
│  │   │  • OAuth2 (Laravel Passport)      │    │  • Integración COMPLETA Equifax   │            │  │
│  │   │  • Gestión de órdenes/pagos       │    │  • Motor de reglas de decisión    │            │  │
│  │   │  • Laravel Octane (Swoole)        │    │  • Keycloak SSO                   │            │  │
│  │   │  • Laravel Horizon (Queues)       │    │  • Inertia.js + Vue 3             │            │  │
│  │   └───────────────────────────────────┘    └───────────────────────────────────┘            │  │
│  │                      │                                    │                                  │  │
│  │                      └──────────────┬─────────────────────┘                                  │  │
│  │                                     │                                                        │  │
│  └─────────────────────────────────────┼────────────────────────────────────────────────────────┘  │
│                                        ▼                                                          │
│  ┌─────────────────────────────────────────────────────────────────────────────────────────────┐  │
│  │                                    MICROSERVICES                                             │  │
│  │                                                                                              │  │
│  │   ┌───────────────────────────────────┐                                                     │  │
│  │   │       DOCUMENTS-OCR               │  Python 3.13 + FastAPI                              │  │
│  │   │       Puerto: 8000                │  Google Gemini AI (gemini-2.5-flash)                │  │
│  │   │       /extract/dui                │  Extracción automática de datos DUI                 │  │
│  │   └───────────────────────────────────┘                                                     │  │
│  │                                                                                              │  │
│  └──────────────────────────────────────────────────────────────────────────────────────────────┘  │
│                                        │                                                          │
│  ┌─────────────────────────────────────┼────────────────────────────────────────────────────────┐  │
│  │                                    DATA LAYER                                                │  │
│  │                                     ▼                                                        │  │
│  │   ┌───────────────────────────────────┐    ┌───────────────────────────────────┐            │  │
│  │   │         MySQL 8.0                 │    │         Redis                     │            │  │
│  │   │         Puerto: 3306              │    │         Puerto: 6379              │            │  │
│  │   │                                   │    │                                   │            │  │
│  │   │  • 50+ tablas                     │    │  • Cache                          │            │  │
│  │   │  • 88 migraciones                 │    │  • Queues (Horizon)               │            │  │
│  │   │  • Esquema compartido             │    │  • Sesiones                       │            │  │
│  │   │    (database-laravel)             │    │                                   │            │  │
│  │   └───────────────────────────────────┘    └───────────────────────────────────┘            │  │
│  │                                                                                              │  │
│  │   ┌───────────────────────────────────┐                                                     │  │
│  │   │    Google Cloud Storage (GCS)     │  Almacenamiento de documentos (DUI, selfies)        │  │
│  │   └───────────────────────────────────┘                                                     │  │
│  │                                                                                              │  │
│  └──────────────────────────────────────────────────────────────────────────────────────────────┘  │
│                                                                                                    │
└────────────────────────────────────────────────────────────────────────────────────────────────────┘

Containers (Servicios)

Container Tecnología Puerto Responsabilidad
onboarding Next.js 14 + React 18 3000 App de solicitud de crédito (10 pasos)
api-laravel Laravel 10 + Octane 8051 API principal para comercios (OAuth2)
back-office Laravel 10 + Nova 4 80 Panel admin + Integración Equifax
documents-ocr Python 3.13 + FastAPI 8000 OCR de DUI con Gemini AI
database-laravel Laravel Package N/A Migraciones compartidas (88 migrations)
MySQL MySQL 8.0 3306 Base de datos relacional (50+ tablas)
Redis Redis Alpine 6379 Cache + Queues + Sessions
GCS Google Cloud Storage N/A Almacenamiento de documentos

Mapa de Dependencias Detallado

                                    ┌─────────────────────────────────────┐
                                    │           ONBOARDING                │
                                    │        (Next.js 14)                 │
                                    │        Puerto: 3000                 │
                                    └──────────────┬──────────────────────┘
                                                   │
                                                   │ HTTP REST
                                                   │ /api/v1/equifax/*
                                                   ▼
┌─────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                         BACK-OFFICE                                             │
│                                      (Laravel 10 + Nova 4)                                      │
│                                         Puerto: 80                                              │
├─────────────────────────────────────────────────────────────────────────────────────────────────┤
│                                                                                                 │
│   Dependencias Internas:                    Dependencias Externas:                              │
│   ┌─────────────────────────┐              ┌─────────────────────────┐                         │
│   │ database-laravel        │◄─────────────┤ Equifax API             │                         │
│   │ (paquete VCS GitLab)    │              │ (OAuth2 + REST)         │                         │
│   └─────────────────────────┘              │ - Búsqueda persona      │                         │
│                                            │ - Pre-calificación      │                         │
│   ┌─────────────────────────┐              │ - Evaluación crediticia │                         │
│   │ nova-components/        │              └─────────────────────────┘                         │
│   │ (4 componentes custom)  │                                                                  │
│   │ - ConditionalBuilder    │              ┌─────────────────────────┐                         │
│   │ - DecisionRuleField     │              │ Keycloak                │                         │
│   │ - PermissionPicker      │              │ (SSO para admins)       │                         │
│   │ - Picker                │              └─────────────────────────┘                         │
│   └─────────────────────────┘                                                                  │
│                                            ┌─────────────────────────┐                         │
│   Servicios:                               │ Documents-OCR           │                         │
│   ├─ EquifaxService                        │ (POST /extract/dui)     │                         │
│   ├─ DocumentOCR                           └─────────────────────────┘                         │
│   ├─ MercanduCoreService                                                                       │
│   └─ MixpanelService                       ┌─────────────────────────┐                         │
│                                            │ Mercandu Core API       │                         │
│                                            │ (plataforma principal)  │                         │
│                                            └─────────────────────────┘                         │
│                                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────────────────────┘
                                                   │
                                                   │ Comparte esquema DB
                                                   ▼
┌─────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                         API-LARAVEL                                             │
│                                      (Laravel 10 + Octane)                                      │
│                                         Puerto: 8051                                            │
├─────────────────────────────────────────────────────────────────────────────────────────────────┤
│                                                                                                 │
│   Dependencias Internas:                    Dependencias Externas:                              │
│   ┌─────────────────────────┐              ┌─────────────────────────┐                         │
│   │ database-laravel        │              │ Twilio                  │                         │
│   │ (paquete VCS GitLab)    │              │ (SMS Global)            │                         │
│   └─────────────────────────┘              └─────────────────────────┘                         │
│                                                                                                 │
│   APIs Expuestas:                          ┌─────────────────────────┐                         │
│   ├─ POST /api/v1/customers                │ Tigo                    │                         │
│   ├─ POST /api/v1/orders                   │ (SMS SV/HN)             │                         │
│   ├─ POST /api/v1/payments                 └─────────────────────────┘                         │
│   └─ GET /api/v1/products                                                                      │
│                                            ┌─────────────────────────┐                         │
│   Managers:                                │ Concepto Móvil          │                         │
│   ├─ AmortizationManager                   │ (SMS multi-país)        │                         │
│   ├─ OrderManager                          └─────────────────────────┘                         │
│   ├─ PaymentManager                                                                            │
│   └─ AmountDecisionManager                 ┌─────────────────────────┐                         │
│                                            │ H4B                     │                         │
│   Jobs (Horizon):                          │ (Payment Gateway)       │                         │
│   ├─ ProcessingPayments                    └─────────────────────────┘                         │
│   ├─ CalculateInstallmentsInDue                                                                │
│   ├─ CalculateInstallmentsInArrears        ┌─────────────────────────┐                         │
│   └─ SendPaymentReminders                  │ AWS S3 / GCS            │                         │
│                                            │ (Almacenamiento)        │                         │
│   Webhooks Salientes:                      └─────────────────────────┘                         │
│   ├─ order_state_changed                                                                       │
│   └─ installment_state_changed             ┌─────────────────────────┐                         │
│                                            │ Keycloak                │                         │
│                                            │ (OAuth2)                │                         │
│                                            └─────────────────────────┘                         │
│                                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────────────────────┘
                                                   │
                                                   │ Comparte esquema DB
                                                   ▼
┌─────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                       DATABASE-LARAVEL                                          │
│                                      (Paquete Composer)                                         │
├─────────────────────────────────────────────────────────────────────────────────────────────────┤
│                                                                                                 │
│   Contenido:                                                                                    │
│   ├─ 88 migraciones                                                                            │
│   ├─ 50+ tablas                                                                                │
│   ├─ 4 vistas SQL                                                                              │
│   └─ ServiceProvider Laravel                                                                   │
│                                                                                                 │
│   Dominios:                                                                                     │
│   ├─ Customer (customers, documents, personal_information)                                     │
│   ├─ Order (orders, installments, repayments, adjustments)                                     │
│   ├─ Payment (payments, processing_payments, capital_registers)                                │
│   ├─ Product (products, periods, amounts, levels)                                              │
│   ├─ Credit (equifax_requests, decision_rules, loans)                                          │
│   ├─ OAuth (oauth_clients, oauth_access_tokens)                                                │
│   └─ Admin (users, roles, permissions, disbursements)                                          │
│                                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────────────────────┘
                                                   │
                                                   ▼
┌─────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                       DOCUMENTS-OCR                                             │
│                                    (Python 3.13 + FastAPI)                                      │
│                                         Puerto: 8000                                            │
├─────────────────────────────────────────────────────────────────────────────────────────────────┤
│                                                                                                 │
│   Endpoints:                               Dependencias Externas:                               │
│   ├─ GET /health                           ┌─────────────────────────┐                         │
│   └─ POST /extract/dui                     │ Google Gemini AI        │                         │
│                                            │ (gemini-2.5-flash)      │                         │
│   Datos Extraídos del DUI:                 │ - Vision OCR            │                         │
│   ├─ number (número DUI)                   └─────────────────────────┘                         │
│   ├─ surname (apellidos)                                                                       │
│   ├─ given_names (nombres)                 ┌─────────────────────────┐                         │
│   ├─ issuance_date                         │ Google Cloud Storage    │                         │
│   └─ expiration_date                       │ (lectura de imágenes)   │                         │
│                                            └─────────────────────────┘                         │
│                                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────────────────────┘

Matriz de Dependencias

Servicio Depende de Es consumido por
onboarding back-office API, Mixpanel Usuarios finales
api-laravel database-laravel, MySQL, Redis, Twilio, Tigo, H4B, Keycloak, GCS Comercios (OAuth2)
back-office database-laravel, MySQL, Redis, Equifax, documents-ocr, Keycloak, Mercandu Core Administradores, onboarding
documents-ocr Google Gemini AI, GCS back-office
database-laravel MySQL api-laravel, back-office

PARTE 2: EVENT STORMING

Bounded Contexts Identificados

┌─────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                    BOUNDED CONTEXTS                                             │
├─────────────────────────────────────────────────────────────────────────────────────────────────┤
│                                                                                                 │
│   ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐           │
│   │    IDENTITY &   │  │     CREDIT      │  │      ORDER      │  │    PAYMENT      │           │
│   │   ONBOARDING    │  │   EVALUATION    │  │   MANAGEMENT    │  │   PROCESSING    │           │
│   │                 │  │                 │  │                 │  │                 │           │
│   │ • Customer      │  │ • EquifaxRequest│  │ • Order         │  │ • Payment       │           │
│   │ • Document      │  │ • DecisionRule  │  │ • Installment   │  │ • ProcessingPmt │           │
│   │ • Verification  │  │ • AmountCustomer│  │ • OrderRepayment│  │ • CapitalRegister│          │
│   └─────────────────┘  └─────────────────┘  └─────────────────┘  └─────────────────┘           │
│                                                                                                 │
│   ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐           │
│   │   COLLECTION    │  │    PRODUCT      │  │    COMMERCE     │  │ ADMINISTRATION  │           │
│   │   & ARREARS     │  │    CATALOG      │  │  INTEGRATION    │  │                 │           │
│   │                 │  │                 │  │                 │  │                 │           │
│   │ • Jobs de mora  │  │ • Product       │  │ • Client(OAuth) │  │ • User          │           │
│   │ • Recordatorios │  │ • Period        │  │ • Webhooks      │  │ • Disbursement  │           │
│   │ • Notificaciones│  │ • Amount/Level  │  │ • H4B Gateway   │  │ • SourceCustomer│           │
│   └─────────────────┘  └─────────────────┘  └─────────────────┘  └─────────────────┘           │
│                                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────────────────────┘

Flujo 1: Customer Onboarding (Registro de Cliente)

┌─────────────────────────────────────────────────────────────────────────────────────────────────┐
│                              FLUJO: CUSTOMER ONBOARDING                                         │
├─────────────────────────────────────────────────────────────────────────────────────────────────┤
│                                                                                                 │
│  ACTOR: Cliente                             SISTEMA: onboarding + back-office                   │
│                                                                                                 │
│  ┌──────────┐    ┌────────────────────────────────────────────────────────────────────────┐    │
│  │ COMANDO  │───▶│                         EVENTOS                                        │    │
│  └──────────┘    └────────────────────────────────────────────────────────────────────────┘    │
│                                                                                                 │
│      ┌─────────────────────────────────────────────────────────────────────────────────┐       │
│      │                                                                                  │       │
│      │   📝 CreateCustomer                                                              │       │
│      │         │                                                                        │       │
│      │         ▼                                                                        │       │
│      │   ┌─────────────────┐     ┌─────────────────┐                                   │       │
│      │   │ CustomerCreated │────▶│ GenerateOTP     │                                   │       │
│      │   │   (Observer)    │     │   (Job)         │                                   │       │
│      │   └─────────────────┘     └────────┬────────┘                                   │       │
│      │                                    │                                             │       │
│      │   📝 ValidatePhone                 ▼                                             │       │
│      │         │              ┌─────────────────────┐                                   │       │
│      │         ▼              │ OTPSent             │                                   │       │
│      │   ┌─────────────────┐  │ (Twilio/Tigo/CM)    │                                   │       │
│      │   │ PhoneValidation │◀─┴─────────────────────┘                                   │       │
│      │   │  Requested      │                                                            │       │
│      │   └────────┬────────┘                                                            │       │
│      │            │                                                                     │       │
│      │   📝 VerifyPhone                                                                 │       │
│      │         │                                                                        │       │
│      │         ▼                                                                        │       │
│      │   ┌─────────────────┐                                                            │       │
│      │   │ PhoneVerified   │     number_verified = true                                 │       │
│      │   └────────┬────────┘                                                            │       │
│      │            │                                                                     │       │
│      │   📝 UploadDocuments                                                             │       │
│      │         │                                                                        │       │
│      │         ▼                                                                        │       │
│      │   ┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐           │       │
│      │   │ DocumentUploaded│────▶│ ExtractDUIData  │────▶│ DUIDataExtracted│           │       │
│      │   │   (to GCS)      │     │ (documents-ocr) │     │ (Gemini AI)     │           │       │
│      │   └─────────────────┘     └─────────────────┘     └────────┬────────┘           │       │
│      │                                                            │                     │       │
│      │   📝 SavePersonalInfo                                      │                     │       │
│      │         │                                                  │                     │       │
│      │         ▼                                                  ▼                     │       │
│      │   ┌─────────────────┐     ┌─────────────────────────────────┐                   │       │
│      │   │ PersonalInfo    │     │ Auto-fill from OCR:             │                   │       │
│      │   │   Saved         │◀────│ - number, surname, given_names  │                   │       │
│      │   └────────┬────────┘     │ - issuance_date, expiration_date│                   │       │
│      │            │              └─────────────────────────────────┘                   │       │
│      │            ▼                                                                     │       │
│      │   ┌─────────────────┐                                                            │       │
│      │   │ OnboardingReady │     Listo para evaluación Equifax                         │       │
│      │   │   ForEvaluation │                                                            │       │
│      │   └─────────────────┘                                                            │       │
│      │                                                                                  │       │
│      └─────────────────────────────────────────────────────────────────────────────────┘       │
│                                                                                                 │
│  PASOS DEL ONBOARDING (Next.js):                                                               │
│  1. Welcome → 2. Login (DUI+tel) → 3. OTP → 4. Consent → 5. General Data                       │
│  6. Work Data → 7. Documents → 8. References → 9. Evaluation → 10. Result                      │
│                                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────────────────────┘

Flujo 2: Credit Evaluation (Evaluación Crediticia)

┌─────────────────────────────────────────────────────────────────────────────────────────────────┐
│                              FLUJO: CREDIT EVALUATION (EQUIFAX)                                 │
├─────────────────────────────────────────────────────────────────────────────────────────────────┤
│                                                                                                 │
│  ACTOR: Sistema (back-office)              EXTERNO: Equifax API                                 │
│                                                                                                 │
│  Estados (EquifaxRequestStep):                                                                  │
│  ┌────────────────────────────────────────────────────────────────────────────────────────┐    │
│  │ CREATED → SEARCH → CONSENT → SAVE_PERSONAL_DATA → SAVE_WORK_DATA → SAVE_DOCUMENTS      │    │
│  │        → CREATE_REQUEST → CREATE_CONSENT → SAVE_PERSONAL_DATA_EQUIFAX                  │    │
│  │        → SAVE_DOCUMENTS_EQUIFAX → EVALUATION → [APPEAL]                                │    │
│  └────────────────────────────────────────────────────────────────────────────────────────┘    │
│                                                                                                 │
│  ┌─────────────────────────────────────────────────────────────────────────────────────┐       │
│  │                                                                                      │       │
│  │   📝 SearchPersonInEquifax                                                           │       │
│  │         │                                                                            │       │
│  │         ▼                                                                            │       │
│  │   ┌─────────────────┐     ┌─────────────────────────────────────────┐               │       │
│  │   │ PersonFound     │────▶│ Equifax API: /searchPerson              │               │       │
│  │   │  (step=SEARCH)  │     │ Busca por DUI en buró de crédito        │               │       │
│  │   └────────┬────────┘     └─────────────────────────────────────────┘               │       │
│  │            │                                                                         │       │
│  │   📝 RegisterConsent                                                                 │       │
│  │         │                                                                            │       │
│  │         ▼                                                                            │       │
│  │   ┌─────────────────┐     ┌─────────────────────────────────────────┐               │       │
│  │   │ ConsentSaved    │────▶│ Firma digital del cliente               │               │       │
│  │   │  (step=CONSENT) │     │ Almacena en GCS + Equifax               │               │       │
│  │   └────────┬────────┘     └─────────────────────────────────────────┘               │       │
│  │            │                                                                         │       │
│  │   📝 SaveDataToEquifax                                                               │       │
│  │         │                                                                            │       │
│  │         ▼                                                                            │       │
│  │   ┌─────────────────┐     ┌─────────────────────────────────────────┐               │       │
│  │   │ DataSentTo      │────▶│ Envía a Equifax:                        │               │       │
│  │   │   Equifax       │     │ • Datos personales                      │               │       │
│  │   │  (steps 7-10)   │     │ • Datos laborales                       │               │       │
│  │   └────────┬────────┘     │ • Documentos (DUI, selfie)              │               │       │
│  │            │              └─────────────────────────────────────────┘               │       │
│  │   📝 RunEvaluation                                                                   │       │
│  │         │                                                                            │       │
│  │         ▼                                                                            │       │
│  │   ┌─────────────────┐     ┌─────────────────────────────────────────┐               │       │
│  │   │ EvaluationRun   │────▶│ Equifax API: /evaluation                │               │       │
│  │   │  (step=EVAL)    │     │ Retorna: score, variables de decisión   │               │       │
│  │   └────────┬────────┘     └─────────────────────────────────────────┘               │       │
│  │            │                                                                         │       │
│  │   📝 ApplyDecisionRules                                                              │       │
│  │         │                                                                            │       │
│  │         ▼                                                                            │       │
│  │   ┌─────────────────┐     ┌─────────────────────────────────────────┐               │       │
│  │   │ DecisionMade    │────▶│ Motor de reglas (Symfony Expression)    │               │       │
│  │   │                 │     │ Evalúa: score, ingresos, deuda, etc.    │               │       │
│  │   └────────┬────────┘     └─────────────────────────────────────────┘               │       │
│  │            │                                                                         │       │
│  │            ├──────────────────────┬──────────────────────┐                          │       │
│  │            ▼                      ▼                      ▼                          │       │
│  │   ┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐                │       │
│  │   │ CreditApproved  │    │ CreditDenied    │    │ CreditInProcess │                │       │
│  │   │ decision=       │    │ decision=       │    │ decision=       │                │       │
│  │   │   APPROVED      │    │   DENIED        │    │   IN_PROCESS    │                │       │
│  │   └────────┬────────┘    └────────┬────────┘    └────────┬────────┘                │       │
│  │            │                      │                      │                          │       │
│  │            ▼                      ▼                      ▼                          │       │
│  │   ┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐                │       │
│  │   │ AmountCustomer  │    │ CreditReject    │    │ ManualReview    │                │       │
│  │   │   Created       │    │  Notification   │    │   Required      │                │       │
│  │   │ (límite asign.) │    │   (Email)       │    │                 │                │       │
│  │   └─────────────────┘    └─────────────────┘    └─────────────────┘                │       │
│  │                                                                                      │       │
│  └─────────────────────────────────────────────────────────────────────────────────────┘       │
│                                                                                                 │
│  DECISIONES POSIBLES:                                                                          │
│  • APPROVED - Crédito aprobado, se asigna AmountCustomer                                       │
│  • DENIED - Crédito rechazado                                                                  │
│  • IN_PROCESS - Requiere revisión manual                                                       │
│  • EXPIRED - Solicitud expirada                                                                │
│  • REJECTED - Rechazado manualmente por admin                                                  │
│                                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────────────────────┘

Flujo 3: Order Creation (Creación de Orden BNPL)

┌─────────────────────────────────────────────────────────────────────────────────────────────────┐
│                              FLUJO: ORDER CREATION                                              │
├─────────────────────────────────────────────────────────────────────────────────────────────────┤
│                                                                                                 │
│  ACTOR: Comercio (via OAuth2)              SISTEMA: api-laravel                                 │
│                                                                                                 │
│  Estados de Order (OrderState):                                                                 │
│  ┌────────────────────────────────────────────────────────────────────────────────────────┐    │
│  │ ACTIVE ←→ PROCESSING_PAYMENT → PAID                                                    │    │
│  │   ↓                                                                                    │    │
│  │  DUE → IN_ARREARS                                                                      │    │
│  │   ↓                                                                                    │    │
│  │ CANCEL                                                                                 │    │
│  └────────────────────────────────────────────────────────────────────────────────────────┘    │
│                                                                                                 │
│  ┌─────────────────────────────────────────────────────────────────────────────────────┐       │
│  │                                                                                      │       │
│  │   📝 PreviewOrder (opcional)                                                         │       │
│  │         │          POST /api/v1/orders/preview                                       │       │
│  │         ▼                                                                            │       │
│  │   ┌─────────────────┐     ┌─────────────────────────────────────────┐               │       │
│  │   │ AmortizationCalc│────▶│ AmortizationManager:                    │               │       │
│  │   │   ulated        │     │ • Calcula cuotas (principal+interés+IVA)│               │       │
│  │   │                 │     │ • Tipos fee: COMPOUND, AMOUNT, %        │               │       │
│  │   └─────────────────┘     └─────────────────────────────────────────┘               │       │
│  │                                                                                      │       │
│  │   📝 CreateOrder                                                                     │       │
│  │         │          POST /api/v1/orders                                               │       │
│  │         ▼                                                                            │       │
│  │   ┌─────────────────┐     ┌─────────────────────────────────────────┐               │       │
│  │   │ OrderCreating   │────▶│ Observer: OrderObserver::creating       │               │       │
│  │   │                 │     │ • Asigna recurrence_number              │               │       │
│  │   └────────┬────────┘     └─────────────────────────────────────────┘               │       │
│  │            │                                                                         │       │
│  │            ▼                                                                         │       │
│  │   ┌─────────────────┐                                                                │       │
│  │   │ OrderCreated    │     Observer: OrderObserver::created                           │       │
│  │   │ status=ACTIVE   │                                                                │       │
│  │   └────────┬────────┘                                                                │       │
│  │            │                                                                         │       │
│  │            ├─────────────────────────────────────────────────────────┐              │       │
│  │            │                                                         │              │       │
│  │            ▼                                                         ▼              │       │
│  │   ┌─────────────────┐                                       ┌─────────────────┐     │       │
│  │   │ CapitalRegister │  amount = -disbursement_amount        │ Installments    │     │       │
│  │   │   Created       │  (registro de desembolso negativo)    │   Generated     │     │       │
│  │   │   (negativo)    │                                       │ (N cuotas)      │     │       │
│  │   └─────────────────┘                                       └────────┬────────┘     │       │
│  │                                                                      │              │       │
│  │                                                                      ▼              │       │
│  │                                                             ┌─────────────────┐     │       │
│  │                                                             │ FirstInstallment│     │       │
│  │                                                             │   Activated     │     │       │
│  │                                                             │ status=ACTIVE   │     │       │
│  │                                                             └────────┬────────┘     │       │
│  │                                                                      │              │       │
│  │   📤 WebhookDispatched                                               │              │       │
│  │            │                                                         │              │       │
│  │            ▼                                                         ▼              │       │
│  │   ┌─────────────────┐                                       ┌─────────────────┐     │       │
│  │   │ order_created   │  → Comercio webhook_url               │ CreateOrder     │     │       │
│  │   │   (webhook)     │  Payload: customer_uuid, order_uuid,  │  Notification   │     │       │
│  │   │                 │           order_status, period_uuid   │ (Email cliente) │     │       │
│  │   └─────────────────┘                                       └─────────────────┘     │       │
│  │                                                                                      │       │
│  └─────────────────────────────────────────────────────────────────────────────────────┘       │
│                                                                                                 │
│  ESTRUCTURA DE INSTALLMENT:                                                                    │
│  ┌────────────────────────────────────────────────────────────────────────────────────────┐    │
│  │ number | amount | principal | interest | vat_interest | debt | fee | status | expired_at│   │
│  │   1    │ $50.00 │  $45.00   │  $4.50   │    $0.50     │ $0   │ $0  │ ACTIVE │ 2024-02-15│   │
│  │   2    │ $50.00 │  $45.50   │  $4.00   │    $0.50     │ $0   │ $0  │ PENDING│ 2024-03-15│   │
│  │   3    │ $50.00 │  $46.00   │  $3.50   │    $0.50     │ $0   │ $0  │ PENDING│ 2024-04-15│   │
│  └────────────────────────────────────────────────────────────────────────────────────────┘    │
│                                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────────────────────┘

Flujo 4: Payment Processing (Procesamiento de Pagos)

┌─────────────────────────────────────────────────────────────────────────────────────────────────┐
│                              FLUJO: PAYMENT PROCESSING                                          │
├─────────────────────────────────────────────────────────────────────────────────────────────────┤
│                                                                                                 │
│  ACTOR: Cliente / Gateway H4B              SISTEMA: api-laravel                                 │
│                                                                                                 │
│  Estados de Payment (PaymentState):                                                             │
│  ┌────────────────────────────────────────────────────────────────────────────────────────┐    │
│  │ PENDING → CONFIRMED → SUCCESS                                                          │    │
│  └────────────────────────────────────────────────────────────────────────────────────────┘    │
│                                                                                                 │
│  ┌─────────────────────────────────────────────────────────────────────────────────────┐       │
│  │                                                                                      │       │
│  │   📝 CreatePayment                                                                   │       │
│  │         │          POST /customers/{uuid}/orders/{id}/pay                            │       │
│  │         ▼                                                                            │       │
│  │   ┌─────────────────┐                                                                │       │
│  │   │ PaymentCreated  │     status = PENDING                                           │       │
│  │   │                 │     Crea ProcessingPayment en cola                             │       │
│  │   └────────┬────────┘                                                                │       │
│  │            │                                                                         │       │
│  │   ⏰ Job: ProcessingPayments (cada minuto)                                           │       │
│  │            │                                                                         │       │
│  │            ▼                                                                         │       │
│  │   ┌─────────────────┐     ┌─────────────────────────────────────────┐               │       │
│  │   │ GatewayQueried  │────▶│ Consulta estado en H4B/STRIPE           │               │       │
│  │   │                 │     │ Si confirmado → status = CONFIRMED      │               │       │
│  │   └────────┬────────┘     └─────────────────────────────────────────┘               │       │
│  │            │                                                                         │       │
│  │            ▼                                                                         │       │
│  │   ┌─────────────────┐                                                                │       │
│  │   │ PaymentConfirmed│     status = SUCCESS                                           │       │
│  │   │                 │     Observer: PaymentObserver::updated                         │       │
│  │   └────────┬────────┘                                                                │       │
│  │            │                                                                         │       │
│  │            ├─────────────────────────────────────────────────────────┐              │       │
│  │            │                                                         │              │       │
│  │            ▼                                                         ▼              │       │
│  │   ┌─────────────────┐                                       ┌─────────────────┐     │       │
│  │   │ CapitalRegister │  amount = +confirmed_amount           │ AllocateDebtTo  │     │       │
│  │   │   Created       │  (registro de ingreso positivo)       │  Installment    │     │       │
│  │   │   (positivo)    │                                       │   (Job async)   │     │       │
│  │   └─────────────────┘                                       └────────┬────────┘     │       │
│  │                                                                      │              │       │
│  │   LÓGICA DE DISTRIBUCIÓN DE PAGO:                                    │              │       │
│  │   ┌────────────────────────────────────────────────────────┐         │              │       │
│  │   │ Orden de aplicación:                                   │         │              │       │
│  │   │ 1. Deuda acumulada (debt + vat_debt)                  │         │              │       │
│  │   │ 2. Cargos por mora (fee + vat_fee)                    │         │              │       │
│  │   │ 3. Intereses (interest + vat_interest)                │         │              │       │
│  │   │ 4. Principal                                          │         │              │       │
│  │   └────────────────────────────────────────────────────────┘         │              │       │
│  │                                                                      │              │       │
│  │                                                                      ▼              │       │
│  │                                                             ┌─────────────────┐     │       │
│  │                                                             │ OrderRepayment  │     │       │
│  │                                                             │   Created       │     │       │
│  │                                                             │ (por cada cuota)│     │       │
│  │                                                             └────────┬────────┘     │       │
│  │                                                                      │              │       │
│  │                                                                      ▼              │       │
│  │   Si cuota totalmente pagada:                               ┌─────────────────┐     │       │
│  │                                                             │ InstallmentPaid │     │       │
│  │                                                             │ status=PAID     │     │       │
│  │                                                             └────────┬────────┘     │       │
│  │                                                                      │              │       │
│  │   Observer: InstallmentObserver::updated                             │              │       │
│  │            │                                                         │              │       │
│  │            ├─────────────────────────────────────────────────────────┤              │       │
│  │            │                                                         │              │       │
│  │            ▼                                                         ▼              │       │
│  │   ┌─────────────────┐                                       ┌─────────────────┐     │       │
│  │   │ NextInstallment │  Activa siguiente cuota               │ installment_    │     │       │
│  │   │   Activated     │  (status PENDING → ACTIVE)            │ state_changed   │     │       │
│  │   └─────────────────┘                                       │   (webhook)     │     │       │
│  │                                                             └─────────────────┘     │       │
│  │                                                                                      │       │
│  │   Si TODAS las cuotas pagadas:                                                       │       │
│  │            │                                                                         │       │
│  │            ▼                                                                         │       │
│  │   ┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐               │       │
│  │   │ OrderFullyPaid  │────▶│ UpgradeLevel    │────▶│ order_state_    │               │       │
│  │   │ status=PAID     │     │   (Job async)   │     │   changed       │               │       │
│  │   │                 │     │ Sube nivel      │     │   (webhook)     │               │       │
│  │   └────────┬────────┘     │ crediticio      │     └─────────────────┘               │       │
│  │            │              └─────────────────┘                                        │       │
│  │            ▼                                                                         │       │
│  │   ┌─────────────────┐                                                                │       │
│  │   │ ApprovedPayment │     Notificación Email al cliente                              │       │
│  │   │  Notification   │                                                                │       │
│  │   └─────────────────┘                                                                │       │
│  │                                                                                      │       │
│  └─────────────────────────────────────────────────────────────────────────────────────┘       │
│                                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────────────────────┘

Flujo 5: Collection & Arrears (Gestión de Mora)

┌─────────────────────────────────────────────────────────────────────────────────────────────────┐
│                              FLUJO: COLLECTION & ARREARS MANAGEMENT                             │
├─────────────────────────────────────────────────────────────────────────────────────────────────┤
│                                                                                                 │
│  ACTOR: Sistema (Jobs programados)         SISTEMA: api-laravel                                 │
│                                                                                                 │
│  Estados de Installment (InstallmentState):                                                     │
│  ┌────────────────────────────────────────────────────────────────────────────────────────┐    │
│  │ PENDING → ACTIVE → DUE → IN_ARREARS                                                    │    │
│  │                 ↘      ↘                                                               │    │
│  │                  PAID   PAID (con mora)                                                │    │
│  └────────────────────────────────────────────────────────────────────────────────────────┘    │
│                                                                                                 │
│  ┌─────────────────────────────────────────────────────────────────────────────────────┐       │
│  │                                                                                      │       │
│  │   ⏰ RECORDATORIOS PRE-VENCIMIENTO                                                   │       │
│  │                                                                                      │       │
│  │   Job: SendPaymentReminders (diario, 9 AM)                                           │       │
│  │         │                                                                            │       │
│  │         ▼                                                                            │       │
│  │   ┌─────────────────┐                                                                │       │
│  │   │ PaymentReminder │     SMS + Email al cliente                                     │       │
│  │   │   Sent          │     Días antes: 5, 3, 1, 0 (día de vencimiento)                │       │
│  │   └─────────────────┘                                                                │       │
│  │                                                                                      │       │
│  │   ═══════════════════════════════════════════════════════════════════════════════   │       │
│  │                                                                                      │       │
│  │   ⏰ MARCADO DE CUOTAS VENCIDAS                                                      │       │
│  │                                                                                      │       │
│  │   Job: CalculateInstallmentsInDue (diario, 2 AM)                                     │       │
│  │         │                                                                            │       │
│  │         ▼                                                                            │       │
│  │   ┌─────────────────┐     Criterio: expired_at <= yesterday()                        │       │
│  │   │ InstallmentDue  │     status: ACTIVE → DUE                                       │       │
│  │   │                 │                                                                │       │
│  │   └────────┬────────┘                                                                │       │
│  │            │                                                                         │       │
│  │            ├─────────────────────────────────────────────────────────┐              │       │
│  │            │                                                         │              │       │
│  │            ▼                                                         ▼              │       │
│  │   ┌─────────────────┐                                       ┌─────────────────┐     │       │
│  │   │ Order.status    │     status: ACTIVE → DUE              │ NextInstallment │     │       │
│  │   │   = DUE         │                                       │   Activated     │     │       │
│  │   └─────────────────┘                                       └────────┬────────┘     │       │
│  │                                                                      │              │       │
│  │            ▼                                                         ▼              │       │
│  │   ┌─────────────────┐                                       ┌─────────────────┐     │       │
│  │   │ installment_    │     Webhook al comercio               │ InstallmentStatus│    │       │
│  │   │ state_changed   │                                       │  ChangeNotif     │    │       │
│  │   │   (webhook)     │                                       │ (Email admin)    │    │       │
│  │   └─────────────────┘                                       └─────────────────┘     │       │
│  │                                                                                      │       │
│  │   ═══════════════════════════════════════════════════════════════════════════════   │       │
│  │                                                                                      │       │
│  │   ⏰ PERÍODO DE GRACIA                                                               │       │
│  │                                                                                      │       │
│  │   Job: SendGracePeriodReminder (diario, 10 AM)                                       │       │
│  │         │                                                                            │       │
│  │         ▼                                                                            │       │
│  │   ┌─────────────────┐                                                                │       │
│  │   │ GracePeriod     │     SMS + Email al cliente                                     │       │
│  │   │ ReminderSent    │     "Tienes X días para pagar sin mora adicional"              │       │
│  │   └─────────────────┘                                                                │       │
│  │                                                                                      │       │
│  │   ═══════════════════════════════════════════════════════════════════════════════   │       │
│  │                                                                                      │       │
│  │   ⏰ MARCADO DE CUOTAS EN MORA                                                       │       │
│  │                                                                                      │       │
│  │   Job: CalculateInstallmentsInArrears (diario, 6 AM)                                 │       │
│  │         │                                                                            │       │
│  │         ▼                                                                            │       │
│  │   ┌─────────────────┐     Criterio: vencida > grace_period días                      │       │
│  │   │ InstallmentIn   │     status: DUE → IN_ARREARS                                   │       │
│  │   │   Arrears       │                                                                │       │
│  │   └────────┬────────┘                                                                │       │
│  │            │                                                                         │       │
│  │            ├─────────────────────────────────────────────────────────┐              │       │
│  │            │                                                         │              │       │
│  │            ▼                                                         ▼              │       │
│  │   ┌─────────────────┐                                       ┌─────────────────┐     │       │
│  │   │ Order.status    │     status: DUE → IN_ARREARS          │ AllocateDebtTo  │     │       │
│  │   │   = IN_ARREARS  │                                       │  Installment    │     │       │
│  │   └─────────────────┘                                       │   (batch job)   │     │       │
│  │                                                             └────────┬────────┘     │       │
│  │            ▼                                                         │              │       │
│  │   ┌─────────────────┐                                                ▼              │       │
│  │   │ installment_    │                                       ┌─────────────────┐     │       │
│  │   │ state_changed   │                                       │ DebtCalculated  │     │       │
│  │   │   (webhook)     │                                       │ fee + vat_fee   │     │       │
│  │   └─────────────────┘                                       │ asignados       │     │       │
│  │                                                             └─────────────────┘     │       │
│  │   ═══════════════════════════════════════════════════════════════════════════════   │       │
│  │                                                                                      │       │
│  │   ⏰ RECORDATORIOS DE MORA                                                           │       │
│  │                                                                                      │       │
│  │   Job: SendLatePaymentReminder (diario, 11 AM)                                       │       │
│  │         │                                                                            │       │
│  │         ▼                                                                            │       │
│  │   ┌─────────────────┐                                                                │       │
│  │   │ LatePayment     │     SMS + Email al cliente                                     │       │
│  │   │ ReminderSent    │     "Tu cuota está vencida. Monto total: $X"                   │       │
│  │   └─────────────────┘                                                                │       │
│  │                                                                                      │       │
│  └─────────────────────────────────────────────────────────────────────────────────────┘       │
│                                                                                                 │
│  CRONOGRAMA DE JOBS:                                                                           │
│  ┌────────────────────────────────────────────────────────────────────────────────────────┐    │
│  │  2:00 AM  │ CalculateInstallmentsInDue      │ Marca cuotas como DUE                   │    │
│  │  6:00 AM  │ CalculateInstallmentsInArrears  │ Marca cuotas como IN_ARREARS            │    │
│  │  9:00 AM  │ SendPaymentReminders            │ Recordatorios pre-vencimiento           │    │
│  │ 10:00 AM  │ SendGracePeriodReminder         │ Recordatorios período de gracia         │    │
│  │ 11:00 AM  │ SendLatePaymentReminder         │ Recordatorios de mora                   │    │
│  │  * * * *  │ ProcessingPayments              │ Cada minuto - procesa pagos pendientes  │    │
│  │  * * * *  │ ProcessingOrderAdjustment       │ Cada minuto - procesa ajustes           │    │
│  └────────────────────────────────────────────────────────────────────────────────────────┘    │
│                                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────────────────────┘

Catálogo de Eventos del Sistema

Eventos de Dominio

Evento Productor Consumidor(es) Payload
CustomerCreated CustomerObserver - customer_id, recurrence_number
PhoneVerified CustomerService - customer_id, phone_number
DocumentUploaded DocumentService documents-ocr document_id, gcs_uri
DUIDataExtracted documents-ocr back-office number, surname, names, dates
EquifaxEvaluationCompleted EquifaxService DecisionRulesEngine score, decision_variables
CreditApproved DecisionRulesEngine AmountCustomerService customer_id, amount, level
CreditDenied DecisionRulesEngine NotificationService customer_id, reason
OrderCreated OrderObserver CapitalRegisterService, NotificationService order_id, amount
InstallmentsGenerated AmortizationManager - order_id, installments[]
PaymentReceived PaymentObserver AllocateDebtJob payment_id, amount
InstallmentPaid InstallmentObserver NextInstallmentActivator installment_id
OrderFullyPaid OrderObserver UpgradeLevelJob order_id, customer_id
InstallmentBecameDue CalculateInstallmentsInDue NotificationService installment_id
InstallmentBecameInArrears CalculateInstallmentsInArrears DebtCalculator installment_id

Webhooks Salientes

Webhook Trigger Payload
order_created OrderObserver::created { event, timestamp, customer_uuid, order_uuid, order_status, period_uuid }
order_state_changed OrderObserver::updated { event, timestamp, customer_uuid, order_uuid, order_status, period_uuid }
installment_state_changed InstallmentObserver::updated { event, timestamp, customer_uuid, order_uuid, installment: { status, amount, number, expired_at } }

Notificaciones

Notificación Canal Trigger
PhoneValidation SMS Solicitud de verificación
PaymentReminder SMS + Email Job diario (5, 3, 1, 0 días antes)
GracePeriodReminder SMS + Email Job diario (durante gracia)
LatePaymentReminder SMS + Email Job diario (en mora)
ApprovedPayment Email Pago exitoso
CreditApprovedNotification Email Crédito aprobado
CreditRejectNotification Email Crédito rechazado

Resumen de Integraciones Externas

┌─────────────────────────────────────────────────────────────────────────────────────────────────┐
│                              MAPA DE INTEGRACIONES EXTERNAS                                     │
├─────────────────────────────────────────────────────────────────────────────────────────────────┤
│                                                                                                 │
│   ┌──────────────┐     ┌──────────────┐     ┌──────────────┐     ┌──────────────┐              │
│   │   EQUIFAX    │     │   KEYCLOAK   │     │   TWILIO     │     │    TIGO      │              │
│   │  (Crédito)   │     │   (SSO)      │     │   (SMS)      │     │  (SMS SV/HN) │              │
│   └──────┬───────┘     └──────┬───────┘     └──────┬───────┘     └──────┬───────┘              │
│          │                    │                    │                    │                       │
│          │ OAuth2 + REST      │ OIDC               │ REST API           │ REST API (XML)        │
│          │                    │                    │                    │                       │
│          ▼                    ▼                    ▼                    ▼                       │
│   ┌─────────────────────────────────────────────────────────────────────────────────────┐      │
│   │                              PLATAFORMA MPAY                                         │      │
│   │                                                                                      │      │
│   │   back-office ◄── Equifax, Keycloak                                                 │      │
│   │   api-laravel ◄── Twilio, Tigo, Concepto Móvil, H4B, Keycloak                       │      │
│   │   documents-ocr ◄── Google Gemini AI, GCS                                           │      │
│   │                                                                                      │      │
│   └─────────────────────────────────────────────────────────────────────────────────────┘      │
│          │                    │                    │                    │                       │
│          ▼                    ▼                    ▼                    ▼                       │
│   ┌──────────────┐     ┌──────────────┐     ┌──────────────┐     ┌──────────────┐              │
│   │CONCEPTO MÓVIL│     │     H4B      │     │ GOOGLE GCS   │     │GOOGLE GEMINI │              │
│   │ (SMS multi)  │     │  (Gateway)   │     │ (Storage)    │     │   (AI/OCR)   │              │
│   └──────────────┘     └──────────────┘     └──────────────┘     └──────────────┘              │
│                                                                                                 │
│   TOTALES:                                                                                      │
│   • 3 servicios SMS (Twilio, Tigo, Concepto Móvil)                                             │
│   • 1 buró de crédito (Equifax)                                                                │
│   • 1 identity provider (Keycloak)                                                              │
│   • 1 payment gateway (H4B)                                                                     │
│   • 1 servicio IA (Google Gemini)                                                              │
│   • 2 cloud storage (GCS, AWS S3)                                                              │
│   • 2 analytics (Mixpanel, Klaviyo - deshabilitado)                                            │
│                                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────────────────────┘

Conclusiones

Fortalezas Arquitectónicas

  1. Separación clara de responsabilidades: Cada servicio tiene un propósito bien definido
  2. Event-driven: Observers y Jobs mantienen el sistema desacoplado
  3. Esquema compartido: database-laravel garantiza consistencia entre servicios
  4. Microservicio especializado: documents-ocr con Gemini AI para OCR inteligente
  5. Multi-canal de notificaciones: SMS + Email con fallbacks por país

Puntos de Atención

  1. Equifax solo en back-office: Toda la integración crediticia está centralizada
  2. Paquete privado GitLab: database-laravel requiere acceso a GitLab
  3. Nova licenciado: back-office requiere licencia Laravel Nova ($199/año)
  4. Sin message broker externo: Redis cubre las necesidades actuales pero podría limitar escalabilidad futura

Métricas del Sistema

Métrica Valor
Servicios 5
Tablas MySQL 50+
Migraciones 88
Jobs programados 7
Notificaciones 23
Integraciones externas 10+
Webhooks salientes 3

Documento generado el 2025-12-19 Análisis realizado con Claude Code (Opus 4.5)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment