Files
TK-FB-Project/api.hyungi.net/routes/userRoutes.js
Hyungi Ahn 74d3a78aa3 feat: 페이지 구조 재구성 및 사이드바 네비게이션 구현
- 페이지 폴더 재구성: safety/, attendance/ 폴더 신규 생성
  - work/ → safety/: 이슈 신고, 출입 신청 관련 페이지 이동
  - common/ → attendance/: 근태/휴가 관련 페이지 이동
  - admin/ 정리: safety-* 파일들을 safety/로 이동

- 사이드바 네비게이션 메뉴 구현
  - 카테고리별 메뉴: 작업관리, 안전관리, 근태관리, 시스템관리
  - 접기/펼치기 기능 및 상태 저장
  - 관리자 전용 메뉴 자동 표시/숨김

- 날씨 API 연동 (기상청 단기예보)
  - TBM 및 navbar에 현재 날씨 표시
  - weatherService.js 추가

- 안전 체크리스트 확장
  - 기본/날씨별/작업별 체크 유형 추가
  - checklist-manage.html 페이지 추가

- 이슈 신고 시스템 구현
  - workIssueController, workIssueModel, workIssueRoutes 추가

- DB 마이그레이션 파일 추가 (실행 대기)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 14:27:22 +09:00

156 lines
5.0 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/authMiddleware');
const logger = require('../utils/logger');
/**
* 모든 라우트에 인증 미들웨어 적용
*/
router.use(verifyToken);
/**
* 관리자 권한 확인 미들웨어
*/
const adminOnly = (req, res, next) => {
const userRole = req.user?.role?.toLowerCase();
if (req.user && (userRole === 'admin' || userRole === 'system' || userRole === 'system admin')) {
next();
} else {
logger.warn('관리자 권한 없는 접근 시도', {
userId: req.user?.user_id,
username: req.user?.username,
role: req.user?.role,
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.worker_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.worker_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 worker_id = ? AND report_date BETWEEN ? AND ? ORDER BY report_date DESC',
[req.user.worker_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 worker_id = ? AND YEAR(record_date) = ? AND MONTH(record_date) = ?`,
[req.user.worker_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 });
}
});
// ========== 자신의 페이지 권한 조회 (Admin 불필요) ==========
// 📄 사용자 페이지 접근 권한 조회 (자신 또는 Admin)
router.get('/:id/page-access', (req, res, next) => {
const requestedId = parseInt(req.params.id);
const currentUserId = req.user?.user_id;
const userRole = req.user?.role?.toLowerCase();
// 자신의 권한 조회이거나 Admin인 경우 허용
if (requestedId === currentUserId || userRole === 'admin' || userRole === 'system admin') {
return userController.getUserPageAccess(req, res, next);
}
return res.status(403).json({
success: false,
message: '자신의 페이지 권한만 조회할 수 있습니다'
});
});
// ========== 관리자 전용 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);
// 🗑️ 사용자 삭제
router.delete('/:id', userController.deleteUser);
// 🔐 사용자 페이지 접근 권한 업데이트 (Admin만)
router.put('/:id/page-access', userController.updateUserPageAccess);
module.exports = router;