feat: 관리자 대시보드 — 토큰·비용·응답시간 집계 API + 앱 /admin 페이지
- backend apps/stats: GET /api/v1/admin/stats?from&to → totals / byUser / byDay. ChatMessage(assistant) 집계만, is_superuser 아니면 403. 테스트 3개 - frontend features/admin: 요약 카드 4개(요청·토큰·비용·평균 응답), 일별 토큰 막대(div), 사용자별 표, 기간 프리셋(오늘/7/30/90일). 헤더에 ADMIN 만 아이콘. 테스트 2개 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
aa37cef13d
commit
d4a5f20787
@@ -12,6 +12,7 @@ const SessionListPage = lazy(() => import("@/features/snap/pages/SessionListPage
|
||||
const NewChatPage = lazy(() => import("@/features/snap/pages/NewChatPage"))
|
||||
const SessionChatPage = lazy(() => import("@/features/snap/pages/SessionChatPage"))
|
||||
const SnippetPalettePage = lazy(() => import("@/features/snippets/pages/SnippetPalettePage"))
|
||||
const AdminStatsPage = lazy(() => import("@/features/admin/pages/AdminStatsPage"))
|
||||
|
||||
const fallback = <CenterSpinner />
|
||||
|
||||
@@ -35,6 +36,7 @@ export const routes: RouteObject[] = [
|
||||
{ path: PATHS.SNAP.slice(1), element: wrap(<SessionListPage />) },
|
||||
{ path: PATHS.SNAP_NEW.slice(1), element: wrap(<NewChatPage />) },
|
||||
{ path: PATHS.SNAP_SESSION.slice(1), element: wrap(<SessionChatPage />) },
|
||||
{ path: PATHS.ADMIN.slice(1), element: wrap(<AdminStatsPage />) },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user