# SR System — 기능 명세서 (Functional Specification) **버전:** 2.0.0 **최종 업데이트:** 2026-06-12 **대상 시스템:** SM/SI 파견 직원 통합 지원 및 IT 자산 관리 포털 (HQ 헬프데스크) --- ## 1. 시스템 개요 ### 1.1 목적 파견 직원 라이프사이클/커리어 관리, 현장 기술 문제 본사(SR) 지원, IT 자산 생명주기 추적 통합 ### 1.2 기대 효과 - 본사-파견지 간 정보 간극 해소 - 운영 효율성 극대화 - IT 자산 추적 및 비용 관리 투명화 ### 1.3 기술 스택 | 계층 | 기술 | 버전 | |------|------|-------| | Frontend | Next.js (App Router) | 16.x | | | TypeScript | 5.x | | | Tailwind CSS | 4.x | | | Zustand (State Management) | 5.x | | Backend | Spring Boot | 3.2.x | | | Java | 17 | | | Spring Data JPA | - | | | Spring Security | - | | Database | PostgreSQL | 15 | | Infra | Docker + Docker Compose | - | | | Nginx Proxy Manager | - | | | Cloudflare Tunnel | - | --- ## 2. 역할 및 권한 체계 (RBAC) ### 2.1 역할 정의 | 역할 | 코드 | 설명 | |------|------|------| | 일반 사용자 | `EMPLOYEE` | 파견지 현장 직원. 포트폴리오 관리, 업무 보고서 작성, SR 티켓 신청, 장비/교육 조회 | | 본사 관리자 | `MANAGER` | 영업/인사/자산 담당. 직원 현황 관리, 보고 결재, SR 티켓 처리, 장비 인벤토리 제어 | | 최고 관리자 | `ADMIN` | 전역 계정 관리, 접근 권한 부여, 공통 코드/메뉴 권한/시스템 설정 동적 제어 | ### 2.2 역할별 접근 가능 메뉴 | 메뉴 | 경로 | EMPLOYEE | MANAGER | ADMIN | |------|------|:--------:|:-------:|:-----:| | Dashboard | `/` | ✅ | ✅ | ✅ | | SR Issues | `/issues` | ✅ | ✅ | ✅ | | Dispatch | `/dispatch` | ✅ | ✅ | ✅ | | ITAM (Assets) | `/itam` | ❌ | ✅ | ✅ | | Employees | `/employees` | ❌ | ✅ | ✅ | | Projects | `/projects` | ❌ | ✅ | ✅ | | Work Reports | `/work-reports` | ✅ | ✅ | ✅ | | Report Review | `/work-reports/review` | ❌ | ✅ | ✅ | | Daily Report | `/daily-reports` | ✅ | ✅ | ✅ | | Training | `/training` | ✅ | ✅ | ✅ | | Calendar | `/calendar` | ✅ | ✅ | ✅ | | Profile | `/profile` | ✅ | ✅ | ✅ | | Portfolio | `/profile/portfolio` | ✅ | ✅ | ✅ | | Settings (Admin) | `/settings/*` | ❌ | ❌ | ✅ | > 메뉴 권한은 `/settings/menus`에서 **동적 변경 가능**. 위 표는 기본값. --- ## 3. 메뉴 트리 ``` MAIN MENU ├── Dashboard / [ALL] ├── SR Issues /issues [ALL] │ └── Ticket Detail /issues/[id] [ALL] ├── Dispatch /dispatch [ALL] │ └── Manage /dispatch/manage [MANAGER+] ITAM (Assets) [MANAGER+] ├── Asset Hub /itam ├── Register /itam/register [단건 + Excel 배치] ├── Check-out /itam/checkout ├── Check-in /itam/checkin EMPLOYEES [MANAGER+] └── Detail Modal /employees (클릭 시) PROJECTS [MANAGER+] ├── List /projects WORK REPORTS [ALL] ├── My Reports /work-reports ├── Report Review /work-reports/review [MANAGER+] DAILY REPORT /daily-reports [ALL] TRAINING /training [ALL] CALENDAR /calendar [ALL] PROFILE [ALL] ├── My Profile /profile └── Portfolio /profile/portfolio ADMIN (Settings) [ADMIN] ├── Codes /settings/codes [공통 코드 + 그룹] ├── Accounts /settings/accounts [직원 CRUD] ├── Batch Employees /settings/batch/employees [Excel 일괄 등록] ├── System /settings/system [SLA/Parking/JWT] ├── Notification /settings/notification ├── Audit Log /settings/audit └── Menu Perms /settings/menus [역할별 메뉴 제어] ``` --- ## 4. 도메인별 상세 기능 ### 4.1 인사 관리 (Employee) #### 4.1.1 개요 직원 정보를 관리합니다. ADMIN은 모든 권한을 가지며 MANAGER는 조회만 가능합니다. 전화번호는 AES-256-GCM으로 암호화되어 저장되며, Click-to-Reveal 방식으로만 열람 가능합니다. #### 4.1.2 API 엔드포인트 | HTTP | 경로 | 설명 | 권한 | |------|------|------|------| | GET | `/api/v1/employees` | 직원 목록 조회 (페이징 + 상태 필터) | MANAGER+ | | GET | `/api/v1/employees/{empId}` | 직원 단건 조회 | EMPLOYEE+ | | GET | `/api/v1/employees/me` | 현재 사용자 프로필 조회 | EMPLOYEE+ | | GET | `/api/v1/employees/search` | 직원 검색 자동완성 (디바운싱 300ms) | MANAGER+ | | POST | `/api/v1/employees` | 직원 생성 | ADMIN | | PUT | `/api/v1/employees/{empId}` | 기본 정보 수정 (이름/이메일/전화번호/입사일/직급/사수/프로필사진) | ADMIN | | PUT | `/api/v1/employees/{empId}/status` | 재직 상태 변경 (ACTIVE/ON_LEAVE/RESIGNED + 퇴사일) | ADMIN | | PUT | `/api/v1/employees/{empId}/role` | 권한 변경 (ADMIN/MANAGER/EMPLOYEE) | ADMIN | | PUT | `/api/v1/employees/{empId}/dispatch-status` | 파견 상태 변경 (WAITING/DISPATCHED) | MANAGER+ | | DELETE | `/api/v1/employees/{empId}` | 직원 삭제 (Soft Delete) | ADMIN | | PUT | `/api/v1/employees/{empId}/profile-image` | 프로필 이미지 URL 저장 | EMPLOYEE+ | | POST | `/api/v1/employees/{empId}/request-phone` | **전화번호 열람 요청** (사유 입력 → 감사 로그 기록) | EMPLOYEE+ | | PUT | `/api/v1/employees/me/password` | 비밀번호 변경 (현재 비밀번호 필요) | EMPLOYEE+ | | PUT | `/api/v1/employees/{empId}/reset-password` | 비밀번호 초기화 (ADMIN 전용) | ADMIN | | POST | `/api/v1/employees/batch` | 직원 일괄 등록 (Excel .xlsx) | ADMIN | | GET | `/api/v1/employees/batch/template` | 직원 일괄 등록 템플릿 다운로드 | ADMIN | | GET | `/api/v1/employees/approvers` | 승인자 목록 조회 (MANAGER/ADMIN) | EMPLOYEE+ | #### 4.1.3 Employee 필드 | 필드 | 타입 | 설명 | 공개 범위 | |------|------|------|:---------:| | `empId` | Long | PK, 자동 증가 | 공개 | | `loginId` | String | 사번 (내부 식별자) | ADMIN | | `name` | String | 이름 | 공개 | | `email` | String | 이메일 (로그인 ID) | MANAGER+ | | `phone` | String | **AES-256-GCM 암호화** 🔒 | Click-to-Reveal | | `roleCode` | Enum | ADMIN/MANAGER/EMPLOYEE | 공개 | | `empStatus` | Enum | ACTIVE/ON_LEAVE/RESIGNED | 공개 | | `dispatchStatus` | Enum | WAITING/DISPATCHED | 공개 | | `joinedDate` | Date | 입사일 | MANAGER+ | | `leftDate` | Date | 퇴사일 | ADMIN | | `position` | String | 직급 (사원/주임/대리/과장/차장/부장/이사) | MANAGER+ | | `managerId` | Long | 사수 (직속 상사 empId) | ADMIN | | `backupManagerId` | Long | 부사수 (대리 결재 empId) | ADMIN | | `profileImage` | String | 프로필 이미지 URL | 공개 | | `emergencyContacts` | List | 비상연락망 (복수) | 본인 + MANAGER+ | #### 4.1.4 전화번호 Click-to-Reveal Flow ``` 화면: 🔒 전화번호 보기 → 클릭 → 사유 입력 dialog ("업무 연락 필요") → POST /employees/{id}/request-phone { reason: "..." } → tb_audit_log INSERT (action=VIEW_PHONE, actor, target, reason, ip) → 전화번호 복호화되어 5초간 표시 → 자동 숨김 ``` #### 4.1.5 일괄 등록 템플릿 헤더 | 컬럼 | 필수 | 예시 | |------|:----:|------| | 로그인ID | ✅ | `EMP-001` | | 이름 | ✅ | `홍길동` | | 이메일 | | `hong@sr-system.com` | | 전화번호 | | `010-0000-0000` | | 권한 | | `EMPLOYEE` | | 재직상태 | | `ACTIVE` | | 파견상태 | | `WAITING` | | 직급 | | `STAFF` | | 입사일 | | `2024-01-01` | > 비밀번호는 `batch1234!`로 자동 설정됩니다. --- ### 4.2 SR 티켓 (Ticket) #### 4.2.1 티켓 카테고리 | 카테고리 | 설명 | 프로젝트 필수 | 승인 필요 | |----------|------|:------------:|:---------:| | `BUG` | 버그 리포트 | ✅ 선택 | ❌ | | `FEATURE` | 기능 요청 | ✅ 선택 | ❌ | | `SUPPORT` | 기술 지원 | ✅ 선택 | ❌ | | `QA` | QA 이슈 | ✅ 선택 | ❌ | | `GENERAL` | 일반 문의 | ❌ | ✅ | | `VACATION` | 휴가 신청 | ❌ | ✅ | | `EXPENSE` | 비용 청구 | ❌ | ✅ | | `EQUIPMENT_REQUEST` | 장비 요청 | ❌ | ✅ | #### 4.2.2 티켓 상태 흐름 ``` 일반 티켓 (BUG/FEATURE/SUPPORT/QA): OPEN → ASSIGNED → IN_PROGRESS → RESOLVED → CLOSED ↕ (앞/뒤로 자유 이동 가능, MANAGER+) 승인 티켓 (VACATION/EXPENSE/EQUIPMENT_REQUEST/GENERAL): PENDING_APPROVAL → APPROVED → (해당 업무 진행) → REJECTED (사유 포함) APPROVED → PENDING_APPROVAL (승인 취소, MANAGER+) REJECTED → PENDING_APPROVAL (재오픈, MANAGER+) ``` #### 4.2.3 API 엔드포인트 | HTTP | 경로 | 설명 | 권한 | |------|------|------|------| | GET | `/api/v1/tickets` | 티켓 목록 (EMPLOYEE는 본인만) | EMPLOYEE+ | | GET | `/api/v1/tickets/{id}` | 티켓 상세 | EMPLOYEE+ | | POST | `/api/v1/tickets` | 티켓 생성 | EMPLOYEE+ | | PUT | `/api/v1/tickets/{id}/status` | 상태 변경 (앞/뒤로) | MANAGER+ | | PUT | `/api/v1/tickets/{id}/assign` | 담당자 배정 | MANAGER+ | | PUT | `/api/v1/tickets/{id}/resolve` | 해결 처리 + 노트 | MANAGER+ | | DELETE | `/api/v1/tickets/{id}` | 티켓 삭제 | MANAGER+ | | GET | `/api/v1/tickets/pending` | 결재 대기 목록 (내가 사수/부사수) | MANAGER+ | | POST | `/api/v1/tickets/{id}/approve` | 승인 (PENDING_APPROVAL→APPROVED) | MANAGER+ | | POST | `/api/v1/tickets/{id}/reject` | 반려 (PENDING_APPROVAL→REJECTED + 사유) | MANAGER+ | | POST | `/api/v1/tickets/{id}/reopen` | 재오픈 (APPROVED/REJECTED→PENDING_APPROVAL) | MANAGER+ | | GET | `/api/v1/tickets/{id}/comments` | 댓글 목록 | EMPLOYEE+ | | POST | `/api/v1/tickets/{id}/comments` | 댓글 등록 (CLOSED 불가) | EMPLOYEE+ | #### 4.2.4 승인 워크플로우 ``` [요청자 EMPLOYEE] 1. New Ticket → Category: 휴가 신청 선택 2. "승인자" 드롭다운에 MANAGER 목록 표시 3. 사수(필수) + 부사수(선택) 지정 4. 생성 → status=PENDING_APPROVAL, approverId=지정한 사수 [승인자 MANAGER] 1. SR Issues 페이지 → "Pending Approvals" 탭 2. 내가 사수/부사수인 PENDING_APPROVAL 목록 확인 3. 티켓 상세 → [Approve] or [Reject (사유 입력)] 4. Approve → status=APPROVED 5. Reject → status=REJECTED + resolutionNote=사유 [요청자 EMPLOYEE] 1. 티켓 상세에서 승인/반려 상태 확인 2. APPROVED → 해당 업무 진행 3. REJECTED → 사유 확인 후 MANAGER에게 재오픈 요청 ``` --- ### 4.3 IT 자산 관리 (ITAM) #### 4.3.1 장비 상태 | 상태 | 설명 | |------|------| | `AVAILABLE` | 지급 가능 (재고) | | `IN_USE` | 사용 중 (직원 할당됨) | | `REPAIRING` | 수리 중 | | `RETIRED` | 폐기 | | `LOST` | 분실 | #### 4.3.2 장비 유형 | 유형 | 설명 | |------|------| | `LAPTOP` | 노트북 | | `MONITOR` | 모니터 | | `TEST_DEVICE` | 테스트 장비 | | `ACCESSORY` | 액세서리 | #### 4.3.3 API 엔드포인트 | HTTP | 경로 | 설명 | 권한 | |------|------|------|------| | GET | `/api/v1/equipment` | 장비 목록 (필터: 유형/상태/제조사) | MANAGER+ | | GET | `/api/v1/equipment/summary` | 상태별 카운트 | MANAGER+ | | GET | `/api/v1/equipment/{id}` | 장비 단건 | MANAGER+ | | POST | `/api/v1/equipment` | 장비 생성 | MANAGER+ | | PUT | `/api/v1/equipment/{id}` | 장비 수정 | MANAGER+ | | DELETE | `/api/v1/equipment/{id}` | 장비 삭제 (Soft Delete) | MANAGER+ | | POST | `/api/v1/equipment/{id}/assign` | 장비 지급 (낙관적 락) | MANAGER+ | | PUT | `/api/v1/equipment/{id}/return` | 장비 반납 | MANAGER+ | | GET | `/api/v1/equipment/{id}/assignments` | 지급/반납 이력 | MANAGER+ | | GET | `/api/v1/equipment/{id}/maintenances` | 유지보수 이력 | MANAGER+ | | POST | `/api/v1/equipment/{id}/maintenance` | 유지보수 추가 | MANAGER+ | | POST | `/api/v1/equipment/{id}/images` | 장비 이미지 추가 | MANAGER+ | | DELETE | `/api/v1/equipment/{id}/images/{idx}` | 장비 이미지 삭제 | MANAGER+ | | POST | `/api/v1/equipment/batch` | 장비 일괄 등록 (Excel) | MANAGER+ | | GET | `/api/v1/equipment/batch/template` | 장비 배치 템플릿 다운로드 | MANAGER+ | | GET | `/api/v1/employees/{empId}/equipment` | 직원별 지급 장비 조회 | EMPLOYEE+ | #### 4.3.4 장비 일괄 등록 템플릿 | 컬럼 | 필수 | 예시 | |------|:----:|------| | 장비유형 | ✅ | `LAPTOP` | | 제조사 | ✅ | `Samsung` | | 모델명 | ✅ | `Galaxy Book Pro` | | 시리얼번호 | ✅ | `SN-2024-0001` | | 자산코드 | ✅ | `NB-001` | | 제원정보 | | `i7/16GB/512GB` | | 구매일 | | `2024-01-15` | --- ### 4.4 업무 보고 (Report) | HTTP | 경로 | 설명 | 권한 | |------|------|------|------| | GET | `/api/v1/reports` | 보고서 목록 (EMPLOYEE=본인만) | EMPLOYEE+ | | GET | `/api/v1/reports/{id}` | 보고서 상세 | EMPLOYEE+ | | POST | `/api/v1/reports` | 보고서 작성 | EMPLOYEE+ | | PUT | `/api/v1/reports/{id}/status` | 상태 변경 (DRAFT→SUBMITTED) | EMPLOYEE | | PUT | `/api/v1/reports/{id}/review` | 결재 처리 (APPROVED/REJECTED) | MANAGER+ | | DELETE | `/api/v1/reports/{id}` | 보고서 삭제 | EMPLOYEE+ | | GET | `/api/v1/reports/summary` | 결재 요약 (상태별 개수) | MANAGER+ | | GET | `/api/v1/reports/sr-auto-complete` | SR 자동 바인딩 | EMPLOYEE+ | ### 4.5 포트폴리오 (Portfolio) | HTTP | 경로 | 설명 | 권한 | |------|------|------|------| | GET | `/api/v1/employees/{id}/portfolio` | 경력 기술서 조회 | EMPLOYEE+ | | GET | `/api/v1/employees/{id}/dispatch-histories` | 파견 이력 목록 | EMPLOYEE+ | | PUT | `/api/v1/employees/{id}/dispatch-histories/{did}/achievements` | 성과 기록 수정 | EMPLOYEE+ | #### 포트폴리오 페이지 (`/profile/portfolio`) 경력 기술서를 타임라인 형식으로 조회합니다. MANAGER/ADMIN은 직원 검색을 통해 타인의 포트폴리오도 조회할 수 있습니다. | 섹션 | 내용 | |------|------| | 요약 카드 | Total Projects, Current, SR Tickets, Reports | | 타임라인 | 프로젝트별 컬러 닷 + 카드 | | Tech Stack | 기술 스택 태그 | | Performed Tasks | 수행 업무 | | Achievements | 성과 기록 (inline 편집 가능) | | Resolved SR Tickets | 해당 프로젝트 해결 SR | | Reports | 업무 보고서 링크 | --- ### 4.6 공통 코드 (Common Code) 동적 드롭다운 값을 관리합니다. ADMIN 전용 설정 페이지에서 CRUD 가능. | HTTP | 경로 | 설명 | 권한 | |------|------|------|------| | GET | `/api/v1/common-codes` | 코드 목록 (groupCode 필터) | EMPLOYEE+ | | GET | `/api/v1/common-codes/groups` | 그룹 목록 | EMPLOYEE+ | | POST | `/api/v1/common-codes` | 코드 생성 | ADMIN | | PUT | `/api/v1/common-codes/{id}` | 코드 수정 | ADMIN | | DELETE | `/api/v1/common-codes/{id}` | 코드 삭제 | ADMIN | | POST | `/api/v1/common-codes/groups` | 그룹 생성 | ADMIN | | PUT | `/api/v1/common-codes/groups/{gc}` | 그룹 수정 | ADMIN | | DELETE | `/api/v1/common-codes/groups/{gc}` | 그룹 삭제 (코드 없을 때만) | ADMIN | #### 코드 그룹 목록 | 그룹 코드 | 용도 | |-----------|------| | `EMP_ROLE` | 권한 (ADMIN/MANAGER/EMPLOYEE) | | `EMP_STATUS` | 재직상태 (ACTIVE/ON_LEAVE/RESIGNED) | | `DISPATCH_STATUS` | 파견상태 (WAITING/DISPATCHED) | | `PROJECT_TYPE` | 프로젝트 유형 (SI/SM/MIGRATION) | | `CONTRACT_TYPE` | 계약 유형 (TURN_KEY/MM) | | `PROJECT_STATUS` | 프로젝트 상태 | | `WORK_LOCATION` | 근무지 유형 (ON_SITE/REMOTE/HYBRID) | | `TICKET_CATEGORY` | 티켓 카테고리 (8종) | | `TICKET_PRIORITY` | 우선순위 (LOW/NORMAL/HIGH/CRITICAL) | | `TICKET_STATUS` | 티켓 상태 (8종) | | `EQUIPMENT_TYPE` | 장비 유형 (4종) | | `EQUIPMENT_STATUS` | 장비 상태 (5종) | | `MAINTENANCE_TYPE` | 유지보수 유형 | | `REPORT_TYPE` | 보고서 유형 (DAILY/WEEKLY/MONTHLY/RETURN) | | `REPORT_STATUS` | 보고서 상태 (DRAFT/SUBMITTED/APPROVED/REJECTED) | | `TRAINING_STATUS` | 교육 상태 (NOT_STARTED/ONGOING/COMPLETED) | | `POSITION` | 직급 (STAFF/SENIOR/ASSISTANT_MANAGER/MANAGER/DEPUTY_GENERAL_MANAGER/GENERAL_MANAGER/DIRECTOR) | --- ### 4.7 메뉴 권한 (Menu Permission) 역할별 메뉴 접근 제어를 설정합니다. ADMIN 전용. | HTTP | 경로 | 설명 | 권한 | |------|------|------|------| | GET | `/api/v1/menu-permissions` | 전체 메뉴 권한 조회 (24개) | EMPLOYEE+ | | PUT | `/api/v1/menu-permissions/{menuKey}` | 메뉴 권한 수정 (allowedRoles) | ADMIN | #### 설정 가능 메뉴 (24개) | 메뉴 키 | 메뉴명 | Parent | |---------|--------|--------| | `dashboard` | Dashboard | - | | `issues` | SR Issues | - | | `dispatch` | Dispatch | - | | `itam` | ITAM (Assets) | - | | `itam-hub` | Asset Hub | itam | | `itam-register` | Register | itam | | `itam-checkout` | Check-out | itam | | `itam-checkin` | Check-in | itam | | `employees` | Employees | - | | `projects` | Projects | - | | `reports` | Work Reports | - | | `reports-review` | Report Review | - | | `training` | Training | - | | `calendar` | Calendar | - | | `profile` | Profile | - | | `profile-portfolio` | Portfolio | profile | | `settings` | Admin | - | | `settings-codes` | Codes | settings | | `settings-accounts` | Accounts | settings | | `settings-batch-employees` | Batch Employees | settings | | `settings-system` | System | settings | | `settings-notification` | Notification | settings | | `settings-audit` | Audit Log | settings | | `settings-menus` | Menu Permissions | settings | --- ### 4.8 시스템 설정 (System Config) | HTTP | 경로 | 설명 | 권한 | |------|------|------|------| | GET | `/api/v1/admin/config` | 전체 설정 조회 | ADMIN | | GET | `/api/v1/admin/config/{key}` | 설정 단건 조회 | ADMIN | | PUT | `/api/v1/admin/config/{key}` | 설정 업데이트 | ADMIN | | PUT | `/api/v1/admin/config/batch` | 일괄 업데이트 | ADMIN | #### 설정 키 목록 | 키 | 기본값 | 설명 | |-----|--------|------| | `sla_check_interval` | 3600000 | SLA 체크 간격 (ms) | | `sla_excluded_statuses` | RESOLVED,CLOSED | SLA 제외 상태 | | `parking_enabled` | false | Parking 모드 | | `parking_weekday_start` | 20:00 | Parking 시작 | | `parking_weekday_end` | 08:00 | Parking 종료 | | `parking_weekends` | true | 주말 Parking | | `jwt_access_expiration` | 3600000 | Access Token (ms) | | `jwt_refresh_expiration` | 604800000 | Refresh Token (ms) | | `notification_slack_enabled` | false | Slack 알림 | | `notification_email_enabled` | false | Email 알림 | | `file_upload_max_size` | 10485760 | 업로드 최대 크기 (bytes) | --- ### 4.9 알림 (Notification) | HTTP | 경로 | 설명 | 권한 | |------|------|------|------| | GET | `/api/v1/notifications` | 내 알림 목록 | EMPLOYEE+ | | GET | `/api/v1/notifications/unread` | 안읽은 알림 카운트 | EMPLOYEE+ | | PUT | `/api/v1/notifications/{id}/read` | 읽음 처리 | EMPLOYEE+ | #### 알림 유형 | 유형 | 발생 조건 | |------|----------| | `TICKET_ASSIGNED` | 티켓 배정 시 | | `REPORT_SUBMITTED` | 보고서 제출 시 | | `REPORT_APPROVED` | 보고서 승인 시 | | `SLA_WARNING` | SLA 초과 시 | | `EQUIPMENT_MAINTENANCE` | 장비 유지보수 등록 시 | --- ### 4.10 감사 로그 (Audit Log) | HTTP | 경로 | 설명 | 권한 | |------|------|------|------| | GET | `/api/v1/notifications` | 시스템 활동 로그 | ADMIN | | - | `tb_audit_log` 테이블 | VIEW_PHONE 액션 기록 | SYSTEM | #### 감사 로그 구조 | 컬럼 | 설명 | 예시 | |------|------|------| | `action` | 액션 유형 | `VIEW_PHONE` | | `target_type` | 대상 유형 | `EMPLOYEE` | | `target_id` | 대상 ID | `52` | | `actor_id` | 실행자 ID | `1` (Admin) | | `reason` | 사유 | `업무 연락 필요` | | `ip_address` | IP 주소 | `192.168.1.100` | | `created_at` | 일시 | `2026-06-12 10:30:00` | --- ## 5. 보안 ### 5.1 인증 (JWT) | 항목 | 설정 | |------|------| | 알고리즘 | HMAC-SHA384 | | Access Token 만료 | 1시간 (설정 가능) | | Refresh Token 만료 | 7일 (설정 가능) | | 저장 위치 | localStorage + Cookie | ### 5.2 비밀번호 | 항목 | 설정 | |------|------| | 알고리즘 | BCrypt | | 인코딩 | Spring Security PasswordEncoder | ### 5.3 전화번호 암호화 | 항목 | 설정 | |------|------| | 알고리즘 | AES-256-GCM | | 구현 | JPA `AttributeConverter` | | 키 저장 | `application.yml` / 환경변수 `PHONE_ENCRYPTION_KEY` | | IV | 12바이트 랜덤, 매 암호화마다 새로 생성 | | 인코딩 | IV + Ciphertext → Base64 | ### 5.4 접근 제어 | 계층 | 방식 | |------|------| | API | `@PreAuthorize` (hasRole) | | 메뉴 | 사이드바 권한 필터링 (`menu-permissions` API) | | 데이터 | EMPLOYEE는 본인 데이터만 조회 가능 | | Soft Delete | 모든 엔티티 `is_deleted = 'Y'/'N'` | --- ## 6. API 응답 규격 ### 성공 ```json { "success": true, "message": "요청이 성공적으로 처리되었습니다.", "data": { ... } } ``` ### 실패 (비즈니스 예외) ```json { "success": false, "message": "이미 결재가 완료된 보고서는 수정할 수 없습니다.", "errorCode": "RPT_ERR_001", "data": null } ``` ### 오류 코드 매트릭스 | ErrorCode | HTTP Status | 메시지 | |-----------|:-----------:|--------| | `EMP_ERR_001` | 400 | 퇴사 처리된 직원 정보는 수정할 수 없습니다 | | `EMP_ERR_002` | 409 | 이미 사용 중인 로그인 ID 입니다 | | `RPT_ERR_001` | 400 | 결재 완료 보고서는 수정/삭제할 수 없습니다 | | `TCK_ERR_001` | 400 | 종료된 티켓은 댓글/수정이 불가능합니다 | | `TCK_ERR_004` | 400 | 처리할 수 없는 상태입니다 | | `EQP_ERR_001` | 400 | 지급 가능한 재고 상태가 아닙니다 | | `SYS_ERR_001` | 409 | 동시성 충돌 - 다시 시도해 주세요 | | `COD_ERR_001` | 404 | 공통코드를 찾을 수 없습니다 | --- ## 7. 배치/스케줄러 | 작업 | 주기 | 설명 | |------|------|------| | SLA 만료 체크 | 매시간 | `due_date` 초과 + `slaWarnFlag='N'` 티켓 → 알림 발송 + `slaWarnFlag='Y'` 갱신 | | Parking 모드 | 설정 시간 | 주말/야간 시스템 접근 제한 | --- ## 8. 데이터 모델 개요 ### 8.1 엔티티 목록 (18개) | 엔티티 | 테이블 | 설명 | |--------|--------|------| | `Employee` | `tb_employee` | 직원 (전화번호 AES 암호화) | | `EmployeeEmergencyContact` | `tb_employee_emergency_contact` | 비상연락망 | | `Project` | `tb_project` | 프로젝트 | | `DispatchHistory` | `tb_dispatch_history` | 파견 이력 | | `Ticket` | `tb_ticket` | SR 티켓 (승인 워크플로우 포함) | | `TicketComment` | `tb_ticket_comment` | 티켓 댓글 | | `Equipment` | `tb_equipment` | 장비 마스터 | | `EquipmentAssignment` | `tb_equipment_assignment` | 장비 지급/반납 이력 | | `EquipmentMaintenance` | `tb_equipment_maintenance` | 장비 유지보수 | | `Report` | `tb_report` | 업무 보고서 | | `TrainingProgress` | `tb_training_progress` | 교육 진도 | | `CommonCode` | `tb_common_code` | 공통 코드 | | `CommonCodeGroup` | `tb_common_code_group` | 공통 코드 그룹 | | `Notification` | `tb_notification` | 알림 | | `SystemConfig` | `tb_system_config` | 시스템 설정 (키-값) | | `MenuPermission` | `tb_menu_permission` | 메뉴 권한 | | `AuditLog` | `tb_audit_log` | 감사 로그 | | `WeeklyPlan` | `tb_weekly_plan` | 주간 계획 | ### 8.2 공통 베이스 엔티티 (`BaseEntity`) | 컬럼 | 타입 | 설명 | |------|------|------| | `created_at` | TIMESTAMP | 생성 일시 | | `updated_at` | TIMESTAMP | 수정 일시 | | `is_deleted` | CHAR(1) | Soft Delete 플래그 ('Y'/'N') | --- ## 9. 프론트엔드 페이지 목록 (24개) | 경로 | 페이지 | 설명 | |------|--------|------| | `/` | Dashboard | 대시보드 (요약 카드 + 빠른 보고서 작성) | | `/login` | Login | 로그인 (email + password) | | `/issues` | SR Issues | 칸반보드 + 티켓 생성 모달 | | `/issues/[id]` | Ticket Detail | 티켓 상세 + 타임라인 + 승인 | | `/dispatch` | Dispatch | 파견 관리 + 포트폴리오 타임라인 | | `/dispatch/manage` | Dispatch Manage | 파견 배정 관리 | | `/itam` | Asset Hub | 장비 대시보드 + 인벤토리 | | `/itam/register` | Register | 장비 단건/배치 등록 | | `/itam/checkout` | Check-out | 장비 지급 | | `/itam/checkin` | Check-in | 장비 반납 | | `/itam/history/[id]` | History | 장비 이력 | | `/employees` | Employees | 직원 목록 + 상세 모달 | | `/projects` | Projects | 프로젝트 관리 | | `/work-reports` | Work Reports | 업무 보고서 | | `/work-reports/review` | Report Review | 보고서 결재 | | `/daily-reports` | Daily Report | 일일 보고서 | | `/training` | Training | 교육 현황 | | `/calendar` | Calendar | 통합 일정 | | `/profile` | Profile | 내 프로필 + 비상연락망 | | `/profile/portfolio` | Portfolio | 경력 기술서 | | `/settings/codes` | Codes | 공통 코드 + 그룹 관리 | | `/settings/accounts` | Accounts | 계정 관리 | | `/settings/batch/employees` | Batch Employees | 직원 일괄 등록 | | `/settings/system` | System | 시스템 설정 | | `/settings/notification` | Notification | 알림 설정 | | `/settings/audit` | Audit Log | 감사 로그 | | `/settings/menus` | Menu Perms | 메뉴 권한 관리 | --- ## 10. 비기능 요구사항 | 항목 | 요구사항 | |------|---------| | 보안 | BCrypt + JWT + AES-256-GCM + Click-to-Reveal + 감사 로그 | | 데이터 무결성 | Soft Delete + 낙관적 락 | | 응답 시간 | 페이지 3초 이내, 검색 자동완성 500ms 이내 | | 알림 | 이벤트 기반 비동기 (EDA) | | SLA | Spring Batch 시간당 스캔 | | 암호화 | 전화번호 AES-256-GCM, 컬럼레벨 암호화 | | 배포 | Docker Compose + Portainer + GitHub Webhook 자동 배포 |