kcg-ai-monitoring/frontend/src/app/App.tsx
Nan Kyung Lee 072d10bacf feat(frontend): SFR-20 LLM 운영 관리 페이지 신규 추가
Qwen3-8B 기반 통합 LLM 운영 플랫폼 웹 콘솔 (10탭):
- 모델 관리: 레지스트리, Blue-Green 배포, 파인튜닝 이력
- 프롬프트 관리: 4종 템플릿, A/B 테스트, Git 버전관리
- 추론 서비스: vLLM 엔드포인트, 오토스케일링, KPI
- 로그/추적: ELK + OpenTelemetry, 마스킹 처리
- 평가/품질: RAGAS 자동 평가, 할루시네이션율, F1
- 데이터: 문서 등록(법령/지침/매뉴얼/단속·수사 사례), 지식 소스
- RAG 파이프라인: 6단계 + Airflow 재색인 + MRR/NDCG
- 품질개선: 불용어 관리, 욕설 필터링, 분류체계, 규칙 보완
- 보안: 3단계 파이프라인 + 망분리 + TLS 1.3
- 운영 모니터링: GPU 노드 + 서비스 상태 + Alertmanager

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

136 lines
9.1 KiB
TypeScript

import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import { AuthProvider, useAuth } from '@/app/auth/AuthContext';
import { MainLayout } from '@/app/layout/MainLayout';
import { LoginPage } from '@features/auth';
/* SFR-01 */ import { AccessControl } from '@features/admin';
/* SFR-02 */ import { SystemConfig, NoticeManagement } from '@features/admin';
/* SFR-03 */ import { DataHub } from '@features/admin';
/* SFR-04 */ import { AIModelManagement } from '@features/ai-operations';
/* SFR-05 */ import { RiskMap } from '@features/risk-assessment';
/* SFR-06 */ import { EnforcementPlan } from '@features/risk-assessment';
/* SFR-07 */ import { PatrolRoute } from '@features/patrol';
/* SFR-08 */ import { FleetOptimization } from '@features/patrol';
/* SFR-09 */ import { DarkVesselDetection } from '@features/detection';
/* SFR-10 */ import { GearDetection } from '@features/detection';
/* SFR-11 */ import { EnforcementHistory } from '@features/enforcement';
/* SFR-12 */ import { MonitoringDashboard } from '@features/monitoring';
/* SFR-13 */ import { Statistics } from '@features/statistics';
/* SFR-14 */ import { ExternalService } from '@features/statistics';
/* SFR-15 */ import { MobileService } from '@features/field-ops';
/* SFR-16 */ import { ShipAgent } from '@features/field-ops';
/* SFR-17 */ import { AIAlert } from '@features/field-ops';
/* SFR-18+19 */ import { MLOpsPage } from '@features/ai-operations';
/* SFR-20 */ import { AIAssistant } from '@features/ai-operations';
/* SFR-20 LLM운영 */ import { LLMOpsPage } from '@features/ai-operations';
/* 기존 */ import { Dashboard } from '@features/dashboard';
import { LiveMapView, MapControl } from '@features/surveillance';
import { EventList } from '@features/enforcement';
import { VesselDetail } from '@features/vessel';
import { ChinaFishing } from '@features/detection';
import { ReportManagement } from '@features/statistics';
import { AdminPanel } from '@features/admin';
// Phase 4: 모선 워크플로우
import { ParentReview } from '@features/parent-inference/ParentReview';
import { ParentExclusion } from '@features/parent-inference/ParentExclusion';
import { LabelSession } from '@features/parent-inference/LabelSession';
// Phase 4: 관리자 로그
import { AuditLogs } from '@features/admin/AuditLogs';
import { AccessLogs } from '@features/admin/AccessLogs';
import { LoginHistoryView } from '@features/admin/LoginHistoryView';
/**
* 권한 가드.
* - user 미인증 시 /login으로 리다이렉트
* - resource 지정 시 hasPermission 체크 → 거부 시 403 표시
*/
function ProtectedRoute({
children,
resource,
operation = 'READ',
}: {
children: React.ReactNode;
resource?: string;
operation?: string;
}) {
const { user, loading, hasPermission } = useAuth();
if (loading) return null;
if (!user) return <Navigate to="/login" replace />;
if (resource && !hasPermission(resource, operation)) {
return (
<div className="flex flex-col items-center justify-center min-h-[60vh] text-center px-6">
<div className="text-4xl mb-4">🚫</div>
<h1 className="text-xl font-bold text-heading mb-2"> </h1>
<p className="text-sm text-hint">
<code className="bg-surface-overlay px-1.5 py-0.5 rounded">{resource}</code>::{operation} .
</p>
</div>
);
}
return <>{children}</>;
}
export default function App() {
return (
<BrowserRouter>
<AuthProvider>
<Routes>
<Route path="/login" element={<LoginPage />} />
<Route path="/" element={<ProtectedRoute><MainLayout /></ProtectedRoute>}>
<Route index element={<Navigate to="/dashboard" replace />} />
{/* SFR-12 대시보드 */}
<Route path="dashboard" element={<ProtectedRoute resource="dashboard"><Dashboard /></ProtectedRoute>} />
<Route path="monitoring" element={<ProtectedRoute resource="monitoring"><MonitoringDashboard /></ProtectedRoute>} />
{/* SFR-05~06 위험도·단속계획 */}
<Route path="risk-map" element={<ProtectedRoute resource="risk-assessment:risk-map"><RiskMap /></ProtectedRoute>} />
<Route path="enforcement-plan" element={<ProtectedRoute resource="risk-assessment:enforcement-plan"><EnforcementPlan /></ProtectedRoute>} />
{/* SFR-09~10 탐지 */}
<Route path="dark-vessel" element={<ProtectedRoute resource="detection:dark-vessel"><DarkVesselDetection /></ProtectedRoute>} />
<Route path="gear-detection" element={<ProtectedRoute resource="detection:gear-detection"><GearDetection /></ProtectedRoute>} />
<Route path="china-fishing" element={<ProtectedRoute resource="detection:china-fishing"><ChinaFishing /></ProtectedRoute>} />
{/* SFR-07~08 순찰경로 */}
<Route path="patrol-route" element={<ProtectedRoute resource="patrol:patrol-route"><PatrolRoute /></ProtectedRoute>} />
<Route path="fleet-optimization" element={<ProtectedRoute resource="patrol:fleet-optimization"><FleetOptimization /></ProtectedRoute>} />
{/* SFR-11 이력 */}
<Route path="enforcement-history" element={<ProtectedRoute resource="enforcement:enforcement-history"><EnforcementHistory /></ProtectedRoute>} />
<Route path="event-list" element={<ProtectedRoute resource="enforcement:event-list"><EventList /></ProtectedRoute>} />
{/* SFR-15~17 현장 대응 */}
<Route path="mobile-service" element={<ProtectedRoute resource="field-ops:mobile-service"><MobileService /></ProtectedRoute>} />
<Route path="ship-agent" element={<ProtectedRoute resource="field-ops:ship-agent"><ShipAgent /></ProtectedRoute>} />
<Route path="ai-alert" element={<ProtectedRoute resource="field-ops:ai-alert"><AIAlert /></ProtectedRoute>} />
{/* SFR-13~14 통계·외부연계 */}
<Route path="statistics" element={<ProtectedRoute resource="statistics:statistics"><Statistics /></ProtectedRoute>} />
<Route path="external-service" element={<ProtectedRoute resource="statistics:external-service"><ExternalService /></ProtectedRoute>} />
<Route path="reports" element={<ProtectedRoute resource="statistics:statistics"><ReportManagement /></ProtectedRoute>} />
{/* SFR-04 AI 모델 */}
<Route path="ai-model" element={<ProtectedRoute resource="ai-operations:ai-model"><AIModelManagement /></ProtectedRoute>} />
{/* SFR-18~20 AI 운영 */}
<Route path="mlops" element={<ProtectedRoute resource="ai-operations:mlops"><MLOpsPage /></ProtectedRoute>} />
<Route path="llm-ops" element={<ProtectedRoute resource="ai-operations:llm-ops"><LLMOpsPage /></ProtectedRoute>} />
<Route path="ai-assistant" element={<ProtectedRoute resource="ai-operations:ai-assistant"><AIAssistant /></ProtectedRoute>} />
{/* SFR-03 데이터허브 */}
<Route path="data-hub" element={<ProtectedRoute resource="admin:system-config"><DataHub /></ProtectedRoute>} />
{/* SFR-02 환경설정 */}
<Route path="system-config" element={<ProtectedRoute resource="admin:system-config"><SystemConfig /></ProtectedRoute>} />
<Route path="notices" element={<ProtectedRoute resource="admin"><NoticeManagement /></ProtectedRoute>} />
{/* SFR-01 권한·시스템 */}
<Route path="access-control" element={<ProtectedRoute resource="admin:permission-management"><AccessControl /></ProtectedRoute>} />
<Route path="admin" element={<ProtectedRoute resource="admin"><AdminPanel /></ProtectedRoute>} />
{/* Phase 4: 관리자 로그 */}
<Route path="admin/audit-logs" element={<ProtectedRoute resource="admin:audit-logs"><AuditLogs /></ProtectedRoute>} />
<Route path="admin/access-logs" element={<ProtectedRoute resource="admin:access-logs"><AccessLogs /></ProtectedRoute>} />
<Route path="admin/login-history" element={<ProtectedRoute resource="admin:login-history"><LoginHistoryView /></ProtectedRoute>} />
{/* Phase 4: 모선 워크플로우 */}
<Route path="parent-inference/review" element={<ProtectedRoute resource="parent-inference-workflow:parent-review"><ParentReview /></ProtectedRoute>} />
<Route path="parent-inference/exclusion" element={<ProtectedRoute resource="parent-inference-workflow:parent-exclusion"><ParentExclusion /></ProtectedRoute>} />
<Route path="parent-inference/label-session" element={<ProtectedRoute resource="parent-inference-workflow:label-session"><LabelSession /></ProtectedRoute>} />
{/* 기존 유지 */}
<Route path="events" element={<ProtectedRoute resource="surveillance:live-map"><LiveMapView /></ProtectedRoute>} />
<Route path="map-control" element={<ProtectedRoute resource="surveillance:map-control"><MapControl /></ProtectedRoute>} />
<Route path="vessel/:id" element={<ProtectedRoute resource="vessel:vessel-detail"><VesselDetail /></ProtectedRoute>} />
</Route>
</Routes>
</AuthProvider>
</BrowserRouter>
);
}