136 lines
4.2 KiB
Python
136 lines
4.2 KiB
Python
"""
|
|
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
|