""" Dashboard API Routes FastAPI endpoints for dashboard statistics and activity. """ import logging from typing import Annotated from fastapi import APIRouter, Depends, Query from backend.web.core.auth import ( AdminTokenDep, get_model_version_repository, get_training_task_repository, ModelVersionRepoDep, TrainingTaskRepoDep, ) from backend.web.schemas.admin import ( DashboardStatsResponse, DashboardActiveModelResponse, ActiveModelInfo, RunningTrainingInfo, RecentActivityResponse, ActivityItem, ) from backend.web.services.dashboard_service import ( DashboardStatsService, DashboardActivityService, ) logger = logging.getLogger(__name__) def create_dashboard_router() -> APIRouter: """Create dashboard API router.""" router = APIRouter(prefix="/admin/dashboard", tags=["Dashboard"]) @router.get( "/stats", response_model=DashboardStatsResponse, summary="Get dashboard statistics", description="Returns document counts and annotation completeness metrics.", ) async def get_dashboard_stats( admin_token: AdminTokenDep, ) -> DashboardStatsResponse: """Get dashboard statistics.""" service = DashboardStatsService() stats = service.get_stats() return DashboardStatsResponse( total_documents=stats["total_documents"], annotation_complete=stats["annotation_complete"], annotation_incomplete=stats["annotation_incomplete"], pending=stats["pending"], completeness_rate=stats["completeness_rate"], ) @router.get( "/active-model", response_model=DashboardActiveModelResponse, summary="Get active model info", description="Returns current active model and running training status.", ) async def get_active_model( admin_token: AdminTokenDep, model_repo: ModelVersionRepoDep, task_repo: TrainingTaskRepoDep, ) -> DashboardActiveModelResponse: """Get active model and training status.""" # Get active model active_model = model_repo.get_active() model_info = None if active_model: model_info = ActiveModelInfo( version_id=str(active_model.version_id), version=active_model.version, name=active_model.name, metrics_mAP=active_model.metrics_mAP, metrics_precision=active_model.metrics_precision, metrics_recall=active_model.metrics_recall, document_count=active_model.document_count, activated_at=active_model.activated_at, ) # Get running training task running_task = task_repo.get_running() training_info = None if running_task: training_info = RunningTrainingInfo( task_id=str(running_task.task_id), name=running_task.name, status=running_task.status, started_at=running_task.started_at, progress=running_task.progress or 0, ) return DashboardActiveModelResponse( model=model_info, running_training=training_info, ) @router.get( "/activity", response_model=RecentActivityResponse, summary="Get recent activity", description="Returns recent system activities sorted by timestamp.", ) async def get_recent_activity( admin_token: AdminTokenDep, limit: Annotated[ int, Query(ge=1, le=50, description="Maximum number of activities"), ] = 10, ) -> RecentActivityResponse: """Get recent system activity.""" service = DashboardActivityService() activities = service.get_recent_activities(limit=limit) return RecentActivityResponse( activities=[ ActivityItem( type=act["type"], description=act["description"], timestamp=act["timestamp"], metadata=act["metadata"], ) for act in activities ] ) return router