Documentacion Tecnica UX UI - martin-hendricks/MISO-PROYECTO-FINAL-SOLVENTA GitHub Wiki
Referencia de diseño para construir los canales de Solventa: tokens, componentes, pantallas y flujos, con el identificador exacto de cada frame en Figma.
Fuentes de diseño
| Archivo | Rol | Canvas |
|---|---|---|
| Solventa — Design System | Design system y app Android | 390 |
| Solventa — Web Customer Experience | Portal cliente y back-office | 1440 · 768 · 390 |
Stack de implementación. Web: AngularJS + TypeScript, unitarias con Karma y E2E con Cucumber/Gherkin. Móvil: Android nativo (Kotlin + Jetpack Compose), Clean Architecture + MVVM + Repository, unitarias con JUnit. No es híbrido ni comparte código de UI entre canales. Detalle en Estrategia de pruebas §4.
Páginas relacionadas: Arquitectura de información · Prototipo navegable · Cumplimiento axe/Nielsen · cliente · · back-office · Validación con usuario
- Guía de estilos (design tokens)
- Catálogo de componentes UI
- Inventario de pantallas por plataforma
- Flujos de navegación
- Consideraciones técnicas
Ambos archivos comparten paleta, tipografía y escala. La diferencia está en cómo se declaran: el archivo móvil usa cuatro colecciones de variables con primitives aliasados por rol semántico; el web usa una sola colección de color con modos Light/Dark.

