- Create TASK-2026-01-25-NOTIFICACIONES-COMPLETAS with full CAPVED docs - Update DATABASE_INVENTORY with auth.notifications, auth.user_push_tokens, investment.distribution_history, investment.distribution_runs tables - Update BACKEND_INVENTORY with push-token endpoints, firebase.client, and unit tests - Update FRONTEND_INVENTORY with notification components, store, service - Update MASTER_INVENTORY with updated totals - Update _INDEX.yml with new task entry Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
780 lines
22 KiB
YAML
780 lines
22 KiB
YAML
# ============================================================================
|
|
# BACKEND_INVENTORY.yml - Trading Platform Trading Platform
|
|
# ============================================================================
|
|
# Proposito: Inventario consolidado de todos los componentes del backend
|
|
# Ultima actualizacion: 2026-01-25
|
|
# Version: 1.1.0
|
|
# ============================================================================
|
|
|
|
version: "1.0.0"
|
|
project: "Trading Platform"
|
|
framework: "Express.js + TypeScript"
|
|
node_version: "20.x"
|
|
last_updated: "2025-12-05"
|
|
|
|
# ============================================================================
|
|
# RESUMEN EJECUTIVO
|
|
# ============================================================================
|
|
summary:
|
|
total_modules: 12
|
|
total_routes_files: 12
|
|
total_services: 34
|
|
total_controllers: 23
|
|
total_middlewares: 5
|
|
total_guards: 1
|
|
total_background_jobs: 1
|
|
total_endpoints_estimated: 57
|
|
status: "En desarrollo activo"
|
|
|
|
# ============================================================================
|
|
# ESTRUCTURA DE DIRECTORIOS
|
|
# ============================================================================
|
|
structure:
|
|
root: "apps/backend/src"
|
|
directories:
|
|
- path: config/
|
|
purpose: "Configuracion de la aplicacion"
|
|
|
|
- path: core/
|
|
purpose: "Componentes core (middleware, guards, filters, interceptors)"
|
|
|
|
- path: modules/
|
|
purpose: "Modulos de negocio"
|
|
|
|
- path: shared/
|
|
purpose: "Utilidades, tipos y constantes compartidas"
|
|
|
|
# ============================================================================
|
|
# MODULOS
|
|
# ============================================================================
|
|
modules:
|
|
# --------------------------------------------------------------------------
|
|
# AUTH - Autenticacion y autorizacion
|
|
# --------------------------------------------------------------------------
|
|
- name: auth
|
|
path: modules/auth/
|
|
epic: OQI-001
|
|
status: implemented
|
|
description: "Autenticacion multi-metodo, OAuth, 2FA, sesiones"
|
|
|
|
routes_file: auth.routes.ts
|
|
endpoints:
|
|
- method: POST
|
|
path: /auth/register
|
|
description: "Registro de usuario con email/password"
|
|
rf: RF-AUTH-002
|
|
|
|
- method: POST
|
|
path: /auth/login
|
|
description: "Login con email/password"
|
|
rf: RF-AUTH-002
|
|
|
|
- method: POST
|
|
path: /auth/logout
|
|
description: "Cerrar sesion"
|
|
rf: RF-AUTH-004
|
|
|
|
- method: POST
|
|
path: /auth/refresh
|
|
description: "Renovar access token"
|
|
rf: RF-AUTH-004
|
|
|
|
- method: POST
|
|
path: /auth/forgot-password
|
|
description: "Solicitar reset de password"
|
|
rf: RF-AUTH-002
|
|
|
|
- method: POST
|
|
path: /auth/reset-password
|
|
description: "Completar reset de password"
|
|
rf: RF-AUTH-002
|
|
|
|
- method: GET
|
|
path: /auth/oauth/:provider
|
|
description: "Iniciar flujo OAuth"
|
|
rf: RF-AUTH-001
|
|
|
|
- method: GET
|
|
path: /auth/oauth/:provider/callback
|
|
description: "Callback de OAuth"
|
|
rf: RF-AUTH-001
|
|
|
|
- method: POST
|
|
path: /auth/phone/send-code
|
|
description: "Enviar codigo SMS"
|
|
rf: RF-AUTH-002
|
|
|
|
- method: POST
|
|
path: /auth/phone/verify
|
|
description: "Verificar codigo SMS"
|
|
rf: RF-AUTH-002
|
|
|
|
- method: POST
|
|
path: /auth/2fa/setup
|
|
description: "Configurar 2FA TOTP"
|
|
rf: RF-AUTH-003
|
|
|
|
- method: POST
|
|
path: /auth/2fa/verify
|
|
description: "Verificar codigo 2FA"
|
|
rf: RF-AUTH-003
|
|
|
|
- method: POST
|
|
path: /auth/2fa/disable
|
|
description: "Deshabilitar 2FA"
|
|
rf: RF-AUTH-003
|
|
|
|
services:
|
|
- name: token.service.ts
|
|
purpose: "Manejo de JWT y refresh tokens"
|
|
methods:
|
|
- generateAccessToken()
|
|
- generateRefreshToken()
|
|
- verifyAccessToken()
|
|
- verifyRefreshToken()
|
|
|
|
- name: oauth.service.ts
|
|
purpose: "Integracion con proveedores OAuth"
|
|
methods:
|
|
- getAuthorizationUrl()
|
|
- handleCallback()
|
|
- linkAccount()
|
|
- unlinkAccount()
|
|
|
|
- name: email.service.ts
|
|
purpose: "Autenticacion por email"
|
|
methods:
|
|
- register()
|
|
- login()
|
|
- sendConfirmation()
|
|
- confirmEmail()
|
|
|
|
- name: phone.service.ts
|
|
purpose: "Autenticacion por telefono"
|
|
methods:
|
|
- sendVerificationCode()
|
|
- verifyCode()
|
|
|
|
- name: twofa.service.ts
|
|
purpose: "Two-Factor Authentication"
|
|
methods:
|
|
- generateSecret()
|
|
- generateQRCode()
|
|
- verifyToken()
|
|
- generateBackupCodes()
|
|
|
|
controllers:
|
|
- name: auth.controller.ts
|
|
purpose: "Controlador principal de auth"
|
|
|
|
validators:
|
|
- name: auth.validators.ts
|
|
purpose: "Validacion de requests de auth"
|
|
|
|
types:
|
|
- name: auth.types.ts
|
|
purpose: "Tipos e interfaces de auth"
|
|
|
|
# --------------------------------------------------------------------------
|
|
# USERS - Gestion de usuarios
|
|
# --------------------------------------------------------------------------
|
|
- name: users
|
|
path: modules/users/
|
|
epic: OQI-001
|
|
status: structure_only
|
|
description: "Gestion de perfiles, settings y KYC"
|
|
|
|
routes_file: users.routes.ts
|
|
endpoints_planned:
|
|
- method: GET
|
|
path: /users/me
|
|
description: "Obtener perfil actual"
|
|
|
|
- method: PATCH
|
|
path: /users/me
|
|
description: "Actualizar perfil"
|
|
|
|
- method: GET
|
|
path: /users/me/settings
|
|
description: "Obtener configuracion"
|
|
|
|
- method: PATCH
|
|
path: /users/me/settings
|
|
description: "Actualizar configuracion"
|
|
|
|
- method: POST
|
|
path: /users/me/kyc
|
|
description: "Enviar documentos KYC"
|
|
|
|
- method: GET
|
|
path: /users/me/kyc/status
|
|
description: "Estado de verificacion KYC"
|
|
|
|
# --------------------------------------------------------------------------
|
|
# EDUCATION - Modulo educativo
|
|
# --------------------------------------------------------------------------
|
|
- name: education
|
|
path: modules/education/
|
|
epic: OQI-002
|
|
status: structure_only
|
|
description: "Cursos, lecciones, quizzes y progreso"
|
|
|
|
routes_file: education.routes.ts
|
|
endpoints_planned:
|
|
- method: GET
|
|
path: /education/courses
|
|
description: "Listar cursos"
|
|
|
|
- method: GET
|
|
path: /education/courses/:slug
|
|
description: "Detalle de curso"
|
|
|
|
- method: POST
|
|
path: /education/courses/:id/enroll
|
|
description: "Inscribirse a curso"
|
|
|
|
- method: GET
|
|
path: /education/courses/:id/lessons
|
|
description: "Listar lecciones"
|
|
|
|
- method: GET
|
|
path: /education/lessons/:id
|
|
description: "Detalle de leccion"
|
|
|
|
- method: POST
|
|
path: /education/lessons/:id/progress
|
|
description: "Actualizar progreso"
|
|
|
|
- method: GET
|
|
path: /education/quizzes/:id
|
|
description: "Obtener quiz"
|
|
|
|
- method: POST
|
|
path: /education/quizzes/:id/submit
|
|
description: "Enviar respuestas"
|
|
|
|
# --------------------------------------------------------------------------
|
|
# TRADING - Trading y charts
|
|
# --------------------------------------------------------------------------
|
|
- name: trading
|
|
path: modules/trading/
|
|
epic: OQI-003
|
|
status: structure_only
|
|
description: "Watchlists, paper trading, senales"
|
|
|
|
routes_file: trading.routes.ts
|
|
endpoints_planned:
|
|
- method: GET
|
|
path: /trading/symbols
|
|
description: "Listar simbolos disponibles"
|
|
|
|
- method: GET
|
|
path: /trading/candles/:symbol
|
|
description: "Obtener velas OHLCV"
|
|
|
|
- method: GET
|
|
path: /trading/ticker/:symbol
|
|
description: "Precio actual"
|
|
|
|
- method: GET
|
|
path: /trading/watchlists
|
|
description: "Listar watchlists"
|
|
|
|
- method: POST
|
|
path: /trading/watchlists
|
|
description: "Crear watchlist"
|
|
|
|
- method: GET
|
|
path: /trading/paper/balance
|
|
description: "Balance paper trading"
|
|
|
|
- method: POST
|
|
path: /trading/paper/orders
|
|
description: "Crear orden paper"
|
|
|
|
- method: GET
|
|
path: /trading/signals
|
|
description: "Listar senales"
|
|
|
|
- method: GET
|
|
path: /trading/ml/overlay/:symbol
|
|
description: "ML overlay para charts"
|
|
|
|
# --------------------------------------------------------------------------
|
|
# INVESTMENT - Cuentas de inversion
|
|
# --------------------------------------------------------------------------
|
|
- name: investment
|
|
path: modules/investment/
|
|
epic: OQI-004
|
|
status: structure_only
|
|
description: "Productos, cuentas, depositos, retiros"
|
|
|
|
routes_file: investment.routes.ts
|
|
endpoints_planned:
|
|
- method: GET
|
|
path: /investment/products
|
|
description: "Listar productos"
|
|
|
|
- method: GET
|
|
path: /investment/accounts
|
|
description: "Mis cuentas de inversion"
|
|
|
|
- method: POST
|
|
path: /investment/accounts
|
|
description: "Abrir cuenta"
|
|
|
|
- method: GET
|
|
path: /investment/accounts/:id
|
|
description: "Detalle de cuenta"
|
|
|
|
- method: POST
|
|
path: /investment/accounts/:id/deposit
|
|
description: "Solicitar deposito"
|
|
|
|
- method: POST
|
|
path: /investment/accounts/:id/withdraw
|
|
description: "Solicitar retiro"
|
|
|
|
- method: GET
|
|
path: /investment/accounts/:id/performance
|
|
description: "Rendimiento de cuenta"
|
|
|
|
# --------------------------------------------------------------------------
|
|
# PAYMENTS - Pagos y suscripciones
|
|
# --------------------------------------------------------------------------
|
|
- name: payments
|
|
path: modules/payments/
|
|
epic: OQI-005
|
|
status: structure_only
|
|
description: "Suscripciones, pagos, wallet, Stripe"
|
|
|
|
routes_file: payments.routes.ts
|
|
endpoints_planned:
|
|
- method: GET
|
|
path: /payments/plans
|
|
description: "Listar planes"
|
|
|
|
- method: POST
|
|
path: /payments/checkout
|
|
description: "Crear sesion de checkout"
|
|
|
|
- method: GET
|
|
path: /payments/subscription
|
|
description: "Mi suscripcion"
|
|
|
|
- method: POST
|
|
path: /payments/subscription/cancel
|
|
description: "Cancelar suscripcion"
|
|
|
|
- method: GET
|
|
path: /payments/wallet
|
|
description: "Mi wallet"
|
|
|
|
- method: POST
|
|
path: /payments/wallet/deposit
|
|
description: "Depositar a wallet"
|
|
|
|
- method: POST
|
|
path: /payments/webhook
|
|
description: "Webhook de Stripe"
|
|
|
|
# --------------------------------------------------------------------------
|
|
# ADMIN - Administracion
|
|
# --------------------------------------------------------------------------
|
|
- name: admin
|
|
path: modules/admin/
|
|
epic: OQI-001
|
|
status: structure_only
|
|
description: "Panel de administracion"
|
|
|
|
routes_file: admin.routes.ts
|
|
endpoints_planned:
|
|
- method: GET
|
|
path: /admin/users
|
|
description: "Listar usuarios"
|
|
|
|
- method: GET
|
|
path: /admin/users/:id
|
|
description: "Detalle de usuario"
|
|
|
|
- method: PATCH
|
|
path: /admin/users/:id/status
|
|
description: "Cambiar estado de usuario"
|
|
|
|
- method: GET
|
|
path: /admin/kyc/pending
|
|
description: "KYC pendientes"
|
|
|
|
- method: POST
|
|
path: /admin/kyc/:id/approve
|
|
description: "Aprobar KYC"
|
|
|
|
- method: GET
|
|
path: /admin/dashboard
|
|
description: "Metricas del sistema"
|
|
|
|
# ============================================================================
|
|
# CORE COMPONENTS
|
|
# ============================================================================
|
|
core:
|
|
middleware:
|
|
- name: auth.middleware.ts
|
|
path: core/middleware/auth.middleware.ts
|
|
purpose: "Verificacion de autenticacion JWT"
|
|
rf: RF-AUTH-004
|
|
|
|
- name: error-handler.ts
|
|
path: core/middleware/error-handler.ts
|
|
purpose: "Manejo global de errores"
|
|
|
|
- name: not-found.ts
|
|
path: core/middleware/not-found.ts
|
|
purpose: "Handler para rutas no encontradas"
|
|
|
|
- name: rate-limiter.ts
|
|
path: core/middleware/rate-limiter.ts
|
|
purpose: "Rate limiting por IP/usuario"
|
|
rf: RF-AUTH-005
|
|
|
|
guards:
|
|
- name: auth.guard.ts
|
|
path: core/guards/auth.guard.ts
|
|
purpose: "Guard de autenticacion"
|
|
|
|
filters:
|
|
- name: http-exception.filter.ts
|
|
path: core/filters/http-exception.filter.ts
|
|
purpose: "Filtro de excepciones HTTP"
|
|
|
|
interceptors:
|
|
- name: transform-response.interceptor.ts
|
|
path: core/interceptors/transform-response.interceptor.ts
|
|
purpose: "Transformacion de respuestas"
|
|
|
|
# ============================================================================
|
|
# SHARED COMPONENTS
|
|
# ============================================================================
|
|
shared:
|
|
database:
|
|
- name: index.ts
|
|
path: shared/database/index.ts
|
|
purpose: "Conexion a PostgreSQL"
|
|
|
|
constants:
|
|
- name: database.constants.ts
|
|
purpose: "Constantes de base de datos"
|
|
|
|
- name: enums.constants.ts
|
|
purpose: "ENUMs sincronizados con BD"
|
|
note: "DEBE mantenerse sincronizado con DATABASE_INVENTORY"
|
|
|
|
- name: routes.constants.ts
|
|
purpose: "Constantes de rutas"
|
|
|
|
types:
|
|
- name: common.types.ts
|
|
purpose: "Tipos comunes compartidos"
|
|
|
|
utils:
|
|
- name: logger.ts
|
|
purpose: "Logger de la aplicacion"
|
|
|
|
# ============================================================================
|
|
# CONFIGURACION
|
|
# ============================================================================
|
|
config:
|
|
file: config/index.ts
|
|
variables:
|
|
- name: DATABASE_URL
|
|
required: true
|
|
purpose: "URL de conexion a PostgreSQL"
|
|
|
|
- name: JWT_SECRET
|
|
required: true
|
|
purpose: "Secret para JWT"
|
|
|
|
- name: JWT_EXPIRES_IN
|
|
required: false
|
|
default: "1d"
|
|
purpose: "Expiracion de access token"
|
|
|
|
- name: REFRESH_TOKEN_EXPIRES_IN
|
|
required: false
|
|
default: "7d"
|
|
purpose: "Expiracion de refresh token"
|
|
|
|
- name: STRIPE_SECRET_KEY
|
|
required: true
|
|
purpose: "API key de Stripe"
|
|
|
|
- name: STRIPE_WEBHOOK_SECRET
|
|
required: true
|
|
purpose: "Secret para webhooks de Stripe"
|
|
|
|
- name: ML_SERVICE_URL
|
|
required: true
|
|
default: "http://localhost:8000"
|
|
purpose: "URL del servicio ML"
|
|
|
|
- name: FRONTEND_URL
|
|
required: true
|
|
purpose: "URL del frontend para CORS"
|
|
|
|
- name: PORT
|
|
required: false
|
|
default: 3000
|
|
purpose: "Puerto del servidor"
|
|
|
|
# ============================================================================
|
|
# MAPEO A EPICAS
|
|
# ============================================================================
|
|
epic_mapping:
|
|
OQI-001:
|
|
modules: [auth, users, admin]
|
|
status: "Parcialmente implementado"
|
|
services_count: 5
|
|
|
|
OQI-002:
|
|
modules: [education]
|
|
status: "Estructura creada"
|
|
services_count: 0
|
|
|
|
OQI-003:
|
|
modules: [trading]
|
|
status: "Estructura creada"
|
|
services_count: 0
|
|
|
|
OQI-004:
|
|
modules: [investment]
|
|
status: "Estructura creada"
|
|
services_count: 0
|
|
|
|
OQI-005:
|
|
modules: [payments]
|
|
status: "Estructura creada"
|
|
services_count: 0
|
|
|
|
OQI-006:
|
|
modules: []
|
|
status: "Pendiente"
|
|
note: "Integracion con ML Engine existente"
|
|
|
|
OQI-007:
|
|
modules: []
|
|
status: "Planificado"
|
|
note: "Modulo llm-agent a crear"
|
|
|
|
OQI-008:
|
|
modules: []
|
|
status: "Planificado"
|
|
note: "Modulo portfolio a crear"
|
|
|
|
# ============================================================================
|
|
# DEPENDENCIAS PRINCIPALES
|
|
# ============================================================================
|
|
dependencies:
|
|
production:
|
|
- express: "^4.18.x"
|
|
- typescript: "^5.x"
|
|
- pg: "^8.x"
|
|
- jsonwebtoken: "^9.x"
|
|
- bcryptjs: "^2.x"
|
|
- stripe: "^14.x"
|
|
- express-rate-limit: "^7.x"
|
|
- helmet: "^7.x"
|
|
- cors: "^2.x"
|
|
- winston: "^3.x"
|
|
- joi: "^17.x"
|
|
|
|
development:
|
|
- "@types/node": "^20.x"
|
|
- "@types/express": "^4.x"
|
|
- ts-node-dev: "^2.x"
|
|
- nodemon: "^3.x"
|
|
|
|
# ============================================================================
|
|
# SCRIPTS
|
|
# ============================================================================
|
|
scripts:
|
|
- name: "start:dev"
|
|
command: "ts-node-dev --respawn src/index.ts"
|
|
purpose: "Desarrollo con hot reload"
|
|
|
|
- name: "build"
|
|
command: "tsc"
|
|
purpose: "Compilar a JavaScript"
|
|
|
|
- name: "start"
|
|
command: "node dist/index.js"
|
|
purpose: "Produccion"
|
|
|
|
- name: "test"
|
|
command: "jest"
|
|
purpose: "Ejecutar tests"
|
|
|
|
# ============================================================================
|
|
# ARCHIVOS CLAVE
|
|
# ============================================================================
|
|
key_files:
|
|
- path: apps/backend/src/index.ts
|
|
purpose: "Entry point de la aplicacion"
|
|
|
|
- path: apps/backend/src/config/index.ts
|
|
purpose: "Configuracion centralizada"
|
|
|
|
- path: apps/backend/package.json
|
|
purpose: "Dependencias y scripts"
|
|
|
|
- path: apps/backend/tsconfig.json
|
|
purpose: "Configuracion de TypeScript"
|
|
|
|
# ============================================================================
|
|
# NOTAS Y PENDIENTES
|
|
# ============================================================================
|
|
notes:
|
|
- "Modulo auth completamente implementado (OQI-001)"
|
|
- "Modulo notifications agregado (2026-01-25) - multi-canal: email, push, in-app, WebSocket"
|
|
- "Distribution job implementado para rendimientos de inversion (00:00 UTC)"
|
|
- "Trading module con export service implementado (CSV, Excel, PDF, JSON)"
|
|
- "Investment module con repositories PostgreSQL"
|
|
- "Modulos ML, LLM, Portfolio en desarrollo"
|
|
- "Tests unitarios pendientes"
|
|
|
|
# ============================================================================
|
|
# MODULO NOTIFICATIONS (Agregado 2026-01-25)
|
|
# ============================================================================
|
|
notifications_module:
|
|
name: notifications
|
|
path: modules/notifications/
|
|
status: implemented
|
|
description: "Sistema de notificaciones multi-canal"
|
|
|
|
components:
|
|
services:
|
|
- name: notification.service.ts
|
|
purpose: "Servicio unificado de notificaciones"
|
|
methods:
|
|
- sendNotification(userId, payload, options)
|
|
- sendBulkNotification(userIds, payload)
|
|
- broadcastNotification(payload)
|
|
- sendInAppNotification(userId, notification)
|
|
- sendEmailNotification(userId, payload)
|
|
- sendPushNotification(userId, payload)
|
|
- getUserNotifications(userId, options)
|
|
- markAsRead(notificationId, userId)
|
|
- markAllAsRead(userId)
|
|
- getUnreadCount(userId)
|
|
- deleteNotification(notificationId, userId)
|
|
- getUserPreferences(userId)
|
|
- updateUserPreferences(userId, updates)
|
|
- sendAlertNotification(userId, alert)
|
|
- sendTradeNotification(userId, trade)
|
|
- sendDistributionNotification(userId, distribution)
|
|
|
|
controllers:
|
|
- name: notification.controller.ts
|
|
purpose: "REST API para notificaciones"
|
|
|
|
routes:
|
|
- name: notification.routes.ts
|
|
base_path: /api/v1/notifications
|
|
|
|
endpoints:
|
|
- method: GET
|
|
path: /notifications
|
|
description: "Listar notificaciones del usuario"
|
|
auth: required
|
|
|
|
- method: GET
|
|
path: /notifications/unread-count
|
|
description: "Obtener conteo de no leidas"
|
|
auth: required
|
|
|
|
- method: GET
|
|
path: /notifications/preferences
|
|
description: "Obtener preferencias de notificacion"
|
|
auth: required
|
|
|
|
- method: PATCH
|
|
path: /notifications/preferences
|
|
description: "Actualizar preferencias"
|
|
auth: required
|
|
|
|
- method: POST
|
|
path: /notifications/read-all
|
|
description: "Marcar todas como leidas"
|
|
auth: required
|
|
|
|
- method: PATCH
|
|
path: /notifications/:id/read
|
|
description: "Marcar una como leida"
|
|
auth: required
|
|
|
|
- method: DELETE
|
|
path: /notifications/:id
|
|
description: "Eliminar notificacion"
|
|
auth: required
|
|
|
|
- method: POST
|
|
path: /notifications/push-token
|
|
description: "Registrar token de push notification"
|
|
auth: required
|
|
added: "2026-01-25"
|
|
|
|
- method: DELETE
|
|
path: /notifications/push-token
|
|
description: "Eliminar token de push notification"
|
|
auth: required
|
|
added: "2026-01-25"
|
|
|
|
notification_types:
|
|
- alert_triggered
|
|
- trade_executed
|
|
- deposit_confirmed
|
|
- withdrawal_completed
|
|
- distribution_received
|
|
- system_announcement
|
|
- security_alert
|
|
- account_update
|
|
|
|
delivery_channels:
|
|
- in_app (WebSocket real-time)
|
|
- email (Nodemailer templates)
|
|
- push (FCM/APNS - implemented 2026-01-25)
|
|
- sms (Twilio ready)
|
|
|
|
tests:
|
|
- path: services/__tests__/notification.service.spec.ts
|
|
lines: ~450
|
|
added: "2026-01-25"
|
|
|
|
integrations:
|
|
- name: Firebase Cloud Messaging
|
|
client: shared/clients/firebase.client.ts
|
|
added: "2026-01-25"
|
|
- name: Web Push (VAPID)
|
|
added: "2026-01-25"
|
|
|
|
# ============================================================================
|
|
# BACKGROUND JOBS (Agregado 2026-01-25)
|
|
# ============================================================================
|
|
background_jobs:
|
|
- name: distribution.job.ts
|
|
module: investment
|
|
test: jobs/__tests__/distribution.job.spec.ts
|
|
test_added: "2026-01-25"
|
|
path: modules/investment/jobs/distribution.job.ts
|
|
schedule: "Daily at 00:00 UTC"
|
|
purpose: "Calcular y distribuir rendimientos de inversion"
|
|
features:
|
|
- Calculo de retornos diarios por producto
|
|
- Aplicacion de performance fees
|
|
- Actualizacion atomica de balances
|
|
- Registro en distribution_history
|
|
- Notificacion a usuarios
|
|
- Auditoria en distribution_runs
|
|
|
|
# ============================================================================
|
|
# FIN DEL INVENTARIO
|
|
# ============================================================================
|