From 755f3919ba2f361566b8f542971302e635bb6733 Mon Sep 17 00:00:00 2001 From: Nan Kyung Lee Date: Wed, 15 Apr 2026 17:12:40 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=EC=8B=9C=EC=8A=A4=ED=85=9C?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=20>=20=EA=B0=90=EC=82=AC=C2=B7=EB=B3=B4?= =?UTF-8?q?=EC=95=88=EC=97=90=20=EC=84=B1=EB=8A=A5=20=EB=AA=A8=EB=8B=88?= =?UTF-8?q?=ED=84=B0=EB=A7=81(PER-01~06)=20=EB=A9=94=EB=89=B4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - V028 Flyway 마이그레이션: admin:performance-monitoring 권한 트리 + RBAC - PerformanceMonitoring.tsx: 5 탭 구조(성능 현황·응답성·처리용량·AI 모델·가용성/확장성) - PER-01~06 전체 커버: 3,000명 규모·상황실 100명 24/7 SLO·S&P 글로벌 AIS 영향 최소화 8대 전략 - 6개 AI 모델 성능 지표(정확도·정밀도·재현율·F1·ROC-AUC) 표시 - 디자인 시스템 준수: PageContainer/PageHeader/Card/Badge intent 기반 Co-Authored-By: Claude Opus 4.6 (1M context) --- .../V028__performance_monitoring_menu.sql | 28 + frontend/src/app/componentRegistry.ts | 3 + .../features/admin/PerformanceMonitoring.tsx | 637 ++++++++++++++++++ frontend/src/features/admin/index.ts | 1 + frontend/src/lib/i18n/locales/en/common.json | 3 +- frontend/src/lib/i18n/locales/ko/common.json | 3 +- 6 files changed, 673 insertions(+), 2 deletions(-) create mode 100644 backend/src/main/resources/db/migration/V028__performance_monitoring_menu.sql create mode 100644 frontend/src/features/admin/PerformanceMonitoring.tsx diff --git a/backend/src/main/resources/db/migration/V028__performance_monitoring_menu.sql b/backend/src/main/resources/db/migration/V028__performance_monitoring_menu.sql new file mode 100644 index 0000000..2bcce36 --- /dev/null +++ b/backend/src/main/resources/db/migration/V028__performance_monitoring_menu.sql @@ -0,0 +1,28 @@ +-- ============================================================ +-- V028: 성능 모니터링 (PER-01~06) 메뉴 추가 +-- 시스템관리 > 감사·보안 서브그룹 +-- ============================================================ + +-- 1. 권한 트리 노드 등록 +INSERT INTO kcg.auth_perm_tree(rsrc_cd, parent_cd, rsrc_nm, rsrc_level, sort_ord) +VALUES ('admin:performance-monitoring', 'admin', '성능 모니터링', 1, 59) +ON CONFLICT (rsrc_cd) DO NOTHING; + +-- 2. 메뉴 메타데이터 갱신 +UPDATE kcg.auth_perm_tree +SET url_path = '/admin/performance-monitoring', + label_key = 'nav.performanceMonitoring', + component_key = 'features/admin/PerformanceMonitoring', + nav_group = 'admin', + nav_sub_group = '감사·보안', + nav_sort = 2110, + labels = '{"ko":"성능 모니터링","en":"Performance Monitoring"}' +WHERE rsrc_cd = 'admin:performance-monitoring'; + +-- 3. ADMIN 역할에 전체 권한 부여 +INSERT INTO kcg.auth_perm(role_sn, rsrc_cd, oper_cd, grant_yn) +SELECT r.role_sn, 'admin:performance-monitoring', op.oper_cd, 'Y' +FROM kcg.auth_role r +CROSS JOIN (VALUES ('READ'), ('CREATE'), ('UPDATE'), ('DELETE'), ('EXPORT')) AS op(oper_cd) +WHERE r.role_cd = 'ADMIN' +ON CONFLICT (role_sn, rsrc_cd, oper_cd) DO NOTHING; diff --git a/frontend/src/app/componentRegistry.ts b/frontend/src/app/componentRegistry.ts index 204ef79..8f255e7 100644 --- a/frontend/src/app/componentRegistry.ts +++ b/frontend/src/app/componentRegistry.ts @@ -128,6 +128,9 @@ export const COMPONENT_REGISTRY: Record = { 'features/admin/DataModelVerification': lazy(() => import('@features/admin').then((m) => ({ default: m.DataModelVerification })), ), + 'features/admin/PerformanceMonitoring': lazy(() => + import('@features/admin').then((m) => ({ default: m.PerformanceMonitoring })), + ), // ── 모선 워크플로우 ── 'features/parent-inference/ParentReview': lazy(() => import('@features/parent-inference/ParentReview').then((m) => ({ diff --git a/frontend/src/features/admin/PerformanceMonitoring.tsx b/frontend/src/features/admin/PerformanceMonitoring.tsx new file mode 100644 index 0000000..cd59ed3 --- /dev/null +++ b/frontend/src/features/admin/PerformanceMonitoring.tsx @@ -0,0 +1,637 @@ +import { useState } from 'react'; +import { Card, CardContent } from '@shared/components/ui/card'; +import { Badge } from '@shared/components/ui/badge'; +import { PageContainer, PageHeader } from '@shared/components/layout'; +import { + Activity, Gauge, Users, Database, Brain, Server, + CheckCircle, AlertTriangle, TrendingUp, Clock, + Zap, Shield, BarChart3, Cpu, HardDrive, Wifi, +} from 'lucide-react'; + +/* + * 성능 모니터링 (PER-01 ~ PER-06) + * + * 총 사용자 3,000명 (본청 200명·상황실 100명 24/7 + 지방청·관할서·함정) + * 통합게이트웨이(V-PASS·VTS·E-nav) + S&P Global AIS A/B 클래스 전제 + * + * ① 성능 현황 ② 응답성(PER-01) ③ 처리용량(PER-02·03) + * ④ AI 모델 성능(PER-04) ⑤ 가용성·확장성(PER-05·06) + */ + +type Tab = 'overview' | 'response' | 'capacity' | 'aiModel' | 'availability'; + +// ─── 성능 KPI ────────────────── +const PERF_KPI = [ + { label: '현재 동시접속', value: '342', unit: '명', icon: Users, color: '#3b82f6', status: 'normal' }, + { label: '대시보드 p95', value: '1.8', unit: '초', icon: Gauge, color: '#10b981', status: 'good' }, + { label: '시스템 가동률', value: '99.87', unit: '%', icon: Shield, color: '#06b6d4', status: 'good' }, + { label: 'AI 추론 p95', value: '1.4', unit: '초', icon: Brain, color: '#8b5cf6', status: 'good' }, + { label: '배치 SLA 준수', value: '100', unit: '%', icon: CheckCircle, color: '#10b981', status: 'good' }, + { label: '이벤트 경보', value: '0', unit: '건', icon: AlertTriangle, color: '#f59e0b', status: 'normal' }, +]; + +// ─── SLO 적용 그룹 ────────────────── +const USER_GROUPS = [ + { group: '본청 상황실', users: 100, concurrent: '100 (100%)', sla: '≤ 2초 대시보드 / ≤ 1초 지도', priority: 'critical' as const, note: '24/7 상시 접속 · 최상위 SLO' }, + { group: '본청 기타', users: 100, concurrent: '50 (50%)', sla: '≤ 3초 대시보드', priority: 'high' as const, note: '주간 업무 시간' }, + { group: '지방청(5개)', users: 400, concurrent: '120 (30%)', sla: '≤ 3초 대시보드', priority: 'high' as const, note: '관할해역 상황실' }, + { group: '관할서', users: 1500, concurrent: '300 (20%)', sla: '≤ 1.5초 조회', priority: 'info' as const, note: '주간 피크' }, + { group: '함정·파출소', users: 800, concurrent: '120 (15%)', sla: '≤ 1초 API', priority: 'info' as const, note: '모바일 Agent · 저대역폭' }, +]; + +// ─── PER-01 응답성 SLO vs 실측 ────────────────── +const RESPONSE_SLO = [ + { target: '메인 대시보드 초기 로드', slo: '2.0초', p50: '0.9초', p95: '1.8초', p99: '2.4초', status: 'good' as const }, + { target: '위험도 지도 격자 조회', slo: '2.0초', p50: '0.7초', p95: '1.6초', p99: '2.1초', status: 'good' as const }, + { target: '의심 선박·어구 단순 조회', slo: '1.5초', p50: '0.4초', p95: '1.1초', p99: '1.7초', status: 'good' as const }, + { target: '복합 분석·시각화', slo: '5.0초', p50: '2.1초', p95: '4.2초', p99: '5.8초', status: 'warn' as const }, + { target: 'AI 추론 API (단건)', slo: '2.0초', p50: '0.6초', p95: '1.4초', p99: '1.9초', status: 'good' as const }, + { target: '연계 API (read)', slo: '500ms', p50: '120ms', p95: '380ms', p99: '510ms', status: 'warn' as const }, + { target: '함정 모바일 Agent API', slo: '1.0초', p50: '0.3초', p95: '0.8초', p99: '1.2초', status: 'good' as const }, + { target: 'AI 탐지 알림 End-to-End', slo: '3.0초', p50: '1.1초', p95: '2.3초', p99: '2.8초', status: 'good' as const }, +]; + +// ─── PER-02 동시접속·TPS ────────────────── +const CAPACITY_METRICS = [ + { metric: '현재 동시접속', current: 342, target: '600 (정상 피크)', max: '900 (작전 피크)', utilization: 57, intent: 'info' as const }, + { metric: '현재 TPS', current: 185, target: '400 TPS', max: '600 TPS', utilization: 46, intent: 'info' as const }, + { metric: '활성 세션', current: 287, target: '500', max: '750', utilization: 57, intent: 'info' as const }, + { metric: 'WebSocket 연결', current: 142, target: '300', max: '500', utilization: 47, intent: 'info' as const }, +]; + +// ─── PER-03 배치 처리 현황 ────────────────── +const BATCH_JOBS = [ + { name: 'AIS 국내 정제·적재', schedule: '매 5분', volume: '~5 GB/일', sla: '5분', avg: '2분 18초', lastRun: '성공', status: 'success' as const }, + { name: 'S&P 글로벌 AIS 집계·격자', schedule: '00:00 야간', volume: '~500 GB/일 (압축 후)', sla: '3시간', avg: '2시간 12분', lastRun: '성공', status: 'success' as const }, + { name: '위성영상 타일링·인덱싱', schedule: '수신 직후', volume: '건당 2~10 GB', sla: '2시간/건', avg: '1시간 24분', lastRun: '성공', status: 'success' as const }, + { name: '피처 스토어 갱신', schedule: '매시 정각', volume: '~200 MB', sla: '1시간', avg: '8분 42초', lastRun: '성공', status: 'success' as const }, + { name: 'AI 모델 재학습 (주간)', schedule: '일요일 02:00', volume: '학습셋 전체', sla: '8시간', avg: '6시간 18분', lastRun: '성공', status: 'success' as const }, + { name: '통계·리포트 집계', schedule: '매시 정각', volume: '~50 MB', sla: '30분', avg: '6분 12초', lastRun: '성공', status: 'success' as const }, + { name: '해양기상·환경 수집', schedule: '매시 정각', volume: '~500 MB', sla: '10분', avg: '3분 48초', lastRun: '지연', status: 'warn' as const }, +]; + +// ─── PER-04 AI 모델 성능 ────────────────── +const AI_MODELS = [ + { model: '불법조업 위험도 예측', accuracy: 92.4, precision: 89.1, recall: 87.6, f1: 88.3, rocAuc: 0.948, target: '≥ 85% 정확도', status: 'good' as const }, + { model: '순찰 경로 추천 (단일)', accuracy: 94.1, precision: 91.2, recall: 90.5, f1: 90.8, rocAuc: 0.961, target: '≥ 90% 정확도', status: 'good' as const }, + { model: '다함정 협력 경로 최적화', accuracy: 91.8, precision: 88.4, recall: 87.9, f1: 88.1, rocAuc: 0.936, target: '≥ 85% 정확도', status: 'good' as const }, + { model: '불법 어선 (Dark Vessel) 탐지', accuracy: 96.2, precision: 94.8, recall: 92.3, f1: 93.5, rocAuc: 0.978, target: '≥ 92% 정확도', status: 'good' as const }, + { model: '불법 어망·어구 탐지', accuracy: 88.7, precision: 85.2, recall: 83.6, f1: 84.4, rocAuc: 0.912, target: '≥ 85% 정확도', status: 'warn' as const }, + { model: 'AIS 조작 패턴 감지', accuracy: 93.5, precision: 91.7, recall: 89.4, f1: 90.5, rocAuc: 0.954, target: '≥ 90% 정확도', status: 'good' as const }, +]; + +// ─── PER-05 가용성·장애복구 ────────────────── +const AVAILABILITY_METRICS = [ + { component: '애플리케이션 서버 (K8s)', uptime: '99.98%', rto: '≤ 30초', rpo: '0 (stateless)', lastIncident: '없음', status: 'good' as const }, + { component: 'DB (PostgreSQL HA)', uptime: '99.95%', rto: '≤ 60초', rpo: '≤ 5초', lastIncident: '2026-03-28', status: 'good' as const }, + { component: 'TimescaleDB (Hot)', uptime: '99.92%', rto: '≤ 120초', rpo: '≤ 15초', lastIncident: '2026-04-02', status: 'good' as const }, + { component: '벡터 DB (RAG)', uptime: '99.87%', rto: '≤ 180초', rpo: '≤ 30초', lastIncident: '2026-04-08', status: 'warn' as const }, + { component: 'NAS 스토리지', uptime: '99.99%', rto: '≤ 60초', rpo: '0 (이중화)', lastIncident: '없음', status: 'good' as const }, + { component: '통합게이트웨이', uptime: '99.89%', rto: '≤ 60초', rpo: '≤ 10초', lastIncident: '2026-04-05', status: 'good' as const }, + { component: 'S&P Global AIS API', uptime: '99.41%', rto: 'Fallback 즉시', rpo: '국내 신호 대체', lastIncident: '2026-04-12', status: 'warn' as const }, + { component: 'LLM Q&A 서버 (H200)', uptime: '99.76%', rto: '≤ 120초', rpo: '0 (stateless)', lastIncident: '2026-04-09', status: 'good' as const }, +]; + +// ─── PER-06 확장성·자원 사용률 ────────────────── +const RESOURCE_USAGE = [ + { resource: '워커 노드 CPU', current: 48, threshold: 70, max: 80, scalePolicy: 'HPA 자동 확장', unit: '%' }, + { resource: '워커 노드 메모리', current: 52, threshold: 75, max: 85, scalePolicy: 'HPA 자동 확장', unit: '%' }, + { resource: 'AI 서버 GPU (RTX pro 6000)', current: 61, threshold: 80, max: 90, scalePolicy: '추론 큐잉', unit: '%' }, + { resource: 'LLM 서버 GPU (H200)', current: 44, threshold: 75, max: 85, scalePolicy: '요청 병합·배치', unit: '%' }, + { resource: 'DB 연결 풀', current: 128, threshold: 300, max: 400, scalePolicy: 'PgBouncer 풀 확대', unit: '개' }, + { resource: 'NAS 사용량', current: 28, threshold: 75, max: 90, scalePolicy: '콜드 티어 이관', unit: '% (100TB)' }, + { resource: 'Kafka 컨슈머 Lag', current: 142, threshold: 5000, max: 10000, scalePolicy: '파티션 증설', unit: 'msg' }, + { resource: 'Redis 캐시 메모리', current: 38, threshold: 70, max: 85, scalePolicy: 'Eviction + 클러스터 확장', unit: '%' }, +]; + +// ─── 성능 영향 최소화 전략 (S&P 글로벌 대응) ────────────────── +const IMPACT_REDUCTION = [ + { strategy: '이중 수집 파이프라인 물리 분리', target: '국내 vs 글로벌 격리', effect: '글로벌 장애 → 국내 무영향', per: 'PER-01·05' }, + { strategy: '경계 조기 필터링', target: '지리·선박 클래스 필터', effect: '원본 50~80% 감축', per: 'PER-03' }, + { strategy: '스트림·백프레셔 (Kafka)', target: 'Lag 임계 초과 시 다운샘플링', effect: '온라인 무영향', per: 'PER-01·03' }, + { strategy: '티어드 스토리지 (Hot/Warm/Cold)', target: '1~7일 / 30일 / 이후', effect: '쿼리 비용 최소화', per: 'PER-03·06' }, + { strategy: '공간 사전 집계 (H3 격자)', target: 'Materialized View', effect: '대시보드 Redis만 조회', per: 'PER-01' }, + { strategy: 'Circuit Breaker (S&P)', target: '실패율 50% 차단', effect: '국내 신호 Fallback', per: 'PER-05' }, + { strategy: 'K8s PriorityClass 격리', target: '온라인 vs 배치', effect: '상황실 SLO 절대 보장', per: 'PER-01·03' }, + { strategy: 'HPA 자동 확장', target: 'CPU/메모리 70% 임계', effect: '피크 자동 대응', per: 'PER-02·06' }, +]; + +const statusIntent = (s: 'good' | 'warn' | 'critical' | 'success'): 'success' | 'warning' | 'critical' => { + if (s === 'good' || s === 'success') return 'success'; + if (s === 'warn') return 'warning'; + return 'critical'; +}; + +const barColor = (ratio: number): string => { + if (ratio < 0.6) return '#10b981'; + if (ratio < 0.8) return '#f59e0b'; + return '#ef4444'; +}; + +export function PerformanceMonitoring() { + const [tab, setTab] = useState('overview'); + + return ( + + + + {/* 탭 */} +
+ {([ + { key: 'overview' as Tab, icon: BarChart3, label: '성능 현황' }, + { key: 'response' as Tab, icon: Gauge, label: '응답성 (PER-01)' }, + { key: 'capacity' as Tab, icon: Users, label: '처리용량 (PER-02·03)' }, + { key: 'aiModel' as Tab, icon: Brain, label: 'AI 모델 (PER-04)' }, + { key: 'availability' as Tab, icon: Shield, label: '가용성·확장성 (PER-05·06)' }, + ]).map(t => ( + + ))} +
+ + {/* ── ① 성능 현황 ── */} + {tab === 'overview' && ( +
+ {/* KPI */} +
+ {PERF_KPI.map(k => ( +
+ +
+
+ {k.value}{k.unit} +
+
{k.label}
+
+
+ ))} +
+ + {/* 사용자 그룹별 SLO */} + +
+ + 사용자 그룹별 SLO (총 2,900명 + 추정) + 본청 200 · 상황실 100 확정 +
+ + + + + + + + + + + + + {USER_GROUPS.map(g => ( + + + + + + + + + ))} + +
그룹총 인원동시접속 추정SLA우선순위특성
{g.group}{g.users.toLocaleString()}명{g.concurrent}{g.sla}{g.priority === 'critical' ? '최상' : g.priority === 'high' ? '높음' : '일반'}{g.note}
+
+ + {/* 성능 영향 최소화 전략 */} + +
+ + 성능 영향 최소화 전략 (글로벌 AIS 대응) +
+
+ {IMPACT_REDUCTION.map((s, i) => ( +
+
{i + 1}
+
+
+ {s.strategy} + {s.per} +
+
대상: {s.target}
+
효과: {s.effect}
+
+
+ ))} +
+
+
+ )} + + {/* ── ② 응답성 (PER-01) ── */} + {tab === 'response' && ( +
+ +
+
+ + PER-01 서비스 응답성 — SLO vs 실측 (p50/p95/p99) +
+ TER-03 검증 통과 +
+ + + + + + + + + + + + + {RESPONSE_SLO.map(r => ( + + + + + + + + + ))} + +
대상SLO 목표p50p95p99상태
{r.target}{r.slo}{r.p50}{r.p95}{r.p99}{r.status === 'good' ? '정상' : '주의'}
+
+ +
+ +
+ + 상황실 전용 SLO (24/7 100명) +
+
+ {[ + { item: '메인 대시보드 초기 로드', target: '≤ 2초', current: '1.8초', met: true }, + { item: '위험도 지도 실시간 갱신', target: '≤ 1초', current: '0.7초', met: true }, + { item: 'AI 탐지 알림 수신 → 표출', target: '≤ 3초 E2E', current: '2.3초', met: true }, + { item: '단속 계획·경로 조회', target: '≤ 1.5초', current: '1.1초', met: true }, + { item: '장애 시 세션 유지', target: '< 30초 복구', current: '18초', met: true }, + ].map(s => ( +
+
+
{s.item}
+
목표: {s.target}
+
+
+ {s.current} + {s.met ? : } +
+
+ ))} +
+
+ + +
+ + 측정 방법론 +
+
    +
  • + +
    샘플링: 1초 간격 p50/p95/p99 집계
    +
  • +
  • + +
    도구: OpenTelemetry + Prometheus + Grafana
    +
  • +
  • + +
    APM: 분산 추적 + Trace ID 요청 단위 관통
    +
  • +
  • + +
    API 재시도: 3회 · Exponential Backoff · 타임아웃 3초
    +
  • +
  • + +
    경보: SLO 위반 지속 5분 → PagerDuty
    +
  • +
  • + +
    원인 분석: RED/USE 방법론 + 로그·메트릭·추적 상관 분석
    +
  • +
+
+
+
+ )} + + {/* ── ③ 처리용량 (PER-02·03) ── */} + {tab === 'capacity' && ( +
+ {/* 동시접속·TPS */} + +
+ + PER-02 동시접속·처리용량 (정상 피크 600 / 작전 피크 900) +
+
+ {CAPACITY_METRICS.map(c => ( +
+
{c.metric}
+
{c.current.toLocaleString()}
+
목표 {c.target} / 최대 {c.max}
+
+
+
+
{c.utilization}% 사용 중
+
+ ))} +
+ + + {/* 배치 작업 현황 */} + +
+ + PER-03 배치 · 대용량 처리 현황 + SLA 준수 6/7 +
+ + + + + + + + + + + + + {BATCH_JOBS.map(j => ( + + + + + + + + + ))} + +
배치 작업스케줄처리 볼륨SLA평균 소요최근 실행
{j.name}{j.schedule}{j.volume}{j.sla}{j.avg}{j.lastRun}
+
+ + {/* 처리 볼륨 산정 */} + +
+ + 데이터 처리 볼륨 (국내 + S&P 글로벌) +
+
+
+
일 수집 (원본)
+
1.6 ~ 3.2 TB
+
AIS(국내) + S&P A/B + 위성 + 환경
+
+
+
일 적재 (필터·압축 후)
+
330 ~ 900 GB
+
경계 필터링 50~80% 감축
+
+
+
3년 누적 (티어드)
+
~360 TB ~ 1 PB
+
NAS 100TB → 객체스토리지 이관
+
+
+
+
+ )} + + {/* ── ④ AI 모델 성능 (PER-04) ── */} + {tab === 'aiModel' && ( +
+ +
+
+ + PER-04 AI 모델 성능 지표 +
+
+ 6개 모델 운영 중 + 어망·어구 모델 개선 필요 +
+
+ + + + + + + + + + + + + + + {AI_MODELS.map(m => ( + + + + + + + + + + + ))} + +
모델정확도정밀도재현율F1ROC-AUC목표상태
{m.model}{m.accuracy}%{m.precision}%{m.recall}%{m.f1}{m.rocAuc}{m.target}{m.status === 'good' ? '통과' : '주의'}
+
+ +
+ +
+ + 모델 성능 저하 대응 +
+
    +
  • + +
    학습/검증/테스트 분할: 70/15/15 비율, K-Fold 5
    +
  • +
  • + +
    드리프트 탐지: 입력 분포 KL divergence 주간 모니터링
    +
  • +
  • + +
    성능 저하 임계: F1 3%p 하락 시 자동 재학습 트리거
    +
  • +
  • + +
    설명가능성: Feature Importance + SHAP 값 제공
    +
  • +
  • + +
    A/B 테스트: Shadow → Canary 5% → 50% → 100% 단계 배포
    +
  • +
+
+ + +
+ + 추론 성능 (GPU 활용) +
+
+
+
+ AI 서버 (RTX pro 6000 Blackwell ×2) + 61% +
+
+
+
+
추론 단건 평균 1.4초 · 큐 대기 <200ms
+
+
+
+ LLM 서버 (H200 ×2) + 44% +
+
+
+
+
Q&A 스트리밍 첫 토큰 평균 380ms
+
+
+
동시 추론 요청 처리
+
+ 최대 100 요청/초 + 큐잉 지연 <1% +
+
+
+ +
+
+ )} + + {/* ── ⑤ 가용성·확장성 (PER-05·06) ── */} + {tab === 'availability' && ( +
+ {/* 가용성 */} + +
+ + PER-05 가용성 및 장애복구 (목표 ≥ 99.9%) +
+ + + + + + + + + + + + + {AVAILABILITY_METRICS.map(a => ( + + + + + + + + + ))} + +
구성요소가동률RTORPO최근 장애상태
{a.component}{a.uptime}{a.rto}{a.rpo}{a.lastIncident}{a.status === 'good' ? '정상' : '주의'}
+
+ + {/* 확장성 */} + +
+ + PER-06 확장성 및 자원 사용률 + 2배(6,000명) 확장 목표 +
+
+ {RESOURCE_USAGE.map(r => { + const ratio = r.current / r.max; + return ( +
+
+ {r.resource} + {r.current}{r.unit === '%' || r.unit.startsWith('%') ? '%' : ' ' + r.unit} +
+
+
+
+
+ 경보 {r.threshold}{r.unit === '%' || r.unit.startsWith('%') ? '%' : ''} · 한계 {r.max}{r.unit === '%' || r.unit.startsWith('%') ? '%' : ''} + {r.scalePolicy} +
+
+ ); + })} +
+ + + {/* 요약 지표 */} +
+ +
+ + 연간 가동률 목표 +
+
99.9%
+
월간 다운타임 ≤ 43분
+
+ +
+ + RTO 평균 +
+
≤ 60초
+
자동 페일오버 · Self-healing
+
+ +
+ + RPO 평균 +
+
≤ 10초
+
실시간 복제 + 백업 이중화
+
+ +
+ + Scale-out 여유 +
+
×2
+
6,000명까지 선형 확장
+
+
+
+ )} + + ); +} diff --git a/frontend/src/features/admin/index.ts b/frontend/src/features/admin/index.ts index d435fec..ba71450 100644 --- a/frontend/src/features/admin/index.ts +++ b/frontend/src/features/admin/index.ts @@ -7,3 +7,4 @@ export { AISecurityPage } from './AISecurityPage'; export { AIAgentSecurityPage } from './AIAgentSecurityPage'; export { DataRetentionPolicy } from './DataRetentionPolicy'; export { DataModelVerification } from './DataModelVerification'; +export { PerformanceMonitoring } from './PerformanceMonitoring'; diff --git a/frontend/src/lib/i18n/locales/en/common.json b/frontend/src/lib/i18n/locales/en/common.json index 10d35c7..3d4d331 100644 --- a/frontend/src/lib/i18n/locales/en/common.json +++ b/frontend/src/lib/i18n/locales/en/common.json @@ -38,7 +38,8 @@ "aiSecurity": "AI Security", "aiAgentSecurity": "AI Agent Security", "dataRetentionPolicy": "Data Retention", - "dataModelVerification": "Model Verification" + "dataModelVerification": "Model Verification", + "performanceMonitoring": "Performance Monitoring" }, "status": { "active": "Active", diff --git a/frontend/src/lib/i18n/locales/ko/common.json b/frontend/src/lib/i18n/locales/ko/common.json index 74b7d9b..c4ee620 100644 --- a/frontend/src/lib/i18n/locales/ko/common.json +++ b/frontend/src/lib/i18n/locales/ko/common.json @@ -38,7 +38,8 @@ "aiSecurity": "AI 보안", "aiAgentSecurity": "AI Agent 보안", "dataRetentionPolicy": "데이터 보관·파기", - "dataModelVerification": "데이터 모델 검증" + "dataModelVerification": "데이터 모델 검증", + "performanceMonitoring": "성능 모니터링" }, "status": { "active": "활성", -- 2.45.2 From 77b6fc9b14a1e4bacc80b4cbe116814484147cf2 Mon Sep 17 00:00:00 2001 From: htlee Date: Thu, 16 Apr 2026 08:03:32 +0900 Subject: [PATCH 2/2] =?UTF-8?q?docs:=20=EB=A6=B4=EB=A6=AC=EC=A6=88=20?= =?UTF-8?q?=EB=85=B8=ED=8A=B8=20=EC=A0=95=EB=A6=AC=20(2026-04-16.2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/RELEASE-NOTES.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/RELEASE-NOTES.md b/docs/RELEASE-NOTES.md index 1beeeec..e84285e 100644 --- a/docs/RELEASE-NOTES.md +++ b/docs/RELEASE-NOTES.md @@ -4,6 +4,15 @@ ## [Unreleased] +## [2026-04-16.2] + +### 추가 +- **성능 모니터링(PER-01~06) 메뉴** — 시스템관리 > 감사·보안에 성능 모니터링 페이지 추가 (PerformanceMonitoring 컴포넌트 + V028 메뉴 마이그레이션) +- **데이터 모델 검증(DAR-11) 메뉴** — DataModelVerification 페이지 + V027 메뉴 +- **데이터 보관·파기 정책(DAR-10) 메뉴** — DataRetentionPolicy 페이지 + V026 메뉴 +- **DAR-03 5종 어구 구조 비교** — AI 모델관리 어구 탐지 탭에 저층 트롤 / 스토우넷 / 자망 / 통발 / 쌍끌이 이미지 및 설명 추가 +- **단속 계획 탭 확장** — 단일 함정 순찰 작전 / 다함정 순찰 작전 탭 추가 (EnforcementPlan) + ## [2026-04-16] ### 추가 -- 2.45.2