kcg-ai-monitoring/docs/data-sharing-analysis.md
htlee c0ce01eaf6 chore: 팀 워크플로우 기반 초기 프로젝트 구성
KCG AI 기반 불법조업 탐지·차단 플랫폼 프론트엔드.
React 19 + TypeScript 5.9 + Vite 8 + MapLibre + deck.gl + Zustand + Tailwind CSS.
SFR 20개 전체 UI 구현 완료, 백엔드 연동 대기.

- npm + Nexus 프록시 레지스트리 설정
- 팀 워크플로우 v1.6.1 부트스트랩 파일 배치
- .githooks (commit-msg, post-checkout)
- package.json name: kcg-ai-monitoring v0.1.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 14:11:29 +09:00

14 KiB

Mock 데이터 공유 현황 분석 및 통합 결과

최초 작성일: 2026-04-06
마지막 업데이트: 2026-04-06
대상: kcg-ai-monitoring 프론트엔드 코드베이스 전체 (31개 페이지)
상태: 통합 완료


1. 선박 데이터 교차참조

현재 동일한 선박 데이터가 여러 컴포넌트에 독립적으로 하드코딩되어 있다. 각 파일마다 동일 선박의 속성(위험도, 위치, 상태 등)이 서로 다른 형식과 값으로 중복 정의되어 있어 데이터 일관성 문제가 발생한다.

선박명 등장 파일 수 파일 목록
鲁荣渔56555 7+ Dashboard, MobileService, LiveMapView, MonitoringDashboard, EventList, EnforcementHistory, ChinaFishing
浙甬渔60651 4 Dashboard, LiveMapView, EventList, DarkVesselDetection
冀黄港渔05001 6 MobileService, LiveMapView, Dashboard, TransferDetection, EventList, GearDetection
3001함 6+ ShipAgent, MobileService, LiveMapView, Dashboard, PatrolRoute, FleetOptimization
3009함 6+ ShipAgent, MobileService, Dashboard, PatrolRoute, FleetOptimization, AIAlert
미상선박-A 5 MobileService, Dashboard, LiveMapView, MonitoringDashboard, EventList

문제점

  • 하나의 선박이 평균 5~7개 파일에 중복 정의됨
  • 선박 속성(이름, MMSI, 위치, 위험도, 상태)이 파일마다 미세하게 다를 수 있음
  • 새 선박 추가/수정 시 모든 관련 파일을 일일이 찾아 수정해야 함

2. 위험도 스케일 불일치

동일한 선박의 위험도가 페이지마다 서로 다른 스케일로 표현되고 있다.

선박명 Dashboard (risk) DarkVesselDetection (risk) MonitoringDashboard
鲁荣渔56555 0.96 (0~1 스케일) - CRITICAL (레벨 문자열)
浙甬渔60651 0.85 (0~1 스케일) 94 (0~100 정수) -
미상선박-A 0.94 (0~1 스케일) 96 (0~100 정수) -

원인 분석

  • Dashboard는 risk: 0.96 형식 (0~1 소수)
  • DarkVesselDetection은 risk: 96 형식 (0~100 정수)
  • MonitoringDashboard는 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW' 레벨 문자열
  • LiveMapView는 risk: 0.94 형식 (0~1 소수)
  • EventList는 레벨 문자열 (AlertLevel)

통합 방안

위험도를 0~100 정수 스케일로 통일하되, 레벨 문자열은 구간별 자동 매핑 유틸로 변환한다.

0~30: LOW | 31~60: MEDIUM | 61~85: HIGH | 86~100: CRITICAL

3. KPI 수치 중복

Dashboard와 MonitoringDashboard가 완전히 동일한 KPI 수치를 독립적으로 정의하고 있다.

지표 Dashboard KPI_DATA MonitoringDashboard KPI
실시간 탐지 47 47
EEZ 침범 18 18
다크베셀 12 12
불법환적 의심 8 8
추적 중 15 15
나포/검문(금일 단속) 3 3

문제점

  • 6개 KPI 수치가 두 파일에 100% 동일하게 하드코딩
  • 수치 변경 시 양쪽 모두 수정해야 함
  • Dashboard에는 prev 필드(전일 비교)가 추가로 있으나, Monitoring에는 없음

4. 이벤트 타임라인 중복

08:47~06:12 시계열 이벤트가 최소 4개 파일에 각각 정의되어 있다.

시각 Dashboard Monitoring MobileService EventList
08:47 EEZ 침범 (鲁荣渔56555) EEZ 침범 (鲁荣渔56555 외 2척) [긴급] EEZ 침범 탐지 EVT-0001 EEZ 침범
08:32 다크베셀 출현 다크베셀 출현 다크베셀 출현 EVT-0002 다크베셀
08:15 선단 밀집 경보 선단 밀집 경보 - EVT-0003 선단밀집
07:58 불법환적 의심 불법환적 의심 환적 의심 EVT-0004 불법환적
07:41 MMSI 변조 탐지 MMSI 변조 탐지 - EVT-0005 MMSI 변조
07:23 함정 검문 완료 함정 검문 완료 - EVT-0006 검문 완료
06:12 속력 이상 탐지 - - EVT-0010 속력 이상

