refactor: System 1 모델/컨트롤러 콜백→async/await 전환

11개 모델 파일의 171개 콜백 메서드를 직접 return/throw 패턴으로 변환.
8개 컨트롤러에서 new Promise 래퍼와 중첩 콜백 제거, console.error→logger.error 교체.
미사용 pageAccessModel.js 삭제. 전체 -3,600줄 감소.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-02-25 09:40:33 +09:00
parent c29a1506bb
commit 5183e9ff85
22 changed files with 4791 additions and 8406 deletions

View File

@@ -8,15 +8,12 @@
*/
const workplaceModel = require('../models/workplaceModel');
const { ValidationError, NotFoundError, DatabaseError } = require('../utils/errors');
const { ValidationError, NotFoundError } = require('../utils/errors');
const { asyncHandler } = require('../middlewares/errorHandler');
const logger = require('../utils/logger');
// ==================== 카테고리(공장) 관련 ====================
/**
* 카테고리 생성
*/
exports.createCategory = asyncHandler(async (req, res) => {
const categoryData = req.body;
@@ -26,12 +23,7 @@ exports.createCategory = asyncHandler(async (req, res) => {
logger.info('카테고리 생성 요청', { name: categoryData.category_name });
const id = await new Promise((resolve, reject) => {
workplaceModel.createCategory(categoryData, (err, lastID) => {
if (err) reject(new DatabaseError('카테고리 생성 중 오류가 발생했습니다'));
else resolve(lastID);
});
});
const id = await workplaceModel.createCategory(categoryData);
logger.info('카테고리 생성 성공', { category_id: id });
@@ -42,16 +34,8 @@ exports.createCategory = asyncHandler(async (req, res) => {
});
});
/**
* 전체 카테고리 조회
*/
exports.getAllCategories = asyncHandler(async (req, res) => {
const rows = await new Promise((resolve, reject) => {
workplaceModel.getAllCategories((err, data) => {
if (err) reject(new DatabaseError('카테고리 목록 조회 중 오류가 발생했습니다'));
else resolve(data);
});
});
const rows = await workplaceModel.getAllCategories();
res.json({
success: true,
@@ -60,16 +44,8 @@ exports.getAllCategories = asyncHandler(async (req, res) => {
});
});
/**
* 활성 카테고리만 조회
*/
exports.getActiveCategories = asyncHandler(async (req, res) => {
const rows = await new Promise((resolve, reject) => {
workplaceModel.getActiveCategories((err, data) => {
if (err) reject(new DatabaseError('활성 카테고리 목록 조회 중 오류가 발생했습니다'));
else resolve(data);
});
});
const rows = await workplaceModel.getActiveCategories();
res.json({
success: true,
@@ -78,18 +54,9 @@ exports.getActiveCategories = asyncHandler(async (req, res) => {
});
});
/**
* 단일 카테고리 조회
*/
exports.getCategoryById = asyncHandler(async (req, res) => {
const categoryId = req.params.id;
const category = await new Promise((resolve, reject) => {
workplaceModel.getCategoryById(categoryId, (err, data) => {
if (err) reject(new DatabaseError('카테고리 조회 중 오류가 발생했습니다'));
else resolve(data);
});
});
const category = await workplaceModel.getCategoryById(categoryId);
if (!category) {
throw new NotFoundError('카테고리를 찾을 수 없습니다');
@@ -102,9 +69,6 @@ exports.getCategoryById = asyncHandler(async (req, res) => {
});
});
/**
* 카테고리 수정
*/
exports.updateCategory = asyncHandler(async (req, res) => {
const categoryId = req.params.id;
const categoryData = req.body;
@@ -115,19 +79,11 @@ exports.updateCategory = asyncHandler(async (req, res) => {
logger.info('카테고리 수정 요청', { category_id: categoryId });
// 기존 카테고리 정보 가져오기
const existingCategory = await new Promise((resolve, reject) => {
workplaceModel.getCategoryById(categoryId, (err, data) => {
if (err) reject(new DatabaseError('카테고리 조회 중 오류가 발생했습니다'));
else resolve(data);
});
});
const existingCategory = await workplaceModel.getCategoryById(categoryId);
if (!existingCategory) {
throw new NotFoundError('카테고리를 찾을 수 없습니다');
}
// layout_image가 요청에 없거나 null이면 기존 값 보존
const updateData = {
...categoryData,
layout_image: (categoryData.layout_image !== undefined && categoryData.layout_image !== null)
@@ -135,12 +91,7 @@ exports.updateCategory = asyncHandler(async (req, res) => {
: existingCategory.layout_image
};
await new Promise((resolve, reject) => {
workplaceModel.updateCategory(categoryId, updateData, (err, result) => {
if (err) reject(new DatabaseError('카테고리 수정 중 오류가 발생했습니다'));
else resolve(result);
});
});
await workplaceModel.updateCategory(categoryId, updateData);
logger.info('카테고리 수정 성공', { category_id: categoryId });
@@ -150,20 +101,12 @@ exports.updateCategory = asyncHandler(async (req, res) => {
});
});
/**
* 카테고리 삭제
*/
exports.deleteCategory = asyncHandler(async (req, res) => {
const categoryId = req.params.id;
logger.info('카테고리 삭제 요청', { category_id: categoryId });
await new Promise((resolve, reject) => {
workplaceModel.deleteCategory(categoryId, (err, result) => {
if (err) reject(new DatabaseError('카테고리 삭제 중 오류가 발생했습니다'));
else resolve(result);
});
});
await workplaceModel.deleteCategory(categoryId);
logger.info('카테고리 삭제 성공', { category_id: categoryId });
@@ -175,9 +118,6 @@ exports.deleteCategory = asyncHandler(async (req, res) => {
// ==================== 작업장 관련 ====================
/**
* 작업장 생성
*/
exports.createWorkplace = asyncHandler(async (req, res) => {
const workplaceData = req.body;
@@ -187,12 +127,7 @@ exports.createWorkplace = asyncHandler(async (req, res) => {
logger.info('작업장 생성 요청', { name: workplaceData.workplace_name });
const id = await new Promise((resolve, reject) => {
workplaceModel.createWorkplace(workplaceData, (err, lastID) => {
if (err) reject(new DatabaseError('작업장 생성 중 오류가 발생했습니다'));
else resolve(lastID);
});
});
const id = await workplaceModel.createWorkplace(workplaceData);
logger.info('작업장 생성 성공', { workplace_id: id });
@@ -203,35 +138,12 @@ exports.createWorkplace = asyncHandler(async (req, res) => {
});
});
/**
* 전체 작업장 조회
*/
exports.getAllWorkplaces = asyncHandler(async (req, res) => {
const categoryId = req.query.category_id;
// 카테고리별 필터링
if (categoryId) {
const rows = await new Promise((resolve, reject) => {
workplaceModel.getWorkplacesByCategory(categoryId, (err, data) => {
if (err) reject(new DatabaseError('작업장 목록 조회 중 오류가 발생했습니다'));
else resolve(data);
});
});
return res.json({
success: true,
data: rows,
message: '작업장 목록 조회 성공'
});
}
// 전체 조회
const rows = await new Promise((resolve, reject) => {
workplaceModel.getAllWorkplaces((err, data) => {
if (err) reject(new DatabaseError('작업장 목록 조회 중 오류가 발생했습니다'));
else resolve(data);
});
});
const rows = categoryId
? await workplaceModel.getWorkplacesByCategory(categoryId)
: await workplaceModel.getAllWorkplaces();
res.json({
success: true,
@@ -240,16 +152,8 @@ exports.getAllWorkplaces = asyncHandler(async (req, res) => {
});
});
/**
* 활성 작업장만 조회
*/
exports.getActiveWorkplaces = asyncHandler(async (req, res) => {
const rows = await new Promise((resolve, reject) => {
workplaceModel.getActiveWorkplaces((err, data) => {
if (err) reject(new DatabaseError('활성 작업장 목록 조회 중 오류가 발생했습니다'));
else resolve(data);
});
});
const rows = await workplaceModel.getActiveWorkplaces();
res.json({
success: true,
@@ -258,18 +162,9 @@ exports.getActiveWorkplaces = asyncHandler(async (req, res) => {
});
});
/**
* 단일 작업장 조회
*/
exports.getWorkplaceById = asyncHandler(async (req, res) => {
const workplaceId = req.params.id;
const workplace = await new Promise((resolve, reject) => {
workplaceModel.getWorkplaceById(workplaceId, (err, data) => {
if (err) reject(new DatabaseError('작업장 조회 중 오류가 발생했습니다'));
else resolve(data);
});
});
const workplace = await workplaceModel.getWorkplaceById(workplaceId);
if (!workplace) {
throw new NotFoundError('작업장을 찾을 수 없습니다');
@@ -282,9 +177,6 @@ exports.getWorkplaceById = asyncHandler(async (req, res) => {
});
});
/**
* 작업장 수정
*/
exports.updateWorkplace = asyncHandler(async (req, res) => {
const workplaceId = req.params.id;
const workplaceData = req.body;
@@ -295,19 +187,11 @@ exports.updateWorkplace = asyncHandler(async (req, res) => {
logger.info('작업장 수정 요청', { workplace_id: workplaceId });
// 기존 작업장 정보 가져오기
const existingWorkplace = await new Promise((resolve, reject) => {
workplaceModel.getWorkplaceById(workplaceId, (err, data) => {
if (err) reject(new DatabaseError('작업장 조회 중 오류가 발생했습니다'));
else resolve(data);
});
});
const existingWorkplace = await workplaceModel.getWorkplaceById(workplaceId);
if (!existingWorkplace) {
throw new NotFoundError('작업장을 찾을 수 없습니다');
}
// layout_image가 요청에 없거나 null이면 기존 값 보존
const updateData = {
...workplaceData,
layout_image: (workplaceData.layout_image !== undefined && workplaceData.layout_image !== null)
@@ -315,12 +199,7 @@ exports.updateWorkplace = asyncHandler(async (req, res) => {
: existingWorkplace.layout_image
};
await new Promise((resolve, reject) => {
workplaceModel.updateWorkplace(workplaceId, updateData, (err, result) => {
if (err) reject(new DatabaseError('작업장 수정 중 오류가 발생했습니다'));
else resolve(result);
});
});
await workplaceModel.updateWorkplace(workplaceId, updateData);
logger.info('작업장 수정 성공', { workplace_id: workplaceId });
@@ -330,20 +209,12 @@ exports.updateWorkplace = asyncHandler(async (req, res) => {
});
});
/**
* 작업장 삭제
*/
exports.deleteWorkplace = asyncHandler(async (req, res) => {
const workplaceId = req.params.id;
logger.info('작업장 삭제 요청', { workplace_id: workplaceId });
await new Promise((resolve, reject) => {
workplaceModel.deleteWorkplace(workplaceId, (err, result) => {
if (err) reject(new DatabaseError('작업장 삭제 중 오류가 발생했습니다'));
else resolve(result);
});
});
await workplaceModel.deleteWorkplace(workplaceId);
logger.info('작업장 삭제 성공', { workplace_id: workplaceId });
@@ -355,9 +226,6 @@ exports.deleteWorkplace = asyncHandler(async (req, res) => {
// ==================== 작업장 지도 영역 관련 ====================
/**
* 카테고리 레이아웃 이미지 업로드
*/
exports.uploadCategoryLayoutImage = asyncHandler(async (req, res) => {
const categoryId = req.params.id;
@@ -369,19 +237,11 @@ exports.uploadCategoryLayoutImage = asyncHandler(async (req, res) => {
logger.info('카테고리 레이아웃 이미지 업로드 요청', { category_id: categoryId, path: imagePath });
// 현재 카테고리 정보 가져오기
const category = await new Promise((resolve, reject) => {
workplaceModel.getCategoryById(categoryId, (err, data) => {
if (err) reject(new DatabaseError('카테고리 조회 중 오류가 발생했습니다'));
else resolve(data);
});
});
const category = await workplaceModel.getCategoryById(categoryId);
if (!category) {
throw new NotFoundError('카테고리를 찾을 수 없습니다');
}
// 카테고리 정보 업데이트 (이미지 경로만 변경)
const updatedData = {
category_name: category.category_name,
description: category.description,
@@ -390,12 +250,7 @@ exports.uploadCategoryLayoutImage = asyncHandler(async (req, res) => {
layout_image: imagePath
};
await new Promise((resolve, reject) => {
workplaceModel.updateCategory(categoryId, updatedData, (err, result) => {
if (err) reject(new DatabaseError('이미지 경로 저장 중 오류가 발생했습니다'));
else resolve(result);
});
});
await workplaceModel.updateCategory(categoryId, updatedData);
logger.info('레이아웃 이미지 업로드 성공', { category_id: categoryId });
@@ -406,9 +261,6 @@ exports.uploadCategoryLayoutImage = asyncHandler(async (req, res) => {
});
});
/**
* 작업장 레이아웃 이미지 업로드
*/
exports.uploadWorkplaceLayoutImage = asyncHandler(async (req, res) => {
const workplaceId = req.params.id;
@@ -420,19 +272,11 @@ exports.uploadWorkplaceLayoutImage = asyncHandler(async (req, res) => {
logger.info('작업장 레이아웃 이미지 업로드 요청', { workplace_id: workplaceId, path: imagePath });
// 현재 작업장 정보 가져오기
const workplace = await new Promise((resolve, reject) => {
workplaceModel.getWorkplaceById(workplaceId, (err, data) => {
if (err) reject(new DatabaseError('작업장 조회 중 오류가 발생했습니다'));
else resolve(data);
});
});
const workplace = await workplaceModel.getWorkplaceById(workplaceId);
if (!workplace) {
throw new NotFoundError('작업장을 찾을 수 없습니다');
}
// 작업장 정보 업데이트 (이미지 경로만 변경)
const updatedData = {
workplace_name: workplace.workplace_name,
category_id: workplace.category_id,
@@ -443,12 +287,7 @@ exports.uploadWorkplaceLayoutImage = asyncHandler(async (req, res) => {
layout_image: imagePath
};
await new Promise((resolve, reject) => {
workplaceModel.updateWorkplace(workplaceId, updatedData, (err, result) => {
if (err) reject(new DatabaseError('이미지 경로 저장 중 오류가 발생했습니다'));
else resolve(result);
});
});
await workplaceModel.updateWorkplace(workplaceId, updatedData);
logger.info('작업장 레이아웃 이미지 업로드 성공', { workplace_id: workplaceId });
@@ -459,9 +298,6 @@ exports.uploadWorkplaceLayoutImage = asyncHandler(async (req, res) => {
});
});
/**
* 지도 영역 생성
*/
exports.createMapRegion = asyncHandler(async (req, res) => {
const regionData = req.body;
@@ -471,12 +307,7 @@ exports.createMapRegion = asyncHandler(async (req, res) => {
logger.info('지도 영역 생성 요청', { workplace_id: regionData.workplace_id });
const id = await new Promise((resolve, reject) => {
workplaceModel.createMapRegion(regionData, (err, lastID) => {
if (err) reject(new DatabaseError('지도 영역 생성 중 오류가 발생했습니다'));
else resolve(lastID);
});
});
const id = await workplaceModel.createMapRegion(regionData);
logger.info('지도 영역 생성 성공', { region_id: id });
@@ -487,18 +318,9 @@ exports.createMapRegion = asyncHandler(async (req, res) => {
});
});
/**
* 카테고리별 지도 영역 조회 (작업장 정보 포함)
*/
exports.getMapRegionsByCategory = asyncHandler(async (req, res) => {
const categoryId = req.params.categoryId;
const rows = await new Promise((resolve, reject) => {
workplaceModel.getMapRegionsByCategory(categoryId, (err, data) => {
if (err) reject(new DatabaseError('지도 영역 조회 중 오류가 발생했습니다'));
else resolve(data);
});
});
const rows = await workplaceModel.getMapRegionsByCategory(categoryId);
res.json({
success: true,
@@ -507,18 +329,9 @@ exports.getMapRegionsByCategory = asyncHandler(async (req, res) => {
});
});
/**
* 작업장별 지도 영역 조회
*/
exports.getMapRegionByWorkplace = asyncHandler(async (req, res) => {
const workplaceId = req.params.workplaceId;
const region = await new Promise((resolve, reject) => {
workplaceModel.getMapRegionByWorkplace(workplaceId, (err, data) => {
if (err) reject(new DatabaseError('지도 영역 조회 중 오류가 발생했습니다'));
else resolve(data);
});
});
const region = await workplaceModel.getMapRegionByWorkplace(workplaceId);
res.json({
success: true,
@@ -527,21 +340,13 @@ exports.getMapRegionByWorkplace = asyncHandler(async (req, res) => {
});
});
/**
* 지도 영역 수정
*/
exports.updateMapRegion = asyncHandler(async (req, res) => {
const regionId = req.params.id;
const regionData = req.body;
logger.info('지도 영역 수정 요청', { region_id: regionId });
await new Promise((resolve, reject) => {
workplaceModel.updateMapRegion(regionId, regionData, (err, result) => {
if (err) reject(new DatabaseError('지도 영역 수정 중 오류가 발생했습니다'));
else resolve(result);
});
});
await workplaceModel.updateMapRegion(regionId, regionData);
logger.info('지도 영역 수정 성공', { region_id: regionId });
@@ -551,20 +356,12 @@ exports.updateMapRegion = asyncHandler(async (req, res) => {
});
});
/**
* 지도 영역 삭제
*/
exports.deleteMapRegion = asyncHandler(async (req, res) => {
const regionId = req.params.id;
logger.info('지도 영역 삭제 요청', { region_id: regionId });
await new Promise((resolve, reject) => {
workplaceModel.deleteMapRegion(regionId, (err, result) => {
if (err) reject(new DatabaseError('지도 영역 삭제 중 오류가 발생했습니다'));
else resolve(result);
});
});
await workplaceModel.deleteMapRegion(regionId);
logger.info('지도 영역 삭제 성공', { region_id: regionId });