Saltar al contenido principal

Eliminar Cuenta de Usuario

Eliminación permanente de la cuenta del usuario autenticado mediante sistema de soft delete con auditoría completa.

DELETE

Marca la cuenta como eliminada, preservando datos para auditoría y posible recuperación


Contexto de Uso

Este endpoint permite a un usuario autenticado solicitar la eliminación permanente de su cuenta. El sistema implementa una eliminación suave (soft delete) donde:

  • La cuenta se marca con isDeleted: true
  • Los datos se copian a la colección DeletedUsers para auditoría
  • El usuario no puede iniciar sesión nuevamente
  • Los datos se preservan para recuperación y cumplimiento legal
  • No se elimina información físicamente de la base de datos

Autenticación requerida: JWT Token válido en header Authorization: Bearer <token>


Validación de Entrada

Autenticación JWT

Token de Acceso Requerido

Este endpoint requiere un JWT token válido en el header de autorización:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Extracción de identidad:

  • El email del usuario se obtiene de req.user.sub.email
  • Este campo proviene del payload decodificado del JWT
  • No se requieren parámetros adicionales en el body

Validación automática:

  • Guard JwtAuthGuard valida el token
  • Si falla, retorna 401 Unauthorized
  • Si pasa, el controlador tiene acceso a req.user

Sin Parámetros de Body

Sin Parámetros Requeridos

Este endpoint no requiere body en la petición:

  • No se envían datos en el cuerpo de la solicitud
  • La identidad del usuario se obtiene completamente del JWT
  • El método HTTP DELETE no espera payload
