snp-connection-monitoring/frontend/src/App.tsx
HYOJIN c330be5a52 feat(phase5): 대시보드 + 통계 + Service Status 페이지
백엔드:
- DashboardService/Controller (요약, 시간별/서비스별/테넌트별 통계, 에러율, 상위API, 최근로그)
- 헬스체크 1분 간격, 매 체크마다 로그 기록 (status page용)
- ServiceStatusDetail API (90일 일별 uptime, 최근 체크 60건)
- 통계 쿼리 최적화 인덱스 추가
- 테넌트별 요청/사용자 비율 API
- 상위 API에 serviceName + apiName 표시

프론트엔드:
- DashboardPage (요약 카드 4개, 하트비트 바, Recharts 차트 4개, 테넌트 차트 2개, 최근 로그 5건+더보기)
- ServiceStatusPage (status.claude.com 스타일, 90일 uptime 바, Overall banner)
- ServiceStatusDetailPage (서비스별 상세, 일별 uptime 바+툴팁, 최근 체크 테이블, 색상 범례)
- 30초 자동 갱신 (대시보드), 60초 자동 갱신 (status)
- Request Logs 배지 색상 대시보드와 통일

Closes #10

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 13:44:23 +09:00

55 lines
2.5 KiB
TypeScript

import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import AuthProvider from './store/AuthContext';
import AuthLayout from './layouts/AuthLayout';
import MainLayout from './layouts/MainLayout';
import ProtectedRoute from './components/ProtectedRoute';
import LoginPage from './pages/LoginPage';
import DashboardPage from './pages/DashboardPage';
import RequestLogsPage from './pages/monitoring/RequestLogsPage';
import RequestLogDetailPage from './pages/monitoring/RequestLogDetailPage';
import ServiceStatusPage from './pages/monitoring/ServiceStatusPage';
import ServiceStatusDetailPage from './pages/monitoring/ServiceStatusDetailPage';
import MyKeysPage from './pages/apikeys/MyKeysPage';
import KeyRequestPage from './pages/apikeys/KeyRequestPage';
import KeyAdminPage from './pages/apikeys/KeyAdminPage';
import ServicesPage from './pages/admin/ServicesPage';
import UsersPage from './pages/admin/UsersPage';
import TenantsPage from './pages/admin/TenantsPage';
import NotFoundPage from './pages/NotFoundPage';
const BASE_PATH = '/snp-connection';
const App = () => {
return (
<BrowserRouter basename={BASE_PATH}>
<AuthProvider>
<Routes>
<Route element={<AuthLayout />}>
<Route path="/login" element={<LoginPage />} />
</Route>
<Route element={<ProtectedRoute />}>
<Route element={<MainLayout />}>
<Route path="/" element={<Navigate to="/dashboard" replace />} />
<Route path="/dashboard" element={<DashboardPage />} />
<Route path="/monitoring/request-logs" element={<RequestLogsPage />} />
<Route path="/monitoring/request-logs/:id" element={<RequestLogDetailPage />} />
<Route path="/monitoring/service-status" element={<ServiceStatusPage />} />
<Route path="/monitoring/service-status/:serviceId" element={<ServiceStatusDetailPage />} />
<Route path="/apikeys/my-keys" element={<MyKeysPage />} />
<Route path="/apikeys/request" element={<KeyRequestPage />} />
<Route path="/apikeys/admin" element={<KeyAdminPage />} />
<Route path="/admin/services" element={<ServicesPage />} />
<Route path="/admin/users" element={<UsersPage />} />
<Route path="/admin/tenants" element={<TenantsPage />} />
<Route path="*" element={<NotFoundPage />} />
</Route>
</Route>
</Routes>
</AuthProvider>
</BrowserRouter>
);
};
export default App;