Hoja de trabajo semana 4 - martin-hendricks/MISO-PROYECTO-FINAL-SOLVENTA GitHub Wiki
| Proyecto | Solventa — Aseguradora digital |
| Elaboración | Juan Acevedo, John Guerrero, Mauricio Rodriguez, Martin Romero |
| Versión | 1.0 |
| Atributos priorizados | Escalabilidad y Latencia (desempeño) |
| Insumos | Enunciado MISW4501-202614-Proyecto.pdf · |
Consolidado de la semana 4: modelos de arquitectura, diseño detallado con tácticas y patrones, y diseño del experimento de arquitectura.
Diagramas embebidos de las tres vistas actualizadas (funcional, despliegue, información). Si el embebido no se ve bien en tu navegador (los SVG grandes a veces se recortan en la vista de wiki), usa el link "Abrir el SVG completo" debajo de cada uno para verlo en tamaño real con zoom/scroll.
- 1.1 Modelo de contexto
- 1.2 Vista funcional — Modelo de componentes
- 1.3 Vista de despliegue — AWS
- 1.4 Vista de información — Modelo de datos
- 1.5 Arquitectura del portal web (MVVM)
- 1.6 Arquitectura del cliente móvil (Android)
| Proyecto | Solventa — Aseguradora digital |
| ID | VC-001 |
| Elaboración | Juan Acevedo, John Guerrero, Mauricio Rodriguez, Martin Romero |
| Versión | 1.0 |
| Vista | Contexto |
| Modelo | Contexto |
Convención
| 🟩 Sistema a diseñar | Solventa |
| 🟨 Canal | Cliente web, cliente móvil, API embebida |
| 🟦 Sistema externo | Open Finance, Open Data, KYC, pagos, firma, IoT, reaseguro, estándares |
| 👤 Actor | Un nodo por rol × canal (evita cruces) |
Actores por canal
| Canal | Actores | Uso principal |
|---|---|---|
| Cliente web | Asesor / Operaciones, Socio, Peritos, Cliente (escritorio) | Gestión completa y back-office |
| Cliente móvil | Cliente asegurado | Autoservicio: siniestro con evidencia, push, biometría, geo |
| API embebida | Socio de distribución | Cotización / emisión en canal del tercero |

| Proyecto | Solventa — Aseguradora digital |
| ID | VC-002 |
| Elaboración | Juan Acevedo, John Guerrero, Mauricio Rodriguez, Martin Romero |
| Versión | 1.0 |
| Vista | Funcional |
| Modelo | Componentes |
Incluye Consentimiento conectado a los adaptadores de datos externos, el Dominio · Transversal (Documentos, Analítica, Notificaciones) separado de Venta y Operación, e interfaces nombradas (ICotizacion, IPerfilamiento, IPublicacion, ISuscripcion, etc.).
Abrir el SVG completo: files/DiagramaComponentesSolventa.svg
| Proyecto | Solventa — Aseguradora digital |
| ID | VC-003 |
| Elaboración | Juan Acevedo, John Guerrero, Mauricio Rodriguez, Martin Romero |
| Versión | 1.0 |
| Vista | Asignación / Despliegue |
| Modelo | Despliegue |
VPC con subred pública (ALB, WAF, CloudFront) y subredes privadas multi-AZ (EKS con grupos de escalado independientes, RDS PostgreSQL Multi-AZ, ElastiCache Redis, MSK/Kafka), más KMS y Secrets Manager para gestión de credenciales.
Abrir el SVG completo: files/DiagramaDespliegueSolventa.svg
| Proyecto | Solventa — Aseguradora digital |
| ID | VC-004 |
| Elaboración | Juan Acevedo, John Guerrero, Mauricio Rodriguez, Martin Romero |
| Versión | 1.0 |
| Vista | Información / Dominio |
| Modelo | Dominio / Datos (entidad-relación por microservicio) |
Convención
| Rectángulo (entidad) | Entidad del dominio de negocio |
+ atributo |
Campo público / dato de negocio relevante |
--> |
Asociación dirigida entre entidades |
"1", "0..*", "1..*"
|
Cardinalidad de la relación |
| Etiqueta en arista | Rol o verbo de la relación (p. ej. otorga, genera) |
Formato del diagrama
| Lenguaje | Diagrama entidad-relación publicado como SVG |
| Orientación | Agrupado por microservicio |
| Alcance | Entidades y relaciones del caso Solventa (cotización → póliza → siniestro / pago) |
Modelo entidad-relación por microservicio (ms_identidad, ms_consentimiento, ms_cotizacion, ms_perfilamiento, ms_suscripcion, ms_polizas, ms_siniestros, ms_pagos, ms_parametrico, ms_socios, analitica, notificaciones), con claves foráneas cruzando límites de servicio donde aplica.
Abrir el SVG completo: files/ModeloDatosSolventa.svg
Siguiendo la regla del curso de que una vista es un capítulo con varios modelos complementarios, el modelo estático anterior (VC-004) se completó con tres modelos adicionales en el mismo documento Lucid: flujos de información y control, estructuras de datos (contratos) y replicación/consistencia. Los cuatro viven como zonas separadas de una única página en el documento "Solventa - Vista de información: modelo de datos, flujos, estructuras y replicación (VC-004/007/008/009)": ver en Lucidchart.
| ID | VC-007 |
| Vista | Información |
| Modelo | Flujos de información y control |
Dos recorridos críticos anotados con dueño del dato (system of record), síncrono/asíncrono, qué se copia vs. qué solo se referencia, y caché con TTL: (a) perfilamiento y oferta de vida hipotecario (Open Finance/Open Data → adaptadores → ms_perfilamiento → ms_cotizacion → ms_suscripcion → ms_polizas), y (b) siniestro paramétrico automático (:AdaptadorTelemetria → :TopicoTelemetria → :MotorParametrico → ms_parametrico → ms_siniestros → ms_pagos).
| ID | VC-008 |
| Vista | Información |
| Modelo | Estructuras de datos — contratos en tránsito |
Envelope + payload polimórfico del evento canónico por tipoEvento, claves de deduplicación/idempotencia (eventoExternoId, idempotencyKey), política de versionado de esquema hacia atrás, tabla de mapeo semántico a estándares ACORD, y estructura de la proyección de lectura desnormalizada del experimento HA-08.
| ID | VC-009 |
| Vista | Información (se toca con Despliegue; el foco es el dato, no el nodo) |
| Modelo | Replicación y consistencia |
Primaria y réplicas por zona de disponibilidad, réplicas de lectura, bus de eventos y cachés, anclado en las metas de continuidad del caso §6.3 (RTO/RPO por zona y región, disponibilidad de pagos e indemnizaciones, journeys críticos). Clasifica cada dato como consistencia fuerte o eventual con su desfase máximo, documenta el TTL/invalidación de :CacheOF/:CacheOD, la propagación de la revocación de consentimiento (≤ 5 min, habeas data) y el punto de anonimización hacia analitica. Nota: la Hoja de trabajo semana 4 no define escenarios EC-DISP; este modelo se ancla directamente en el caso §6.3.
| Proyecto | Solventa — Aseguradora digital |
| ID | VC-005 |
| Elaboración | Juan Acevedo, John Guerrero, Mauricio Rodriguez, Martin Romero |
| Versión | 1.0 |
| Vista | Desarrollo / capas |
| Modelo | Patrón MVVM del portal web (Angular) |
| Alcance | Solo el canal web (SPA Angular). No cubre el cliente móvil, el BFF ni los microservicios. |
Diagrama de componentes del portal web Angular: View (componentes standalone, sin lógica de negocio) → ViewModel (estado observable con signals, expone loading / ready / degraded / error) → Model (dominio puro, casos de uso y puertos, arquitectura hexagonal en el front). Cada uno de los cinco recorridos críticos (cotización, suscripción y emisión, perfilamiento hipotecario, siniestro asistido, ciclo de vida de póliza) es un feature module con lazy loading.

