trading-platform/docs/02-definicion-modulos/OQI-001-fundamentos-auth/historias-usuario/US-AUTH-014-gestion-dispositivos.md
Adrian Flores Cortes cdec253b02 [TASK-2026-01-25-FRONTEND-ANALYSIS] docs: Add frontend specifications and user stories
- Add 5 frontend specification documents (ET-*-frontend.md):
  - ET-AUTH-006: Authentication module frontend spec
  - ET-ML-008: ML Signals module frontend spec
  - ET-LLM-007: LLM Agent module frontend spec
  - ET-PFM-008: Portfolio Manager frontend spec (design)
  - ET-MKT-003: Marketplace frontend spec (design)

- Add 8 new user stories:
  - US-AUTH-013: Global logout
  - US-AUTH-014: Device management
  - US-ML-008: Ensemble signal view
  - US-ML-009: ICT analysis view
  - US-ML-010: Multi-symbol scan
  - US-LLM-011: Execute trade from chat
  - US-PFM-013: Rebalance alerts
  - US-PFM-014: PDF report generation

- Update task index with completed analysis

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 01:47:27 -06:00

20 KiB

id title type status priority epic story_points created_date updated_date
US-AUTH-014 Gestión de Dispositivos User Story To Do Media OQI-001 5 2026-01-25 2026-01-25

US-AUTH-014: Gestión de Dispositivos

Version: 1.0.0 Fecha: 2026-01-25 Estado: Pendiente Story Points: 5 Prioridad: P2 (Media) Épica: OQI-001


Historia de Usuario

Como usuario de Trading Platform Quiero ver y administrar los dispositivos donde tengo sesión activa Para mantener control total sobre mi cuenta y detectar accesos no autorizados


Criterios de Aceptación

AC-001: Listado de dispositivos activos

Dado que estoy autenticado Cuando accedo a Configuración > Seguridad > Dispositivos Entonces debería ver una lista de todos mis dispositivos con sesión activa

AC-002: Información de cada dispositivo

Dado que estoy viendo mi lista de dispositivos Cuando observo cada dispositivo listado Entonces debería ver:

  • Icono del navegador (Chrome, Safari, Firefox, etc.)
  • Sistema operativo (Windows, macOS, iOS, Android, Linux)
  • Modelo/Nombre del dispositivo (si está disponible)
  • Ubicación aproximada (Ciudad, País)
  • Dirección IP
  • Fecha y hora de última actividad
  • Badge "Dispositivo actual" si es la sesión activa

AC-003: Cierre de sesión individual

Dado que identifico un dispositivo que no reconozco Cuando hago click en "Cerrar sesión" Entonces debería:

  1. Ver diálogo de confirmación
  2. Al confirmar, cerrar sesión en ese dispositivo
  3. Ver notificación "Dispositivo desconectado"
  4. El dispositivo desaparece de la lista
  5. Si ese dispositivo intenta hacer request, recibe 401 Unauthorized

AC-004: Información detallada del navegador

Dado que quiero investigar un dispositivo sospechoso Cuando hago click en el dispositivo para ver más detalles Entonces debería ver:

  • Versión exacta del navegador
  • Versión exacta del SO
  • User Agent (para auditoría)
  • Historial de actividad en últimas 7 días (gráfico de línea)
  • Ubicaciones desde las que se accedió
  • Primer acceso registrado
  • Último acceso registrado

AC-005: Indicador de dispositivo actual

Dado que estoy viendo mis dispositivos Cuando identifico el dispositivo desde el cual estoy accediendo Entonces debería estar claramente marcado con:

  • Badge "🟢 Este dispositivo"
  • Ubicado al inicio de la lista
  • Color diferenciado (verde o azul)
  • SIN botón "Cerrar sesión"

AC-006: Ordenes de dispositivos

Dado que tengo múltiples dispositivos activos Cuando veo la lista Entonces debería:

  • Mostrar "Este dispositivo" primero
  • Los demás ordenados por última actividad (descendente)
  • Mostrar fecha/hora relativa (Hace 2 min, Hace 3 horas, etc.)

AC-007: Detección de navegadores

Dado que accedo desde diferentes navegadores Cuando reviso mis dispositivos Entonces debería ver iconos apropiados:

  • 🌐 Chrome
  • 🔴 Firefox
  • 🧭 Safari
  • 🌌 Edge
  • 📱 Mobile browsers
  • Desconocido

