refactor: vacationRequest 콜백→async/await 전환

- 모델: 콜백 래퍼 제거, 결과 직접 반환 (async/await 네이티브)
- 컨트롤러: 중첩 콜백 → 플랫한 async/await 구조
- console.error → logger.error 전환
- 코드 566줄 → 247줄 (모델) + 컨트롤러 대폭 간소화

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-02-25 08:59:00 +09:00
parent 9f35d33f65
commit c29a1506bb
2 changed files with 248 additions and 624 deletions

View File

@@ -4,8 +4,7 @@
*/ */
const vacationRequestModel = require('../models/vacationRequestModel'); const vacationRequestModel = require('../models/vacationRequestModel');
// TODO: workerVacationBalanceModel 구현 필요 const logger = require('../utils/logger');
// const workerVacationBalanceModel = require('../models/workerVacationBalanceModel');
const vacationRequestController = { const vacationRequestController = {
/** /**
@@ -16,81 +15,33 @@ const vacationRequestController = {
const { worker_id, vacation_type_id, start_date, end_date, days_used, reason } = req.body; const { worker_id, vacation_type_id, start_date, end_date, days_used, reason } = req.body;
const requested_by = req.user.user_id; const requested_by = req.user.user_id;
// 필수 필드 검증
if (!worker_id || !vacation_type_id || !start_date || !end_date || !days_used) { if (!worker_id || !vacation_type_id || !start_date || !end_date || !days_used) {
return res.status(400).json({ return res.status(400).json({ success: false, message: '필수 필드가 누락되었습니다' });
success: false,
message: '필수 필드가 누락되었습니다'
});
} }
// 날짜 유효성 검증 if (new Date(end_date) < new Date(start_date)) {
const startDate = new Date(start_date); return res.status(400).json({ success: false, message: '종료일은 시작일보다 이후여야 합니다' });
const endDate = new Date(end_date);
if (endDate < startDate) {
return res.status(400).json({
success: false,
message: '종료일은 시작일보다 이후여야 합니다'
});
} }
// 기간 중복 체크 // 기간 중복 체크
vacationRequestModel.checkOverlap(worker_id, start_date, end_date, null, (err, results) => { const overlapRows = await vacationRequestModel.checkOverlap(worker_id, start_date, end_date);
if (err) { if (overlapRows[0].count > 0) {
console.error('기간 중복 체크 오류:', err); return res.status(400).json({ success: false, message: '해당 기간에 이미 신청된 휴가가 있습니다' });
return res.status(500).json({
success: false,
message: '기간 중복 체크 중 오류가 발생했습니다'
});
} }
if (results[0].count > 0) { const result = await vacationRequestModel.create({
return res.status(400).json({ worker_id, vacation_type_id, start_date, end_date,
success: false, days_used, reason: reason || null, status: 'pending', requested_by
message: '해당 기간에 이미 신청된 휴가가 있습니다'
}); });
}
// TODO: 잔여 연차 확인 로직 구현 필요
// 현재는 잔여 연차 확인 없이 신청 가능
// 휴가 신청 생성
const requestData = {
worker_id,
vacation_type_id,
start_date,
end_date,
days_used,
reason: reason || null,
status: 'pending',
requested_by
};
vacationRequestModel.create(requestData, (err, result) => {
if (err) {
console.error('휴가 신청 생성 오류:', err);
return res.status(500).json({
success: false,
message: '휴가 신청 생성 중 오류가 발생했습니다'
});
}
res.status(201).json({ res.status(201).json({
success: true, success: true,
message: '휴가 신청이 완료되었습니다', message: '휴가 신청이 완료되었습니다',
data: { data: { request_id: result.insertId }
request_id: result.insertId
}
});
});
}); });
} catch (error) { } catch (error) {
console.error('휴가 신청 생성 오류:', error); logger.error('휴가 신청 생성 오류:', error);
res.status(500).json({ res.status(500).json({ success: false, message: '서버 오류가 발생했습니다' });
success: false,
message: '서버 오류가 발생했습니다'
});
} }
}, },
@@ -112,33 +63,15 @@ const vacationRequestController = {
if (req.user.worker_id) { if (req.user.worker_id) {
filters.worker_id = req.user.worker_id; filters.worker_id = req.user.worker_id;
} else { } else {
return res.status(403).json({ return res.status(403).json({ success: false, message: '권한이 없습니다' });
success: false,
message: '권한이 없습니다'
});
} }
} }
vacationRequestModel.getAll(filters, (err, results) => { const results = await vacationRequestModel.getAll(filters);
if (err) { res.json({ success: true, data: results });
console.error('휴가 신청 목록 조회 오류:', err);
return res.status(500).json({
success: false,
message: '휴가 신청 목록 조회 중 오류가 발생했습니다'
});
}
res.json({
success: true,
data: results
});
});
} catch (error) { } catch (error) {
console.error('휴가 신청 목록 조회 오류:', error); logger.error('휴가 신청 목록 조회 오류:', error);
res.status(500).json({ res.status(500).json({ success: false, message: '서버 오류가 발생했습니다' });
success: false,
message: '서버 오류가 발생했습니다'
});
} }
}, },
@@ -147,45 +80,22 @@ const vacationRequestController = {
*/ */
async getRequestById(req, res) { async getRequestById(req, res) {
try { try {
const { id } = req.params; const results = await vacationRequestModel.getById(req.params.id);
vacationRequestModel.getById(id, (err, results) => {
if (err) {
console.error('휴가 신청 조회 오류:', err);
return res.status(500).json({
success: false,
message: '휴가 신청 조회 중 오류가 발생했습니다'
});
}
if (results.length === 0) { if (results.length === 0) {
return res.status(404).json({ return res.status(404).json({ success: false, message: '해당 휴가 신청을 찾을 수 없습니다' });
success: false,
message: '해당 휴가 신청을 찾을 수 없습니다'
});
} }
const request = results[0]; const request = results[0];
// 권한 검증: 관리자 또는 본인만 조회 가능
if (req.user.access_level !== 'system' && req.user.worker_id !== request.worker_id) { if (req.user.access_level !== 'system' && req.user.worker_id !== request.worker_id) {
return res.status(403).json({ return res.status(403).json({ success: false, message: '권한이 없습니다' });
success: false,
message: '권한이 없습니다'
});
} }
res.json({ res.json({ success: true, data: request });
success: true,
data: request
});
});
} catch (error) { } catch (error) {
console.error('휴가 신청 조회 오류:', error); logger.error('휴가 신청 조회 오류:', error);
res.status(500).json({ res.status(500).json({ success: false, message: '서버 오류가 발생했습니다' });
success: false,
message: '서버 오류가 발생했습니다'
});
} }
}, },
@@ -197,39 +107,19 @@ const vacationRequestController = {
const { id } = req.params; const { id } = req.params;
const { start_date, end_date, days_used, reason } = req.body; const { start_date, end_date, days_used, reason } = req.body;
// 기존 신청 조회 const results = await vacationRequestModel.getById(id);
vacationRequestModel.getById(id, (err, results) => {
if (err) {
console.error('휴가 신청 조회 오류:', err);
return res.status(500).json({
success: false,
message: '휴가 신청 조회 중 오류가 발생했습니다'
});
}
if (results.length === 0) { if (results.length === 0) {
return res.status(404).json({ return res.status(404).json({ success: false, message: '해당 휴가 신청을 찾을 수 없습니다' });
success: false,
message: '해당 휴가 신청을 찾을 수 없습니다'
});
} }
const existingRequest = results[0]; const existingRequest = results[0];
// 권한 검증
if (req.user.access_level !== 'system' && req.user.worker_id !== existingRequest.worker_id) { if (req.user.access_level !== 'system' && req.user.worker_id !== existingRequest.worker_id) {
return res.status(403).json({ return res.status(403).json({ success: false, message: '권한이 없습니다' });
success: false,
message: '권한이 없습니다'
});
} }
// 대기 중인 신청만 수정 가능
if (existingRequest.status !== 'pending') { if (existingRequest.status !== 'pending') {
return res.status(400).json({ return res.status(400).json({ success: false, message: '승인/거부된 신청은 수정할 수 없습니다' });
success: false,
message: '승인/거부된 신청은 수정할 수 없습니다'
});
} }
const updateData = {}; const updateData = {};
@@ -243,68 +133,19 @@ const vacationRequestController = {
const newStartDate = start_date || existingRequest.start_date; const newStartDate = start_date || existingRequest.start_date;
const newEndDate = end_date || existingRequest.end_date; const newEndDate = end_date || existingRequest.end_date;
vacationRequestModel.checkOverlap( const overlapRows = await vacationRequestModel.checkOverlap(
existingRequest.worker_id, existingRequest.worker_id, newStartDate, newEndDate, id
newStartDate,
newEndDate,
id,
(err, overlapResults) => {
if (err) {
console.error('기간 중복 체크 오류:', err);
return res.status(500).json({
success: false,
message: '기간 중복 체크 중 오류가 발생했습니다'
});
}
if (overlapResults[0].count > 0) {
return res.status(400).json({
success: false,
message: '해당 기간에 이미 신청된 휴가가 있습니다'
});
}
// 수정 실행
vacationRequestModel.update(id, updateData, (err, result) => {
if (err) {
console.error('휴가 신청 수정 오류:', err);
return res.status(500).json({
success: false,
message: '휴가 신청 수정 중 오류가 발생했습니다'
});
}
res.json({
success: true,
message: '휴가 신청이 수정되었습니다'
});
});
}
); );
} else { if (overlapRows[0].count > 0) {
// 날짜 변경 없이 바로 수정 return res.status(400).json({ success: false, message: '해당 기간에 이미 신청된 휴가가 있습니다' });
vacationRequestModel.update(id, updateData, (err, result) => { }
if (err) {
console.error('휴가 신청 수정 오류:', err);
return res.status(500).json({
success: false,
message: '휴가 신청 수정 중 오류가 발생했습니다'
});
} }
res.json({ await vacationRequestModel.update(id, updateData);
success: true, res.json({ success: true, message: '휴가 신청이 수정되었습니다' });
message: '휴가 신청이 수정되었습니다'
});
});
}
});
} catch (error) { } catch (error) {
console.error('휴가 신청 수정 오류:', error); logger.error('휴가 신청 수정 오류:', error);
res.status(500).json({ res.status(500).json({ success: false, message: '서버 오류가 발생했습니다' });
success: false,
message: '서버 오류가 발생했습니다'
});
} }
}, },
@@ -315,62 +156,26 @@ const vacationRequestController = {
try { try {
const { id } = req.params; const { id } = req.params;
// 기존 신청 조회 const results = await vacationRequestModel.getById(id);
vacationRequestModel.getById(id, (err, results) => {
if (err) {
console.error('휴가 신청 조회 오류:', err);
return res.status(500).json({
success: false,
message: '휴가 신청 조회 중 오류가 발생했습니다'
});
}
if (results.length === 0) { if (results.length === 0) {
return res.status(404).json({ return res.status(404).json({ success: false, message: '해당 휴가 신청을 찾을 수 없습니다' });
success: false,
message: '해당 휴가 신청을 찾을 수 없습니다'
});
} }
const existingRequest = results[0]; const existingRequest = results[0];
// 권한 검증
if (req.user.access_level !== 'system' && req.user.worker_id !== existingRequest.worker_id) { if (req.user.access_level !== 'system' && req.user.worker_id !== existingRequest.worker_id) {
return res.status(403).json({ return res.status(403).json({ success: false, message: '권한이 없습니다' });
success: false,
message: '권한이 없습니다'
});
} }
// 대기 중인 신청만 삭제 가능
if (existingRequest.status !== 'pending') { if (existingRequest.status !== 'pending') {
return res.status(400).json({ return res.status(400).json({ success: false, message: '승인/거부된 신청은 삭제할 수 없습니다' });
success: false,
message: '승인/거부된 신청은 삭제할 수 없습니다'
});
} }
vacationRequestModel.delete(id, (err, result) => { await vacationRequestModel.delete(id);
if (err) { res.json({ success: true, message: '휴가 신청이 삭제되었습니다' });
console.error('휴가 신청 삭제 오류:', err);
return res.status(500).json({
success: false,
message: '휴가 신청 삭제 중 오류가 발생했습니다'
});
}
res.json({
success: true,
message: '휴가 신청이 삭제되었습니다'
});
});
});
} catch (error) { } catch (error) {
console.error('휴가 신청 삭제 오류:', error); logger.error('휴가 신청 삭제 오류:', error);
res.status(500).json({ res.status(500).json({ success: false, message: '서버 오류가 발생했습니다' });
success: false,
message: '서버 오류가 발생했습니다'
});
} }
}, },
@@ -383,71 +188,24 @@ const vacationRequestController = {
const { review_note } = req.body; const { review_note } = req.body;
const reviewed_by = req.user.user_id; const reviewed_by = req.user.user_id;
// 관리자 권한 확인
if (req.user.access_level !== 'system') { if (req.user.access_level !== 'system') {
return res.status(403).json({ return res.status(403).json({ success: false, message: '관리자만 승인할 수 있습니다' });
success: false,
message: '관리자만 승인할 수 있습니다'
});
}
// 기존 신청 조회
vacationRequestModel.getById(id, (err, results) => {
if (err) {
console.error('휴가 신청 조회 오류:', err);
return res.status(500).json({
success: false,
message: '휴가 신청 조회 중 오류가 발생했습니다'
});
} }
const results = await vacationRequestModel.getById(id);
if (results.length === 0) { if (results.length === 0) {
return res.status(404).json({ return res.status(404).json({ success: false, message: '해당 휴가 신청을 찾을 수 없습니다' });
success: false,
message: '해당 휴가 신청을 찾을 수 없습니다'
});
} }
const request = results[0]; if (results[0].status !== 'pending') {
return res.status(400).json({ success: false, message: '이미 처리된 신청입니다' });
if (request.status !== 'pending') {
return res.status(400).json({
success: false,
message: '이미 처리된 신청입니다'
});
} }
// 상태 업데이트 await vacationRequestModel.updateStatus(id, { status: 'approved', reviewed_by, review_note });
const statusData = { res.json({ success: true, message: '휴가 신청이 승인되었습니다' });
status: 'approved',
reviewed_by,
review_note
};
vacationRequestModel.updateStatus(id, statusData, (err, result) => {
if (err) {
console.error('휴가 승인 오류:', err);
return res.status(500).json({
success: false,
message: '휴가 승인 중 오류가 발생했습니다'
});
}
// TODO: 잔여 연차에서 차감 로직 구현 필요
// 현재는 연차 차감 없이 승인만 처리
res.json({
success: true,
message: '휴가 신청이 승인되었습니다'
});
});
});
} catch (error) { } catch (error) {
console.error('휴가 승인 오류:', error); logger.error('휴가 승인 오류:', error);
res.status(500).json({ res.status(500).json({ success: false, message: '서버 오류가 발생했습니다' });
success: false,
message: '서버 오류가 발생했습니다'
});
} }
}, },
@@ -460,68 +218,24 @@ const vacationRequestController = {
const { review_note } = req.body; const { review_note } = req.body;
const reviewed_by = req.user.user_id; const reviewed_by = req.user.user_id;
// 관리자 권한 확인
if (req.user.access_level !== 'system') { if (req.user.access_level !== 'system') {
return res.status(403).json({ return res.status(403).json({ success: false, message: '관리자만 거부할 수 있습니다' });
success: false,
message: '관리자만 거부할 수 있습니다'
});
}
// 기존 신청 조회
vacationRequestModel.getById(id, (err, results) => {
if (err) {
console.error('휴가 신청 조회 오류:', err);
return res.status(500).json({
success: false,
message: '휴가 신청 조회 중 오류가 발생했습니다'
});
} }
const results = await vacationRequestModel.getById(id);
if (results.length === 0) { if (results.length === 0) {
return res.status(404).json({ return res.status(404).json({ success: false, message: '해당 휴가 신청을 찾을 수 없습니다' });
success: false,
message: '해당 휴가 신청을 찾을 수 없습니다'
});
} }
const request = results[0]; if (results[0].status !== 'pending') {
return res.status(400).json({ success: false, message: '이미 처리된 신청입니다' });
if (request.status !== 'pending') {
return res.status(400).json({
success: false,
message: '이미 처리된 신청입니다'
});
} }
// 상태 업데이트 await vacationRequestModel.updateStatus(id, { status: 'rejected', reviewed_by, review_note });
const statusData = { res.json({ success: true, message: '휴가 신청이 거부되었습니다' });
status: 'rejected',
reviewed_by,
review_note
};
vacationRequestModel.updateStatus(id, statusData, (err, result) => {
if (err) {
console.error('휴가 거부 오류:', err);
return res.status(500).json({
success: false,
message: '휴가 거부 중 오류가 발생했습니다'
});
}
res.json({
success: true,
message: '휴가 신청이 거부되었습니다'
});
});
});
} catch (error) { } catch (error) {
console.error('휴가 거부 오류:', error); logger.error('휴가 거부 오류:', error);
res.status(500).json({ res.status(500).json({ success: false, message: '서버 오류가 발생했습니다' });
success: false,
message: '서버 오류가 발생했습니다'
});
} }
}, },
@@ -530,34 +244,15 @@ const vacationRequestController = {
*/ */
async getPendingRequests(req, res) { async getPendingRequests(req, res) {
try { try {
// 관리자 권한 확인
if (req.user.access_level !== 'system') { if (req.user.access_level !== 'system') {
return res.status(403).json({ return res.status(403).json({ success: false, message: '관리자만 조회할 수 있습니다' });
success: false,
message: '관리자만 조회할 수 있습니다'
});
} }
vacationRequestModel.getAllPending((err, results) => { const results = await vacationRequestModel.getAllPending();
if (err) { res.json({ success: true, data: results });
console.error('대기 중인 휴가 신청 조회 오류:', err);
return res.status(500).json({
success: false,
message: '대기 중인 휴가 신청 조회 중 오류가 발생했습니다'
});
}
res.json({
success: true,
data: results
});
});
} catch (error) { } catch (error) {
console.error('대기 중인 휴가 신청 조회 오류:', error); logger.error('대기 중인 휴가 신청 조회 오류:', error);
res.status(500).json({ res.status(500).json({ success: false, message: '서버 오류가 발생했습니다' });
success: false,
message: '서버 오류가 발생했습니다'
});
} }
} }
}; };

