Skip to content

Eliminar Usuarios

Endpoint para eliminar usuarios del sistema de forma segura.

  • DELETE /api/v1/users/:id - Eliminar usuario específico

Elimina un usuario específico del sistema. Esta operación es irreversible y requiere permisos de administrador.

  • Método: DELETE
  • Endpoint: /api/v1/users/:id
  • Autenticación: Requerida (Bearer Token)
  • Permisos: Administrador
  • Tipo de eliminación: Lógica (soft delete)
  • Reversible: No (requiere restauración manual)
Accept: application/json
Authorization: Bearer {token}
ParámetroTipoRequeridoDescripción
idintegerID del usuario a eliminar
  • ✋ El propio usuario (auto-eliminación)
  • 👑 Usuarios con rol de super administrador
  • 📄 Usuarios con documentos activos pendientes
  • 💼 Usuarios que son únicos administradores de una empresa
  • 🔗 Usuarios con dependencias críticas en el sistema
  • ✅ Usuario existe y está activo
  • ✅ Usuario no tiene documentos en proceso
  • ✅ Usuario no es el último administrador
  • ✅ No hay dependencias críticas
Terminal window
DELETE /api/v1/users/123456789
{
"message": "Usuario eliminado correctamente",
"status": "OK",
"payload": {
"uuid": 123456789,
"name": "Juan",
"last_name": "Pérez",
"email": "[email protected]",
"status": "deleted",
"deleted_at": "2025-01-17 16:30:00",
"deleted_by": 987654321
}
}
{
"message": "Usuario no encontrado",
"status": "ERROR"
}
{
"message": "No tienes permisos para eliminar usuarios",
"status": "ERROR"
}
{
"message": "No se puede eliminar el usuario",
"status": "ERROR",
"errors": {
"restriction": ["El usuario tiene documentos activos pendientes"],
"dependency": ["Es el único administrador de la empresa"]
}
}
{
"message": "No puedes eliminar tu propia cuenta",
"status": "ERROR"
}
Terminal window
# Eliminar usuario
curl -X DELETE "https://dev-facturacion.e-dinky.test/api/v1/users/123456789" \
-H "Accept: application/json" \
-H "Authorization: Bearer {token}"
# Verificar si usuario puede ser eliminado (opcional)
curl -X GET "https://dev-facturacion.e-dinky.test/api/v1/users/123456789/can-delete" \
-H "Accept: application/json" \
-H "Authorization: Bearer {token}"
const checkUserDependencies = async (userId) => {
const dependencies = {
documents: 0,
companies: 0,
permissions: 0,
active_sessions: 0
};
try {
// Verificar documentos
const docsResponse = await axios.get('/api/v1/documents', {
params: {
filters: JSON.stringify([
{ field: 'user_id', condition: 'eq', value: userId },
{ field: 'status', condition: 'ne', value: 'deleted' }
])
}
});
dependencies.documents = docsResponse.data.payload.count;
// Verificar empresas administradas
const companiesResponse = await axios.get('/api/v1/companies', {
params: {
filters: JSON.stringify([
{ field: 'admin_user_id', condition: 'eq', value: userId }
])
}
});
dependencies.companies = companiesResponse.data.payload.count;
return dependencies;
} catch (error) {
console.error('Error verificando dependencias:', error.message);
return dependencies;
}
};
function backupUserData($userId, $token) {
try {
// Obtener datos completos del usuario
$userResponse = Http::withHeaders([
'Authorization' => 'Bearer ' . $token,
])->get("https://dev-facturacion.e-dinky.test/api/v1/users/{$userId}");
if (!$userResponse->successful()) {
throw new Exception('No se pudo obtener datos del usuario');
}
$userData = $userResponse->json()['payload'];
// Obtener documentos del usuario
$documentsResponse = Http::withHeaders([
'Authorization' => 'Bearer ' . $token,
])->get('https://dev-facturacion.e-dinky.test/api/v1/documents', [
'filters' => json_encode([
['field' => 'user_id', 'condition' => 'eq', 'value' => $userId]
])
]);
$documents = $documentsResponse->successful() ?
$documentsResponse->json()['payload']['items'] : [];
// Crear backup
$backup = [
'user' => $userData,
'documents' => $documents,
'backup_date' => date('Y-m-d H:i:s'),
'backup_by' => getCurrentUserId()
];
// Guardar backup
$backupFile = "user_backup_{$userId}_" . date('Y-m-d_H-i-s') . '.json';
file_put_contents(storage_path("backups/{$backupFile}"), json_encode($backup, JSON_PRETTY_PRINT));
return $backupFile;
} catch (Exception $e) {
throw new Exception('Error creando backup: ' . $e->getMessage());
}
}
const logUserDeletion = async (userId, deletedBy, reason = null) => {
const auditLog = {
action: 'user_deletion',
user_id: userId,
deleted_by: deletedBy,
reason: reason,
timestamp: new Date().toISOString(),
ip_address: getClientIP(),
user_agent: getUserAgent()
};
try {
await axios.post('/api/v1/audit-logs', auditLog, { headers });
console.log('Eliminación registrada en auditoría');
} catch (error) {
console.error('Error registrando auditoría:', error.message);
}
};
CódigoDescripciónAcción
200Usuario eliminado exitosamenteConfirmar eliminación
401Token inválidoRenovar autenticación
403Sin permisosVerificar permisos de administrador
404Usuario no encontradoVerificar ID del usuario
422No se puede eliminarRevisar restricciones
500Error del servidorReintentar más tarde
// Proceso de eliminación en etapas
const gradualUserDeletion = async (userId) => {
// Etapa 1: Desactivar usuario
await updateUser(userId, { status: 'inactive' });
console.log('Usuario desactivado');
// Etapa 2: Esperar período de gracia (ej: 30 días)
const gracePeriod = 30 * 24 * 60 * 60 * 1000; // 30 días
console.log('Período de gracia iniciado');
// Etapa 3: Eliminar definitivamente
setTimeout(async () => {
const result = await deleteUser(userId);
if (result.success) {
console.log('Usuario eliminado definitivamente');
}
}, gracePeriod);
};
// Transferir documentos antes de eliminar
function transferUserAssets($fromUserId, $toUserId, $token) {
// Transferir documentos
$documentsResponse = Http::withHeaders([
'Authorization' => 'Bearer ' . $token,
])->get('https://dev-facturacion.e-dinky.test/api/v1/documents', [
'filters' => json_encode([
['field' => 'user_id', 'condition' => 'eq', 'value' => $fromUserId]
])
]);
if ($documentsResponse->successful()) {
$documents = $documentsResponse->json()['payload']['items'];
foreach ($documents as $document) {
// Transferir cada documento
Http::withHeaders([
'Authorization' => 'Bearer ' . $token,
])->put("https://dev-facturacion.e-dinky.test/api/v1/documents/{$document['id']}/transfer", [
'new_owner_id' => $toUserId
]);
}
}
echo "Activos transferidos de usuario {$fromUserId} a {$toUserId}\n";
}
// Notificar eliminación a administradores
const notifyUserDeletion = async (deletedUser, deletedBy) => {
const notification = {
type: 'user_deleted',
message: `Usuario ${deletedUser.name} ${deletedUser.last_name} ha sido eliminado`,
deleted_user: {
id: deletedUser.uuid,
name: deletedUser.name,
email: deletedUser.email
},
deleted_by: deletedBy,
timestamp: new Date().toISOString()
};
try {
await axios.post('/api/v1/notifications/admin', notification, { headers });
console.log('Notificación enviada a administradores');
} catch (error) {
console.error('Error enviando notificación:', error.message);
}
};
// Sistema de recuperación de usuarios eliminados
class UserRecoveryService {
public function createRecoveryPoint($userId, $token) {
$userData = $this->getUserData($userId, $token);
$recoveryData = [
'user_data' => $userData,
'created_at' => now(),
'expires_at' => now()->addDays(90) // 90 días para recuperar
];
// Guardar punto de recuperación
$recoveryId = $this->saveRecoveryPoint($userId, $recoveryData);
return $recoveryId;
}
public function recoverUser($recoveryId, $token) {
$recoveryData = $this->getRecoveryPoint($recoveryId);
if (!$recoveryData || $recoveryData['expires_at'] < now()) {
throw new Exception('Punto de recuperación expirado o no encontrado');
}
// Recrear usuario
$newUser = $this->createUserFromRecovery($recoveryData['user_data'], $token);
return $newUser;
}
}
// Eliminar usuarios inactivos automáticamente
const cleanupInactiveUsers = async (daysInactive = 365) => {
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - daysInactive);
const inactiveUsers = await searchUsers([
{ field: 'last_login', condition: 'le', value: cutoffDate.toISOString().split('T')[0] },
{ field: 'status', condition: 'eq', value: 'inactive' }
]);
console.log(`Encontrados ${inactiveUsers.length} usuarios inactivos`);
for (const user of inactiveUsers) {
const canDelete = await canDeleteUser(user.uuid);
if (canDelete.can_delete) {
console.log(`Eliminando usuario inactivo: ${user.email}`);
await deleteUser(user.uuid);
} else {
console.log(`Omitiendo ${user.email}: ${canDelete.reason}`);
}
}
};

2. Eliminación por Violación de Políticas

Section titled “2. Eliminación por Violación de Políticas”
// Eliminar usuario por violación de políticas
function deleteUserForPolicyViolation($userId, $violationType, $evidence, $token) {
// Registrar violación
$violation = [
'user_id' => $userId,
'violation_type' => $violationType,
'evidence' => $evidence,
'reported_at' => now(),
'action_taken' => 'user_deletion'
];
// Guardar evidencia
$evidenceFile = saveViolationEvidence($userId, $evidence);
// Crear backup completo
$backupFile = backupUserData($userId, $token);
// Eliminar usuario
$result = deleteUser($userId, $token);
if ($result) {
// Registrar en sistema de compliance
recordComplianceAction($violation, $backupFile, $evidenceFile);
// Notificar a legal/compliance
notifyComplianceTeam($violation);
}
return $result;
}

3. Migración de Datos Antes de Eliminación

Section titled “3. Migración de Datos Antes de Eliminación”
// Migrar datos críticos antes de eliminar
const migrateAndDeleteUser = async (userId, migrationTarget) => {
try {
// 1. Identificar datos críticos
const criticalData = await identifyCriticalUserData(userId);
// 2. Migrar documentos importantes
if (criticalData.documents.length > 0) {
await migrateDocuments(criticalData.documents, migrationTarget.documents);
}
// 3. Migrar configuraciones
if (criticalData.settings) {
await migrateUserSettings(criticalData.settings, migrationTarget.settings);
}
// 4. Actualizar referencias
await updateUserReferences(userId, migrationTarget.userId);
// 5. Eliminar usuario
const result = await deleteUser(userId);
if (result.success) {
console.log('Usuario eliminado y datos migrados correctamente');
return { success: true, migrated: criticalData };
}
} catch (error) {
console.error('Error en migración y eliminación:', error.message);
return { success: false, error: error.message };
}
};
  • 🚨 Irreversible: La eliminación es permanente y no se puede deshacer fácilmente
  • 🔐 Permisos: Solo administradores pueden eliminar usuarios
  • 📋 Verificaciones: Siempre verificar dependencias antes de eliminar
  • 💾 Backup: Crear respaldo antes de eliminaciones importantes
  • 📝 Auditoría: Registrar todas las eliminaciones para auditoría
  • 🔄 Transferencia: Transferir activos críticos antes de eliminar
  • Período de gracia: Considerar período de gracia para recuperación
  • 🚫 Restricciones: Respetar restricciones del sistema
  • 📧 Notificaciones: Notificar eliminaciones a administradores
  • 🔍 Verificación: Verificar que la eliminación se completó correctamente