feat: 모노레포 전환 + 백엔드 RBAC + prediction 이식 + 15화면 실데이터 연동 #3
No reviewers
레이블
레이블 없음
마일스톤 없음
담당자 없음
참여자 2명
알림
마감일
마감일이 설정되지 않았습니다.
의존성
No dependencies set.
Reference: gc/kcg-ai-monitoring#3
불러오는 중...
Reference in New Issue
Block a user
No description provided.
Delete Branch "feature/monorepo-backend-rbac"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
변경 사항
구조
백엔드 (Spring Boot 3.x + Java 21)
Prediction (Python FastAPI)
프론트엔드
배포
커밋: 23건, 파일: 376개 변경 (+25,838 / -1,870)
테스트
Phase 3-1~10: 백엔드 - pom.xml에 spring-boot-starter-aop 추가 - JPA 엔티티 12종 + Repository 9종 (User/LoginHistory/Role/UserRole/PermTree/Perm/AuditLog/AccessLog 등) - PermResolver: wing 프로젝트의 permResolver.ts를 Java로 이식 - 트리 BFS + 부모 READ 게이팅 + 다중 역할 OR 합집합 + 부모 fallback - PermissionService: Caffeine 캐싱 (TTL 10분) - JwtService + JwtAuthFilter (HttpOnly 쿠키 + Authorization 헤더 fallback) - AuthProvider 인터페이스 + PasswordAuthProvider (BCrypt + 5회 잠금) - REQUIRES_NEW + noRollbackFor로 fail_cnt 증가 보존 - AuthService + LoginAuditWriter (REQUIRES_NEW로 실패 기록 보존) - AuthController: /api/auth/login, /logout, /me - @RequirePermission 어노테이션 + PermissionAspect (메서드 권한 체크) - @Auditable 어노테이션 + AuditAspect (의사결정 자동 기록) - AccessLogFilter: 모든 HTTP 요청 비동기 기록 (BlockingQueue) - SecurityConfig 본격 도입 (CORS + JWT 필터 + 401/403 핸들러) Phase 3-10: 데모 계정 - V006__demo_accounts.sql: 5개 데모 계정 (admin/operator/analyst/field/viewer) + 역할 매핑 (PLACEHOLDER 해시) - AccountSeeder.java: 시동 시 BCrypt 해시 시드 (PLACEHOLDER만 갱신) - 데모 계정도 실제 권한, 로그인 이력, 감사로그 기록 대상 Phase 3-11: 백엔드 검증 완료 - admin/operator/viewer 로그인 성공 - 권한 매트릭스: ADMIN(49), OPERATOR(40), VIEWER(35) - 트리 상속 검증: detection READ → 자식 4개 자동 상속 - 잘못된 비밀번호 → fail_cnt 증가 + login_hist FAILED 기록 - 정상 로그인 → fail_cnt 0 초기화 - 모든 요청 access_log에 비동기 기록 V001/V002: CHAR(1) → VARCHAR(1) 변경 (Hibernate validate 호환성) Phase 3-12: 프론트엔드 연동 - services/authApi.ts: 백엔드 호출 클라이언트 (login/logout/me) - AuthContext.tsx: 백엔드 API 통합 + 트리 기반 hasPermission + 부모 fallback (예: detection:gear-detection 미등록 시 detection 검사) + 30분 세션 타임아웃 유지 - DemoQuickLogin.tsx: 데모 퀵로그인 컴포넌트 분리 + isDemoLoginEnabled() = VITE_SHOW_DEMO_LOGIN === 'true' + 데모 클릭 시에도 정상 백엔드 인증 플로우 사용 - LoginPage.tsx: 백엔드 인증 호출 + DemoQuickLogin 통합 + 에러 메시지 한국어 변환 (WRONG_PASSWORD:N, ACCOUNT_LOCKED 등) + GPKI/SSO 탭은 disabled (Phase 9 도입 예정) - frontend/.env.development: VITE_SHOW_DEMO_LOGIN=true - frontend/.env.production: VITE_SHOW_DEMO_LOGIN=true (현재 단계) - .gitignore에 frontend/.env.{development,production} 예외 추가 설계 핵심: - 데모 계정은 백엔드 DB에 실제 권한 부여 + 로그인/감사 기록 대상 - DemoQuickLogin 컴포넌트는 환경변수로 토글 가능하도록 구조 분리 - 향후 운영 배포 시 .env.production만 false로 변경하면 데모 영역 숨김 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>Phase 4-1: 운영자 워크플로우 백엔드 (자체 DB) - ParentResolution / ParentReviewLog / CandidateExclusion / LabelSession 엔티티 - Repository 4종 + DTO 5종 - ParentInferenceWorkflowService (HYBRID 패턴): - review (CONFIRM/REJECT/RESET) - parent-inference-workflow:parent-review (UPDATE) - excludeForGroup - parent-inference-workflow:parent-exclusion (CREATE) - excludeGlobal - parent-inference-workflow:exclusion-management (CREATE) [admin] - releaseExclusion (UPDATE) - createLabelSession / cancelLabelSession (CREATE/UPDATE) - ParentInferenceWorkflowController: @RequirePermission으로 권한 강제 - 모든 액션에 @Auditable AOP → audit_log + review_log 동시 기록 Phase 4-2: PermTreeController + AdminLogController - GET /api/perm-tree (모든 사용자) - 메뉴/사이드바 구성용 - GET /api/roles (admin:role-management) - 역할+권한 매트릭스 - GET /api/admin/audit-logs / access-logs / login-history Phase 4-3: iran 백엔드 프록시 (stub) - IranBackendClient: RestClient 기반, 호출 실패 시 null 반환 (graceful) - VesselAnalysisProxyController: serviceAvailable=false 응답 - PredictionProxyController: DISCONNECTED 응답 - Phase 5에서 iran 백엔드 실 연결 시 코드 변경 최소 Phase 4-4: 프론트엔드 services - parentInferenceApi.ts: 모선 워크플로우 22개 함수 - adminApi.ts: 감사로그/접근이력/로그인이력/권한트리/역할 조회 Phase 4-5: 사이드바 권한 필터링 + ProtectedRoute 권한 가드 - AuthContext.PATH_TO_RESOURCE에 신규 경로 매핑 추가 - ProtectedRoute에 resource/operation prop 추가 → 권한 거부 시 403 페이지 표시 - 모든 라우트에 권한 리소스 명시 - MainLayout 사이드바: parent-inference-workflow + admin 로그 메뉴 추가 - 사이드바 hasAccess 필터링 (이전부터 구현됨, 신규 메뉴에도 자동 적용) Phase 4-6: 신규 페이지 3종 - ParentReview.tsx: 모선 확정/거부/리셋 + 신규 등록 폼 - ParentExclusion.tsx: GROUP/GLOBAL 제외 등록 + 해제 - LabelSession.tsx: 학습 세션 생성/취소 - AuditLogs.tsx: 감사 로그 조회 - AccessLogs.tsx: 접근 이력 조회 - LoginHistoryView.tsx: 로그인 이력 조회 Phase 4-7: i18n 키 + 라우터 등록 - 한국어/영어 nav.* + group.* 키 추가 - App.tsx에 12개 신규 라우트 등록 + 권한 가드 적용 Phase 4-8: 검증 완료 - 백엔드 컴파일/기동 성공 - 프론트엔드 빌드 성공 (475ms) - E2E 시나리오: - operator 로그인 → CONFIRM 확정 → MANUAL_CONFIRMED 갱신 - operator GROUP 제외 → 성공 - operator GLOBAL 제외 → 403 FORBIDDEN (권한 없음) - operator 학습 세션 생성 → ACTIVE - admin GLOBAL 제외 → 성공 - 감사 로그 자동 기록: REVIEW_PARENT/EXCLUDE_CANDIDATE_GROUP/ LABEL_PARENT_CREATE/EXCLUDE_CANDIDATE_GLOBAL 등 14건 - 권한 트리 RBAC + AOP 정상 동작 확인 설계 핵심: - 운영자 의사결정만 자체 DB에 저장 (HYBRID) - iran 백엔드 데이터는 향후 Phase 5에서 합쳐서 표시 - @RequirePermission + @Auditable로 모든 액션 권한 + 감사 자동화 - 데모 계정으로 완전한 워크플로우 시연 가능 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>버그 수정: - AccessControl 무한 새로고침 (loadRoles의 userStats 의존성 → setUserStats 호출 → 무한 루프) loadRoles에서 항상 fetchUserStats를 같이 호출하도록 변경 백엔드 API 추가: - RoleManagementService (역할/권한 매트릭스 CRUD) - createRole / updateRole / deleteRole (built-in 보호) - updatePermissions (Y/N upsert + null 시 명시 권한 제거) - assignUserRoles (전체 교체 방식, 권한 캐시 evict) - 모든 액션에 @Auditable 자동 기록 - PermTreeController 확장: - POST /api/roles (admin:role-management:CREATE) - PUT /api/roles/{sn} (admin:role-management:UPDATE) - DELETE /api/roles/{sn} (admin:role-management:DELETE) - PUT /api/roles/{sn}/permissions (admin:permission-management:UPDATE) - PUT /api/admin/users/{id}/roles (admin:user-management:UPDATE) - DTO: RoleCreateRequest, RoleUpdateRequest, PermissionUpdateRequest, UserRoleAssignRequest - GlobalExceptionHandler: - IllegalArgumentException → 400 BAD_REQUEST - IllegalStateException → 409 CONFLICT - AccessDeniedException → 403 FORBIDDEN 프론트엔드: - lib/permission/permResolver.ts (TypeScript 미러) - resolveSingleRoleEffective: 백엔드 PermResolver와 동일 알고리즘 - 4가지 셀 상태 계산 (explicit-granted/inherited-granted/explicit-denied/forced-denied) - PermissionsPanel.tsx (트리 + R/C/U/D/E 매트릭스) - 좌측: 역할 목록 + 신규 생성 + 삭제 (built-in 보호) - 우측: 트리 표 + 셀 클릭 (Y → N → 미지정 순환) - 부모 READ 게이팅 시각화 (강제 거부 회색 비활성) - 변경된 셀만 일괄 저장 (dirty 추적) - UserRoleAssignDialog.tsx - 사용자에게 역할 다중 선택 배정 (체크박스) - adminApi.ts 확장: createRole/updateRole/deleteRole/updateRolePermissions/assignUserRoles - AccessControl.tsx 갱신: - 역할 관리 탭 → PermissionsPanel 통합 - 사용자 관리 탭 → 역할 배정 버튼 추가 (UserCog 아이콘) 검증: - 역할 생성 → TESTROLE 6번으로 추가 - 권한 매트릭스 갱신 → dashboard/monitoring READ 부여 (changed: 2) - 역할 삭제 → built-in이 아니면 OK - built-in ADMIN 삭제 시도 → 400 BAD_REQUEST (BUILTIN_ROLE_CANNOT_DELETE) - viewer에게 OPERATOR + ANALYST 다중 배정 → roles=[OPERATOR, ANALYST] → 재로그인 시 detection READ 등 자동 상속 확인 - 권한 캐시 evictAllPermissions 즉시 반영 - 프론트 빌드 통과 (533ms) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>MR 승인 (via /mr skill)