문제점

  • 동일 이벤트의 description이 파일마다 미세하게 다름 (예: "鲁荣渔56555" vs "鲁荣渔56555 외 2척")
  • EventList에는 ID가 있으나(EVT-xxxx), 다른 파일에는 없음
  • Dashboard에는 10개, Monitoring에는 6개, EventList에는 15개로 건수도 불일치

5. 환적 데이터 100% 중복

TransferDetection.tsxChinaFishing.tsxTR-001~TR-003 환적 데이터가 완전히 동일하게 정의되어 있다.

TransferDetection.tsx:
  const transferData = [
    { id: 'TR-001', time: '2026-01-20 13:42:11', a: {name:'장저우8호'}, b: {name:'黑江9호'}, ... },
    { id: 'TR-002', time: '2026-01-20 11:15:33', ... },
    { id: 'TR-003', time: '2026-01-20 09:23:45', ... },
  ];

ChinaFishing.tsx:
  const TRANSFER_DATA = [
    { id: 'TR-001', time: '2026-01-20 13:42:11', a: {name:'장저우8호'}, b: {name:'黑江9호'}, ... },
    { id: 'TR-002', time: '2026-01-20 11:15:33', ... },
    { id: 'TR-003', time: '2026-01-20 09:23:45', ... },
  ];

문제점

  • 변수명만 다르고 (transferData vs TRANSFER_DATA) 데이터 구조와 값이 100% 동일
  • 한쪽만 수정하면 다른 쪽과 불일치 발생

6. 함정 상태 불일치

동일 함정의 상태가 페이지마다 모순되는 경우가 확인되었다.

함정 ShipAgent Dashboard PatrolRoute FleetOptimization
5001함 오프라인 (status: '오프라인') 가용 (PATROL_SHIPS에 대기로 표시) 가용 (status: '가용') 가용 (status: '가용')
3009함 온라인 (동기화 중) 검문 중 출동중 출동중
1503함 미배포 - - 정비중

문제점

  • 5001함이 ShipAgent에서는 오프라인이지만, Dashboard/PatrolRoute/FleetOptimization에서는 가용으로 표시됨 -- 직접적 모순
  • 3009함의 상태가 "온라인", "검문 중", "출동중"으로 파일마다 다름
  • 실제 운영 시 혼란을 초래할 수 있는 시나리오 불일치

7. 현재 상태: 통합 완료

아래 분석에서 식별한 모든 중복/불일치 문제를 해소하기 위해, 7개 공유 Mock 모듈 + 7개 Zustand 스토어 체계로 통합이 완료되었다.

7.1 완료된 아키텍처: mock -> store -> page

┌─────────────────────────────────────────────────────────────────────────┐
│                  src/data/mock/ (7개 공유 모듈)                          │
├───────────┬──────────┬──────────┬────────┬───────────┬────────┬────────┤
│ vessels   │ patrols  │ events   │ kpi    │ transfers │ gear   │enforce-│
│ .ts       │ .ts      │ .ts      │ .ts    │ .ts       │ .ts    │ment.ts │
└─────┬─────┴─────┬────┴─────┬────┴───┬────┴─────┬────┴───┬────┴───┬────┘
      │           │          │        │          │        │        │
      ▼           ▼          ▼        ▼          ▼        ▼        ▼
┌─────────────────────────────────────────────────────────────────────────┐
│              src/stores/ (7개 Zustand 스토어 + settingsStore)            │
├───────────┬──────────┬──────────┬────────┬───────────┬────────┬────────┤
│ vessel    │ patrol   │ event    │ kpi    │ transfer  │ gear   │enforce-│
│ Store     │ Store    │ Store    │ Store  │ Store     │ Store  │mentStr │
└─────┬─────┴─────┬────┴─────┬────┴───┬────┴─────┬────┴───┬────┴───┬────┘
      │           │          │        │          │        │        │
      ▼           ▼          ▼        ▼          ▼        ▼        ▼
┌─────────────────────────────────────────────────────────────────────────┐
│              src/features/*/ (페이지 컴포넌트)                           │
│  store.load() 호출 -> store에서 데이터 구독 -> 뷰 변환은 페이지 책임      │
└─────────────────────────────────────────────────────────────────────────┘

7.2 스토어별 소비 현황 (16개 페이지가 스토어 사용)

스토어 소비 페이지
useVesselStore Dashboard, LiveMapView, DarkVesselDetection, VesselDetail
usePatrolStore Dashboard, PatrolRoute, FleetOptimization
useEventStore Dashboard, MonitoringDashboard, LiveMapView, EventList, MobileService, AIAlert
useKpiStore Dashboard, MonitoringDashboard, Statistics
useTransferStore TransferDetection, ChinaFishing
useGearStore GearDetection
useEnforcementStore EnforcementPlan, EnforcementHistory

7.3 페이지 전용 인라인 데이터 (미통합)

아래 페이지들은 도메인 특성상 공유 mock에 포함하지 않고 페이지 전용 인라인 데이터를 유지한다.

페이지 인라인 데이터 사유
ChinaFishing COUNTERS_ROW1/2, VESSEL_LIST, MONTHLY_DATA, VTS_ITEMS 중국어선 전용 센서 카운터/통계 (다른 페이지에서 미사용)
VesselDetail VESSELS: VesselTrack[] 항적 데이터 구조가 VesselData와 다름 (주석으로 명시)
MLOpsPage 실험/배포 데이터 MLOps 전용 도메인 데이터
MapControl 훈련구역 데이터 해상사격 훈련구역 전용
DataHub 수신현황 데이터 데이터 허브 전용 모니터링
AIModelManagement 모델/규칙 데이터 AI 모델 관리 전용
AIAssistant SAMPLE_CONVERSATIONS 챗봇 샘플 대화
LoginPage DEMO_ACCOUNTS 데모 인증 정보
기타 (AdminPanel, SystemConfig 등) 각 페이지 전용 설정/관리 데이터 관리 도메인 특화

7.4 설계 원칙 (구현 완료)

  1. 위험도 0~100 통일: 모든 선박의 위험도를 0~100 정수로 통일. 레벨 문자열은 유틸 함수로 변환.
  2. 단일 원천(Single Source of Truth): 각 데이터는 하나의 mock 모듈에서만 정의하고, 스토어를 통해 접근.
  3. Lazy Loading: 스토어의 load() 메서드가 최초 호출 시 import()로 mock 데이터를 동적 로딩 (loaded 플래그로 중복 방지).
  4. 뷰 변환은 페이지 책임: mock 모듈/스토어는 원본 데이터만 제공하고, 화면별 가공(필터, 정렬, 포맷)은 각 페이지에서 수행.

7.5 Mock 모듈 상세 (참고용)

참고: 초기 분석에서 계획했던 areas.ts는 최종 구현 시 enforcement.ts(단속 이력 데이터)로 대체되었다. 해역/구역 데이터는 RiskMap, MapControl 등 각 페이지에서 전용 데이터로 관리한다.

# 모듈 파일 스토어 내용
1 data/mock/vessels.ts vesselStore 중국어선 + 한국어선 + 미상선박 마스터 (MOCK_VESSELS, MOCK_SUSPECTS)
2 data/mock/patrols.ts patrolStore 경비함정 마스터 + 경로/시나리오/커버리지
3 data/mock/events.ts eventStore 이벤트 타임라인 + 알림 데이터
4 data/mock/kpi.ts kpiStore KPI 수치 + 월별 추이
5 data/mock/transfers.ts transferStore 환적 데이터 (TR-001~003)
6 data/mock/gear.ts gearStore 어구 데이터 (불법어구 목록)
7 data/mock/enforcement.ts enforcementStore 단속 이력 + 단속 계획 데이터

8. 작업 완료 요약

모듈 상태 스토어 소비 페이지 수
vessels.ts 완료 4개 (useVesselStore)
events.ts 완료 6개 (useEventStore)
patrols.ts 완료 3개 (usePatrolStore)
kpi.ts 완료 3개 (useKpiStore)
transfers.ts 완료 2개 (useTransferStore)
gear.ts 완료 1개 (useGearStore)
enforcement.ts 완료 2개 (useEnforcementStore)

실제 작업 결과

  • Mock 모듈 생성: 7개 파일 (src/data/mock/)
  • Zustand 스토어 생성: 7개 + 1개 설정용 (src/stores/)
  • 기존 페이지 리팩토링: 16개 페이지에서 스토어 소비로 전환
  • 나머지 15개 페이지: 도메인 특화 인라인 데이터 유지 (공유 필요성 없음)

9. 결론

위 1~6절에서 분석한 6개의 심각한 중복/불일치 문제(위험도 스케일, 함정 상태 모순, KPI 중복, 이벤트 불일치, 환적 100% 중복, 선박 교차참조)는 7개 공유 mock 모듈 + 7개 Zustand 스토어 도입으로 모두 해소되었다.

달성한 효과:

  • 데이터 일관성: Single Source of Truth로 불일치 원천 차단
  • 유지보수성: 데이터 변경 시 mock 모듈 1곳만 수정
  • 확장성: 신규 페이지 추가 시 기존 store import로 즉시 사용
  • 코드 품질: 중복 인라인 데이터 제거, 16개 페이지가 스토어 기반으로 전환
  • 성능: Zustand lazy loading으로 최초 접근 시에만 mock 데이터 로딩

1~6절의 분석 내용은 통합 전 문제 식별 기록으로 보존한다.