diff --git a/backend/src/backend/platform.py b/backend/src/backend/platform.py index 6c00d1d..a4937f7 100644 --- a/backend/src/backend/platform.py +++ b/backend/src/backend/platform.py @@ -25,6 +25,10 @@ Workspace membership CRUD:: PATCH /workspaces/{workspace_id}/members/{user_id} — update role/status DELETE /workspaces/{workspace_id}/members/{user_id} — remove a member +Platform employee roster:: + + GET /employees — list all non-deleted users + Invariants ---------- @@ -200,6 +204,22 @@ def member_payload( } +def platform_employee_payload( + user: Users, + role: Roles | None, +) -> dict[str, Any]: + return { + "user_id": user.user_id, + "username": user.username, + "display_name": user.display_name, + "email": user.email, + "status": user.status, + "role_code": role.role_code if role is not None else None, + "role_name": role.role_name if role is not None else None, + "created_at": user.created_at.isoformat(), + } + + # --------------------------------------------------------------------------- # Internal helpers # --------------------------------------------------------------------------- @@ -256,6 +276,32 @@ def _envelope(request_id: str, data: Any, meta: dict[str, Any] | None = None) -> } +# --------------------------------------------------------------------------- +# Platform employee roster +# --------------------------------------------------------------------------- + + +@router.get("/employees") +async def list_platform_employees( + context: SystemAdminContext = Depends(system_admin_context), + session: AsyncSession = Depends(database_session), +) -> dict[str, Any]: + """List every non-soft-deleted platform user.""" + rows = ( + await session.execute( + select(Users, Roles) + .outerjoin(Roles, Roles.role_id == Users.platform_role_id) + .where(Users.is_deleted == 0) + .order_by(Users.created_at, Users.user_id) + ) + ).all() + return _envelope( + context.request_id, + [platform_employee_payload(user, role) for user, role in rows], + {"count": len(rows)}, + ) + + # --------------------------------------------------------------------------- # Workspace CRUD # ---------------------------------------------------------------------------