PermissionsPanel UI 수정:
- 같은 노드의 effective READ가 거부되면 C/U/D/E도 forced-denied
(READ가 안 되면 그 페이지 자체에 접근 못 하므로 다른 작업도 의미 없음)
→ 사용자가 Read를 N으로 바꾸는 즉시 같은 행의 CUDE도 회색 비활성
DataTable EXPORT 권한 가드:
- exportResource prop 추가
- useAuth().hasPermission(resource, 'EXPORT')로 export 버튼 표시 여부 결정
- AccessControl의 사용자 관리 / 감사 로그 DataTable에 적용
- exportResource="admin:user-management"
- exportResource="admin:audit-logs"
Operation 의미 명확화:
- ParentExclusion release 엔드포인트를 UPDATE → DELETE 로 재분류
(제외 항목을 "삭제(해제)"하는 의미가 더 정확)
V007 마이그레이션: 권한 트리 명칭을 사이드바 i18n 라벨과 일치
- Level 0 13개 + Level 1 32개 노드의 rsrc_nm을 nav.* / group.* 라벨에 맞춤
- 예: "어구탐지" → "어구 탐지", "Dark Vessel" → "다크베셀 탐지"
- 권한 관리 트리를 운영자가 사이드바와 동일한 명칭으로 이해 가능
API의 RCUDE 적용 현황 (참고):
- READ 19건, UPDATE 8건, CREATE 4건, DELETE 1→2건
- EXPORT는 백엔드 엔드포인트 별도 없음 → 프론트 EXPORT 가드로 처리
- 향후 백엔드 CSV/Excel 생성 API 추가 시 EXPORT operation으로 가드
검증:
- V007 마이그레이션 자동 적용 + Started in 3.272s
- Level 0 13개 모두 사이드바 라벨로 변경됨 확인
- 프론트 빌드 통과 (599ms)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Phase 6: iran 백엔드 실연결 + 화면 연동
- application.yml: app.iran-backend.base-url=https://kcg.gc-si.dev
- IranBackendClient: RestClient 확장 (Accept JSON header, getAs<T>)
- VesselAnalysisProxyController: HYBRID 합성 로직 추가
- GET /api/vessel-analysis: stats + 7423건 분석 결과 통과
- GET /api/vessel-analysis/groups: 476건 그룹 + 자체 DB resolution 합성
- GET /api/vessel-analysis/groups/{key}/detail
- GET /api/vessel-analysis/groups/{key}/correlations
- 권한: detection / detection:gear-detection (READ)
- 프론트 services/vesselAnalysisApi.ts: 타입 + 필터 헬퍼
(filterDarkVessels, filterSpoofingVessels, filterTransshipSuspects)
- features/detection/RealGearGroups.tsx: 어구/선단 그룹 실시간 표시
(FLEET/GEAR_IN_ZONE/GEAR_OUT_ZONE 필터, 통계 5종, 운영자 결정 합성 표시)
- features/detection/RealVesselAnalysis.tsx: 분석 결과 모드별 렌더
- mode='dark' / 'spoofing' / 'transship' / 'all'
- 위험도순 정렬 + 6개 통계 카드 + 해역/Dark/Spoofing/전재 표시
- 화면 연동:
- GearDetection → RealGearGroups 추가
- DarkVesselDetection → RealDarkVessels + RealSpoofingVessels
- ChinaFishing(dashboard) → RealAllVessels
- TransferDetection → RealTransshipSuspects
Phase 7: 시스템 상태 대시보드
- features/monitoring/SystemStatusPanel.tsx
- 3개 서비스 카드: KCG Backend / iran 백엔드 / Prediction
- 위험도 분포 (CRITICAL/HIGH/MEDIUM/LOW) 4개 박스
- 30초 자동 폴링
- MonitoringDashboard 최상단에 SystemStatusPanel 추가
Phase 8: AI 채팅 기반 (SSE는 Phase 9 인증 후)
- 프론트 services/chatApi.ts: sendChatMessage (graceful fallback)
- 백엔드 PredictionProxyController.chat 추가
- POST /api/prediction/chat
- 권한: ai-operations:ai-assistant (READ)
- 현재 stub 응답 (iran chat 인증 토큰 필요)
- AIAssistant 페이지에 백엔드 호출 통합
(handleSend → sendChatMessage → 응답 표시 + graceful 메시지)
검증:
- 백엔드 컴파일/기동 성공 (Started in 5.2s)
- iran 프록시: 471개 그룹, 7423건 분석 결과 정상 통과
- 프론트 빌드 통과 (502ms)
- E2E 시나리오:
- admin 로그인 → /api/vessel-analysis/groups → 476건 + serviceAvailable=true
- /api/prediction/chat → stub 응답 (Phase 9 안내)
설계 원칙:
- iran 백엔드 미연결 시 graceful degradation (serviceAvailable=false + 빈 데이터)
- HYBRID 합성: prediction 후보 + 자체 DB의 운영자 결정을 백엔드에서 조합
- 향후 iran 인증 토큰 통과 후 SSE 채팅 활성화
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
백엔드 API 추가:
- UserManagementController (admin:user-management)
- GET /api/admin/users : 사용자 목록 + 역할 코드
- GET /api/admin/users/stats : 상태별/역할별/인증방식별 카운트
- POST /api/admin/users/{id}/unlock : 잠금 해제 (@Auditable USER_UNLOCK)
- PUT /api/admin/users/{id}/status : 상태 변경 (@Auditable USER_STATUS_CHANGE)
- 권한 캐시 evict 자동 호출
- AdminStatsController (admin:audit-logs/access-logs/login-history READ)
- GET /api/admin/stats/audit : 전체/24시간/실패/액션별/시간별 통계
- GET /api/admin/stats/access : 전체/24시간/4xx/5xx/평균응답/인기경로
- GET /api/admin/stats/login : 성공률/사용자별/일별 추세
프론트엔드 연결:
- adminApi.ts 확장: AdminUser/UserStats/AuditStats/AccessStats/LoginStats
타입 정의 + 사용자/통계 fetch 함수
- AccessControl.tsx (시스템 관리 > 권한 관리):
- 4개 탭 모두 백엔드 연결
- 역할 관리: GET /api/roles + 사용자별 카운트 표시
- 사용자 관리: GET /api/admin/users + DataTable + 잠금 해제 버튼
+ 통계 카드 4개 (총/활성/잠금/비활성)
- 감사 로그: GET /api/admin/audit-logs + GET /api/admin/stats/audit
+ 액션별 분포 Badge + 통계 카드
- 보안 정책: 실제 백엔드 동작과 일치하도록 갱신
- AuditLogs.tsx: 메트릭 카드 4개 + 액션별 분포
- AccessLogs.tsx: 메트릭 카드 5개 (전체/24시간/4xx/5xx/평균) + Top 10 경로 테이블
- LoginHistoryView.tsx: 메트릭 카드 5개 + 사용자별 + 일별 추세
검증:
- /api/admin/users → 5명 (admin/operator/analyst/field/viewer)
- /api/admin/users/stats → byRole, byStatus, byProvider 카운트
- /api/admin/stats/audit → total 15, 액션 6종, hourly 추세
- /api/admin/stats/login → success 80%, byUser top, daily 추세
- 프론트엔드 빌드 통과 (493ms)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Phase 1: 모노레포 디렉토리 구조 구축
- 기존 React 프로젝트를 frontend/ 디렉토리로 이동 (git mv)
- backend/ 디렉토리 생성 (Phase 2에서 Spring Boot 초기화)
- database/migration/ 디렉토리 생성 (Phase 2에서 Flyway 마이그레이션)
- 루트 .gitignore에 frontend/, backend/ 경로 반영
- 루트 CLAUDE.md를 모노레포 가이드로 갱신
- Makefile 추가 (dev/build/lint 통합 명령)
- frontend/vite.config.ts에 /api → :8080 백엔드 proxy 설정
- .githooks/pre-commit을 모노레포 구조에 맞게 갱신
(frontend/ 변경 시 frontend/ 내부에서 검증)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- /init-project로 팀 표준 워크플로우 적용 (CLAUDE.md, settings.json hooks, pre-commit)
- Prettier + eslint-config-prettier 설치 및 ESLint 연동
- format/format:check npm 스크립트 추가
- vite-env.d.ts 추가 (import.meta.env 타입 정의)
- pre-commit 차단 해제: GearDetection/BaseChart 타입 캐스팅
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>