Files
tk-factory-services/system1-factory/api/routes/userRoutes.js
Hyungi Ahn abd7564e6b 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>
2026-03-05 13:13:10 +09:00

154 lines
5.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 사용자 관리 라우터
*
* 사용자 CRUD 및 상태 관리를 위한 API 라우트 정의
*
* @author TK-FB-Project
* @since 2025-12-11
*/
const express = require('express');
const router = express.Router();
const userController = require('../controllers/userController');
const { verifyToken } = require('../middlewares/auth');
const logger = require('../utils/logger');
/**
* 모든 라우트에 인증 미들웨어 적용
*/
router.use(verifyToken);
/**
* 관리자 권한 확인 미들웨어
* role 또는 access_level로 관리자 확인
*/
const adminOnly = (req, res, next) => {
const userRole = req.user?.role?.toLowerCase();
const accessLevel = req.user?.access_level?.toLowerCase();
// role 기반 확인
const isAdminByRole = userRole === 'admin' || userRole === 'system' || userRole === 'system admin';
// access_level 기반 확인 (role이 없는 경우 대비)
const isAdminByAccessLevel = accessLevel === 'admin' || accessLevel === 'system';
if (req.user && (isAdminByRole || isAdminByAccessLevel)) {
next();
} else {
logger.warn('관리자 권한 없는 접근 시도', {
userId: req.user?.user_id,
username: req.user?.username,
role: req.user?.role,
accessLevel: req.user?.access_level,
url: req.originalUrl
});
return res.status(403).json({
success: false,
message: '관리자 권한이 필요합니다'
});
}
};
// ========== 개인 정보 조회 API (관리자 권한 불필요) ==========
// 내 정보 조회
router.get('/me', userController.getMyInfo || ((req, res) => res.json({ success: true, data: req.user })));
// 내 출근 기록 조회
router.get('/me/attendance-records', async (req, res) => {
try {
const { year, month } = req.query;
const AttendanceModel = require('../models/attendanceModel');
const startDate = `${year}-${String(month).padStart(2, '0')}-01`;
const endDate = `${year}-${String(month).padStart(2, '0')}-31`;
const records = await AttendanceModel.getDailyRecords(startDate, endDate, req.user.user_id);
res.json({ success: true, data: records });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
// 내 연차 잔액 조회
router.get('/me/vacation-balance', async (req, res) => {
try {
const AttendanceModel = require('../models/attendanceModel');
const year = req.query.year || new Date().getFullYear();
const balance = await AttendanceModel.getWorkerVacationBalance(req.user.user_id, year);
res.json({ success: true, data: balance });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
// 내 작업 보고서 조회
router.get('/me/work-reports', async (req, res) => {
try {
const { startDate, endDate } = req.query;
const db = require('../config/database');
const reports = await db.query(
'SELECT * FROM daily_work_reports WHERE user_id = ? AND report_date BETWEEN ? AND ? ORDER BY report_date DESC',
[req.user.user_id, startDate, endDate]
);
res.json({ success: true, data: reports });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
// 내 월별 통계
router.get('/me/monthly-stats', async (req, res) => {
try {
const { year, month } = req.query;
const { getDb } = require('../dbPool');
const db = await getDb();
const [stats] = await db.execute(
`SELECT
SUM(total_work_hours) as month_hours,
COUNT(DISTINCT record_date) as work_days
FROM daily_attendance_records
WHERE user_id = ? AND YEAR(record_date) = ? AND MONTH(record_date) = ?`,
[req.user.user_id, year, month]
);
res.json({ success: true, data: stats[0] || { month_hours: 0, work_days: 0 } });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
// ========== 페이지 권한 조회는 pageAccessRoutes.js에서 처리 ==========
// GET /:id/page-access → /api/users/:userId/page-access (pageAccessRoutes.js)
// tkuser의 user_page_permissions 테이블을 조회하는 통합 핸들러 사용
// ========== 관리자 전용 API ==========
/**
* 모든 라우트에 관리자 권한 적용
*/
router.use(adminOnly);
// 📋 사용자 목록 조회
router.get('/', userController.getAllUsers);
// 👤 특정 사용자 조회
router.get('/:id', userController.getUserById);
// 새 사용자 생성
router.post('/', userController.createUser);
// ✏️ 사용자 정보 수정
router.put('/:id', userController.updateUser);
// 🔄 사용자 상태 변경
router.put('/:id/status', userController.updateUserStatus);
// 🔑 사용자 비밀번호 초기화 (000000)
router.post('/:id/reset-password', userController.resetUserPassword);
// 🗑️ 사용자 비활성화 (Soft Delete)
router.delete('/:id', userController.deleteUser);
// 💀 사용자 영구 삭제 (Hard Delete)
router.delete('/:id/permanent', userController.permanentDeleteUser);
// 🔐 사용자 페이지 접근 권한 업데이트 (Admin만)
router.put('/:id/page-access', userController.updateUserPageAccess);
module.exports = router;