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

@@ -36,19 +36,19 @@ const createDailyWorkReport = asyncHandler(async (req, res) => {
* 기여자별 요약 조회
*/
const getContributorsSummary = asyncHandler(async (req, res) => {
const { date, worker_id } = req.query;
const { date, user_id } = req.query;
if (!date || !worker_id) {
return res.status(400).json({ error: 'date와 worker_id가 필요합니다.' });
if (!date || !user_id) {
return res.status(400).json({ error: 'date와 user_id가 필요합니다.' });
}
const data = await dailyWorkReportModel.getContributorsByDate(date, worker_id);
const data = await dailyWorkReportModel.getContributorsByDate(date, user_id);
const totalHours = data.reduce((sum, contributor) => sum + parseFloat(contributor.total_hours || 0), 0);
const result = {
date,
worker_id,
user_id,
contributors: data,
total_contributors: data.length,
grand_total_hours: totalHours
@@ -61,13 +61,13 @@ const getContributorsSummary = asyncHandler(async (req, res) => {
* 개인 누적 현황 조회
*/
const getMyAccumulatedData = async (req, res) => {
const { date, worker_id } = req.query;
const { date, user_id } = req.query;
const created_by = req.user?.user_id || req.user?.id;
if (!date || !worker_id) {
if (!date || !user_id) {
return res.status(400).json({
error: 'date와 worker_id가 필요합니다.',
example: 'date=2024-06-16&worker_id=1'
error: 'date와 user_id가 필요합니다.',
example: 'date=2024-06-16&user_id=1'
});
}
@@ -78,11 +78,11 @@ const getMyAccumulatedData = async (req, res) => {
}
try {
const data = await dailyWorkReportModel.getMyAccumulatedHours(date, worker_id, created_by);
const data = await dailyWorkReportModel.getMyAccumulatedHours(date, user_id, created_by);
res.json({
date,
worker_id,
user_id,
created_by,
my_data: data,
timestamp: new Date().toISOString()
@@ -187,14 +187,14 @@ const getDailyWorkReportsByDate = async (req, res) => {
* 작업보고서 검색 (페이지네이션 포함)
*/
const searchWorkReports = async (req, res) => {
const { start_date, end_date, worker_id, project_id, work_status_id, page = 1, limit = 20 } = req.query;
const { start_date, end_date, user_id, project_id, work_status_id, page = 1, limit = 20 } = req.query;
const created_by = req.user?.user_id || req.user?.id;
if (!start_date || !end_date) {
return res.status(400).json({
error: 'start_date와 end_date가 필요합니다.',
example: 'start_date=2024-01-01&end_date=2024-01-31',
optional: ['worker_id', 'project_id', 'work_status_id', 'page', 'limit']
optional: ['user_id', 'project_id', 'work_status_id', 'page', 'limit']
});
}
@@ -207,7 +207,7 @@ const searchWorkReports = async (req, res) => {
const searchParams = {
start_date,
end_date,
worker_id: worker_id ? parseInt(worker_id) : null,
user_id: user_id ? parseInt(user_id) : null,
project_id: project_id ? parseInt(project_id) : null,
work_status_id: work_status_id ? parseInt(work_status_id) : null,
created_by,
@@ -377,7 +377,7 @@ const removeDailyWorkReport = async (req, res) => {
* 작업자의 특정 날짜 전체 삭제
*/
const removeDailyWorkReportByDateAndWorker = async (req, res) => {
const { date, worker_id } = req.params;
const { date, user_id } = req.params;
const deleted_by = req.user?.user_id || req.user?.id;
const access_level = req.user?.access_level || req.user?.role;
@@ -397,20 +397,20 @@ const removeDailyWorkReportByDateAndWorker = async (req, res) => {
}
try {
const affectedRows = await dailyWorkReportModel.removeByDateAndWorker(date, worker_id, deleted_by);
const affectedRows = await dailyWorkReportModel.removeByDateAndWorker(date, user_id, deleted_by);
if (affectedRows === 0) {
return res.status(404).json({
error: '삭제할 작업보고서를 찾을 수 없습니다.',
date: date,
worker_id: worker_id
user_id: user_id
});
}
res.json({
message: `${date} 날짜의 작업자 ${worker_id} 작업보고서 ${affectedRows}개가 삭제되었습니다.`,
message: `${date} 날짜의 작업자 ${user_id} 작업보고서 ${affectedRows}개가 삭제되었습니다.`,
date,
worker_id,
user_id,
affected_rows: affectedRows,
deleted_by,
timestamp: new Date().toISOString()
@@ -642,21 +642,21 @@ const deleteErrorType = asyncHandler(async (req, res) => {
* 누적 현황 조회
*/
const getAccumulatedReports = async (req, res) => {
const { date, worker_id } = req.query;
const { date, user_id } = req.query;
if (!date || !worker_id) {
if (!date || !user_id) {
return res.status(400).json({
error: 'date와 worker_id가 필요합니다.',
example: 'date=2024-06-16&worker_id=1'
error: 'date와 user_id가 필요합니다.',
example: 'date=2024-06-16&user_id=1'
});
}
try {
const data = await dailyWorkReportModel.getAccumulatedReportsByDate(date, worker_id);
const data = await dailyWorkReportModel.getAccumulatedReportsByDate(date, user_id);
res.json({
date,
worker_id,
user_id,
total_entries: data.length,
accumulated_data: data,
timestamp: new Date().toISOString()
@@ -678,7 +678,7 @@ const createFromTbm = async (req, res) => {
const {
tbm_assignment_id,
tbm_session_id,
worker_id,
user_id,
project_id,
work_type_id,
report_date,
@@ -691,10 +691,10 @@ const createFromTbm = async (req, res) => {
} = req.body;
// 필수 필드 검증
if (!tbm_assignment_id || !tbm_session_id || !worker_id || !report_date || !total_hours) {
if (!tbm_assignment_id || !tbm_session_id || !user_id || !report_date || !total_hours) {
return res.status(400).json({
success: false,
message: '필수 필드가 누락되었습니다. (assignment_id, session_id, worker_id, report_date, total_hours)'
message: '필수 필드가 누락되었습니다. (assignment_id, session_id, user_id, report_date, total_hours)'
});
}
@@ -704,7 +704,7 @@ const createFromTbm = async (req, res) => {
const reportData = {
tbm_assignment_id,
tbm_session_id,
worker_id,
user_id,
project_id,
work_type_id,
report_date,