Changes include: - Updated architecture documentation - Enhanced module definitions (OQI-001 to OQI-008) - ML integration documentation updates - Trading strategies documentation - Orchestration and inventory updates - Docker configuration updates 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
14 KiB
| id | title | type | status | priority | epic | project | story_points | created_date | updated_date |
|---|---|---|---|---|---|---|---|---|---|
| US-INV-008 | Recibir Distribución de Utilidades | User Story | Done | Media | OQI-004 | trading-platform | 3 | 2025-12-05 | 2026-01-04 |
US-INV-008: Recibir Distribución de Utilidades
Metadata
| Campo | Valor |
|---|---|
| ID | US-INV-008 |
| Épica | OQI-004 - Cuentas de Inversión |
| Módulo | investment |
| Prioridad | P1 |
| Story Points | 5 |
| Sprint | Sprint 6 |
| Estado | Pendiente |
| Asignado a | Por asignar |
Historia de Usuario
Como inversor, quiero recibir distribuciones automáticas de utilidades mensuales, para obtener retornos periódicos de mi inversión sin tener que hacer nada manualmente.
Descripción Detallada
El sistema debe ejecutar un proceso automático mensual (primer día de cada mes) que calcula las utilidades generadas por cada cuenta de inversión en el mes anterior, y distribuye las ganancias (o registra las pérdidas) actualizando el balance. Los usuarios deben recibir notificación de la distribución y poder ver el histórico.
Mockups/Wireframes
┌─────────────────────────────────────────────────────────────────┐
│ DISTRIBUCIÓN DE UTILIDADES │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 📬 Nueva Distribución Mensual - Noviembre 2025 │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 🎉 ¡Felicidades! │ │
│ │ │ │
│ │ Tu agente Atlas generó utilidades en Noviembre 2025 │ │
│ │ │ │
│ │ Balance inicial (01 Nov): $1,000.00 │ │
│ │ Balance final (30 Nov): $1,048.00 │ │
│ │ ───────────────────────────── │ │
│ │ Utilidad del mes: +$48.00 (+4.8%) │ │
│ │ │ │
│ │ Nuevo balance: $1,048.00 │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 📊 Desglose del Mes │ │
│ │ │ │
│ │ Total trades: 28 │ │
│ │ Trades ganadores: 22 (78.6%) │ │
│ │ Trades perdedores: 6 (21.4%) │ │
│ │ │ │
│ │ Ganancia total trades: +$125.30 │ │
│ │ Pérdida total trades: -$45.20 │ │
│ │ Comisiones exchange: -$32.10 │ │
│ │ ───────────────────────────── │ │
│ │ Utilidad neta: +$48.00 │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 📈 Historial de Distribuciones │ │
│ │ │ │
│ │ Nov 2025: +$48.00 (+4.8%) 🟢 │ │
│ │ Oct 2025: +$32.00 (+3.2%) 🟢 │ │
│ │ Sep 2025: +$51.00 (+5.1%) 🟢 │ │
│ │ Ago 2025: +$29.00 (+2.9%) 🟢 │ │
│ │ Jul 2025: -$12.00 (-1.2%) 🔴 │ │
│ │ Jun 2025: +$63.00 (+6.3%) 🟢 │ │
│ │ │ │
│ │ [Ver historial completo →] │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Criterios de Aceptación
Escenario 1: Distribución mensual automática exitosa
DADO que es el día 1 del mes a las 00:00 UTC
Y existen cuentas de inversión activas
CUANDO el cron job executeMonthlyDistribution() se ejecuta
ENTONCES para cada cuenta activa:
Y se calcula utilidad del mes anterior
Y se crea transacción tipo "distribution"
Y se actualiza balance de la cuenta
Y se envía email con resumen de distribución
Y se envía notificación push
Y se registra log de ejecución exitosa
Escenario 2: Distribución con utilidad positiva
DADO que la cuenta tuvo balance inicial $1,000
Y balance final $1,048
CUANDO se ejecuta distribución
ENTONCES se calcula utilidad = $48 (+4.8%)
Y se crea transacción con amount = 48, type = "distribution"
Y el nuevo balance es $1,048
Y se envía email "¡Ganaste $48 este mes!"
Escenario 3: Distribución con pérdida
DADO que la cuenta tuvo balance inicial $1,000
Y balance final $988
CUANDO se ejecuta distribución
ENTONCES se calcula pérdida = -$12 (-1.2%)
Y se crea transacción con amount = -12, type = "distribution"
Y el nuevo balance es $988
Y se envía email "Reporte mensual: -$12 este mes"
Escenario 4: Cuenta sin actividad en el mes
DADO que la cuenta no tuvo trades en el mes
Y el balance no cambió
CUANDO se ejecuta distribución
ENTONCES se registra utilidad = $0 (0%)
Y NO se crea transacción
Y NO se envía email
Escenario 5: Ver historial de distribuciones
DADO que el usuario tiene cuenta con 6 meses de historial
CUANDO navega a /investment/distributions/:accountId
ENTONCES se muestra lista de distribuciones mensuales
Y cada distribución muestra: mes, utilidad, porcentaje, desglose
Y se muestra gráfico de evolución
Escenario 6: Cuenta cerrada durante el mes
DADO que la cuenta se cerró el día 15 del mes
CUANDO se ejecuta distribución mensual
ENTONCES se calcula utilidad solo hasta día 15
Y se procesa distribución proporcional
Y se marca la cuenta como "final distribution"
Criterios Adicionales
- Calcular métricas detalladas (win rate, total trades, etc.)
- Guardar snapshot del balance al inicio de cada mes
- Permitir re-ejecutar distribución si falla
- Dashboard de admin para monitorear distribuciones
- Alertas si alguna distribución falla
Tareas Técnicas
Database:
- DB-INV-001: Tabla investment.distributions
- DB-INV-002: Tabla investment.monthly_snapshots
- DB-INV-003: Función PL/pgSQL para calcular utilidades
- DB-INV-004: Índices en (account_id, period)
Backend:
- BE-INV-001: Implementar DistributionService.executeMonthly()
- BE-INV-002: Implementar DistributionService.calculateProfit()
- BE-INV-003: Cron job (node-cron) ejecutar primer día de mes
- BE-INV-004: Endpoint GET /investment/accounts/:id/distributions
- BE-INV-005: Crear transacciones de distribución
- BE-INV-006: Enviar emails de distribución
- BE-INV-007: Endpoint POST /admin/distributions/rerun (manual)
- BE-INV-008: Logging y monitoreo de distribuciones
Frontend:
- FE-INV-001: Crear página DistributionsPage.tsx
- FE-INV-002: Crear componente DistributionCard.tsx
- FE-INV-003: Crear componente MonthlyBreakdown.tsx
- FE-INV-004: Crear componente DistributionHistory.tsx
- FE-INV-005: Notificación toast para nueva distribución
- FE-INV-006: Implementar distributionsStore
Tests:
- TEST-INV-001: Test cálculo de utilidades
- TEST-INV-002: Test cron job execution
- TEST-INV-003: Test distribución con pérdidas
- TEST-INV-004: Test cuenta cerrada mid-month
- TEST-INV-005: Test email sending
- TEST-INV-006: Test E2E flujo completo
Dependencias
Depende de:
- US-INV-004: Ver dashboard portfolio - Estado: Pendiente
- US-INV-007: Ver transacciones - Estado: Pendiente
- Email service configurado
Bloquea:
- US-INV-011: Exportar reporte PDF
Notas Técnicas
Endpoints involucrados:
| Método | Endpoint | Descripción |
|---|---|---|
| GET | /investment/accounts/:id/distributions | Lista de distribuciones |
| GET | /investment/distributions/:id | Detalle de distribución |
| POST | /admin/distributions/execute | Ejecutar manualmente |
Entidades/Tablas:
investment.distributions: Registro de distribucionesinvestment.monthly_snapshots: Snapshots de inicio de mesinvestment.transactions: Transacciones de distribución
Schema investment.distributions:
CREATE TABLE investment.distributions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
account_id UUID NOT NULL REFERENCES investment.accounts(id),
period VARCHAR(7) NOT NULL, -- "2025-11"
start_date DATE NOT NULL,
end_date DATE NOT NULL,
opening_balance DECIMAL(15,2) NOT NULL,
closing_balance DECIMAL(15,2) NOT NULL,
profit_amount DECIMAL(15,2) NOT NULL,
profit_percentage DECIMAL(5,2) NOT NULL,
total_trades INTEGER NOT NULL,
winning_trades INTEGER NOT NULL,
losing_trades INTEGER NOT NULL,
total_gains DECIMAL(15,2) NOT NULL,
total_losses DECIMAL(15,2) NOT NULL,
total_fees DECIMAL(15,2) NOT NULL,
transaction_id UUID REFERENCES investment.transactions(id),
executed_at TIMESTAMP DEFAULT NOW(),
UNIQUE(account_id, period)
);
Response GET /distributions:
{
distributions: [
{
id: "uuid",
accountId: "uuid",
period: "2025-11",
startDate: "2025-11-01",
endDate: "2025-11-30",
openingBalance: 1000,
closingBalance: 1048,
profitAmount: 48,
profitPercentage: 4.8,
breakdown: {
totalTrades: 28,
winningTrades: 22,
losingTrades: 6,
winRate: 78.6,
totalGains: 125.30,
totalLosses: -45.20,
totalFees: -32.10
},
executedAt: "2025-12-01T00:00:00Z"
}
]
}
Cron Schedule:
// Ejecutar el día 1 de cada mes a las 00:00 UTC
cron.schedule('0 0 1 * *', async () => {
await DistributionService.executeMonthlyDistribution();
});
Cálculo de Utilidad:
profit = closingBalance - openingBalance - depositsInMonth + withdrawalsInMonth
profitPercentage = (profit / openingBalance) * 100
Email Template:
Subject: 📊 Distribución Mensual - Noviembre 2025
Hola {userName},
¡Tu agente {agentName} completó otro mes de trading!
Resumen del Mes:
- Balance inicial: ${openingBalance}
- Balance final: ${closingBalance}
- Utilidad: ${profit} ({profitPercentage}%)
Estadísticas:
- Total trades: {totalTrades}
- Win rate: {winRate}%
[Ver detalle completo →]
Manejo de Errores:
- Si falla distribución para una cuenta, continuar con las demás
- Registrar error en tabla
distribution_errors - Enviar alerta a admin
- Permitir re-ejecución manual desde admin panel
Definition of Ready (DoR)
- Historia claramente escrita
- Criterios de aceptación definidos
- Story points estimados
- Dependencias identificadas
- Fórmula de cálculo definida
- Email templates diseñados
- API spec disponible
Definition of Done (DoD)
- Código implementado según criterios
- Tests unitarios escritos y pasando
- Tests de integración pasando
- Cron job configurado y testeado
- Email service funcionando
- Manejo de errores robusto
- Logging completo
- Code review aprobado
- Documentación actualizada
- Tested en staging con fecha simulada
- QA aprobado
- Desplegado en ambiente de pruebas
Historial de Cambios
| Fecha | Cambio | Autor |
|---|---|---|
| 2025-12-05 | Creación | Requirements-Analyst |
Creada por: Requirements-Analyst Fecha: 2025-12-05 Última actualización: 2025-12-05