Material 3 con primary #005050. Cada token existe en Light y Dark; en Android los roles apuntan a un primitivo mediante alias.
| Token | Light | Dark | Uso principal |
|---|---|---|---|
primary |
#005050 |
#84d4d3 |
Acción principal, destino activo, marca |
on-primary |
#ffffff |
#003737 |
Texto e icono sobre primary
|
primary-container |
#006a6a |
#004f4f |
Contenedor de énfasis medio |
on-primary-container |
#97e7e6 |
#a0f0f0 |
Texto sobre primary-container
|
secondary-container |
#cce8e7 |
#324b4b |
Tab activo, chip seleccionado, badge |
on-secondary-container |
#506969 |
#cce8e7 |
Texto sobre secondary-container
|
surface |
#f7faf9 |
#101414 |
Fondo de pantalla |
on-surface |
#181c1c |
#e0e3e3 |
Texto principal |
on-surface-variant |
#3e4948 |
#bec9c8 |
Texto secundario, labels |
surface-container |
#ebeeee |
#1d2020 |
Encabezado de tabla, fila resaltada |
surface-container-low |
#f1f4f4 |
#191c1c |
TopNav, tarjetas KPI |
surface-container-lowest |
#ffffff |
#0c0f0f |
Tarjetas, diálogos, campos |
outline |
#6e7979 |
#889392 |
Borde de campo y botón outlined |
outline-variant |
#bec9c8 |
#3e4948 |
Divisores, bordes sutiles |
error |
#ba1a1a |
#ffb4ab |
Error, acción destructiva |
error-container |
#ffdad6 |
#93000a |
Fondo de bloque de error |
Regla de pares. Un fill primary siempre lleva texto on-primary; nunca texto primary sobre fill primary. Los pares verificados en S7 cumplen WCAG 2.2 §1.4.3 AA: on-surface / surface 16.4:1, on-surface-variant / surface 8.9:1, on-primary / primary 9.3:1.
Deuda registrada. El helper de campos (
#6e7979sobre#f7faf9) da 4.28:1 a 12 px; AA exige 4.5:1. Corregir subiendo el tamaño o oscureciendo el token. Ver Cumplimiento axe/Nielsen.

Hanken Grotesk para UI, JetBrains Mono para montos e identificadores. No se usa Inter.
| Token | Fuente | Tamaño / interlineado | Uso |
|---|---|---|---|
display |
Hanken Grotesk Regular | 57 / 64 | Claim de marca (solo web pre-login) |
headline-lg |
Hanken Grotesk SemiBold | 32 / 40 | Título de pantalla (web) |
headline-lg-mobile |
Hanken Grotesk SemiBold | 28 / 36 | Título de pantalla (Android) |
headline-sm |
Hanken Grotesk Medium | 24 / 32 | Título de sección y de tarjeta |
title-md |
Hanken Grotesk Medium | 16 / 24 | Título de fila, etiqueta de campo |
body-lg |
Hanken Grotesk Regular | 16 / 24 | Texto corrido, valor de campo |
body-md |
Hanken Grotesk Regular | 14 / 20 | Texto secundario, ayuda |
label-md-tabular |
JetBrains Mono Medium | 12 / 16 | Montos, POL-88421, claves de idempotencia |
Por qué mono en cifras. Los dígitos tabulares alinean verticalmente en tablas y listas, y distinguen POL-90102 de texto corrido. Todo monto pasa por el formateador de locale: el núcleo entrega prima y código de moneda, el canal formatea (PL-01).
| Token | Valor | Uso |
|---|---|---|
sp-1 / spacing/xs
|
4 px | Separación mínima intra-componente |
sp-2 / spacing/sm
|
8 px | Inline entre elementos hermanos |
sp-3 |
12 px | Padding vertical de campo |
sp-4 / spacing/md
|
16 px | Padding de tarjeta, gutter móvil |
sp-5 |
20 px | Padding de tarjeta amplia |
sp-6 / spacing/lg
|
24 px | Gutter desktop, padding de panel |
sp-7 / spacing/xl
|
32 px | Separación entre secciones |
sp-8 |
40 px | Bloque mayor |
sp-10 |
64 px | Respiro de página |
El archivo móvil declara además padding/xs…xl con los mismos valores, para distinguir separación de relleno al bindear.
| Token | Valor | Uso |
|---|---|---|
radius/sm |
4 px | Chip pequeño, indicador |
radius/md / sm inputs
|
8 px | Campos, selects, notas |
radius/lg / lg cards
|
12 px | Tarjetas, tablas, paneles |
xl paneles |
16 px | Diálogos, hojas |
radius/full |
9999 px | Botones (pills), avatar, badges |
| Nivel 0 | sin sombra | Contenido plano |
| Nivel 1 | y:1 r:4 a:0.08 |
Tarjetas, TopNav |
| Nivel 2 | y:4 r:12 a:0.12 |
Diálogos web |
| Nivel 3 | — | Bottom sheets Android |
Breakpoint = ancho de canvas en el que cambia el layout web. No aplica a la app Android, que es nativa a 390.
| Ancho | Plataforma | Comportamiento |
|---|---|---|
| 390 | Web móvil | Una columna, hamburger → nav-menu / 390
|
| 768 | Tablet | Misma IA, gutters condensados |
| 1024 | Desktop | TopNav completo |
| 1440 | Desktop amplio | Canvas de referencia del diseño |
El back-office solo existe a 1440: es herramienta de escritorio.
Material Symbols (Rounded). El archivo móvil publica 15 iconos como componentes individuales bajo Icon/*:
placeholder · back · home · description · emergency_home · person · check · cancel · info · chevron_right · visibility · add · lock · menu · error
Un icono nunca comunica estado por sí solo: siempre lleva texto asociado.
Cada uno vive en su propia página del archivo de design system, con variantes formales y slots de texto expuestos como propiedades.
| Componente | Variantes | Propiedades | Uso |
|---|---|---|---|
Button |
Style: Filled · Tonal · Outlined · Text × State: Default · Disabled (8) |
Label |
Acción primaria, secundaria y terciaria |
IconButton |
Style: Default · On-surface (2) |
— | Acción compacta en barras |
TextField |
Style: Outlined · Filled × State: Default · Error · ReadOnly (6) |
Label, Value, Helper
|
Captura de datos |
Select |
Selected: 6 ramos × State: Closed · Open (12) |
— | Elección de ramo en cotización |
Chip |
Selected: True · False (2) |
— | Filtro de lista |
Switch |
Checked: True · False (2) |
— | Consentimientos, preferencias |
Banner |
Type: Info · Error (2) |
— | Aviso en pantalla, degradación |
StatusIcon |
Kind: Success · Error · Processing (3) |
— | Resultado de emisión y de aviso |
TopAppBar |
Variant: Root · Back (2) |
— | Barra superior |
BottomNav |
Selected: Inicio · Polizas · Siniestros · Perfil (4) |
— | Shell de cuatro destinos |
Card |
— | — | Contenedor de resumen |
ListRow |
— | — | Fila de lista |
FAB |
— | — | Reportar siniestro |
BottomSheet |
— | — | Overlays de Perfil |
Skeleton |
— | — | Carga |

Select con seis ramos. Las opciones son los ramos L1 renombrados tras la validación con usuario: Protección de dispositivo, Microseguro de vida, Clima y vuelos, Vida hipotecario, Pagos, Viaje. Reemplazan a «SOAT» y «Hogar», que no se entendían fuera de contexto colombiano.
Definidos en la página Chrome del archivo web.
| Componente | Variantes | Medidas | Uso |
|---|---|---|---|
Button |
Style: Filled · Outlined · Text |
padding 14/24, gap 8, radio full, texto Medium 16 | Acciones |
TopNav |
Selected: Inicio · Pólizas · Siniestros · Perfil |
1440 × 64, padding lateral 24 | Shell cliente desktop |
TopNavCompact |
Selected: los mismos 4 |
390 × 56 | Shell cliente móvil (hamburger) |
Footer |
— | 1440 × 88, padding 24/48 | Pie legal |

Estados de campo documentados en la galería: DEFAULT, FOCUS, ERROR (con mensaje) y DISABLED (40 % de opacidad). Badges de cliente: Vigente · En curso · Oferta · Rechazada · Pendiente. El stepper de emisión marca Cotizar → Oferta → Emisión → Póliza → Aviso.
Cuatro sets propios en la página Back-office · Asesor / Operador. Nacen porque el cliente administra sus pólizas mientras el asesor opera carteras de terceros: la arquitectura de información es distinta, no una variante de la de cliente.
| Componente | Variantes | Uso |
|---|---|---|
TopNavAdmin |
Selected: Clientes · Cotizaciones · Pólizas · Avisos |
Shell de back-office, con tag «Back-office», selector de rol y cerrar sesión |
BadgeBO |
Estado: En revisión · Aprobada · Rechazada · Pagada · Cancelada · Activo · Inactivo |
Estados que los badges de cliente no cubren |
DialogConfirm |
Estado: Default · MotivoVacio |
Confirmación destructiva con motivo obligatorio |
EmptyState |
Estado: ColaVacia · SinPermiso · SinClientes |
Sin contenido y sin permiso de rol |
Todos reutilizan Button y Footer del cliente como instancias, y bindean la misma colección Color: el back-office hereda el design system, no lo duplica.
| Patrón | Regla |
|---|---|
| Estado nunca solo por color | Todo badge y toda selección llevan texto o icono además del color |
| Monto en mono | Cifras e identificadores en JetBrains Mono, formateados por locale en el canal |
| Error en la misma vista | Un dato inválido se resuelve donde se capturó; no se navega ni se pierde lo escrito |
| Acción destructiva con motivo | Confirmación explícita + motivo obligatorio + aviso de irreversibilidad |
| Permiso JIT | El diálogo del SO aparece al usar la función, nunca en splash |
| Hit target ≥ 48 px | Botones a 49 px de alto (verificado en S7) |
82 frames en total. El identificador abre el frame directamente en Figma.
Canvas 390 × 844. Página Screens del archivo de design system.
| # | Pantalla | Shell | node-id | HU |
|---|---|---|---|---|
| 1 | splash-solventa |
A | 4:3 |
HU-95 |
| 2 | idioma-region |
A | 66:585 |
HU-94 |
| 3 | idioma-region-mx |
A | 128:777 |
HU-94 |
| 4 | onboarding |
A | 4:6 |
HU-45 |
| 5 | login |
A | 4:23 |
HU-90 |
| 6 | login-error |
A | 53:525 |
HU-90 |
| 7 | consentimiento-datos |
A | 4:49 |
HU-46 |
| 8 | inicio |
B | 4:138 |
HU-93 |
| 9 | nueva-cotizacion |
C | 4:181 |
HU-92 |
| 10 | ver-oferta |
C | 4:223 |
HU-11 |
| 11 | emision-progreso |
D | 4:261 |
HU-20 |
| 12 | poliza-emitida |
E | 4:275 |
HU-20 |
| 13 | suscripcion-rechazada |
D | 4:287 |
HU-99 |
| 14 | consentimiento-hipotecario |
C | 5:165 |
HU-53 |
| 15 | oferta-hipotecario |
C | 5:200 |
HU-57 |
| 16 | lista-polizas |
B | 5:239 |
HU-47 |
| 17 | detalle-poliza |
C | 5:297 |
HU-47 |
| 18 | aviso-vencimiento |
C | 5:349 |
HU-64 |
| 19 | aviso-renovacion |
C | 5:398 |
HU-65 |
| 20 | lista-siniestros |
B | 6:324 |
HU-31 |
| 21 | aviso-siniestro |
C | 6:394 |
HU-22 |
| 22 | evidencia-siniestro |
C | 6:451 |
HU-23 |
| 23 | confirmacion-siniestro |
C | 54:557 |
HU-97 |
| 24 | parametrico |
C | 6:500 |
HU-36 |
| 25 | hub-perfil |
B | 6:559 |
HU-91 |
Estados de permiso y denegación (HU-101, HU-24) — misma ruta, otra UI:
| # | Pantalla | node-id |
|---|---|---|
| 26 | permiso-camara |
70:677 |
| 27 | permiso-fotos |
70:692 |
| 28 | permiso-ubicacion |
66:592 |
| 29 | evidencia-camara-denegada |
70:707 |
| 30 | evidencia-geo-denegada |
66:599 |
Overlays (bottom sheets; cierran con Close y no empujan el NavHost): overlay-idioma-region [102:738] · overlay-permiso-ubicacion [102:782] · overlay-permiso-camara [102:811] · overlay-permiso-fotos [102:840] · overlay-consentimiento-datos [111:773] · overlay-consentimiento-vida-crediticia [111:784] · overlay-cerrar-sesion [54:768]
Canvas 1440. Página Screens.
| # | Pantalla | Shell | node-id | HU |
|---|---|---|---|---|
| 1 | login |
A | 4:15 |
HU-103 |
| 2 | idioma-region |
A | 4:32 |
HU-108 |
| 3 | idioma-region-mx |
A | 61:380 |
HU-108 |
| 4 | registro |
A | 4:55 |
HU-102 |
| 5 | consentimiento-datos |
A | 4:80 |
HU-115 |
| 6 | inicio |
B | 5:9 |
HU-109 |
| 7 | lista-polizas |
B | 5:43 |
HU-118 |
| 8 | lista-siniestros |
B | 5:72 |
HU-117 |
| 9 | hub-perfil |
B | 5:103 |
HU-106 |
| 10 | nueva-cotizacion |
C | 6:128 |
HU-104 |
| 11 | ver-oferta |
C | 6:162 |
HU-113 |
| 12 | emision-progreso |
D | 6:186 |
HU-114 |
| 13 | poliza-emitida |
E | 6:191 |
HU-114 |
| 14 | suscripcion-rechazada |
D | 6:199 |
HU-112 |
| 15 | detalle-poliza |
C | 7:122 |
HU-18 |
| 16 | aviso-vencimiento |
C | 7:145 |
HU-119 |
| 17 | aviso-renovacion |
C | 7:168 |
HU-120 |
| 18 | aviso-siniestro |
C | 7:191 |
HU-116 |
| 19 | evidencia-siniestro |
C | 7:216 |
HU-100 |
| 20 | evidencia-siniestro-geo |
C | 62:361 |
HU-100 |
| 21 | parametrico |
C | 7:241 |
HU-37 |
| 22 | consentimiento-hipotecario |
C | 7:265 |
HU-105 |
| 23 | oferta-hipotecario |
C | 7:292 |
HU-105 |
Overlays web (diálogos que cierran con Close, no rutas): overlay-idioma-region [7:318] · overlay-consentimiento-datos [7:326] · overlay-consentimiento-vida-crediticia [7:334] · overlay-cerrar-sesion [7:342] · overlay-ubicacion-navegador [62:391]
Responsive (página Responsive) — demuestra que la IA se conserva y solo cambia el layout:
| Ancho | Frames |
|---|---|
| 390 |
login [28:49] · inicio [28:68] · nav-menu [30:9] · lista-polizas [30:23] · lista-siniestros [30:38] · hub-perfil [30:51] |
| 768 |
login [30:117] · inicio [30:72] |
Canvas 1440, solo desktop. Página Back-office · Asesor / Operador.
| # | Pantalla | Rol | node-id | HU |
|---|---|---|---|---|
| 1 | bo-login |
ambos | 221:1128 |
— |
| 2 | shell-asesor |
asesor | 131:2 |
HU-8 |
| 3 | shell-asesor-sin-permiso |
asesor | 137:591 |
HU-8 |
| 4 | asesor-cotizacion |
asesor | 132:31 |
HU-10 |
| 5 | asesor-cotizacion-error |
asesor | 132:126 |
HU-10 |
| 6 | asesor-emision |
asesor | 134:79 |
HU-19 |
| 7 | asesor-emision-rechazo |
asesor | 134:161 |
HU-19 |
| 8 | bo-cola-avisos |
operador | 135:129 |
HU-26 |
| 9 | bo-cola-avisos-vacia |
operador | 135:247 |
HU-26 |
| 10 | bo-aviso-decision |
operador | 136:189 |
HU-27 |
| 11 | bo-aviso-decision-sin-motivo |
operador | 136:235 |
HU-27 |
| 12 | bo-pago-parametrico |
operador | 136:282 |
HU-29 |
| 13 | bo-pago-reintento |
operador | 136:357 |
HU-29 |
| 14 | bo-renovar-poliza |
operador | 137:312 |
HU-59 |
| 15 | bo-renovar-no-vigente |
operador | 137:381 |
HU-59 |
| 16 | bo-cancelar-poliza |
operador | 137:450 |
HU-61 |
| 17 | bo-cancelar-ya-cancelada |
operador | 137:519 |
HU-61 |
Gestión de clientes y listas (ampliación posterior del equipo):
| # | Pantalla | node-id |
|---|---|---|
| 18 | lista-cotizaciones |
213:465 |
| 19 | lista-polizas |
213:534 |
| 20 | lista-clientes-vacia |
213:879 |
| 21 | cliente-detalle |
213:603 |
| 22 | cliente-form |
213:672 |
| 23 | cliente-form-editar |
213:741 |
| 24 | cliente-baja |
213:810 |
Cotización por ramo — cinco variantes del formulario, una por ramo L1: asesor-cotizacion-viaje [254:1191] · -vida [254:1289] · -clima [254:1387] · -pagos [254:1485] · -hipotecario [254:1583]
| Asesor · cartera | Operador · cola de avisos |
|---|---|
![]() |
![]() |
Ambos archivos tienen una página Screens · S7 validación con la versión revisada tras la inspección de accesibilidad y la prueba con usuario: 34 frames en web y 39 en móvil. Cada uno cierra con su propio tablero de hallazgos — web 178:382, móvil 216:811.
Esta es la versión vigente para implementar el canal cliente. Las páginas
Screensoriginales quedan como historial del prototipo de la semana 6.
Qué cambió respecto a Screens
| Cambio | Heurística | Dónde se ve |
|---|---|---|
| Ramos renombrados: Protección de dispositivo · Microseguro de vida · Clima y vuelos · Vida hipotecario en lugar de SOAT y Hogar | H2 lenguaje del usuario | nueva-cotizacion |
| Indicador «paso N de 4» en el flujo de compra | H1 visibilidad del estado | cotización → oferta → emisión → póliza |
| Ayuda contextual y enlace al documento legal en cada consentimiento | H10 ayuda | consentimiento-* |
| «Pago automático» en lugar de «paramétrico»; habeas data con Ley 1581 de 2012 | H2 lenguaje del usuario |
parametrico, consentimiento-datos
|
| Columna Ramo en tablas y ramo + estado en cada fila | H6 reconocer antes que recordar | listas |
| 5 variantes de cotización, una por ramo | H4 consistencia | nueva-cotizacion-* |
Galería de los seis recorridos críticos (PDF §5.1) en ambos canales. El resto de frames se consulta en Figma.
Web · login
|
Web · registro
|
Web · consentimiento-datos
|
|---|---|---|
![]() |
![]() |
![]() |
Móvil · onboarding
|
Móvil · login
|
|---|---|
![]() |
![]() |
Web · idioma-region
|
Web · inicio
|
Móvil · idioma-region
|
Móvil · inicio
|
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Web · nueva-cotizacion
|
Web · ver-oferta
|
Web · poliza-emitida
|
|---|---|---|
![]() |
![]() |
![]() |
Móvil · nueva-cotizacion
|
Móvil · ver-oferta
|
Móvil · poliza-emitida
|
|---|---|---|
![]() |
![]() |
![]() |
El indicador «paso N de 4» y el CTA de continuidad cierran el salto Aceptar → Ver mi póliza que detectó la validación.
Web · aviso-siniestro
|
Móvil · aviso-siniestro
|
Móvil · permiso-camara
|
Móvil · evidencia-siniestro
|
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
La diferencia de canal se ve aquí: el móvil pide permiso JIT al usar la cámara; el web adjunta archivo y usa el prompt del navegador.
Web · parametrico
|
Móvil · parametrico
|
Web · oferta-hipotecario
|
Móvil · oferta-hipotecario
|
Web · detalle-poliza
|
|---|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
| Shell | Android | Web cliente | Back-office |
|---|---|---|---|
| A Pre-login |
NavigationBar oculta |
Sin TopNav de destinos; split 1440 / stacked 390 | bo-login |
| B Destino raíz | BottomNav, tab activo en secondary-container
|
TopNav, destino subrayado |
TopNavAdmin, destino subrayado |
| C Anidada | BottomNav del tab padre | TopNav del padre + ← Volver | TopNavAdmin del padre + ← Volver |
| D / E Emisión · resultado | Nav oculta | Nav oculta | Nav visible: el asesor puede atender otro caso |
| Overlay | Bottom sheet, cierra con Close | Diálogo, cierra con Close |
DialogConfirm sobre scrim |
flowchart TB
Splash["splash-solventa"] --> Idioma["idioma-region"]
Idioma -->|"Mexico"| IdiomaMx["idioma-region-mx<br/>$1,234.56 MXN"]
Idioma --> Onboarding["onboarding<br/>datos + documento"]
IdiomaMx --> Onboarding
Idioma -->|"Ya tengo cuenta"| Login["login"]
Onboarding --> Consent["consentimiento-datos<br/>habeas data"]
Consent --> Inicio["inicio"]
Login -->|"credenciales invalidas"| LoginErr["login-error<br/>estado, no ruta"]
LoginErr --> Login
Login -->|"exito"| Inicio
Inicio -->|"CTA Nueva cotizacion"| Cotizar["nueva-cotizacion<br/>paso 1 de 4"]
Cotizar --> Oferta["ver-oferta<br/>prima, moneda, venceEn"]
Oferta -->|"vencida"| Cotizar
Oferta -->|"Aceptar"| Emision["emision-progreso"]
Emision -->|"aprobada"| Emitida["poliza-emitida"]
Emision -->|"rechazada HU-13"| Rechazo["suscripcion-rechazada<br/>motivo persistido"]
Emitida -->|"Ver mi poliza"| Detalle["detalle-poliza"]
Emitida -->|"Ir al inicio"| Inicio
Rechazo --> Inicio
classDef navOff fill:#ffdad6,stroke:#ba1a1a,color:#410002
class Splash,Idioma,IdiomaMx,Onboarding,Consent,Login,LoginErr,Emision,Emitida,Rechazo navOff
Los nodos en rojo tienen la NavigationBar oculta: shell A pre-login y shell D/E durante la emisión. El cliente no puede cambiar de tab a mitad del proceso.
flowchart TB
Lista["lista-siniestros<br/>destino raiz"] -->|"FAB Reportar"| Aviso["aviso-siniestro<br/>formulario + foto"]
Aviso -->|"adjuntar foto"| PermCam{"permiso-camara<br/>dialogo del SO"}
PermCam -->|"Permitir"| Evidencia["evidencia-siniestro"]
PermCam -->|"Denegar"| PermFotos{"permiso-fotos<br/>galeria"}
PermFotos -->|"Permitir"| Evidencia
PermFotos -->|"Denegar"| SinCam["evidencia-camara-denegada<br/>misma ruta, otra UI"]
Evidencia -->|"geoetiquetar"| PermGps{"permiso-ubicacion"}
PermGps -->|"Permitir"| ConGps["evidencia con GPS"]
PermGps -->|"No permitir"| SinGps["evidencia-geo-denegada<br/>misma ruta, otra UI"]
ConGps --> Confirma["confirmacion-siniestro<br/>siniestroId"]
SinGps --> Confirma
SinCam --> Confirma
Confirma --> Lista
Confirma --> Inicio["inicio"]
classDef permiso fill:#cce8e7,stroke:#005050,color:#00201f
classDef degradado fill:#ffdad6,stroke:#ba1a1a,color:#410002
class PermCam,PermFotos,PermGps permiso
class SinCam,SinGps degradado
Tres reglas que el diagrama hace explícitas:
- El permiso se pide al usar la función, nunca en splash ni al instalar (PDF §5.2).
-
Todos los caminos llegan a
confirmacion-siniestro: ningún permiso denegado bloquea el envío del aviso. - Denegar no crea una ruta nueva — es la misma pantalla con otra UI.
flowchart LR
Inicio["inicio<br/>card Vida Crediticia"] --> Consent{"consentimiento-hipotecario<br/>perfilamiento"}
Consent -->|"No otorgar"| Inicio
Consent -->|"Otorgar"| Adaptador["HU-54 adaptadores<br/>Open Finance / Open Data"]
Adaptador -->|"responde a tiempo"| OfertaOk["oferta-hipotecario"]
Adaptador -->|"falla o excede el limite"| OfertaDeg["oferta-hipotecario<br/>banner de degradacion"]
OfertaOk -->|"Aceptar"| Emision["emision HU-20"]
OfertaDeg -->|"Aceptar"| Emision
classDef degradado fill:#ffdad6,stroke:#ba1a1a,color:#410002
class OfertaDeg degradado
Sin consentimiento no se invoca ningún adaptador. Si el perfilamiento se degrada (HU-56), la oferta se entrega igual con valor de respaldo y el banner lo advierte: la degradación nunca es silenciosa ni cancela la originación.
flowchart TB
Login["login"] --> Inicio["inicio"]
Inicio --> Polizas["lista-polizas"]
Inicio --> Siniestros["lista-siniestros"]
Inicio --> Perfil["hub-perfil"]
Inicio -->|"CTA Nueva cotizacion"| Cotizar["nueva-cotizacion"]
Polizas --> Detalle["detalle-poliza<br/>solo lectura"]
Detalle --> AvisoV["aviso-vencimiento"]
Detalle --> AvisoR["aviso-renovacion"]
Siniestros --> AvisoS["aviso-siniestro"]
AvisoS --> Evidencia["evidencia-siniestro<br/>archivo adjunto"]
Evidencia -->|"Usar ubicacion del navegador"| Prompt{"overlay-ubicacion-navegador"}
Prompt -->|"Permitir"| Geo["evidencia-siniestro-geo"]
Prompt -->|"Bloquear"| Evidencia
Perfil --> Overlays["overlays: idioma,<br/>consentimientos, cerrar sesion"]
Cotizar --> Oferta["ver-oferta"]
Oferta -->|"Aceptar"| Emision["emision-progreso"]
Emision --> Emitida["poliza-emitida"]
Emitida --> Detalle
classDef navOff fill:#ffdad6,stroke:#ba1a1a,color:#410002
classDef overlay fill:#ebeeee,stroke:#6e7979,color:#181c1c
class Emision,Emitida navOff
class Prompt,Overlays overlay
En 390 el TopNav colapsa a hamburger → nav-menu / 390, con los mismos cuatro destinos. Los overlays son diálogos que cierran con Close, no rutas: no empujan el historial.
Diferencia con Android: aquí la evidencia es un archivo adjunto y la ubicación usa el prompt del navegador, no el permiso del sistema operativo.
flowchart TB
BoLogin["bo-login"] --> Shell["shell-asesor<br/>Mi cartera: KPIs + cola"]
Shell --> Clientes["Clientes"]
Shell --> Cotizaciones["Cotizaciones"]
Shell --> PolizasBO["Polizas"]
Shell --> Avisos["Avisos"]
Clientes --> ListaCli["lista-clientes-vacia<br/>cliente-detalle"]
ListaCli --> FormCli["cliente-form<br/>cliente-form-editar"]
ListaCli --> Baja["cliente-baja"]
Cotizaciones --> ListaCot["lista-cotizaciones"]
ListaCot --> Cotiza["asesor-cotizacion<br/>5 variantes por ramo"]
Cotiza -->|"dato invalido"| CotErr["asesor-cotizacion-error<br/>CTA bloqueado"]
CotErr --> Cotiza
Cotiza -->|"Continuar a emision"| EmisionBO["asesor-emision<br/>stepper"]
EmisionBO -->|"aprobada"| PolizaOk["poliza emitida"]
EmisionBO -->|"rechazada"| EmisionRech["asesor-emision-rechazo"]
PolizasBO --> ListaPol["lista-polizas"]
ListaPol --> Renovar["bo-renovar-poliza"]
ListaPol --> Cancelar["bo-cancelar-poliza"]
Renovar -->|"no vigente"| RenovarNo["bo-renovar-no-vigente<br/>bloqueo"]
Cancelar -->|"ya cancelada"| CancelarNo["bo-cancelar-ya-cancelada<br/>bloqueo"]
Avisos --> Cola["bo-cola-avisos<br/>bo-cola-avisos-vacia"]
Cola -->|"Rechazar"| Decision{"bo-aviso-decision<br/>modal sobre la cola"}
Decision -->|"sin motivo"| SinMotivo["bo-aviso-decision-sin-motivo<br/>CTA deshabilitado"]
SinMotivo --> Decision
Decision -->|"con motivo"| Cola
Cola -->|"Aprobar"| Pago["bo-pago-parametrico"]
Pago -->|"reintento misma clave"| Reintento["bo-pago-reintento<br/>mismo comprobante"]
Shell -.->|"rol sin permiso"| SinPermiso["shell-asesor-sin-permiso<br/>conserva el shell"]
classDef bloqueo fill:#ffdad6,stroke:#ba1a1a,color:#410002
classDef modal fill:#ebeeee,stroke:#6e7979,color:#181c1c
class CotErr,RenovarNo,CancelarNo,SinMotivo,SinPermiso bloqueo
class Decision modal
Los nodos en rojo son bloqueos de negocio, no errores técnicos: el CTA queda deshabilitado y la pantalla explica por qué, con una salida alternativa. shell-asesor-sin-permiso conserva el TopNavAdmin y solo sustituye el contenido — es la consecuencia visible de la autorización del servidor (HU-75), no su implementación.
A diferencia del cliente, el asesor conserva la navegación durante la emisión: puede atender otro caso sin perder el progreso.
Los canales no son la misma interfaz redimensionada. Estas diferencias son deliberadas y se validan con pruebas de regresión visual.
| Aspecto | Android | Web cliente | Back-office |
|---|---|---|---|
| Navegación |
NavigationBar inferior, 4 tabs |
TopNav superior; hamburger en 390 |
TopNavAdmin, 4 destinos + rol |
| Evidencia | Cámara y galería del SO, GPS | Archivo adjunto, geolocalización del navegador | Solo lectura de la evidencia del cliente |
| Permisos | Diálogo nativo JIT | Prompt del navegador | No aplica |
| Perfil | Bottom sheets | Diálogos | Selector de rol (lectura) |
| i18n |
values-es-rMX / rCL / rPE
|
@angular/localize |
Hereda locale del usuario |
| Anchos | 390 nativo | 390 · 768 · 1024 · 1440 | Solo 1440 |
| Emisión | Nav oculta (shell D/E) | Nav oculta | Nav visible |
Ni el cliente web ni el móvil tienen campana de notificaciones ni destinos Open Finance / Risk Analysis.
| Figma | Android (Compose) | Web (AngularJS) |
|---|---|---|
Button |
Button / FilledTonalButton / OutlinedButton / TextButton M3 |
<solv-button style="filled|outlined|text"> |
TextField |
OutlinedTextField con isError y supportingText
|
<solv-textfield> con estados default/focus/error/disabled |
BottomNav / TopNav
|
NavigationBar + NavHost
|
Componente de layout con destino activo subrayado |
Chip / Select
|
FilterChip / ExposedDropdownMenuBox
|
<solv-chip> / <select> accesible |
BottomSheet |
ModalBottomSheet |
<dialog> con foco atrapado |
StatusIcon / Banner
|
Composable de estado | Componente de alerta con role="status"
|
BadgeBO |
— (no aplica) | <solv-badge estado="..."> |
DialogConfirm |
— (no aplica) |
<dialog> con motivo obligatorio |
Tokens como código. La colección Color tiene modos Light/Dark: en Android se exporta a Theme.kt / colors.xml (values-night), y en web a custom properties bajo prefers-color-scheme. El valor nunca se escribe a mano en un componente.
-
El canal formatea, el núcleo no. El núcleo entrega prima y código de moneda;
NumberFormat/Intlaplican el locale. Cambiar de locale no cambia la prima. - El canal no inventa estado. Emisión, suscripción y siniestro muestran el estado real del núcleo. Si el núcleo rechazó, nunca se muestra «emitida».
-
Idempotencia visible. Reintentar un pago o un aviso devuelve el mismo comprobante o
siniestroId; la UI lo comunica en vez de ocultarlo. -
Autorización en el servidor. Ocultar un botón no es un control:
shell-asesor-sin-permisorefleja lo que el servidor ya denegó (HU-75). - Estado nunca solo por color, y contraste AA en los pares del design system.
- Permisos JIT, nunca en splash, y denegar jamás bloquea el recorrido.
El canal web consume :BFFWeb y el móvil :BFFMovil; ninguno llama al núcleo directamente. Cada BFF valida el JWT que emite ms-identidad y expone payloads pensados para su pantalla — el móvil los lleva acotados por operar en redes variables. Ver Vista funcional y Backlog BFF.
- Portal de socio (aliados): no diseñado.
- Back-office en 768 / 390: es herramienta de escritorio.
- axe-core y TalkBack no corren sobre Figma; la verificación automatizada queda para el canal implementado (PF2).
- Modo oscuro: los tokens existen en ambos modos, pero las pantallas están compuestas en Light.

























