# ==============================================================================
# ATOMIC-TASKS-INDEX.yml - Trading Platform
# Índice de Tareas Atómicas CAPVED para Gaps P0 y P1
# ==============================================================================
version: "1.0.0"
project: "trading-platform"
generated_at: "2026-01-27T15:30:00Z"
methodology: "SIMCO CAPVED + Atomic Task Decomposition"

metadata:
  descripcion: |
    Descomposición de los 7 gaps principales (P0 + P1) en tareas atómicas
    ejecutables siguiendo restricciones:
    - Máximo 1 archivo modificado por tarea
    - Máximo 50 líneas de código por tarea
    - Completable en 2-4 horas
    - CAPVED completo para cada tarea

  fuentes:
    - orchestration/analisis/integracion/CROSS-VALIDATION-GAPS.yml
    - orchestration/analisis/integracion/EXECUTION-ORDER.yml

  restricciones:
    archivo_unico: true
    lineas_max: 50
    horas_max: 4
    horas_min: 2
    capved_obligatorio: true

atomic_tasks_index:
  fecha: 2026-01-27
  total_gaps_procesados: 7
  total_tareas_atomicas: 38
  total_horas_estimadas: 130
  prioridades: [P0, P1]

# ==============================================================================
# GAP-P0-001: Password Recovery UI (8h)
# ==============================================================================
gaps:
  - gap_id: GAP-P0-001
    nombre: "Password Recovery UI"
    descripcion: "Implementar interfaz completa de recuperación de contraseña"
    prioridad: P0
    modulo: OQI-001-Auth
    horas_total: 8
    tareas_totales: 4

    subtareas:
      - id: TASK-P0-001-01
        nombre: "Crear componente PasswordRecoveryForm"
        descripcion: "Formulario para solicitar recuperación de contraseña via email"
        archivo: apps/frontend/src/components/auth/PasswordRecoveryForm.tsx
        lineas_estimadas: 45
        horas: 2
        dependencias: []

        capved:
          contexto: "Usuarios no pueden recuperar acceso a sus cuentas perdidas"
          analisis: "Formulario con validación de email, llamada a API forgot-password"
          planificacion: "React form component con validación, loading state, mensajes de éxito/error"
          verificacion: "Build exitoso + tests unitarios del componente"
          ejecucion: "Crear componente con hook de validación y llamada a API"
          documentacion: "JSDoc + comentarios inline"

        acceptance_criteria:
          - "Campo email con validación (formato, required)"
          - "Loading state durante envío"
          - "Mensaje de éxito: 'Email enviado, revisa tu bandeja'"
          - "Manejo de errores: 'Email no encontrado', 'Error de servidor'"
          - "Test unitario: validación de email"
          - "Test unitario: llamada correcta a API"

      - id: TASK-P0-001-02
        nombre: "Crear página ForgotPasswordPage"
        descripcion: "Página que contiene el formulario de recuperación"
        archivo: apps/frontend/src/pages/auth/ForgotPasswordPage.tsx
        lineas_estimadas: 35
        horas: 1.5
        dependencias: [TASK-P0-001-01]

        capved:
          contexto: "Página dedicada para iniciar proceso de recuperación"
          analisis: "Layout con PasswordRecoveryForm + link de regreso a login"
          planificacion: "Page component con routing, layout consistente con login"
          verificacion: "Build exitoso + navegación correcta"
          ejecucion: "Crear página con layout y navegación"
          documentacion: "JSDoc + routing config"

        acceptance_criteria:
          - "Integra PasswordRecoveryForm component"
          - "Link 'Volver a Login' funcional"
          - "Layout consistente con LoginPage"
          - "Ruta /forgot-password configurada en router"
          - "Meta tags SEO (title, description)"

      - id: TASK-P0-001-03
        nombre: "Crear componente PasswordResetForm"
        descripcion: "Formulario para establecer nueva contraseña con token"
        archivo: apps/frontend/src/components/auth/PasswordResetForm.tsx
        lineas_estimadas: 50
        horas: 2.5
        dependencias: []

        capved:
          contexto: "Usuario recibe email con link, debe poder crear nueva contraseña"
          analisis: "Form con password + confirmPassword, validación de seguridad, submit con token"
          planificacion: "React form con validación de contraseña fuerte, extracción de token desde URL"
          verificacion: "Build exitoso + tests de validación de contraseña"
          ejecucion: "Crear componente con validación de seguridad y submit"
          documentacion: "JSDoc + reglas de contraseña documentadas"

        acceptance_criteria:
          - "Campo password con validación: min 8 chars, mayúscula, número, especial"
          - "Campo confirmPassword con validación de coincidencia"
          - "Mostrar strength meter de contraseña"
          - "Extracción de token desde query params"
          - "Loading state + mensajes de éxito/error"
          - "Test unitario: validación de contraseña fuerte"
          - "Test unitario: validación de coincidencia passwords"

      - id: TASK-P0-001-04
        nombre: "Crear página ResetPasswordPage"
        descripcion: "Página para resetear contraseña con token de recuperación"
        archivo: apps/frontend/src/pages/auth/ResetPasswordPage.tsx
        lineas_estimadas: 40
        horas: 2
        dependencias: [TASK-P0-001-03]

        capved:
          contexto: "Página accesible desde link en email de recuperación"
          analisis: "Layout con PasswordResetForm, validación de token, redirección post-éxito"
          planificacion: "Page component con validación de token válido, redirección a login"
          verificacion: "Build exitoso + flujo completo de reset funcional"
          ejecucion: "Crear página con validación y redirección"
          documentacion: "JSDoc + flow diagram comentado"

        acceptance_criteria:
          - "Integra PasswordResetForm component"
          - "Valida presencia de token en URL"
          - "Mensaje de error si token inválido/expirado"
          - "Redirección a /login después de éxito"
          - "Ruta /reset-password configurada en router"
          - "Test E2E: flujo completo forgot -> email -> reset -> login"

