feat(mvp): complete M13 clean-up milestone (real usernames, avatar studio redesign, pause menu, audio manager)
checkpoint / checkpoint (push) Successful in 6m22s
checkpoint / checkpoint (push) Successful in 6m22s
This commit is contained in:
@@ -25,6 +25,13 @@ class UserResponse(BaseModel):
|
||||
model_config = {"from_attributes": True}
|
||||
|
||||
|
||||
class UserSummary(BaseModel):
|
||||
id: int
|
||||
username: str
|
||||
|
||||
model_config = {"from_attributes": True}
|
||||
|
||||
|
||||
class UserUpdate(BaseModel):
|
||||
email: EmailStr | None = None
|
||||
is_active: bool | None = None
|
||||
@@ -40,6 +47,43 @@ async def get_current_user_profile(
|
||||
return current_user
|
||||
|
||||
|
||||
@router.get("/search", response_model=list[UserSummary])
|
||||
async def search_users(
|
||||
current_user: CurrentUser,
|
||||
db: Annotated[AsyncSession, Depends(get_db)],
|
||||
q: str = "",
|
||||
limit: int = 20,
|
||||
):
|
||||
"""Search active users by username substring."""
|
||||
cleaned_q = q.strip()
|
||||
result = await db.execute(
|
||||
select(User)
|
||||
.where(
|
||||
User.is_active == True,
|
||||
User.username.ilike(f"%{cleaned_q}%"),
|
||||
User.id != current_user.id,
|
||||
)
|
||||
.limit(limit)
|
||||
)
|
||||
return list(result.scalars().all())
|
||||
|
||||
|
||||
@router.get("/by-username/{username}", response_model=UserSummary)
|
||||
async def get_user_by_username(
|
||||
username: str,
|
||||
current_user: CurrentUser,
|
||||
db: Annotated[AsyncSession, Depends(get_db)],
|
||||
):
|
||||
"""Get active user by exact username."""
|
||||
result = await db.execute(
|
||||
select(User).where(User.username == username.strip(), User.is_active == True)
|
||||
)
|
||||
user = result.scalar_one_or_none()
|
||||
if not user:
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
return user
|
||||
|
||||
|
||||
@router.get("/{user_id}", response_model=UserResponse)
|
||||
async def get_user(
|
||||
user_id: int,
|
||||
|
||||
Reference in New Issue
Block a user