79 lines
2.4 KiB
Python
79 lines
2.4 KiB
Python
"""User management API: list, detail, update, approve — only owner."""
|
|
from fastapi import APIRouter, Depends, HTTPException, Query, status
|
|
from sqlalchemy import select, func
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.database import get_db
|
|
from app.middleware.auth import require_role
|
|
from app.models.user import User
|
|
from app.schemas.user import UserResponse, UserUpdateRequest
|
|
|
|
router = APIRouter(prefix="/api/v1/users", tags=["users"])
|
|
|
|
|
|
@router.get("", response_model=list[UserResponse])
|
|
async def list_users(
|
|
page: int = Query(1, ge=1),
|
|
page_size: int = Query(20, ge=1, le=100),
|
|
user: User = Depends(require_role("owner")),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
result = await db.execute(
|
|
select(User).offset((page - 1) * page_size).limit(page_size)
|
|
)
|
|
return result.scalars().all()
|
|
|
|
|
|
@router.get("/{user_id}", response_model=UserResponse)
|
|
async def get_user(
|
|
user_id: str,
|
|
user: User = Depends(require_role("owner")),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
result = await db.execute(select(User).where(User.id == user_id))
|
|
target = result.scalar_one_or_none()
|
|
if not target:
|
|
raise HTTPException(status_code=404, detail="User not found")
|
|
return target
|
|
|
|
|
|
@router.patch("/{user_id}", response_model=UserResponse)
|
|
async def update_user(
|
|
user_id: str,
|
|
body: UserUpdateRequest,
|
|
user: User = Depends(require_role("owner")),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
result = await db.execute(select(User).where(User.id == user_id))
|
|
target = result.scalar_one_or_none()
|
|
if not target:
|
|
raise HTTPException(status_code=404, detail="User not found")
|
|
|
|
if body.role is not None:
|
|
target.role = body.role
|
|
if body.is_active is not None:
|
|
target.is_active = body.is_active
|
|
|
|
await db.commit()
|
|
await db.refresh(target)
|
|
return target
|
|
|
|
|
|
@router.post("/{user_id}/approve", response_model=UserResponse)
|
|
async def approve_user(
|
|
user_id: str,
|
|
user: User = Depends(require_role("owner")),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
result = await db.execute(select(User).where(User.id == user_id))
|
|
target = result.scalar_one_or_none()
|
|
if not target:
|
|
raise HTTPException(status_code=404, detail="User not found")
|
|
if target.is_approved:
|
|
raise HTTPException(status_code=400, detail="User already approved")
|
|
|
|
target.is_approved = True
|
|
await db.commit()
|
|
await db.refresh(target)
|
|
return target
|