refactor(backend): 일일 이슈 보고 API 전체 리팩토링

- dailyIssueReport 기능을 Controller-Service-Model 아키텍처로 재구성
- Model 계층을 Promise 기반으로 전환하고 트랜잭션을 적용하여 안정성 확보
- API 전반의 코드 품질 및 유지보수성 향상
This commit is contained in:
2025-07-28 12:41:41 +09:00
parent 5268fec1ef
commit e3b2718767
3 changed files with 200 additions and 128 deletions

View File

@@ -1,110 +1,58 @@
const dailyIssueReportModel = require('../models/dailyIssueReportModel');
// /controllers/dailyIssueReportController.js
const dailyIssueReportService = require('../services/dailyIssueReportService');
// 1. CREATE: 단일 또는 다중 등록 (worker_id 배열 지원)
exports.createDailyIssueReport = async (req, res) => {
/**
* 1. CREATE: 일일 이슈 보고서 생성 (Service Layer 사용)
*/
const createDailyIssueReport = async (req, res) => {
try {
const body = req.body;
// 기본 필드
const base = {
date: body.date,
project_id: body.project_id,
start_time: body.start_time,
end_time: body.end_time,
issue_type_id: body.issue_type_id
};
if (!base.date || !base.project_id || !base.start_time || !base.end_time || !base.issue_type_id || !body.worker_id) {
return res.status(400).json({ error: '필수 필드 누락' });
}
// worker_id 배열화
const workers = Array.isArray(body.worker_id) ? body.worker_id : [body.worker_id];
const insertedIds = [];
for (const wid of workers) {
const payload = { ...base, worker_id: wid };
const insertId = await new Promise((resolve, reject) => {
dailyIssueReportModel.create(payload, (err, id) => {
if (err) reject(err);
else resolve(id);
});
});
insertedIds.push(insertId);
}
res.json({ success: true, issue_report_ids: insertedIds });
// 프론트엔드에서 worker_ids로 보내주기로 약속함
const issueData = { ...req.body, worker_ids: req.body.worker_ids || req.body.worker_id };
const result = await dailyIssueReportService.createDailyIssueReportService(issueData);
res.status(201).json({ success: true, ...result });
} catch (err) {
console.error('🔥 createDailyIssueReport error:', err);
res.status(500).json({ error: err.message || String(err) });
console.error('💥 이슈 보고서 생성 컨트롤러 오류:', err);
res.status(400).json({ success: false, error: err.message });
}
};
// 2. READ BY DATE
exports.getDailyIssuesByDate = async (req, res) => {
/**
* 2. READ BY DATE: 날짜별 이슈 조회 (Service Layer 사용)
*/
const getDailyIssuesByDate = async (req, res) => {
try {
const { date } = req.query;
const rows = await new Promise((resolve, reject) => {
dailyIssueReportModel.getAllByDate(date, (err, data) => {
if (err) reject(err);
else resolve(data);
});
});
res.json(rows);
const issues = await dailyIssueReportService.getDailyIssuesByDateService(date);
res.json(issues);
} catch (err) {
res.status(500).json({ error: err.message || String(err) });
console.error('💥 이슈 보고서 조회 컨트롤러 오류:', err);
res.status(500).json({ success: false, error: err.message });
}
};
// 3. READ ONE
exports.getDailyIssueById = async (req, res) => {
/**
* 3. DELETE: 이슈 보고서 삭제 (Service Layer 사용)
*/
const removeDailyIssue = async (req, res) => {
try {
const { id } = req.params;
const row = await new Promise((resolve, reject) => {
dailyIssueReportModel.getById(id, (err, data) => {
if (err) reject(err);
else resolve(data);
});
});
if (!row) return res.status(404).json({ error: 'DailyIssueReport not found' });
res.json(row);
const result = await dailyIssueReportService.removeDailyIssueService(id);
res.json({ success: true, ...result });
} catch (err) {
res.status(500).json({ error: err.message || String(err) });
console.error('💥 이슈 보고서 삭제 컨트롤러 오류:', err);
const statusCode = err.statusCode || 500;
res.status(statusCode).json({ success: false, error: err.message });
}
};
// 4. UPDATE
exports.updateDailyIssue = async (req, res) => {
try {
const { id } = req.params;
const changes = await new Promise((resolve, reject) => {
dailyIssueReportModel.update(id, req.body, (err, affectedRows) => {
if (err) reject(err);
else resolve(affectedRows);
});
});
if (changes === 0) return res.status(404).json({ error: 'No changes or not found' });
res.json({ success: true, changes });
} catch (err) {
res.status(500).json({ error: err.message || String(err) });
}
};
// 레거시 함수들은 더 이상 라우팅되지 않으므로 제거하거나 주석 처리 가능
// exports.getDailyIssueById = ...
// exports.updateDailyIssue = ...
// 5. DELETE
exports.removeDailyIssue = async (req, res) => {
try {
const { id } = req.params;
const changes = await new Promise((resolve, reject) => {
dailyIssueReportModel.remove(id, (err, affectedRows) => {
if (err) reject(err);
else resolve(affectedRows);
});
});
if (changes === 0) return res.status(404).json({ error: 'DailyIssueReport not found' });
res.json({ success: true, changes });
} catch (err) {
res.status(500).json({ error: err.message || String(err) });
}
module.exports = {
createDailyIssueReport,
getDailyIssuesByDate,
removeDailyIssue,
};