Design
P0
Flujos de Usuario
Para qué

Rutas completas del usuario a través del producto, incluyendo happy paths, error paths y priorización.

Audiencia

Diseño, ingeniería y QA.

Flow: Authentication

Acceso Seguro a la Plataforma

JTBD: “Cuando quiero acceder a mi salud, quiero entrar rápido y seguro”
Actor: Usuario (nuevo o existente)
Trigger: Abrir la app
Priority: P0 (Critical — gate to everything)
Duration: <30 segundos (returning user) | 2-3 minutos (new user)


Happy Path: Login Completo

Flujo completo de login: verificacion de sesion, magic link, codigo de invitacion y social login


Error Paths

Path 1: Email no registrado (sin código de invitación)

Error: email no registrado, flujo con codigo de invitacion o solicitud de acceso

Error: magic link expirado con opciones de reenvio o volver al inicio

Path 3: Cuenta bloqueada (brute force)

Error: cuenta bloqueada tras 5 intentos fallidos, auto-desbloqueo o soporte

Path 4: Social login — email ya registrado con otro método

Error: social login con email ya registrado por otro metodo, login o vincular cuentas


Screen 1: Login

Propósito: Punto de entrada único — email-first flow con magic link

+---------------------------------------------+
| ADEN Logo (centrado)                        |
|                                             |
| "Medicina preventiva personalizada"         |
|                                             |
| [Login]  [Registrarse]          <- tabs     |
|                                             |
| Correo electrónico                          |
| +------------------------------------------+
| | maria@ejemplo.com                        |
| +------------------------------------------+
| Te enviaremos un enlace para ingresar       |
|                                             |
| [        CONTINUAR        ]     <- #0f2fc7 |
|                                             |
| -------- o continua con --------            |
|                                             |
| [G]  Continuar con Google                   |
| [A]  Continuar con Apple                    |
|                                             |
| No tienes cuenta? Registrate                |
+---------------------------------------------+

Happy path:

  1. Usuario ingresa email
  2. Email encontrado en DB → magic link enviado → redirect a verify-email
  3. Email no encontrado → muestra pantalla de código de invitación

Validaciones:

  • Email: RFC 5322, 3-254 chars, required
  • Error inline: “Email inválido” (formato incorrecto)

Copy:

  • Título: “Medicina preventiva personalizada”
  • CTA: “Continuar”
  • Helper: “Te enviaremos un enlace para ingresar”
  • Social: “o continua con”
  • Footer: “No tienes cuenta? Registrate”

Transitions:

  • Email existe → /auth/verify-email (magic link sent)
  • Email no existe → Invitation code form (same page, step 2)
  • Social login → OAuth flow → Dashboard (existing) or Register (new)
  • Tab “Registrarse” → /auth/register

Step 2: Código de Invitación (inline, misma página)

