refactor: worker_id → user_id 전체 마이그레이션 (Phase 1-4)

sso_users.user_id를 단일 식별자로 통합. JWT에서 worker_id 제거,
department_id/is_production 추가. 백엔드 15개 모델, 11개 컨트롤러,
4개 서비스, 7개 라우트, 프론트엔드 32+ JS/11+ HTML 변환.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-03-05 13:13:10 +09:00
parent 2197cdb3d5
commit abd7564e6b
90 changed files with 1790 additions and 925 deletions

View File

@@ -329,7 +329,7 @@
workStatus = {};
workers.forEach(w => {
const record = records.find(r => r.worker_id === w.worker_id);
const record = records.find(r => r.user_id === w.user_id);
// 입사일 이전인지 확인
const joinDate = w.join_date ? w.join_date.split('T')[0] : null;
@@ -337,7 +337,7 @@
if (isBeforeJoin) {
// 입사 전 날짜
workStatus[w.worker_id] = {
workStatus[w.user_id] = {
isPresent: false,
type: 'not_hired',
hours: 0,
@@ -396,7 +396,7 @@
const typeInfo = attendanceTypes.find(t => t.value === type);
workStatus[w.worker_id] = {
workStatus[w.user_id] = {
isPresent: record.is_present === 1 || typeInfo?.isLeave,
type: type,
hours: typeInfo !== undefined ? typeInfo.hours : 8,
@@ -406,7 +406,7 @@
};
} else {
// 출근 체크 기록이 없는 경우 - 결근 상태
workStatus[w.worker_id] = {
workStatus[w.user_id] = {
isPresent: false,
type: 'normal',
hours: 8,
@@ -435,7 +435,7 @@
}
tbody.innerHTML = workers.map((w, idx) => {
const s = workStatus[w.worker_id];
const s = workStatus[w.user_id];
// 미입사 상태 처리
if (s.isNotHired) {
@@ -503,7 +503,7 @@
${statusText}
</td>
<td>
<select class="type-select" onchange="updateType(${w.worker_id}, this.value)">
<select class="type-select" onchange="updateType(${w.user_id}, this.value)">
${attendanceTypes.map(t => `
<option value="${t.value}" ${s.type === t.value ? 'selected' : ''}>${t.label}</option>
`).join('')}
@@ -513,7 +513,7 @@
<td class="hours-cell">
${showOvertimeInput ? `
<input type="number" class="overtime-input" value="${s.overtimeHours}" min="0" max="8" step="0.5"
onchange="updateOvertime(${w.worker_id}, this.value)">
onchange="updateOvertime(${w.user_id}, this.value)">
` : '-'}
</td>
<td class="hours-cell"><strong>${totalHours}h</strong></td>
@@ -551,9 +551,9 @@
function setAllNormal() {
workers.forEach(w => {
workStatus[w.worker_id].type = 'normal';
workStatus[w.worker_id].hours = 8;
workStatus[w.worker_id].overtimeHours = 0;
workStatus[w.user_id].type = 'normal';
workStatus[w.user_id].hours = 8;
workStatus[w.user_id].overtimeHours = 0;
});
render();
updateSummary();
@@ -638,14 +638,14 @@
// 미입사자 제외하고 저장할 데이터 생성
const recordsToSave = workers
.filter(w => !workStatus[w.worker_id]?.isNotHired)
.filter(w => !workStatus[w.user_id]?.isNotHired)
.map(w => {
const s = workStatus[w.worker_id];
const s = workStatus[w.user_id];
const totalHours = s.type === 'overtime' ? s.hours + s.overtimeHours : s.hours;
return {
record_date: date,
worker_id: w.worker_id,
user_id: w.user_id,
attendance_type_id: typeIdMap[s.type] || 1,
vacation_type_id: vacationTypeIdMap[s.type] || null,
total_work_hours: totalHours,
@@ -674,8 +674,8 @@
alert(`${ok}명 저장 완료`);
isAlreadySaved = true;
workers.forEach(w => {
if (workStatus[w.worker_id]) {
workStatus[w.worker_id].isSaved = true;
if (workStatus[w.user_id]) {
workStatus[w.user_id].isSaved = true;
}
});
render();