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,51 +1,50 @@
const { getDb } = require('../dbPool');
/**
* 1. 등록 (단일 레코드)
* 1. 여러 개의 이슈 보고서를 트랜잭션으로 생성합니다.
* @param {Array<object>} reports - 생성할 보고서 데이터 배열
* @returns {Promise<Array<number>>} - 삽입된 ID 배열
*/
const create = async (report, callback) => {
const createMany = async (reports) => {
const db = await getDb();
const conn = await db.getConnection();
try {
const db = await getDb();
const {
date,
worker_id,
project_id,
start_time,
end_time,
issue_type_id,
description = null // 선택값 처리
} = report;
await conn.beginTransaction();
const [result] = await db.query(
`INSERT INTO DailyIssueReports
(date, worker_id, project_id, start_time, end_time, issue_type_id, description)
VALUES (?, ?, ?, ?, ?, ?, ?)`,
[date, worker_id, project_id, start_time, end_time, issue_type_id, description]
);
const insertedIds = [];
const sql = `
INSERT INTO DailyIssueReports
(date, worker_id, project_id, start_time, end_time, issue_type_id)
VALUES (?, ?, ?, ?, ?, ?)
`;
callback(null, result.insertId);
for (const report of reports) {
const { date, worker_id, project_id, start_time, end_time, issue_type_id } = report;
const [result] = await conn.query(sql, [date, worker_id, project_id, start_time, end_time, issue_type_id]);
insertedIds.push(result.insertId);
}
await conn.commit();
return insertedIds;
} catch (err) {
callback(err);
await conn.rollback();
console.error('[Model] 여러 이슈 보고서 생성 중 오류:', err);
throw new Error('데이터베이스에 이슈 보고서를 생성하는 중 오류가 발생했습니다.');
} finally {
conn.release();
}
};
/**
* 2. 특정 날짜의 전체 이슈 목록 조회
* 2. 특정 날짜의 전체 이슈 목록 조회 (Promise 기반)
*/
const getAllByDate = async (date, callback) => {
const getAllByDate = async (date) => {
try {
const db = await getDb();
const [rows] = await db.query(
`SELECT
d.id,
d.date,
w.worker_name,
p.project_name,
d.start_time,
d.end_time,
t.category,
t.subcategory,
d.description
d.id, d.date, w.worker_name, p.project_name, d.start_time, d.end_time,
t.category, t.subcategory, d.description
FROM DailyIssueReports d
LEFT JOIN Workers w ON d.worker_id = w.worker_id
LEFT JOIN Projects p ON d.project_id = p.project_id
@@ -54,9 +53,10 @@ const getAllByDate = async (date, callback) => {
ORDER BY d.start_time ASC`,
[date]
);
callback(null, rows);
return rows;
} catch (err) {
callback(err);
console.error(`[Model] ${date} 이슈 목록 조회 오류:`, err);
throw new Error('데이터베이스에서 이슈 목록을 조회하는 중 오류가 발생했습니다.');
}
};
@@ -102,22 +102,53 @@ const update = async (id, data, callback) => {
};
/**
* 5. 삭제
* 5. 삭제 (Promise 기반)
*/
const remove = async (id, callback) => {
const remove = async (id) => {
try {
const db = await getDb();
const [result] = await db.query(`DELETE FROM DailyIssueReports WHERE id = ?`, [id]);
callback(null, result.affectedRows);
return result.affectedRows;
} catch (err) {
console.error(`[Model] 이슈(id: ${id}) 삭제 오류:`, err);
throw new Error('데이터베이스에서 이슈를 삭제하는 중 오류가 발생했습니다.');
}
};
// V1 함수들은 점진적으로 제거 예정
const create = async (report, callback) => {
try {
const db = await getDb();
const {
date,
worker_id,
project_id,
start_time,
end_time,
issue_type_id,
description = null // 선택값 처리
} = report;
const [result] = await db.query(
`INSERT INTO DailyIssueReports
(date, worker_id, project_id, start_time, end_time, issue_type_id, description)
VALUES (?, ?, ?, ?, ?, ?, ?)`,
[date, worker_id, project_id, start_time, end_time, issue_type_id, description]
);
callback(null, result.insertId);
} catch (err) {
callback(err);
}
};
module.exports = {
create,
createMany, // 신규
getAllByDate,
remove,
// 레거시 호환성을 위해 V1 함수들 임시 유지
create: (report, callback) => createMany([report]).then(ids => callback(null, ids[0])).catch(err => callback(err)),
getById,
update,
remove
};