+---------------------------------------------+
|         [icono llave, bg #e8ebf8]           |
|                                             |
| "No encontramos una cuenta con ese email."  |
| "Si tienes un código de invitación,         |
|  ingresalo aquí."                           |
|                                             |
| Código de invitación                        |
| +------------------------------------------+
| | ADEN-XXXX-XXXX                           |
| +------------------------------------------+
|                                             |
| [  VOLVER  ]       [  VERIFICAR  ]         |
+---------------------------------------------+

Validaciones:

  • Código: formato ADEN-XXXX-XXXX, required
  • Error: “Código inválido” | “Código ya utilizado” | “Código expirado”

Transitions:

  • Código válido → /auth/register?email=... (pre-fill)
  • “Volver” → Step 1 (email form)

Screen 2: Registro

Propósito: Crear cuenta nueva con datos mínimos

+---------------------------------------------+
| ADEN Logo (centrado)                        |
|                                             |
| "Medicina preventiva personalizada"         |
|                                             |
| [Login]  [Registrarse]          <- tabs     |
|                                             |
| Nombre completo                             |
| +------------------------------------------+
| | María Garcia                             |
| +------------------------------------------+
|                                             |
| Correo electrónico                          |
| +------------------------------------------+
| | maria@ejemplo.com          <- pre-filled |
| +------------------------------------------+
|                                             |
| Código de invitación                        |
| +------------------------------------------+
| | ADEN-XXXX-XXXX                           |
| +------------------------------------------+
| Te enviaremos un enlace para verificar      |
| tu cuenta                                   |
|                                             |
| [x] Acepto los Terminos y Condiciones      |
|     y la Politica de Privacidad             |
|                                             |
| [        CONTINUAR        ]     <- #0f2fc7 |
|                                             |
| Ya tienes cuenta? Inicia sesión             |
+---------------------------------------------+

Happy path:

  1. Campos pre-filled si viene de login (email) o invitation (código)
  2. Usuario completa nombre, acepta terminos
  3. Submit → cuenta creada → redirect a verify-email

Validaciones (from edge-cases.md):

Campo Regla Error
Nombre Required, 2-100 chars, letras/números/espacios/guiones “Mínimo 2 caracteres” / “Caracteres no permitidos”
Email Required, RFC 5322, 3-254 chars, unique “Email inválido” / “Email ya registrado”
Código Required, formato ADEN-XXXX-XXXX “Código inválido”
Terminos Required checkbox “Debes aceptar los terminos”

Error paths:

  • Email ya registrado → “Email ya registrado” + links “Iniciar sesión” / “Olvidaste contraseña?” / “Usar otro email”
  • Security: no revelar si el email existe vía timing; response time uniforme

Copy:

  • Título: “Medicina preventiva personalizada”
  • CTA: “Continuar”
  • Helper: “Te enviaremos un enlace para verificar tu cuenta”
  • Terminos: “Acepto los Terminos y Condiciones y la Politica de Privacidad”
  • Footer: “Ya tienes cuenta? Inicia sesión”

Transitions:

  • Éxito → /auth/verify-email
  • “Terminos y Condiciones” → /auth/terms (view-only)
  • “Politica de Privacidad” → /auth/privacy (view-only)
  • “Inicia sesión” → /auth

Screen 3: Verificar Email

Propósito: Confirmar que el usuario controla el email ingresado

+---------------------------------------------+
|      [icono email, bg #e8ebf8, grande]      |
|                                             |
|   "Verifica tu correo electrónico"          |
|                                             |
|   Hemos enviado un enlace de                |
|   verificación a                            |
|   maria@ejemplo.com                         |
|                                             |
|   Revisa tu bandeja de entrada y haz        |
|   clic en el enlace para continuar.         |
|                                             |
|   -----------------------------------------|
|                                             |
|   No recibiste el correo?                   |
|                                             |
|   [      REENVIAR ENLACE      ]  <- outline |
|                                             |
|   Email incorrecto? Cambiar email           |
|                                             |
|   <- Volver a iniciar sesión                |
+---------------------------------------------+

Happy path:

  1. Post-registro: usuario ve esta pantalla
  2. Abre email → click magic link → token validado → redirect
  3. Si es nuevo usuario → Onboarding Step 1
  4. Si es usuario existente (magic link login) → Dashboard

Resend logic:

  • Click “Reenviar enlace” → nuevo email enviado
  • Visual feedback: botón cambia a “Enlace reenviado” (verde, 3s)
  • Rate limit: max 3 reenvios por hora por email
  • Cooldown visual: botón deshabilitado 60s después de cada reenvio

Error paths:

  • Email no llega (user waits) → sugerencia “Revisa tu carpeta de spam”
  • Email no llega después de 24h → ver CASE 2 en edge-cases:
    • Day 1: Email de verificación (normal)
    • Day 2: Reminder email + in-app banner
    • Day 3: Block access → “Verifica tu email para continuar”
    • Day 7: Auto-delete account (unverified)

Copy:

  • Título: “Verifica tu correo electrónico”
  • Body: “Hemos enviado un enlace de verificación a [email]”
  • Helper: “Revisa tu bandeja de entrada y haz clic en el enlace para continuar.”
  • Resend: “No recibiste el correo?” / “Reenviar enlace”
  • Confirm: “Enlace reenviado”
  • Fix: “Email incorrecto? Cambiar email”

Transitions:

  • Magic link clicked → Dashboard (existing) o Onboarding (new)
  • “Cambiar email” → /auth/register
  • “Volver a iniciar sesión” → /auth

Screen 4: Olvide Contraseña

Propósito: Permitir recuperación de acceso vía email

+---------------------------------------------+
|                                             |
|   "Recuperar contraseña"                    |
|                                             |
|   Ingresa tu correo electrónico y te        |
|   enviaremos un enlace para restablecer     |
|   tu contraseña.                            |
|                                             |
|   Correo electrónico                        |
|   +----------------------------------------+
|   | maria@ejemplo.com                      |
|   +----------------------------------------+
|                                             |
|   [      ENVIAR ENLACE      ]   <- #0f2fc7 |
|                                             |
|   <- Volver a iniciar sesión                |
+---------------------------------------------+

Estado éxito (reemplaza form):

+---------------------------------------------+
|      [icono check, bg emerald-100]          |
|                                             |
|   "Correo enviado"                          |
|                                             |
|   Revisa tu bandeja de entrada y sigue      |
|   las instrucciones para restablecer        |
|   tu contraseña.                            |
|                                             |
|   No lo ves? Revisa tu carpeta de spam.     |
|                                             |
|   <- Volver a iniciar sesión                |
+---------------------------------------------+

Happy path:

  1. Usuario ingresa email
  2. Submit → email enviado (siempre muestra éxito, incluso si email no existe — security)
  3. Email contiene link → click → pantalla reset password → nueva contraseña → login

Rate limit (from edge-cases.md):

  • Max 3 solicitudes por hora por email
  • Si excede: “Espera 1 hora antes de intentar de nuevo”

Validaciones:

  • Email: RFC 5322, required
  • Error: “Email inválido” (formato)

Security:

  • Siempre mostrar estado de éxito (no revelar si email existe o no)
  • Reset link expira en 1 hora
  • Link es de un solo uso

Copy:

  • Título: “Recuperar contraseña”
  • Body: “Ingresa tu correo electrónico y te enviaremos un enlace para restablecer tu contraseña.”
  • CTA: “Enviar enlace”
  • Success título: “Correo enviado”
  • Success body: “Revisa tu bandeja de entrada y sigue las instrucciones para restablecer tu contraseña.”
  • Spam hint: “No lo ves? Revisa tu carpeta de spam.”
  • Back: “Volver a iniciar sesión”

Transitions:

  • Submit → Success state (misma página, form se oculta)
  • “Volver a iniciar sesión” → /auth

Screen 5: MFA Setup

Propósito: Seguridad adicional opcional (recomendada)

Trigger: Ofrecido durante onboarding (post-verificación) o desde Ajustes

+---------------------------------------------+
|                                             |
|   "Protege tu cuenta"                       |
|                                             |
|   Agrega una capa extra de seguridad.       |
|   Te pediremos un código adicional al       |
|   iniciar sesión.                           |
|                                             |
|   Elige tu método:                          |
|                                             |
|   +----------------------------------------+
|   | [icono phone]                          |
|   | SMS                                    |
|   | Recibe un código por mensaje de texto  |
|   +----------------------------------------+
|                                             |
|   +----------------------------------------+
|   | [icono shield]                         |
|   | App de autenticación                   |
|   | Google Authenticator, Authy, etc.      |
|   +----------------------------------------+
|                                             |
|   [    CONFIGURAR    ]          <- #0f2fc7 |
|   [    AHORA NO      ]         <- outline  |
|                                             |
|   Puedes configurar esto después en        |
|   Ajustes > Seguridad                       |
+---------------------------------------------+

MFA: Flujo SMS

+---------------------------------------------+
|   "Verificar tu teléfono"                   |
|                                             |
|   Número de teléfono                        |
|   +----------------------------------------+
|   | +57 | 300 123 4567                     |
|   +----------------------------------------+
|                                             |
|   [  ENVIAR CODIGO  ]          <- #0f2fc7  |
+---------------------------------------------+

          |  (SMS enviado)
          v

+---------------------------------------------+
|   "Ingresa el código"                       |
|                                             |
|   Enviamos un código a +57 ***4567          |
|                                             |
|   [ _ ] [ _ ] [ _ ] [ _ ] [ _ ] [ _ ]      |
|                                             |
|   No recibiste el código? Reenviar (45s)    |
|                                             |
|   [  VERIFICAR  ]              <- #0f2fc7  |
+---------------------------------------------+

MFA: Flujo App Autenticador

+---------------------------------------------+
|   "Configura tu app de autenticación"       |
|                                             |
|   1. Abre tu app (Google Authenticator,     |
|      Authy, etc.)                           |
|   2. Escanea este código QR:                |
|                                             |
|   +--------+                                |
|   | QR     |                                |
|   | CODE   |                                |
|   +--------+                                |
|                                             |
|   No puedes escanear? Usa este código:      |
|   ABCD-EFGH-IJKL-MNOP                      |
|                                             |
|   3. Ingresa el código de 6 digitos:        |
|   [ _ ] [ _ ] [ _ ] [ _ ] [ _ ] [ _ ]      |
|                                             |
|   [  VERIFICAR  ]              <- #0f2fc7  |
+---------------------------------------------+

Happy path:

  1. Usuario elige método (SMS o app)
  2. Completa verificación
  3. Codigos de respaldo generados (10 codigos de un solo uso)
  4. Confirmación: “MFA activado”

Error paths:

  • Código SMS incorrecto → “Código incorrecto. Intenta de nuevo.” (max 3 intentos)
  • Código app incorrecto → “Código incorrecto. Asegurate de que el reloj de tu teléfono este sincronizado.”
  • SMS no llega → “Reenviar” (cooldown 45s, max 3 reenvios)
  • Teléfono no válido → “Número de teléfono inválido”

Codigos de respaldo:

+---------------------------------------------+
|   "Guarda tus codigos de respaldo"          |
|                                             |
|   Si pierdes acceso a tu método de MFA,     |
|   usa uno de estos codigos para entrar.     |
|                                             |
|   +----------------------------------------+
|   | a1b2-c3d4    e5f6-g7h8                 |
|   | i9j0-k1l2    m3n4-o5p6                 |
|   | q7r8-s9t0    u1v2-w3x4                 |
|   | y5z6-a7b8    c9d0-e1f2                 |
|   | g3h4-i5j6    k7l8-m9n0                 |
|   +----------------------------------------+
|                                             |
|   [COPIAR]  [DESCARGAR]                     |
|                                             |
|   Cada código solo se puede usar una vez.   |
|                                             |
|   [  LISTO  ]                   <- #0f2fc7 |
+---------------------------------------------+

Transitions:

  • “Ahora no” → continua onboarding / dashboard
  • MFA completado → codigos de respaldo → onboarding / dashboard
  • Desde Ajustes → Ajustes > Seguridad (return)

Screen 6: Terminos y Condiciones / Politica de Privacidad

Propósito: Documentos legales requeridos, view-only

Terminos y Condiciones

+---------------------------------------------+
| [<]  Terminos y Condiciones                 |
|      Actualizado: 15 Enero 2026             |
|---------------------------------------------|
|                                             |
| 1. Aceptación de los Términos               |
| Al acceder y utilizar la plataforma ADEN,   |
| usted acepta estar sujeto a estos...        |
|                                             |
| 2. Descripción del Servicio                 |
| ADEN es una plataforma de medicina          |
| preventiva personalizada que ofrece...      |
|                                             |
| 3. Datos de Salud                           |
| ...                                         |
|                                             |
| 4. Privacidad y Seguridad                   |
| ...                                         |
|                                             |
| 5. Responsabilidad                          |
| ...                                         |
+---------------------------------------------+

Politica de Privacidad

+---------------------------------------------+
| [<]  Politica de Privacidad                 |
|      Actualizado: 15 Enero 2026             |
|---------------------------------------------|
|                                             |
| 1. Información que Recopilamos              |
| +----------+ +----------+ +----------+      |
| | Personal | | Salud    | | Uso      |      |
| | Nombre,  | | Labs,    | | Páginas, |      |
| | email... | | historial| | clicks.. |      |
| +----------+ +----------+ +----------+      |
|                                             |
| 2. Como Usamos tu Información               |
| ...                                         |
|                                             |
| 3. Tus Derechos (Habeas Data)               |
| ...                                         |
+---------------------------------------------+

Behavior:

  • View-only, scroll
  • Back button → return to registration
  • No user action required (acceptance is vía checkbox on registration)
  • Last updated date visible in header

Transitions:

  • Back button → /auth/register

Biometric Authentication Flow (Returning Users)

ADEN uses device biometrics (FaceID / TouchID) for returning users who have previously authenticated.

Flow Diagram

Flujo de autenticacion biometrica: FaceID/TouchID con fallback a magic link

Smart Login (Remember User)

+---------------------------------------------+
|                                             |
|      [Avatar María]                         |
|                                             |
|   "Hola, María"                             |
|                                             |
|      [FaceID icon]                          |
|   Toca para ingresar                        |
|                                             |
|   No eres María? Usar otra cuenta           |
+---------------------------------------------+

Rules:

  • Biometric enabled after first successful login (user opt-in prompt)
  • Biometric bypasses email entry but NOT session refresh
  • If device biometric changes (e.g., new fingerprint added), invalidate stored credentials
  • If app not opened for >30 days, require full re-authentication
  • “Usar otra cuenta” → clears stored credentials, shows full login

URL format: https://app.aden.health/auth/verify?token=abc123&type=email_verification

Flow:
  1. User taps link in email client
  2. App installed?
     → Yes: Universal link → app opens → token validated → redirect
     → No: Web fallback → browser → token validated → app store prompt

  3. Token validation:
     → Valid: Account verified → redirect to next step
     → Expired (>24h): "Este enlace ya expiro. Reenviar enlace."
     → Invalid: "Enlace invalido. Volver al inicio."
     → Already used: "Tu cuenta ya está verificada. Iniciar sesión."
URL format: https://app.aden.health/auth/reset?token=xyz789&type=password_reset

Flow:
  1. User taps link in email client
  2. Token validation:
     → Valid: Show new password form
     → Expired (>1h): "Este enlace ya expiro. Solicitar nuevo enlace."
     → Invalid: "Enlace invalido."
     → Already used: "Este enlace ya fue utilizado."
URL format: https://app.aden.health/auth/login?token=def456&type=magic_link

Flow:
  1. User taps link in email client
  2. Token validation:
     → Valid (<15min): Session created → Dashboard
     → Expired (>15min): "Este enlace ya expiro. Solicitar nuevo enlace."
     → Invalid: "Enlace invalido."

Session Management

Token Architecture

Access Token:
  - Type: JWT
  - Expiry: 15 minutes
  - Storage: Memory only (not localStorage)
  - Refresh: Automatic vía refresh token

Refresh Token:
  - Type: Opaque
  - Expiry: 30 days
  - Storage: Secure httpOnly cookie
  - Rotation: New refresh token on each use (old one invalidated)

Biometric Token:
  - Type: Device-bound credential
  - Storage: Secure Enclave (iOS) / Keystore (Android)
  - Expiry: 30 days (or until biometric change detected)

Session Lifecycle

Ciclo de vida de la sesion: auto-refresh, logout, invalidacion por seguridad

Logout

Explicit logout:
  1. Clear access token (memory)
  2. Revoke refresh token (server-side)
  3. Clear biometric credential
  4. Redirect to login

Implicit logout (session expired):
  1. Show: "Tu sesión expiró"
  2. Options: [Iniciar sesión] 
  3. Preserve current URL for post-login redirect

Security Considerations

Brute Force Protection

Login attempts (per email):
  - 1-3 attempts: Normal
  - 4th attempt: CAPTCHA required
  - 5th attempt: Account locked 15 minutes
  - 10th attempt: Account locked 1 hour + email notification
  - 20th attempt: Account locked indefinitely + security team notified

IP-based throttling:
  - 100 login attempts per IP per hour (across all accounts)
  - Exceeded: IP blocked 1 hour + logged

Account Lockout

Trigger: 5 failed login attempts

Behavior:
  1. Lock account for 15 minutes
  2. Show: "Tu cuenta está bloqueada temporalmente por seguridad. Intenta de nuevo en 15 minutos."
  3. Send email: "Detectamos varios intentos de inicio de sesión fallidos. Si no fuiste tu, te recomendamos cambiar tu contraseña."
  4. CTA in email: [Cambiar contraseña] [Fui yo, ignorar]

Auto-unlock: After 15 minutes
Manual unlock: Vía password reset link

Rate Limits (Auth-specific)

Action Limit Window Error Message
Login attempts 5 per email 15 min “Cuenta bloqueada temporalmente”
Magic link requests 3 per email 1 hour “Espera un momento antes de solicitar otro enlace”
Password reset 3 per email 1 hour “Espera 1 hora antes de intentar de nuevo”
Email verification resend 3 per email 1 hour “Enlace reenviado. Revisa tu bandeja.”
MFA code attempts 3 per session Per attempt “Código incorrecto. Intenta de nuevo.”
Registration (per IP) 5 accounts 24 hours “Demasiados registros desde esta ubicación”

Additional Security Measures

- HTTPS only (HSTS enforced)
- CSRF tokens on all forms
- Content Security Policy headers
- Input sanitization (XSS prevention)
- SQL injection prevention (parameterized queries)
- Timing-attack prevention on email lookups (constant-time response)
- Magic links: single-use, short-lived (15min)
- Password reset links: single-use, 1 hour expiry
- Session invalidation on password change (all devices)
- Device fingerprinting for suspicious login detection
- Geo-anomaly detection (login from new country → email alert)

Critical Metrics

Métrica Meta Impacto
Login → Dashboard <5s (returning) Friction kills retention
Registration completion >85% Funnel health
Email verification rate >90% (Day 1) Unverified = lost user
Magic link click-through >80% Email deliverability
Biometric adoption >60% (prompted users) Reduces friction
MFA adoption >30% (optional) Security posture
Account lockout rate <1% Indicates UX or attack issues
Password reset usage <5% monthly High = password UX problem

Implementation Notes

  • Validation: En vivo, per-field (no esperar al final)
  • Skeleton loading: 260-500ms en primera carga
  • FadeInUp animations: 260ms per element, staggered 0.2s
  • Copy: Español colombiano, sin jerga técnica
  • Error recovery: Siempre opción de “atrás” o contactar soporte
  • Magic link: Método principal de autenticación (passwordless)
  • Invitation codes: Required para registro (beta cerrada)
  • Social login: Google y Apple como alternativas
  • Biometric: Ofrecido post-primer-login, opt-in
  • MFA: Opcional, recomendado, configurable en Ajustes > Seguridad
  • Deep links: Universal links (iOS) / App Links (Android) con web fallback