363 lines
10 KiB
Python
363 lines
10 KiB
Python
# Removed __future__ annotations to fix OpenAPI schema generation
|
|
|
|
from fastapi import APIRouter, Depends, Request, Query
|
|
from sqlalchemy.orm import Session
|
|
|
|
from adapters.db.session import get_db
|
|
from adapters.db.repositories.user_repo import UserRepository
|
|
from adapters.api.v1.schemas import QueryInfo, SuccessResponse, UsersListResponse, UsersSummaryResponse, UserResponse
|
|
from app.core.responses import success_response, format_datetime_fields
|
|
from app.core.auth_dependency import get_current_user, AuthContext
|
|
from app.core.permissions import require_user_management
|
|
|
|
|
|
router = APIRouter(prefix="/users", tags=["users"])
|
|
|
|
|
|
@router.post("/search",
|
|
summary="لیست کاربران با فیلتر پیشرفته",
|
|
description="دریافت لیست کاربران با قابلیت فیلتر، جستجو، مرتبسازی و صفحهبندی. نیاز به مجوز usermanager در سطح اپلیکیشن دارد.",
|
|
response_model=SuccessResponse,
|
|
responses={
|
|
200: {
|
|
"description": "لیست کاربران با موفقیت دریافت شد",
|
|
"content": {
|
|
"application/json": {
|
|
"example": {
|
|
"success": True,
|
|
"message": "لیست کاربران دریافت شد",
|
|
"data": {
|
|
"items": [
|
|
{
|
|
"id": 1,
|
|
"email": "user@example.com",
|
|
"mobile": "09123456789",
|
|
"first_name": "احمد",
|
|
"last_name": "احمدی",
|
|
"is_active": True,
|
|
"referral_code": "ABC123",
|
|
"created_at": "2024-01-01T00:00:00Z"
|
|
}
|
|
],
|
|
"pagination": {
|
|
"total": 1,
|
|
"page": 1,
|
|
"per_page": 10,
|
|
"total_pages": 1,
|
|
"has_next": False,
|
|
"has_prev": False
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
401: {
|
|
"description": "کاربر احراز هویت نشده است"
|
|
},
|
|
403: {
|
|
"description": "دسترسی غیرمجاز - نیاز به مجوز usermanager",
|
|
"content": {
|
|
"application/json": {
|
|
"example": {
|
|
"success": False,
|
|
"message": "Missing app permission: user_management",
|
|
"error_code": "FORBIDDEN"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
)
|
|
@require_user_management()
|
|
def list_users(
|
|
request: Request,
|
|
query_info: QueryInfo,
|
|
ctx: AuthContext = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""
|
|
دریافت لیست کاربران با قابلیت فیلتر، جستجو، مرتبسازی و صفحهبندی
|
|
|
|
پارامترهای QueryInfo:
|
|
- sort_by: فیلد مرتبسازی (مثال: created_at, first_name)
|
|
- sort_desc: ترتیب نزولی (true/false)
|
|
- take: تعداد رکورد در هر صفحه (پیشفرض: 10)
|
|
- skip: تعداد رکورد صرفنظر شده (پیشفرض: 0)
|
|
- search: عبارت جستجو
|
|
- search_fields: فیلدهای جستجو (مثال: ["first_name", "last_name", "email"])
|
|
- filters: آرایه فیلترها با ساختار:
|
|
[
|
|
{
|
|
"property": "is_active",
|
|
"operator": "=",
|
|
"value": true
|
|
},
|
|
{
|
|
"property": "first_name",
|
|
"operator": "*",
|
|
"value": "احمد"
|
|
}
|
|
]
|
|
|
|
عملگرهای پشتیبانی شده:
|
|
- = : برابر
|
|
- > : بزرگتر از
|
|
- >= : بزرگتر یا مساوی
|
|
- < : کوچکتر از
|
|
- <= : کوچکتر یا مساوی
|
|
- != : نامساوی
|
|
- * : شامل (contains)
|
|
- ?* : خاتمه یابد (ends with)
|
|
- *? : شروع شود (starts with)
|
|
- in : در بین مقادیر آرایه
|
|
"""
|
|
repo = UserRepository(db)
|
|
users, total = repo.query_with_filters(query_info)
|
|
|
|
# تبدیل User objects به dictionary
|
|
user_dicts = [repo.to_dict(user) for user in users]
|
|
|
|
# فرمت کردن تاریخها
|
|
formatted_users = [format_datetime_fields(user_dict, request) for user_dict in user_dicts]
|
|
|
|
# محاسبه اطلاعات صفحهبندی
|
|
page = (query_info.skip // query_info.take) + 1
|
|
total_pages = (total + query_info.take - 1) // query_info.take
|
|
|
|
response_data = {
|
|
"items": formatted_users,
|
|
"pagination": {
|
|
"total": total,
|
|
"page": page,
|
|
"per_page": query_info.take,
|
|
"total_pages": total_pages,
|
|
"has_next": page < total_pages,
|
|
"has_prev": page > 1
|
|
},
|
|
"query_info": {
|
|
"sort_by": query_info.sort_by,
|
|
"sort_desc": query_info.sort_desc,
|
|
"search": query_info.search,
|
|
"search_fields": query_info.search_fields,
|
|
"filters": [{"property": f.property, "operator": f.operator, "value": f.value} for f in (query_info.filters or [])]
|
|
}
|
|
}
|
|
|
|
return success_response(response_data, request)
|
|
|
|
|
|
@router.get("",
|
|
summary="لیست ساده کاربران",
|
|
description="دریافت لیست ساده کاربران. نیاز به مجوز usermanager در سطح اپلیکیشن دارد.",
|
|
response_model=SuccessResponse,
|
|
responses={
|
|
200: {
|
|
"description": "لیست کاربران با موفقیت دریافت شد",
|
|
"content": {
|
|
"application/json": {
|
|
"example": {
|
|
"success": True,
|
|
"message": "لیست کاربران دریافت شد",
|
|
"data": [
|
|
{
|
|
"id": 1,
|
|
"email": "user@example.com",
|
|
"mobile": "09123456789",
|
|
"first_name": "احمد",
|
|
"last_name": "احمدی",
|
|
"is_active": True,
|
|
"referral_code": "ABC123",
|
|
"created_at": "2024-01-01T00:00:00Z"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
401: {
|
|
"description": "کاربر احراز هویت نشده است"
|
|
},
|
|
403: {
|
|
"description": "دسترسی غیرمجاز - نیاز به مجوز usermanager",
|
|
"content": {
|
|
"application/json": {
|
|
"example": {
|
|
"success": False,
|
|
"message": "Missing app permission: user_management",
|
|
"error_code": "FORBIDDEN"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
)
|
|
@require_user_management()
|
|
def list_users_simple(
|
|
ctx: AuthContext = Depends(get_current_user),
|
|
db: Session = Depends(get_db),
|
|
limit: int = Query(10, ge=1, le=100, description="تعداد رکورد در هر صفحه"),
|
|
offset: int = Query(0, ge=0, description="تعداد رکورد صرفنظر شده")
|
|
):
|
|
"""دریافت لیست ساده کاربران"""
|
|
repo = UserRepository(db)
|
|
|
|
# Create basic query info
|
|
query_info = QueryInfo(take=limit, skip=offset)
|
|
users, total = repo.query_with_filters(query_info)
|
|
|
|
# تبدیل User objects به dictionary
|
|
user_dicts = [repo.to_dict(user) for user in users]
|
|
|
|
# فرمت کردن تاریخها
|
|
formatted_users = [format_datetime_fields(user_dict, None) for user_dict in user_dicts]
|
|
|
|
return success_response(formatted_users, None)
|
|
|
|
|
|
@router.get("/{user_id}",
|
|
summary="دریافت اطلاعات یک کاربر",
|
|
description="دریافت اطلاعات کامل یک کاربر بر اساس شناسه. نیاز به مجوز usermanager در سطح اپلیکیشن دارد.",
|
|
response_model=SuccessResponse,
|
|
responses={
|
|
200: {
|
|
"description": "اطلاعات کاربر با موفقیت دریافت شد",
|
|
"content": {
|
|
"application/json": {
|
|
"example": {
|
|
"success": True,
|
|
"message": "اطلاعات کاربر دریافت شد",
|
|
"data": {
|
|
"id": 1,
|
|
"email": "user@example.com",
|
|
"mobile": "09123456789",
|
|
"first_name": "احمد",
|
|
"last_name": "احمدی",
|
|
"is_active": True,
|
|
"referral_code": "ABC123",
|
|
"created_at": "2024-01-01T00:00:00Z"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
401: {
|
|
"description": "کاربر احراز هویت نشده است"
|
|
},
|
|
403: {
|
|
"description": "دسترسی غیرمجاز - نیاز به مجوز usermanager",
|
|
"content": {
|
|
"application/json": {
|
|
"example": {
|
|
"success": False,
|
|
"message": "Missing app permission: user_management",
|
|
"error_code": "FORBIDDEN"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
404: {
|
|
"description": "کاربر یافت نشد",
|
|
"content": {
|
|
"application/json": {
|
|
"example": {
|
|
"success": False,
|
|
"message": "کاربر یافت نشد",
|
|
"error_code": "USER_NOT_FOUND"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
)
|
|
@require_user_management()
|
|
def get_user(
|
|
user_id: int,
|
|
request: Request,
|
|
ctx: AuthContext = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""دریافت اطلاعات یک کاربر بر اساس ID"""
|
|
repo = UserRepository(db)
|
|
user = repo.get_by_id(user_id)
|
|
|
|
if not user:
|
|
from fastapi import HTTPException
|
|
raise HTTPException(status_code=404, detail="کاربر یافت نشد")
|
|
|
|
user_dict = repo.to_dict(user)
|
|
formatted_user = format_datetime_fields(user_dict, request)
|
|
|
|
return success_response(formatted_user, request)
|
|
|
|
|
|
@router.get("/stats/summary",
|
|
summary="آمار کلی کاربران",
|
|
description="دریافت آمار کلی کاربران شامل تعداد کل، فعال و غیرفعال. نیاز به مجوز usermanager در سطح اپلیکیشن دارد.",
|
|
response_model=SuccessResponse,
|
|
responses={
|
|
200: {
|
|
"description": "آمار کاربران با موفقیت دریافت شد",
|
|
"content": {
|
|
"application/json": {
|
|
"example": {
|
|
"success": True,
|
|
"message": "آمار کاربران دریافت شد",
|
|
"data": {
|
|
"total_users": 100,
|
|
"active_users": 85,
|
|
"inactive_users": 15,
|
|
"active_percentage": 85.0
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
401: {
|
|
"description": "کاربر احراز هویت نشده است"
|
|
},
|
|
403: {
|
|
"description": "دسترسی غیرمجاز - نیاز به مجوز usermanager",
|
|
"content": {
|
|
"application/json": {
|
|
"example": {
|
|
"success": False,
|
|
"message": "Missing app permission: user_management",
|
|
"error_code": "FORBIDDEN"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
)
|
|
@require_user_management()
|
|
def get_users_summary(
|
|
request: Request,
|
|
ctx: AuthContext = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""دریافت آمار کلی کاربران"""
|
|
repo = UserRepository(db)
|
|
|
|
# تعداد کل کاربران
|
|
total_users = repo.count_all()
|
|
|
|
# تعداد کاربران فعال
|
|
active_users = repo.query_with_filters(QueryInfo(
|
|
filters=[{"property": "is_active", "operator": "=", "value": True}]
|
|
))[1]
|
|
|
|
# تعداد کاربران غیرفعال
|
|
inactive_users = total_users - active_users
|
|
|
|
response_data = {
|
|
"total_users": total_users,
|
|
"active_users": active_users,
|
|
"inactive_users": inactive_users,
|
|
"active_percentage": round((active_users / total_users * 100), 2) if total_users > 0 else 0
|
|
}
|
|
|
|
return success_response(response_data, request)
|
|
|
|
|