From 58234d3c30e01eed440cfb4b1e4ffc3bec0f96b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A1=B0=EB=8C=80=ED=9D=AC?= <joedaehui@ajou.ac.kr> Date: Thu, 14 Nov 2024 23:47:24 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20=EC=8A=A4=EC=BC=80=EC=A4=84=20?= =?UTF-8?q?=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=A4=91=EB=B3=B5=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=ED=95=A8=EC=88=98=ED=99=94=20(#5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/scheduleService.js | 143 ++++++++++++++++++------------------ 1 file changed, 71 insertions(+), 72 deletions(-) diff --git a/services/scheduleService.js b/services/scheduleService.js index 7fd1707..79a787f 100644 --- a/services/scheduleService.js +++ b/services/scheduleService.js @@ -3,6 +3,54 @@ const Schedule = require('../models/Schedule'); class schedulService { + /** + * transactin wrapper 함수 + */ + async withTransaction(callback) { + const transaction = await Schedule.sequelize.transaction(); + try { + const result = await callback(transaction); + await transaction.commit(); + return result; + } catch (error) { + await transaction.rollback(); + throw error; + } + } + + /** + * 공통 where 절 생성 + */ + getScheduleWhereClause(userId, id = null) { + const where = { + user_id: userId, + [Op.or]: [ + { is_fixed: true }, + { + is_fixed: false, + expiry_date: { + [Op.gt]: new Date() + } + } + ] + }; + + if (id) { + where.id = id; + } + + return where; + } + + /** + * 스케줄 유효성 검사 + */ + validateScheduleTime(start_time, end_time) { + if (new Date(start_time) >= new Date(end_time)) { + throw new Error('Start time must be before end time'); + } + } + /** * 유동 스케줄 만료일 구하기 */ @@ -19,16 +67,9 @@ class schedulService { * 사용자 스케줄 생성 */ async createSchedule({ userId, title, start_time, end_time, is_fixed }) { - const transaction = await Schedule.sequelize.transaction(); + return this.withTransaction(async (transaction) => { + this.validateScheduleTime(start_time, end_time); - try { - - // 일정 시작 시간 - 종료 시간 유효성 검사 - if (new Date(start_time) >= new Date(end_time)) { - throw new Error('Start time must be before end time'); - } - - // 중복 검사 const overlap = await this.checkScheduleOverlap(userId, start_time, end_time); if (overlap) { throw new Error('Schedule overlaps with existing schedule'); @@ -43,75 +84,57 @@ class schedulService { expiry_date: is_fixed ? null : this.getNextMonday() }; - const schedule = await Schedule.create(scheduleData, { transaction }); - await transaction.commit(); - return schedule; - } catch (error) { - await transaction.rollback(); - throw new Error(`Failed to create schedule: ${error.message}`); - } + return Schedule.create(scheduleData, { transaction }); + }); } /** * 사용자 스케줄 수정 */ async updateSchedule(id, userId, updateData) { - const transaction = await Schedule.sequelize.transaction(); - - try { + return this.withTransaction(async (transaction) => { const schedule = await Schedule.findOne({ - where: { id, user_id: userId } + where: { id, user_id: userId }, + transaction }); if (!schedule) { throw new Error('Schedule not found'); } - // 일정 시작 시간 - 종료 시간 유효성 검사 - if (new Date(updateData.start_time) >= new Date(updateData.end_time)) { - throw new Error('Start time must be before end time'); - } + this.validateScheduleTime(updateData.start_time, updateData.end_time); - // 중복 검사 - const overlap = await this.checkScheduleOverlap(userId, updateData.start_time, updateData.end_time); + const overlap = await this.checkScheduleOverlap( + userId, + updateData.start_time, + updateData.end_time, + id + ); if (overlap) { throw new Error('Schedule overlaps with existing schedule'); } - // 스케줄 타입 변경하지 못하도록 update값 삭제 -> 기존값 유지 delete updateData.is_fixed; - - await schedule.update(updateData, { transaction }); - await transaction.commit(); - return schedule; - } catch (error) { - await transaction.rollback(); - throw new Error(`Failed to update schedule: ${error.message}`); - } + return schedule.update(updateData, { transaction }); + }); } /** * 사용자 스케줄 삭제 */ async deleteSchedule(id, userId) { - const transaction = await Schedule.sequelize.transaction(); - - try { - const schedule = await Schedule.destroy({ + return this.withTransaction(async (transaction) => { + const result = await Schedule.destroy({ where: { id, user_id: userId }, transaction }); - if (!schedule) { + if (!result) { throw new Error('Schedule not found'); } - await transaction.commit(); return true; - } catch (error) { - await transaction.rollback(); - throw new Error(`Failed to delete schedule: ${error.message}`); - } + }); } /** @@ -119,22 +142,10 @@ class schedulService { */ async getAllSchedules(userId) { try { - const schedules = await Schedule.findAll({ - where: { - user_id: userId, - [Op.or]: [ - { is_fixed: true }, - { - is_fixed: false, - expiry_date: { - [Op.gt]: new Date() - } - } - ] - }, + return Schedule.findAll({ + where: this.getScheduleWhereClause(userId), order: [['start_time', 'ASC']] }); - return schedules; } catch (error) { throw new Error(`Failed to fetch schedules: ${error.message}`); } @@ -146,19 +157,7 @@ class schedulService { async getScheduleById(id, userId) { try { const schedule = await Schedule.findOne({ - where: { - id, - user_id: userId, - [Op.or]: [ - { is_fixed: true }, - { - is_fixed: false, - expiry_date: { - [Op.gt]: new Date() - } - } - ] - } + where: this.getScheduleWhereClause(userId, id) }); if (!schedule) { -- GitLab