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")