File size: 3,927 Bytes
6e8d513 |
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 |
"""User management endpoints"""
from fastapi import APIRouter, HTTPException, Header
from typing import Optional
import logging
from services.user_service import user_service
from models.user import (
UserRegisterRequest,
UserResponse,
UserUpdateNameRequest,
UserGetRequest,
)
router = APIRouter()
logger = logging.getLogger(__name__)
@router.post("/register", response_model=UserResponse, tags=["Users"])
async def register_user(request: UserRegisterRequest):
"""
Register a new user or get existing user by unique_id
- **unique_id**: Browser-generated unique identifier (from localStorage)
- **name**: Optional display name (will generate random if not provided)
Returns user data including the user_id to store in localStorage
"""
try:
user = user_service.register_or_get_user(
unique_id=request.unique_id,
name=request.name
)
logger.info(f"User registered/retrieved: {user.get('id')}")
return UserResponse(**user)
except ValueError as e:
logger.error(f"Validation error: {str(e)}")
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
logger.error(f"Registration error: {str(e)}")
raise HTTPException(status_code=500, detail=f"Registration failed: {str(e)}")
@router.get("/me", response_model=UserResponse, tags=["Users"])
async def get_current_user(x_user_id: Optional[str] = Header(None, alias="X-User-ID")):
"""
Get current user by user_id from header
- **X-User-ID**: User UUID (sent in request header)
Returns user data
"""
if not x_user_id:
raise HTTPException(status_code=400, detail="X-User-ID header is required")
try:
user = user_service.get_user_by_id(x_user_id)
if not user:
raise HTTPException(status_code=404, detail="User not found")
return UserResponse(**user)
except HTTPException:
raise
except Exception as e:
logger.error(f"Error getting user: {str(e)}")
raise HTTPException(status_code=500, detail=f"Failed to get user: {str(e)}")
@router.get("/by-unique-id", response_model=UserResponse, tags=["Users"])
async def get_user_by_unique_id(unique_id: str):
"""
Get user by unique_id (query parameter)
- **unique_id**: Browser-generated unique identifier
Returns user data
"""
try:
user = user_service.get_user_by_unique_id(unique_id)
if not user:
raise HTTPException(status_code=404, detail="User not found")
return UserResponse(**user)
except HTTPException:
raise
except Exception as e:
logger.error(f"Error getting user: {str(e)}")
raise HTTPException(status_code=500, detail=f"Failed to get user: {str(e)}")
@router.patch("/me/name", response_model=UserResponse, tags=["Users"])
async def update_user_name(
request: UserUpdateNameRequest,
x_user_id: Optional[str] = Header(None, alias="X-User-ID")
):
"""
Update user's display name
- **X-User-ID**: User UUID (sent in request header)
- **name**: New display name
Returns updated user data
"""
if not x_user_id:
raise HTTPException(status_code=400, detail="X-User-ID header is required")
try:
user = user_service.update_user_name(
user_id=x_user_id,
name=request.name
)
logger.info(f"Updated user name: {x_user_id}")
return UserResponse(**user)
except ValueError as e:
logger.error(f"Validation error: {str(e)}")
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
logger.error(f"Update error: {str(e)}")
raise HTTPException(status_code=500, detail=f"Update failed: {str(e)}")
|