feat: 다수 기능 개선 - 순찰, 출근, 작업분석, 모바일 UI 등
- 순찰/점검 기능 개선 (zone-detail 페이지 추가) - 출근/근태 시스템 개선 (연차 조회, 근무현황) - 작업분석 대분류 그룹화 및 마이그레이션 스크립트 - 모바일 네비게이션 UI 추가 - NAS 배포 도구 및 문서 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
271
docs/vacation-data-flow-guide.md
Normal file
271
docs/vacation-data-flow-guide.md
Normal file
@@ -0,0 +1,271 @@
|
||||
# 휴가 데이터 흐름 가이드
|
||||
|
||||
> 작성일: 2026-02-05
|
||||
> 목적: 휴가 관련 데이터 저장 구조 및 연동 방식 문서화
|
||||
|
||||
---
|
||||
|
||||
## 1. 테이블 구조
|
||||
|
||||
### 1.1 vacation_balance_details (연간 휴가 잔액)
|
||||
**목적**: 작업자별 연간 휴가 발생/사용 일수 관리
|
||||
|
||||
| 컬럼 | 설명 | 예시 |
|
||||
|------|------|------|
|
||||
| `worker_id` | 작업자 ID | 1 |
|
||||
| `vacation_type_id` | 휴가 **유형** ID (vacation_types 참조) | 1 (이월), 2 (정기연차) |
|
||||
| `year` | 연도 | 2026 |
|
||||
| `total_days` | 발생 일수 | 15 |
|
||||
| `used_days` | 사용 일수 (자동 연동) | 3 |
|
||||
| `remaining_days` | 잔여 일수 (자동 계산 컬럼) | 12 |
|
||||
|
||||
### 1.2 daily_attendance_records (일별 근태 기록)
|
||||
**목적**: 일별 출근/휴가/근무시간 기록
|
||||
|
||||
| 컬럼 | 설명 | 예시 |
|
||||
|------|------|------|
|
||||
| `worker_id` | 작업자 ID | 1 |
|
||||
| `record_date` | 기록 날짜 | 2026-02-05 |
|
||||
| `attendance_type_id` | 근태 유형 (1=정상, 2=지각, 3=조퇴, 4=결근, 5=휴가) | 5 |
|
||||
| `vacation_type_id` | 휴가 **사용** 유형 (1=연차, 2=반차, 3=반반차) | 1 |
|
||||
| `total_work_hours` | 총 근무시간 | 8.0 |
|
||||
|
||||
### 1.3 vacation_types (휴가 유형 마스터)
|
||||
**목적**: 휴가 유형 정의 및 차감 우선순위
|
||||
|
||||
| type_code | type_name | priority | 용도 |
|
||||
|-----------|-----------|----------|------|
|
||||
| CARRYOVER | 이월 | 1 | 작년 이월 연차 |
|
||||
| ANNUAL | 정기연차 | 2 | 올해 발생 연차 |
|
||||
| LONG_SERVICE | 장기근속 | 3 | 장기근속 보상 |
|
||||
| WEDDING | 결혼 | 4 | 경조사 |
|
||||
| SPOUSE_BIRTH | 배우자 출산 | 4 | 경조사 |
|
||||
| ... | ... | 4 | 기타 경조사 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 데이터 흐름
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 휴가 데이터 흐름도 │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
[annual-overview.html] [work-status.html]
|
||||
연간 연차 현황 페이지 근무 현황 페이지
|
||||
│ │
|
||||
│ 발생 일수 입력 │ 휴가 사용 기록
|
||||
│ (이월, 정기연차, 장기근속, 경조사) │ (연차/반차/반반차)
|
||||
▼ ▼
|
||||
┌──────────────────┐ ┌──────────────────┐
|
||||
│ vacation_balance │◀───── 연동 ───────│ daily_attendance │
|
||||
│ _details │ │ _records │
|
||||
│ │ │ │
|
||||
│ total_days: 15 │ used_days │ vacation_type_id │
|
||||
│ used_days: 3 ◀──┼──── 자동 업데이트 ──┼── 1 (연차) │
|
||||
│ remaining: 12 │ │ │
|
||||
└──────────────────┘ └──────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 연동 로직
|
||||
|
||||
### 3.1 휴가 사용 시 (work-status.html에서 저장)
|
||||
|
||||
**파일**: `api.hyungi.net/services/attendanceService.js`
|
||||
|
||||
```javascript
|
||||
// upsertAttendanceRecordService 함수 내부
|
||||
|
||||
// 1. 기존 기록 조회
|
||||
const existingRecord = await AttendanceModel.getDailyAttendanceRecords(record_date, worker_id);
|
||||
|
||||
// 2. 휴가 사용 유형 → 차감 일수 변환
|
||||
// vacation_type_id: 1=연차(1일), 2=반차(0.5일), 3=반반차(0.25일)
|
||||
const daysMap = { 1: 1, 2: 0.5, 3: 0.25 };
|
||||
const newDays = daysMap[vacation_type_id] || 0;
|
||||
|
||||
// 3. 이전 휴가가 있었으면 복구 (변경된 경우)
|
||||
if (previousDays > 0) {
|
||||
await vacationBalanceModel.restoreByPriority(worker_id, year, previousDays);
|
||||
}
|
||||
|
||||
// 4. 새 휴가 차감 (우선순위: 이월 → 정기연차 → 장기근속 → 경조사)
|
||||
if (newDays > 0) {
|
||||
await vacationBalanceModel.deductByPriority(worker_id, year, newDays);
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 차감 우선순위 로직
|
||||
|
||||
**파일**: `api.hyungi.net/models/vacationBalanceModel.js`
|
||||
|
||||
```javascript
|
||||
// deductByPriority 함수
|
||||
|
||||
// 1. 우선순위순으로 잔여 일수가 있는 잔액 조회
|
||||
SELECT * FROM vacation_balance_details vbd
|
||||
INNER JOIN vacation_types vt ON vbd.vacation_type_id = vt.id
|
||||
WHERE vbd.worker_id = ? AND vbd.year = ?
|
||||
AND (vbd.total_days - vbd.used_days) > 0
|
||||
ORDER BY vt.priority ASC -- 이월(1) → 정기연차(2) → 장기근속(3) → 경조사(4)
|
||||
|
||||
// 2. 순서대로 차감
|
||||
for (const balance of balances) {
|
||||
const available = balance.remaining_days;
|
||||
const toDeduct = Math.min(remaining, available);
|
||||
|
||||
UPDATE vacation_balance_details
|
||||
SET used_days = used_days + ?
|
||||
WHERE id = ?
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 주요 파일 위치
|
||||
|
||||
```
|
||||
api.hyungi.net/
|
||||
├── models/
|
||||
│ ├── vacationBalanceModel.js # 휴가 잔액 DB 쿼리
|
||||
│ │ ├── deductByPriority() # 우선순위 차감 ★
|
||||
│ │ └── restoreByPriority() # 우선순위 복구 ★
|
||||
│ └── attendanceModel.js # 근태 기록 DB 쿼리
|
||||
│
|
||||
├── services/
|
||||
│ └── attendanceService.js # 근태 저장 비즈니스 로직
|
||||
│ └── upsertAttendanceRecordService() # 연동 로직 포함 ★
|
||||
│
|
||||
├── controllers/
|
||||
│ ├── vacationBalanceController.js # 휴가 잔액 API
|
||||
│ └── attendanceController.js # 근태 API
|
||||
│
|
||||
└── routes/
|
||||
├── vacationBalanceRoutes.js
|
||||
└── attendanceRoutes.js
|
||||
|
||||
web-ui/pages/attendance/
|
||||
├── annual-overview.html # 연간 연차 현황 (발생 일수 입력) - 관리자 전용
|
||||
├── my-vacation-info.html # 내 연차 정보 (잔여 확인 + 연장근로) - 전체 사용자 ★
|
||||
├── work-status.html # 근무 현황 (휴가 사용 기록)
|
||||
└── monthly.html # 월별 출근부 (조회 전용)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. API 엔드포인트
|
||||
|
||||
### 5.1 휴가 잔액 관련
|
||||
|
||||
| Method | Endpoint | 설명 |
|
||||
|--------|----------|------|
|
||||
| GET | `/vacation-balances/year/:year` | 연도별 전체 잔액 조회 |
|
||||
| GET | `/vacation-balances/worker/:workerId/year/:year` | 작업자별 잔액 조회 |
|
||||
| POST | `/vacation-balances/bulk-upsert` | 일괄 저장 (연간 연차 현황) |
|
||||
|
||||
### 5.2 근태 기록 관련
|
||||
|
||||
| Method | Endpoint | 설명 |
|
||||
|--------|----------|------|
|
||||
| POST | `/attendance/records` | 근태 기록 저장 (휴가 연동 포함) |
|
||||
| GET | `/attendance/records?date=&worker_id=` | 근태 기록 조회 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 차감 일수 매핑
|
||||
|
||||
### 6.1 휴가 사용 유형 (daily_attendance_records.vacation_type_id)
|
||||
|
||||
| ID | 유형 | 차감 일수 |
|
||||
|----|------|----------|
|
||||
| 1 | 연차 (ANNUAL_FULL) | 1일 |
|
||||
| 2 | 반차 (ANNUAL_HALF) | 0.5일 |
|
||||
| 3 | 반반차 (ANNUAL_QUARTER) | 0.25일 |
|
||||
|
||||
### 6.2 근태 유형 (daily_attendance_records.attendance_type_id)
|
||||
|
||||
| ID | 유형 | 설명 |
|
||||
|----|------|------|
|
||||
| 1 | NORMAL | 정상 출근 |
|
||||
| 2 | LATE | 지각 |
|
||||
| 3 | EARLY_LEAVE | 조퇴 |
|
||||
| 4 | ABSENT | 결근 |
|
||||
| 5 | VACATION | 휴가 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 주의사항
|
||||
|
||||
### 7.1 휴가 잔액이 없는 경우
|
||||
- 잔액이 없어도 근태 기록은 저장됨
|
||||
- 콘솔에 경고 로그 출력
|
||||
- 관리자가 연간 연차 현황에서 발생 일수를 먼저 입력해야 함
|
||||
|
||||
### 7.2 휴가 수정 시
|
||||
- 기존 휴가 → 복구 (restoreByPriority)
|
||||
- 새 휴가 → 차감 (deductByPriority)
|
||||
- 연차 → 반차 변경 시: 1일 복구 → 0.5일 차감
|
||||
|
||||
### 7.3 복구 우선순위
|
||||
- 차감 우선순위의 역순으로 복구
|
||||
- 마지막에 차감된 유형부터 먼저 복구
|
||||
- 예: 경조사(4) → 장기근속(3) → 정기연차(2) → 이월(1)
|
||||
|
||||
---
|
||||
|
||||
## 8. 테스트 시나리오
|
||||
|
||||
### 8.1 기본 플로우
|
||||
1. [연간 연차 현황] 김철수에게 정기연차 15일 입력 → 저장
|
||||
2. [근무 현황] 2026-02-05에 김철수 연차 선택 → 저장
|
||||
3. [연간 연차 현황] 새로고침 → 총 사용: 1일, 잔여: 14일 확인
|
||||
|
||||
### 8.2 수정 플로우
|
||||
1. [근무 현황] 기존 연차(1일) → 반차(0.5일)로 변경 → 저장
|
||||
2. [연간 연차 현황] 새로고침 → 총 사용: 0.5일, 잔여: 14.5일 확인
|
||||
|
||||
### 8.3 우선순위 테스트
|
||||
1. [연간 연차 현황] 이월 2일, 정기연차 15일 입력
|
||||
2. [근무 현황] 연차 3회 사용 (3일)
|
||||
3. [연간 연차 현황] 확인:
|
||||
- 이월: 2일 발생, 2일 사용, 0일 잔여
|
||||
- 정기연차: 15일 발생, 1일 사용, 14일 잔여
|
||||
|
||||
---
|
||||
|
||||
## 9. 내 연차 정보 페이지 (my-vacation-info.html)
|
||||
|
||||
### 9.1 기능
|
||||
- **연차 잔여 현황**: 유형별(이월, 정기연차, 장기근속, 경조사) 잔여 일수 표시
|
||||
- **월간 연장근로**: 선택한 월의 연장근로 시간 및 일별 상세
|
||||
|
||||
### 9.2 접근 권한
|
||||
| 사용자 유형 | 기능 |
|
||||
|------------|------|
|
||||
| 일반 사용자 | 본인 정보만 조회 (user.worker_id 기준) |
|
||||
| 관리자 | 작업자 선택하여 조회 가능 |
|
||||
|
||||
### 9.3 연장근로 계산 로직
|
||||
```javascript
|
||||
// daily_attendance_records에서 8시간 초과분 합산
|
||||
records.forEach(r => {
|
||||
const hours = parseFloat(r.total_work_hours) || 0;
|
||||
if (hours > 8) {
|
||||
totalOvertimeHours += (hours - 8);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 9.4 메뉴 위치
|
||||
- 근태 관리 > 내 연차 정보 (최상단)
|
||||
|
||||
---
|
||||
|
||||
## 10. 향후 개선 사항
|
||||
|
||||
- [ ] 휴가 신청/승인 시스템 연동 (vacation_requests 테이블)
|
||||
- [ ] 연차 촉진제 알림 기능
|
||||
- [ ] 휴가 사용 내역 상세 조회 기능
|
||||
- [ ] 부서별 휴가 현황 대시보드
|
||||
224
docs/zone-data-guide.md
Normal file
224
docs/zone-data-guide.md
Normal file
@@ -0,0 +1,224 @@
|
||||
# 구역 관련 데이터 구조 가이드
|
||||
|
||||
## 개요
|
||||
|
||||
작업장(구역) 관련 데이터는 여러 테이블에 분산 저장됩니다. 이 문서는 각 테이블의 역할과 관계를 정리합니다.
|
||||
|
||||
---
|
||||
|
||||
## 테이블 구조
|
||||
|
||||
### 1. 설비 정보 (`equipments`)
|
||||
|
||||
**용도**: 회사 소유 설비/장비의 마스터 데이터
|
||||
|
||||
**등록 경로**: 설비 관리 페이지 (`/pages/equipment/`)
|
||||
|
||||
| 주요 컬럼 | 설명 |
|
||||
|-----------|------|
|
||||
| `equipment_id` | PK |
|
||||
| `equipment_code` | 관리번호 (예: TKP-001) |
|
||||
| `equipment_name` | 설비명 |
|
||||
| `equipment_type` | 유형 (용접기, 턴테이블 등) |
|
||||
| `workplace_id` | 원래 배치된 작업장 |
|
||||
| `status` | 상태 (active, repair_needed, maintenance 등) |
|
||||
| `map_x_percent`, `map_y_percent` | 지도상 위치 (%) |
|
||||
| `is_temporarily_moved` | 임시 이동 여부 |
|
||||
| `current_workplace_id` | 현재 위치 (이동 시) |
|
||||
|
||||
**특징**:
|
||||
- 영구적인 자산 관리 목적
|
||||
- 설비 관리 페이지에서 CRUD
|
||||
- 구역 상세 페이지에서는 **조회만** 가능
|
||||
|
||||
---
|
||||
|
||||
### 2. 구역 현황 (`workplace_zone_items`)
|
||||
|
||||
**용도**: 작업장 내 일시적/상시적 현황 기록 (적치물, 작업중 물품, 미신고품 등)
|
||||
|
||||
**등록 경로**: 구역 상세 페이지 (`/pages/inspection/zone-detail.html`)
|
||||
|
||||
| 주요 컬럼 | 설명 |
|
||||
|-----------|------|
|
||||
| `item_id` | PK |
|
||||
| `workplace_id` | 작업장 ID |
|
||||
| `item_name` | 명칭 |
|
||||
| `item_type` | 상태/유형 (working, temp_storage, moved_equipment, unreported) |
|
||||
| `warning_level` | 주의 수준 (good, caution, needs_management) |
|
||||
| `project_type` | 프로젝트 여부 (project, non_project, unknown) |
|
||||
| `project_id` | 연결된 프로젝트 ID |
|
||||
| `x_percent`, `y_percent` | 지도상 위치 (%) |
|
||||
| `width_percent`, `height_percent` | 영역 크기 (%) |
|
||||
| `color` | 표시 색상 |
|
||||
| `description` | 상세 설명 |
|
||||
| `created_by` | 등록자 |
|
||||
|
||||
**특징**:
|
||||
- 순회점검 중 또는 수시로 등록
|
||||
- 사진 첨부 가능 (`zone_item_photos` 테이블)
|
||||
- 해소되면 삭제 또는 비활성화
|
||||
|
||||
---
|
||||
|
||||
### 3. 구역 현황 사진 (`zone_item_photos`)
|
||||
|
||||
**용도**: 구역 현황에 첨부된 사진
|
||||
|
||||
| 주요 컬럼 | 설명 |
|
||||
|-----------|------|
|
||||
| `photo_id` | PK |
|
||||
| `item_id` | 연결된 현황 ID (FK → workplace_zone_items) |
|
||||
| `photo_url` | 사진 경로 |
|
||||
| `created_at` | 업로드 시간 |
|
||||
|
||||
---
|
||||
|
||||
### 4. 구역 현황 이력 (`zone_item_history`)
|
||||
|
||||
**용도**: 구역 현황의 등록/수정/삭제 이력 추적
|
||||
|
||||
| 주요 컬럼 | 설명 |
|
||||
|-----------|------|
|
||||
| `history_id` | PK |
|
||||
| `item_id` | 현황 ID (FK → workplace_zone_items) |
|
||||
| `action_type` | 행위 (created, updated, deleted) |
|
||||
| `changed_fields` | 변경된 필드명 (JSON) |
|
||||
| `old_values` | 이전 값 (JSON) |
|
||||
| `new_values` | 새 값 (JSON) |
|
||||
| `changed_by` | 변경자 ID |
|
||||
| `changed_at` | 변경 시간 |
|
||||
|
||||
**특징**:
|
||||
- 모든 변경사항 자동 기록
|
||||
- 누가, 언제, 무엇을 변경했는지 추적 가능
|
||||
- 삭제된 항목의 마지막 상태도 보존
|
||||
|
||||
---
|
||||
|
||||
### 5. 순회점검 세션 (`patrol_sessions`)
|
||||
|
||||
**용도**: 일일순회점검 수행 기록
|
||||
|
||||
**등록 경로**: 일일순회점검 페이지 (`/pages/inspection/daily-patrol.html`)
|
||||
|
||||
| 주요 컬럼 | 설명 |
|
||||
|-----------|------|
|
||||
| `session_id` | PK |
|
||||
| `patrol_date` | 점검 날짜 |
|
||||
| `patrol_time` | 시간대 (morning, afternoon) |
|
||||
| `category_id` | 점검 공장 |
|
||||
| `inspector_id` | 점검자 |
|
||||
| `status` | 상태 (in_progress, completed) |
|
||||
| `notes` | 특이사항 |
|
||||
|
||||
---
|
||||
|
||||
### 6. 순회점검 체크기록 (`patrol_check_records`)
|
||||
|
||||
**용도**: 각 작업장별 체크리스트 점검 결과
|
||||
|
||||
| 주요 컬럼 | 설명 |
|
||||
|-----------|------|
|
||||
| `record_id` | PK |
|
||||
| `session_id` | 세션 ID (FK → patrol_sessions) |
|
||||
| `workplace_id` | 작업장 ID |
|
||||
| `checklist_item_id` | 체크항목 ID |
|
||||
| `is_checked` | 점검 완료 여부 |
|
||||
| `check_result` | 결과 (pass, fail, na) |
|
||||
| `notes` | 비고 |
|
||||
|
||||
**특징**:
|
||||
- 점검 세션 완료 시 일괄 저장
|
||||
- 일시적인 점검 기록 (매일 새로 생성)
|
||||
|
||||
---
|
||||
|
||||
## 데이터 흐름도
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 구역 상세 페이지 │
|
||||
│ (zone-detail.html) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
┌───────────────┼───────────────┐
|
||||
▼ ▼ ▼
|
||||
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
||||
│ equipments │ │ workplace_ │ │ patrol_ │
|
||||
│ (설비) │ │ zone_items │ │ sessions │
|
||||
│ │ │ (현황) │ │ (점검) │
|
||||
└──────────────┘ └──────────────┘ └──────────────┘
|
||||
│ │ │
|
||||
│ ▼ ▼
|
||||
│ ┌──────────────┐ ┌──────────────┐
|
||||
│ │ zone_item_ │ │ patrol_check │
|
||||
│ │ photos │ │ _records │
|
||||
│ │ (사진) │ │ (체크기록) │
|
||||
│ └──────────────┘ └──────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ repair_ │
|
||||
│ requests │
|
||||
│ (수리요청) │
|
||||
└──────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 사용 시나리오
|
||||
|
||||
### 시나리오 1: 순회점검 중 미신고품 발견
|
||||
|
||||
1. 일일순회점검 진행 (`patrol_sessions` 생성)
|
||||
2. 체크리스트 점검 (`patrol_check_records` 저장)
|
||||
3. 미신고품 발견 → 구역 현황 등록 (`workplace_zone_items`)
|
||||
4. 사진 촬영 → 첨부 (`zone_item_photos`)
|
||||
|
||||
### 시나리오 2: 설비 상태 확인
|
||||
|
||||
1. 구역 상세 페이지 접근
|
||||
2. 지도에 설비 표시 (`equipments` 조회)
|
||||
3. 수리 필요 설비 확인 → 수리 요청 (`repair_requests`)
|
||||
|
||||
### 시나리오 3: 임시 적치물 관리
|
||||
|
||||
1. 작업 중 자재 임시 적치
|
||||
2. 구역 현황 등록 (item_type: temp_storage)
|
||||
3. 작업 완료 후 → 현황 삭제
|
||||
|
||||
---
|
||||
|
||||
## API 엔드포인트
|
||||
|
||||
| 기능 | Method | Endpoint |
|
||||
|------|--------|----------|
|
||||
| 설비 목록 | GET | `/api/equipments` |
|
||||
| 구역 현황 목록 | GET | `/api/patrol/workplaces/:id/zone-items` |
|
||||
| 구역 현황 등록 | POST | `/api/patrol/workplaces/:id/zone-items` |
|
||||
| 구역 현황 수정 | PUT | `/api/patrol/zone-items/:itemId` |
|
||||
| 구역 현황 삭제 | DELETE | `/api/patrol/zone-items/:itemId` |
|
||||
| 현황 사진 업로드 | POST | `/api/patrol/zone-items/photos` |
|
||||
| 순회점검 세션 | POST | `/api/patrol/sessions` |
|
||||
| 체크기록 저장 | POST | `/api/patrol/sessions/:id/records` |
|
||||
|
||||
---
|
||||
|
||||
## 주의사항
|
||||
|
||||
1. **설비 vs 구역 현황**
|
||||
- 설비: 회사 자산 (영구 관리)
|
||||
- 구역 현황: 일시적 상황 기록 (수시 변경)
|
||||
|
||||
2. **순회점검 체크기록 vs 구역 현황**
|
||||
- 체크기록: 당일 점검 결과 (일회성)
|
||||
- 구역 현황: 해소될 때까지 유지 (지속성)
|
||||
|
||||
3. **프로젝트 연결**
|
||||
- 구역 현황만 프로젝트 연결 가능
|
||||
- 설비는 작업장에만 연결
|
||||
|
||||
---
|
||||
|
||||
*최종 수정: 2026-02-05*
|
||||
Reference in New Issue
Block a user