Abrir en tamaño completo: files/Diagram-web/solventa-portal-web-mvvm.png · Fuente PlantUML: files/Diagram-web/solventa-portal-web-componentes_1.puml · Documento completo (razonamiento, código de ejemplo, convenciones de carpetas, riesgos): files/Diagram-web/mvvm-portal-web-solventa_1.md
| Proyecto | Solventa — Aseguradora digital |
| ID | VC-006 |
| Elaboración | Juan Acevedo, John Guerrero, Mauricio Rodriguez, Martin Romero |
| Versión | 1.0 |
| Vista | Desarrollo / capas |
| Modelo | Capas del cliente Android (Clean Architecture + MVVM + Repository) |
Diagrama de capas en tiempo de ejecución de la app Android (Kotlin / Jetpack). No describe el sistema Solventa completo: cubre el canal móvil (login, póliza, siniestro con evidencia, pagos y renovación) y cómo el cliente se conecta al Mobile BFF y a Room en modo offline-first. El bloque Identidad (derecha) concentra biometría, tokens y el interceptor JWT.
Capas (izquierda → derecha)
| Capa | Responsabilidad |
|---|---|
| Presentation (Jetpack + MVVM) |
MainActivity y fragments (LoginFragment, DetalleFragment, PagoFragment, RenovacionFragment) observan ViewModels (StateFlow / LiveData / UiState). Push vía FCM. El ViewModel invoca casos de uso; no habla con red ni con Room. |
| Domain | Casos de uso (EntrarAlSistema, ReportarSiniestro, ValidarCodigos, ConsultarPagos, RenovarPoliza, SincronizarUsuario) y contratos de repositorio (Póliza / Siniestro / Pago). Sin APIs de Android. |
| Data (Repository) |
*RepositoryImpl orquesta remoto vs local: Retrofit y DTO → Mobile BFF; DAOs → Room (SQLite). WorkManager encola evidencia diferida. |
| Identidad |
BiometricPrompt (huella / rostro; fallback PIN) desbloquea la sesión en el dispositivo. TokenStore (DataStore / EncryptedPrefs) y AuthInterceptor (OkHttp) inyectan JWT solo en APIs protegidas. Login y refresh no llevan access token; Room y Push no pasan por el interceptor. El JWT se valida en el BFF. |
Abrir el SVG completo: images/android-arquitectura-runtime.svg
| Nivel | Qué es | Qué gobierna |
|---|---|---|
| Estilo arquitectónico | Decisión de primer nivel y alto grado de abstracción. Establece vocabulario, reglas y lineamientos sobre la topología del modelo y su semántica. | Determina qué atributos de calidad quedan intrínsecamente favorecidos o desfavorecidos. |
| Táctica arquitectónica | Técnica que modifica, refina y especializa un estilo en puntos y componentes específicos. | Asegura la respuesta y la medida de respuesta estipuladas en un escenario de calidad. |
| Patrón de diseño | Solución conocida a un problema recurrente de estructuración y asignación de responsabilidades entre clases y objetos. | Conecta la táctica con el código. |
| Familia de modelos | Qué hace evidente | Elementos |
|---|---|---|
| Módulo | Unidades de implementación (tiempo de desarrollo). | Clases, paquetes, capas; relaciones usa a / depende de. |
| Componente y Conector (C&C) | Ejecución en tiempo de corrida. | Componentes y conectores — el conector es el elemento determinante para el cumplimiento del atributo de calidad. |
| Asignación | Asignación de software a entidades del mundo real. | Despliegue (nodos), concurrencia (procesos/hilos), asignación de trabajo. |
Catálogo de desempeño del curso. Desempeño = habilidad de cumplir requerimientos de tiempo; se subdivide en latencia (tiempo entre evento y respuesta) y escalabilidad (incrementar la carga sin perjudicar los tiempos de respuesta).
| Familia I — control del acceso a recursos compartidos | Familia II — incremento y manejo de recursos disponibles |
|---|---|
| Manejo de la prioridad de los eventos | Introducción de concurrencia |
| Limitar la respuesta a los eventos | Múltiples copias de computación (horizontal) |
| Incrementar la latencia de los recursos | Incrementar los recursos de computación (vertical) |
| Múltiples copias de datos |
La utilización de un API gateway está catalogada por el material como táctica de disponibilidad (ocultar localización e instancias, enmascarar fallas), con uso complementario en seguridad.
Las decisiones de este documento se sustentan sobre los siguientes modelos:
| Modelo | Vista | Enlace |
|---|---|---|
| Modelo de componentes | Funcional — Componente y Conector | §1.2 Vista funcional — Modelo de componentes |
| Modelo de despliegue | Asignación | §1.3 Vista de despliegue — AWS |
| Modelo de datos | Información | §1.4 Vista de información — Modelo de datos |
| Estilo | Familia | Dónde vive | Favorece | Sacrifica |
|---|---|---|---|---|
| Microservicios | C&C |
Dominio · Venta y Dominio · Operación como unidades desplegables con almacén propio |
Escalabilidad selectiva, modificabilidad | Latencia de red interna, consistencia distribuida |
| Llamada-retorno sincrónico (N-niveles) | C&C | APISocios → :MsCotización → :MotorRaiting |
Baja latencia y consistencia inmediata en el journey de venta | Acoplamiento temporal |
| Publicador-suscriptor (EDA) | C&C |
:BusEventos → :Analitica, :Notificaciones, :Documentos; :ColaPagos tras :MsPagos; :TopicoTelemetria → :MotorParametrico
|
Escalabilidad: absorbe picos con contrapresión, admite consumidores nuevos sin tocar productores | Consistencia eventual, idempotencia |
| Capas + adaptadores (anticorrupción) | Módulo |
:AdaptadorOF, :AdaptadorOD, :AdaptadorPasarela, :AdaptadorKYC, :AdaptadorTelemetria
|
Modificabilidad e integrabilidad | Una indirección más por llamada |
Regla de reparto. Es síncrono lo que el usuario espera mirando la pantalla (cotizar, perfilar, suscribir, emitir). Es asíncrono lo que puede converger después (notificar, analizar, conciliar, telemetría paramétrica). Esa frontera es la decisión que más pesa sobre latencia y escalabilidad a la vez.
| Táctica (nombre del catálogo) | Familia | Modelo donde está presente | Componente del diagrama | Escenario |
|---|---|---|---|---|
| Múltiples copias de datos | II | Modelo C&C |
:CacheOF, :CacheOD delante de :AdaptadorOF / :AdaptadorOD
|
EC-LAT-09 — p95 ≤ 250 ms resolviendo con valor de respaldo |
| Limitar la respuesta a los eventos | I | Modelo C&C |
:MsPolizas confirma y publica en :BusEventos; firma y notificación salen del camino crítico. :ColaPagos entre :MsPagos y el flujo asíncrono |
EC-LAT-05 / EC-LAT-06 — p95 ≤ 1,5 s · p99 ≤ 3 s |
| Introducción de concurrencia | II | Modelo de Asignación (concurrencia) | Fan-out paralelo de :MsPerfilamiento hacia :AdaptadorOF y :AdaptadorOD
|
EC-LAT-03 / EC-LAT-04 — p95 ≤ 400 ms · p99 ≤ 800 ms |
Aritmética que justifica la concurrencia. EC-LAT-07 fija ≤ 120 ms por dependencia externa y EC-LAT-03 fija 400 ms para todo el perfilamiento. Invocar :AdaptadorOF y :AdaptadorOD en serie consume 240 ms de los 400; en paralelo, 120 ms. Es la única forma aritméticamente viable de cumplir el escenario.
Respuesta a la pregunta 3 del enunciado (¿cómo se protege el presupuesto de latencia de la cotización cuando depende de Open Finance?): no con el :ApiGateway —que añade un salto—, sino porque :CacheOF ya tiene el perfil y la llamada a :AdaptadorOF es una actualización oportunista, no una dependencia bloqueante. EC-LAT-08 corta a 700 ms y :MsCotización resuelve con el respaldo.
| Táctica (nombre del catálogo) | Familia | Modelo donde está presente | Componente del diagrama | Escenario |
|---|---|---|---|---|
| Múltiples copias de computación | II | Modelo de Asignación (despliegue) | Réplicas de :MsCotización + :MotorRaiting como grupo, separadas de :MsPerfilamiento + :MotorRiesgo
|
EC-ESC-01 — 500 → 50.000 cot/min sostenidas 30 min |
| Incrementar los recursos de computación | II | Modelo de Asignación (despliegue) | Nodos de :MotorRaiting / :MotorRiesgo (cómputo intensivo, poco estado) |
EC-ESC-02 — capacidad ampliada ≤ 60 s |
| Introducción de concurrencia + contrapresión | II | Modelo C&C y de Asignación |
:AdaptadorTelemetria → :TopicoTelemetria → :MotorParametrico con grupo de consumidores |
EC-ESC-03 — ≥ 1.000.000 eventos en 10 min, con procesamiento exactamente una vez |
Las dos primeras son decisiones de la familia de asignación: su evidencia se documenta en el modelo de despliegue, no en el de componentes.
Por qué
:MsCotizacióny:MsPerfilamientoson componentes separados. No es modularidad estética: sus curvas de carga no coinciden.:MsCotizaciónescala con la campaña de un socio (EC-ESC-01, pico inducido y previsible);:MsPerfilamientoescala con el cierre de mes de los bancos aliados (EC-LAT-04, pico de originación). Escalarlos juntos obliga a dimensionar por el máximo de ambos. Esta es la justificación de fondo del estilo de microservicios en este caso.
Cómo se combinan los dos escalamientos. El horizontal es la decisión por defecto, porque aporta elasticidad y tolerancia a la falla de una zona. El vertical se emplea sobre los motores de cálculo para ganar los primeros segundos de la rampa, donde el aprovisionamiento horizontal aún no ha terminado.
Los patrones de la sección siguiente aterrizan mayoritariamente tácticas de modificabilidad, no de desempeño. Se documentan aquí para que la trazabilidad táctica → patrón quede completa: cada patrón de §2.7 apunta a una táctica descrita en §2.4, §2.5 o en esta sección. No son los atributos priorizados, pero sostienen a los que sí lo son — el bajo acoplamiento, en particular, es precondición del escalamiento selectivo.
| Táctica (nombre del catálogo) | Atributo | Modelo donde está presente | Componente del diagrama | Escenario |
|---|---|---|---|---|
| Reducción del acoplamiento | Modificabilidad | Modelo de Módulo | Interfaces provided/required entre componentes; :BusEventos como intermediario orientado a mensajes; capa :Adaptador*
|
EC-MOD-05 · EC-INT-03 · EC-INT-04
|
| Mantener alta cohesión | Modificabilidad | Modelo de Módulo | Submódulos de Dominio · Venta y Dominio · Operación; cada motor separado de su orquestador |
EC-MOD-01 · EC-MOD-03 · EC-MOD-04
|
| Utilización de un API Gateway | Disponibilidad y seguridad | Modelo C&C |
:ApiGateway con :APISocios, :BFFWeb, :BFFMovil, :ApiTelemetria
|
EC-INT-04 · EC-SEG-07
|
Por qué el bajo acoplamiento no es un tema secundario aquí. Solo se puede replicar de forma independiente aquello que no arrastra a sus vecinos. Si
:MsCotizacióndependiera de la implementación de sus colaboradores, escalarla obligaría a escalarlos con ella y desaparecería la ventaja de tener curvas de carga separadas. Es decir: la táctica de modificabilidad es la que hace posible la de escalabilidad.
Cada patrón se presenta con la táctica que aterriza (descrita en §2.4, §2.5 o §2.6), el componente donde vive, el modelo que lo hace evidente, el escenario que sostiene y la razón por la que se tomó la decisión — no solo qué hace, sino qué alternativa se descartó y qué se aceptó a cambio.
| Táctica que aterriza | Utilización de un API Gateway (disponibilidad y seguridad): ocultar la localización y disponibilidad de los microservicios y enmascarar fallas. |
| Componente del diagrama |
:ApiGateway con :APISocios, :BFFWeb, :BFFMovil, :ApiTelemetria
|
| Modelo donde está presente | Modelo C&C |
| Escenario |
EC-INT-04 — evolución compatible de contratos multicanal |
| ASR | HA-31 |
Por qué esta decisión. Solventa expone su núcleo a cuatro canales con ciclos de vida independientes: una app móvil que queda instalada en el dispositivo del cliente, un portal web, más de treinta socios que integran una vez y no vuelven a tocar el código, y un flujo de telemetría. Sin un punto de entrada único, cada canal quedaría atado a la topología interna del backend: dividir un microservicio o cambiar su dirección obligaría a coordinar el redespliegue de apps ya instaladas y de integraciones de terceros que Solventa no controla. La alternativa —exponer los microservicios directamente— era más simple y más rápida, pero congelaba la estructura interna. Se aceptó un salto de red adicional en el camino crítico a cambio de poder reorganizar el backend sin romper contratos externos, y como beneficio secundario el punto único es donde se concentran el control de acceso y el enmascaramiento de fallas.
| Táctica que aterriza | Utilización de un API Gateway, especializada por canal. Protege además el presupuesto de latencia al agregar en el borde, aunque la agregación no es una táctica nombrada del catálogo de desempeño. |
| Componente del diagrama |
:BFFWeb y :BFFMovil, separados de :APISocios
|
| Modelo donde está presente | Modelo C&C |
| Escenarios |
EC-INT-04 · EC-LAT-05
|
| ASR |
HA-31 · HA-05
|
Por qué esta decisión. Los tres canales no piden lo mismo. La web cubre la gestión completa del negocio; el móvil un subconjunto de tareas rápidas con evidencia, biometría y modo offline; los socios solo cotización y emisión embebidas. Una API única para los tres obligaría a servir el máximo común denominador, y el cliente compensaría la diferencia con varias llamadas encadenadas — un costo que se paga directamente contra el presupuesto de 1,5 s de EC-LAT-05. La alternativa era una sola API y clientes más gordos; se descartó porque traslada al canal un trabajo de composición que el borde hace mejor y más cerca de los datos. Se aceptó mantener tres piezas de borde en vez de una a cambio de que cada canal evolucione a su propio ritmo y de que la agregación ocurra donde no cuesta latencia.
| Táctica que aterriza | Reducción del acoplamiento (modificabilidad): usar APIs e intermediarios para que el dominio no dependa de la implementación del proveedor. |
| Componente del diagrama |
:AdaptadorOF, :AdaptadorOD, :AdaptadorPasarela, :AdaptadorKYC, :AdaptadorTelemetria
|
| Modelo donde está presente | Modelo de Módulo |
| Escenarios |
EC-MOD-05 · EC-INT-03
|
| ASR |
HA-28 · HA-30
|
Por qué esta decisión. El enunciado es explícito en que gran parte del valor del negocio depende de integraciones fuera del control de Solventa, y que la regulación de Finanzas Abiertas sigue madurando. Sin una capa de traducción, el esquema de cada proveedor se filtraría hasta el dominio: los campos de Open Finance aparecerían dentro del motor de riesgo y los de la pasarela dentro de pagos. Ese acoplamiento convierte un cambio de proveedor —o un cambio normativo del proveedor— en un cambio transversal que toca varios componentes. Se aceptó una indirección adicional por llamada a cambio de que la sustitución de un tercero quede contenida en un solo módulo, que es exactamente lo que EC-MOD-05 exige medir.
| Táctica que aterriza | Limitar la respuesta a los eventos (latencia, familia I) e introducción de concurrencia + contrapresión (escalabilidad, familia II). |
| Componente del diagrama | :BusEventos |
| Modelo donde está presente | Modelo C&C |
| Escenario | EC-ESC-03 |
| ASR | HA-11 |
Por qué esta decisión. Un mismo hecho de negocio —una póliza emitida, un siniestro aprobado, un pago aplicado— le interesa a varios consumidores a la vez: analítica, notificaciones, documentos, y mañana fraude o reportes al regulador. Con comunicación punto a punto, cada consumidor nuevo obliga a modificar y redesplegar al productor, y la lista de consumidores solo crece con el negocio. El mediador invierte esa dependencia: el productor publica el hecho y deja de saber quién lo escucha. Se aceptó consistencia eventual —y la obligación de resolver idempotencia y trazabilidad— a cambio de poder sumar consumidores sin tocar productores y de absorber picos con contrapresión en lugar de propagarlos.
| Táctica que aterriza | Es consecuencia obligada de Introducción de concurrencia (§2.4) y Múltiples copias de computación (§2.5), ambas de familia II: sin él, esas dos tácticas se anulan entre sí. |
| Componente del diagrama | Pool de conexiones dentro de cada réplica de :MotorRaiting y :MotorRiesgo
|
| Modelo donde está presente | Modelo de Asignación (concurrencia y despliegue) |
| Escenarios |
EC-LAT-03 · EC-ESC-01
|
| ASR |
HA-03 · HA-09
|
Por qué esta decisión. No es una elección estética: es la consecuencia obligada de haber adoptado concurrencia. La táctica de introducción de concurrencia multiplica los hilos dentro de cada réplica, y la de múltiples copias de computación multiplica las réplicas. Si cada hilo abriera su propio pool, las conexiones contra el almacén crecerían como hilos × réplicas — con 4 hilos y 20 réplicas son 80 pools golpeando la misma base. La contienda que se eliminó en el cómputo reaparecería en la persistencia, y las dos tácticas de escalamiento se anularían entre sí. Una única instancia por proceso acota las conexiones y deja que el paralelismo escale sin castigar el almacén.
| Táctica que aterriza | Mantener alta cohesión (modificabilidad). Protege además el presupuesto de las tácticas de latencia al eliminar un salto de red del camino crítico. |
| Componente del diagrama |
:MotorRiesgo decide sobre el perfil; :MotorParametrico sobre el umbral |
| Modelo donde está presente | Modelo de Módulo |
| Escenario |
EC-LAT-03 — p95 ≤ 400 ms |
| ASR | HA-03 |
Por qué esta decisión. En una arquitectura distribuida cada decisión que se toma lejos de su dato cuesta un viaje de red, y ese viaje se descuenta de un presupuesto de 400 ms del que 120 ms ya están comprometidos por dependencia externa. La alternativa natural —un motor de reglas central que decidiera por todos los dominios— habría sido más fácil de gobernar, pero obligaría a que perfilamiento le enviara el perfil completo y esperara, y convertiría ese motor en cuello de botella común y en punto único de acoplamiento. Se prefirió pagar en gobierno (dos motores en vez de uno) para no pagar en latencia, poniendo cada decisión pegada al componente que ya tiene la información para tomarla.
| Táctica que aterriza | Mantener alta cohesión (modificabilidad): que las responsabilidades de cada componente estén ligadas a un único propósito. |
| Componente del diagrama | Paquete Dominio · Venta; :MotorRaiting como única razón de cambio del precio |
| Modelo donde está presente | Modelo de Módulo |
| Escenario |
EC-MOD-03 — regla de precio |
| ASR | HA-26 |
Por qué esta decisión. El precio y la política de aceptación de riesgo cambian con una frecuencia que dicta actuaría, no ingeniería, y cambian por razones distintas entre sí. Si esa lógica viviera dentro de los orquestadores, cada ajuste de fórmula obligaría a redesplegar la cotización completa y a arrastrar en el mismo despliegue código que no cambió. Se separó el motor de quien lo orquesta para que la unidad de cambio coincida con la unidad de despliegue, que es la condición que EC-MOD-03 mide: el 100 % del cambio se despliega sin tocar componentes ajenos al motor de rating.
| Táctica que aterriza | Reducción del acoplamiento (modificabilidad). Es precondición de múltiples copias de computación: solo se replica de forma independiente lo que no arrastra a sus vecinos. |
| Componente del diagrama | Interfaces provided/required entre componentes; :BusEventos como intermediario; capa de adaptadores |
| Modelo donde está presente | Modelo de Módulo |
| Escenarios |
EC-MOD-05 · EC-INT-04
|
| ASR |
HA-28 · HA-31
|
Por qué esta decisión. El bajo acoplamiento se suele justificar solo por modificabilidad, pero en este caso es precondición de los dos atributos priorizados: solo se puede replicar de forma independiente aquello que no arrastra a sus vecinos. Si :MsCotización dependiera de la implementación de sus colaboradores, escalarla obligaría a escalarlos con ella y desaparecería la ventaja de tener curvas de carga separadas. Por eso se aplicaron los tres mecanismos del catálogo a la vez —interfaz, intermediario orientado a mensajes y adaptador— en lugar de conformarse con uno. Se aceptó más piezas y más contratos que mantener a cambio de que el escalamiento selectivo sea realmente posible.
| Táctica que aterriza | Reducción del acoplamiento (modificabilidad), en su forma más estricta: el dominio no controla el ciclo de vida de su colaborador. |
| Componente del diagrama | Contratos entre el dominio y la capa de adaptadores |
| Modelo donde está presente | Modelo de Módulo |
| Escenarios |
EC-MOD-05 · EC-INT-03
|
| ASR |
HA-28 · HA-30
|
Por qué esta decisión. Tener adaptadores no basta: si el dominio conociera al adaptador concreto y controlara su creación, seguiría atado a una implementación y el beneficio se perdería en el primer cambio de proveedor. Invertir la dependencia significa que el dominio declara qué necesita y recibe una abstracción ya construida, sin saber quién la implementa ni gestionar su ciclo de vida. Ese detalle es lo que convierte la contención del cambio en una propiedad verificable: por eso EC-MOD-05 puede exigir que el 100 % del cambio quede dentro del módulo de integración, y EC-INT-03 que el 100 % de los consumidores existentes siga operando sin modificación.
| Táctica que aterriza | Reducción del acoplamiento (modificabilidad): concentrar la creación en un solo responsable evita que varios objetos dependan entre sí para instanciarse. |
| Componente del diagrama |
:MsCotización crea la oferta; :MsSiniestros crea la evidencia y la evaluación |
| Modelo donde está presente | Modelo de Módulo y modelo de dominio |
| Escenario | EC-MOD-01 |
| ASR | HA-25 |
Por qué esta decisión. En una arquitectura de microservicios con base de datos por servicio, la pregunta de quién instancia cada entidad no es un detalle de código: determina qué servicio es dueño de su ciclo de vida y, por lo tanto, de su almacén. Si un componente ajeno creara la evidencia de un siniestro, tendría que conocer el estado de la reclamación y quedaría acoplado al servicio que la gobierna, rompiendo la frontera del dato. Aplicar la regla de que crea quien contiene y usa estrechamente al objeto confina el ciclo de vida de cada entidad a su microservicio, que es la precondición del almacén propio por servicio y de la trazabilidad entre las tres vistas: componente que crea → entidad de dominio → esquema propietario.
| Táctica que aterriza | Mantener alta cohesión y reducción del acoplamiento (modificabilidad): unidades pequeñas, con una sola razón de cambio y un punto de extensión propio. |
| Componente del diagrama | Tres pares orquestador / motor: :MsCotización–:MotorRaiting, :MsPerfilamiento–:MotorRiesgo, :MsSiniestros–:MotorParametrico
|
| Modelo donde está presente | Modelo de Módulo |
| Escenarios |
EC-MOD-01 · EC-MOD-04
|
| ASR |
HA-25 · HA-27
|
Por qué esta decisión. El negocio de Solventa crece incorporando ramos: viaje, dispositivos, microseguros de vida, paramétricos, protección de pagos. Si cada ramo nuevo obligara a modificar los orquestadores, el costo de crecer aumentaría con el tamaño del portafolio y la meta de expansión regional se volvería inviable. Al concentrar la variabilidad del negocio en los motores, cada motor tiene una sola razón de cambio (SRP) y a la vez es el único punto por donde el producto se extiende (OCP). Son las dos caras de la misma decisión: lo que hace barato modificar es exactamente lo que hace barato extender. Que el patrón aparezca tres veces, y no una, es lo que lo convierte en principio aplicado y no en coincidencia.
Un trade-off es lo que se sacrifica para conseguir algo. Ninguna decisión mejora todos los atributos a la vez; lo que sigue no son defectos ni deuda pendiente, sino decisiones conscientes con su mitigación.
| Decisión | Se gana | Se sacrifica | Mitigación |
|---|---|---|---|
| Microservicios sobre monolito modular | Escalamiento selectivo por curva de carga | Latencia de red interna, complejidad operativa | Presupuesto de latencia por salto; fronteras alineadas con capacidades de negocio para evitar el monolito distribuido |
:BusEventos para el flujo paramétrico |
Absorción de picos; consumidores nuevos sin tocar productores | Consistencia eventual | Idempotencia por clave de evento |
:CacheOF / :CacheOD en el camino crítico |
Presupuesto protegido ante terceros degradados | Decidir con datos menos frescos | TTL por fuente + linaje de toda cotización resuelta con respaldo |
:ColaPagos solo en :MsPagos, no en los demás dominios |
Durabilidad y reintento idempotente donde se mueve dinero | Asimetría respecto de los demás recorridos | Es deliberada: el flujo de dinero exige durabilidad y aplicación exactamente una vez, exigencia que los demás recorridos no tienen |
:ApiGateway como punto único |
Enmascaramiento de fallas y superficie de ataque reducida | Un salto extra en el camino crítico y un punto de congestión | Replicado y multi-zona; sin lógica de negocio en el gateway |
| Escalamiento horizontal como decisión por defecto | Elasticidad y tolerancia a la falla de una zona | Mayor tiempo de aprovisionamiento en la rampa inicial | Escalamiento vertical de los motores de cálculo para cubrir los primeros segundos del pico |
- Enunciado del caso:
files/MISW4501-202614-Proyecto.pdf— §4 Ecosistema de integraciones, §6.1 Latencia, §6.2 Escalabilidad, §8 Decisiones de arquitectura, §9 Preguntas de discusión. -
Hoja de trabajo — objetivos de negocio y escenarios de calidad
EC-*. - Visión de arquitectura — modelos de contexto, dominio, componentes, datos y despliegue.
| Campo | Detalle |
|---|---|
| Título del experimento | Modelo de lectura de baja latencia para el estado de siniestro mediante CQRS con proyección materializada y caché |
| Propósito del experimento | Evaluar si las tácticas de latencia propuestas para la consulta de estado de siniestro —desacoplar el modelo de lectura del de escritura, materializar una proyección desnormalizada y servirla desde un almacén en memoria— permiten cumplir el ASR EC-LAT-11 (p95 ≤ 150 ms), y determinar cuál es el nivel mínimo de complejidad que lo satisface. |
| Resultados esperados | Se espera que la lectura directa sobre el modelo transaccional normalizado no alcance el umbral bajo la carga de operación regular, que la proyección materializada reduzca el p95 de forma sustancial, y que el caché en memoria aporte una mejora adicional. El experimento debe además cuantificar el costo de esas tácticas en términos de staleness (lag de proyección) para determinar si la consistencia eventual resultante es aceptable para el escenario. |
| Elementos de arquitectura involucrados |
ASR asociado: EC-LAT-11 — Latencia, prioridad (A,A). Historia de arquitectura: HA-08. Vistas y modelos: Vista funcional (modelo de componentes: API de consulta, almacenes de lectura y escritura); Vista de información ; Vista de despliegue (modelo de contenedores). Puntos de sensibilidad que se desean probar: separación del modelo de lectura, política de caché (TTL e invalidación) y tasa de llegada de consultas. |
| Esfuerzo estimado | Tiempo: 1,5 semanas — 60 horas Horas hombre: 15 horas/hombre (4 integrantes) |
Lista de recursos requeridos para ejecutar el experimento (software, librerías, hardware):
- Lenguaje y framework: Python 3.12, FastAPI, Uvicorn
- Contenerización: Docker y Docker Compose V2
- Almacenamiento: PostgreSQL 16 (modelo transaccional y proyección), Redis 7 (caché)
- Mensajería: Redpanda (API compatible con Kafka)
-
Librerías:
asyncpg,redis-py(asyncio),aiokafka,orjson,pydantic,prometheus-client - Generación de carga: k6
- Observabilidad: Prometheus, Grafana
- Hardware: estación de desarrollo con mínimo 16 GB de RAM, 4 núcleos y 20 GB de disco libre (el dataset sintético ocupa ~2 GB más índices)
Si separamos el modelo de lectura del de escritura mediante CQRS, materializando el estado del siniestro en una proyección desnormalizada (un registro autocontenido por siniestro) mantenida de forma asíncrona por un proyector que consume los eventos de dominio del proceso de evaluación, y servimos esa proyección desde un almacén clave-valor en memoria con fallback a la proyección persistente,
entonces la consulta de estado de siniestro alcanzará un p95 ≤ 150 ms bajo la carga esperada en producción regular,
aceptando como contrapartida consistencia eventual acotada (lag de proyección p95 ≤ 2 s), duplicación de datos y mayor complejidad operativa.
| Campo | Detalle |
|---|---|
| Historia de arquitectura asociada | HA-08 — Modelo de lectura de baja latencia para el estado de siniestro |
| Escenario de calidad | EC-LAT-11 — Latencia, prioridad (A,A), clasificado como ASR |
| Nivel de incertidumbre | Medio-Alto. El equipo tiene experiencia previa con CQRS, pero desconoce (a) si la proyección por sí sola basta o si el caché es indispensable, (b) cuánto lag introduce el proyector bajo carga concurrente de lectura, y (c) cuál es el punto de quiebre de cada alternativa. El costo de equivocarse es alto: revertir CQRS una vez adoptado implica reescribir el camino de lectura y el proceso de evaluación completo. |
| # | Punto de sensibilidad | ¿Qué probar? |
|---|---|---|
| 1 | Grado de separación del modelo de lectura. Es la decisión arquitectónica central: cuánta separación entre comando y consulta se requiere para satisfacer el ASR. | Variar la estrategia de lectura en tres niveles: A lectura directa sobre el modelo transaccional normalizado (sin separación), B proyección materializada persistente (separación lógica y física del esquema), C proyección + caché en memoria (separación con copia adicional en otro medio de almacenamiento). |
| 2 | Política del caché. Determina el balance entre latencia y staleness, que es el trade-off que la historia HA-08 pone en tensión: el cliente quiere inmediatez, pero también quiere ver el estado vigente. | Variar el TTL del caché: 0 s (sin caché, equivale al brazo B), 30 s (valor propuesto) y 300 s. Medir simultáneamente el p95 y el lag observado por el cliente. |
| 3 | Tasa de llegada de consultas. Identifica el margen de crecimiento de cada alternativa antes de incumplir el ASR. | Escalones de 10, 25, 50 y 80 solicitudes por segundo, registrando el p95 en cada escalón para localizar el punto de quiebre de cada brazo. |
| Estilo de arquitectura asociado al experimento | Análisis (atributos de calidad que favorece y desfavorece) |
|---|---|
| CQRS (segregación de responsabilidades de comando y consulta) |
Favorece: • Latencia de lectura • Escalabilidad independiente de lectura y escritura • Modificabilidad del esquema de consulta • Disponibilidad de la consulta ante presión sobre el modelo transaccional Desfavorece: • Consistencia (pasa de fuerte a eventual) • Simplicidad operativa (componente adicional con modos de falla propios) • Testabilidad extremo a extremo • Eficiencia de almacenamiento (datos duplicados) |
| Arquitectura orientada a eventos (publicación/suscripción) |
Favorece: • Desacople entre el proceso de evaluación y el modelo de lectura • Escalabilidad del procesamiento asíncrono • Integrabilidad con futuros consumidores (notificaciones, analítica) Desfavorece: • Consistencia inmediata • Trazabilidad y depuración del flujo • Complejidad de la infraestructura (broker, particiones, consumer groups) |
| Microservicios (contexto general de Solventa) |
Favorece: • Disponibilidad • Escalabilidad • Mantenibilidad • Flexibilidad tecnológica Desfavorece: • Latencia extremo a extremo (saltos de red adicionales) • Orquestación/coreografía • Consistencia distribuida |
La tensión que resuelve este experimento es visible en la tabla: el estilo de microservicios, ya adoptado en Solventa, desfavorece la latencia, y HA-08 es precisamente un ASR de latencia. CQRS se introduce como contramedida deliberada a esa contrapartida, no como preferencia estilística.
| Táctica de arquitectura asociada al experimento | Descripción |
|---|---|
| Reducir la demanda computacional | Para el sistema Solventa, el estado de un siniestro se compone hoy a partir de cinco entidades normalizadas (siniestro, póliza, hitos, documentos y peritaje), lo que obliga a la consulta a resolver joins y agregaciones en tiempo de petición. La táctica consiste en trasladar ese cómputo fuera del camino crítico: el proyector construye el estado completo una sola vez, en el momento en que ocurre el evento, y lo almacena listo para entregar. La consulta pasa a ser un acceso por clave primaria sin joins ni agregaciones. |
| Mantener múltiples copias de los datos | Se introducen dos copias derivadas del estado del siniestro: una proyección persistente en PostgreSQL, desnormalizada y con un registro por siniestro, y una copia volátil en Redis servida desde memoria. Cada copia acorta el camino de acceso a costa de introducir una ventana de desactualización que debe ser medida y acotada. |
| Introducir concurrencia | La actualización del modelo de lectura se ejecuta en un componente independiente (el proyector), que consume los eventos de dominio de forma asíncrona y trabaja en paralelo a las consultas de los clientes. El cliente nunca espera a que la proyección se actualice. |
| Reducir el overhead de procesamiento | El estado se almacena ya serializado (JSONB en la proyección, JSON en el caché) y se emplea un serializador de alto desempeño en la respuesta HTTP, de modo que la representación no se reconstruye en cada petición. |
| Componente | Propósito y comportamiento esperado | Tecnología asociada |
|---|---|---|
| API de Consulta de Siniestros | Expone el recurso de consulta de estado de siniestro. Debe implementar los tres brazos del experimento sobre el mismo binario, seleccionables por configuración, de modo que la estrategia de lectura sea la única variable que cambie entre corridas. Devuelve una representación idéntica en los tres brazos. | Python, FastAPI, Uvicorn (uvloop), asyncpg, redis-py, orjson
|
| Proyector de Estado de Siniestro | Consume los eventos de dominio del proceso de evaluación y actualiza la proyección materializada de forma idempotente. Debe descartar eventos con versión anterior a la almacenada e invalidar la entrada correspondiente del caché. Expone el lag de proyección como métrica. | Python, aiokafka, asyncpg, redis-py, prometheus-client
|
| Simulador del Proceso de Evaluación | Genera cambios de estado sobre siniestros del conjunto caliente a una tasa configurable, escribiendo en el modelo transaccional y publicando el evento correspondiente. Mantiene la proyección bajo actualización activa durante toda la medición, condición exigida por el escenario EC-LAT-11. | Python, aiokafka, asyncpg
|
| Almacén Transaccional | Contiene el modelo normalizado del proceso de evaluación. Es el origen de la verdad y la fuente de lectura del brazo A. Debe conservar sus índices para que la línea base sea una implementación razonablemente optimizada. | PostgreSQL 16, esquema siniestros_w
|
| Almacén de Proyección | Contiene la vista materializada, un registro autocontenido por siniestro con la respuesta preconstruida. Es la fuente de lectura del brazo B y el respaldo del brazo C. | PostgreSQL 16, esquema siniestros_r
|
| Caché de Estado | Almacena en memoria las entradas más consultadas bajo una política cache-aside con expiración e invalidación proactiva desde el proyector. | Redis 7 |
| Conector | Comportamiento deseado en el experimento | Tecnología asociada |
|---|---|---|
| Conector HTTP de consulta | El generador de carga emite solicitudes contra el recurso de estado de siniestro a una tasa de llegada fija (no un número fijo de usuarios), de modo que la degradación del servicio no reduzca automáticamente la carga y enmascare el p95. Registra la latencia extremo a extremo por solicitud. | Cliente: k6 con ejecutor de tasa de llegada escalonada. Servidor: Uvicorn sobre ASGI. |
| Conector de eventos asíncrono | Cada cambio de estado del proceso de evaluación se publica como un evento particionado por identificador de siniestro, lo que garantiza el orden por agregado. Un consumidor perteneciente a un grupo dedicado procesa los eventos y actualiza la proyección. El evento transporta el estado completo (event-carried state transfer), de modo que el proyector nunca consulta de vuelta el modelo de escritura y el desacople exigido por HA-08 se preserva. | Publicador: aiokafka producer. Broker: Redpanda. Consumidor: aiokafka consumer con consumer group. |
| Conector de acceso transaccional (brazo A) | Resuelve la consulta componiendo el estado a partir de las cinco entidades normalizadas mediante joins y agregaciones en tiempo de petición. Representa la línea base contra la cual se mide la mejora. |
asyncpg sobre PostgreSQL, esquema siniestros_w. Pool de conexiones de tamaño fijo. |
| Conector de acceso a la proyección (brazos B y C) | Resuelve la consulta mediante un acceso por clave primaria a un único registro, sin joins ni agregaciones. |
asyncpg sobre PostgreSQL, esquema siniestros_r. |
| Conector de caché (brazo C) | Implementa cache-aside: ante un acierto devuelve la entrada en memoria; ante un fallo consulta la proyección, entrega el resultado y escribe la entrada con expiración. El proyector invalida la entrada al aplicar un cambio de estado, de modo que el caché nunca sirve una versión anterior a la ya proyectada. |
redis-py en modo asíncrono sobre Redis 7, política allkeys-lru. |
| Conector de telemetría | La API y el proyector exponen métricas en formato de texto plano que Prometheus recolecta periódicamente; el generador de carga envía sus métricas por escritura remota al mismo Prometheus, de modo que latencia de cliente y de servidor queden en la misma línea de tiempo y sean comparables. |
prometheus-client (exposición), Prometheus (scrape y remote-write receiver), Grafana (visualización). |
| Tecnología asociada con el experimento | Selección | Justificación |
|---|---|---|
| Lenguajes de programación | Python 3.12 | Alineado con el stack del equipo y con el resto de componentes de Solventa. Su modelo asíncrono permite representar fielmente el comportamiento de un servicio de lectura con E/S intensiva. |
| Frameworks de desarrollo | FastAPI + Uvicorn (uvloop, httptools) | Framework ASGI nativo asíncrono, necesario para que el camino de lectura no bloquee el event loop. Uvicorn con uvloop reduce el overhead del servidor, de modo que la latencia medida refleje la estrategia de lectura y no el transporte. |
| Plataforma de despliegue | Docker + Docker Compose V2 | Permite fijar límites explícitos de CPU y memoria por componente, condición indispensable para que las corridas sean reproducibles y comparables entre brazos en una estación de desarrollo. |
| Bases de datos | PostgreSQL 16 (esquemas siniestros_w y siniestros_r)Redis 7 |
PostgreSQL sostiene tanto el modelo normalizado como la proyección, lo que aísla la variable bajo estudio: la diferencia entre brazos A y B proviene del modelo de datos, no del motor. Redis aporta el almacenamiento en memoria del brazo C. |
| Mensajería | Redpanda | API compatible con Kafka, con un consumo de recursos considerablemente menor en un nodo único, lo que es determinante en un montaje local donde el broker compite por CPU con el generador de carga. |
| Herramientas de análisis | k6, Prometheus, Grafana | k6 ofrece un ejecutor de tasa de llegada (imprescindible para medir latencia correctamente) y umbrales declarativos que permiten codificar el criterio de aceptación del ASR en el propio script. Prometheus y Grafana correlacionan latencia de cliente, latencia interna, lag de proyección y consumo de recursos en una misma línea de tiempo. |
| Librerías |
asyncpg, redis-py (asyncio), aiokafka, orjson, pydantic, prometheus-client
|
Drivers asíncronos en toda la ruta de lectura, requisito no negociable: un driver síncrono dentro de una corrutina bloquea el event loop completo y produciría una refutación falsa de la hipótesis. orjson minimiza el costo de serialización, que de otro modo contaminaría la comparación entre brazos. |
| Integrante | Tareas a realizar | Esfuerzo estimado |
|---|---|---|
| Alex Mauricio Rodriguez Sanchez |
Desarrollar la API de Consulta de Siniestros: • Crear la aplicación FastAPI y el ciclo de vida de los pools. • Implementar los tres brazos de lectura sobre el mismo binario. • Instrumentar la latencia interna y el hit-rate del caché. |
15 horas |
| Martin Ricardo Romero Ortiz |
Preparar el entorno de ejecución: • Crear y configurar el docker-compose.yml con límites de recursos por componente.• Configurar la red de Docker, PostgreSQL (parámetros de memoria), Redis y Redpanda. • Configurar Prometheus, Grafana y el remote-write desde k6. • Apoyar en la integración y ejecución de las corridas. |
15 horas |
| John Edwin Guerrero Ayala |
Desarrollar el Proyector y el Simulador: • Implementar el consumidor de eventos con upsert idempotente por versión. • Implementar la invalidación del caché y la métrica de lag. • Construir el simulador del proceso de evaluación sobre el conjunto caliente. |
15 horas |
| Juan Camilo Acevedo Ospina |
Planificar y dirigir el experimento: • Definir el contrato del evento de dominio y el modelo de la proyección. • Generar el dataset sintético y verificar que el volumen supere la memoria del motor. • Construir el script de carga y el protocolo de corridas contrabalanceadas. • Analizar los resultados y redactar el informe final. |
15 horas |
Total: 60 horas — 1,5 semanas
El esfuerzo debe recalibrarse una vez conocida la duración real de la generación del dataset, que es la actividad con mayor incertidumbre del cronograma.