# Employee API (사원관리 API) 규칙 ## 개요 사원관리 API는 테넌트 내 사원 정보를 관리하는 API입니다. `users` 테이블과 `tenant_user_profiles` 테이블을 조합하여 사원 정보를 구성합니다. ## 핵심 모델 ### TenantUserProfile - **위치**: `App\Models\Tenants\TenantUserProfile` - **역할**: 테넌트별 사용자 프로필 (사원 정보) - **특징**: `json_extra` 필드에 사원 상세 정보 저장 ### User - **위치**: `App\Models\Members\User` - **역할**: 기본 사용자 계정 (이름, 이메일, 비밀번호) ## 엔드포인트 | Method | Path | 설명 | |--------|------|------| | GET | `/v1/employees` | 사원 목록 조회 | | GET | `/v1/employees/{id}` | 사원 상세 조회 | | POST | `/v1/employees` | 사원 등록 | | PATCH | `/v1/employees/{id}` | 사원 수정 | | DELETE | `/v1/employees/{id}` | 사원 삭제 (상태 변경) | | DELETE | `/v1/employees/bulk` | 사원 일괄 삭제 | | GET | `/v1/employees/stats` | 사원 통계 | | POST | `/v1/employees/{id}/account` | 시스템 계정 생성 | ## 데이터 구조 ### 기본 필드 (TenantUserProfile) | 필드 | 타입 | 설명 | |------|------|------| | `tenant_id` | int | 테넌트 ID | | `user_id` | int | 사용자 ID (FK → users) | | `department_id` | int | 부서 ID (nullable) | | `position_key` | string | 직위 코드 | | `job_title_key` | string | 직책 코드 | | `work_location_key` | string | 근무지 코드 | | `employment_type_key` | string | 고용 형태 코드 | | `employee_status` | string | 고용 상태 (active/leave/resigned) | | `manager_user_id` | int | 상위 관리자 ID (nullable) | | `profile_photo_path` | string | 프로필 사진 경로 | | `display_name` | string | 표시명 | | `json_extra` | json | 확장 사원 정보 | ### json_extra 필드 구조 ```json { "employee_code": "EMP001", "resident_number": "encrypted_value", "gender": "male|female", "address": "서울시 강남구...", "salary": 5000000, "hire_date": "2024-01-15", "rank": "대리", "bank_account": { "bank": "국민은행", "account": "123-456-789", "holder": "홍길동" }, "work_type": "regular|contract|part_time", "contract_info": { "start_date": "2024-01-15", "end_date": "2025-01-14" }, "emergency_contact": { "name": "김부모", "phone": "010-1234-5678", "relation": "부모" }, "education": [], "certifications": [] } ``` ### 허용된 json_extra 키 ```php $allowedKeys = [ 'employee_code', // 사원번호 'resident_number', // 주민등록번호 (암호화 필수) 'gender', // 성별 'address', // 주소 'salary', // 급여 'hire_date', // 입사일 'rank', // 직급 'bank_account', // 급여계좌 'work_type', // 근무유형 'contract_info', // 계약 정보 'emergency_contact', // 비상연락처 'education', // 학력 'certifications', // 자격증 ]; ``` ## 비즈니스 규칙 ### 사원 등록 (store) 1. `users` 테이블에 사용자 생성 2. `user_tenants` pivot에 관계 추가 (is_default: true) 3. `tenant_user_profiles` 생성 4. `json_extra`에 사원 정보 설정 ```php // 자동 생성되는 user_id 형식 $userId = strtolower(explode('@', $email)[0] . '_' . Str::random(4)); ``` ### 사원 삭제 (destroy) - **Hard Delete 하지 않음** - `employee_status`를 `resigned`로 변경 - 사용자 계정은 유지됨 ### 사원 상태 (employee_status) | 상태 | 설명 | |------|------| | `active` | 재직 중 | | `leave` | 휴직 | | `resigned` | 퇴사 | ### 시스템 계정 (has_account) - 시스템 계정 = `users.password`가 NULL이 아닌 경우 - `POST /employees/{id}/account`로 비밀번호 설정 시 계정 생성 - 첫 로그인 시 비밀번호 변경 필요 (`must_change_password: true`) ## 검색/필터 파라미터 | 파라미터 | 타입 | 설명 | |----------|------|------| | `q` | string | 이름/이메일/사원코드 검색 | | `status` | string | 고용 상태 필터 | | `department_id` | int | 부서 필터 | | `has_account` | bool | 시스템 계정 보유 여부 | | `sort_by` | string | 정렬 기준 (기본: created_at) | | `sort_dir` | string | 정렬 방향 (asc/desc) | | `per_page` | int | 페이지당 항목 수 (기본: 20) | ## 관계 (Relationships) ```php // TenantUserProfile public function user(): BelongsTo // 기본 사용자 정보 public function department(): BelongsTo // 소속 부서 public function manager(): BelongsTo // 상위 관리자 ``` ## 스코프 (Scopes) ```php $query->active(); // employee_status = 'active' $query->onLeave(); // employee_status = 'leave' $query->resigned(); // employee_status = 'resigned' ``` ## Accessor ```php $profile->employee_code; // json_extra['employee_code'] $profile->hire_date; // json_extra['hire_date'] $profile->address; // json_extra['address'] $profile->emergency_contact; // json_extra['emergency_contact'] ``` ## 주의사항 1. **주민등록번호**: 반드시 암호화하여 저장 2. **멀티테넌트**: tenant_id 자동 스코핑 3. **Audit**: created_by/updated_by 자동 기록 4. **삭제**: Hard Delete 금지, employee_status 변경으로 처리