- 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>
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:
- Ver diálogo de confirmación
- Al confirmar, cerrar sesión en ese dispositivo
- Ver notificación "Dispositivo desconectado"
- El dispositivo desaparece de la lista
- 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:
- Ver notificación in-app "Nuevo dispositivo conectado"
- Recibir email con detalles: navegador, SO, ubicación, IP
- 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
DeviceServicegetAllDevices(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-012extractBrowserIcon()- nuevogetDeviceFingerprint()- 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
- Hook/middleware para loguear cada request en
-
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:
- Session token actual en localStorage/cookie
- Session ID del request
- 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