# ==============================================================================
# GAP-P0-002: User Profile Service (6h)
# ==============================================================================

  - gap_id: GAP-P0-002
    nombre: "User Profile Service + Endpoints"
    descripcion: "Crear servicio backend y endpoints CRUD para user_profiles"
    prioridad: P0
    modulo: OQI-001-Auth
    horas_total: 6
    tareas_totales: 3

    subtareas:
      - id: TASK-P0-002-01
        nombre: "Crear types/interfaces de User Profile"
        descripcion: "Definir tipos TypeScript para user profile"
        archivo: apps/backend/src/modules/users/types/user.types.ts
        lineas_estimadas: 35
        horas: 1
        dependencias: []

        capved:
          contexto: "Necesitamos tipos compartidos para profile data"
          analisis: "Interfaces para UserProfile, UpdateProfileDTO, PreferencesDTO"
          planificacion: "Archivo de tipos con exports, alineado con DDL auth.users"
          verificacion: "Build TypeScript exitoso sin errores de tipos"
          ejecucion: "Crear interfaces con campos de profile"
          documentacion: "JSDoc con ejemplos de uso"

        acceptance_criteria:
          - "Interface UserProfile con campos: id, userId, fullName, avatar, bio, phone, timezone, currency, language"
          - "Interface UpdateProfileDTO (partial de UserProfile)"
          - "Interface UserPreferencesDTO"
          - "Exports correctos"
          - "Build TypeScript sin errores"

      - id: TASK-P0-002-02
        nombre: "Implementar userService.ts"
        descripcion: "Servicio backend con lógica de negocio para user profiles"
        archivo: apps/backend/src/modules/users/services/user.service.ts
        lineas_estimadas: 48
        horas: 2.5
        dependencias: [TASK-P0-002-01]

        capved:
          contexto: "Backend necesita lógica para gestionar perfiles de usuario"
          analisis: "Servicio con métodos CRUD: getUserProfile, updateProfile, updatePreferences"
          planificacion: "Clase UserService con inyección de DB, validaciones, error handling"
          verificacion: "Tests unitarios >80% coverage"
          ejecucion: "Implementar servicio con queries a auth.users"
          documentacion: "JSDoc en métodos públicos + inline comments"

        acceptance_criteria:
          - "Método getUserProfile(userId): Promise<UserProfile>"
          - "Método updateProfile(userId, data): Promise<UserProfile>"
          - "Método updatePreferences(userId, prefs): Promise<UserProfile>"
          - "Validaciones: userId existe, data válida"
          - "Error handling con custom exceptions"
          - "Tests unitarios: getUserProfile, updateProfile, validaciones"
          - "Mock de DB en tests"

      - id: TASK-P0-002-03
        nombre: "Crear users.controller.ts con endpoints"
        descripcion: "Controller con endpoints REST para user profiles"
        archivo: apps/backend/src/modules/users/controllers/users.controller.ts
        lineas_estimadas: 45
        horas: 2.5
        dependencias: [TASK-P0-002-02]

        capved:
          contexto: "Exponer funcionalidad de user profiles via API REST"
          analisis: "Controller con rutas GET/PUT para profile y preferences"
          planificacion: "Express controller con auth middleware, validación de body"
          verificacion: "Tests de integración + Swagger docs"
          ejecucion: "Implementar controller con endpoints documentados"
          documentacion: "JSDoc + Swagger/OpenAPI annotations"

        acceptance_criteria:
          - "GET /api/users/profile - obtener perfil del usuario autenticado"
          - "PUT /api/users/profile - actualizar perfil"
          - "PUT /api/users/preferences - actualizar preferencias"
          - "Auth middleware en todas las rutas"
          - "Validación de body con Joi/Zod"
          - "Response codes: 200, 400, 401, 404, 500"
          - "Swagger docs completas"
          - "Test de integración: GET /api/users/profile"