// Correcto
await fetch('/auth/account', {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${token}`
}
});

// No necesitas body

Tipos de Respuesta

Respuesta Exitosa

Cuenta Eliminada Exitosamente

Código 1012 - La cuenta se marcó como eliminada correctamente.

{
"code": 1012,
"message": "Account deleted successfully",
"data": {
"status": "success"
}
}

Efectos de la eliminación:

  • Campo isDeleted: true en el usuario
  • Registro creado en colección DeletedUsers
  • Usuario no puede iniciar sesión nuevamente
  • Datos preservados para auditoría
  • Timestamp de eliminación registrado

Próximos pasos:

  • Limpiar tokens del cliente
  • Cerrar todas las sesiones activas
  • Redirigir a página de despedida
  • Mostrar confirmación al usuario

Errores de Validación

Token JWT Inválido o Expirado

HTTP 401 Unauthorized - El token JWT no es válido o ha expirado.

{
"statusCode": 401,
"message": "Unauthorized"
}

Causas comunes:

  • Token JWT no enviado en header
  • Token JWT inválido o mal formado
  • Token JWT expirado
  • Firma del token incorrecta
  • Header Authorization mal formado

Acción requerida:

  • Usuario debe iniciar sesión nuevamente
  • Obtener un nuevo accessToken
  • Reintentar la operación con token válido

Usuario No Encontrado

Código 4001 - El usuario especificado en el JWT no existe en la base de datos.

{
"code": 4001,
"message": "User not found"
}

Causas posibles:

  • Email en JWT no existe en MongoDB
  • Usuario ya fue eliminado previamente
  • Base de datos inconsistente
  • Token JWT contiene datos inválidos

Acción requerida:

  • Verificar que el token corresponda a un usuario válido
  • Si ya fue eliminado, informar al usuario
  • Limpiar sesión y redirigir a login

Error del Servidor

Código 5003 - Error interno al procesar la eliminación.

{
"code": 5003,
"message": "Error deleting user",
"statusCode": 500
}

Causas posibles:

  • Error de conexión con MongoDB
  • Fallo al crear registro en DeletedUsers
  • Error al actualizar campo isDeleted
  • Timeout de base de datos

Respuesta genérica alternativa:

{
"statusCode": 500,
"message": "Error deleting account."
}

Acción requerida:

  • Reintentar la operación
  • Si persiste, contactar soporte
  • Verificar estado del servidor

Flujo de Eliminación

Diagrama de Secuencia

sequenceDiagram
participant U as Usuario
participant C as Cliente
participant API as API
participant JWT as JWTGuard
participant DB as MongoDB
participant DU as DeletedUsers

U->>C: Solicita eliminar cuenta
C->>API: DELETE /auth/account<br/>Authorization: Bearer token

API->>JWT: Validar JWT token

alt Token inválido
JWT-->>API: Error validación
API-->>C: 401 Unauthorized
C-->>U: Sesión expirada
else Token válido
JWT-->>API: Usuario autenticado
API->>API: Extraer email de JWT
API->>DB: Buscar usuario por email

alt Usuario no existe
DB-->>API: null
API-->>C: 404 (code: 4001)
C-->>U: Usuario no encontrado
else Usuario existe
DB-->>API: Datos del usuario
API->>DU: Crear registro eliminación
Note over DU: email, deletedAt, reason
API->>DB: UPDATE isDeleted = true

alt Error en proceso
API-->>C: 500 (code: 5003)
C-->>U: Error del servidor
else Eliminación exitosa
API-->>C: 200 (code: 1012)
C->>C: Limpiar tokens
C->>C: Cerrar sesiones
C-->>U: Cuenta eliminada
Note over U,DU: Redirigir a página despedida
end
end
end

Proceso Interno del Endpoint

Flujo de Procesamiento

Pasos del Proceso de Eliminación

1. Validación de Autenticación

@UseGuards(JwtAuthGuard)
@Delete('account')
async deleteAccount(@Request() req) {
// Guard valida automáticamente el token
// Si falla, retorna 401 Unauthorized
}

2. Extracción de Email del Usuario

const email = req.user.sub.email;
// Email obtenido del payload decodificado del JWT
// Formato: { sub: { email: "user@example.com" } }

3. Búsqueda del Usuario

const user = await this.userModel.findOne({ email });

if (!user) {
throw new NotFoundException({
code: 4001,
message: 'User not found'
});
}

4. Creación de Registro en DeletedUsers

await this.deletedUserModel.create({
email: user.email,
deletedAt: new Date(),
reason: 'User requested deletion'
});
// Preserva evidencia de la eliminación para auditoría

5. Marcado como Eliminado (Soft Delete)

await this.userModel.findOneAndUpdate(
{ email: user.email },
{ $set: { isDeleted: true } }
);
// No elimina el documento, solo marca el campo

6. Respuesta Exitosa

return {
code: 1012,
message: 'Account deleted successfully',
data: {
status: 'success'
}
};

7. Manejo de Errores

try {
// Proceso de eliminación...
} catch (error) {
throw new InternalServerErrorException({
code: 5003,
message: 'Error deleting user',
statusCode: 500
});
}

Seguridad y Auditoría

Características de Seguridad

Protecciones Implementadas

Autenticación Estricta:

  • Solo usuarios autenticados pueden eliminar su cuenta
  • JWT Guard valida automáticamente el token
  • No se permite eliminación de cuentas ajenas
  • El email se extrae del JWT, no del body (previene manipulación)

Eliminación Suave (Soft Delete):

  • No elimina datos físicamente de la base de datos
  • Marca usuario con isDeleted: true
  • Preserva toda la información histórica
  • Permite auditorías y cumplimiento legal

Registro de Auditoría:

// Colección DeletedUsers almacena:
{
email: string, // Email del usuario eliminado
deletedAt: Date, // Timestamp exacto de eliminación
reason: string, // Motivo: "User requested deletion"
_id: ObjectId // ID único del registro
}

Prevención de Re-uso:

  • Email queda bloqueado en DeletedUsers
  • Usuario no puede crear nueva cuenta con mismo email
  • Previene fraude y abuso del sistema
  • Requiere limpieza manual para liberar email

Datos Preservados

Información Mantenida Post-Eliminación

Colección Users:

  • Todos los datos del usuario intactos
  • Campo isDeleted: true agregado
  • Historial completo preservado
  • Wallets y balances mantenidos
  • Transacciones históricas disponibles
  • Configuraciones de seguridad guardadas

Colección DeletedUsers:

  • Email del usuario eliminado
  • Fecha y hora exacta de eliminación
  • Razón de la eliminación
  • Referencia cruzada con Users

Propósito de Preservación:

  • Cumplimiento de regulaciones (GDPR, etc.)
  • Auditorías de seguridad
  • Investigaciones de fraude
  • Recuperación en casos especiales
  • Análisis de churn y retención

Ejemplos de Implementación

JavaScript (Fetch API)

Implementación Básica
async function deleteAccount(accessToken) {
try {
const response = await fetch('https://api.swapbits.co/auth/account', {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${accessToken}`
}
});

