from fastapi import APIRouter, Depends, HTTPException from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.db.session import get_session from app.models.user import User from app.schemas.user import UserPreferencesUpdate, UserRead, UserUpsert router = APIRouter(prefix="/users", tags=["users"]) @router.post("", response_model=UserRead) async def upsert_user(payload: UserUpsert, session: AsyncSession = Depends(get_session)) -> User: result = await session.execute(select(User).where(User.telegram_id == payload.telegram_id)) user = result.scalar_one_or_none() if user is None: user = User(**payload.model_dump(exclude_none=True)) session.add(user) else: for field, value in payload.model_dump(exclude_none=True).items(): setattr(user, field, value) await session.commit() await session.refresh(user) return user @router.get("/telegram/{telegram_id}", response_model=UserRead) async def get_user_by_telegram_id( telegram_id: int, session: AsyncSession = Depends(get_session) ) -> User: result = await session.execute(select(User).where(User.telegram_id == telegram_id)) return result.scalar_one() @router.patch("/{user_id}/preferences", response_model=UserRead) async def update_preferences( user_id: int, payload: UserPreferencesUpdate, session: AsyncSession = Depends(get_session) ) -> User: user = await session.get(User, user_id) if user is None: raise HTTPException(status_code=404, detail="User not found") for field, value in payload.model_dump(exclude_none=True).items(): setattr(user, field, value) await session.commit() await session.refresh(user) return user