Skip to content
Snippets Groups Projects
Commit 58234d3c authored by 조대희's avatar 조대희
Browse files

refactor: 스케줄 서비스 중복 코드 함수화 (#5)

parent 387f65ca
No related branches found
No related tags found
2 merge requests!31Develop,!6[#5] Schedule 서비스 로직 개발
...@@ -3,6 +3,54 @@ const Schedule = require('../models/Schedule'); ...@@ -3,6 +3,54 @@ const Schedule = require('../models/Schedule');
class schedulService { 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 { ...@@ -19,16 +67,9 @@ class schedulService {
* 사용자 스케줄 생성 * 사용자 스케줄 생성
*/ */
async createSchedule({ userId, title, start_time, end_time, is_fixed }) { 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); const overlap = await this.checkScheduleOverlap(userId, start_time, end_time);
if (overlap) { if (overlap) {
throw new Error('Schedule overlaps with existing schedule'); throw new Error('Schedule overlaps with existing schedule');
...@@ -43,75 +84,57 @@ class schedulService { ...@@ -43,75 +84,57 @@ class schedulService {
expiry_date: is_fixed ? null : this.getNextMonday() expiry_date: is_fixed ? null : this.getNextMonday()
}; };
const schedule = await Schedule.create(scheduleData, { transaction }); return Schedule.create(scheduleData, { transaction });
await transaction.commit(); });
return schedule;
} catch (error) {
await transaction.rollback();
throw new Error(`Failed to create schedule: ${error.message}`);
}
} }
/** /**
* 사용자 스케줄 수정 * 사용자 스케줄 수정
*/ */
async updateSchedule(id, userId, updateData) { async updateSchedule(id, userId, updateData) {
const transaction = await Schedule.sequelize.transaction(); return this.withTransaction(async (transaction) => {
try {
const schedule = await Schedule.findOne({ const schedule = await Schedule.findOne({
where: { id, user_id: userId } where: { id, user_id: userId },
transaction
}); });
if (!schedule) { if (!schedule) {
throw new Error('Schedule not found'); throw new Error('Schedule not found');
} }
// 일정 시작 시간 - 종료 시간 유효성 검사 this.validateScheduleTime(updateData.start_time, updateData.end_time);
if (new Date(updateData.start_time) >= new Date(updateData.end_time)) {
throw new Error('Start time must be before end time');
}
// 중복 검사 const overlap = await this.checkScheduleOverlap(
const overlap = await this.checkScheduleOverlap(userId, updateData.start_time, updateData.end_time); userId,
updateData.start_time,
updateData.end_time,
id
);
if (overlap) { if (overlap) {
throw new Error('Schedule overlaps with existing schedule'); throw new Error('Schedule overlaps with existing schedule');
} }
// 스케줄 타입 변경하지 못하도록 update값 삭제 -> 기존값 유지
delete updateData.is_fixed; delete updateData.is_fixed;
return schedule.update(updateData, { transaction });
await schedule.update(updateData, { transaction }); });
await transaction.commit();
return schedule;
} catch (error) {
await transaction.rollback();
throw new Error(`Failed to update schedule: ${error.message}`);
}
} }
/** /**
* 사용자 스케줄 삭제 * 사용자 스케줄 삭제
*/ */
async deleteSchedule(id, userId) { async deleteSchedule(id, userId) {
const transaction = await Schedule.sequelize.transaction(); return this.withTransaction(async (transaction) => {
const result = await Schedule.destroy({
try {
const schedule = await Schedule.destroy({
where: { id, user_id: userId }, where: { id, user_id: userId },
transaction transaction
}); });
if (!schedule) { if (!result) {
throw new Error('Schedule not found'); throw new Error('Schedule not found');
} }
await transaction.commit();
return true; return true;
} catch (error) { });
await transaction.rollback();
throw new Error(`Failed to delete schedule: ${error.message}`);
}
} }
/** /**
...@@ -119,22 +142,10 @@ class schedulService { ...@@ -119,22 +142,10 @@ class schedulService {
*/ */
async getAllSchedules(userId) { async getAllSchedules(userId) {
try { try {
const schedules = await Schedule.findAll({ return Schedule.findAll({
where: { where: this.getScheduleWhereClause(userId),
user_id: userId,
[Op.or]: [
{ is_fixed: true },
{
is_fixed: false,
expiry_date: {
[Op.gt]: new Date()
}
}
]
},
order: [['start_time', 'ASC']] order: [['start_time', 'ASC']]
}); });
return schedules;
} catch (error) { } catch (error) {
throw new Error(`Failed to fetch schedules: ${error.message}`); throw new Error(`Failed to fetch schedules: ${error.message}`);
} }
...@@ -146,19 +157,7 @@ class schedulService { ...@@ -146,19 +157,7 @@ class schedulService {
async getScheduleById(id, userId) { async getScheduleById(id, userId) {
try { try {
const schedule = await Schedule.findOne({ const schedule = await Schedule.findOne({
where: { where: this.getScheduleWhereClause(userId, id)
id,
user_id: userId,
[Op.or]: [
{ is_fixed: true },
{
is_fixed: false,
expiry_date: {
[Op.gt]: new Date()
}
}
]
}
}); });
if (!schedule) { if (!schedule) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment