Improve user delete flow
This commit is contained in:
@@ -7,6 +7,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from typing import Dict, Any
|
||||
import structlog
|
||||
import uuid
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from app.core.database import get_db
|
||||
from app.schemas.auth import UserResponse, PasswordChange
|
||||
@@ -120,7 +121,7 @@ async def update_current_user(
|
||||
detail="Failed to update user"
|
||||
)
|
||||
|
||||
@router.delete("/delete/users/{user_id}")
|
||||
@router.delete("/delete/{user_id}")
|
||||
async def delete_admin_user(
|
||||
user_id: str,
|
||||
background_tasks: BackgroundTasks,
|
||||
@@ -158,35 +159,83 @@ async def delete_admin_user(
|
||||
detail="Cannot delete your own account"
|
||||
)
|
||||
|
||||
# Initialize deletion service
|
||||
# Quick validation that user exists before starting background task
|
||||
deletion_service = AdminUserDeleteService(db)
|
||||
|
||||
# Perform the deletion
|
||||
try:
|
||||
result = await deletion_service.delete_admin_user_complete(
|
||||
user_id=user_id,
|
||||
requesting_user_id=current_user.id
|
||||
)
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"message": f"Admin user {user_id} has been successfully deleted",
|
||||
"deletion_details": result
|
||||
}
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error("Unexpected error during user deletion",
|
||||
user_id=user_id,
|
||||
error=str(e))
|
||||
user_info = await deletion_service._validate_admin_user(user_id)
|
||||
if not user_info:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="An unexpected error occurred during user deletion"
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Admin user {user_id} not found"
|
||||
)
|
||||
|
||||
# Start deletion as background task for better performance
|
||||
background_tasks.add_task(
|
||||
execute_admin_user_deletion,
|
||||
user_id=user_id,
|
||||
requesting_user_id=current_user.id,
|
||||
db_url=str(db.bind.url) # Pass DB connection string for background task
|
||||
)
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"message": f"Admin user deletion for {user_id} has been initiated",
|
||||
"status": "processing",
|
||||
"user_info": user_info,
|
||||
"initiated_at": datetime.utcnow().isoformat(),
|
||||
"note": "Deletion is processing in the background. Check logs for completion status."
|
||||
}
|
||||
|
||||
# Add this background task function to services/auth/app/api/users.py:
|
||||
|
||||
async def execute_admin_user_deletion(
|
||||
user_id: str,
|
||||
requesting_user_id: str,
|
||||
db_url: str
|
||||
):
|
||||
"""
|
||||
Background task to execute complete admin user deletion
|
||||
"""
|
||||
# Create new database session for background task
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
engine = create_async_engine(db_url)
|
||||
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
async with async_session() as session:
|
||||
try:
|
||||
# Initialize deletion service with new session
|
||||
deletion_service = AdminUserDeleteService(session)
|
||||
|
||||
# Perform the deletion
|
||||
result = await deletion_service.delete_admin_user_complete(
|
||||
user_id=user_id,
|
||||
requesting_user_id=requesting_user_id
|
||||
)
|
||||
|
||||
logger.info("Background admin user deletion completed successfully",
|
||||
user_id=user_id,
|
||||
requesting_user=requesting_user_id,
|
||||
result=result)
|
||||
|
||||
except Exception as e:
|
||||
logger.error("Background admin user deletion failed",
|
||||
user_id=user_id,
|
||||
requesting_user=requesting_user_id,
|
||||
error=str(e))
|
||||
|
||||
# Attempt to publish failure event
|
||||
try:
|
||||
deletion_service = AdminUserDeleteService(session)
|
||||
await deletion_service._publish_user_deletion_failed_event(user_id, str(e))
|
||||
except:
|
||||
pass
|
||||
|
||||
finally:
|
||||
await engine.dispose()
|
||||
|
||||
|
||||
@router.get("/delete/users/{user_id}/deletion-preview")
|
||||
@router.get("/delete/{user_id}/deletion-preview")
|
||||
async def preview_user_deletion(
|
||||
user_id: str,
|
||||
current_user = Depends(get_current_user_dep),
|
||||
|
||||
Reference in New Issue
Block a user