""" Tool_OCR - Admin Router Administrative endpoints for system management """ import logging from typing import Optional from datetime import datetime from fastapi import APIRouter, Depends, HTTPException, status, Query from sqlalchemy.orm import Session from app.core.deps import get_db, get_current_admin_user from app.models.user import User from app.services.admin_service import admin_service from app.services.audit_service import audit_service logger = logging.getLogger(__name__) router = APIRouter(prefix="/api/v2/admin", tags=["Admin"]) @router.get("/stats", summary="Get system statistics") async def get_system_stats( db: Session = Depends(get_db), admin_user: User = Depends(get_current_admin_user) ): """ Get overall system statistics Requires admin privileges """ try: stats = admin_service.get_system_statistics(db) return stats except Exception as e: logger.exception("Failed to get system stats") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Failed to get system stats: {str(e)}" ) @router.get("/users", summary="List all users") async def list_users( page: int = Query(1, ge=1), page_size: int = Query(50, ge=1, le=100), db: Session = Depends(get_db), admin_user: User = Depends(get_current_admin_user) ): """ Get list of all users with statistics Requires admin privileges """ try: skip = (page - 1) * page_size users, total = admin_service.get_user_list(db, skip=skip, limit=page_size) return { "users": users, "total": total, "page": page, "page_size": page_size, "has_more": (skip + len(users)) < total } except Exception as e: logger.exception("Failed to list users") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Failed to list users: {str(e)}" ) @router.get("/users/top", summary="Get top users") async def get_top_users( metric: str = Query("tasks", regex="^(tasks|completed_tasks)$"), limit: int = Query(10, ge=1, le=50), db: Session = Depends(get_db), admin_user: User = Depends(get_current_admin_user) ): """ Get top users by metric - **metric**: Ranking metric (tasks or completed_tasks) - **limit**: Number of users to return Requires admin privileges """ try: top_users = admin_service.get_top_users(db, metric=metric, limit=limit) return top_users except Exception as e: logger.exception("Failed to get top users") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Failed to get top users: {str(e)}" ) @router.get("/audit-logs", summary="Get audit logs") async def get_audit_logs( user_id: Optional[int] = Query(None), event_category: Optional[str] = Query(None), event_type: Optional[str] = Query(None), date_from: Optional[str] = Query(None), date_to: Optional[str] = Query(None), success_only: Optional[bool] = Query(None), page: int = Query(1, ge=1), page_size: int = Query(100, ge=1, le=500), db: Session = Depends(get_db), admin_user: User = Depends(get_current_admin_user) ): """ Get audit logs with filtering - **user_id**: Filter by user ID (optional) - **event_category**: Filter by category (authentication, task, admin, system) - **event_type**: Filter by event type (optional) - **date_from**: Filter from date (YYYY-MM-DD, optional) - **date_to**: Filter to date (YYYY-MM-DD, optional) - **success_only**: Filter by success status (optional) Requires admin privileges """ try: # Parse dates date_from_dt = datetime.fromisoformat(date_from) if date_from else None date_to_dt = datetime.fromisoformat(date_to) if date_to else None skip = (page - 1) * page_size logs, total = audit_service.get_logs( db=db, user_id=user_id, event_category=event_category, event_type=event_type, date_from=date_from_dt, date_to=date_to_dt, success_only=success_only, skip=skip, limit=page_size ) return { "logs": [log.to_dict() for log in logs], "total": total, "page": page, "page_size": page_size, "has_more": (skip + len(logs)) < total } except Exception as e: logger.exception("Failed to get audit logs") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Failed to get audit logs: {str(e)}" ) @router.get("/audit-logs/user/{user_id}/summary", summary="Get user activity summary") async def get_user_activity_summary( user_id: int, days: int = Query(30, ge=1, le=365), db: Session = Depends(get_db), admin_user: User = Depends(get_current_admin_user) ): """ Get user activity summary for the last N days - **user_id**: User ID - **days**: Number of days to look back (default: 30) Requires admin privileges """ try: summary = audit_service.get_user_activity_summary(db, user_id=user_id, days=days) return summary except Exception as e: logger.exception(f"Failed to get activity summary for user {user_id}") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Failed to get user activity summary: {str(e)}" )