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

@@ -142,8 +142,8 @@ class WorkReportReviewManager {
}
dummyAttendance.push({
id: `att_${worker.worker_id}_${dateStr}`,
worker_id: worker.worker_id,
id: `att_${worker.user_id}_${dateStr}`,
user_id: worker.user_id,
worker_name: worker.worker_name,
date: dateStr,
attendance_type: attendanceType,
@@ -196,7 +196,7 @@ class WorkReportReviewManager {
if (startDate) params.append('start_date', startDate);
if (endDate) params.append('end_date', endDate);
if (workerId) params.append('worker_id', workerId);
if (workerId) params.append('user_id', workerId);
if (projectId) params.append('project_id', projectId);
// 페이지네이션 (일단 많이 가져오기)
@@ -250,26 +250,26 @@ class WorkReportReviewManager {
// 각 보고서에 대해 근무시간 검증
this.reports.forEach(report => {
const attendance = this.attendanceData.find(att =>
att.worker_id === report.worker_id && att.date === report.report_date
att.user_id === report.user_id && att.date === report.report_date
);
if (attendance) {
const expectedHours = attendance.expected_hours;
const actualHours = this.getWorkerDailyHours(report.worker_id, report.report_date);
const actualHours = this.getWorkerDailyHours(report.user_id, report.report_date);
report.expected_hours = expectedHours;
report.actual_hours = actualHours;
report.attendance_type = attendance.attendance_type;
report.hours_status = this.getHoursStatus(actualHours, expectedHours);
report.is_reviewed = this.reviewedReports.has(`${report.worker_id}_${report.report_date}`);
report.is_reviewed = this.reviewedReports.has(`${report.user_id}_${report.report_date}`);
} else {
// 휴가 정보가 없으면 기본 8시간으로 가정
const actualHours = this.getWorkerDailyHours(report.worker_id, report.report_date);
const actualHours = this.getWorkerDailyHours(report.user_id, report.report_date);
report.expected_hours = 8;
report.actual_hours = actualHours;
report.attendance_type = 'NORMAL';
report.hours_status = this.getHoursStatus(actualHours, 8);
report.is_reviewed = this.reviewedReports.has(`${report.worker_id}_${report.report_date}`);
report.is_reviewed = this.reviewedReports.has(`${report.user_id}_${report.report_date}`);
}
});
}
@@ -277,7 +277,7 @@ class WorkReportReviewManager {
getWorkerDailyHours(workerId, date) {
// 해당 작업자의 특정 날짜 총 작업시간 계산
return this.reports
.filter(r => r.worker_id === workerId && r.report_date === date)
.filter(r => r.user_id === workerId && r.report_date === date)
.reduce((sum, r) => sum + (r.work_hours || 0), 0);
}
@@ -315,9 +315,9 @@ class WorkReportReviewManager {
(Math.random() * 6 + 2); // 정상 시간 (2-8시간)
dummyData.push({
id: 1000000 + i * 100 + worker.worker_id * 10 + j, // 고유 정수 ID
id: 1000000 + i * 100 + worker.user_id * 10 + j, // 고유 정수 ID
report_date: dateStr,
worker_id: worker.worker_id,
user_id: worker.user_id,
worker_name: worker.worker_name,
project_id: this.projects[Math.floor(Math.random() * this.projects.length)]?.project_id || 1,
project_name: this.projects[Math.floor(Math.random() * this.projects.length)]?.project_name || 'Unknown',
@@ -344,7 +344,7 @@ class WorkReportReviewManager {
if (workerSelect) {
workerSelect.innerHTML = '<option value="">전체 작업자</option>';
this.workers.forEach(worker => {
workerSelect.innerHTML += `<option value="${worker.worker_id}">${worker.worker_name}</option>`;
workerSelect.innerHTML += `<option value="${worker.user_id}">${worker.worker_name}</option>`;
});
}
@@ -540,7 +540,7 @@ class WorkReportReviewManager {
const grouped = {};
this.filteredReports.forEach(report => {
const key = `${report.worker_id}_${report.report_date}`;
const key = `${report.user_id}_${report.report_date}`;
if (!grouped[key]) {
grouped[key] = [];
}
@@ -569,7 +569,7 @@ class WorkReportReviewManager {
selectWorkerDate(workerId, date) {
// 해당 작업자의 특정 날짜 보고서들을 선택
const reports = this.filteredReports.filter(r =>
r.worker_id == workerId && r.report_date === date
r.user_id == workerId && r.report_date === date
);
if (reports.length > 0) {
@@ -600,7 +600,7 @@ class WorkReportReviewManager {
// const response = await fetch(`${API}/daily-work-reports/review`, {
// method: 'POST',
// headers: { ...getAuthHeaders(), 'Content-Type': 'application/json' },
// body: JSON.stringify({ worker_id: workerId, report_date: date, reviewed: true })
// body: JSON.stringify({ user_id: workerId, report_date: date, reviewed: true })
// });
// 현재는 로컬 상태만 업데이트
@@ -608,7 +608,7 @@ class WorkReportReviewManager {
// 해당 보고서들의 검토 상태 업데이트
this.reports.forEach(report => {
if (report.worker_id == workerId && report.report_date === date) {
if (report.user_id == workerId && report.report_date === date) {
report.is_reviewed = true;
}
});
@@ -627,7 +627,7 @@ class WorkReportReviewManager {
}
getWorkerName(workerId) {
const worker = this.workers.find(w => w.worker_id == workerId);
const worker = this.workers.find(w => w.user_id == workerId);
return worker ? worker.worker_name : `작업자${workerId}`;
}
@@ -680,7 +680,7 @@ class WorkReportReviewManager {
<div class="panel-actions">
${!report.is_reviewed && report.hours_status === 'NORMAL' && !allReports.some(r => r.work_status_id === 2) ?
`<button type="button" class="panel-btn save" onclick="workReportReview.markAsReviewed('${report.worker_id}', '${report.report_date}')">
`<button type="button" class="panel-btn save" onclick="workReportReview.markAsReviewed('${report.user_id}', '${report.report_date}')">
✅ 검토완료 처리
</button>` : ''
}