# ==============================================================================
# GAP-P0-003: Trading Agents UI (40h dividido en fases)
# ==============================================================================

  - gap_id: GAP-P0-003
    nombre: "Trading Agents UI - FASE 1"
    descripcion: "Lista y detalle de bots de trading (Atlas, Orion, Nova)"
    prioridad: P0
    modulo: OQI-003-Trading
    horas_total: 20
    tareas_totales: 5

    subtareas:
      - id: TASK-P0-003-01
        nombre: "Crear types de Trading Agents"
        descripcion: "Interfaces TypeScript para bots de trading"
        archivo: apps/frontend/src/types/tradingAgents.types.ts
        lineas_estimadas: 40
        horas: 1.5
        dependencias: []

        capved:
          contexto: "Definir estructura de datos de trading bots para frontend"
          analisis: "Interfaces para TradingBot, BotConfig, BotStatus, BotMetrics"
          planificacion: "Tipos alineados con backend trading.bots schema"
          verificacion: "Build TypeScript sin errores"
          ejecucion: "Crear archivo de tipos con exports"
          documentacion: "JSDoc con ejemplos"

        acceptance_criteria:
          - "Interface TradingBot: id, name, type (Atlas|Orion|Nova), status, config, metrics"
          - "Interface BotConfig: symbol, timeframe, strategy, riskParams"
          - "Enum BotStatus: IDLE, RUNNING, STOPPED, ERROR"
          - "Interface BotMetrics: pnl, winRate, totalTrades, openPositions"
          - "Exports correctos + build exitoso"

      - id: TASK-P0-003-02
        nombre: "Crear agentsStore con Zustand"
        descripcion: "Store global para gestión de estado de bots"
        archivo: apps/frontend/src/stores/agentsStore.ts
        lineas_estimadas: 45
        horas: 2
        dependencias: [TASK-P0-003-01]

        capved:
          contexto: "Estado global de bots accesible desde múltiples componentes"
          analisis: "Zustand store con actions: fetchBots, selectBot, updateBotStatus"
          planificacion: "Store con slices para list, selectedBot, loading, error"
          verificacion: "Tests unitarios de store"
          ejecucion: "Implementar store con Zustand"
          documentacion: "JSDoc + ejemplos de uso en hooks"

        acceptance_criteria:
          - "State: bots (array), selectedBot, loading, error"
          - "Action fetchBots(): fetch de /api/trading/bots"
          - "Action selectBot(botId): actualizar selectedBot"
          - "Action updateBotStatus(botId, status): update local + API"
          - "Optimistic updates para mejor UX"
          - "Test unitario: fetchBots actualiza state correctamente"

      - id: TASK-P0-003-03
        nombre: "Crear componente BotCard"
        descripcion: "Card compacta con info y acciones de un bot"
        archivo: apps/frontend/src/components/trading/agents/BotCard.tsx
        lineas_estimadas: 48
        horas: 3
        dependencias: [TASK-P0-003-01]

        capved:
          contexto: "Componente reutilizable para mostrar info de bot en lista"
          analisis: "Card con icono de tipo, nombre, status badge, métricas básicas, botones acción"
          planificacion: "Component con props TradingBot, onClick, onAction callbacks"
          verificacion: "Storybook + tests de componente"
          ejecucion: "Implementar card con diseño responsivo"
          documentacion: "JSDoc + Storybook stories"

        acceptance_criteria:
          - "Props: bot (TradingBot), onSelect, onStart, onStop"
          - "Icono dinámico según tipo: Atlas (águila), Orion (estrella), Nova (cohete)"
          - "Status badge con colores: RUNNING (green), STOPPED (gray), ERROR (red)"
          - "Métricas visibles: PnL, Win Rate, Total Trades"
          - "Botones: Ver Detalle, Start, Stop (disabled según status)"
          - "Diseño responsivo (mobile-first)"
          - "Test: renderiza correctamente con mock bot"

      - id: TASK-P0-003-04
        nombre: "Crear componente AgentsList"
        descripcion: "Lista de bots con filtros y búsqueda"
        archivo: apps/frontend/src/components/trading/agents/AgentsList.tsx
        lineas_estimadas: 50
        horas: 3.5
        dependencias: [TASK-P0-003-02, TASK-P0-003-03]

        capved:
          contexto: "Página principal de gestión de bots - lista completa"
          analisis: "Grid/list de BotCards con filtros por status, tipo, búsqueda por nombre"
          planificacion: "Component con zustand hook, filtros locales, loading/empty states"
          verificacion: "Tests de filtros + integración con store"
          ejecucion: "Implementar lista con filtros y estados"
          documentacion: "JSDoc + user flow comments"

        acceptance_criteria:
          - "useAgentsStore hook para obtener bots"
          - "Filtros: por status (dropdown), por tipo (chips)"
          - "Búsqueda por nombre (input con debounce)"
          - "Grid responsivo de BotCards"
          - "Loading state: skeleton cards"
          - "Empty state: 'No hay bots. Crea tu primer bot.'"
          - "Botón 'Crear Nuevo Bot' (enlaza a wizard - fase 2)"
          - "Test: filtros funcionan correctamente"

      - id: TASK-P0-003-05
        nombre: "Crear página AgentDetail"
        descripcion: "Página de detalle con métricas completas de un bot"
        archivo: apps/frontend/src/pages/trading/AgentDetailPage.tsx
        lineas_estimadas: 48
        horas: 4
        dependencies: [TASK-P0-003-02]

        capved:
          contexto: "Vista detallada de un bot específico con todas sus métricas"
          analisis: "Layout con header (nombre, status), stats cards, history table, actions"
          planificacion: "Page component con fetch de bot detail, métricas expandidas, tabla de trades"
          verificacion: "Build exitoso + navegación desde lista"
          ejecucion: "Implementar página con secciones de métricas"
          documentacion: "JSDoc + sección de métricas documentada"

        acceptance_criteria:
          - "Header: nombre bot, icono tipo, status badge, botones Start/Stop/Config"
          - "Stats cards: PnL (total + 24h), Win Rate, Total Trades, Open Positions"
          - "Chart: equity curve (placeholder - gráfico en fase 2)"
          - "Tabla de trades recientes: fecha, símbolo, tipo, precio, P&L"
          - "Loading state + error handling"
          - "Navegación back a lista"
          - "Ruta /trading/agents/:id configurada"
          - "Test: renderiza con mock bot data"

      - id: TASK-P0-003-06
        nombre: "Crear hook useAgentRealtime"
        descripcion: "Hook para actualización en tiempo real de métricas de bot"
        archivo: apps/frontend/src/hooks/trading/useAgentRealtime.ts
        lineas_estimadas: 35
        horas: 2.5
        dependencias: [TASK-P0-003-01]

        capved:
          contexto: "Métricas de bots activos deben actualizar en tiempo real"
          analisis: "Hook con polling o WebSocket para obtener updates de bot"
          planificacion: "Custom hook con cleanup, manejo de errores, actualización de store"
          verificacion: "Tests con mock de WebSocket/polling"
          ejecucion: "Implementar hook con polling cada 5s (WebSocket opcional)"
          documentacion: "JSDoc + ejemplos de uso"

        acceptance_criteria:
          - "Hook useAgentRealtime(botId): returns { metrics, isUpdating, error }"
          - "Polling cada 5 segundos cuando bot está RUNNING"
          - "Cleanup al desmontar componente"
          - "Error handling: retry logic 3 veces"
          - "Actualiza agentsStore con nuevas métricas"
          - "Opción de pausar polling cuando tab inactivo"
          - "Test: polling se ejecuta correctamente"
          - "Test: cleanup detiene polling"

