admin_users_personels

This commit is contained in:
Roo
2026-06-29 14:11:15 +00:00
parent 383e5511b6
commit df4a0f07ff
237 changed files with 17849 additions and 2934 deletions

View File

@@ -497,6 +497,7 @@ async def list_users(
role: Optional[str] = Query(None, description="Szerepkör szűrés (pl. admin, user)"),
is_active: Optional[bool] = Query(None, description="Aktív státusz szűrés"),
is_deleted: Optional[bool] = Query(None, description="Törölt státusz szűrés"),
plan_filter: Optional[str] = Query(None, description="Csomag szűrés (pl. FREE, PREMIUM, ENTERPRISE)"),
db: AsyncSession = Depends(deps.get_db),
current_user: User = Depends(deps.get_current_active_user),
_ = Depends(deps.RequirePermission("user:view")),
@@ -580,8 +581,10 @@ async def list_users(
)
if role:
# Case-insensitive role matching
role_upper = role.upper()
try:
role_enum = UserRole(role)
role_enum = UserRole(role_upper)
query = query.where(User.role == role_enum)
except ValueError:
raise HTTPException(
@@ -592,6 +595,8 @@ async def list_users(
query = query.where(User.is_active == is_active)
if is_deleted is not None:
query = query.where(User.is_deleted == is_deleted)
if plan_filter:
query = query.where(User.subscription_plan == plan_filter.upper())
count_query = select(func.count()).select_from(query.subquery())
total_result = await db.execute(count_query)
@@ -625,6 +630,12 @@ async def list_users(
parts.append(str(address.house_number))
address_str = ', '.join(parts) if parts else None
# Személy nevének összefűzése
person_name = None
if person:
parts = [p for p in [person.last_name, person.first_name] if p]
person_name = ' '.join(parts) if parts else None
user_list.append({
"id": u.id,
"email": u.email,
@@ -637,6 +648,7 @@ async def list_users(
"created_at": u.created_at.isoformat() if u.created_at else None,
"deleted_at": u.deleted_at.isoformat() if u.deleted_at else None,
# Person adatok
"person_name": person_name,
"first_name": person.first_name if person else None,
"last_name": person.last_name if person else None,
"phone": person.phone if person else None,
@@ -656,6 +668,148 @@ async def list_users(
}
@router.get("/users/stats", tags=["User Management"])
async def get_user_stats(
db: AsyncSession = Depends(deps.get_db),
current_user: User = Depends(deps.get_current_active_user),
_ = Depends(deps.RequirePermission("user:view")),
):
"""
Felhasználói statisztikák a Dashboard számára.
Visszaadja az összesítő adatokat: teljes, aktív, törölt, kitiltott felhasználók,
mai/héti/havi új regisztrációk, szerepkör és előfizetés szerinti megoszlás,
nyelvi statisztikák, Person kapcsolatok, szervezeti adatok.
"""
from datetime import date, timedelta
today_start = datetime.now(timezone.utc).replace(hour=0, minute=0, second=0, microsecond=0)
week_start = today_start - timedelta(days=today_start.weekday())
month_start = today_start.replace(day=1)
# === ALAP STATISZTIKÁK ===
total_result = await db.execute(select(func.count(User.id)))
total_users = total_result.scalar() or 0
active_result = await db.execute(
select(func.count(User.id)).where(User.is_active == True, User.is_deleted == False)
)
active_users = active_result.scalar() or 0
deleted_result = await db.execute(
select(func.count(User.id)).where(User.is_deleted == True)
)
deleted_users = deleted_result.scalar() or 0
# Banned = is_active=False AND is_deleted=False (deactivated but not deleted)
banned_result = await db.execute(
select(func.count(User.id)).where(User.is_active == False, User.is_deleted == False)
)
banned_users = banned_result.scalar() or 0
# === ÚJ REGISZTRÁCIÓK ===
new_today_result = await db.execute(
select(func.count(User.id)).where(User.created_at >= today_start)
)
new_users_today = new_today_result.scalar() or 0
new_week_result = await db.execute(
select(func.count(User.id)).where(User.created_at >= week_start)
)
new_users_this_week = new_week_result.scalar() or 0
new_month_result = await db.execute(
select(func.count(User.id)).where(User.created_at >= month_start)
)
new_users_this_month = new_month_result.scalar() or 0
# === SZEREPKÖR SZERINTI MEGOSZLÁS ===
role_result = await db.execute(
select(User.role, func.count(User.id)).group_by(User.role)
)
users_by_role = {}
for row in role_result:
role_key = row[0].value if hasattr(row[0], "value") else str(row[0])
users_by_role[role_key] = row[1]
# === ELŐFIZETÉS SZERINTI MEGOSZLÁS ===
plan_result = await db.execute(
select(User.subscription_plan, func.count(User.id)).group_by(User.subscription_plan)
)
users_by_plan = {row[0]: row[1] for row in plan_result}
# === NYELV SZERINTI MEGOSZLÁS ===
lang_result = await db.execute(
select(User.preferred_language, func.count(User.id)).group_by(User.preferred_language)
)
users_by_language = {row[0]: row[1] for row in lang_result}
# === PERSON KAPCSOLATOK ===
with_person_result = await db.execute(
select(func.count(User.id)).where(User.person_id.isnot(None))
)
users_with_person = with_person_result.scalar() or 0
users_without_person = total_users - users_with_person
# === SZERVEZETI STATISZTIKÁK ===
from app.models.marketplace.organization import Organization, OrganizationMember
org_count_result = await db.execute(
select(func.count(Organization.id)).where(Organization.is_deleted == False)
)
active_organizations_count = org_count_result.scalar() or 0
memberships_result = await db.execute(
select(func.count(OrganizationMember.id))
)
total_memberships = memberships_result.scalar() or 0
# === JÁRMŰ STATISZTIKÁK ===
from app.models.vehicle.asset import Asset
vehicle_count_result = await db.execute(
select(func.count(Asset.id))
)
total_vehicles = vehicle_count_result.scalar() or 0
# === REGISZTRÁCIÓS TREND (utolsó 30 nap) ===
thirty_days_ago = today_start - timedelta(days=30)
trend_result = await db.execute(
text("""
SELECT DATE(created_at) as reg_date, COUNT(*) as cnt
FROM identity.users
WHERE created_at >= :start_date
GROUP BY DATE(created_at)
ORDER BY reg_date
"""),
{"start_date": thirty_days_ago}
)
registration_trend = [
{"date": row[0].isoformat() if hasattr(row[0], 'isoformat') else str(row[0]), "count": row[1]}
for row in trend_result
]
return {
"total_users": total_users,
"active_users": active_users,
"deleted_users": deleted_users,
"banned_users": banned_users,
"new_users_today": new_users_today,
"new_users_this_week": new_users_this_week,
"new_users_this_month": new_users_this_month,
"users_by_role": users_by_role,
"users_by_plan": users_by_plan,
"users_by_language": users_by_language,
"users_with_person": users_with_person,
"users_without_person": users_without_person,
"total_vehicles": total_vehicles,
"active_organizations_count": active_organizations_count,
"total_memberships": total_memberships,
"registration_trend": registration_trend,
}
@router.post("/users/bulk-action", tags=["User Management"])
async def bulk_user_action(
request: BulkActionRequest,
@@ -732,11 +886,11 @@ async def bulk_user_action(
affected_count += 1
audit_log = SecurityAuditLog(
user_id=current_user.id,
actor_id=current_user.id,
action=f"bulk_{request.action}",
details=f"Bulk action '{request.action}' on {affected_count} users. IDs: {request.user_ids}",
payload_before={},
payload_after={"details": f"Bulk action '{request.action}' on {affected_count} users. IDs: {request.user_ids}"},
is_critical=(request.action in ("hard_delete", "ban")),
ip_address="admin_api"
)
db.add(audit_log)