Edge Cases & Business Rules
Validaciones, Reglas, y Qué Pasa Cuando Las Cosas Fallan
Propósito: Definir límites del sistema y comportamiento ante situaciones especiales
Audiencia: Engineers, QA, Product
Alcance: Reglas que afectan UX
Validation Rules
Field-Level Validations
- Required: Sí
- Format: Must match RFC 5322 simplified
- Único: Sí (DB check async)
- Length: 3-254 chars
- Error: “Email inválido” | “Email ya registrado”
Nombre
- Required: Sí
- Length: 2-100 chars
- Allowed: Letras, números, espacios, guiones, apóstrofes
- Error: “Mínimo 2 caracteres” | “Caracteres no permitidos”
Fecha Nacimiento
- Required: Sí
- Range: 1920-2008 (edad 18+)
- Validation: ¿Edad >= 18?
- Error: “Debes ser mayor de 18 años”
Peso
- Required: Sí
- Range: 30-300 kg
- Decimal: 1 lugar (ej: 68.5)
- Error: “Peso debe estar entre 30 y 300 kg”
Contraseña
- Required: Sí (al registrarse)
- Length: Mínimo 8 caracteres
- Complexity: Mayúscula + número + carácter especial (recomendado, no requerido)
- Match: Debe coincidir con “Confirmar contraseña”
- Error: “Contraseña muy débil” | “No coinciden”
Business-Level Validations
Onboarding Duración
Validación: ¿Usuario completa en <1 día?
→ Sí: Normal, continúa
→ No (>7 días): Mostrar notificación "Completa onboarding"
→ No (>30 días): Auto-cancel, enviar email "¿Necesitas ayuda?"
Check-in Diario (Timing)
Validación: ¿Usuario hace check-in en fecha X?
→ Sí (antes de 2am): Cuenta para día X
→ Sí (después de 2am): Cuenta para día X+1
→ No (entire day missed): Streak se resetea a 0
→ Sí (next day): Streak inicia en 1
Adherencia Cálculo
Fórmula: (check-ins_completados / días_en_ciclo) × 100
Ejemplos:
- 45 check-ins en 45 días = 100%
- 32 check-ins en 45 días = 71%
- 25 check-ins en 45 días = 56%
Regla: <50% adherencia → Ciclo fallido, opción "Reintentar"
Biomarcador Out-of-Range
Validación: ¿Valor está fuera de rango?
→ Estado = "REVISAR" (azul) si dentro de 110% de rango
→ Estado = "ATENCION" (rojo) si >110% o <-10%
Ejemplo (Glucosa rango 70-100):
- 68 (1% abajo): REVISAR
- 60 (14% abajo): ATENCION
- 112 (12% arriba): ATENCION
RCV (Reference Change Value) Threshold
Regla: ¿Cambio es REAL o variación biológica?
Fórmula general: RCV = Z × √2 × CV
Z = 1.96 (95% confidence)
CV = Coeficiente de variación (~10-15% por biomarcador)
Resultado: Si cambio > RCV threshold → "CAMBIO REAL"
Ejemplo (Colesterol):
RCV threshold: ~15%
Anterior: 245, Ahora: 198
Cambio: 19% → REAL (RCV detected)
Data Constraints
Ciclo Duration
BASELINE: 7 días (no flexible)
EXECUTION: 82 días (no flexible)
CIERRE: 1 día (no flexible)
TOTAL: 90 días exactos
Regla: Si usuario intenta acceder a ciclo >100 días:
→ Forzar cierre + generar reporte
Concurrent Operations
Regla: ¿Dos updates simultáneos al mismo objeto?
→ Last-write-wins (timestamp)
→ Show toast: "Tus cambios fueron sobreescritos"
Regla: ¿Dos Check-ins el mismo día?
→ Rechazar segundo (error message)
→ "Ya completaste check-in hoy"
Labs Processing Time
Upload → Procesamiento (con OCR): 30 minutos - 2 horas
Notificación: "Tu análisis está listo"
Timeout: Si >4 horas, notificar usuario + opción "Contactar"
Special Cases
CASE 1: Usuario Menor de Edad
Trigger: Fecha nacimiento < 18 años
Behavior:
Step 1: Mostrar error inline
"Debes ser mayor de 18 años para usar ADEN"
Step 2: Opciones:
[ Actualizar fecha ] [ Salir ]
Step 3: Si continúan intentando:
→ Block account después de 3 intentos
→ Log security event
CASE 2: Email No Verificado Después de 24h
Trigger: Onboarding completado, email NO verificado
Behavior:
Day 1: Enviar 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)
CTA siempre: Resend verification link
CASE 3: Labs No Cargadas (Día 88+)
Trigger: Ciclo casi termina, labs no cargadas
Behavior:
Day 85: Notificación "Próximas 5 días para cargar labs"
Day 88: Notificación + email urgente
Day 89: Modal bloqueante
"Carga tus exámenes para completar el ciclo"
[CARGAR] [CONTACTAR SOPORTE]
Day 90:
Si aún sin labs → Ciclo incompleto
Reporte parcial (sin datos finales)
Opción: "Cargar labs después"
CASE 4: Same Username Already Exists
Trigger: Registro con email que ya existe
Behavior:
Error: "Email ya registrado"
Opciones:
[ Iniciar sesión ]
[ ¿Olvidaste contraseña? ]
[ Usar otro email ]
Seguridad: No revelar "Este usuario existe"
CASE 5: Labs Resultado Con Valores Extremos
Trigger: Laboratorio carga resultado físicamente imposible (ej: Glucosa 10,000)
Behavior:
Validation: ¿Valor > 3σ de rango esperado?
→ Flag como "possibly_erroneous"
→ Mostrar warning: "Este valor parece incorrecto"
→ CTA: [CONFIRMAR] [EDITAR]
Si usuario confirma:
→ Procesar como normal
→ Log flag en DB
Si usuario edita:
→ Form input permitido
→ Re-validate
CASE 6: Multiple Alerts Same Type
Trigger: 3+ alertas de tipo “biomarcador” en 24h
Behavior:
Sin grouping:
Alert 1: Tu glucosa subió
Alert 2: Tu colesterol bajó
Alert 3: Tu AST subió
Con grouping (nuestro approach):
Alert Group: 3 cambios en tus exámenes
[VER DETALLES]
Shows all 3, pero en 1 card
CASE 7: Premium Feature (Post-MVP)
Trigger: Usuario intenta acceder a feature no incluida en plan
Behavior:
Modal:
"Esta función está en Próximamente"
"Deja tu email para notificaciones"
[ NOTIFICARME ]
O:
Modal (si paid plan):
"Mejora tu plan para acceder"
[ VER PLANES ]
CASE 8: Streaks & Timezone
Trigger: Usuario en Colombia (UTC-5), check-in a las 11:59 PM
Behavior:
Regla: Check-in cuenta para día LOCAL (user's timezone)
Ejemplo:
- User en Medellín (UTC-5)
- Hace check-in a 23:59 (11:59 PM)
- Date stored: 2026-04-05 (su zona)
- Streakcount: +1 para 2026-04-05
Si es 00:01 (12:01 AM):
- Streak: +1 para 2026-04-06
CASE 9: Duplicate Onboarding (User Reloads)
Trigger: Usuario recarga página en mitad de onboarding Step 3
Behavior:
Option 1 (nuestro approach): Auto-save en DB
- Cada Step, guardar en background
- Si user recarga Step 3: vuelve a Step 3 (populated)
- User no pierde progreso
Option 2 (localStorage fallback):
- Si falla DB save, caché en localStorage
- Mostrar warning: "No guardamos todavía" (bottom banner)
- Retry automático cada 30s
Error Recovery Patterns
Recovery 1: Network Timeout (Check-in)
User submits check-in → 10s timeout
Behavior:
1. Show: "Algo tardó. Reintentando..."
2. Retry (exponential backoff): 1s, 2s, 4s, 8s
3. After 3 retries failed:
- Option A: Save offline + sync later
- Option B: "Contactar soporte"
- Data is NOT lost
Recovery 2: Halfway Through Onboarding (Step 4 → 5)
User at Step 4, loses connection, tries to go to Step 5
Behavior:
1. Step 4 auto-saved (async)
2. Step 5: Show cached versión
3. Warning banner: "Algunos datos podrían estar desactualizados"
4. Offer: "Reintenta conexión" button
Rate Limits & Abuse Prevention
Rate Limit: Check-in
Max: 1 per user per calendar day
If violated: "Ya completaste check-in hoy"
Rate Limit: API Calls
Max: 60 requests/minute per user
If exceeded: 429 error + "Espera un momento e intenta de nuevo"
Rate Limit: Password Reset
Max: 3 per hour per email
If exceeded: "Espera 1 hora antes de intentar de nuevo"
Abuse Detection
If user submits 100 biomarcador values with nonsense:
→ Flag account
→ Email: "Detected unusual activity. Verify it's you"
→ 2FA check required
Compliance & GDPR
Data Delete Request
Flow:
1. User: Settings → Datos & Privacidad → [Borrar Cuenta]
2. Confirmation: "Esto es irreversible"
3. Email verification link
4. After 30 days: Account + all data deleted
Data Export Request
Flow:
1. User: Settings → Datos & Privacidad → [Descargar Datos]
2. Email: ZIP with JSON files
3. Include: User profile, check-ins, biomarcadores, ciclos
Conclusión: Architecture & UX generation complete.
6 OOUX Objects defined
7 JTBDs documented & prioritized
5 User Flows diagrammed
30 Screens catalogued
IA & Navigation mapped
Global States defined
Edge Cases handled
Ready for: Wireframes → Figma Design → Frontend Implementation