const result = await response.json();

if (response.ok && result.code === 1012) {
console.log('Cuenta eliminada correctamente');

// Limpiar tokens
localStorage.removeItem('accessToken');
sessionStorage.clear();

// Redirigir
window.location.href = '/goodbye';

return result;
} else {
throw new Error(result.message || 'Error al eliminar cuenta');
}
} catch (error) {
console.error('Error:', error);
throw error;
}
}
Con Sistema de Confirmación
async function confirmAndDeleteAccount(accessToken) {
// Primera confirmación
const confirmed = confirm(
'⚠️ ADVERTENCIA: Eliminación de Cuenta\n\n' +
'Esta acción eliminará permanentemente:\n' +
'• Todos tus datos personales\n' +
'• Tus wallets y balances\n' +
'• Tu historial de transacciones\n' +
'• Todas tus configuraciones\n\n' +
'¿Estás seguro de que deseas continuar?'
);

if (!confirmed) {
console.log('Eliminación cancelada por el usuario');
return { cancelled: true };
}

// Segunda confirmación con texto
const confirmation = prompt(
'Para confirmar, escribe "ELIMINAR" (en mayúsculas):'
);

if (confirmation !== 'ELIMINAR') {
alert('Confirmación incorrecta. Eliminación cancelada.');
return { cancelled: true };
}

try {
const result = await deleteAccount(accessToken);
return { success: true, data: result };
} catch (error) {
alert(`Error: ${error.message}`);
return { success: false, error: error.message };
}
}

// Uso
const accessToken = localStorage.getItem('accessToken');
confirmAndDeleteAccount(accessToken)
.then(result => {
if (result.success) {
console.log('Cuenta eliminada exitosamente');
} else if (result.cancelled) {
console.log('Usuario canceló la operación');
}
});

TypeScript (Axios)

Servicio Completo de Eliminación
import axios, { AxiosError } from 'axios';

interface DeleteAccountResponse {
code: number;
message: string;
data: {
status: string;
};
}

interface ErrorResponse {
code?: number;
message: string;
statusCode?: number;
}

class AccountDeletionService {
private readonly apiUrl = 'https://api.swapbits.co';
private accessToken: string;

constructor(accessToken: string) {
if (!accessToken) {
throw new Error('Token de acceso requerido');
}
this.accessToken = accessToken;
}

/**
* Elimina la cuenta del usuario autenticado
*/
async deleteAccount(): Promise<DeleteAccountResponse> {
try {
const response = await axios.delete<DeleteAccountResponse>(
`${this.apiUrl}/auth/account`,
{
headers: {
'Authorization': `Bearer ${this.accessToken}`
}
}
);

if (response.data.code === 1012) {
// Limpiar datos locales después de eliminación exitosa
this.clearAuthData();
}

return response.data;
} catch (error) {
throw this.handleError(error);
}
}

/**
* Maneja errores de la petición
*/
private handleError(error: unknown): Error {
if (axios.isAxiosError(error)) {
const axiosError = error as AxiosError<ErrorResponse>;
const errorData = axiosError.response?.data;
const status = axiosError.response?.status;

switch (status) {
case 401:
return new Error('Sesión expirada. Inicia sesión nuevamente.');
case 404:
if (errorData?.code === 4001) {
return new Error('Usuario no encontrado.');
}
return new Error('Recurso no encontrado.');
case 500:
if (errorData?.code === 5003) {
return new Error('Error del servidor al eliminar cuenta. Intenta más tarde.');
}
return new Error('Error interno del servidor.');
default:
return new Error(errorData?.message || 'Error desconocido');
}
}

return new Error('Error de conexión');
}

/**
* Limpia todos los datos de autenticación
*/
private clearAuthData(): void {
// Limpiar localStorage
localStorage.removeItem('accessToken');
localStorage.removeItem('refreshToken');

// Limpiar sessionStorage
sessionStorage.removeItem('pinAuthToken');
sessionStorage.clear();

// Limpiar cookies
document.cookie.split(";").forEach((cookie) => {
document.cookie = cookie
.replace(/^ +/, "")
.replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/");
});
}

/**
* Valida que la cuenta puede ser eliminada
*/
async canDelete(): Promise<{ canDelete: boolean; reason?: string }> {
// Aquí puedes agregar validaciones adicionales
// Por ejemplo: verificar saldo, transacciones pendientes, etc.

return { canDelete: true };
}
}

