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>
136 lines
9.1 KiB
TypeScript
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>
|
|
);
|
|
}
|