Files
invoice-master-poc-v2/packages/backend/backend/web/api/v1/admin/dashboard.py
Yaojia Wang b602d0a340 re-structure
2026-02-01 22:55:31 +01:00

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