From a378c510a1aee98da61d0ed1ae954f9308c72e19 Mon Sep 17 00:00:00 2001 From: Wo-ogie <siwall0105@gmail.com> Date: Sat, 25 Nov 2023 12:13:35 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=82=B4=20=EC=8A=A4=EC=BC=80=EC=A4=84?= =?UTF-8?q?=20=EC=A0=80=EC=9E=A5=ED=95=98=EA=B8=B0=20API=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.js | 2 ++ controllers/schedule.js | 41 +++++++++++++++++++++++++++++++ dto/response/schedulesResponse.js | 15 +++++++++++ errors/scheduleErrors.js | 7 ++++++ middlewares/auth.js | 28 +++++++++++++++++++++ middlewares/index.js | 13 ---------- routes/meeting.js | 2 +- routes/mySchedule.js | 9 +++++++ 8 files changed, 103 insertions(+), 14 deletions(-) create mode 100644 controllers/schedule.js create mode 100644 dto/response/schedulesResponse.js create mode 100644 errors/scheduleErrors.js create mode 100644 middlewares/auth.js delete mode 100644 middlewares/index.js create mode 100644 routes/mySchedule.js diff --git a/app.js b/app.js index 0fd3e42..2897b98 100644 --- a/app.js +++ b/app.js @@ -10,6 +10,7 @@ dotenv.config(); const meetingRouter = require('./routes/meeting'); const participantRouter = require('./routes/participant'); +const myScheduleRouter = require('./routes/mySchedule'); const { sequelize } = require('./models'); const app = express(); @@ -50,6 +51,7 @@ app.use( app.use('/meetings', meetingRouter); app.use('/meetings/:meetingId/participants', participantRouter); +app.use('/meetings/:meetingId/my/schedules', myScheduleRouter); app.use((req, res, next) => { const error = new Error(`There is no router. ${req.method} ${req.url}`); diff --git a/controllers/schedule.js b/controllers/schedule.js new file mode 100644 index 0000000..56067f5 --- /dev/null +++ b/controllers/schedule.js @@ -0,0 +1,41 @@ +const { Schedule, sequelize } = require('../models'); +const { getLoggedInParticipantId } = require('../middlewares/auth'); +const SchedulesResponse = require('../dto/response/schedulesResponse'); +const { createScheduleAlreadyExistError } = require('../errors/scheduleErrors'); + +async function validateScheduleNotExist(participantId) { + const numOfSchedules = await Schedule.count({ + where: { + ParticipantId: participantId, + }, + }); + if (numOfSchedules > 0) { + throw createScheduleAlreadyExistError(); + } +} + +exports.createMySchedules = async (req, res, next) => { + const participantId = getLoggedInParticipantId(req, res, next); + const { availableSchedules } = req.body; + try { + await validateScheduleNotExist(participantId); + + const schedules = await sequelize.transaction(async (transaction) => + Promise.all( + availableSchedules.map((availableSchedule) => + Schedule.create( + { + availableDate: availableSchedule.availableDate, + availableTimes: availableSchedule.availableTimes, + ParticipantId: participantId, + }, + { transaction }, + ), + ), + ), + ); + return res.json(SchedulesResponse.from(schedules)); + } catch (error) { + return next(error); + } +}; diff --git a/dto/response/schedulesResponse.js b/dto/response/schedulesResponse.js new file mode 100644 index 0000000..db96a75 --- /dev/null +++ b/dto/response/schedulesResponse.js @@ -0,0 +1,15 @@ +const ScheduleResponse = require('./scheduleResponse'); + +class SchedulesResponse { + constructor(schedules) { + this.schedules = schedules; + } + + static from(schedules) { + return new SchedulesResponse( + schedules.map((schedule) => ScheduleResponse.from(schedule)), + ); + } +} + +module.exports = SchedulesResponse; diff --git a/errors/scheduleErrors.js b/errors/scheduleErrors.js new file mode 100644 index 0000000..29ab8f8 --- /dev/null +++ b/errors/scheduleErrors.js @@ -0,0 +1,7 @@ +exports.createScheduleAlreadyExistError = () => { + const error = new Error( + '기존에 저장한 스케줄이 존재합니다. 기존 스케줄 데이터를 삭제한 후 다시 시도하거나, 수정하기 API를 사용해주세요.', + ); + error.status = 409; + return error; +}; diff --git a/middlewares/auth.js b/middlewares/auth.js new file mode 100644 index 0000000..81884a2 --- /dev/null +++ b/middlewares/auth.js @@ -0,0 +1,28 @@ +function parseParticipantData(req, res, next) { + let participantData = null; + if (req.signedCookies.participantData) { + participantData = JSON.parse(req.signedCookies.participantData); + } + if (!participantData) { + const error = new Error('인증 권한이 없습니다.'); + error.status = 401; + return next(error); + } + return participantData; +} + +exports.isAuthenticated = (req, res, next) => { + const participantData = parseParticipantData(req); + if (participantData.meetingId !== req.params.meetingId) { + const error = new Error('접근 권한이 없습니다.'); + error.status = 401; + next(error); + return; + } + next(); +}; + +exports.getLoggedInParticipantId = (req, res, next) => { + const participantData = parseParticipantData(req, res, next); + return participantData?.participantId; +}; diff --git a/middlewares/index.js b/middlewares/index.js deleted file mode 100644 index 27afea0..0000000 --- a/middlewares/index.js +++ /dev/null @@ -1,13 +0,0 @@ -exports.isAuthenticated = (req, res, next) => { - let participantData = null; - if (req.signedCookies.participantData) { - participantData = JSON.parse(req.signedCookies.participantData); - } - if (!participantData || participantData.meetingId !== req.params.meetingId) { - const error = new Error('접근 권한이 없습니다.'); - error.status = 401; - next(error); - return; - } - next(); -}; diff --git a/routes/meeting.js b/routes/meeting.js index 7763ca5..956df30 100644 --- a/routes/meeting.js +++ b/routes/meeting.js @@ -1,5 +1,5 @@ const express = require('express'); -const { isAuthenticated } = require('../middlewares/index'); +const { isAuthenticated } = require('../middlewares/auth'); const { createMeeting, entry, diff --git a/routes/mySchedule.js b/routes/mySchedule.js new file mode 100644 index 0000000..20991db --- /dev/null +++ b/routes/mySchedule.js @@ -0,0 +1,9 @@ +const express = require('express'); +const { isAuthenticated } = require('../middlewares/auth'); +const { createMySchedules } = require('../controllers/schedule'); + +const router = express.Router({ mergeParams: true }); + +router.post('/bulk', isAuthenticated, createMySchedules); + +module.exports = router; -- GitLab