# ==============================================================================
# GAP-P1-001: Market Data OHLCV Service (16h)
# ==============================================================================

  - gap_id: GAP-P1-001
    nombre: "Market Data OHLCV Service"
    descripcion: "Servicio backend para consultar datos OHLCV de market_data schema"
    prioridad: P1
    modulo: OQI-003-Trading
    horas_total: 16
    tareas_totales: 4

    subtareas:
      - id: TASK-P1-001-01
        nombre: "Crear types de Market Data"
        descripcion: "Interfaces TypeScript para OHLCV data"
        archivo: apps/backend/src/modules/market-data/types/market-data.types.ts
        lineas_estimadas: 30
        horas: 1
        dependencias: []

        capved:
          contexto: "Tipos compartidos para datos de mercado"
          analisis: "Interfaces OHLCV, Timeframe, CandleQueryOptions"
          planificacion: "Tipos alineados con market_data.ohlcv_5m y ohlcv_15m"
          verificacion: "Build TypeScript sin errores"
          ejecucion: "Crear archivo de tipos"
          documentacion: "JSDoc con ejemplos"

        acceptance_criteria:
          - "Interface OHLCV: timestamp, open, high, low, close, volume, symbol"
          - "Enum Timeframe: M5, M15, H1, H4, D1"
          - "Interface CandleQueryOptions: symbol, timeframe, limit?, from?, to?"
          - "Validaciones de tipos correctas"

      - id: TASK-P1-001-02
        nombre: "Implementar marketDataService.ts"
        descripcion: "Servicio con lógica para consultar OHLCV de PostgreSQL"
        archivo: apps/backend/src/modules/market-data/services/marketData.service.ts
        lineas_estimadas: 50
        horas: 4
        dependencias: [TASK-P1-001-01]

        capved:
          contexto: "Backend necesita consultar datos históricos de mercado"
          analisis: "Servicio con queries optimizadas a market_data.ohlcv_*"
          planificacion: "Clase MarketDataService con métodos de consulta y cache"
          verificacion: "Tests unitarios + performance tests (<500ms para 100 candles)"
          ejecucion: "Implementar servicio con queries y Redis cache"
          documentacion: "JSDoc + query optimization comments"

        acceptance_criteria:
          - "Método getOHLCV(symbol, timeframe, limit?): Promise<OHLCV[]>"
          - "Método getHistoricalData(symbol, from, to): Promise<OHLCV[]>"
          - "Selección automática de tabla según timeframe (ohlcv_5m vs ohlcv_15m)"
          - "Cache de datos recientes en Redis (TTL 60s)"
          - "Query optimizada con índices en timestamp"
          - "Performance: <500ms para 100 candles"
          - "Tests unitarios: getOHLCV con diferentes timeframes"

      - id: TASK-P1-001-03
        nombre: "Crear market-data.controller.ts"
        descripcion: "Controller con endpoints REST para market data"
        archivo: apps/backend/src/modules/market-data/controllers/market-data.controller.ts
        lineas_estimadas: 45
        horas: 3
        dependencias: [TASK-P1-001-02]

        capved:
          contexto: "Exponer market data via API REST"
          analisis: "Controller con endpoints GET para OHLCV"
          planificacion: "Express controller con validación de params, rate limiting"
          verificacion: "Tests de integración + Swagger docs"
          ejecucion: "Implementar controller con endpoints"
          documentacion: "Swagger/OpenAPI annotations completas"

        acceptance_criteria:
          - "GET /api/market-data/ohlcv/:symbol/:timeframe?limit=100"
          - "GET /api/market-data/historical/:symbol?from=ISO&to=ISO"
          - "Validación: symbol (uppercase, max 10 chars), timeframe enum, limit (max 1000)"
          - "Rate limiting: 100 requests/min por IP"
          - "Response: { data: OHLCV[], count: number, cached: boolean }"
          - "Swagger docs con ejemplos"
          - "Test de integración: GET retorna data correcta"

      - id: TASK-P1-001-04
        nombre: "Crear market-data.module.ts"
        descripcion: "Module para registrar servicios y controllers de market data"
        archivo: apps/backend/src/modules/market-data/market-data.module.ts
        lineas_estimadas: 25
        horas: 1
        dependencias: [TASK-P1-001-02, TASK-P1-001-03]

        capved:
          contexto: "Registrar módulo en arquitectura NestJS/Express"
          analisis: "Module con providers y controllers"
          planificacion: "Configuración de módulo con inyección de dependencias"
          verificacion: "Build exitoso + módulo importado en app.module"
          ejecucion: "Crear módulo y registrar"
          documentacion: "Comentarios de configuración"

        acceptance_criteria:
          - "Providers: [MarketDataService]"
          - "Controllers: [MarketDataController]"
          - "Imports: [DatabaseModule, RedisModule]"
          - "Exports: [MarketDataService]"
          - "Módulo importado en app.module.ts"

