"""User management router (admin only).""" import uuid from fastapi import APIRouter, Depends, status from sqlalchemy.orm import Session from app.database import get_db from app.dependencies.auth import require_role from app.domain.unit_of_work import UnitOfWork from app.models.user import User from app.schemas.user import UserCreate, UserUpdate, UserOut from app.services.audit_service import log_action from app.services.user_service import ( create_user, get_user_or_raise, list_users, update_user, ) router = APIRouter(prefix="/users", tags=["users"]) # --------------------------------------------------------------------------- # GET /users — list all users # --------------------------------------------------------------------------- @router.get("", response_model=list[UserOut]) def list_users_route( db: Session = Depends(get_db), current_user: User = Depends(require_role("admin")), ): """Return a list of all users. **Requires admin role.**""" return list_users(db) # --------------------------------------------------------------------------- # POST /users — create a new user # --------------------------------------------------------------------------- @router.post("", response_model=UserOut, status_code=status.HTTP_201_CREATED) def create_user_route( payload: UserCreate, db: Session = Depends(get_db), current_user: User = Depends(require_role("admin")), ): """Create a new user. **Requires admin role.**""" with UnitOfWork(db) as uow: user = create_user( db, username=payload.username, email=payload.email, password=payload.password, role=payload.role, ) log_action( db, user_id=current_user.id, action="create_user", entity_type="user", entity_id=user.id, details={"username": user.username, "role": user.role}, ) uow.commit() db.refresh(user) return user # --------------------------------------------------------------------------- # GET /users/{id} — get a single user # --------------------------------------------------------------------------- @router.get("/{user_id}", response_model=UserOut) def get_user( user_id: uuid.UUID, db: Session = Depends(get_db), current_user: User = Depends(require_role("admin")), ): """Return a single user by ID. **Requires admin role.**""" return get_user_or_raise(db, user_id) # --------------------------------------------------------------------------- # PATCH /users/{id} — update a user # --------------------------------------------------------------------------- @router.patch("/{user_id}", response_model=UserOut) def update_user_route( user_id: uuid.UUID, payload: UserUpdate, db: Session = Depends(get_db), current_user: User = Depends(require_role("admin")), ): """Update one or more fields of an existing user. **Requires admin role.**""" update_data = payload.model_dump(exclude_unset=True) with UnitOfWork(db) as uow: user = update_user(db, user_id, **update_data) log_action( db, user_id=current_user.id, action="update_user", entity_type="user", entity_id=user.id, details={"updated_fields": list(update_data.keys())}, ) uow.commit() db.refresh(user) return user