AC-008: Datos de sesión activa

Dado que tengo una sesión activa Cuando veo los detalles del dispositivo Entonces debería ver:

  • Token actual (primeros 10 caracteres) para referencia
  • Fecha de creación de la sesión
  • Próxima fecha de expiración
  • Último refresh de token (si aplica)

AC-009: Patrón de actividad

Dado que quiero monitorear actividad Cuando hago click en "Ver actividad" de un dispositivo Entonces debería ver:

  • Gráfico de actividad por hora/día
  • Número de requests por período
  • Últimas 10 acciones (endpoint, timestamp)
  • Horarios de pico de uso

AC-010: Alertas de nuevos dispositivos

Dado que inicio sesión desde un nuevo dispositivo Cuando completo el login Entonces debería:

  1. Ver notificación in-app "Nuevo dispositivo conectado"
  2. Recibir email con detalles: navegador, SO, ubicación, IP
  3. Link en email para cerrar sesión inmediatamente si no fui yo

Mockup

┌─────────────────────────────────────────────────────────┐
│  Configuración > Seguridad > Dispositivos              │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  Dispositivos activos                                   │
│  Administra dónde está abierta tu sesión               │
│                                                         │
│  ┌─────────────────────────────────────────────────┐   │
│  │                                                  │   │
│  │  🌐 Chrome en Windows              🟢 Este      │   │
│  │                                    dispositivo  │   │
│  │  San Francisco, Estados Unidos • 201.45.67.89  │   │
│  │  Última actividad: Hace 2 minutos               │   │
│  │                                                  │   │
│  │  [Ver más detalles]                             │   │
│  └─────────────────────────────────────────────────┘   │
│                                                         │
│  ┌─────────────────────────────────────────────────┐   │
│  │                                                  │   │
│  │  📱 Safari en iPhone                [Cerrar] │   │
│  │                                                  │   │
│  │  Ciudad de México, México • 189.203.45.12      │   │
│  │  Última actividad: Hace 3 horas                 │   │
│  │                                                  │   │
│  │  [Ver más detalles]                             │   │
│  └─────────────────────────────────────────────────┘   │
│                                                         │
│  ┌─────────────────────────────────────────────────┐   │
│  │                                                  │   │
│  │  🔴 Firefox en Linux                [Cerrar] │   │
│  │                                                  │   │
│  │  Madrid, España • 85.123.45.67                  │   │
│  │  Última actividad: Hace 2 días                  │   │
│  │                                                  │   │
│  │  [Ver más detalles]                             │   │
│  └─────────────────────────────────────────────────┘   │
│                                                         │
│  ────────────────────────────────────────────────────  │
│                                                         │
│  Información de seguridad                               │
│  • Total de sesiones activas: 3                        │
│  • Última sesión nueva: 3 horas atrás                  │
│  • Si ves un dispositivo desconocido, ciérralo        │
│                                                         │
└─────────────────────────────────────────────────────────┘

Modal de detalles:
┌─────────────────────────────────────────────────────────┐
│                                                         │
│  Detalles del dispositivo                               │
│                                                         │
│  🌐 Chrome 130.0.0.0                                    │
│  Windows 11 (Build 23631)                               │
│                                                         │
│  Ubicación:                                             │
│  San Francisco, Estados Unidos (37.7749°, -122.4194°)  │
│                                                         │
│  IP: 201.45.67.89                                       │
│  ISP: Verizon Communications                            │
│                                                         │
│  Sesión:                                                │
│  Creada: 25 Ene 2026, 14:30 CST                        │
│  Última actividad: Hace 2 minutos                       │
│  Próxima expiración: 24 Feb 2026, 14:30 CST             │
│  Token: abc123def...                                    │
│                                                         │
│  Actividad (últimas 24 horas):                          │
│  [Gráfico de línea con actividad por hora]              │
│                                                         │
│  Últimos requests:                                      │
│  14:45 - GET /api/portfolio                             │
│  14:43 - GET /api/market/BTC                            │
│  14:41 - POST /api/orders                               │
│                                                         │
│  ┌──────────────────────┐  ┌──────────────────────┐    │
│  │       Volver         │  │   Cerrar sesión      │    │
│  └──────────────────────┘  └──────────────────────┘    │
│                                                         │
└─────────────────────────────────────────────────────────┘