View File

@@ -9,22 +9,16 @@ const vacationRequestModel = {
/** /**
* 휴가 신청 생성 * 휴가 신청 생성
*/ */
async create(requestData, callback) { async create(requestData) {
try {
const db = await getDb(); const db = await getDb();
const query = `INSERT INTO vacation_requests SET ?`; const [result] = await db.query(`INSERT INTO vacation_requests SET ?`, requestData);
const [result] = await db.query(query, requestData); return result;
callback(null, result);
} catch (error) {
callback(error);
}
}, },
/** /**
* 휴가 신청 목록 조회 (필터링 지원) * 휴가 신청 목록 조회 (필터링 지원)
*/ */
async getAll(filters = {}, callback) { async getAll(filters = {}) {
try {
const db = await getDb(); const db = await getDb();
let query = ` let query = `
@@ -45,30 +39,22 @@ const vacationRequestModel = {
const params = []; const params = [];
// 작업자 필터
if (filters.worker_id) { if (filters.worker_id) {
query += ` AND vr.worker_id = ?`; query += ` AND vr.worker_id = ?`;
params.push(filters.worker_id); params.push(filters.worker_id);
} }
// 상태 필터
if (filters.status) { if (filters.status) {
query += ` AND vr.status = ?`; query += ` AND vr.status = ?`;
params.push(filters.status); params.push(filters.status);
} }
// 기간 필터
if (filters.start_date) { if (filters.start_date) {
query += ` AND vr.start_date >= ?`; query += ` AND vr.start_date >= ?`;
params.push(filters.start_date); params.push(filters.start_date);
} }
if (filters.end_date) { if (filters.end_date) {
query += ` AND vr.end_date <= ?`; query += ` AND vr.end_date <= ?`;
params.push(filters.end_date); params.push(filters.end_date);
} }
// 휴가 유형 필터
if (filters.vacation_type_id) { if (filters.vacation_type_id) {
query += ` AND vr.vacation_type_id = ?`; query += ` AND vr.vacation_type_id = ?`;
params.push(filters.vacation_type_id); params.push(filters.vacation_type_id);
@@ -77,19 +63,15 @@ const vacationRequestModel = {
query += ` ORDER BY vr.created_at DESC`; query += ` ORDER BY vr.created_at DESC`;
const [rows] = await db.query(query, params); const [rows] = await db.query(query, params);
callback(null, rows); return rows;
} catch (error) {
callback(error);
}
}, },
/** /**
* 특정 휴가 신청 조회 * 특정 휴가 신청 조회
*/ */
async getById(requestId, callback) { async getById(requestId) {
try {
const db = await getDb(); const db = await getDb();
const query = ` const [rows] = await db.query(`
SELECT SELECT
vr.*, vr.*,
w.worker_name, w.worker_name,
@@ -108,117 +90,72 @@ const vacationRequestModel = {
LEFT JOIN users requester ON vr.requested_by = requester.user_id LEFT JOIN users requester ON vr.requested_by = requester.user_id
LEFT JOIN users reviewer ON vr.reviewed_by = reviewer.user_id LEFT JOIN users reviewer ON vr.reviewed_by = reviewer.user_id
WHERE vr.request_id = ? WHERE vr.request_id = ?
`; `, [requestId]);
const [rows] = await db.query(query, [requestId]); return rows;
callback(null, rows);
} catch (error) {
callback(error);
}
}, },
/** /**
* 휴가 신청 수정 * 휴가 신청 수정
*/ */
async update(requestId, updateData, callback) { async update(requestId, updateData) {
try {
const db = await getDb(); const db = await getDb();
const query = `UPDATE vacation_requests SET ? WHERE request_id = ?`; const [result] = await db.query(`UPDATE vacation_requests SET ? WHERE request_id = ?`, [updateData, requestId]);
const [result] = await db.query(query, [updateData, requestId]); return result;
callback(null, result);
} catch (error) {
callback(error);
}
}, },
/** /**
* 휴가 신청 삭제 * 휴가 신청 삭제
*/ */
async delete(requestId, callback) { async delete(requestId) {
try {
const db = await getDb(); const db = await getDb();
const query = `DELETE FROM vacation_requests WHERE request_id = ?`; const [result] = await db.query(`DELETE FROM vacation_requests WHERE request_id = ?`, [requestId]);
const [result] = await db.query(query, [requestId]); return result;
callback(null, result);
} catch (error) {
callback(error);
}
}, },
/** /**
* 휴가 신청 승인/거부 * 휴가 신청 승인/거부
*/ */
async updateStatus(requestId, statusData, callback) { async updateStatus(requestId, statusData) {
try {
const db = await getDb(); const db = await getDb();
const query = ` const [result] = await db.query(`
UPDATE vacation_requests UPDATE vacation_requests
SET SET status = ?, reviewed_by = ?, reviewed_at = NOW(), review_note = ?
status = ?,
reviewed_by = ?,
reviewed_at = NOW(),
review_note = ?
WHERE request_id = ? WHERE request_id = ?
`; `, [statusData.status, statusData.reviewed_by, statusData.review_note || null, requestId]);
const [result] = await db.query(query, [ return result;
statusData.status,
statusData.reviewed_by,
statusData.review_note || null,
requestId
]);
callback(null, result);
} catch (error) {
callback(error);
}
}, },
/** /**
* 특정 작업자의 대기 중인 휴가 신청 수 * 특정 작업자의 대기 중인 휴가 신청 수
*/ */
async getPendingCount(workerId, callback) { async getPendingCount(workerId) {
try {
const db = await getDb(); const db = await getDb();
const query = ` const [rows] = await db.query(`
SELECT COUNT(*) as count SELECT COUNT(*) as count FROM vacation_requests
FROM vacation_requests
WHERE worker_id = ? AND status = 'pending' WHERE worker_id = ? AND status = 'pending'
`; `, [workerId]);
const [rows] = await db.query(query, [workerId]); return rows;
callback(null, rows);
} catch (error) {
callback(error);
}
}, },
/** /**
* 특정 작업자의 승인된 휴가 일수 합계 (특정 기간) * 특정 작업자의 승인된 휴가 일수 합계 (특정 기간)
*/ */
async getApprovedDaysInPeriod(workerId, startDate, endDate, callback) { async getApprovedDaysInPeriod(workerId, startDate, endDate) {
try {
const db = await getDb(); const db = await getDb();
const query = ` const [rows] = await db.query(`
SELECT COALESCE(SUM(days_used), 0) as total_days SELECT COALESCE(SUM(days_used), 0) as total_days FROM vacation_requests
FROM vacation_requests WHERE worker_id = ? AND status = 'approved' AND start_date >= ? AND end_date <= ?
WHERE worker_id = ? `, [workerId, startDate, endDate]);
AND status = 'approved' return rows;
AND start_date >= ?
AND end_date <= ?
`;
const [rows] = await db.query(query, [workerId, startDate, endDate]);
callback(null, rows);
} catch (error) {
callback(error);
}
}, },
/** /**
* 휴가 기간 중복 체크 * 휴가 기간 중복 체크
*/ */
async checkOverlap(workerId, startDate, endDate, excludeRequestId = null, callback) { async checkOverlap(workerId, startDate, endDate, excludeRequestId = null) {
try {
const db = await getDb(); const db = await getDb();
let query = ` let query = `
SELECT COUNT(*) as count SELECT COUNT(*) as count FROM vacation_requests
FROM vacation_requests
WHERE worker_id = ? WHERE worker_id = ?
AND status IN ('pending', 'approved') AND status IN ('pending', 'approved')
AND ( AND (
@@ -235,19 +172,15 @@ const vacationRequestModel = {
} }
const [rows] = await db.query(query, params); const [rows] = await db.query(query, params);
callback(null, rows); return rows;
} catch (error) {
callback(error);
}
}, },
/** /**
* 모든 대기 중인 휴가 신청 (관리자용) * 모든 대기 중인 휴가 신청 (관리자용)
*/ */
async getAllPending(callback) { async getAllPending() {
try {
const db = await getDb(); const db = await getDb();
const query = ` const [rows] = await db.query(`
SELECT SELECT
vr.*, vr.*,
w.worker_name, w.worker_name,
@@ -259,12 +192,8 @@ const vacationRequestModel = {
LEFT JOIN users requester ON vr.requested_by = requester.user_id LEFT JOIN users requester ON vr.requested_by = requester.user_id
WHERE vr.status = 'pending' WHERE vr.status = 'pending'
ORDER BY vr.created_at ASC ORDER BY vr.created_at ASC
`; `);
const [rows] = await db.query(query); return rows;
callback(null, rows);
} catch (error) {
callback(error);
}
} }
}; };