Files
sam-docs/rules/employee-api.md
김보곤 5517b7f04d docs: [esign] 근로계약서 최신 연봉정보 반영 문서화
- features/esign/README.md: 근로계약서 사원 연동 섹션 추가
- projects/e-sign/changelog.md: v1.1.1 변경 이력 추가
- rules/employee-api.md: 전자계약 연동 참조 추가
- dev/changes/20260311: esign 연봉정보 개선 내용 추가
2026-03-11 17:04:27 +09:00

7.8 KiB

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 필드 구조

{
  "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 키

$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에 사원 정보 설정
// 자동 생성되는 user_id 형식
$userId = strtolower(explode('@', $email)[0] . '_' . Str::random(4));

사원 삭제 (destroy)

  • Hard Delete 하지 않음
  • employee_statusresigned로 변경
  • 사용자 계정은 유지됨

사원 상태 (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)

// TenantUserProfile
public function user(): BelongsTo      // 기본 사용자 정보
public function department(): BelongsTo // 소속 부서
public function manager(): BelongsTo    // 상위 관리자

스코프 (Scopes)

$query->active();    // employee_status = 'active'
$query->onLeave();   // employee_status = 'leave'
$query->resigned();  // employee_status = 'resigned'

Accessor

$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']

연봉 정보 관리 (MNG 내부 API)

접근 제한: 특정 사용자만 접근 가능 (hardcoded: 이의찬, 전진선, 김보곤)

엔드포인트

Method Path 설명
GET /api/admin/hr/employees/{id}/salary 연봉 정보 조회
PUT /api/admin/hr/employees/{id}/salary 연봉 정보 저장/수정
DELETE /api/admin/hr/employees/{id}/salary/history/{historyIndex} 연봉 이력 삭제

데이터 저장 구조

연봉 정보는 tenant_user_profiles.json_extra.salary_info에 JSON으로 저장한다.

{
  "salary_info": {
    "annual_salary": 50000000,
    "effective_date": "2026-01-01",
    "notes": "연봉 인상",
    "history": [
      {
        "annual_salary": 45000000,
        "effective_date": "2025-01-01",
        "notes": "입사 시 연봉",
        "recorded_at": "2025-01-15 09:00:00",
        "recorded_by": "김보곤"
      }
    ]
  }
}

비즈니스 규칙

  • R1: 연봉 정보 저장 시 이전 값이 history 배열에 자동 추가된다
  • R2: 이력 삭제는 배열 인덱스 기반이다 (프론트에서 reverse 표시 → 원본 인덱스 변환 필요)
  • R3: 일반 API 응답(toArray())에서 salary_info는 자동 제거된다 (민감 데이터 보호)
  • R4: 연봉 정보는 MNG 사원관리 페이지의 조회/수정 화면에서만 표시된다

전자계약(E-Sign) 연동

근로계약서 사원불러오기에서 연봉 정보를 활용한다:

  • EsignApiController::searchEmployees()getSalaryInfo()로 최신 연봉 조회
  • annual_salary + salary_effective_date 반환
  • 현재 연봉이 null이면 이력에서 effective_date 기준 최신 탐색 (fallback)
  • 연봉 적용일 기준으로 연봉계약 시작/종료일 자동 계산

상세: E-Sign 기능 문서 — 근로계약서 사원 연동

관련 파일

파일 역할
mng/app/Http/Controllers/Api/Admin/HR/EmployeeSalaryController.php 연봉 CRUD API 컨트롤러
mng/app/Http/Controllers/ESign/EsignApiController.php searchEmployees() — 전자계약 사원 검색
mng/app/Models/HR/Employee.php getSalaryInfo(), setSalaryInfo() 메서드
mng/resources/views/hr/employees/partials/salary-info.blade.php 연봉 정보 UI (Alpine.js)
mng/resources/views/esign/create.blade.php 근로계약서 변수 자동 매핑
mng/routes/api.php 라우트 정의 (라인 1185-1188)

주의사항

  1. 주민등록번호: 반드시 암호화하여 저장
  2. 멀티테넌트: tenant_id 자동 스코핑
  3. Audit: created_by/updated_by 자동 기록
  4. 삭제: Hard Delete 금지, employee_status 변경으로 처리
  5. 연봉 정보: 특수 권한 사용자만 접근 가능, 일반 API 응답에서 자동 제외