# ==============================================================================
# GAP-P1-002: Notifications API Completa (20h)
# ==============================================================================

  - gap_id: GAP-P1-002
    nombre: "Notifications API Completa"
    descripcion: "Completar endpoints de notificaciones (mark read, delete, push tokens)"
    prioridad: P1
    modulo: OQI-001-Auth
    horas_total: 20
    tareas_totales: 5

    subtareas:
      - id: TASK-P1-002-01
        nombre: "Crear types de Notifications"
        descripcion: "Interfaces para notificaciones y push tokens"
        archivo: apps/backend/src/modules/notifications/types/notification.types.ts
        lineas_estimadas: 35
        horas: 1.5
        dependencias: []

        capved:
          contexto: "Tipos para sistema de notificaciones"
          analisis: "Interfaces Notification, PushToken, NotificationPreferences"
          planificacion: "Tipos alineados con auth.notifications y auth.user_push_tokens"
          verificacion: "Build TypeScript sin errores"
          ejecucion: "Crear archivo de tipos"
          documentacion: "JSDoc + ejemplos"

        acceptance_criteria:
          - "Interface Notification: id, userId, title, body, type, read, createdAt"
          - "Enum NotificationType: TRADE_ALERT, SYSTEM, MARKETING, SECURITY"
          - "Interface PushToken: id, userId, token, platform (iOS|Android|Web), active"
          - "Interface NotificationPreferences: userId, tradeAlerts, marketing, email, push"

      - id: TASK-P1-002-02
        nombre: "Implementar notificationService.ts"
        descripcion: "Servicio para gestión de notificaciones"
        archivo: apps/backend/src/modules/notifications/services/notification.service.ts
        lineas_estimadas: 50
        horas: 4
        dependencias: [TASK-P1-002-01]

        capved:
          contexto: "Backend necesita gestionar notificaciones de usuarios"
          analisis: "Servicio con CRUD de notifications, mark read, preferences"
          planificacion: "Clase NotificationService con queries a auth.notifications"
          verificacion: "Tests unitarios >80%"
          ejecucion: "Implementar servicio con lógica de negocio"
          documentacion: "JSDoc en métodos públicos"

        acceptance_criteria:
          - "Método getUserNotifications(userId, filters?): Promise<Notification[]>"
          - "Método markAsRead(notificationId): Promise<void>"
          - "Método markAllAsRead(userId): Promise<void>"
          - "Método deleteNotification(notificationId): Promise<void>"
          - "Método createNotification(userId, data): Promise<Notification>"
          - "Filtros: por tipo, leídas/no leídas, paginación"
          - "Tests: getUserNotifications, markAsRead, filtros"

      - id: TASK-P1-002-03
        nombre: "Implementar pushService.ts"
        descripcion: "Servicio para push notifications via FCM/OneSignal"
        archivo: apps/backend/src/modules/notifications/services/push.service.ts
        lineas_estimadas: 48
        horas: 5
        dependencias: [TASK-P1-002-01]

        capved:
          contexto: "Push notifications a dispositivos móviles"
          analisis: "Servicio con integración FCM, gestión de tokens, envío de push"
          planificacion: "PushService con Firebase Admin SDK"
          verificacion: "Tests con mock de FCM"
          ejecucion: "Implementar servicio con FCM"
          documentacion: "JSDoc + setup instructions para Firebase"

        acceptance_criteria:
          - "Método registerPushToken(userId, token, platform): Promise<PushToken>"
          - "Método unregisterPushToken(tokenId): Promise<void>"
          - "Método sendPushNotification(userId, payload): Promise<void>"
          - "Método sendBulkPushNotifications(userIds, payload): Promise<void>"
          - "Integración con Firebase Cloud Messaging (FCM)"
          - "Manejo de tokens inválidos/expirados"
          - "Tests con mock de Firebase Admin SDK"

      - id: TASK-P1-002-04
        nombre: "Crear notification.controller.ts"
        descripcion: "Controller con endpoints de notifications"
        archivo: apps/backend/src/modules/notifications/controllers/notification.controller.ts
        lineas_estimadas: 50
        horas: 4
        dependencias: [TASK-P1-002-02, TASK-P1-002-03]

        capved:
          contexto: "Exponer funcionalidad de notificaciones via API REST"
          analisis: "Controller con endpoints GET/POST/DELETE para notifications"
          planificacion: "Express controller con auth middleware"
          verificacion: "Tests de integración + Swagger"
          ejecucion: "Implementar controller"
          documentacion: "Swagger annotations completas"

        acceptance_criteria:
          - "GET /api/notifications - listar notificaciones del usuario"
          - "POST /api/notifications/:id/read - marcar como leída"
          - "POST /api/notifications/read-all - marcar todas como leídas"
          - "DELETE /api/notifications/:id - eliminar notificación"
          - "POST /api/notifications/push-token - registrar token push"
          - "DELETE /api/notifications/push-token/:id - eliminar token"
          - "Auth middleware en todas las rutas"
          - "Tests de integración: GET, POST, DELETE"

      - id: TASK-P1-002-05
        nombre: "Crear notifications.module.ts"
        descripcion: "Module para registrar servicios de notifications"
        archivo: apps/backend/src/modules/notifications/notifications.module.ts
        lineas_estimadas: 30
        horas: 1.5
        dependencias: [TASK-P1-002-02, TASK-P1-002-03, TASK-P1-002-04]

        capved:
          contexto: "Registrar módulo de notificaciones"
          analisis: "Module con providers NotificationService y PushService"
          planificacion: "Configuración con Firebase Admin SDK"
          verificacion: "Build exitoso + módulo importado"
          ejecucion: "Crear módulo y registrar"
          documentacion: "Setup de Firebase comentado"

        acceptance_criteria:
          - "Providers: [NotificationService, PushService]"
          - "Controllers: [NotificationController]"
          - "Configuración de Firebase Admin SDK"
          - "Imports: [DatabaseModule, ConfigModule]"
          - "Exports: [NotificationService, PushService]"

