- New backend/api/admin/overview.py: aggregate stats (user_count, total_storage_bytes, doc_status) + last 10 audit entries in one payload - Sub-router carries NO prefix (parent __init__.py carries /api/admin) - Reuses _build_filtered_query_with_handles + _audit_to_dict_with_handles from api.audit — no new serializer or query logic - Registered overview_router on admin parent router in __init__.py - All 8 ADMIN-11 tests pass; existing admin and audit suites stay green
53 lines
1.5 KiB
Python
53 lines
1.5 KiB
Python
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter, Depends
|
|
from sqlalchemy import func, select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from db.models import AuditLog, Document, Quota, User
|
|
from deps.auth import get_current_admin
|
|
from deps.db import get_db
|
|
from api.audit import _build_filtered_query_with_handles
|
|
from api.audit import _audit_to_dict_with_handles
|
|
|
|
router = APIRouter() # NO prefix — parent __init__.py carries /api/admin (D-02)
|
|
|
|
|
|
@router.get("/overview")
|
|
async def get_overview(
|
|
session: AsyncSession = Depends(get_db),
|
|
_admin: User = Depends(get_current_admin),
|
|
) -> dict:
|
|
user_count = await session.scalar(
|
|
select(func.count(User.id)).where(User.role == "user")
|
|
) or 0
|
|
|
|
total_storage_bytes = await session.scalar(
|
|
select(func.sum(Quota.used_bytes))
|
|
) or 0
|
|
|
|
status_rows = (
|
|
await session.execute(
|
|
select(Document.status, func.count(Document.id)).group_by(Document.status)
|
|
)
|
|
).all()
|
|
doc_status = {row[0]: row[1] for row in status_rows}
|
|
|
|
audit_q = (
|
|
_build_filtered_query_with_handles(None, None, None, None)
|
|
.order_by(AuditLog.created_at.desc())
|
|
.limit(10)
|
|
)
|
|
audit_rows = (await session.execute(audit_q)).all()
|
|
recent_audit = [
|
|
_audit_to_dict_with_handles(row[0], row[1], row[2], row[3])
|
|
for row in audit_rows
|
|
]
|
|
|
|
return {
|
|
"user_count": user_count,
|
|
"total_storage_bytes": total_storage_bytes,
|
|
"doc_status": doc_status,
|
|
"recent_audit": recent_audit,
|
|
}
|