Files
Daniil 259d3da89f rev 4
2026-04-07 13:42:45 +03:00

81 lines
2.8 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("Пользователь уже существует или нарушены ограничения") 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("Обновление нарушает ограничения") from e
await self._session.refresh(user)
return user
async def update_password(self, user: User, new_hash: str) -> None:
user.password_hash = new_hash
await self._session.commit()
async def deactivate(self, user: User) -> None:
user.is_active = False
await self._session.commit()