Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | /** * 프로젝트 분석 서비스 * * 기간별 프로젝트, 작업자, 작업 유형 분석 데이터 처리 * * @author TK-FB-Project * @since 2025-12-11 */ const analysisModel = require('../models/analysisModel'); const { ValidationError, DatabaseError } = require('../utils/errors'); const logger = require('../utils/logger'); /** * 기간별 프로젝트 분석 데이터 조회 * * @param {string} startDate - 시작일 (YYYY-MM-DD) * @param {string} endDate - 종료일 (YYYY-MM-DD) * @returns {Promise<object>} 가공된 분석 데이터 */ const getAnalysisService = async (startDate, endDate) => { // 필수 필드 검증 if (!startDate || !endDate) { throw new ValidationError('시작일과 종료일이 필요합니다', { required: ['startDate', 'endDate'], received: { startDate, endDate } }); } logger.info('분석 데이터 조회 요청', { startDate, endDate }); try { const analysisData = await analysisModel.getAnalysis(startDate, endDate); const { summary, byProject, byWorker, byTask, details } = analysisData; const totalHours = summary.totalHours || 0; // 비율(percentage) 계산 헬퍼 함수 const addPercentage = (item) => ({ ...item, hours: parseFloat(item.hours.toFixed(1)), percentage: totalHours > 0 ? parseFloat((item.hours / totalHours * 100).toFixed(1)) : 0 }); const result = { summary: { ...summary, totalHours: parseFloat(totalHours.toFixed(1)) }, byProject: byProject.map(addPercentage), byWorker: byWorker.map(addPercentage), byTask: byTask.map(addPercentage), details: details.map(d => ({ ...d, work_hours: parseFloat(d.work_hours.toFixed(1)) })) }; logger.info('분석 데이터 조회 성공', { startDate, endDate, totalHours: result.summary.totalHours, projectCount: result.byProject.length, workerCount: result.byWorker.length, detailCount: result.details.length }); return result; } catch (error) { logger.error('분석 데이터 조회 실패', { startDate, endDate, error: error.message }); throw new DatabaseError('분석 데이터 조회 중 오류가 발생했습니다'); } }; module.exports = { getAnalysisService }; |