From 8ce5b3349bdf89ae80e4d3c94dcaf0984e5ee76b Mon Sep 17 00:00:00 2001
From: Wo-ogie <siwall0105@gmail.com>
Date: Sun, 10 Dec 2023 00:19:50 +0900
Subject: [PATCH] =?UTF-8?q?refactor:=20Meeting=20=EA=B4=80=EB=A0=A8=20?=
 =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=9E=AC=EC=82=AC=EC=9A=A9=20=EA=B0=80?=
 =?UTF-8?q?=EB=8A=A5=ED=95=98=EB=8F=84=EB=A1=9D=20controller-service=20?=
 =?UTF-8?q?=EA=B5=AC=EC=A1=B0=EB=A1=9C=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 controllers/meeting.js | 81 ++++++++----------------------------------
 services/meeting.js    | 79 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 93 insertions(+), 67 deletions(-)
 create mode 100644 services/meeting.js

diff --git a/controllers/meeting.js b/controllers/meeting.js
index 3e4fe8f..99d1f50 100644
--- a/controllers/meeting.js
+++ b/controllers/meeting.js
@@ -1,10 +1,13 @@
 const bcrypt = require('bcrypt');
-const { Meeting, Participant, Schedule } = require('../models');
-const meetingRepositotry = require('../repository/meeting');
-const { sendMeetingVoteEndNotificationEmail } = require('../services/mail');
+const { Meeting, Participant } = require('../models');
+const meetingRepository = require('../repository/meeting');
+const {
+  getMeetingById,
+  getMeetingWithParticipantsById,
+  getMeetingWithParticipantsAndSchedulesById,
+  closeMeetingById,
+} = require('../services/meeting');
 const {
-  createMeetingNotFoundError,
-  createMeetingIsAlreadyClosedError,
   createPasswordNotMatchedError,
   createPasswordIsNullError,
 } = require('../errors/meetingErrors');
@@ -28,51 +31,6 @@ async function encryptPassword(password, next) {
   }
 }
 
-async function getMeetingById(meetingId) {
-  const meeting = await Meeting.findOne({
-    where: { id: meetingId },
-  });
-  if (!meeting) {
-    throw createMeetingNotFoundError();
-  }
-  return meeting;
-}
-
-async function getMeetingWithParticipantsById(meetingId) {
-  const meeting = await Meeting.findOne({
-    where: { id: meetingId },
-    include: [
-      {
-        model: Participant,
-      },
-    ],
-  });
-  if (!meeting) {
-    throw createMeetingNotFoundError();
-  }
-  return meeting;
-}
-
-async function getMeetingWithParticipantsAndSchedulesById(meetingId) {
-  const meeting = await Meeting.findOne({
-    where: { id: meetingId },
-    include: [
-      {
-        model: Participant,
-        include: [
-          {
-            model: Schedule,
-          },
-        ],
-      },
-    ],
-  });
-  if (!meeting) {
-    throw createMeetingNotFoundError();
-  }
-  return meeting;
-}
-
 async function getParticipantByNameAndMeetingId(name, meetingId) {
   const participant = await Participant.findOne({
     where: {
@@ -218,7 +176,7 @@ exports.getTopThreeConfirmedTimes = async (req, res, next) => {
     return res.status(400).json({ message: 'Purpose is required' });
   }
   try {
-    const results = await meetingRepositotry.getTopThreeConfirmedTimes(purpose);
+    const results = await meetingRepository.getTopThreeConfirmedTimes(purpose);
     return res.json({
       topThreeConfirmedTimes: results,
     });
@@ -227,31 +185,20 @@ exports.getTopThreeConfirmedTimes = async (req, res, next) => {
   }
 };
 
-function validateMeetingIsNotClosed(meeting) {
-  if (meeting.isClosed === true) {
-    throw createMeetingIsAlreadyClosedError();
-  }
-}
-
 exports.closeMeeting = async (req, res, next) => {
   try {
+    // TODO: query 최적화 필요
     const { meetingId } = req.params;
-    const meeting = await getMeetingWithParticipantsById(meetingId);
+
+    let meeting = await getMeetingById(meetingId);
     await validatePasswordIsMatched(
       req.body.adminPassword,
       meeting.adminPassword,
     );
-    validateMeetingIsNotClosed(meeting);
 
-    meeting.isClosed = true;
-    await meeting.save();
+    await closeMeetingById(meetingId);
 
-    await Promise.all(
-      meeting.Participants.filter((participant) => participant.email).map(
-        (participant) =>
-          sendMeetingVoteEndNotificationEmail(participant.email, meetingId),
-      ),
-    );
+    meeting = await getMeetingWithParticipantsById(meetingId);
     return res.json(MeetingResponse.from(meeting));
   } catch (error) {
     return next(error);
diff --git a/services/meeting.js b/services/meeting.js
new file mode 100644
index 0000000..6bfea25
--- /dev/null
+++ b/services/meeting.js
@@ -0,0 +1,79 @@
+const { sendMeetingVoteEndNotificationEmail } = require('./mail');
+const { Meeting, Participant, Schedule } = require('../models');
+const {
+  createMeetingNotFoundError,
+  createMeetingIsAlreadyClosedError,
+} = require('../errors/meetingErrors');
+
+const getMeetingById = async (meetingId) => {
+  const meeting = await Meeting.findOne({
+    where: { id: meetingId },
+  });
+  if (!meeting) {
+    throw createMeetingNotFoundError();
+  }
+  return meeting;
+};
+
+const getMeetingWithParticipantsById = async (meetingId) => {
+  const meeting = await Meeting.findOne({
+    where: { id: meetingId },
+    include: [
+      {
+        model: Participant,
+      },
+    ],
+  });
+  if (!meeting) {
+    throw createMeetingNotFoundError();
+  }
+  return meeting;
+};
+
+const getMeetingWithParticipantsAndSchedulesById = async (meetingId) => {
+  const meeting = await Meeting.findOne({
+    where: { id: meetingId },
+    include: [
+      {
+        model: Participant,
+        include: [
+          {
+            model: Schedule,
+          },
+        ],
+      },
+    ],
+  });
+  if (!meeting) {
+    throw createMeetingNotFoundError();
+  }
+  return meeting;
+};
+
+function validateMeetingIsNotClosed(meeting) {
+  if (meeting.isClosed === true) {
+    throw createMeetingIsAlreadyClosedError();
+  }
+}
+
+const closeMeetingById = async (meetingId) => {
+  const meeting = getMeetingById(meetingId);
+  validateMeetingIsNotClosed(meeting);
+
+  meeting.isClosed = true;
+  await meeting.save();
+
+  await Promise.all(
+    meeting.Participants.filter((participant) => participant.email).map(
+      (participant) =>
+        sendMeetingVoteEndNotificationEmail(participant.email, meetingId),
+    ),
+  );
+};
+
+module.exports = {
+  getMeetingById,
+  getMeetingWithParticipantsById,
+  getMeetingWithParticipantsAndSchedulesById,
+  closeMeetingById,
+};
-- 
GitLab