feat: 작업자 관리 개선 - 작업보고서 표시/현장직 구분/퇴사 처리

작업자 관리 페이지에 3가지 상태 관리 기능을 추가했습니다:
1. 작업 보고서 표시 여부 (관리자 등은 작업보고서에 표시 안함)
2. 현장직/사무직 구분 (사무직은 출퇴근 관리 불필요)
3. 퇴사 처리 (퇴사자 별도 표시)

## 주요 변경사항

### 데이터베이스
- **마이그레이션**: 20260119095549_add_worker_display_fields.js
  - workers 테이블에 show_in_work_reports (BOOLEAN) 추가
  - workers 테이블에 employment_status (ENUM: employed, resigned) 추가

### 백엔드
- **workerModel.js**: create, update 함수에 새로운 필드 처리 로직 추가

### 프론트엔드
- **worker-management.html**: 작업자 모달에 3가지 체크박스 추가
  - 작업 보고서에 표시
  - 현장직 (활성화) - 사무직과 구분
  - 퇴사 처리
- **worker-management.js**:
  - 퇴사자 카드 렌더링 시 별도 스타일 적용
  - 새 필드 값 로드 및 저장 처리
- **daily-work-report.js**:
  - 작업 보고서 작성 시 show_in_work_reports=true이고 퇴사하지 않은 작업자만 표시

## 배포 절차
```bash
cd api.hyungi.net
npm run db:migrate
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-01-19 10:02:32 +09:00
parent 70630b380a
commit 25cca1482e
5 changed files with 129 additions and 28 deletions

View File

@@ -0,0 +1,34 @@
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.up = async function(knex) {
await knex.schema.alterTable('workers', (table) => {
// 작업 보고서 표시 여부 (기본값: true, 작업자는 표시, 관리자는 선택 가능)
table.boolean('show_in_work_reports')
.defaultTo(true)
.notNullable()
.comment('작업 보고서에 표시 여부');
// 재직 상태 (employed: 재직, resigned: 퇴사)
table.enum('employment_status', ['employed', 'resigned'])
.defaultTo('employed')
.notNullable()
.comment('재직 상태');
});
console.log('✅ workers 테이블에 show_in_work_reports, employment_status 컬럼 추가 완료');
};
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.down = async function(knex) {
await knex.schema.alterTable('workers', (table) => {
table.dropColumn('show_in_work_reports');
table.dropColumn('employment_status');
});
console.log('✅ workers 테이블에서 show_in_work_reports, employment_status 컬럼 삭제 완료');
};

View File

@@ -19,14 +19,16 @@ const create = async (worker, callback) => {
join_date = null,
salary = null,
annual_leave = null,
status = 'active'
status = 'active',
show_in_work_reports = true,
employment_status = 'employed'
} = worker;
const [result] = await db.query(
`INSERT INTO workers
(worker_name, job_type, join_date, salary, annual_leave, status)
VALUES (?, ?, ?, ?, ?, ?)`,
[worker_name, job_type, formatDate(join_date), salary, annual_leave, status]
(worker_name, job_type, join_date, salary, annual_leave, status, show_in_work_reports, employment_status)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
[worker_name, job_type, formatDate(join_date), salary, annual_leave, status, show_in_work_reports, employment_status]
);
callback(null, result.insertId);
@@ -81,7 +83,9 @@ const update = async (worker, callback) => {
status,
join_date,
salary,
annual_leave
annual_leave,
show_in_work_reports,
employment_status
} = worker;
// 업데이트할 필드만 동적으로 구성
@@ -112,6 +116,14 @@ const update = async (worker, callback) => {
updates.push('annual_leave = ?');
values.push(annual_leave);
}
if (show_in_work_reports !== undefined) {
updates.push('show_in_work_reports = ?');
values.push(show_in_work_reports);
}
if (employment_status !== undefined) {
updates.push('employment_status = ?');
values.push(employment_status);
}
if (updates.length === 0) {
callback(new Error('업데이트할 필드가 없습니다'));