// Hook de React para eliminación de cuenta
export function useDeleteAccount() {
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [success, setSuccess] = useState(false);

const deleteAccount = async (accessToken: string): Promise<boolean> => {
setLoading(true);
setError(null);
setSuccess(false);

try {
const service = new AccountDeletionService(accessToken);
const result = await service.deleteAccount();

setSuccess(true);
return true;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Error desconocido';
setError(errorMessage);
return false;
} finally {
setLoading(false);
}
};

return { loading, error, success, deleteAccount };
}

Python (requests)

Cliente Python Completo
import requests
from typing import Dict, Any, Optional
from datetime import datetime

class AccountDeletionClient:
"""Cliente para eliminación de cuenta de usuario"""

def __init__(self, access_token: str, api_url: str = 'https://api.swapbits.co'):
if not access_token:
raise ValueError('Token de acceso requerido')

self.access_token = access_token
self.api_url = api_url
self.headers = {
'Authorization': f'Bearer {access_token}'
}

def delete_account(self) -> Dict[str, Any]:
"""
Elimina la cuenta del usuario autenticado

Returns:
Respuesta del servidor con código y mensaje

Raises:
Exception: Si hay error en la solicitud
"""
url = f'{self.api_url}/auth/account'

try:
response = requests.delete(url, headers=self.headers, timeout=10)
response_data = response.json()

# Manejar respuesta exitosa
if response.status_code == 200 and response_data.get('code') == 1012:
return {
'success': True,
'code': response_data['code'],
'message': response_data['message'],
'data': response_data['data']
}

# Manejar errores específicos
return self._handle_error(response.status_code, response_data)

except requests.exceptions.Timeout:
raise Exception('Tiempo de espera agotado. Intenta nuevamente.')
except requests.exceptions.ConnectionError:
raise Exception('Error de conexión. Verifica tu internet.')
except requests.exceptions.RequestException as e:
raise Exception(f'Error en la solicitud: {str(e)}')
except ValueError:
raise Exception('Respuesta inválida del servidor')

def _handle_error(self, status_code: int, response_data: Dict) -> Dict:
"""Maneja errores de la API"""
error_code = response_data.get('code')
message = response_data.get('message', 'Error desconocido')

error_map = {
401: 'Sesión expirada. Inicia sesión nuevamente.',
404: 'Usuario no encontrado.' if error_code == 4001 else message,
500: 'Error del servidor. Intenta más tarde.' if error_code == 5003 else message
}

error_message = error_map.get(status_code, message)

return {
'success': False,
'error': error_message,
'code': error_code,
'status_code': status_code
}

def confirm_deletion() -> bool:
"""Solicita confirmación al usuario antes de eliminar"""
print("\n" + "=" * 70)
print("⚠️ ADVERTENCIA: ELIMINACIÓN PERMANENTE DE CUENTA")
print("=" * 70)
print("\nEstás a punto de eliminar tu cuenta permanentemente.")
print("\nPerderás acceso a:")
print(" • Todos tus datos personales")
print(" • Tus wallets y balances de criptomonedas")
print(" • Tu historial completo de transacciones")
print(" • Todas tus configuraciones y preferencias")
print(" • Cualquier beneficio o recompensa acumulada")
print("\n" + "=" * 70)