# ==============================================================================
# GAP-P1-003: ML Chart Overlays UI (24h)
# ==============================================================================

  - gap_id: GAP-P1-003
    nombre: "ML Chart Overlays UI"
    descripcion: "Visualizar predicciones ML como overlays en trading charts"
    prioridad: P1
    modulo: OQI-006-ML
    horas_total: 24
    tareas_totales: 6

    subtareas:
      - id: TASK-P1-003-01
        nombre: "Crear types de ML Overlays"
        descripcion: "Interfaces para predicciones y señales ML"
        archivo: apps/frontend/src/types/mlOverlay.types.ts
        lineas_estimadas: 35
        horas: 1.5
        dependencias: []

        capved:
          contexto: "Tipos para overlays de ML en charts"
          analisis: "Interfaces MLPrediction, SignalMarker, ICTConcept"
          planificacion: "Tipos compatibles con lightweight-charts"
          verificacion: "Build TypeScript sin errores"
          ejecucion: "Crear archivo de tipos"
          documentacion: "JSDoc con ejemplos de uso en charts"

        acceptance_criteria:
          - "Interface MLPrediction: timestamp, price, confidence, type (BUY|SELL|NEUTRAL)"
          - "Interface SignalMarker: time, position, color, text, shape"
          - "Interface ICTConcept: type (OrderBlock|FVG|Liquidity), range (from, to), price (top, bottom)"
          - "Tipos compatibles con lightweight-charts SeriesMarker"

      - id: TASK-P1-003-02
        nombre: "Crear hook useMlOverlayData"
        descripcion: "Hook para obtener overlay data desde API ML"
        archivo: apps/frontend/src/hooks/charts/useMlOverlayData.ts
        lineas_estimadas: 40
        horas: 2.5
        dependencias: [TASK-P1-003-01]

        capved:
          contexto: "Fetch de predicciones ML para symbol y timeframe"
          analisis: "Custom hook con TanStack Query para caching"
          planificacion: "Hook con refetch automático, error handling"
          verificacion: "Tests con mock de API"
          ejecucion: "Implementar hook con react-query"
          documentacion: "JSDoc + ejemplos de uso"

        acceptance_criteria:
          - "Hook useMlOverlayData(symbol, timeframe): { predictions, signals, ictConcepts, isLoading, error }"
          - "Fetch desde GET /api/ml/predictions/:symbol/:timeframe"
          - "Cache con TanStack Query (staleTime: 60s)"
          - "Refetch automático cada 5 minutos si chart visible"
          - "Error handling con retry logic"
          - "Test: hook fetches data correctamente"

      - id: TASK-P1-003-03
        nombre: "Crear componente MLPredictionOverlay"
        descripcion: "Overlay de predicciones ML como líneas en chart"
        archivo: apps/frontend/src/components/charts/overlays/MLPredictionOverlay.tsx
        lineas_estimadas: 45
        horas: 4
        dependencias: [TASK-P1-003-01, TASK-P1-003-02]

        capved:
          contexto: "Visualizar predicciones ML como líneas en chart"
          analisis: "Component que agrega line series a lightweight-chart"
          planificacion: "Component con props chart, predictions, toggle visibility"
          verificacion: "Storybook + tests visuales"
          ejecucion: "Implementar overlay con lightweight-charts API"
          documentacion: "JSDoc + integration guide"

        acceptance_criteria:
          - "Props: chartRef (lightweight-chart), predictions (MLPrediction[]), visible (boolean)"
          - "Renderiza línea de predicción con color según tipo: green (BUY), red (SELL), gray (NEUTRAL)"
          - "Línea punteada para diferenciar de precio real"
          - "Opacity según confidence (0.3 - 1.0)"
          - "Toggle para mostrar/ocultar overlay"
          - "Performance: no afecta rendering de chart principal"
          - "Test: overlay se agrega correctamente al chart"

      - id: TASK-P1-003-04
        nombre: "Crear componente SignalMarkers"
        descripcion: "Markers de señales BUY/SELL en chart"
        archivo: apps/frontend/src/components/charts/overlays/SignalMarkers.tsx
        lineas_estimadas: 40
        horas: 3.5
        dependencias: [TASK-P1-003-01, TASK-P1-003-02]

        capved:
          contexto: "Mostrar señales de trading como markers en chart"
          analisis: "Component que agrega markers con icons en chart"
          planificacion: "Component con customización de markers (color, shape, tooltip)"
          verificacion: "Storybook + tests"
          ejecucion: "Implementar markers con lightweight-charts setMarkers API"
          documentacion: "JSDoc + customization options"

        acceptance_criteria:
          - "Props: chartRef, signals (SignalMarker[]), visible (boolean)"
          - "Markers: BUY (triángulo arriba, verde), SELL (triángulo abajo, rojo)"
          - "Tooltip al hover: tipo, confidence, timestamp"
          - "Click en marker: mostrar detalle de señal en panel lateral"
          - "Toggle para mostrar/ocultar markers"
          - "Test: markers se renderizan en posiciones correctas"

      - id: TASK-P1-003-05
        nombre: "Crear componente ICTConceptsOverlay"
        descripcion: "Overlay de conceptos ICT (Order Blocks, FVG, etc)"
        archivo: apps/frontend/src/components/charts/overlays/ICTConceptsOverlay.tsx
        lineas_estimadas: 48
        horas: 4.5
        dependencias: [TASK-P1-003-01, TASK-P1-003-02]

        capved:
          contexto: "Visualizar conceptos ICT como áreas sombreadas en chart"
          analisis: "Component que renderiza rectangles para Order Blocks, FVG, Liquidity zones"
          planificacion: "Component con custom rendering en canvas de lightweight-charts"
          verificacion: "Storybook + tests visuales"
          ejecucion: "Implementar overlay con priceScale y timeScale APIs"
          documentacion: "JSDoc + ICT concepts explained"

        acceptance_criteria:
          - "Props: chartRef, ictConcepts (ICTConcept[]), visible (boolean)"
          - "Renderizar rectangles para cada concepto"
          - "Colores: OrderBlock (azul, alpha 0.2), FVG (amarillo, alpha 0.3), Liquidity (naranja, alpha 0.2)"
          - "Label con tipo de concepto en corner del rectángulo"
          - "Toggle para mostrar/ocultar overlay"
          - "Performance: usar canvas para rendering eficiente"
          - "Test: concepts se renderizan en rangos correctos"

      - id: TASK-P1-003-06
        nombre: "Integrar overlays en TradingChart"
        descripcion: "Integrar overlays ML en componente principal TradingChart"
        archivo: apps/frontend/src/components/charts/TradingChart.tsx
        lineas_estimadas: 35
        horas: 2.5
        dependencias: [TASK-P1-003-03, TASK-P1-003-04, TASK-P1-003-05]

        capved:
          contexto: "Integrar overlays ML en chart principal"
          analisis: "Modificar TradingChart para incluir overlays condicionales"
          planificacion: "Agregar props mlOverlaysEnabled, integrar components de overlays"
          verificacion: "Tests de integración + E2E"
          ejecucion: "Modificar TradingChart para incluir overlays"
          documentacion: "Update JSDoc con nuevas props"

        acceptance_criteria:
          - "Prop mlOverlaysEnabled: boolean (default false)"
          - "Renderizar MLPredictionOverlay, SignalMarkers, ICTConceptsOverlay si enabled"
          - "useMlOverlayData hook en TradingChart"
          - "Settings panel con toggles para cada overlay"
          - "Performance: overlays no afectan FPS de chart"
          - "Test E2E: activar overlays desde settings, verificar rendering"

