--- id: "US-INV-009" title: "Cerrar Cuenta de Inversión" type: "User Story" status: "Done" priority: "Media" epic: "OQI-004" project: "trading-platform" story_points: 3 created_date: "2025-12-05" updated_date: "2026-01-04" --- # US-INV-009: Cerrar Cuenta de Inversión ## Metadata | Campo | Valor | |-------|-------| | **ID** | US-INV-009 | | **Épica** | OQI-004 - Cuentas de Inversión | | **Módulo** | investment | | **Prioridad** | P2 | | **Story Points** | 3 | | **Sprint** | Sprint 7 | | **Estado** | Pendiente | | **Asignado a** | Por asignar | --- ## Historia de Usuario **Como** inversor, **quiero** poder cerrar mi cuenta de inversión, **para** dejar de operar con ese agente y retirar todos mis fondos. ## Descripción Detallada El usuario debe poder cerrar su cuenta de inversión de forma controlada. El proceso incluye: cerrar todas las posiciones abiertas del agente, procesar un retiro automático de todos los fondos, cambiar el estado de la cuenta a "closed", y enviar confirmación. La cuenta cerrada debe permanecer visible en modo lectura para histórico. ## Mockups/Wireframes ``` ┌─────────────────────────────────────────────────────────────────┐ │ CERRAR CUENTA DE INVERSIÓN │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ⚠️ ¿Estás seguro que deseas cerrar tu cuenta en Atlas? │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ 📊 Estado actual de tu cuenta │ │ │ │ │ │ │ │ Balance total: $1,245.50 │ │ │ │ En posiciones abiertas: $180.70 │ │ │ │ Disponible para retiro: $1,064.80 │ │ │ │ │ │ │ │ Rendimiento total: +$245.50 (+24.5%) │ │ │ │ Tiempo activa: 6 meses │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ ⚙️ Lo que sucederá al cerrar: │ │ │ │ │ │ │ │ 1. Se cerrarán todas las posiciones abiertas (2) │ │ │ │ 2. Se procesará un retiro automático de todos los fondos│ │ │ │ 3. El agente dejará de operar tu cuenta │ │ │ │ 4. Recibirás los fondos en 72 horas │ │ │ │ 5. Podrás ver el historial pero no operar │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ Método de pago para recibir fondos │ │ │ │ │ │ │ │ (*) Tarjeta terminada en ****4242 │ │ │ │ ( ) Cuenta bancaria ****5678 │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ 💰 Resumen del retiro final │ │ │ │ │ │ │ │ Monto total: $1,245.50 │ │ │ │ Comisión (2%): $24.91 │ │ │ │ ───────────────────────────── │ │ │ │ Recibirás: $1,220.59 │ │ │ │ Fecha estimada: 2025-12-08 (72h) │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ [✓] Entiendo que esta acción no se puede deshacer │ │ [✓] Confirmo que quiero cerrar mi cuenta │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ CERRAR CUENTA Y RETIRAR FONDOS │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ [Cancelar] │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` --- ## Criterios de Aceptación **Escenario 1: Cerrar cuenta exitosamente** ```gherkin DADO que el usuario tiene cuenta activa con balance $1,245.50 Y tiene 2 posiciones abiertas CUANDO solicita cerrar cuenta Y confirma los checkboxes Y hace click en "Cerrar cuenta y retirar fondos" ENTONCES el agente cierra todas las posiciones abiertas Y se actualiza el balance con P&L de posiciones cerradas Y se crea solicitud de retiro por el balance total Y se cambia status de cuenta a "closing" Y después de 72h se cambia a "closed" Y se envía email de confirmación ``` **Escenario 2: Cerrar cuenta sin posiciones abiertas** ```gherkin DADO que el usuario tiene cuenta activa Y no tiene posiciones abiertas Y tiene balance de $1,000 CUANDO solicita cerrar cuenta ENTONCES se crea retiro por $1,000 Y se cambia status a "closing" inmediatamente Y NO se requiere cerrar posiciones ``` **Escenario 3: Cerrar cuenta con balance cero** ```gherkin DADO que el usuario tiene cuenta con balance $0 CUANDO solicita cerrar cuenta ENTONCES se cambia status a "closed" inmediatamente Y NO se crea retiro Y se muestra mensaje "Cuenta cerrada exitosamente" ``` **Escenario 4: Cerrar cuenta con retiro pendiente** ```gherkin DADO que el usuario tiene retiro pendiente activo CUANDO intenta cerrar cuenta ENTONCES se muestra error "Tienes un retiro pendiente" Y se muestra "Espera a que se complete o cancélalo para continuar" Y NO se permite cerrar cuenta ``` **Escenario 5: Ver cuenta cerrada (modo lectura)** ```gherkin DADO que la cuenta está en status "closed" CUANDO el usuario accede a la cuenta ENTONCES se muestra toda la información histórica Y se muestra badge "CUENTA CERRADA" Y NO se muestran acciones (depositar, retirar) Y puede ver historial completo y exportar reportes ``` **Escenario 6: Reabrir cuenta cerrada** ```gherkin DADO que el usuario tiene cuenta cerrada CUANDO navega a la página del producto ENTONCES se muestra opción "Reabrir cuenta" Y al hacer click se reactiva la cuenta (status "active") Y balance inicial es $0 Y se envía email de reactivación ``` ## Criterios Adicionales - [ ] Validar que no hay transacciones pendientes - [ ] Guardar razón de cierre (opcional, dropdown) - [ ] Período de gracia de 30 días antes de eliminar definitivamente - [ ] Permitir exportar todos los datos antes de cerrar - [ ] Enviar encuesta de satisfacción --- ## Tareas Técnicas **Database:** - [ ] DB-INV-001: Agregar status "closing" y "closed" a enum - [ ] DB-INV-002: Campo closed_at en investment.accounts - [ ] DB-INV-003: Campo closure_reason (opcional) **Backend:** - [ ] BE-INV-001: Endpoint POST /investment/accounts/:id/close - [ ] BE-INV-002: Implementar AccountService.closeAccount() - [ ] BE-INV-003: Integración con agente ML para cerrar posiciones - [ ] BE-INV-004: Crear retiro automático de fondos - [ ] BE-INV-005: Validar no hay retiros pendientes - [ ] BE-INV-006: Cron job para marcar "closed" después de 72h - [ ] BE-INV-007: Endpoint POST /investment/accounts/:id/reopen - [ ] BE-INV-008: Enviar email de cierre **Frontend:** - [ ] FE-INV-001: Crear página CloseAccountPage.tsx - [ ] FE-INV-002: Crear componente ClosureSummary.tsx - [ ] FE-INV-003: Crear componente ClosureConfirmation.tsx - [ ] FE-INV-004: Modal de confirmación final - [ ] FE-INV-005: Badge "CUENTA CERRADA" en dashboard - [ ] FE-INV-006: Opción "Reabrir cuenta" **Tests:** - [ ] TEST-INV-001: Test cierre con posiciones abiertas - [ ] TEST-INV-002: Test cierre sin balance - [ ] TEST-INV-003: Test validaciones - [ ] TEST-INV-004: Test reapertura - [ ] TEST-INV-005: Test E2E flujo completo --- ## Dependencias **Depende de:** - [ ] US-INV-006: Solicitar retiro - Estado: Pendiente - [ ] OQI-006: ML Agents (cerrar posiciones) - Estado: Pendiente **Bloquea:** - Ninguna --- ## Notas Técnicas **Endpoints involucrados:** | Método | Endpoint | Descripción | |--------|----------|-------------| | POST | /investment/accounts/:id/close | Cerrar cuenta | | POST | /investment/accounts/:id/reopen | Reabrir cuenta | | GET | /investment/accounts/:id/closure-preview | Preview cierre | **Entidades/Tablas:** - `investment.accounts`: Actualizar status y closed_at - `investment.withdrawals`: Crear retiro final - `investment.account_closures`: Log de cierres **Request Body POST /close:** ```typescript { paymentMethodId: "pm_xxx", closePositions: true, reason?: "no_longer_interested" | "moving_to_competitor" | "satisfied_with_profits" | "other", feedback?: "Optional text feedback" } ``` **Response:** ```typescript { account: { id: "uuid", status: "closing", closedAt: null, // se setea después de 72h finalBalance: 1245.50 }, withdrawal: { id: "uuid", amount: 1245.50, fee: 24.91, netAmount: 1220.59, status: "pending", estimatedCompletionAt: "2025-12-08T..." }, positionsClosed: 2 } ``` **Estados de Cuenta:** - `active`: Cuenta operativa - `closing`: En proceso de cierre (esperando retiro) - `closed`: Cerrada definitivamente (solo lectura) **Flujo de Cierre:** 1. Usuario solicita cierre 2. Sistema valida (no retiros pendientes, etc.) 3. Agente cierra todas las posiciones abiertas 4. Se actualiza balance con P&L final 5. Se crea retiro automático por balance total 6. Status cambia a "closing" 7. Después de 72h (cuando se completa retiro): - Status cambia a "closed" - Se setea closed_at timestamp 8. Usuario recibe email de cierre completado **Email Template:** ``` Subject: ✅ Cuenta de Inversión Cerrada Hola {userName}, Tu cuenta en {agentName} ha sido cerrada exitosamente. Resumen: - Balance final: ${finalBalance} - Rendimiento total: ${totalReturn} ({totalReturnPercentage}%) - Tiempo activa: {duration} Fondos: - Retiro de ${withdrawalAmount} procesado - Recibirás ${netAmount} en tu {paymentMethod} Puedes volver a abrir tu cuenta en cualquier momento. [Reabrir cuenta →] ``` **Restricciones:** - No se puede cerrar cuenta con retiros pendientes - No se puede depositar en cuenta "closing" o "closed" - Cuentas cerradas son solo lectura - Histórico se mantiene indefinidamente - Se puede reabrir cuenta cerrada en cualquier momento --- ## Definition of Ready (DoR) - [x] Historia claramente escrita - [x] Criterios de aceptación definidos - [x] Story points estimados - [x] Dependencias identificadas - [ ] Diseño/mockup disponible - [x] API spec disponible ## Definition of Done (DoD) - [ ] Código implementado según criterios - [ ] Tests unitarios escritos y pasando - [ ] Tests de integración pasando - [ ] Flujo completo testeado - [ ] Integración con agente ML funcionando - [ ] Email service funcionando - [ ] 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