# Primera confirmación
response = input("\n¿Estás seguro de que deseas continuar? (sí/no): ").strip().lower()
if response not in ['sí', 'si', 'yes', 's']:
print("\n✓ Eliminación cancelada.")
return False

# Segunda confirmación con texto específico
print("\nPara confirmar, escribe exactamente: ELIMINAR")
confirmation = input("Confirmación: ").strip()

if confirmation != 'ELIMINAR':
print("\n✗ Confirmación incorrecta. Eliminación cancelada.")
return False

return True

def delete_account_interactive(access_token: str) -> None:
"""Función interactiva para eliminar cuenta"""
try:
# Solicitar confirmación
if not confirm_deletion():
return

# Crear cliente y eliminar cuenta
print("\nProcesando eliminación...")
client = AccountDeletionClient(access_token)
result = client.delete_account()

if result['success']:
print(f"\n✓ {result['message']}")
print(f"Código: {result['code']}")
print(f"Estado: {result['data']['status']}")
print("\nGracias por usar nuestros servicios.")
print("Tu cuenta ha sido marcada para eliminación.")
else:
print(f"\n✗ Error: {result['error']}")
print(f"Código: {result.get('code', 'N/A')}")

except Exception as e:
print(f"\n✗ Error inesperado: {e}")

# Ejemplo de uso
if __name__ == '__main__':
print("Sistema de Eliminación de Cuenta\n")

# Obtener token (en producción vendría de archivo seguro o variable de entorno)
access_token = input('Ingresa tu token de acceso: ').strip()

if not access_token:
print("Error: Token requerido")
exit(1)

delete_account_interactive(access_token)

cURL

Comando Básico
curl -X DELETE 'https://api.swapbits.co/auth/account' \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
Script Bash Completo con Validaciones
#!/bin/bash

# Script para eliminación de cuenta con confirmaciones
API_URL="https://api.swapbits.co/auth/account"

# Colores para output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Función de confirmación
confirm_deletion() {
echo -e "${RED}═══════════════════════════════════════════════════════════${NC}"
echo -e "${RED} ⚠️ ADVERTENCIA: ELIMINACIÓN DE CUENTA ⚠️${NC}"
echo -e "${RED}═══════════════════════════════════════════════════════════${NC}"
echo ""
echo "Esta acción eliminará permanentemente:"
echo " • Todos tus datos personales"
echo " • Tus wallets y balances"
echo " • Tu historial de transacciones"
echo " • Todas tus configuraciones"
echo ""

read -p "¿Deseas continuar? (sí/no): " confirm

if [[ ! "$confirm" =~ ^(sí|si|yes|s|SI|SÍ)$ ]]; then
echo -e "${GREEN}✓ Eliminación cancelada${NC}"
return 1
fi

echo ""
echo -e "${YELLOW}Para confirmar, escribe exactamente: ELIMINAR${NC}"
read -p "Confirmación: " double_confirm

if [ "$double_confirm" != "ELIMINAR" ]; then
echo -e "${RED}✗ Confirmación incorrecta. Eliminación cancelada.${NC}"
return 1
fi

return 0
}