Modal de confirmación:
┌─────────────────────────────────────────────────────────┐
│                                                         │
│              ⚠️ Cerrar sesión en dispositivo?          │
│                                                         │
│  Se cerrará la sesión de:                              │
│  📱 Safari en iPhone                                    │
│  Ciudad de México, México                               │
│                                                         │
│  Esta acción no se puede deshacer. El dispositivo      │
│  deberá iniciar sesión nuevamente.                      │
│                                                         │
│  ┌──────────────────────┐  ┌──────────────────────┐    │
│  │      Cancelar        │  │   Cerrar sesión      │    │
│  └──────────────────────┘  └──────────────────────┘    │
│                                                         │
└─────────────────────────────────────────────────────────┘

Email de nuevo dispositivo:
┌─────────────────────────────────────────────────────────┐
│  De: Trading Platform Security <security@trading.com>  │
│  Asunto: Nuevo dispositivo conectado a tu cuenta        │
│                                                         │
│  Hola Juan,                                             │
│                                                         │
│  Se inició sesión en tu cuenta desde un nuevo          │
│  dispositivo:                                           │
│                                                         │
│  🌐 Chrome en Windows                                   │
│  📍 San Francisco, Estados Unidos                       │
│  🕐 25 de Enero, 2026 a las 14:30 CST                  │
│  🌐 IP: 201.45.67.89                                   │
│                                                         │
│  ¿Fuiste tú?                                            │
│  Si reconoces esta actividad, puedes ignorar este      │
│  email.                                                 │
│                                                         │
│  ¿No fuiste tú?                                         │
│  ┌──────────────────────────────────────────────┐      │
│  │    Cerrar sesión en este dispositivo         │      │
│  └──────────────────────────────────────────────┘      │
│                                                         │
│  Ver todos mis dispositivos:                            │
│  [https://trading.example.com/settings/devices]         │
│                                                         │
└─────────────────────────────────────────────────────────┘

Tareas Técnicas

Database (DB)

  • Tabla user_sessions (ver US-AUTH-012):

    • Verificar campos: device_type, device_name, browser, os, ip_address, location_city, location_country
    • Agregar si falta: user_agent (TEXT para auditoría)
    • Agregar si falta: last_activity_details (JSONB para tracking fino)
  • Tabla device_activity_log:

    CREATE TABLE device_activity_log (
      id UUID PRIMARY KEY,
      session_id UUID REFERENCES user_sessions(id) ON DELETE CASCADE,
      endpoint VARCHAR(255),
      method VARCHAR(10), -- GET, POST, PUT, DELETE, etc.
      status_code INTEGER,
      response_time_ms INTEGER,
      created_at TIMESTAMP DEFAULT NOW(),
      INDEX idx_session_created (session_id, created_at),
      INDEX idx_created (created_at)
    );
    

Backend (BE)

  • Endpoint GET /api/auth/devices

    • Listar todos los dispositivos activos del usuario
    • Marcar dispositivo actual
    • Ordenar por última actividad DESC
    • Incluir: device_type, device_name, os, browser, ip, location, last_activity
    • Response: HTTP 200
  • Endpoint GET /api/auth/devices/:id

    • Obtener detalles completos de un dispositivo
    • Incluir: user_agent, histórico de actividad (7 días), primero/último acceso
    • Incluir: gráfico de actividad por hora
    • Incluir: últimos 10 requests
    • Response: HTTP 200 o 404
  • Endpoint DELETE /api/auth/devices/:id

    • Cerrar sesión en dispositivo específico
    • Invalidar tokens asociados
    • Loguear la acción en audit trail
    • Enviar email al usuario
    • Response: HTTP 204 o 401/404
  • Service DeviceService

    • getAllDevices(userId)
    • getDeviceDetails(userId, deviceId)
    • terminateDevice(userId, deviceId)
    • isCurrentDevice(userId, sessionId)
    • getDeviceActivitySummary(deviceId, days)
    • getLastNRequests(deviceId, limit)
  • Service DeviceDetectionService (mejorado)

    • parseUserAgent() - ya existe en US-AUTH-012
    • extractBrowserIcon() - nuevo
    • getDeviceFingerprint() - nuevo para consistencia
  • Logging de actividad

    • Hook/middleware para loguear cada request en device_activity_log
    • Incluir: endpoint, método, status code, tiempo de respuesta
    • Asociar a session_id actual
  • Email de notificación

    • Template "Nuevo dispositivo conectado"
    • Incluir link para cerrar sesión desde email
    • Usar SendGrid o similar
  • Tests unitarios (12 casos)

  • Tests de integración (8 escenarios)

Frontend (FE)

  • Página Settings/Security/Devices.tsx (nueva)
  • Componente DeviceCard.tsx (nuevo)
  • Componente DeviceDetailsModal.tsx (nuevo)
  • Modal de confirmación de cierre
  • Gráfico de actividad (line chart con lightweight-charts)
  • Tabla de últimos requests
  • Función para obtener icono de navegador
  • Badge "Este dispositivo" con lógica de sesión actual
  • Ordenamiento automático por última actividad
  • Tests con React Testing Library

Testing (QA)

  • E2E: Ver lista de dispositivos
  • E2E: Ver detalles de dispositivo
  • E2E: Cerrar sesión en dispositivo individual
  • E2E: Confirmar cierre desde modal
  • E2E: Dispositivo desaparece después de cerrar
  • E2E: Email se envía en nuevo dispositivo
  • Performance: Lista de dispositivos < 300ms
  • Performance: Detalles de dispositivo < 500ms
  • Seguridad: No mostrar tokens completos
  • Seguridad: Solo usuario propietario puede ver/cerrar

Dependencias

  • Bloqueantes:

    • US-AUTH-012: Gestión de Sesiones (tabla user_sessions)
    • Sistema de geolocalización (de US-AUTH-012)
  • Relacionadas:

    • US-AUTH-002: Login (sesión inicial)
    • US-AUTH-013: Cambio de contraseña (seguridad complementaria)

Definition of Ready (DoR)

  • API contract definido y aprobado
  • Mockups validados con UX
  • Esquema de BD detallado
  • Servicio de email configurado
  • Estructura de logs de actividad definida

Definition of Done (DoD)

  • Endpoint GET /api/auth/devices implementado
  • Endpoint GET /api/auth/devices/:id implementado
  • Endpoint DELETE /api/auth/devices/:id implementado
  • Tabla device_activity_log creada
  • Logging de actividad funcional
  • Página Settings/Security/Devices.tsx implementada
  • Componentes DeviceCard y DeviceDetailsModal implementados
  • Gráfico de actividad funcional
  • Email de notificación configurable
  • Tests unitarios con 80%+ cobertura
  • Tests de integración pasando
  • Tests E2E implementados
  • Documentación actualizada
  • QA aprobado en staging
  • Deploy a producción exitoso

Notas Técnicas

Device Identification

interface DeviceInfo {
  id: string; // session_id
  browser: string; // "Chrome 130"
  os: string; // "Windows 11"
  device_type: "desktop" | "mobile" | "tablet" | "unknown";
  device_name: string; // "Chrome on Windows"
  ip_address: string;
  location: {
    city: string;
    country: string;
    latitude?: number;
    longitude?: number;
  };
  user_agent: string;
  is_current: boolean;
  last_activity: Date;
  created_at: Date;
  expires_at: Date;
}

Browser Icons Mapping

const BROWSER_ICONS = {
  'Chrome': '🌐',
  'Firefox': '🔴',
  'Safari': '🧭',
  'Edge': '🌌',
  'Opera': '⭕',
  'Mobile': '📱',
  'Unknown': '❓'
};

Activity Graph Data

interface ActivityDataPoint {
  hour: number; // 0-23
  date: string; // "2026-01-25"
  request_count: number;
  timestamp: Date;
}

// Graficar: últimas 24 horas con actividad por hora
// Líneas suave, mostrar puntos de máxima actividad

Current Device Detection

El dispositivo "actual" se detecta comparando:

  1. Session token actual en localStorage/cookie
  2. Session ID del request
  3. El primer dispositivo con expires_at > now() y session_id === actual es "Este dispositivo"

Email Trigger

Se dispara email de "Nuevo dispositivo" cuando:

const isNewDevice = !existingSession ||
  (existingSession.device_name !== currentDevice.device_name) ||
  (existingSession.ip_address !== currentDevice.ip_address);

Audit Trail

Cada acción se registra:

- Dispositivo X cerrado por usuario Y
- Timestamp: 2026-01-25 14:30:00
- Reason: manual_close
- IP del usuario que cerró: admin_ip

Requerimientos Relacionados

Especificaciones Relacionadas