Files
main_backend/cpv3/modules/users/repository.py
T
2026-02-03 02:15:07 +03:00

77 lines
2.5 KiB
Python

from __future__ import annotations
import uuid
from sqlalchemy import Select, select
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.asyncio import AsyncSession
from cpv3.modules.users.models import User
from cpv3.modules.users.schemas import UserCreate, UserRegister, UserUpdate
from cpv3.infrastructure.security import hash_password
class UserRepository:
"""Repository for User database operations."""
def __init__(self, session: AsyncSession) -> None:
self._session = session
async def get_by_id(self, user_id: uuid.UUID) -> User | None:
result = await self._session.execute(select(User).where(User.id == user_id))
return result.scalar_one_or_none()
async def get_by_username(self, username: str) -> User | None:
result = await self._session.execute(
select(User).where(User.username == username)
)
return result.scalar_one_or_none()
async def list_all(self, *, requester: User) -> list[User]:
stmt: Select[tuple[User]] = select(User)
if not requester.is_staff:
stmt = stmt.where(User.id == requester.id)
result = await self._session.execute(stmt.order_by(User.created_at.desc()))
return list(result.scalars().all())
async def create(self, *, data: UserCreate | UserRegister) -> User:
user = User(
username=data.username,
email=data.email,
password_hash=hash_password(data.password),
first_name=data.first_name,
last_name=data.last_name,
phone_number=data.phone_number,
avatar=data.avatar,
)
self._session.add(user)
try:
await self._session.commit()
except IntegrityError as e:
await self._session.rollback()
raise ValueError("User already exists or violates constraints") from e
await self._session.refresh(user)
return user
async def update(self, user: User, data: UserUpdate) -> User:
update_data = data.model_dump(exclude_unset=True)
for key, value in update_data.items():
if value is not None:
setattr(user, key, value)
try:
await self._session.commit()
except IntegrityError as e:
await self._session.rollback()
raise ValueError("Update violates constraints") from e
await self._session.refresh(user)
return user
async def deactivate(self, user: User) -> None:
user.is_active = False
await self._session.commit()