arkan-api / app /services /user.py
masry86's picture
initial commit - arkan backend
de0f1ef
import math
from app.core.exceptions import ConflictError, NotFoundError
from app.core.security import get_password_hash
from app.repositories.user import UserRepository
from app.schemas.user import UserCreate, UserListResponse, UserResponse, UserUpdate
class UserService:
def __init__(self, repo: UserRepository):
self.repo = repo
async def list_users(self, page: int, size: int) -> UserListResponse:
users, total = await self.repo.list(
offset=(page - 1) * size,
limit=size,
order_by=None,
)
return UserListResponse(
items=[UserResponse.model_validate(u) for u in users],
total=total,
page=page,
size=size,
pages=math.ceil(total / size) if total else 1,
)
async def create_user(self, data: UserCreate) -> UserResponse:
if await self.repo.get_by_username(data.username):
raise ConflictError("البيانات المدخلة غير صحيحة")
if data.email and await self.repo.get_by_email(data.email):
raise ConflictError("البيانات المدخلة غير صحيحة")
user = await self.repo.create(
username=data.username,
email=data.email,
password_hash=get_password_hash(data.password),
role=data.role,
)
return UserResponse.model_validate(user)
async def get_user(self, user_id: int) -> UserResponse:
user = await self.repo.get(user_id)
if not user:
raise NotFoundError("User")
return UserResponse.model_validate(user)
async def update_user(self, user_id: int, data: UserUpdate) -> UserResponse:
user = await self.repo.get(user_id)
if not user:
raise NotFoundError("User")
updates = data.model_dump(exclude_unset=True)
if "email" in updates and updates["email"] and updates["email"] != user.email:
existing = await self.repo.get_by_email(updates["email"])
if existing:
raise ConflictError("البيانات المدخلة غير صحيحة") # ✅ تم التعديل
if "password" in updates:
updates["password_hash"] = get_password_hash(updates.pop("password"))
user = await self.repo.update(user, **updates)
return UserResponse.model_validate(user)
async def delete_user(self, user_id: int, current_admin_id: int) -> None:
if user_id == current_admin_id:
raise ConflictError("Cannot delete your own account")
user = await self.repo.get(user_id)
if not user:
raise NotFoundError("User")
await self.repo.delete(user)