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>
13 KiB
| id | title | type | status | priority | epic | project | story_points | created_date | updated_date |
|---|---|---|---|---|---|---|---|---|---|
| US-INV-006 | Solicitar Retiro | User Story | Done | Media | OQI-004 | trading-platform | 3 | 2025-12-05 | 2026-01-04 |
US-INV-006: Solicitar Retiro
Metadata
| Campo | Valor |
|---|---|
| ID | US-INV-006 |
| Épica | OQI-004 - Cuentas de Inversión |
| Módulo | investment |
| Prioridad | P0 |
| Story Points | 5 |
| Sprint | Sprint 5 |
| Estado | Pendiente |
| Asignado a | Por asignar |
Historia de Usuario
Como inversor, quiero solicitar retiros de mi cuenta de inversión, para retirar ganancias o capital cuando lo necesite.
Descripción Detallada
El usuario debe poder solicitar retiro de fondos desde su cuenta de inversión. El sistema debe validar balance disponible, aplicar período de espera de 72 horas, cerrar posiciones abiertas del agente si es necesario, y procesar el retiro vía Stripe. El usuario debe poder ver el estado de sus retiros pendientes.
Mockups/Wireframes
┌─────────────────────────────────────────────────────────────────┐
│ SOLICITAR RETIRO │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Balance disponible: $1,245.50 │
│ En posiciones abiertas: $180.70 │
│ │
│ ⚠️ Los retiros tienen un período de procesamiento de 72 horas │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Monto a retirar │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ $ │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ [ ] 25% [ ] 50% [ ] 75% [ ] 100% (todo) │ │
│ │ │ │
│ │ Mínimo: $50 USD │ │
│ │ Máximo disponible: $1,064.80 (balance - posiciones) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Método de pago para recibir │ │
│ │ │ │
│ │ (*) Tarjeta terminada en ****4242 │ │
│ │ ( ) Cuenta bancaria ****5678 │ │
│ │ │ │
│ │ [+ Agregar nuevo método] │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 📋 Resumen │ │
│ │ │ │
│ │ Monto solicitado: $500.00 │ │
│ │ Comisión (2%): $10.00 │ │
│ │ ───────────────────────────── │ │
│ │ Recibirás: $490.00 │ │
│ │ │ │
│ │ Nuevo balance: $745.50 │ │
│ │ Fecha estimada: 2025-12-08 (72h) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ⚠️ Si tienes posiciones abiertas, el agente las cerrará antes │
│ de procesar el retiro para liberar fondos. │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ SOLICITAR RETIRO │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Criterios de Aceptación
Escenario 1: Solicitar retiro exitoso
DADO que el usuario tiene balance de $1,245.50
Y no tiene posiciones abiertas
CUANDO solicita retiro de $500
Y selecciona método de pago
Y hace click en "Solicitar retiro"
ENTONCES se crea solicitud de retiro con status "pending"
Y se reserva $500 del balance
Y se muestra confirmación "Retiro solicitado, procesará en 72h"
Y se envía email de confirmación
Y se muestra en lista de retiros pendientes
Escenario 2: Retiro con posiciones abiertas
DADO que el usuario tiene balance $1,245.50
Y tiene $180.70 en posiciones abiertas
CUANDO solicita retiro de $1,000
ENTONCES se muestra advertencia "Se cerrarán posiciones abiertas"
Y el usuario confirma
Y el agente cierra todas las posiciones
Y se procesa el retiro con el balance final
Escenario 3: Monto mayor al disponible
DADO que el usuario tiene balance disponible de $1,064.80
CUANDO intenta retirar $1,500
ENTONCES se muestra error "Fondos insuficientes"
Y se muestra "Máximo disponible: $1,064.80"
Y el botón de confirmar está deshabilitado
Escenario 4: Monto menor al mínimo
DADO que el usuario está solicitando retiro
CUANDO ingresa monto de $25
Y el mínimo es $50
ENTONCES se muestra error "El monto mínimo es $50 USD"
Y el botón está deshabilitado
Escenario 5: Procesar retiro después de 72h
DADO que existe retiro con status "pending"
Y han pasado 72 horas desde la solicitud
CUANDO el cron job ejecuta processWithdrawals()
ENTONCES se procesa el pago con Stripe
Y se actualiza status a "completed"
Y se actualiza balance de cuenta
Y se envía email "Retiro completado"
Escenario 6: Ver retiros pendientes
DADO que el usuario tiene 2 retiros pendientes
CUANDO navega a sección de retiros
ENTONCES se muestra lista de retiros
Y cada retiro muestra: monto, fecha solicitud, tiempo restante, status
Y puede cancelar retiros que aún están en período de espera
Criterios Adicionales
- Permitir cancelar retiro dentro de las primeras 24h
- Mostrar countdown de tiempo restante para retiros pendientes
- Límite de 1 retiro activo por vez
- Validar que cuenta no esté en status "closed"
- Logging detallado para auditoría
Tareas Técnicas
Database:
- DB-INV-001: Schema investment.withdrawals
- DB-INV-002: Enum withdrawal_status (pending, processing, completed, failed, cancelled)
- DB-INV-003: Índice en (account_id, status)
Backend:
- BE-INV-001: Endpoint POST /investment/accounts/:id/withdraw
- BE-INV-002: Implementar WithdrawalService.requestWithdrawal()
- BE-INV-003: Validar balance disponible
- BE-INV-004: Integración con agente ML para cerrar posiciones
- BE-INV-005: Implementar WithdrawalService.processWithdrawal()
- BE-INV-006: Integración Stripe Transfers/Payouts
- BE-INV-007: Cron job para procesar retiros después de 72h
- BE-INV-008: Endpoint GET /investment/accounts/:id/withdrawals
- BE-INV-009: Endpoint DELETE /investment/withdrawals/:id (cancelar)
Frontend:
- FE-INV-001: Crear página WithdrawPage.tsx
- FE-INV-002: Crear componente WithdrawForm.tsx
- FE-INV-003: Crear componente WithdrawSummary.tsx
- FE-INV-004: Crear componente PendingWithdrawals.tsx
- FE-INV-005: Crear componente CountdownTimer.tsx
- FE-INV-006: Implementar withdrawalStore
Tests:
- TEST-INV-001: Test unitario WithdrawalService
- TEST-INV-002: Test validaciones de balance
- TEST-INV-003: Test integración Stripe
- TEST-INV-004: Test cron job procesamiento
- TEST-INV-005: Test E2E flujo completo retiro
Dependencias
Depende de:
- US-INV-003: Realizar depósito - Estado: Pendiente
- OQI-005: Integración Stripe - Estado: Pendiente
- OQI-006: ML Agents (cerrar posiciones) - Estado: Pendiente
Bloquea:
- US-INV-007: Ver historial transacciones
- US-INV-009: Cerrar cuenta
Notas Técnicas
Endpoints involucrados:
| Método | Endpoint | Descripción |
|---|---|---|
| POST | /investment/accounts/:id/withdraw | Solicitar retiro |
| GET | /investment/accounts/:id/withdrawals | Lista de retiros |
| DELETE | /investment/withdrawals/:id | Cancelar retiro |
Entidades/Tablas:
investment.withdrawals: Solicitudes de retiroinvestment.accounts: Actualizar balanceinvestment.transactions: Registrar transacción
Request Body POST /withdraw:
{
amount: 500,
paymentMethodId: "pm_xxx",
closePositions: true, // si tiene posiciones abiertas
reason: "profit_withdrawal" // opcional
}
Response:
{
withdrawal: {
id: "uuid",
accountId: "uuid",
amount: 500,
fee: 10,
netAmount: 490,
status: "pending",
requestedAt: "2025-12-05T10:00:00Z",
estimatedCompletionAt: "2025-12-08T10:00:00Z",
paymentMethodId: "pm_xxx"
},
account: {
balance: 745.50,
reservedBalance: 500
}
}
Estados de Retiro:
pending: Solicitado, esperando 72hprocessing: Procesando pago con Stripecompleted: Retiro completado exitosamentefailed: Fallo en procesamiento (reintentable)cancelled: Cancelado por usuario
Flujo de Retiro:
- Usuario solicita retiro
- Sistema valida balance y cierra posiciones si es necesario
- Se crea withdrawal con status "pending"
- Balance se reserva (no disponible para trading)
- Después de 72h, cron job cambia status a "processing"
- Se procesa pago con Stripe
- Si éxito: status "completed", se actualiza balance
- Si falla: status "failed", se libera balance reservado
Límites:
- Retiro mínimo: $50 USD
- Retiro máximo: Balance disponible
- Comisión: 2% del monto
- Período de espera: 72 horas
- Máximo 1 retiro pendiente por cuenta
Definition of Ready (DoR)
- Historia claramente escrita
- Criterios de aceptación definidos
- Story points estimados
- Dependencias identificadas
- Integración Stripe documentada
- Diseño/mockup disponible
- API spec disponible
Definition of Done (DoD)
- Código implementado según criterios
- Tests unitarios escritos y pasando
- Tests de integración pasando
- Integración Stripe funcionando
- Cron job configurado y probado
- Code review aprobado
- Documentación actualizada
- 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