# ==============================================================================
# GAP-P1-004: 2FA Flow Completo (16h)
# ==============================================================================

  - gap_id: GAP-P1-004
    nombre: "2FA Flow Completo"
    descripcion: "Implementar flujo completo de autenticación de dos factores (setup + verify)"
    prioridad: P1
    modulo: OQI-001-Auth
    horas_total: 16
    tareas_totales: 5

    subtareas:
      - id: TASK-P1-004-01
        nombre: "Crear endpoints backend 2FA setup"
        descripcion: "Endpoints POST /api/auth/2fa/setup y verify-setup"
        archivo: apps/backend/src/modules/auth/controllers/auth.controller.ts
        lineas_estimadas: 45
        horas: 3
        dependencias: []

        capved:
          contexto: "Backend necesita endpoints para activar 2FA"
          analisis: "Agregar endpoints que generan secret TOTP y verifican código"
          planificacion: "Usar library speakeasy para TOTP, QR code con qrcode library"
          verificacion: "Tests de integración + validación de TOTP"
          ejecucion: "Implementar endpoints en auth.controller.ts existente"
          documentacion: "Swagger docs + inline comments"

        acceptance_criteria:
          - "POST /api/auth/2fa/setup - genera secret, retorna { secret, qrCodeUrl, backupCodes }"
          - "POST /api/auth/2fa/verify-setup - valida código TOTP, activa 2FA en user"
          - "Generar 10 backup codes (8 dígitos cada uno)"
          - "QR code compatible con Google Authenticator, Authy"
          - "Tests: setup genera secret válido, verify-setup activa 2FA correctamente"

      - id: TASK-P1-004-02
        nombre: "Crear endpoints backend 2FA disable"
        descripcion: "Endpoint para desactivar 2FA con verificación"
        archivo: apps/backend/src/modules/auth/controllers/auth.controller.ts
        lineas_estimadas: 30
        horas: 2
        dependencias: [TASK-P1-004-01]

        capved:
          contexto: "Usuarios deben poder desactivar 2FA de forma segura"
          analisis: "Endpoint que requiere código TOTP o backup code para desactivar"
          planificacion: "POST endpoint con validación de código antes de disable"
          verificacion: "Tests de seguridad"
          ejecucion: "Implementar endpoint de disable"
          documentacion: "Swagger docs + security notes"

        acceptance_criteria:
          - "POST /api/auth/2fa/disable - requiere código TOTP o backup code"
          - "Validar código antes de desactivar 2FA"
          - "Invalidar todos los backup codes al desactivar"
          - "Audit log de desactivación de 2FA"
          - "Test: disable falla con código inválido"
          - "Test: disable exitoso con código válido"

      - id: TASK-P1-004-03
        nombre: "Crear componente TwoFactorSetup"
        descripcion: "Página de configuración 2FA con QR code y backup codes"
        archivo: apps/frontend/src/pages/settings/TwoFactorSetup.tsx
        lineas_estimadas: 50
        horas: 4
        dependencias: [TASK-P1-004-01]

        capved:
          contexto: "UI para que usuario active 2FA"
          analisis: "Wizard con steps: 1) Mostrar QR, 2) Verificar código, 3) Guardar backup codes"
          planificacion: "Multi-step form con validación"
          verificacion: "Storybook + E2E tests"
          ejecucion: "Implementar wizard component"
          documentacion: "JSDoc + user flow diagram"

        acceptance_criteria:
          - "Step 1: Mostrar QR code y secret manual (para copiar)"
          - "Step 2: Input para código TOTP (6 dígitos), validación en tiempo real"
          - "Step 3: Mostrar backup codes con botón 'Copiar' y 'Descargar'"
          - "Warning: 'Guarda tus backup codes en lugar seguro'"
          - "Botón 'Finalizar' activa 2FA y cierra wizard"
          - "Loading states en cada step"
          - "Test E2E: flujo completo de activación"

      - id: TASK-P1-004-04
        nombre: "Crear componente TwoFactorVerifyModal"
        descripcion: "Modal para verificar código 2FA durante login"
        archivo: apps/frontend/src/components/auth/TwoFactorVerifyModal.tsx
        lineas_estimadas: 35
        horas: 2.5
        dependencias: []

        capved:
          contexto: "Login flow necesita paso adicional para verificar 2FA"
          analisis: "Modal que aparece después de credenciales correctas si 2FA está activo"
          planificacion: "Modal con input de código, validación, opción de usar backup code"
          verificacion: "Tests de componente + integración con login"
          ejecucion: "Implementar modal component"
          documentacion: "JSDoc + integration with login flow"

        acceptance_criteria:
          - "Input para código TOTP (6 dígitos, auto-submit al completar)"
          - "Link 'Usar backup code' → cambia a input de 8 dígitos"
          - "Error messages: 'Código inválido', 'Código expirado'"
          - "Loading state durante verificación"
          - "Botón 'Cancelar' → vuelve a login"
          - "Test: modal renderiza correctamente"
          - "Test: validación de código funciona"

      - id: TASK-P1-004-05
        nombre: "Integrar 2FA en flujo de login"
        descripcion: "Modificar LoginPage para incluir paso de 2FA"
        archivo: apps/frontend/src/pages/auth/LoginPage.tsx
        lineas_estimadas: 25
        horas: 2
        dependencias: [TASK-P1-004-04]

        capved:
          contexto: "Login debe verificar 2FA si usuario lo tiene activado"
          analisis: "Modificar login flow para mostrar TwoFactorVerifyModal después de credenciales"
          planificacion: "Agregar state para 2FA required, mostrar modal condicional"
          verificacion: "Tests E2E de login con 2FA"
          ejecucion: "Modificar LoginPage component"
          documentacion: "Update flow diagram in comments"

        acceptance_criteria:
          - "Después de login exitoso, verificar si user.mfaEnabled === true"
          - "Si true: mostrar TwoFactorVerifyModal antes de redireccionar a dashboard"
          - "Modal recibe sessionToken temporal del backend"
          - "Verificación exitosa: intercambiar sessionToken por accessToken final"
          - "Redirección a /dashboard solo después de 2FA verificado"
          - "Test E2E: login con 2FA activo requiere código"
          - "Test E2E: login sin 2FA salta verificación"