# Función principal de eliminación
delete_account() {
local token=$1

if [ -z "$token" ]; then
echo -e "${RED}✗ Token de acceso requerido${NC}"
return 1
fi

echo -e "${YELLOW}Procesando eliminación...${NC}"

# Hacer petición a la API
response=$(curl -s -w "\n%{http_code}" -X DELETE "$API_URL" \
-H "Authorization: Bearer $token" \
-H "Content-Type: application/json")

# Separar body y status code
http_code=$(echo "$response" | tail -n1)
body=$(echo "$response" | sed '$d')

# Verificar si jq está instalado
if ! command -v jq &> /dev/null; then
echo "Respuesta: $body"
[ "$http_code" -eq 200 ] && echo -e "${GREEN}✓ Eliminación exitosa${NC}" || echo -e "${RED}✗ Error${NC}"
return
fi

# Parsear JSON
code=$(echo "$body" | jq -r '.code // empty')
message=$(echo "$body" | jq -r '.message // empty')

# Manejar respuesta
case $http_code in
200)
if [ "$code" = "1012" ]; then
echo -e "${GREEN}✓ Cuenta eliminada exitosamente${NC}"
echo "Mensaje: $message"
echo ""
echo "Gracias por usar nuestros servicios."
else
echo -e "${YELLOW}Respuesta inesperada${NC}"
echo "Código: $code"
echo "Mensaje: $message"
fi
;;
401)
echo -e "${RED}✗ Sesión expirada${NC}"
echo "Por favor, inicia sesión nuevamente."
;;
404)
echo -e "${RED}✗ Usuario no encontrado${NC}"
echo "Código: $code"
;;
500)
echo -e "${RED}✗ Error del servidor${NC}"
echo "Mensaje: $message"
echo "Intenta nuevamente más tarde."
;;
*)
echo -e "${RED}✗ Error desconocido${NC}"
echo "HTTP Status: $http_code"
echo "Respuesta: $body"
;;
esac
}

# Modo interactivo
if [ "$#" -eq 0 ]; then
echo "Sistema de Eliminación de Cuenta"
echo ""
read -p "Token de acceso: " access_token
echo ""

if confirm_deletion; then
echo ""
delete_account "$access_token"
fi
else
# Modo con parámetro
delete_account "$1"
fi

Consideraciones de Seguridad

Protecciones Implementadas

Medidas de Seguridad

1. Autenticación Estricta

// Solo el propietario puede eliminar su cuenta
@UseGuards(JwtAuthGuard)
async deleteAccount(@Request() req) {
const email = req.user.sub.email;
// Email extraído del JWT, no del body
// Previene manipulación de parámetros
}

2. Validación de Permisos

// No se permite eliminar cuentas ajenas
class AccountDeletionValidator {
canDelete(tokenEmail: string, targetEmail: string): boolean {
return tokenEmail === targetEmail;
}
}

3. Soft Delete (Preservación de Datos)

// No se eliminan datos físicamente
await userModel.findOneAndUpdate(
{ email },
{ $set: { isDeleted: true } }
);
// Datos intactos para auditoría

4. Registro de Auditoría

// Cada eliminación se registra
await deletedUserModel.create({
email: user.email,
deletedAt: new Date(),
reason: 'User requested deletion',
deletedBy: 'self' // o ID de admin si aplica
});

5. Prevención de Re-uso de Email

// Email bloqueado en DeletedUsers
// Previene creación de nueva cuenta con mismo email
// Requiere limpieza manual para liberar

Recomendaciones de Implementación

Mejores Prácticas

1. Período de Gracia (Recomendado)

// Implementar período de 30 días antes de eliminación final
interface DeletionRequest {
email: string;
requestedAt: Date;
scheduledFor: Date; // requestedAt + 30 días
status: 'pending' | 'cancelled' | 'completed';
}

// Permitir cancelación dentro del período
async cancelDeletion(email: string) {
await deletionRequestModel.updateOne(
{ email, status: 'pending' },
{ $set: { status: 'cancelled' } }
);
}

2. Notificación por Email

// Enviar confirmación de eliminación
await emailService.send({
to: user.email,
subject: 'Confirmación de eliminación de cuenta',
template: 'account-deletion-confirmation',
data: {
userName: user.name,
deletionDate: new Date(),
cancellationLink: generateCancellationLink(user.email)
}
});

3. Limpieza de Datos Relacionados

// Cancelar servicios y limpiar datos asociados
async cleanupUserData(userId: string) {
await Promise.all([
walletService.closeWallets(userId),
transactionService.archiveHistory(userId),
sessionService.revokeAll(userId),
subscriptionService.cancel(userId),
notificationService.unsubscribe(userId)
]);
}

