/** * 작업자 관리 컨트롤러 * * 작업자 CRUD API 엔드포인트 핸들러 * * @author TK-FB-Project * @since 2025-12-11 */ const workerModel = require('../models/workerModel'); const { ValidationError, NotFoundError, DatabaseError } = require('../utils/errors'); const { asyncHandler } = require('../middlewares/errorHandler'); const logger = require('../utils/logger'); const cache = require('../utils/cache'); const { optimizedQueries } = require('../utils/queryOptimizer'); /** * 작업자 생성 */ exports.createWorker = asyncHandler(async (req, res) => { const workerData = req.body; logger.info('작업자 생성 요청', { name: workerData.name }); const lastID = await new Promise((resolve, reject) => { workerModel.create(workerData, (err, id) => { if (err) reject(new DatabaseError('작업자 생성 중 오류가 발생했습니다')); else resolve(id); }); }); // 작업자 관련 캐시 무효화 await cache.invalidateCache.worker(); logger.info('작업자 생성 성공', { worker_id: lastID }); res.status(201).json({ success: true, data: { worker_id: lastID }, message: '작업자가 성공적으로 생성되었습니다' }); }); /** * 전체 작업자 조회 (캐싱 및 페이지네이션 적용) */ exports.getAllWorkers = asyncHandler(async (req, res) => { const { page = 1, limit = 10, search = '', status = '' } = req.query; const cacheKey = cache.createKey('workers', 'list', page, limit, search, status); // 캐시에서 조회 const cachedData = await cache.get(cacheKey); if (cachedData) { logger.debug('캐시 히트', { cacheKey }); return res.json({ success: true, data: cachedData.data, pagination: cachedData.pagination, message: '작업자 목록 조회 성공 (캐시)' }); } // 최적화된 쿼리 사용 const result = await optimizedQueries.getWorkersPaged(page, limit, search, status); // 캐시에 저장 (5분) await cache.set(cacheKey, result, cache.TTL.MEDIUM); logger.debug('캐시 저장', { cacheKey }); res.json({ success: true, data: result.data, pagination: result.pagination, message: '작업자 목록 조회 성공' }); }); /** * 단일 작업자 조회 */ exports.getWorkerById = asyncHandler(async (req, res) => { const id = parseInt(req.params.worker_id, 10); if (isNaN(id)) { throw new ValidationError('유효하지 않은 작업자 ID입니다'); } const row = await new Promise((resolve, reject) => { workerModel.getById(id, (err, data) => { if (err) reject(new DatabaseError('작업자 조회 중 오류가 발생했습니다')); else resolve(data); }); }); if (!row) { throw new NotFoundError('작업자를 찾을 수 없습니다'); } res.json({ success: true, data: row, message: '작업자 조회 성공' }); }); /** * 작업자 수정 */ exports.updateWorker = asyncHandler(async (req, res) => { const id = parseInt(req.params.worker_id, 10); if (isNaN(id)) { throw new ValidationError('유효하지 않은 작업자 ID입니다'); } const workerData = { ...req.body, worker_id: id }; console.log('🔧 작업자 수정 요청:', { worker_id: id, 받은데이터: req.body, 처리할데이터: workerData }); const changes = await new Promise((resolve, reject) => { workerModel.update(workerData, (err, affected) => { if (err) { console.error('❌ workerModel.update 에러:', err); reject(new DatabaseError(`작업자 수정 중 오류가 발생했습니다: ${err.message}`)); } else resolve(affected); }); }); if (changes === 0) { throw new NotFoundError('작업자를 찾을 수 없습니다'); } // 작업자 관련 캐시 무효화 logger.info('작업자 수정 후 캐시 무효화', { worker_id: id }); await cache.invalidateCache.worker(); logger.info('작업자 수정 성공', { worker_id: id }); res.json({ success: true, data: { changes }, message: '작업자 정보가 성공적으로 수정되었습니다' }); }); /** * 작업자 삭제 */ exports.removeWorker = asyncHandler(async (req, res) => { const id = parseInt(req.params.worker_id, 10); if (isNaN(id)) { throw new ValidationError('유효하지 않은 작업자 ID입니다'); } const changes = await new Promise((resolve, reject) => { workerModel.remove(id, (err, affected) => { if (err) reject(new DatabaseError('작업자 삭제 중 오류가 발생했습니다')); else resolve(affected); }); }); if (changes === 0) { throw new NotFoundError('작업자를 찾을 수 없습니다'); } // 작업자 관련 캐시 무효화 logger.info('작업자 삭제 후 캐시 무효화 시작', { worker_id: id }); await cache.invalidateCache.worker(); await cache.delPattern('workers:*'); await cache.flush(); logger.info('작업자 삭제 후 캐시 무효화 완료', { worker_id: id }); res.json({ success: true, message: '작업자가 성공적으로 삭제되었습니다' }); });