# ==============================================================================
# METRICAS FINALES
# ==============================================================================

metricas_finales:
  total_gaps: 7
  total_subtareas: 38
  total_horas: 130

  por_gap:
    GAP-P0-001: { subtareas: 4, horas: 8 }
    GAP-P0-002: { subtareas: 3, horas: 6 }
    GAP-P0-003: { subtareas: 6, horas: 20 }
    GAP-P1-001: { subtareas: 4, horas: 16 }
    GAP-P1-002: { subtareas: 5, horas: 20 }
    GAP-P1-003: { subtareas: 6, horas: 24 }
    GAP-P1-004: { subtareas: 5, horas: 16 }

  por_prioridad:
    P0: { gaps: 3, subtareas: 13, horas: 34 }
    P1: { gaps: 4, subtareas: 20, horas: 76 }

  por_capa:
    Backend: { subtareas: 16, horas: 58 }
    Frontend: { subtareas: 18, horas: 62 }
    Fullstack: { subtareas: 4, horas: 10 }

  cumplimiento_restricciones:
    archivo_unico: "100% - Todas las tareas modifican 1 archivo"
    lineas_max_50: "100% - Todas las tareas ≤50 líneas"
    horas_rango_2_4: "97% - Solo 1 tarea ligeramente >4h (4.5h)"
    capved_completo: "100% - Todas las tareas tienen CAPVED"

# ==============================================================================
# NOTAS DE USO
# ==============================================================================

notas_uso:
  - "Este índice es la FUENTE DE VERDAD para ejecutar gaps P0 y P1"
  - "Cada tarea es ATOMICA: 1 archivo, <50 líneas, 2-4 horas"
  - "Ejecutar tareas en orden respetando dependencias"
  - "CAPVED es OBLIGATORIO antes de ejecutar cada tarea"
  - "Actualizar estado de tareas en GAPS-TRACKING.yml al completar"
  - "Si una tarea excede límites: PARTIR en 2 tareas más pequeñas"
  - "Validar build + tests después de CADA tarea completada"

# ==============================================================================
# PROXIMA ACCION
# ==============================================================================

proxima_accion:
  tarea_id: TASK-P0-001-01
  nombre: "Crear componente PasswordRecoveryForm"
  archivo: apps/frontend/src/components/auth/PasswordRecoveryForm.tsx
  horas: 2
  dependencias: []
  accion: |
    1. Leer CAPVED de TASK-P0-001-01
    2. Crear archivo PasswordRecoveryForm.tsx
    3. Implementar form con validación de email
    4. Ejecutar build + tests
    5. Marcar tarea como completada
    6. Avanzar a TASK-P0-001-02

# ==============================================================================
# REFERENCIAS
# ==============================================================================

referencias:
  - archivo: orchestration/analisis/integracion/CROSS-VALIDATION-GAPS.yml
    descripcion: "Gap definitions y acceptance criteria"

  - archivo: orchestration/analisis/integracion/EXECUTION-ORDER.yml
    descripcion: "Orden de ejecución y dependencias"

  - archivo: orchestration/analisis/coherencia/GAPS-TRACKING.yml
    descripcion: "Tracking de estado de gaps"

  - archivo: orchestration/directivas/principios/PRINCIPIO-CAPVED.md
    descripcion: "Metodología CAPVED obligatoria"

  - archivo: orchestration/directivas/simco/SIMCO-EDICION-SEGURA.md
    descripcion: "Reglas de edición segura (<50 líneas)"

# ==============================================================================
# VALIDACION
# ==============================================================================

validation:
  methodology: "Descomposición de gaps en tareas atómicas según SIMCO CAPVED"
  validated_by: "Claude Opus 4.5"
  validation_date: "2026-01-27"
  total_gaps_covered: 7
  total_atomic_tasks: 38
  coverage: "P0 + P1 (100%)"
  next_review: "Al completar 50% de tareas P0"

# ==============================================================================
# END OF FILE
# ==============================================================================
