| | """User Profile Router.""" |
| |
|
| | from fastapi import APIRouter, HTTPException, Depends, Query |
| | from sqlalchemy.ext.asyncio import AsyncSession |
| | from sqlalchemy import text |
| |
|
| | from app.shared.db.session import get_db |
| | from app.users import Profile, ProfileUpdate, ProfileResponse |
| |
|
| |
|
| | router = APIRouter(prefix="/users", tags=["Users"]) |
| |
|
| |
|
| | @router.get( |
| | "/me", |
| | response_model=ProfileResponse, |
| | summary="Get current user profile", |
| | description="Returns the profile for the authenticated user.", |
| | ) |
| | async def get_my_profile( |
| | user_id: str = Query(..., description="User ID (from auth)"), |
| | db: AsyncSession = Depends(get_db), |
| | ) -> ProfileResponse: |
| | """Get current user's profile.""" |
| | result = await db.execute( |
| | text(""" |
| | SELECT id, full_name, phone, role, locale, avatar_url, created_at, updated_at |
| | FROM profiles |
| | WHERE id = :user_id |
| | """), |
| | {"user_id": user_id} |
| | ) |
| | row = result.fetchone() |
| | |
| | if not row: |
| | raise HTTPException(status_code=404, detail="Profile not found") |
| | |
| | profile = Profile( |
| | id=str(row.id), |
| | full_name=row.full_name, |
| | phone=row.phone, |
| | role=row.role, |
| | locale=row.locale, |
| | avatar_url=row.avatar_url, |
| | created_at=row.created_at, |
| | updated_at=row.updated_at, |
| | ) |
| | |
| | return ProfileResponse(profile=profile, message="Profile retrieved") |
| |
|
| |
|
| | @router.put( |
| | "/me", |
| | response_model=ProfileResponse, |
| | summary="Update current user profile", |
| | description="Updates the profile for the authenticated user.", |
| | ) |
| | async def update_my_profile( |
| | updates: ProfileUpdate, |
| | user_id: str = Query(..., description="User ID (from auth)"), |
| | db: AsyncSession = Depends(get_db), |
| | ) -> ProfileResponse: |
| | """Update current user's profile.""" |
| | |
| | update_fields = [] |
| | params = {"user_id": user_id} |
| | |
| | if updates.full_name is not None: |
| | update_fields.append("full_name = :full_name") |
| | params["full_name"] = updates.full_name |
| | if updates.phone is not None: |
| | update_fields.append("phone = :phone") |
| | params["phone"] = updates.phone |
| | if updates.locale is not None: |
| | update_fields.append("locale = :locale") |
| | params["locale"] = updates.locale |
| | if updates.avatar_url is not None: |
| | update_fields.append("avatar_url = :avatar_url") |
| | params["avatar_url"] = updates.avatar_url |
| | |
| | if not update_fields: |
| | raise HTTPException(status_code=400, detail="No fields to update") |
| | |
| | update_fields.append("updated_at = NOW()") |
| | |
| | query = f""" |
| | UPDATE profiles |
| | SET {', '.join(update_fields)} |
| | WHERE id = :user_id |
| | RETURNING id, full_name, phone, role, locale, avatar_url, created_at, updated_at |
| | """ |
| | |
| | result = await db.execute(text(query), params) |
| | await db.commit() |
| | |
| | row = result.fetchone() |
| | if not row: |
| | raise HTTPException(status_code=404, detail="Profile not found") |
| | |
| | profile = Profile( |
| | id=str(row.id), |
| | full_name=row.full_name, |
| | phone=row.phone, |
| | role=row.role, |
| | locale=row.locale, |
| | avatar_url=row.avatar_url, |
| | created_at=row.created_at, |
| | updated_at=row.updated_at, |
| | ) |
| | |
| | return ProfileResponse(profile=profile, message="Profile updated") |
| |
|
| |
|
| | @router.get( |
| | "/{user_id}", |
| | response_model=ProfileResponse, |
| | summary="Get user profile by ID", |
| | description="Returns the profile for a specific user (admin only).", |
| | ) |
| | async def get_profile_by_id( |
| | user_id: str, |
| | db: AsyncSession = Depends(get_db), |
| | ) -> ProfileResponse: |
| | """Get user profile by ID.""" |
| | result = await db.execute( |
| | text(""" |
| | SELECT id, full_name, phone, role, locale, avatar_url, created_at, updated_at |
| | FROM profiles |
| | WHERE id = :user_id |
| | """), |
| | {"user_id": user_id} |
| | ) |
| | row = result.fetchone() |
| | |
| | if not row: |
| | raise HTTPException(status_code=404, detail="Profile not found") |
| | |
| | profile = Profile( |
| | id=str(row.id), |
| | full_name=row.full_name, |
| | phone=row.phone, |
| | role=row.role, |
| | locale=row.locale, |
| | avatar_url=row.avatar_url, |
| | created_at=row.created_at, |
| | updated_at=row.updated_at, |
| | ) |
| | |
| | return ProfileResponse(profile=profile, message="Profile retrieved") |
| |
|