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

@@ -392,7 +392,7 @@
// 데이터 정리
vacationData = {};
workers.forEach(w => {
vacationData[w.worker_id] = {
vacationData[w.user_id] = {
carryover: 0,
annual: 0,
longService: 0,
@@ -403,9 +403,9 @@
// 잔액 데이터 매핑
balances.forEach(b => {
if (!vacationData[b.worker_id]) return;
if (!vacationData[b.user_id]) return;
const code = b.type_code || '';
const data = vacationData[b.worker_id];
const data = vacationData[b.user_id];
if (code === 'CARRYOVER' || b.type_name === '이월') {
data.carryover = b.total_days || 0;
@@ -443,7 +443,7 @@
}
tbody.innerHTML = workers.map((w, idx) => {
const d = vacationData[w.worker_id] || { carryover: 0, annual: 0, longService: 0, specials: [], totalUsed: 0 };
const d = vacationData[w.user_id] || { carryover: 0, annual: 0, longService: 0, specials: [], totalUsed: 0 };
const carryover = parseFloat(d.carryover) || 0;
const annual = parseFloat(d.annual) || 0;
const longService = parseFloat(d.longService) || 0;
@@ -454,29 +454,29 @@
const remainingClass = remaining > 0 ? 'positive' : remaining < 0 ? 'negative' : 'zero';
return `
<tr data-worker-id="${w.worker_id}">
<tr data-user-id="${w.user_id}">
<td>${idx + 1}</td>
<td class="worker-name">${w.worker_name}</td>
<td>
<input type="number" class="num-input ${carryover < 0 ? 'negative' : ''}"
value="${carryover}" step="0.5"
data-field="carryover"
onchange="updateField(${w.worker_id}, 'carryover', this.value)">
onchange="updateField(${w.user_id}, 'carryover', this.value)">
</td>
<td>
<input type="number" class="num-input"
value="${annual}" step="0.5"
data-field="annual"
onchange="updateField(${w.worker_id}, 'annual', this.value)">
onchange="updateField(${w.user_id}, 'annual', this.value)">
</td>
<td>
<input type="number" class="num-input"
value="${longService}" step="0.5"
data-field="longService"
onchange="updateField(${w.worker_id}, 'longService', this.value)">
onchange="updateField(${w.user_id}, 'longService', this.value)">
</td>
<td>
<button class="special-btn" onclick="openSpecialModal(${w.worker_id}, '${w.worker_name}')">
<button class="special-btn" onclick="openSpecialModal(${w.user_id}, '${w.worker_name}')">
${(d.specials || []).length > 0 ? `${specialTotal}` : '추가'}
${(d.specials || []).length > 0 ? `<span class="special-count">${d.specials.length}</span>` : ''}
</button>
@@ -497,7 +497,7 @@
vacationData[workerId][field] = val;
// 입력 스타일 업데이트
const input = document.querySelector(`tr[data-worker-id="${workerId}"] input[data-field="${field}"]`);
const input = document.querySelector(`tr[data-user-id="${workerId}"] input[data-field="${field}"]`);
if (input) {
input.classList.toggle('negative', val < 0);
}
@@ -508,7 +508,7 @@
}
function updateRowTotals(workerId) {
const row = document.querySelector(`tr[data-worker-id="${workerId}"]`);
const row = document.querySelector(`tr[data-user-id="${workerId}"]`);
if (!row) return;
const d = vacationData[workerId];
@@ -668,12 +668,12 @@
// 데이터 수집
for (const w of workers) {
const d = vacationData[w.worker_id];
const d = vacationData[w.user_id];
if (!d) continue;
if (typeIdMap['CARRYOVER']) {
balancesToSave.push({
worker_id: w.worker_id,
user_id: w.user_id,
vacation_type_id: typeIdMap['CARRYOVER'],
year: currentYear,
total_days: d.carryover
@@ -681,7 +681,7 @@
}
if (typeIdMap['ANNUAL']) {
balancesToSave.push({
worker_id: w.worker_id,
user_id: w.user_id,
vacation_type_id: typeIdMap['ANNUAL'],
year: currentYear,
total_days: d.annual
@@ -689,7 +689,7 @@
}
if (typeIdMap['LONG_SERVICE']) {
balancesToSave.push({
worker_id: w.worker_id,
user_id: w.user_id,
vacation_type_id: typeIdMap['LONG_SERVICE'],
year: currentYear,
total_days: d.longService
@@ -726,7 +726,7 @@
}
if (specialTypeId) {
balancesToSave.push({
worker_id: w.worker_id,
user_id: w.user_id,
vacation_type_id: specialTypeId,
year: currentYear,
total_days: special.days,