Skip to content
Snippets Groups Projects
scheduleService.js 5.27 KiB
Newer Older
  • Learn to ignore specific revisions
  • // services/scheduleService.js
    
    const sequelize = require('../config/sequelize');
    
    const { Op } = require('sequelize');
    
    const Schedule = require('../models/Schedule');
    
    const ScheduleResponseDTO = require('../dtos/ScheduleResponseDTO');
    
    class ScheduleService {
        /**
         * 스케줄 생성 (벌크)
    
         * @param {object} [transaction] - Sequelize 트랜잭션 객체 -> 미팅방에서 쓰기위해 트랜잭션을 넘겨받는걸 추가 
    
        async createSchedules({ userId, title, is_fixed, events }, transaction = null) {
            const scheduleDTOs = [];
    
            for (const event of events) {
                const { time_idx } = event;
    
                // 중복 스케줄 검사
                const overlap = await this.checkScheduleOverlap(userId, time_idx, transaction);
                if (overlap) {
                    throw new Error(`Schedule overlaps with existing schedule at time_idx ${time_idx}`);
    
                const scheduleData = {
                    user_id: userId,
                    title,
                    time_idx,
                    is_fixed,
                };
    
                const schedule = await Schedule.create(scheduleData, { transaction });
                scheduleDTOs.push(new ScheduleResponseDTO(schedule));
            }
    
            return scheduleDTOs;
    
        /**
         * 스케줄 수정 (벌크)
    
         * @param {Array} updates - 수정할 스케줄 배열
    
        async updateSchedules(userId, updates, transaction = null) {
            const updatedSchedules = [];
    
            for (const update of updates) {
                const { time_idx, title, is_fixed } = update;
    
                const schedule = await Schedule.findOne({
                    where: { user_id: userId, time_idx },
                    transaction,
                });
    
                if (!schedule) {
                    throw new Error(`Schedule not found at time_idx ${time_idx}`);
                }
    
                const updatedData = {};
                if (title !== undefined) updatedData.title = title;
                if (is_fixed !== undefined) updatedData.is_fixed = is_fixed;
    
                const updatedSchedule = await schedule.update(updatedData, { transaction });
                updatedSchedules.push(new ScheduleResponseDTO(updatedSchedule));
            }
    
            return updatedSchedules;
    
        /**
         * 스케줄 삭제 (벌크)
    
         * @param {number} userId - 사용자 ID
         * @param {Array<number>} time_idxs - 삭제할 스케줄의 time_idx 배열
         * @param {object} [transaction] - Sequelize 트랜잭션 객체
    
        async deleteSchedules(userId, time_idxs, transaction = null) {
            const deleted_time_idxs = [];
    
            for (const time_idx of time_idxs) {
                const deletedCount = await Schedule.destroy({
                    where: { user_id: userId, time_idx },
                    transaction,
                });
    
                if (deletedCount === 0) {
                    throw new Error(`Schedule not found at time_idx ${time_idx}`);
    
                deleted_time_idxs.push(time_idx);
            }
    
            return { deleted_time_idxs };
    
        /**
         * 특정 time_idx로 스케줄 조회
         */
        async getScheduleByTimeIdx(userId, time_idx) {
            const schedule = await Schedule.findOne({
                where: { user_id: userId, time_idx },
            });
    
            if (!schedule) {
                throw new Error('Schedule not found');
            }
    
            return new ScheduleResponseDTO(schedule);
    
        /**
         * 모든 스케줄 조회
         */
        async getAllSchedules(userId) {
            try {
                const schedules = await Schedule.findAll({
                    where: { user_id: userId },
                    order: [['time_idx', 'ASC']],
                });
                return schedules.map((schedule) => new ScheduleResponseDTO(schedule));
            } catch (error) {
                throw new Error(`Failed to fetch schedules: ${error.message}`);
            }
    
        async checkScheduleOverlap(userId, time_idx, transaction = null) {
    
            const overlappingSchedule = await Schedule.findOne({
                where: { user_id: userId, time_idx },
                transaction,
            });
    
            return !!overlappingSchedule;
        }
    
        async checkScheduleOverlapByTime(userId, time_idx_start, time_idx_end, transaction = null) {
    
            console.log(
                `checkScheduleOverlapByTime 호출: userId=${userId}, time_idx_start=${time_idx_start}, time_idx_end=${time_idx_end}`
            );
    
            const overlappingSchedule = await Schedule.findOne({
                where: {
                    user_id: userId,
    
                    time_idx: {
                        [Op.between]: [time_idx_start, time_idx_end] 
                    }
    
                },
                transaction,
            });
    
             console.log(`중복 스케줄: ${JSON.stringify(overlappingSchedule)}`);
        const result = !!overlappingSchedule;
        console.log(`스케줄 충돌 결과: ${result}`);
        return result;
    
        /**
         * 만료된 스케줄 삭제
         */
    
        async cleanExpiredSchedules() {
            try {
                const deletedCount = await Schedule.destroy({
                    where: { is_fixed: false },
                });
                //console.log(`Deleted ${deletedCount} flexible schedules.`);
            } catch (error) {
                console.error('Failed to clean expired schedules:', error);
                throw error;
            }
    
    module.exports = new ScheduleService();