hesabixArc/hesabixAPI/build/lib/adapters/api/v1/users.py
2025-10-02 03:21:43 +03:30

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)