# 11. 요구사항 추적표 (requierment.xlsx 기반) > 원본: `d:\sc\requierment.xlsx` — 기능 86개 + 비기능 17개 + 확인필요사항 7건 > 수정일: 2026-03-25 --- ## 0. 기능 요구사항 전체 매핑표 > PH1 Y/N은 Excel "Phase 1 (Y/N)" 컬럼 기준 ### User Registration (No.1~7) | No. | Category | 요구사항 요약 | PH1 | 계획서 | 비고 | |-----|----------|-------------|:---:|--------|------| | 1 | 기준정보 | SAP SF HR Master 파일 업로드 | Y | 08-sap | PH1 수동 업로드 | | 2 | 기준정보 | 내부 인력 필드 (사번~Part 5레벨) Read-only | Y | 02-db | users 테이블 | | 3 | 기준정보 | 정기 배치 자동 업데이트 | N | 08-sap | PH2: 안정화 후 | | 4 | 기준정보 | 외주 인력 파일 업로드 (표준 템플릿) | Y | 07-api | 확인필요사항#1 | | 5 | 기준정보 | 외주 인력 개별 입력창 | N | - | PH2: 정책 미확정 | | 6 | 기준정보 | 파일 업로드는 SA가 관리 | Y | 07-api | SA 권한 | | 7 | 기준정보 | 외부 사용자 최소 정보 (회사명~내부담당자) | Y | 02-db | users 테이블 확장 | ### Login (No.8~16) | No. | Category | 요구사항 요약 | PH1 | 계획서 | 비고 | |-----|----------|-------------|:---:|--------|------| | 8 | 로그인 | 내부 사용자 ID/PW 로그인 | Y | wbx-spring | AuthController | | 9 | 로그인 | 외부 사용자 2Way 인증 | N | - | PH2: 외주 포털 후 | | 10 | 로그인 | ID/PW 찾기 기능 | Y | wbx-spring | PasswordPolicy | | 11 | 로그인 | ID = 사번 (오션 표준) | Y | 02-db | employee_number | | 12 | 로그인 | PW 정책 (대소문자+특수문자) | Y | wbx-spring | PasswordPolicy | | 13 | 로그인 | PW 입력 시 "*" 마스킹 | Y | FE 기본 | - | | 14 | 로그인 | PW 주기적 재설정 | Y | wbx-spring | expiryDays | | 15 | 로그인 | PW 5회 실패 시 재설정 프로세스 | Y | wbx-spring | maxFailedAttempts | | 16 | Interface | SSO (Entra ID) 적용 | Y | wbx-spring | SsoSuccessHandler | ### User Home (No.17~24) | No. | Category | 요구사항 요약 | PH1 | 계획서 | 비고 | |-----|----------|-------------|:---:|--------|------| | 17 | 권한관리 | 권한별 홈 페이지 라우팅 | Y | 07-api | 확인필요사항#2 | | 18 | 사용자등급 | 6종 역할 (SA/PM/PCM/PTK/DL/User) | Y | 02-db | roles 테이블 | | 19 | 사용자등급 | SA 전체 기능 컨트롤 | N | - | PH2: 보안 감사용 | | 20 | 사용자등급 | PM 권한 (WBS/Member/승인) | Y | 05-approval | | | 21 | 사용자등급 | PCM/PTK 권한 (WBS Task 배정) | Y | 04-wbs | | | 22 | 사용자등급 | User 할당 Project/WBS만 조회 | Y | 03-timesheet | | | 23 | 사용자등급 | DL 결재 권한 (조직원 Timesheet) | Y | 05-approval | DL 정책 TBD | | 24 | 사용자등급 | SA 접속/Activity 로그 관리 | N | - | PH2: 보안 감사 | ### Project Registration (No.25~30) | No. | Category | 요구사항 요약 | PH1 | 계획서 | 비고 | |-----|----------|-------------|:---:|--------|------| | 25 | PJT Creation | 프로젝트 생성 절차 (PM/PCM→SA 승인) | Y | 07-api | | | 26 | PJT Creation | Project Type 3종 (Non/Other/EPC) | Y | 02-db | project_type | | 27 | PJT Creation | Canonical WBS 파일 업로드→PM 승인 | Y | 04-wbs | | | 28 | PJT Edit | 변경 WBS 신규 파일 업로드 | Y | 04-wbs | | | 29 | PJT Edit | WBS 버전 관리/비교 | N | 04-wbs | PH1-2차 | | 30 | PJT Edit | 기존 WBS 시수 조회 | N | - | PH2: No.29 연계 | ### WBS Upload (No.31~41) | No. | Category | 요구사항 요약 | PH1 | 계획서 | 비고 | |-----|----------|-------------|:---:|--------|------| | 31 | P6 WBS | WBS L5 + Activity 정보 접수 | Y | 04-wbs | P6WbsParser | | 32 | P6 WBS | 월단위 Snapshot 비교 | N | - | PH2: 고도화 | | 33 | Canonical WBS | 표준 WBS, Project별 수정 불가 | Y | 04-wbs | | | 34 | Canonical WBS | WBS 5레벨 구조 (L1~L5) | Y | 04-wbs | | | 35 | Canonical WBS | WBS Upload 5단계 절차 | Y | 04-wbs | | | 36 | WBS Versioning | Effective 날짜 기준 버전 등록 | Y | 04-wbs | | | 37 | WBS Versioning | 종결/폐기 Mapping 사용불가 처리 | Y | 04-wbs | | | 38 | TEAL | TEAL 선정 기준 (MH투입/관리/측정 가능) | Y | 04-wbs | | | 39 | TEAL | TEAL 선정 및 Upload 4단계 | Y | 04-wbs | | | 40 | TEAL Versioning | 버전 정보 (Version/Date/승인/변경Log) | Y | 04-wbs | | | 41 | TEAL Versioning | 과거 TT는 입력 당시 버전 유지 | Y | 04-wbs | | ### Resource Assignment (No.42~50) | No. | Category | 요구사항 요약 | PH1 | 계획서 | 비고 | |-----|----------|-------------|:---:|--------|------| | 42 | Availability | SA가 기본 입력 기준 수정 | N | - | PH2: 확인필요사항#4 | | 43 | Availability | 1일 최소 근무시간 8시간 | Y | 03-timesheet | RuleEngine | | 44 | Availability | Activity 최소 1개 이상 | Y | 03-timesheet | | | 45 | Availability | 주 최대 52시간, Location별 다름 | Y | 03-timesheet | RuleEngine | | 46 | Availability | 초과근무/휴게시간 규칙 | N | - | PH2: 세부 규칙 UI | | 47 | Project Assign | Discipline → Project Assign | Y | 07-api | | | 48 | Project Assign | Non-Project는 별도 Assign 없이 전체 | Y | 03-timesheet | | | 49 | Availability | Project별 Location/Job_Role 설정 | N | - | PH2: Unit Rate | | 50 | WBS Assign | WBS-Discipline 자동 Assign | N | - | PH2: 방식 미확정 | ### My Project Setup (No.51~54) | No. | Category | 요구사항 요약 | PH1 | 계획서 | 비고 | |-----|----------|-------------|:---:|--------|------| | 51 | Assigned PJT | Assign된 Project 정보 확인 | Y | 07-api | /my-projects | | 52 | Assigned PJT | 프로젝트 상세 정보 조회 | Y | 07-api | | | 53 | Assigned PJT | 권한별 정보 제한 | Y | wbx-spring | RBAC | | 54 | Activity Setup | Favorite/Default 설정 | N | - | PH2: 편의 기능 | ### Time Sheet (No.55~69) | No. | Category | 요구사항 요약 | PH1 | 계획서 | 비고 | |-----|----------|-------------|:---:|--------|------| | 55 | Non-Project | Overhead 최소 입력 (Type/Activity/Hour) | Y | 03-timesheet | NON_PROJECT | | 56 | Non-Project | Overhead Type 4종 (수정 가능) | Y | 02-db | overhead_types | | 57 | Non-Project | TEAL 기반 Activity 선택 | Y | 03-timesheet | | | 58 | Non-Project | Resource Assignment 규칙 적용 | Y | 03-timesheet | RuleEngine | | 59 | Non-Project | WBS/Project 정보 입력 불가 | Y | 03-timesheet | | | 60 | Other Project | Tender/Pre-FEED/FEED/Internal 포함 | Y | 03-timesheet | OTHER_PROJECT | | 61 | Other Project | 최소 입력 (PJT/WBS L2~4/Activity/Hour) | Y | 03-timesheet | | | 62 | Other Project | P6 연동 불필요, Canonical WBS 사용 | Y | 04-wbs | | | 63 | Other Project | Project별 Bench Marking | N | - | PH2: 데이터 축적 후 | | 64 | EPC Project | EPC 필수 입력 (PJT/WBS L2~5/Activity/Hour) | Y | 03-timesheet | PH1-2차: Revision | | 65 | EPC Project | Location/Role/진행률 추가 입력 | N | - | PH2: Unit Rate | | 66 | EPC Project | P6 WBS 비노출, 할당 WBS만 선택 | Y | 03-timesheet | | | 67 | 공통 | Remark 입력 (선택) | Y | 03-timesheet | | | 68 | 공통 | Excel 템플릿 제공 + 임포트 | Y | 03-timesheet | | | 69 | 공통 | 일자별 Activity별 1행, 합계 표시 | Y | 03-timesheet | | ### Approval (No.70~75+) | No. | Category | 요구사항 요약 | PH1 | 계획서 | 비고 | |-----|----------|-------------|:---:|--------|------| | 70 | Process | Daily 입력, Weekly 승인, Alert | Y | 05-approval | | | 71 | Process | User→DL→PM 3단계 승인 | Y | 05-approval | | | 72 | Process | 승인/반려 + Comment | Y | 05-approval | | | 73 | Process | 일괄 승인 | Y | 05-approval | | | 74 | Process | 승인 이력 조회 | Y | 05-approval | | | 75 | Process | 초과 기준 하이라이트 (min/max/OT) | Y | 05-approval | PH1-2차 | ### Reporting (No.76~86) | No. | Category | 요구사항 요약 | PH1 | 계획서 | 비고 | |-----|----------|-------------|:---:|--------|------| | 76 | RCP연계 | RCP 연계 Plan vs Actual 분석 | N | - | PH2: RCP 시스템 미개발 | | 77 | RCP연계 | RCP 연계 Capacity Gap 분석 | N | - | PH2: RCP 미개발 | | 78 | RCP연계 | RCP 연계 Productivity Trend 분석 | N | - | PH2: RCP 미개발 | | 79 | Version | WBS 버전 관리 + 이력 조회 | N | 04-wbs | PH2: 이력 조회 UI 협의 | | 80 | Interface | Cognite 연계 데이터 Export | N | 08-sap | PH2: Extractor 서버 필요 | | 81 | WBS 검토 | P6 WBS vs Canonical WBS Mis-Align 검토 | N | - | PH2: 운영 데이터 축적 후 | | 82 | 일반 보고서 | Project별 투입 Manhour 분석 | Y | 06-report | PH1 기본 리포트 | | 83 | 일반 보고서 | Canonical WBS Level별 Manhour 분석 | Y | 06-report | PH1 기본 리포트 | | 84 | 일반 보고서 | Discipline별 생산성 분석 | N | - | PH2: Progress Rate 필요 | | 85 | 일반 보고서 | Phase별 Manhour 비율 분석 | N | 06-report | PH1-2차 또는 PH2 협의 | | 86 | 일반 보고서 | Non-Project Manhour 비율 분석 | N | 06-report | PH1-2차 또는 PH2 협의 | ### Non-Functional (NF.1~17) | NF | Category | 요구사항 요약 | 계획서 | |----|----------|-------------|--------| | 1 | Cloud/Server | Azure Hybrid Security Zone | 09-devops | | 2 | Cloud/Server | Azure IaaS 기반 | 09-devops | | 3 | Security/Server | HIWARE, V3, Secuver TOS | 09-devops | | 4 | Security/DB | Cubeone (TDE), Dbsafer (Proxy) | 09-devops | | 5 | Security/Cloud | Defender + Analytics | 09-devops | | 6 | Security/정보보호 | 보안 취약점 점검 (웹/모바일/서버/소스) | 09-devops | | 7 | Security/정보보호 | 개인정보 보호 정책 준수 | 09-devops | | 8 | Monitoring/Server | onTune (SMS), MCCS (HA) | 09-devops | | 9 | Monitoring/DB | Maxguage (DB 모니터링) | 09-devops | | 10 | Monitoring/App | Jennifer (APM) | 09-devops | | 11 | Auth/Internal | Entra ID SSO | wbx-spring | | 12 | Auth/External | 2Way 인증 (외부 사용자) | PH2 | | 13 | Interface/HR | SAP BTP CPI (SuccessFactors) | 08-sap | | 14 | Interface/P6 | P6 파일 기반 연동 (물리 I/F 없음) | 04-wbs | | 15 | Interface/Cognite | Extractor 서버 필요 | PH2 | | 16 | Architecture | HA 구성 (Web, WAS) | 09-devops | | 17 | Architecture | 백업 전략 (시스템 복구) | 09-devops | --- ## 1. HR Master Data 필드 상세 (No.1~2) SAP SuccessFactors에서 업로드되는 내부 인력 정보 필드. **Read-only**로 관리. > **No.2 원문 (Eng)**: Employee Number, Employee Name, Business Unit (LV1), Division (LV2), Department (LV3), Discipline/Team (LV4), Part (LV5), Attendance Type, Individual Job Code ```sql -- V1 보완: users 테이블 컬럼 (SAP SF 필드 매핑) ALTER TABLE users ADD COLUMN employee_number VARCHAR(20); -- 사번 = 로그인 ID (No.11) ALTER TABLE users ADD COLUMN business_unit VARCHAR(100); -- LV1: Business Unit ALTER TABLE users ADD COLUMN division VARCHAR(100); -- LV2: Division ALTER TABLE users ADD COLUMN department VARCHAR(100); -- LV3: Department ALTER TABLE users ADD COLUMN discipline_team VARCHAR(100); -- LV4: Discipline/Team ALTER TABLE users ADD COLUMN part VARCHAR(100); -- LV5: Part (★ 5레벨) ALTER TABLE users ADD COLUMN attendance_type VARCHAR(50); -- 근태유형 (SAP SF) ALTER TABLE users ADD COLUMN individual_job_code VARCHAR(50); -- 개인 직무코드 (SAP SF) ALTER TABLE users ADD COLUMN job_role VARCHAR(100); -- Job Role ALTER TABLE users ADD COLUMN grade VARCHAR(50); -- Grade/직급 ALTER TABLE users ADD COLUMN start_date DATE; -- 입사일 ALTER TABLE users ADD COLUMN end_date DATE; -- 종료일 ALTER TABLE users ADD COLUMN company_name VARCHAR(200); -- 외주: 회사명 (No.7) ALTER TABLE users ADD COLUMN org_unit VARCHAR(200); -- 외주: 조직 정보 (No.7) ALTER TABLE users ADD COLUMN internal_contact VARCHAR(200); -- 외주: 내부 담당자 정보 (No.7) -- 조직 계층 테이블 (HR 데이터 정규화) — 5레벨 CREATE TABLE org_hierarchy ( id BIGINT IDENTITY PRIMARY KEY, level INT NOT NULL, -- 1=BU, 2=Division, 3=Department, 4=Discipline/Team, 5=Part code VARCHAR(50) NOT NULL, name VARCHAR(200) NOT NULL, parent_id BIGINT REFERENCES org_hierarchy(id), is_active BIT DEFAULT 1, UNIQUE (level, code) ); ``` ### JPA Entity 보완 ```java @Entity @Table(name = "users") public class User extends BaseEntity { // ... 기존 필드 ... @Column(length = 20, unique = true) private String employeeNumber; // 사번 = 로그인 ID (No.11) // 조직 4레벨 (SAP SF 기준) private String businessUnit; // LV1 private String division; // LV2 private String department; // LV3 private String section; // LV4 private String discipline; private String jobRole; private String grade; private LocalDate startDate; private LocalDate endDate; // 외주 전용 (No.7) private String companyName; private String internalContact; @Enumerated(EnumType.STRING) @Column(length = 20) private EmploymentType employmentType; // INTERNAL, SUBCONTRACTOR } ``` --- ## 2. Non-Project Overhead 유형 상세 (No.55~59) 요구사항 No.56에서 명시된 Overhead Type. **SA가 수정 가능**해야 함. ```java // 시스템 초기 Overhead Types (No.56 — 영문 원본 기준, 향후 수정 가능) // ★ 기존 계획서의 9종 → 원본 4종으로 수정 public enum OverheadType { TRAINING("Training", "Employee education and competency development activities"), SYSTEM_PROCESS_DEV("System and Process Development", "System and process development and improvement activities"), ORG_OPERATION("Organizational Operation", "Internal organizational administrative tasks"), CORPORATE_INITIATIVE("Corporate Initiative or Strategy", "Executive-led corporate strategic initiatives"); // ★ Leave, Sick Leave 등은 Non-Project TEAL Activity로 별도 관리 // ★ SA가 추가 가능 (DB 테이블 기반) } ``` **보완**: Overhead Type을 Enum 대신 **DB 테이블**로 관리 (SA 수정 가능 요건) ```sql CREATE TABLE overhead_types ( id BIGINT IDENTITY PRIMARY KEY, code VARCHAR(50) NOT NULL UNIQUE, name VARCHAR(200) NOT NULL, description NVARCHAR(500), is_active BIT DEFAULT 1, sort_order INT DEFAULT 0, created_at DATETIME2 DEFAULT GETDATE() ); -- 초기 데이터 INSERT INTO overhead_types (code, name, description) VALUES ('TRAINING', 'Training', 'Employee education and competency development'), ('SYS_PROC_DEV', 'System and Process Development', 'System and process development and improvement'), ('ORG_OPERATION', 'Organizational Operation', 'Internal organizational administrative tasks'), ('CORPORATE_INITIATIVE','Corporate Initiative or Strategy', 'Executive-led corporate strategic initiatives'); -- ★ 추가 유형은 SA가 화면에서 등록 (No.56: "향후 수정 가능") ``` **Non-Project TEAL**: Admin이 Non-Project 전용 TEAL을 설정 → 사용자는 이 TEAL에서만 Activity 선택 (No.57) --- ## 3. Canonical WBS 레벨 구조 상세 (No.33~34) 요구사항 No.34에서 명시된 정확한 구조: ``` Level 1: Project Level 2: Phase (Engineering, Procurement, Construction, Commissioning, etc.) Level 3: Asset or Area ★ 기존 계획 "Discipline/Category" → 수정 Level 4: Work or Discipline ★ 기존 계획 "Sub-Category/Work Package" → 수정 Level 5: Deliverable, Package, or Material ★ Engineering and SCM only (No.34) ``` > **주의**: Level 5는 Engineering/SCM Phase에서만 사용. Construction 등은 Level 4까지만. ### Project Type별 WBS 적용 (No.26) | Project Type | WBS Level | 비고 | |-------------|-----------|------| | **EPC Project** | Level 2~5 | P6 WBS 연동, Canonical 매핑 | | **Other Project** (Tender/Pre-FEED/FEED/IDD) | Level 2~4 | P6 연동 불필요, Canonical만 (No.62) | | **Non-Project** (Overhead) | 없음 | WBS/Project 입력 불가 (No.59) | ```sql -- Project Type Enum 보완 -- project_type: 'EPC', 'TENDER', 'PRE_FEED', 'FEED', 'INTERNAL_DESIGN', 'NON_PROJECT' ALTER TABLE projects ADD COLUMN project_type VARCHAR(30) NOT NULL DEFAULT 'EPC'; -- Project Type별 WBS 레벨 제한 CREATE TABLE project_type_config ( id BIGINT IDENTITY PRIMARY KEY, project_type VARCHAR(30) NOT NULL UNIQUE, min_wbs_level INT DEFAULT 2, max_wbs_level INT DEFAULT 5, requires_p6 BIT DEFAULT 0, requires_teal BIT DEFAULT 1, description NVARCHAR(200) ); INSERT INTO project_type_config VALUES (1, 'EPC', 2, 5, 1, 1, 'EPC Project - P6 연동, Level 5까지'), (2, 'TENDER', 2, 4, 0, 1, 'Tender/Bidding'), (3, 'PRE_FEED', 2, 4, 0, 1, 'Pre-FEED'), (4, 'FEED', 2, 4, 0, 1, 'FEED'), (5, 'INTERNAL_DESIGN', 2, 4, 0, 1, 'Internal Design Development'), (6, 'NON_PROJECT', 0, 0, 0, 0, 'Non-Project/Overhead'); ``` --- ## 4. 권한 매트릭스 (Sheet1 기반) 요구사항 원본 Sheet1의 기능별 역할 접근 권한: | Category | Sub Category | SA(Admin) | PM | PL(LE)/GM/DL | Engineer/Staff | |----------|-------------|-----------|-----|--------------|----------------| | **Time Sheet** | Time Sheet Register | O | O | O | O | | | Excel Import | O | O | O | - | | **Project Mgmt** | Project Registration | O | O | - | - | | | Project Information | O | - | - | - | | **User Mgmt** | User Registration | O | O | O | - | | | User Information | O | O | O | O | | | ID/Password Mgmt | O | O | O | O | | **WBS Mgmt** | WBS Upload | O | - | - | - | | | WBS Version Mgmt | O | - | - | - | | | TEAL Management | O | - | - | - | | **Resource Assign** | Resource Availability | O | O | - | - | | | Project Assign | O | - | - | - | | | WBS Assign | O | O | - | - | | | Task(TEAL) Assign | O | O | O | - | | **My Project** | Assignment Status | O | O | O | O | | | Favorite Setting | O | O | O | O | | **Approval** | Approval Request | O | O | O | O | | | Approval Management | O | O | O | - | | | Approval History | O | O | O | O | | **Report** | Project MH Analysis | O | O | O | - | | | WBS MH Analysis | O | O | O | - | | | Discipline MH Analysis | O | O | O | - | | | Overhead MH Analysis | O | O | O | - | | | WBS Change Review | O | O | O | - | ### Spring Security 보완 ```java // 역할 코드 보완: PL(LE)/GM = DL (Discipline Lead) // 원본에서 Admin = SA, PL(LE)/GM = DL 매핑 // 권한 테이블 (DB 기반, SA가 수정 가능) CREATE TABLE role_permissions ( id BIGINT IDENTITY PRIMARY KEY, role_id BIGINT NOT NULL REFERENCES roles(id), module VARCHAR(50) NOT NULL, -- TIMESHEET, PROJECT, USER, WBS, RESOURCE, APPROVAL, REPORT sub_module VARCHAR(50) NOT NULL, -- REGISTER, IMPORT, UPLOAD, etc. can_access BIT DEFAULT 0, UNIQUE (role_id, module, sub_module) ); // @PreAuthorize에서 DB 기반 권한 체크 @Component("perm") public class PermissionChecker { public boolean check(String module, String subModule) { Long userId = SecurityUtils.getCurrentUserId(); return rolePermissionRepository.hasAccess(userId, module, subModule); } } // Controller에서 사용 @GetMapping("/api/reports/project-hours") @PreAuthorize("@perm.check('REPORT', 'PROJECT_MH_ANALYSIS')") public ProjectHoursReport getProjectHours(...) { ... } ``` --- ## 5. Resource Assignment 모듈 (누락 보완) 요구사항 No.42~50: 기존 계획서에 상세 누락된 모듈. ### 핵심 기능 | No. | 기능 | 설명 | |-----|------|------| | 42 | 기본 입력 기준 수정 | SA가 Timesheet 기본 설정 변경 가능 | | 43 | 1일 최소 8시간 | 규칙 엔진 | | 44 | Activity 최소 1개 | 빈 Timesheet 제출 불가 | | 45 | 주 최대 52시간 | Location(국가)별 다르게 지정 가능 | | 46 | 초과근무/휴게시간 규칙 | 규칙 지정 가능 | | 47 | Project별 Assign | Discipline마다 0~N개 프로젝트 배정 | | 48 | Non-Project 별도 Assign 불필요 | 모든 사용자 사용 가능 | | 49 | Location/Job_Role 설정 | 프로젝트별 사용 가능한 Location, Role 설정 (PH2) | | 50 | WBS Discipline 자동 Assign | PCM/PTK가 표준 템플릿으로 투입인력 일괄 등록 | ```sql -- 근무 규칙 설정 (SA 관리, No.42~46) CREATE TABLE work_rules ( id BIGINT IDENTITY PRIMARY KEY, rule_name VARCHAR(100) NOT NULL, location_code VARCHAR(50), -- 국가/지역별 규칙 (NULL=전체 기본값) min_daily_hours DECIMAL(4,2) DEFAULT 8.00, max_daily_hours DECIMAL(4,2) DEFAULT 10.00, max_weekly_hours DECIMAL(5,2) DEFAULT 52.00, overtime_threshold DECIMAL(4,2) DEFAULT 8.00, -- 초과근무 기준 break_time_minutes INT DEFAULT 60, -- 휴게시간 is_default BIT DEFAULT 0, is_active BIT DEFAULT 1, created_at DATETIME2 DEFAULT GETDATE() ); INSERT INTO work_rules (rule_name, location_code, min_daily_hours, max_weekly_hours, is_default) VALUES ('Korea Standard', 'KR', 8.00, 52.00, 1), ('Offshore Standard', 'OFFSHORE', 8.00, 60.00, 0); -- 프로젝트 인력 배정 (No.47~48) CREATE TABLE project_assignments ( id BIGINT IDENTITY PRIMARY KEY, project_id BIGINT NOT NULL REFERENCES projects(id), user_id BIGINT NOT NULL REFERENCES users(id), discipline VARCHAR(100), assigned_by BIGINT REFERENCES users(id), -- PM/PCM/PTK start_date DATE, end_date DATE, is_active BIT DEFAULT 1, created_at DATETIME2 DEFAULT GETDATE(), UNIQUE (project_id, user_id) ); -- WBS별 Discipline 배정 (No.50) CREATE TABLE wbs_discipline_assignments ( id BIGINT IDENTITY PRIMARY KEY, canonical_wbs_id BIGINT NOT NULL REFERENCES canonical_wbs(id), discipline VARCHAR(100) NOT NULL, assigned_by BIGINT REFERENCES users(id), created_at DATETIME2 DEFAULT GETDATE(), UNIQUE (canonical_wbs_id, discipline) ); ``` ### REST API 추가 ``` # Resource Assignment (02-database-schema, 08-api-spec 보완) GET /api/work-rules 근무 규칙 목록 (SA) PUT /api/work-rules/{id} 근무 규칙 수정 (SA) GET /api/projects/{id}/assignments 프로젝트 인력 배정 목록 POST /api/projects/{id}/assignments 인력 배정 (PM/PCM/PTK) POST /api/projects/{id}/assignments/upload 인력 배정 일괄 업로드 (No.50) DELETE /api/projects/{id}/assignments/{userId} 인력 배정 해제 GET /api/projects/{id}/wbs-disciplines WBS-Discipline 배정 현황 POST /api/projects/{id}/wbs-disciplines WBS-Discipline 배정 ``` --- ## 6. 비기능 요구사항 — 한화오션 표준 보안 SW 상세 (NF.3~10) ### 서버 보안 (NF.3) | SW | 용도 | Azure 대응 | |----|------|-----------| | **HIWARE** | 서버 접근 제어 | Azure Bastion + HIWARE Agent | | **V3** (AhnLab) | 서버 백신 | VM에 V3 Agent 설치 | | **Secuver TOS** | 서버 보안 (파일 무결성 등) | VM에 Agent 설치 | ### DB 보안 (NF.4) | SW | 용도 | Azure 대응 | |----|------|-----------| | **Cubeone** | DB 암호화 | Azure SQL TDE + Cubeone (컬럼 레벨) | | **Dbsafer** | DB 접근 제어 | Dbsafer Proxy 구성 | ### 클라우드 보안 (NF.5) | SW | 용도 | |----|------| | **Azure Defender** | 위협 탐지 | | **Azure Log Analytics** | 보안 이벤트 분석 | ### 모니터링 (NF.8~10) | SW | 용도 | 대상 | |----|------|------| | **onTune** | SMS (서버 모니터링) | VM CPU/Memory/Disk | | **MCCS** | HA (Windows 클러스터) | WAS 이중화 (※ Linux → N/A) | | **Maxguage** | DB 모니터링 | Azure SQL 성능 분석 | | **Jennifer** | WAS 모니터링 | Spring Boot Tomcat APM | ### application-prod.yml 보완 ```yaml # Jennifer APM 연동 (NF.10) # JVM Args: -javaagent:/opt/jennifer/agent.java/jennifer.jar # Actuator + Prometheus (Maxguage 보완/대안) management: endpoints: web: exposure: include: health,info,metrics,prometheus health: db: enabled: true redis: enabled: true ``` ### 보안성 심의 체크리스트 (NF.6~7) ``` □ 웹 애플리케이션 취약점 점검 (OWASP Top 10) □ 모바일 앱 보안 점검 (해당 시 PH2) □ 서버/네트워크 인프라 보안 점검 □ 소스코드 보안 점검 (SonarQube / Fortify) □ 모의해킹 (Penetration Testing) □ 개인정보 보호 관리 (개인정보보호법 준수) □ 한화그룹 보안 표준 준수 확인 ``` --- ## 7. Timesheet 상세 보완 ### Remark 필드 (No.67) ``` 필수 입력 아님. 필요 시 아래 내용 입력: - Change Order Number - Deliverable Number - 기타 참고 사항 ``` **보완**: Change Order 관련 MH 관리를 위해 별도 Activity 분리 입력 방안 검토 필요 ### Timesheet 행 구조 (No.69) ``` 1행 = 1일자 × 1 Activity ------------------------------------------------------ 번호 | 날짜 | WBS L1~5 | Activity | Manhour | Remark ------------------------------------------------------ 1 | 4/7 | E.01.03 | Detail | 4.0 | 2 | 4/7 | E.01.04 | Review | 4.0 | ← 동일 날짜, 다른 Activity ------------------------------------------------------ 일 합계: 8.0h 전체 합계: Summary Row 표시 ``` ### Excel Import 정확한 컬럼 (No.68) ``` 표준 템플릿 컬럼: | Date | Project Code | WBS L2 | WBS L3 | WBS L4 | WBS L5 | Activity | Hours | Remark | ``` --- ## 8. 확인필요사항 (7건) 추적 원본 Excel 하단의 "확인필요사항" — 프로젝트 착수 전 고객 확정 필요. | # | 영역 | 내용 | 현재 상태 | 계획 반영 | |---|------|------|----------|----------| | 1 | User Registration | 파트너사 및 외주 인력 관리 정책 — 파트너 마스터 연계 여부 | 별도 파트너 마스터 연계 미고려. 전사 데이터 표준화 후 검토 | PH1-1: 파일 업로드만 | | 2 | User Home | 사용자 관리규정 및 권한관리 정책 — User Type별 업무범위 | No.18 참조 (기능 기반 역할 정의 확정) | plans/wbx-spring/02-auth-jwt-sso.md 반영 | | 3 | WBS Upload | WBS별 Resource Plan 방식 — TT에서 투입시수 규모 세팅 여부 | TT에서 WBS별 투입시수 규모 세팅 | 05-wbs-teal.md 반영 | | 4 | Resource Assignment | PM 인력 배치 시 해당 인력 스케줄 확인 및 참여 확인 절차 | PM/PCM/PTK가 WBS별 Discipline 선정 → 각 Discipline별 투입인력 선정 후 리스트 제출 | Resource Assignment 모듈 | | 5 | Time Sheet (EPC) | C단계(Construction) 시수 입력 및 관리 방안 | **C단계 시수관리 대상 제외**. EPU 담당자의 C단계 관리업무만 TT에 등록 | 04-timesheet.md 주석 | | 6 | Approval | 각 업무요건별 승인 절차 — 대상 Action 도출, 프로세스 설계 | User → DL → PM 3단계 확정 | 06-approval.md 반영 | | 7 | Resource Assignment | Project Assignment 프로세스 상세 | SA가 Project 생성 → PM/PCM이 인력 배정 → 확정 | Resource Assignment 모듈 | --- ## 9. 외부 시스템 인터페이스 상세 (NF.13~15) ### 인터페이스 전체 맵 ``` ┌──────────────────┐ ┌─────────────┐ ┌────────────────┐ │ SAP │ │ │ │ │ │ SuccessFactors │────▶│ SAP BTP │────▶│ WTMgr │ │ (HR Master) │ │ (NF.13) │ │ Spring Boot │ └──────────────────┘ └─────────────┘ │ │ │ ┌──────────┐│ ┌──────────────────┐ File Upload │ │ REST API ││ │ Primavera P6 │─────────────────────────▶│ │ ││ │ (WBS/Schedule) │ (NF.14, 물리적 I/F 없음) │ └──────────┘│ └──────────────────┘ │ │ │ ┌──────────┐│ ┌──────────────────┐ Extractor │ │ Export ││ │ Cognite │◀────────────────────────│ │ API ││ │ (Data Platform) │ (NF.15) │ └──────────┘│ └──────────────────┘ └────────────────┘ ``` ### 9-1. SAP SuccessFactors 연동 (NF.13) — SAP BTP 필수 > **NF.13 원문**: "In the case of direct integration with SuccessFactors, SAP BTP must be applied." #### 연동 아키텍처 ``` SAP SuccessFactors │ │ OData API (Employee Central) ▼ ┌─────────────────────────┐ │ SAP BTP │ │ (Business Technology │ │ Platform) │ │ │ │ ┌───────────────────┐ │ │ │ Integration Suite │ │ │ │ (CPI/CI) │ │ │ │ │ │ │ │ ● OData → REST │ │ │ │ ● 필드 매핑 │ │ │ │ ● 스케줄링 (배치) │ │ │ └───────┬───────────┘ │ └──────────┼──────────────┘ │ REST API (JSON) ▼ ┌─────────────────────────┐ │ WTMgr │ │ POST /api/integration │ │ /hr/sync │ └─────────────────────────┘ ``` #### 단계별 구현 | Phase | 방식 | 설명 | |-------|------|------| | **PH1-1** | **파일 업로드** (No.1) | SA가 SF에서 Export한 Excel/CSV를 수동 업로드. BTP 불필요 | | **PH1-2** | **배치 자동화** (No.3) | SAP BTP Integration Suite → 정기 Batch (일 1회) → WTMgr REST API | | **PH2** | **실시간 이벤트** | SF Employee Events → BTP → WTMgr Webhook (입/퇴사 즉시 반영) | #### SAP BTP Integration Suite 설정 ```yaml # BTP CPI iFlow 설정 예시 Source: System: SAP SuccessFactors API: /odata/v2/PerPersonal, /odata/v2/EmpJob, /odata/v2/FODepartment Auth: OAuth2 (SAP Trust) Mapping: SF.personIdExternal → WTMgr.employeeNumber SF.firstName + lastName → WTMgr.fullName SF.email → WTMgr.email SF.businessUnit → WTMgr.businessUnit (LV1) SF.division → WTMgr.division (LV2) SF.department → WTMgr.department (LV3) SF.customString1 → WTMgr.disciplineTeam (LV4) # Discipline/Team SF.customString2 → WTMgr.part (LV5) # Part SF.attendanceType → WTMgr.attendanceType SF.jobCode → WTMgr.individualJobCode Target: System: WTMgr Endpoint: POST /api/integration/hr/sync Auth: Service Account JWT (M2M) Schedule: Daily 02:00 KST ``` #### Spring Boot 수신 API ```java @RestController @RequestMapping("/api/integration/hr") @PreAuthorize("hasRole('SYSTEM') or hasRole('SA')") // M2M 또는 SA만 public class HrIntegrationController { private final HrSyncService hrSyncService; /** * SAP BTP → WTMgr HR 데이터 동기화 * PH1-1: SA 수동 파일 업로드 대안 * PH1-2: BTP CPI 자동 호출 */ @PostMapping("/sync") public HrSyncResult syncEmployees(@Valid @RequestBody HrSyncRequest request) { return hrSyncService.syncAll(request.getEmployees()); } /** * SA 수동 업로드 (PH1-1: BTP 없이 Excel 업로드) */ @PostMapping("/upload") public HrSyncResult uploadExcel(@RequestParam("file") MultipartFile file) { return hrSyncService.uploadFromExcel(file); } } // 동기화 요청 DTO public record HrSyncRequest( List employees, String syncSource, // "SAP_BTP" | "MANUAL_UPLOAD" LocalDateTime syncTime ) {} public record HrEmployeeDto( String employeeNumber, String fullName, String email, String businessUnit, // LV1 String division, // LV2 String department, // LV3 String disciplineTeam, // LV4 String part, // LV5 String attendanceType, String individualJobCode, String jobRole, LocalDate startDate, LocalDate endDate, boolean isActive ) {} ``` #### SAP BTP 사전 확보 사항 | 항목 | 제공 주체 | 마감 | |------|----------|------| | BTP 테넌트 접근 권한 | 한화시스템/SAP | W2 | | SF OData API 엔드포인트 및 인증 정보 | 한화시스템 | W2 | | 필드 매핑 확정 (SF → WTMgr) | 한화오션 + 아큐라 | W3 | | BTP CPI iFlow 개발/배포 권한 | 한화시스템 | PH1-2 | ### 9-2. P6 연동 (NF.14) — 파일 기반만 > **NF.14 원문**: "Since there is no physical interface with P6, data integration must be implemented using exported files." | 항목 | 내용 | |------|------| | 연동 방식 | P6 Export → Excel/CSV → WTMgr Upload | | 물리적 I/F | **없음** (API 연동 불가) | | 업로드 주체 | **PM** (No.27), PCM이 승인 (No.35) | | 필수 필드 | WBS Level 1~5, P6 Activity ID, P6 Activity Name, Version Number, Effective Date, Approval Reference (No.31) | | 빈도 | WBS 변경 시 수시 + 월 1회 Snapshot 비교 (No.32) | ### 9-3. Cognite 연동 (NF.15) — PH2 > **NF.15 원문**: "An extractor server is required to support interface integration with Cognite." ``` Export 대상 Dimension/Fact (No.80): - Employee Dimension (사번, 이름, 부서, Discipline) - Project Dimension (프로젝트코드, 이름, Type) - Canonical WBS Dimension (WBS 코드, Level, 이름) - Time Fact Table (날짜, 시수, Activity, 승인상태) - Mapping Version Metadata (★ 기존 계획 누락 → 추가) ``` ```java // Cognite Export REST API (PH2) @GetMapping("/api/integration/cognite/export") @PreAuthorize("hasRole('SA')") public CogniteExportData exportForCognite( @RequestParam @DateTimeFormat(iso = DATE) LocalDate from, @RequestParam @DateTimeFormat(iso = DATE) LocalDate to) { return CogniteExportData.builder() .employees(employeeDimensionService.export()) .projects(projectDimensionService.export()) .canonicalWbs(wbsDimensionService.export()) .timeFacts(timesheetFactService.export(from, to)) .mappingVersions(wbsVersionService.exportMetadata()) // ★ 추가 .exportedAt(LocalDateTime.now()) .build(); } ``` --- ## 10. 최종 점검 — 기존 계획서 오류 정정 ### 정정 사항 요약 | # | 기존 계획서 | 수정 내용 | 근거 | |---|-----------|----------|------| | 1 | 조직 4레벨 (BU/Division/Dept/Section) | **5레벨**: BU/Division/Dept/Discipline·Team/**Part** + Attendance Type, Individual Job Code | No.2 (Eng) | | 2 | Canonical WBS L3 = "Discipline/Category" | **L3 = Asset or Area** | No.34 (Eng) | | 3 | Canonical WBS L4 = "Sub-Category/Work Package" | **L4 = Work or Discipline** | No.34 (Eng) | | 4 | Canonical WBS L5 = "Deliverable/Activity" | **L5 = Deliverable, Package, or Material (Engineering & SCM only)** | No.34 (Eng) | | 5 | Overhead 9종 (Leave, Sick Leave 등 포함) | **4종**: Training, Sys&Proc Dev, Org Operation, Corporate Initiative | No.56 (Eng) | | 6 | WBS 업로드 주체 = PCM/PTK | **PM**이 업로드, **PCM**이 승인 | No.27, No.35 | | 7 | No.49 Location/Role = PH2 | Phase 미지정 (메인 요구사항), 설계 시 고려 필요 | No.49 | | 8 | EPC 추가 필드 미반영 | Location, Role/Position, **Earned Value(진행률)** 검토 | No.65 | | 9 | Cognite Export 4개 Dimension | **5개**: + Mapping Version Metadata | No.80 (Eng) | | 10 | 미완료 Timesheet 알림 미반영 | **필수**: 담당자에게 미완료 Timesheet alert 전송 | No.70 | | 11 | Project 생성 = PM 직접 | PM/PCM 정보 입력 → **SA 승인** 후 등록 | No.25 | | 12 | Non-Project TEAL = 기본 내장 | **Admin이 설정**한 Non-Project TEAL에서만 Activity 선택 | No.57 | | 13 | SAP BTP 연동 = 간략 설명만 | **상세 아키텍처 추가** (BTP CPI iFlow, OData → REST 매핑) | NF.13 | ### 04-timesheet-module.md 보완 필요 ```java // No.65: EPC Timesheet 추가 필드 (PH2 후보, 설계 시 확장 고려) @Entity @Table(name = "timesheet_entries") public class TimesheetEntry extends BaseEntity { // ... 기존 필드 ... // ★ No.65 추가 필드 (nullable, PH2에서 활성화) private String location; // Onshore/Offshore/국가코드 private String rolePosition; // Job Role (동일 사용자 복수 Role 가능) private BigDecimal earnedValue; // 진행률 (%) — Earned Value } // ★ 주의: "동일 사용자가 복수 Role → Unit Rate 변경", "Location 변경 → Unit Rate 변경" (No.65 Remark) ``` ### 06-approval-workflow.md 보완 필요 ```java // No.70: 미완료 Timesheet 알림 (★ 기존 계획 누락) @Component public class TimesheetReminderScheduler { /** * 매일 오후 5시: 당일 미작성 Timesheet 알림 (No.70) * "The system must send alerts to responsible users * for incomplete timesheets to ensure timely submission" */ @Scheduled(cron = "0 0 17 * * MON-FRI") public void sendDailyReminder() { List usersWithoutEntry = timesheetService .findUsersWithoutEntryForDate(LocalDate.now()); for (User user : usersWithoutEntry) { notificationService.sendTimesheetReminder(user, LocalDate.now()); } } /** * 매주 금요일 오전 10시: 주간 미제출 Timesheet 알림 */ @Scheduled(cron = "0 0 10 * * FRI") public void sendWeeklySubmitReminder() { LocalDate weekStart = LocalDate.now().with(DayOfWeek.MONDAY); List unsubmitted = timesheetService .findUsersWithUnsubmittedWeek(weekStart); for (User user : unsubmitted) { notificationService.sendWeeklySubmitReminder(user, weekStart); } } } ``` ### 05-wbs-teal-module.md 보완 필요 ```java // No.27: WBS 업로드 주체 수정 // 기존: PCM/PTK 업로드 // 수정: PM이 업로드 → PCM이 승인 (No.35) @PostMapping("/api/projects/{projectId}/wbs/upload") @PreAuthorize("hasAnyRole('SA', 'PM')") // ★ PM 권한 (기존 PCM → PM) public WbsVersionDto uploadP6Wbs(...) { ... } @PostMapping("/api/projects/{projectId}/wbs/versions/{verId}/approve") @PreAuthorize("hasAnyRole('SA', 'PCM')") // ★ PCM 승인 public WbsVersionDto approveWbs(...) { ... } ``` --- ## 11. API 스펙 보완 (07-api-spec.md 추가분) ### 추가 필요 API (기존 57개 → 최종 78개) | Method | Path | 설명 | Phase | |--------|------|------|-------| | GET | `/api/overhead-types` | Overhead Type 목록 | PH1-1 | | POST | `/api/overhead-types` | Overhead Type 추가 (SA) | PH1-1 | | PUT | `/api/overhead-types/{id}` | Overhead Type 수정 (SA) | PH1-1 | | GET | `/api/work-rules` | 근무 규칙 목록 | PH1-1 | | PUT | `/api/work-rules/{id}` | 근무 규칙 수정 (SA) | PH1-1 | | GET | `/api/projects/{id}/assignments` | 프로젝트 인력 배정 목록 | PH1-1 | | POST | `/api/projects/{id}/assignments` | 인력 배정 | PH1-1 | | POST | `/api/projects/{id}/assignments/upload` | 인력 일괄 업로드 | PH1-1 | | DELETE | `/api/projects/{id}/assignments/{userId}` | 인력 배정 해제 | PH1-1 | | GET | `/api/projects/{id}/wbs-disciplines` | WBS-Discipline 현황 | PH1-1 | | POST | `/api/projects/{id}/wbs-disciplines` | WBS-Discipline 배정 | PH1-1 | | POST | `/api/projects/{id}/wbs/versions/{id}/approve` | WBS 버전 승인 (PCM) ★ 추가 | PH1-1 | | GET | `/api/role-permissions` | 역할별 권한 매트릭스 (SA) | PH1-1 | | POST | `/api/integration/hr/sync` | SAP BTP HR 동기화 수신 ★ 추가 | PH1-2 | | POST | `/api/integration/hr/upload` | SA 수동 HR 파일 업로드 ★ 추가 | PH1-1 | | GET | `/api/notifications/pending` | 미완료 Timesheet 알림 목록 ★ 추가 | PH1-1 | | GET | `/api/users/me/favorites` | 내 Favorite 설정 | PH2 | | PUT | `/api/users/me/favorites` | Favorite 저장 | PH2 | | GET | `/api/integration/cognite/export` | Cognite Export ★ 추가 | PH2 | | GET | `/api/reports/wbs-misalign` | WBS Mis-Align 검토 (No.81) ★ 추가 | PH2 | | GET | `/api/reports/discipline-productivity` | Discipline 생산성 (No.84) ★ 추가 | PH2 | ### 최종 API 수 | 모듈 | PH1-1차 | PH1-2차 | PH2 | 합계 | |------|---------|---------|-----|------| | Auth | 8 | 0 | 0 | 8 | | Users | 7 | 1 | 2 | 10 | | Projects | 7 | 0 | 0 | 7 | | WBS | 6 | 1 | 0 | 7 | | TEAL | 4 | 0 | 0 | 4 | | Timesheets | 8 | 0 | 0 | 8 | | Approvals | 7 | 1 | 0 | 8 | | Reports | 4 | 2 | 3 | 9 | | Home/Notification | 3 | 0 | 0 | 3 | | Resource Assign | 8 | 0 | 0 | 8 | | Config (규칙/Type) | 4 | 0 | 0 | 4 | | **Integration (SAP/Cognite)** | **1** | **1** | **1** | **3** | | **합계** | **67** | **6** | **6** | **79** |