Files
sam-docs/rules/attendance-api.md
hskwon 5d1190a0d3 docs: plans 폴더 추가 및 HR API 규칙 문서 정리
- plans/ 폴더 신규 생성 (개발 계획 임시 문서용)
- hr-api-react-sync-plan.md를 specs → plans로 이동
- INDEX.md 업데이트 (폴더 구조, 워크플로우)
- rules/ HR API 규칙 문서 추가 (employee, attendance, department-tree)
- pricing API 요청 문서 업데이트
2025-12-09 14:44:39 +09:00

6.5 KiB

Attendance API (근태관리 API) 규칙

개요

근태관리 API는 테넌트 내 사용자의 출퇴근 및 근태 정보를 관리하는 API입니다. attendances 테이블을 사용하며, 상세 출퇴근 정보는 json_details 필드에 저장합니다.

핵심 모델

Attendance

  • 위치: App\Models\Tenants\Attendance
  • 역할: 일별 근태 기록
  • 특징:
    • BelongsToTenant 트레이트 사용 (멀티테넌트 자동 스코핑)
    • SoftDeletes 적용
    • json_details 필드에 상세 출퇴근 정보 저장

엔드포인트

Method Path 설명
GET /v1/attendances 근태 목록 조회
GET /v1/attendances/{id} 근태 상세 조회
POST /v1/attendances 근태 등록
PATCH /v1/attendances/{id} 근태 수정
DELETE /v1/attendances/{id} 근태 삭제
DELETE /v1/attendances/bulk 근태 일괄 삭제
POST /v1/attendances/check-in 출근 기록
POST /v1/attendances/check-out 퇴근 기록
GET /v1/attendances/monthly-stats 월간 통계

데이터 구조

기본 필드

필드 타입 설명
id int PK
tenant_id int 테넌트 ID
user_id int 사용자 ID (FK → users)
base_date date 기준 일자
status string 근태 상태
json_details json 상세 출퇴근 정보
remarks string 비고 (500자 제한)
created_by int 생성자
updated_by int 수정자
deleted_by int 삭제자
deleted_at timestamp Soft Delete

근태 상태 (status)

상태 설명
onTime 정상 출근 (기본값)
late 지각
absent 결근
vacation 휴가
businessTrip 출장
fieldWork 외근
overtime 야근
remote 재택근무

json_details 필드 구조

{
  "check_in": "09:00:00",
  "check_out": "18:00:00",
  "gps_data": {
    "check_in": {
      "lat": 37.5665,
      "lng": 126.9780,
      "accuracy": 10
    },
    "check_out": {
      "lat": 37.5665,
      "lng": 126.9780,
      "accuracy": 10
    }
  },
  "external_work": {
    "location": "고객사",
    "purpose": "미팅",
    "start_time": "14:00:00",
    "end_time": "16:00:00"
  },
  "multiple_entries": [
    { "in": "09:00:00", "out": "12:00:00" },
    { "in": "13:00:00", "out": "18:00:00" }
  ],
  "work_minutes": 480,
  "overtime_minutes": 60,
  "late_minutes": 30,
  "early_leave_minutes": 0,
  "vacation_type": "annual|half|sick"
}

허용된 json_details 키

$allowedKeys = [
    'check_in',           // 출근 시간 (HH:MM:SS)
    'check_out',          // 퇴근 시간 (HH:MM:SS)
    'gps_data',           // GPS 데이터 (출퇴근 위치)
    'external_work',      // 외근 정보
    'multiple_entries',   // 다중 출퇴근 기록
    'work_minutes',       // 총 근무 시간 (분)
    'overtime_minutes',   // 초과 근무 시간 (분)
    'late_minutes',       // 지각 시간 (분)
    'early_leave_minutes',// 조퇴 시간 (분)
    'vacation_type',      // 휴가 유형
];

비즈니스 규칙

출근 기록 (check-in)

  1. 오늘 기록이 있으면 업데이트, 없으면 새로 생성
  2. check_in 시간과 GPS 데이터 저장
  3. 출근 시간 기준으로 상태 자동 결정 (09:00 기준 지각 판단)
// 상태 자동 결정 로직
if ($checkIn > '09:00:00') {
    $status = 'late';
} else {
    $status = 'onTime';
}

퇴근 기록 (check-out)

  1. 오늘 출근 기록이 없으면 에러 반환
  2. check_out 시간과 GPS 데이터 저장
  3. 근무 시간(work_minutes) 자동 계산
// 근무 시간 계산
$checkIn = Carbon::createFromFormat('H:i:s', $jsonDetails['check_in']);
$checkOut = Carbon::createFromFormat('H:i:s', $checkOutTime);
$jsonDetails['work_minutes'] = $checkOut->diffInMinutes($checkIn);

근태 등록 (store)

  1. 같은 날 같은 사용자 기록이 있으면 에러 반환
  2. json_details 직접 전달 또는 개별 필드에서 구성
// json_details 처리 방식
$jsonDetails = isset($data['json_details']) && is_array($data['json_details'])
    ? $data['json_details']
    : $this->buildJsonDetails($data);

월간 통계 (monthly-stats)

통계 항목:

  • 총 근무일수
  • 상태별 일수 (정상, 지각, 결근, 휴가, 출장, 외근, 야근, 재택)
  • 총 근무 시간 (분)
  • 총 초과 근무 시간 (분)

검색/필터 파라미터

파라미터 타입 설명
user_id int 사용자 필터
date date 특정 날짜 필터
date_from date 시작 날짜
date_to date 종료 날짜
status string 근태 상태 필터
department_id int 부서 필터 (사용자의 부서)
sort_by string 정렬 기준 (기본: base_date)
sort_dir string 정렬 방향 (기본: desc)
per_page int 페이지당 항목 수 (기본: 20)

관계 (Relationships)

public function user(): BelongsTo     // 사용자 정보
public function creator(): BelongsTo  // 생성자
public function updater(): BelongsTo  // 수정자

스코프 (Scopes)

$query->onDate('2024-01-15');              // 특정 날짜
$query->betweenDates('2024-01-01', '2024-01-31'); // 날짜 범위
$query->forUser(123);                       // 특정 사용자
$query->withStatus('late');                 // 특정 상태

Accessor

$attendance->check_in;           // json_details['check_in']
$attendance->check_out;          // json_details['check_out']
$attendance->gps_data;           // json_details['gps_data']
$attendance->external_work;      // json_details['external_work']
$attendance->multiple_entries;   // json_details['multiple_entries']
$attendance->work_minutes;       // json_details['work_minutes']
$attendance->overtime_minutes;   // json_details['overtime_minutes']
$attendance->late_minutes;       // json_details['late_minutes']
$attendance->early_leave_minutes;// json_details['early_leave_minutes']
$attendance->vacation_type;      // json_details['vacation_type']

주의사항

  1. 중복 방지: 같은 날짜 + 같은 사용자 조합은 유일해야 함
  2. 멀티테넌트: BelongsToTenant 트레이트로 자동 스코핑
  3. Soft Delete: deleted_by 기록 후 삭제
  4. Audit: created_by/updated_by 자동 기록
  5. 시간 형식: check_in/check_out은 HH:MM:SS 형식
  6. 표준 출근 시간: 기본 09:00:00 (회사별 설정 필요)