From d08d614b5fb52ae450c214e6ff678930a1ff373a Mon Sep 17 00:00:00 2001 From: htlee Date: Thu, 9 Apr 2026 12:05:35 +0900 Subject: [PATCH] =?UTF-8?q?fix(frontend):=20=EB=A9=94=EB=89=B4=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=20=ED=95=B4=EC=86=8C=20+=20system-flow=20=EB=85=B8?= =?UTF-8?q?=EB=93=9C=20=EB=8F=99=EA=B8=B0=ED=99=94=20+=20V019=20=EA=B6=8C?= =?UTF-8?q?=ED=95=9C=20=ED=8A=B8=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - /map-control labelKey nav.riskMap → nav.mapControl (위험도 지도 중복 해소) - i18n nav.mapControl 키 추가 (ko: 해역 관리, en: Map Control) - V019 마이그레이션: ai-operations:llm-ops 권한 트리 항목 추가 (PR #22 누락분) - system-flow 08-frontend.json: 누락 노드 14개 추가 - ui.map_control, ui.risk_map, ui.patrol_route, ui.fleet_optimization - ui.report_management, ui.external_service - ui.ai_model, ui.mlops, ui.llm_ops - ui.mobile_service, ui.ship_agent - ui.admin_panel, ui.permissions Co-Authored-By: Claude Opus 4.6 (1M context) --- .../db/migration/V019__llm_ops_perm.sql | 16 ++ frontend/src/app/layout/MainLayout.tsx | 2 +- frontend/src/flow/manifest/08-frontend.json | 143 ++++++++++++++++++ frontend/src/lib/i18n/locales/en/common.json | 1 + frontend/src/lib/i18n/locales/ko/common.json | 1 + 5 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 backend/src/main/resources/db/migration/V019__llm_ops_perm.sql diff --git a/backend/src/main/resources/db/migration/V019__llm_ops_perm.sql b/backend/src/main/resources/db/migration/V019__llm_ops_perm.sql new file mode 100644 index 0000000..a589b08 --- /dev/null +++ b/backend/src/main/resources/db/migration/V019__llm_ops_perm.sql @@ -0,0 +1,16 @@ +-- ============================================================ +-- V019: LLM 운영 페이지 권한 트리 항목 추가 +-- PR #22에서 추가된 /llm-ops 페이지에 대응하는 권한 리소스 +-- ============================================================ + +INSERT INTO kcg.auth_perm_tree(rsrc_cd, parent_cd, rsrc_nm, rsrc_level, sort_ord) +VALUES ('ai-operations:llm-ops', 'ai-operations', 'LLM 운영', 1, 35) +ON CONFLICT (rsrc_cd) DO NOTHING; + +-- ADMIN 역할에 자동 부여 +INSERT INTO kcg.auth_perm(role_sn, rsrc_cd, oper_cd, grant_yn) +SELECT r.role_sn, 'ai-operations:llm-ops', 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/layout/MainLayout.tsx b/frontend/src/app/layout/MainLayout.tsx index bb3559d..1ebb4ef 100644 --- a/frontend/src/app/layout/MainLayout.tsx +++ b/frontend/src/app/layout/MainLayout.tsx @@ -47,7 +47,7 @@ const NAV_ENTRIES: NavEntry[] = [ { to: '/dashboard', icon: LayoutDashboard, labelKey: 'nav.dashboard' }, { to: '/monitoring', icon: Activity, labelKey: 'nav.monitoring' }, { to: '/events', icon: Radar, labelKey: 'nav.realtimeEvent' }, - { to: '/map-control', icon: Map, labelKey: 'nav.riskMap' }, + { to: '/map-control', icon: Map, labelKey: 'nav.mapControl' }, // ── 위험도·단속 ── { to: '/risk-map', icon: Layers, labelKey: 'nav.riskMap' }, { to: '/enforcement-plan', icon: Shield, labelKey: 'nav.enforcementPlan' }, diff --git a/frontend/src/flow/manifest/08-frontend.json b/frontend/src/flow/manifest/08-frontend.json index 3b6d315..3112d89 100644 --- a/frontend/src/flow/manifest/08-frontend.json +++ b/frontend/src/flow/manifest/08-frontend.json @@ -153,6 +153,50 @@ "status": "implemented", "file": "frontend/src/features/parent-inference/LabelSession.tsx" }, + { + "id": "ui.map_control", + "label": "해역 관리", + "shortDescription": "해역 구역 설정/관리 화면", + "stage": "UI", + "menu": "감시", + "kind": "ui", + "trigger": "on_demand", + "status": "implemented", + "file": "frontend/src/features/surveillance/MapControl.tsx" + }, + { + "id": "ui.risk_map", + "label": "위험도 지도", + "shortDescription": "해역별 위험도 히트맵", + "stage": "UI", + "menu": "위험평가", + "kind": "ui", + "trigger": "on_demand", + "status": "implemented", + "file": "frontend/src/features/risk-assessment/RiskMap.tsx" + }, + { + "id": "ui.patrol_route", + "label": "순찰경로 추천", + "shortDescription": "AI 기반 순찰 경로 최적화", + "stage": "UI", + "menu": "순찰", + "kind": "ui", + "trigger": "on_demand", + "status": "implemented", + "file": "frontend/src/features/patrol/PatrolRoute.tsx" + }, + { + "id": "ui.fleet_optimization", + "label": "다함정 최적화", + "shortDescription": "다수 함정 배치 최적화", + "stage": "UI", + "menu": "순찰", + "kind": "ui", + "trigger": "on_demand", + "status": "implemented", + "file": "frontend/src/features/patrol/FleetOptimization.tsx" + }, { "id": "ui.statistics", "label": "통계", @@ -164,6 +208,28 @@ "status": "implemented", "file": "frontend/src/features/statistics/Statistics.tsx" }, + { + "id": "ui.report_management", + "label": "보고서 관리", + "shortDescription": "보고서 생성/조회", + "stage": "UI", + "menu": "통계", + "kind": "ui", + "trigger": "on_demand", + "status": "implemented", + "file": "frontend/src/features/statistics/ReportManagement.tsx" + }, + { + "id": "ui.external_service", + "label": "외부 서비스", + "shortDescription": "외부 연동 서비스 설정", + "stage": "UI", + "menu": "통계", + "kind": "ui", + "trigger": "on_demand", + "status": "implemented", + "file": "frontend/src/features/statistics/ExternalService.tsx" + }, { "id": "ui.ai_alert", "label": "현장 AI 경보", @@ -185,5 +251,82 @@ "trigger": "on_demand", "status": "implemented", "file": "frontend/src/features/ai-operations/AIAssistant.tsx" + }, + { + "id": "ui.ai_model", + "label": "AI 모델관리", + "shortDescription": "AI 모델 배포/모니터링", + "stage": "UI", + "menu": "AI", + "kind": "ui", + "trigger": "on_demand", + "status": "implemented", + "file": "frontend/src/features/ai-operations/AIModelManagement.tsx" + }, + { + "id": "ui.mlops", + "label": "MLOps", + "shortDescription": "ML 파이프라인 운영", + "stage": "UI", + "menu": "AI", + "kind": "ui", + "trigger": "on_demand", + "status": "implemented", + "file": "frontend/src/features/ai-operations/MLOpsPage.tsx" + }, + { + "id": "ui.llm_ops", + "label": "LLM 운영", + "shortDescription": "LLM 모델 운영 관리", + "stage": "UI", + "menu": "AI", + "kind": "ui", + "trigger": "on_demand", + "status": "implemented", + "file": "frontend/src/features/ai-operations/LLMOpsPage.tsx" + }, + { + "id": "ui.mobile_service", + "label": "모바일 서비스", + "shortDescription": "현장 모바일 서비스", + "stage": "UI", + "menu": "현장", + "kind": "ui", + "trigger": "on_demand", + "status": "implemented", + "file": "frontend/src/features/field-ops/MobileService.tsx" + }, + { + "id": "ui.ship_agent", + "label": "함정 Agent", + "shortDescription": "함정 단말 에이전트", + "stage": "UI", + "menu": "현장", + "kind": "ui", + "trigger": "on_demand", + "status": "implemented", + "file": "frontend/src/features/field-ops/ShipAgent.tsx" + }, + { + "id": "ui.admin_panel", + "label": "시스템 관리", + "shortDescription": "사용자/역할/권한 관리", + "stage": "UI", + "menu": "관리", + "kind": "ui", + "trigger": "on_demand", + "status": "implemented", + "file": "frontend/src/features/admin/AdminPanel.tsx" + }, + { + "id": "ui.permissions", + "label": "권한 관리", + "shortDescription": "RBAC 트리 권한 매트릭스", + "stage": "UI", + "menu": "관리", + "kind": "ui", + "trigger": "on_demand", + "status": "implemented", + "file": "frontend/src/features/admin/AccessControl.tsx" } ] diff --git a/frontend/src/lib/i18n/locales/en/common.json b/frontend/src/lib/i18n/locales/en/common.json index 6685d58..0fb1bfd 100644 --- a/frontend/src/lib/i18n/locales/en/common.json +++ b/frontend/src/lib/i18n/locales/en/common.json @@ -3,6 +3,7 @@ "dashboard": "Dashboard", "monitoring": "Alert Monitor", "riskMap": "Risk Map", + "mapControl": "Map Control", "enforcementPlan": "Enforcement Plan", "darkVessel": "Dark Vessel", "gearDetection": "Gear Detection", diff --git a/frontend/src/lib/i18n/locales/ko/common.json b/frontend/src/lib/i18n/locales/ko/common.json index 9539842..d646cca 100644 --- a/frontend/src/lib/i18n/locales/ko/common.json +++ b/frontend/src/lib/i18n/locales/ko/common.json @@ -3,6 +3,7 @@ "dashboard": "종합 상황판", "monitoring": "경보 현황판", "riskMap": "위험도 지도", + "mapControl": "해역 관리", "enforcementPlan": "단속 계획", "darkVessel": "다크베셀 탐지", "gearDetection": "어구 탐지",