61 lines
2.1 KiB
Python
61 lines
2.1 KiB
Python
"""Users — profile + role assignment (v2.6, Casdoor-backed).
|
|
|
|
GET /users/me — the caller's profile: role, PM's project, display name.
|
|
PATCH /users/{id} — assign role (admin only).
|
|
"""
|
|
from fastapi import APIRouter, Depends
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.auth import UserContext, get_current_user, require_role
|
|
from app.db.engine import get_db
|
|
from app.models.procurement import Project, User
|
|
from app.schemas.procurement import UserRoleUpdate
|
|
from app.utils.errors import NotFoundError
|
|
from app.utils.serialization import to_iso
|
|
|
|
router = APIRouter(prefix="/users", tags=["users"])
|
|
|
|
USER_ROLE_LABELS = {
|
|
"pm": "مدیر پروژه",
|
|
"procurement_manager": "مدیر تدارکات",
|
|
"admin": "ادمین",
|
|
}
|
|
|
|
|
|
def user_to_dict(user: User, project: Project | None = None) -> dict:
|
|
return {
|
|
"id": str(user.id),
|
|
"casdoor_id": user.casdoor_id,
|
|
"first_name": user.first_name,
|
|
"last_name": user.last_name,
|
|
"phone": user.phone,
|
|
"role": user.role,
|
|
"role_label": USER_ROLE_LABELS.get(user.role) if user.role else None,
|
|
"project_id": str(project.id) if project else None,
|
|
"project_name": project.name if project else None,
|
|
"created_at": to_iso(user.created_at),
|
|
}
|
|
|
|
|
|
@router.get("/me")
|
|
async def me(ctx: UserContext = Depends(get_current_user), db: AsyncSession = Depends(get_db)):
|
|
project = await db.scalar(select(Project).where(Project.pm_user_id == ctx.user.id)) if ctx.role == "pm" else None
|
|
return {"data": user_to_dict(ctx.user, project)}
|
|
|
|
|
|
@router.patch("/{user_id}")
|
|
async def update_user_role(
|
|
user_id,
|
|
payload: UserRoleUpdate,
|
|
_: UserContext = Depends(require_role("admin")),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
user = await db.get(User, user_id)
|
|
if user is None:
|
|
raise NotFoundError("کاربر یافت نشد")
|
|
user.role = payload.role
|
|
await db.flush()
|
|
project = await db.scalar(select(Project).where(Project.pm_user_id == user.id)) if user.role == "pm" else None
|
|
return {"data": user_to_dict(user, project)}
|