4. Verificación de Transacciones Pendientes

async canDeleteAccount(userId: string): Promise<boolean> {
const pendingTx = await transactionModel.countDocuments({
userId,
status: 'pending'
});

return pendingTx === 0;
}

5. Backup de Datos Críticos

// Crear respaldo antes de marcar como eliminado
async backupUserData(user: User) {
await backupModel.create({
userId: user._id,
email: user.email,
data: user.toObject(),
wallets: await walletModel.find({ userId: user._id }),
transactions: await txModel.find({ userId: user._id }).limit(1000),
createdAt: new Date(),
expiresAt: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000) // 90 días
});
}

Proceso de Eliminación

Estado Actual (Soft Delete Inmediato)

graph TD
A[Usuario solicita eliminación] --> B{Token válido?}
B -->|No| C[Error 401]
B -->|Sí| D[Buscar usuario]
D --> E{Usuario existe?}
E -->|No| F[Error 4001]
E -->|Sí| G[Crear registro DeletedUsers]
G --> H[Marcar isDeleted = true]
H --> I[Respuesta exitosa 1012]
I --> J[Usuario no puede iniciar sesión]
J --> K[Datos preservados]

style I fill:#90EE90
style C fill:#FFB6C1
style F fill:#FFB6C1

Proceso Recomendado (Con Período de Gracia)

graph TD
A[Usuario solicita eliminación] --> B[Marcar deletionRequested = true]
B --> C[Establecer deletionDate = now + 30 días]
C --> D[Enviar email confirmación]
D --> E[Crear DeletionRequest pendiente]
E --> F{Usuario cancela?}
F -->|Sí| G[Actualizar status = cancelled]
G --> H[Usuario puede seguir usando cuenta]
F -->|No| I{30 días pasaron?}
I -->|No| F
I -->|Sí| J[Job automático ejecuta eliminación]
J --> K[Marcar isDeleted = true]
K --> L[Mover a DeletedUsers]
L --> M[Limpiar datos relacionados]

style G fill:#90EE90
style L fill:#FFD700

Códigos de Respuesta

CódigoHTTP StatusDescripciónAcción Sugerida
1012200Cuenta eliminada exitosamenteLimpiar tokens y redirigir
4001404Usuario no encontradoVerificar JWT y base de datos
5003500Error al eliminar usuarioReintentar o contactar soporte
-401Token JWT inválido/expiradoIniciar sesión nuevamente
-500Error genérico del servidorReintentar más tarde

Notas Importantes

Aspectos Críticos del Endpoint

  1. Eliminación Suave: La cuenta no se elimina físicamente, solo se marca con isDeleted: true

  2. Preservación de Datos: Todos los datos se mantienen intactos para auditoría y cumplimiento legal

  3. Sin Período de Gracia Actual: La eliminación es inmediata (se recomienda implementar período de espera de 30 días)

  4. Recuperación Posible: Con asistencia de soporte técnico, la cuenta puede ser reactivada

  5. Registro en DeletedUsers: Email y fecha de eliminación se almacenan permanentemente

  6. Bloqueo de Email: El email queda bloqueado hasta limpieza manual, no permite re-registro

  7. Sesiones Inválidas: Todas las sesiones activas quedan inmediatamente invalidadas

  8. Sin Limpieza de Datos: Wallets, transacciones y configuraciones permanecen en la base de datos

  9. Auditoría Completa: Cada eliminación se registra con timestamp exacto y razón

  10. Solo Auto-Eliminación: Usuario solo puede eliminar su propia cuenta, no la de otros


Probar esta API

API Explorer

En el API Explorer podrás:

  • Enviar peticiones reales con tu token JWT
  • Ver respuestas en tiempo real
  • Experimentar con diferentes tokens
  • Simular errores de autenticación
  • Ver ejemplos de código generados automáticamente

Enlaces Relacionados

Gestión de Cuenta

Autenticación

  • Login - POST /auth/login

Seguridad

  • Sistema 2FA - Configurar autenticación de dos factores