from fastapi import HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from externals.databases.pg_crud import ( get_file_by_filename, delete_file_by_filename, set_file_deleted_by_filename, ) from externals.storages.azure_blob import delete_blob_by_filename from utils.logger import get_logger logger = get_logger("knowledge-delete") class KnowledgeDeleteService: def __init__(self, db: AsyncSession, user): self.db = db self.user = user async def delete(self, filename: str) -> None: try: logger.info( "knowledge.delete.requested", extra={ "cv_filename": filename, "user_id": str(self.user.user_id), "tenant_id": str(self.user.tenant_id), }, ) # 1️⃣ Check DB record cv_file = await get_file_by_filename(self.db, filename=filename, user_id=self.user.user_id) if not cv_file: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"File '{filename}' not found", ) # 2️⃣ Delete blob blob_deleted = await delete_blob_by_filename(filename=filename, tenant_id=self.user.tenant_id, user_id=self.user.user_id) if not blob_deleted: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to delete blob file", ) # 3️⃣ Delete DB record await delete_file_by_filename(self.db, filename) logger.info( "knowledge.delete.success", extra={ "cv_filename": filename, "user_id": str(self.user.user_id), }, ) return {"status": "success", "message": f"file '{filename}' has been deleted", "data": { "cv_filename": filename, "user_id": str(self.user.user_id)} } except Exception as e: logger.error( "knowledge.delete.failed", extra={ "cv_filename": filename, "user_id": str(self.user.user_id), "error": str(e), }, ) raise HTTPException(status_code=500, detail=f"Failed to delete file '{filename}': {str(e)}") async def set_deleted(self, filename: str) -> dict: try: logger.info( "knowledge.set_deleted.requested", extra={ "cv_filename": filename, "user_id": str(self.user.user_id), "tenant_id": str(self.user.tenant_id), }, ) # 1️⃣ Check DB record cv_file = await get_file_by_filename(self.db, filename=filename, user_id=self.user.user_id) if not cv_file: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"File '{filename}' not found", ) # 2️⃣ Mark as deleted updated = await set_file_deleted_by_filename(self.db, filename=filename, user_id=self.user.user_id) if not updated: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to mark file as deleted", ) logger.info( "knowledge.set_deleted.success", extra={ "cv_filename": filename, "user_id": str(self.user.user_id), }, ) return { "status": "success", "message": f"File '{filename}' marked as deleted", "data": { "cv_filename": filename, "user_id": str(self.user.user_id), }, } except Exception as e: logger.error( "knowledge.set_deleted.failed", extra={ "cv_filename": filename, "user_id": str(self.user.user_id), "error": str(e), }, ) raise HTTPException(status_code=500, detail=f"Failed to mark file '{filename}' as deleted: {str(e)}")