Coverage for src/lexigram/auth/admin/pages/overview.py: 0%
28 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-25 12:26 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-25 12:26 +0800
1"""Auth overview management page — user and session counts."""
3from __future__ import annotations
5from datetime import UTC, datetime
6from typing import Any
8from lexigram.contracts.admin import PageContent
9from lexigram.contracts.admin.widget_content import Stat, StatContent
10from lexigram.contracts.auth.repositories import SessionRepositoryProtocol
11from lexigram.contracts.auth.store import UserStoreProtocol
12from lexigram.logging import get_logger
14logger = get_logger(__name__)
17class AuthOverviewPage:
18 """Admin overview page for authentication stats."""
20 def __init__(
21 self,
22 user_store: UserStoreProtocol | None = None,
23 session_repo: SessionRepositoryProtocol | None = None,
24 ) -> None:
25 self._user_store = user_store
26 self._session_repo = session_repo
28 async def handle(self, request: Any) -> PageContent:
29 user_count: str | int = "N/A"
30 session_count: str | int = "N/A"
32 if self._user_store is not None:
33 try:
34 user_count = await self._user_store.count_users()
35 except Exception:
36 logger.warning("auth_overview.user_count_unavailable")
38 if self._session_repo is not None:
39 try:
40 sessions = await self._session_repo.find_active_by_user(
41 user_id="*",
42 cutoff=datetime.now(UTC),
43 )
44 session_count = len(sessions)
45 except Exception:
46 session_count = "N/A"
48 return PageContent(
49 title="Authentication",
50 body=StatContent(
51 stats=(
52 Stat(label="Total Users", value=str(user_count), icon="users"),
53 Stat(
54 label="Active Sessions",
55 value=str(session_count),
56 icon="activity",
57 ),
58 )
59 ),
60 )