import uuid from typing import Optional from fastapi import APIRouter, Depends, HTTPException, Query from pydantic import BaseModel from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from app.database import get_db from app.middleware.auth import get_current_user, require_director from app.models.user import User from app.schemas.customer import UserOut router = APIRouter(prefix="/users", tags=["Users"]) class UpdateUserRoleRequest(BaseModel): role: str # manager / director / leader department: str = "" @router.get("/", response_model=list[UserOut]) async def list_users( role: Optional[str] = Query(None), current_user: dict = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): """List all users. Used for companion selection, assignment, etc.""" query = select(User) if role: query = query.where(User.role == role) query = query.order_by(User.name) result = await db.execute(query) return result.scalars().all() @router.get("/me") async def get_current_user_info( current_user: dict = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): """Get current user's full profile.""" result = await db.execute(select(User).where(User.id == uuid.UUID(current_user["user_id"]))) user = result.scalar_one_or_none() if not user: raise HTTPException(status_code=404, detail="User not found") return { "id": str(user.id), "casdoor_id": user.casdoor_id, "name": user.name, "role": user.role, "department": user.department, "wecom_userid": user.wecom_userid, } @router.put("/{user_id}/role") async def update_user_role( user_id: str, data: UpdateUserRoleRequest, current_user: dict = Depends(require_director), db: AsyncSession = Depends(get_db), ): """Director updates a user's role. Only director can do this.""" if data.role not in ("manager", "director", "leader"): raise HTTPException(status_code=400, detail="Invalid role. Must be manager/director/leader") result = await db.execute(select(User).where(User.id == uuid.UUID(user_id))) user = result.scalar_one_or_none() if not user: raise HTTPException(status_code=404, detail="User not found") user.role = data.role if data.department: user.department = data.department await db.commit() await db.refresh(user) return { "id": str(user.id), "name": user.name, "role": user.role, "department": user.department, }