Files
erp-nutzfahrzeuge/backend/app/routers/users.py
T

108 lines
3.4 KiB
Python
Raw Normal View History

"""Users router: admin-only user management (list, create, update, deactivate)."""
import uuid
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from app.database import get_db
from app.dependencies import get_pagination, require_role
from app.models.user import User
from app.schemas.user import (
UserCreate,
UserListResponse,
UserResponse,
UserUpdate,
)
from app.services.auth_service import (
create_user as svc_create_user,
deactivate_user as svc_deactivate_user,
list_users as svc_list_users,
update_user as svc_update_user,
)
router = APIRouter(prefix="/users", tags=["users"])
@router.get("/", response_model=UserListResponse, status_code=status.HTTP_200_OK)
async def list_users(
db: AsyncSession = Depends(get_db),
pagination: dict = Depends(get_pagination),
admin: User = Depends(require_role(["admin"])),
):
"""List all users with pagination. Admin only."""
users, total = await svc_list_users(
db, page=pagination["page"], page_size=pagination["page_size"]
)
return UserListResponse(
items=[UserResponse.model_validate(u) for u in users],
total=total,
page=pagination["page"],
page_size=pagination["page_size"],
)
@router.post("/", response_model=UserResponse, status_code=status.HTTP_201_CREATED)
async def create_user(
body: UserCreate,
db: AsyncSession = Depends(get_db),
admin: User = Depends(require_role(["admin"])),
):
"""Create a new user. Admin only."""
try:
user = await svc_create_user(
db,
email=body.email,
password=body.password,
full_name=body.full_name,
role=body.role,
language=body.language,
)
except ValueError as exc:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail={"error": {"code": "DUPLICATE_EMAIL", "message": str(exc)}},
)
return UserResponse.model_validate(user)
@router.put("/{user_id}", response_model=UserResponse, status_code=status.HTTP_200_OK)
async def update_user(
user_id: uuid.UUID,
body: UserUpdate,
db: AsyncSession = Depends(get_db),
admin: User = Depends(require_role(["admin"])),
):
"""Update a user's fields. Admin only."""
updates = body.model_dump(exclude_unset=True)
if not updates:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail={"error": {"code": "NO_FIELDS", "message": "No fields to update"}},
)
user = await svc_update_user(db, user_id, **updates)
if user is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail={"error": {"code": "USER_NOT_FOUND", "message": "User not found"}},
)
return UserResponse.model_validate(user)
@router.delete(
"/{user_id}", response_model=UserResponse, status_code=status.HTTP_200_OK
)
async def delete_user(
user_id: uuid.UUID,
db: AsyncSession = Depends(get_db),
admin: User = Depends(require_role(["admin"])),
):
"""Deactivate a user (soft delete). Admin only."""
user = await svc_deactivate_user(db, user_id)
if user is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail={"error": {"code": "USER_NOT_FOUND", "message": "User not found"}},
)
return UserResponse.model_validate(user)