Files
TK-FB-Project/api.hyungi.net/models/dailyIssueReportModel.js
Hyungi Ahn bc5df77595 refactor(db): Replace SELECT * with explicit columns in models
Replaced `SELECT *` statements across multiple data models with explicit column lists to improve query performance, reduce data transfer, and increase code clarity. This is part of the Phase 2 refactoring plan.

- Refactored queries in the following models:
  - projectModel
  - toolsModel
  - attendanceModel
  - dailyIssueReportModel
  - issueTypeModel
  - workReportModel
  - userModel
  - dailyWorkReportModel

fix(api): Add missing volume mounts to docker-compose

Modified docker-compose.yml to mount the `config`, `middlewares`, `utils`, and `services` directories into the API container. This fixes a `MODULE_NOT_FOUND` error that caused the container to crash on startup.

feat(db): Add migration for missing project columns

Created a new database migration to add `is_active`, `project_status`, and `completed_date` columns to the `projects` table, resolving an inconsistency between the model code and the schema.

docs: Add deployment notes

Added a new markdown file to document the testing (macOS, Docker Desktop) and production (Synology NAS, Container Manager) environments.
2025-12-19 10:33:29 +09:00

154 lines
4.3 KiB
JavaScript

const { getDb } = require('../dbPool');
/**
* 1. 여러 개의 이슈 보고서를 트랜잭션으로 생성합니다.
* @param {Array<object>} reports - 생성할 보고서 데이터 배열
* @returns {Promise<Array<number>>} - 삽입된 ID 배열
*/
const createMany = async (reports) => {
const db = await getDb();
const conn = await db.getConnection();
try {
await conn.beginTransaction();
const insertedIds = [];
const sql = `
INSERT INTO DailyIssueReports
(date, worker_id, project_id, start_time, end_time, issue_type_id)
VALUES (?, ?, ?, ?, ?, ?)
`;
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) {
await conn.rollback();
console.error('[Model] 여러 이슈 보고서 생성 중 오류:', err);
throw new Error('데이터베이스에 이슈 보고서를 생성하는 중 오류가 발생했습니다.');
} finally {
conn.release();
}
};
/**
* 2. 특정 날짜의 전체 이슈 목록 조회 (Promise 기반)
*/
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
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
LEFT JOIN IssueTypes t ON d.issue_type_id = t.issue_type_id
WHERE d.date = ?
ORDER BY d.start_time ASC`,
[date]
);
return rows;
} catch (err) {
console.error(`[Model] ${date} 이슈 목록 조회 오류:`, err);
throw new Error('데이터베이스에서 이슈 목록을 조회하는 중 오류가 발생했습니다.');
}
};
/**
* 3. 단일 조회 (선택사항: 컨트롤러에서 사용 중)
*/
const getById = async (id, callback) => {
try {
const db = await getDb();
const [rows] = await db.query(`SELECT id, date, worker_id, project_id, issue_type_id, description, created_at, start_time, end_time FROM DailyIssueReports WHERE id = ?`, [id]);
callback(null, rows[0]);
} catch (err) {
callback(err);
}
};
/**
* 4. 수정
*/
const update = async (id, data, callback) => {
try {
const db = await getDb();
const fields = [];
const values = [];
for (const key in data) {
fields.push(`${key} = ?`);
values.push(data[key]);
}
values.push(id); // 마지막에 id
const [result] = await db.query(
`UPDATE DailyIssueReports SET ${fields.join(', ')} WHERE id = ?`,
values
);
callback(null, result.affectedRows);
} catch (err) {
callback(err);
}
};
/**
* 5. 삭제 (Promise 기반)
*/
const remove = async (id) => {
try {
const db = await getDb();
const [result] = await db.query(`DELETE FROM DailyIssueReports WHERE id = ?`, [id]);
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 = {
createMany, // 신규
getAllByDate,
remove,
// 레거시 호환성을 위해 V1 함수들 임시 유지
create: (report, callback) => createMany([report]).then(ids => callback(null, ids[0])).catch(err => callback(err)),
getById,
update,
};