File size: 4,390 Bytes
d7a7993 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
"""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."""
# Build dynamic update query
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")
|