From 84ec912d27debd8d93bc59ee1c15a3da9658c832 Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Sat, 30 Nov 2024 18:15:37 +0900
Subject: [PATCH 01/61] =?UTF-8?q?rename:=20=ED=8C=8C=EC=9D=BC=EB=AA=85=20?=
 =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=95=88=EB=90=9C=20=EC=98=A4=EB=A5=98=20?=
 =?UTF-8?q?=ED=95=B4=EA=B2=B0(#21)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 models/Invite.js | 5 +++--
 models/index.js  | 1 -
 sync.js          | 2 --
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/models/Invite.js b/models/Invite.js
index d4e6105..621344c 100644
--- a/models/Invite.js
+++ b/models/Invite.js
@@ -1,7 +1,8 @@
-//models/invite.js
-
+// models/invite.js
 const { DataTypes } = require('sequelize');
 const sequelize = require('../config/sequelize');
+const User = require('./user');
+const Meeting = require('./meeting');
 
 const Invite = sequelize.define('Invite', {
     status: {
diff --git a/models/index.js b/models/index.js
index 2998026..5218166 100644
--- a/models/index.js
+++ b/models/index.js
@@ -46,5 +46,4 @@ module.exports = {
     MeetingParticipant,
   Friend,
   FcmToken, 
-  Invite,
 };
diff --git a/sync.js b/sync.js
index 84cfdef..3890bf2 100644
--- a/sync.js
+++ b/sync.js
@@ -1,7 +1,5 @@
 // sync.js
 
-//require('dotenv').config(); // �섍꼍 蹂��� 濡쒕뱶
-
 const sequelize = require('./config/sequelize');
 const model=require('./models'); // 紐⑤뜽�ㅼ쓣 媛��몄샂 (�ъ씠�� �댄럺�몃줈 紐⑤뜽�ㅼ씠 �깅줉��)
 
-- 
GitLab


From af05da72100f0da67c91b5891eccf44a42f92a91 Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Sat, 30 Nov 2024 18:16:47 +0900
Subject: [PATCH 02/61] =?UTF-8?q?rename:=20=ED=8C=8C=EC=9D=BC=EB=AA=85=20?=
 =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=95=88=EB=90=9C=20=EC=98=A4=EB=A5=98=20?=
 =?UTF-8?q?=ED=95=B4=EA=B2=B0(#21)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 schemas/ChatRooms.js       | 2 +-
 services/meetingService.js | 3 ---
 2 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/schemas/ChatRooms.js b/schemas/ChatRooms.js
index 1c2001c..323bb94 100644
--- a/schemas/ChatRooms.js
+++ b/schemas/ChatRooms.js
@@ -1,4 +1,4 @@
-// schemas/chatRooms.js
+//schemas/chatRooms.js
 const mongoose = require('mongoose');
 
 // MongoDB 梨꾪똿諛� �ㅽ궎留� �섏젙 (FCM �좏겙�� 諛곗뿴濡� 愿�由�)
diff --git a/services/meetingService.js b/services/meetingService.js
index 0c04014..24b9e67 100644
--- a/services/meetingService.js
+++ b/services/meetingService.js
@@ -1,7 +1,4 @@
 
-// const { Meeting, MeetingParticipant, User, Schedule } = require('../models');
-// const ChatRoom = require('../models/chatRooms');
-// const FcmToken = require('../models/fcmToken');
 // services/meetingService.js
 const { v4: uuidv4 } = require('uuid');
 const { Op } = require('sequelize');
-- 
GitLab


From be050e46651a8753c634f09405edddfbe950aba0 Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Sat, 30 Nov 2024 18:18:14 +0900
Subject: [PATCH 03/61] =?UTF-8?q?rename:=20=ED=8C=8C=EC=9D=BC=EB=AA=85=20?=
 =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=95=88=EB=90=9C=20=EC=98=A4=EB=A5=98=20?=
 =?UTF-8?q?=ED=95=B4=EA=B2=B0(#21)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 models/Friend.js | 28 ----------------------------
 1 file changed, 28 deletions(-)
 delete mode 100644 models/Friend.js

diff --git a/models/Friend.js b/models/Friend.js
deleted file mode 100644
index 21ef4aa..0000000
--- a/models/Friend.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// models/friend.js
-
-const { DataTypes } = require('sequelize');
-const sequelize = require('../config/sequelize');
-const User = require('./user');
-
-const Friend = sequelize.define('Friend', {
-    status: {
-        type: DataTypes.ENUM('PENDING', 'ACCEPTED'),
-        allowNull: false,
-        defaultValue: 'PENDING',
-    }
-}, {
-    tableName: 'Friends',
-    timestamps: true,
-    underscored: true,
-    indexes: [
-        {
-            unique: true,
-            fields: ['requester_id', 'receiver_id']
-        },
-        {
-            fields: ['status']
-        }
-    ]
-});
-
-module.exports = Friend;
-- 
GitLab


From 12fbca62339594fa44ff31585764ea392dfde784 Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Sat, 30 Nov 2024 18:18:51 +0900
Subject: [PATCH 04/61] =?UTF-8?q?rename:=20=ED=8C=8C=EC=9D=BC=EB=AA=85=20?=
 =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=95=88=EB=90=9C=20=EC=98=A4=EB=A5=98=20?=
 =?UTF-8?q?=ED=95=B4=EA=B2=B0(#21)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 models/friend.js | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)
 create mode 100644 models/friend.js

diff --git a/models/friend.js b/models/friend.js
new file mode 100644
index 0000000..21ef4aa
--- /dev/null
+++ b/models/friend.js
@@ -0,0 +1,28 @@
+// models/friend.js
+
+const { DataTypes } = require('sequelize');
+const sequelize = require('../config/sequelize');
+const User = require('./user');
+
+const Friend = sequelize.define('Friend', {
+    status: {
+        type: DataTypes.ENUM('PENDING', 'ACCEPTED'),
+        allowNull: false,
+        defaultValue: 'PENDING',
+    }
+}, {
+    tableName: 'Friends',
+    timestamps: true,
+    underscored: true,
+    indexes: [
+        {
+            unique: true,
+            fields: ['requester_id', 'receiver_id']
+        },
+        {
+            fields: ['status']
+        }
+    ]
+});
+
+module.exports = Friend;
-- 
GitLab


From 476327cd151c014e39bfced78edb59d68fb783a2 Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Mon, 2 Dec 2024 21:57:38 +0900
Subject: [PATCH 05/61] =?UTF-8?q?refactor;=20=EB=AF=B8=ED=8C=85=EC=BB=A8?=
 =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=EC=97=90=20=EB=AF=B8=ED=8C=85?=
 =?UTF-8?q?=EB=82=98=EA=B0=80=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?=
 =?UTF-8?q?=EA=B0=80(#22)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 controllers/meetingController.js | 17 +++++++++++++++++
 models/fcmToken.js               |  1 +
 passport/googleStrategy.js       |  2 +-
 services/schedule.test.js        |  6 ++----
 4 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/controllers/meetingController.js b/controllers/meetingController.js
index 12ee66a..b6cc752 100644
--- a/controllers/meetingController.js
+++ b/controllers/meetingController.js
@@ -116,6 +116,23 @@ class MeetingController {
             res.status(500).json({ error: err.message || '紐⑥엫 �곸꽭 議고쉶 �ㅽ뙣' });
         }
     }
+    /*
+    Delete /api/meetings/:meetingId
+    */
+    async closeMeeting(req,res)
+    {
+    
+        const { meetingId } = req.params;
+        const userid=req.user.id;  
+        try {
+            const meetingDetail = await MeetingService.leaveMeeting(meetingId,userId);
+            res.status(200).json('紐⑥엫 ��젣�깃났!');
+        } catch (err) {
+            console.error('紐⑥엫 ��젣 �ㅻ쪟', err);
+            res.status(500).json({ error: err.message || '紐⑥엫��젣 �ㅽ뙣' });
+        }
+    }
+
 }
 
 module.exports = new MeetingController();
diff --git a/models/fcmToken.js b/models/fcmToken.js
index f9fa920..855b833 100644
--- a/models/fcmToken.js
+++ b/models/fcmToken.js
@@ -1,3 +1,4 @@
+//models/friend.js
 const { DataTypes } = require('sequelize');
 const sequelize = require('../config/sequelize');
 const User = require('./user'); // �щ컮瑜� 寃쎈줈 �뺤씤
diff --git a/passport/googleStrategy.js b/passport/googleStrategy.js
index 7acaf17..cd23c9d 100644
--- a/passport/googleStrategy.js
+++ b/passport/googleStrategy.js
@@ -5,7 +5,7 @@ const User = require('../models/user');
 
 module.exports = new GoogleStrategy(
   {
-    clientID: process.env.GOOGLE_CLIENT_ID, // .env �뚯씪�� �ㅼ젙
+    clientID: process.env.GOOGLE_CLIENT_ID,
     clientSecret: process.env.GOOGLE_CLIENT_SECRET,
     callbackURL: process.env.CALLBACK_URL,
   },
diff --git a/services/schedule.test.js b/services/schedule.test.js
index 373d1e5..1002f0a 100644
--- a/services/schedule.test.js
+++ b/services/schedule.test.js
@@ -1,16 +1,14 @@
 // test/scheduleService.test.js
-const sequelize = require('../config/sequelize'); // �ㅼ젣 寃쎈줈�� 留욊쾶 �섏젙
+const sequelize = require('../config/sequelize'); 
 const { Schedule, User } = require('../models');
-const ScheduleService = require('../services/scheduleService'); // Uppercase 'S'濡� 媛��몄삤湲�
+const ScheduleService = require('../services/scheduleService'); 
 const ScheduleResponseDTO = require('../dtos/ScheduleResponseDTO');
 
 beforeAll(async () => {
-    // �뚯뒪�� �ㅼ쐞�멸� �쒖옉�섍린 �꾩뿉 �곗씠�곕쿋�댁뒪瑜� �숆린�뷀빀�덈떎.
     await sequelize.sync({ force: true });
 });
 
 beforeEach(async () => {
-    // 媛� �뚯뒪�멸� �쒖옉�섍린 �꾩뿉 湲곗〈 �곗씠�곕� ��젣�⑸땲��.
     await Schedule.destroy({ where: {} });
     await User.destroy({ where: {} });
 
-- 
GitLab


From 6e0ce3d02d604e018fd9a350f3e5abb728f61e9e Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Tue, 3 Dec 2024 02:51:51 +0900
Subject: [PATCH 06/61] =?UTF-8?q?refactor=20:=20=EC=BB=A8=ED=8A=B8?=
 =?UTF-8?q?=EB=A1=A4=EB=9F=AC=20=EB=B0=8F=20=EA=B8=B0=ED=83=80=20=EC=A3=BC?=
 =?UTF-8?q?=EC=84=9D=20=EC=A0=95=EB=A6=AC(#22)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 controllers/meetingController.js |  2 +-
 services/friendService.js        | 41 ++++++++++++++------------------
 2 files changed, 19 insertions(+), 24 deletions(-)

diff --git a/controllers/meetingController.js b/controllers/meetingController.js
index b6cc752..6624622 100644
--- a/controllers/meetingController.js
+++ b/controllers/meetingController.js
@@ -14,7 +14,7 @@ class MeetingController {
      *     "time_idx_start": 40, // ��: 10:00 AM
      *     "time_idx_end": 42,   // ��: 10:30 AM
      *     "location": "�뚯쓽�� A",
-     *     "deadline": "2024-04-25T23:59:59Z",
+     *     "deadline": "43",
      *     "type": "OPEN" // "OPEN" �먮뒗 "CLOSE"
      *      "max_num":
      * }
diff --git a/services/friendService.js b/services/friendService.js
index d35b3c7..4d61554 100644
--- a/services/friendService.js
+++ b/services/friendService.js
@@ -11,9 +11,7 @@ const FriendListDTO = require('../dtos/FriendListDTO');
 class FriendService {
     /**
      * User 議댁옱 �щ� �좏슚�� 寃���
-     * @param {number} userId - 寃��ы븷 �ъ슜�� ID
-     * @returns {Promise<User>} - �좏슚�� �ъ슜�� 媛앹껜
-     * @throws {Error} - �ъ슜�먭� 議댁옱�섏� �딆쓣 寃쎌슦
+     * userId - 寃��ы븷 �ъ슜�� ID
      */
     async validUser(userId) {
         const user = await User.findByPk(userId);
@@ -25,10 +23,9 @@ class FriendService {
 
     /**
      * 移쒓뎄 �붿껌 蹂대궡湲�
-     * @param {number} userId - 移쒓뎄 �붿껌�� 蹂대궡�� �ъ슜�� ID
-     * @param {number} friendId - 移쒓뎄 �붿껌�� 諛쏅뒗 �ъ슜�� ID
-     * @returns {Promise<FriendResponseDTO>} - �앹꽦�� 移쒓뎄 �붿껌 DTO
-     * @throws {Error} - �좏슚�섏� �딆� �붿껌�� 寃쎌슦
+     * userId - 移쒓뎄 �붿껌�� 蹂대궡�� �ъ슜�� ID
+     * friendId - 移쒓뎄 �붿껌�� 諛쏅뒗 �ъ슜�� ID
+     * returns - �앹꽦�� 移쒓뎄 �붿껌 DTO
      */
     async sendFriendRequest(userId, friendId) {
         await this.validUser(userId);
@@ -81,8 +78,8 @@ class FriendService {
 
     /**
      * 諛쏆� 移쒓뎄 �붿껌 紐⑸줉 議고쉶
-     * @param {number} userId - �붿껌�� 諛쏆� �ъ슜�� ID
-     * @returns {Promise<Array<FriendResponseDTO>>} - 諛쏆� 移쒓뎄 �붿껌 紐⑸줉 DTO 諛곗뿴
+      userId - �붿껌�� 諛쏆� �ъ슜�� ID
+     諛쏆� 移쒓뎄 �붿껌 紐⑸줉 DTO 諛곗뿴
      */
     async getReceivedRequests(userId) {
         const receivedRequests = await Friend.findAll({
@@ -101,8 +98,7 @@ class FriendService {
 
     /**
      * 蹂대궦 移쒓뎄 �붿껌 紐⑸줉 議고쉶
-     * @param {number} userId - �붿껌�� 蹂대궦 �ъ슜�� ID
-     * @returns {Promise<Array<FriendResponseDTO>>} - 蹂대궦 移쒓뎄 �붿껌 紐⑸줉 DTO 諛곗뿴
+     * userId - �붿껌�� 蹂대궦 �ъ슜�� ID
      */
     async getSentRequests(userId) {
         const sentRequests = await Friend.findAll({
@@ -163,10 +159,9 @@ class FriendService {
 
     /**
      * 移쒓뎄 �붿껌 嫄곗젅
-     * @param {number} userId - �붿껌�� 嫄곗젅�섎뒗 �ъ슜�� ID
-     * @param {number} friendId - 移쒓뎄 �붿껌�� 蹂대궦 �ъ슜�� ID
-     * @returns {Promise<number>} - ��젣�� 移쒓뎄 �붿껌 ��
-     * @throws {Error} - 移쒓뎄 �붿껌�� 議댁옱�섏� �딆쓣 寃쎌슦
+     *userId - �붿껌�� 嫄곗젅�섎뒗 �ъ슜�� ID
+     *  friendId - 移쒓뎄 �붿껌�� 蹂대궦 �ъ슜�� ID
+     * returns  - ��젣�� 移쒓뎄 �붿껌 ��
      */
     async rejectFriendRequest(userId, friendId) {
         const result = await Friend.destroy({
@@ -186,10 +181,10 @@ class FriendService {
 
     /**
      * 移쒓뎄 紐⑸줉 議고쉶
-     * @param {number} userId - 移쒓뎄 紐⑸줉�� 議고쉶�� �ъ슜�� ID
-     * @param {number} limit - �� �섏씠吏��� �쒖떆�� 移쒓뎄 ��
-     * @param {number} offset - �섏씠吏� �ㅽ봽��
-     * @returns {Promise<Array<FriendListDTO>>} - 移쒓뎄 紐⑸줉 DTO 諛곗뿴
+     userId - 移쒓뎄 紐⑸줉�� 議고쉶�� �ъ슜�� ID
+     limit - �� �섏씠吏��� �쒖떆�� 移쒓뎄 ��
+     offset - �섏씠吏� �ㅽ봽��
+     移쒓뎄 紐⑸줉 DTO 諛곗뿴
      */
     async getFriendList(userId, pagination) {
         const { limit = 20, offset = 0 } = pagination;
@@ -232,10 +227,10 @@ class FriendService {
 
     /**
      * 移쒓뎄 ��젣
-     * @param {number} userId - 移쒓뎄瑜� ��젣�섎뒗 �ъ슜�� ID
-     * @param {number} friendId - ��젣�� 移쒓뎄�� �ъ슜�� ID
-     * @returns {Promise<number>} - ��젣�� 移쒓뎄 愿�怨� ��
-     * @throws {Error} - 移쒓뎄 愿�怨꾧� 議댁옱�섏� �딆쓣 寃쎌슦
+     - 移쒓뎄瑜� ��젣�섎뒗 �ъ슜�� ID
+     - ��젣�� 移쒓뎄�� �ъ슜�� ID
+     - ��젣�� 移쒓뎄 愿�怨� ��
+     -移쒓뎄 愿�怨꾧� 議댁옱�섏� �딆쓣 寃쎌슦
      */
     async deleteFriend(userId, friendId) {
         const result = await Friend.destroy({
-- 
GitLab


From 177fc7540866e343a41add7c47ac095fe2b4e9e7 Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Tue, 3 Dec 2024 14:03:47 +0900
Subject: [PATCH 07/61] =?UTF-8?q?refactor:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?=
 =?UTF-8?q?=20=EB=A6=AC=EB=8B=A4=EC=9D=B4=EB=A0=89=ED=8A=B8=20url=20?=
 =?UTF-8?q?=ED=94=84=EB=A1=A0=ED=8A=B8=EB=A1=9C=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app.js                     |  2 +-
 middlewares/auth.js        | 11 ++++++-----
 passport/googleStrategy.js |  8 ++++----
 routes/auth.js             | 33 +++++++++++++++++++++++++--------
 4 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/app.js b/app.js
index 952e375..937f5c0 100644
--- a/app.js
+++ b/app.js
@@ -19,7 +19,7 @@ app.use(morgan('dev'));  //濡쒓퉭��
 // CORS �ㅼ젙
 app.use(
   cors({
-    origin: 'http://localhost:3000', 
+    origin: process.env.FRONTEND_URL, 
     methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
     allowedHeaders: ['Content-Type', 'Authorization'],
     credentials: true,
diff --git a/middlewares/auth.js b/middlewares/auth.js
index afc74ea..52eb397 100644
--- a/middlewares/auth.js
+++ b/middlewares/auth.js
@@ -1,15 +1,16 @@
 // middlewares/auth.js
-
-exports.isLoggedIn = (req, res, next) => { //濡쒓렇�몃맂 �ъ슜�먯옄留� �묎렐�덉슜
+exports.isLoggedIn = (req, res, next) => { // 濡쒓렇�몃맂 �ъ슜�먮쭔 �묎렐 �덉슜
   if (req.isAuthenticated()) {
     return next();
   }
-  res.redirect('/auth/login');
+  // 由щ떎�대젆�� ���� 401 Unauthorized �곹깭 諛섑솚
+  res.status(401).json({ error: '濡쒓렇�� �섏��딆� �ъ슜��' });
 };
 
-exports.isNotLoggedIn = (req, res, next) => { //濡쒓렇�� �덈릺硫� 由щ떎�대젆�� 
+exports.isNotLoggedIn = (req, res, next) => { // 濡쒓렇�� �덈맂 �ъ슜�먮쭔 �묎렐 �덉슜
   if (!req.isAuthenticated()) {
     return next();
   }
-  res.redirect('/');
+  // 由щ떎�대젆�� ���� 400 Bad Request �곹깭 諛섑솚 (�꾩슂�� �곕씪 蹂�寃� 媛���)
+  res.status(400).json({ error: '�대� 濡쒓렇�몃맂' });
 };
diff --git a/passport/googleStrategy.js b/passport/googleStrategy.js
index cd23c9d..ada1aef 100644
--- a/passport/googleStrategy.js
+++ b/passport/googleStrategy.js
@@ -1,15 +1,15 @@
 // passport/googleStrategy.js
-
 const { Strategy: GoogleStrategy } = require('passport-google-oauth20');
-const User = require('../models/user');
+const User = require('../models/user'); // �ъ슜�� 紐⑤뜽�� 媛��몄샃�덈떎.
 
 module.exports = new GoogleStrategy(
   {
     clientID: process.env.GOOGLE_CLIENT_ID,
     clientSecret: process.env.GOOGLE_CLIENT_SECRET,
     callbackURL: process.env.CALLBACK_URL,
+    passReqToCallback: true, // req 媛앹껜瑜� 肄쒕갚�� �꾨떖
   },
-  async (accessToken, refreshToken, profile, done) => {
+  async (req, accessToken, refreshToken, profile, done) => {
     try {
       // �꾨줈�꾩뿉�� �ъ슜�� �뺣낫 異붿텧
       const email = profile.emails[0].value;
@@ -23,7 +23,7 @@ module.exports = new GoogleStrategy(
 
       return done(null, user);
     } catch (err) {
-      return done(err);
+      return done(err, null);
     }
   }
 );
diff --git a/routes/auth.js b/routes/auth.js
index 7eda249..16247d5 100644
--- a/routes/auth.js
+++ b/routes/auth.js
@@ -1,5 +1,4 @@
 // routes/auth.js
-
 const express = require('express');
 const passport = require('passport');
 
@@ -12,23 +11,41 @@ router.get('/login', (req, res) => {
 
 // GET /auth/logout
 router.get('/logout', (req, res) => {
-  req.logout(() => {
-    res.redirect('/');
+  req.logout((err) => {
+    if (err) {
+      return res.status(500).json({ error: 'Failed to logout' });
+    }
+    res.redirect(process.env.FRONTEND_URL);
   });
 });
 
 // GET /auth/google
-router.get(
-  '/google',
-  passport.authenticate('google', { scope: ['profile', 'email'] })
-);
+router.get('/google', (req, res, next) => {
+  const redirectUrl = req.query.redirectUrl || process.env.FRONTEND_URL;
+
+  // 由щ떎�대젆�� URL 寃�利�
+  const allowedDomains = [process.env.FRONTEND_URL];
+  if (!allowedDomains.some((domain) => redirectUrl.startsWith(domain))) {
+    return res.status(400).json({ error: 'Invalid redirect URL' });
+  }
+
+  // �몄뀡�� redirectUrl ����
+  req.session.redirectUrl = redirectUrl;
+
+  passport.authenticate('google', { scope: ['profile', 'email'] })(req, res, next);
+});
 
 // GET /auth/google/callback
 router.get(
   '/google/callback',
   passport.authenticate('google', { failureRedirect: '/auth/login' }),
   (req, res) => {
-    res.redirect('/');
+    // �몄뀡�먯꽌 redirectUrl 媛��몄삤湲�
+    const redirectUrl = req.session.redirectUrl || process.env.FRONTEND_URL;
+
+    // �몄뀡�먯꽌 redirectUrl �쒓굅
+    req.session.redirectUrl = null;
+    res.redirect(redirectUrl);
   }
 );
 
-- 
GitLab


From e67e1bf4bb529c2f3bc266507844b0ab66cf615b Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Tue, 3 Dec 2024 15:12:34 +0900
Subject: [PATCH 08/61] =?UTF-8?q?refactor:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?=
 =?UTF-8?q?=20=EC=98=A4=EB=A5=98=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 routes/auth.js | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/routes/auth.js b/routes/auth.js
index 16247d5..6234891 100644
--- a/routes/auth.js
+++ b/routes/auth.js
@@ -1,4 +1,3 @@
-// routes/auth.js
 const express = require('express');
 const passport = require('passport');
 
@@ -15,17 +14,20 @@ router.get('/logout', (req, res) => {
     if (err) {
       return res.status(500).json({ error: 'Failed to logout' });
     }
-    res.redirect(process.env.FRONTEND_URL);
+    res.redirect(process.env.FRONTEND_URL || 'http://localhost:3000'); // 湲곕낯媛� �ㅼ젙
   });
 });
 
 // GET /auth/google
 router.get('/google', (req, res, next) => {
-  const redirectUrl = req.query.redirectUrl || process.env.FRONTEND_URL;
+  // 湲곕낯 redirectUrl �ㅼ젙
+  const redirectUrl = req.query.redirectUrl || process.env.FRONTEND_URL || 'http://localhost:3000';
 
-  // 由щ떎�대젆�� URL 寃�利�
-  const allowedDomains = [process.env.FRONTEND_URL];
-  if (!allowedDomains.some((domain) => redirectUrl.startsWith(domain))) {
+  // allowedDomains 諛곗뿴 �뺤씤 諛� 湲곕낯媛� �ㅼ젙
+  const allowedDomains = [process.env.FRONTEND_URL || 'http://localhost:3000'];
+
+  // redirectUrl 寃�利�
+  if (!allowedDomains.some((domain) => redirectUrl && redirectUrl.startsWith(domain))) {
     return res.status(400).json({ error: 'Invalid redirect URL' });
   }
 
@@ -41,10 +43,12 @@ router.get(
   passport.authenticate('google', { failureRedirect: '/auth/login' }),
   (req, res) => {
     // �몄뀡�먯꽌 redirectUrl 媛��몄삤湲�
-    const redirectUrl = req.session.redirectUrl || process.env.FRONTEND_URL;
+    const redirectUrl = req.session.redirectUrl || process.env.FRONTEND_URL || 'http://localhost:3000';
 
     // �몄뀡�먯꽌 redirectUrl �쒓굅
     req.session.redirectUrl = null;
+
+    // �꾨줎�몄뿏�쒕줈 由щ떎�대젆��
     res.redirect(redirectUrl);
   }
 );
-- 
GitLab


From 1e9d919264f1d44ab75316d22582d521929c5765 Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Tue, 3 Dec 2024 15:39:31 +0900
Subject: [PATCH 09/61] =?UTF-8?q?refactor:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?=
 =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 routes/auth.js | 30 +++++++-----------------------
 1 file changed, 7 insertions(+), 23 deletions(-)

diff --git a/routes/auth.js b/routes/auth.js
index 6234891..9e2c4c3 100644
--- a/routes/auth.js
+++ b/routes/auth.js
@@ -4,36 +4,20 @@ const passport = require('passport');
 const router = express.Router();
 
 // GET /auth/login
-router.get('/login', (req, res) => {
-  res.send('<a href="/auth/google">Log in with Google</a>');
-});
-
-// GET /auth/logout
-router.get('/logout', (req, res) => {
-  req.logout((err) => {
-    if (err) {
-      return res.status(500).json({ error: 'Failed to logout' });
-    }
-    res.redirect(process.env.FRONTEND_URL || 'http://localhost:3000'); // 湲곕낯媛� �ㅼ젙
-  });
-});
-
-// GET /auth/google
-router.get('/google', (req, res, next) => {
-  // 湲곕낯 redirectUrl �ㅼ젙
+router.get('/login', (req, res, next) => {
+  // �꾨줎�몄뿏�쒖뿉�� �꾨떖�� redirectUrl 媛��몄삤湲�
   const redirectUrl = req.query.redirectUrl || process.env.FRONTEND_URL || 'http://localhost:3000';
 
-  // allowedDomains 諛곗뿴 �뺤씤 諛� 湲곕낯媛� �ㅼ젙
+  // redirectUrl �좏슚�� 寃�利�
   const allowedDomains = [process.env.FRONTEND_URL || 'http://localhost:3000'];
-
-  // redirectUrl 寃�利�
-  if (!allowedDomains.some((domain) => redirectUrl && redirectUrl.startsWith(domain))) {
+  if (!allowedDomains.some((domain) => redirectUrl.startsWith(domain))) {
     return res.status(400).json({ error: 'Invalid redirect URL' });
   }
 
-  // �몄뀡�� redirectUrl ����
+  // redirectUrl �몄뀡�� ����
   req.session.redirectUrl = redirectUrl;
 
+  // Google OAuth �몄쬆 �쒖옉
   passport.authenticate('google', { scope: ['profile', 'email'] })(req, res, next);
 });
 
@@ -48,7 +32,7 @@ router.get(
     // �몄뀡�먯꽌 redirectUrl �쒓굅
     req.session.redirectUrl = null;
 
-    // �꾨줎�몄뿏�쒕줈 由щ떎�대젆��
+    // �몄쬆 �꾨즺 �� �꾨줎�몄뿏�쒕줈 由щ떎�대젆��
     res.redirect(redirectUrl);
   }
 );
-- 
GitLab


From 1912498b85cef16031f4d8348e3d8ac727f92150 Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Tue, 3 Dec 2024 21:47:57 +0900
Subject: [PATCH 10/61] =?UTF-8?q?=ED=94=84=EB=A1=A0=ED=8A=B8=EC=97=90?=
 =?UTF-8?q?=EC=84=9C=20=EC=83=9D=EA=B8=B0=EB=8A=94=20=EB=A1=9C=EA=B7=B8?=
 =?UTF-8?q?=EC=9D=B8=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app.js                          | 22 ++++++++++++++--------
 controllers/friendController.js |  2 +-
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/app.js b/app.js
index 937f5c0..b749726 100644
--- a/app.js
+++ b/app.js
@@ -25,21 +25,27 @@ app.use(
     credentials: true,
   })
 );
-
-
-// 誘몃뱾�⑥뼱 �ㅼ젙
-app.use(express.json());
-app.use(express.urlencoded({ extended: false }));
-
-// �몄뀡 �ㅼ젙
+// 
 app.use(
   session({
-    secret: 'your_session_secret', 
+    secret: 'your-secret-key',
     resave: false,
     saveUninitialized: false,
+    rolling: true,
+    cookie: {
+      httpOnly: true,
+      secure: false, 
+      maxAge: 60 * 60 * 1000, // 1�쒓컙
+      sameSite: 'lax', 
+    },
   })
 );
 
+
+// 誘몃뱾�⑥뼱 �ㅼ젙
+app.use(express.json());
+app.use(express.urlencoded({ extended: false }));
+
 // Passport 珥덇린�� 諛� �몄뀡 �곌껐
 app.use(passport.initialize());
 app.use(passport.session());
diff --git a/controllers/friendController.js b/controllers/friendController.js
index ce50caf..41b5cf9 100644
--- a/controllers/friendController.js
+++ b/controllers/friendController.js
@@ -4,7 +4,7 @@ const { User } = require('../models');
 class friendController {
         /**
          * 移쒓뎄 �붿껌 蹂대궡湲�
-         * �대씪�댁뼵�몃뒗 userId�� �붿껌�� 蹂대궪 �ъ슜�먯쓽 email�� �꾩넚
+         * �대씪�댁뼵�몃뒗 userId�� �붿껌�� 蹂대궪 �ъ슜�먯쓽 email�� body�먯쟾��
          */
         async sendFriendRequest(req, res, next) {
             const { userId, email } = req.body;
-- 
GitLab


From e55e7a77486ca7b7e665124a47a00ddb29627ab1 Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Tue, 3 Dec 2024 21:56:14 +0900
Subject: [PATCH 11/61] =?UTF-8?q?=ED=94=84=EB=A1=A0=ED=8A=B8=EC=97=90?=
 =?UTF-8?q?=EC=84=9C=20=EC=83=9D=EA=B8=B0=EB=8A=94=20=EB=A1=9C=EA=B7=B8?=
 =?UTF-8?q?=EC=9D=B8=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app.js                          | 22 ++++++++++++++--------
 controllers/friendController.js |  2 +-
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/app.js b/app.js
index 937f5c0..b749726 100644
--- a/app.js
+++ b/app.js
@@ -25,21 +25,27 @@ app.use(
     credentials: true,
   })
 );
-
-
-// 誘몃뱾�⑥뼱 �ㅼ젙
-app.use(express.json());
-app.use(express.urlencoded({ extended: false }));
-
-// �몄뀡 �ㅼ젙
+// 
 app.use(
   session({
-    secret: 'your_session_secret', 
+    secret: 'your-secret-key',
     resave: false,
     saveUninitialized: false,
+    rolling: true,
+    cookie: {
+      httpOnly: true,
+      secure: false, 
+      maxAge: 60 * 60 * 1000, // 1�쒓컙
+      sameSite: 'lax', 
+    },
   })
 );
 
+
+// 誘몃뱾�⑥뼱 �ㅼ젙
+app.use(express.json());
+app.use(express.urlencoded({ extended: false }));
+
 // Passport 珥덇린�� 諛� �몄뀡 �곌껐
 app.use(passport.initialize());
 app.use(passport.session());
diff --git a/controllers/friendController.js b/controllers/friendController.js
index ce50caf..41b5cf9 100644
--- a/controllers/friendController.js
+++ b/controllers/friendController.js
@@ -4,7 +4,7 @@ const { User } = require('../models');
 class friendController {
         /**
          * 移쒓뎄 �붿껌 蹂대궡湲�
-         * �대씪�댁뼵�몃뒗 userId�� �붿껌�� 蹂대궪 �ъ슜�먯쓽 email�� �꾩넚
+         * �대씪�댁뼵�몃뒗 userId�� �붿껌�� 蹂대궪 �ъ슜�먯쓽 email�� body�먯쟾��
          */
         async sendFriendRequest(req, res, next) {
             const { userId, email } = req.body;
-- 
GitLab


From 74a8b016876f46960972d00750920c95bd3f8e7b Mon Sep 17 00:00:00 2001
From: Ubuntu <ubuntu@ip-172-31-1-27.ap-northeast-2.compute.internal>
Date: Tue, 3 Dec 2024 13:22:59 +0000
Subject: [PATCH 12/61] =?UTF-8?q?refactor:=20=EB=B0=B0=ED=8F=AC=EC=BD=94?=
 =?UTF-8?q?=EB=93=9C=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .gitignore                                    |  1 +
 models/{Invite.js => invite.js}               |  0
 output.log                                    |  8 +++++
 ...9d-firebase-adminsdk-d1inm-24566bf0b9.json | 13 +++++++
 schemas/{ChatRooms.js => chatRooms.js}        |  0
 start.sh                                      | 34 +++++++++++++++++++
 weblog.log                                    | 22 ++++++++++++
 7 files changed, 78 insertions(+)
 rename models/{Invite.js => invite.js} (100%)
 create mode 100644 output.log
 create mode 100644 resources/firebase/yanawa-89d9d-firebase-adminsdk-d1inm-24566bf0b9.json
 rename schemas/{ChatRooms.js => chatRooms.js} (100%)
 create mode 100755 start.sh
 create mode 100644 weblog.log

diff --git a/.gitignore b/.gitignore
index 241c0f6..e8b5752 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
 node_modules/
 .env
 config.json/
+resources/
diff --git a/models/Invite.js b/models/invite.js
similarity index 100%
rename from models/Invite.js
rename to models/invite.js
diff --git a/output.log b/output.log
new file mode 100644
index 0000000..819b52d
--- /dev/null
+++ b/output.log
@@ -0,0 +1,8 @@
+MongoDB URI: mongodb+srv://admin:lim1234!!@goodmeeting.vkniz.mongodb.net/
+(node:44244) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(Use `node --trace-warnings ...` to show where the warning was created)
+(node:44244) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+�� MongoDB �곌껐 �깃났
+Rdb�곗씠�곕쿋�댁뒪 �곌껐 �깃났.
+紐⑤뱺 紐⑤뜽�� �깃났�곸쑝濡� �숆린�붾릺�덉뒿�덈떎.
+Server is running on 8080
diff --git a/resources/firebase/yanawa-89d9d-firebase-adminsdk-d1inm-24566bf0b9.json b/resources/firebase/yanawa-89d9d-firebase-adminsdk-d1inm-24566bf0b9.json
new file mode 100644
index 0000000..b397868
--- /dev/null
+++ b/resources/firebase/yanawa-89d9d-firebase-adminsdk-d1inm-24566bf0b9.json
@@ -0,0 +1,13 @@
+{
+  "type": "service_account",
+  "project_id": "yanawa-89d9d",
+  "private_key_id": "24566bf0b90cae5dfabe6d1f4994f17d57a816a6",
+  "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCht11GDE9ixnOC\nVLgohfV53E6f4DxuOfaQ88ZIEo7gCgwI36XweE7swyLA3KLYGPEb5b6bmzPPZvcA\n+bTAGfcm+h8a94EqcKc+IrXvr2nQSj5A9RNvWAW7YcEMU/r/a43QXYG9zHczIvYr\nd/ay0uadJzAn5uMGgQsGSYwv+lgi3JjEkTQDhcUJIH94FjVBlgjSG0YSlgJ57mAJ\npt2kr1sjPeVAY4nmP+tHds9aufYjljC6ANVBHjRv2lC+deLIJYnzMy9RGQYB3rXO\nW/pPvp5MK2bHfxscvlPRs6xRCIhqkS7fO44xyW8yDo1ND5guQHjKqW/X+7n5yQ48\n3/9kfFjZAgMBAAECggEADbS/TIkNj2cXciPhCdo0sHPaHBXCuWrjOWzX0NL11goz\n8+qUo1lnAw0U3Hi2uo7+nGkv6vtP/FOTOrtvNNrehiiryzrP8TtkCVGizuI0myk3\ntoSu9YBl1/hUhsl1XAGPHupV7TKvpZ9gctWzjHtwfUBNhgw9EJeOSiWgoo5auvWJ\nwg5j9cDjAEJKKrTUsPIeE1v0RXXwYmSkoAP87NOF/vQxFJhhiKDszxRK/YU+ZtJc\nWKLOmmxB6pNnYpmEd05yUWw2WJ/JOsbtKFF7w/MYT1yaJ3spmblM01t+GvOc+Hda\noxxNA4pK58d654xg6co7oOfKgSkEHQLzS9Gii2SoAwKBgQDelr7UssQhcOVMGji9\n8VQIk5fnISLznR8BuKupDuW1zhKm75vbgHrwDDjN8hE9W0YhmQgKuj4dfWS2TqyA\nFgvV3PI/RJ/ZRJX4isC25l2VmzyNfjCqkLpNzLExMMaYB3OxTXFxgrEM7xb2vwJe\n7QYGoF88DjHvGBCc08F6gCCGJwKBgQC5/YOPT21I7m1HjcBdoRs3Xg8+hg2OAZCG\ni2TAW5pd8TeAXtylS2iZbk3Jpmg/ShwQMGGnsjpuVs2K28bwlosZX3y/nfJHmzG+\neWK1ZGhrUrVl/dJLui2dyFebzjWjC+xgz84GG5jb1yXUZ5nAArPBXMLAaEN0R5jE\nDvMiAd6I/wKBgENJKGidnYJKYVYu+wYYBIIPM7UPpEQmM/BORb32HeRmZecGuYOS\nBBe6ahV/XkzA4aNYYkDz6cD6Xc5qW+TgRTWh86zCbtu7yuX186mWW6XU5moTQlzd\nISRRgyLOjsn4PrXTJj7c9e5l+/gc53eQiOjJ4+AAnoGbMbJmpK8GOk6zAoGAN1tf\nNt5bFqPwXqWwJa333cjfHKrlieipTYJboG0jSuaqsEiLv57sKQ6NlIE08fFq3N6p\nkjIX9hNb5gJ3+c+04v5qsNWf8PQeICUc3gRel+LsHsknOGbXgOjKOpNrn3XDCyWO\nmn7IRlaI6elT97RWMC0dwgrGWOueamxQrUSFKZ0CgYEAzg0NYIl1PaygbqDY/F+K\ngOSIA/PblcQOTwdZE9TtTotjeqFrOYjIEjUVMNJaWAUXFmkHwjGNL+y3nwHokWpN\n0igbTAxxl6uHG24SJsIPG6GlvVgOWvHjQ2n10iXPJNOz4NsBVC+F1Wh7WU+2dhVH\nN0uplgmlvAItjFmCZK66pjc=\n-----END PRIVATE KEY-----\n",
+  "client_email": "firebase-adminsdk-d1inm@yanawa-89d9d.iam.gserviceaccount.com",
+  "client_id": "116723201622055361661",
+  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
+  "token_uri": "https://oauth2.googleapis.com/token",
+  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
+  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-d1inm%40yanawa-89d9d.iam.gserviceaccount.com",
+  "universe_domain": "googleapis.com"
+}
diff --git a/schemas/ChatRooms.js b/schemas/chatRooms.js
similarity index 100%
rename from schemas/ChatRooms.js
rename to schemas/chatRooms.js
diff --git a/start.sh b/start.sh
new file mode 100755
index 0000000..00e9bb6
--- /dev/null
+++ b/start.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+# Define application file names
+APP_JS="app.js"
+WS_SERVER_JS="wsServer.js"
+
+# Find and kill processes for app.js
+APP_PID=$(pgrep -f "node .*${APP_JS}")
+if [ -n "$APP_PID" ]; then
+  echo "Stopping ${APP_JS} with PID: $APP_PID"
+  kill -9 "$APP_PID"
+else
+  echo "No running process found for ${APP_JS}"
+fi
+
+# Find and kill processes for wsServer.js
+WS_SERVER_PID=$(pgrep -f "node .*${WS_SERVER_JS}")
+if [ -n "$WS_SERVER_PID" ]; then
+  echo "Stopping ${WS_SERVER_JS} with PID: $WS_SERVER_PID"
+  kill -9 "$WS_SERVER_PID"
+else
+  echo "No running process found for ${WS_SERVER_JS}"
+fi
+
+# Start app.js with nohup
+echo "Starting ${APP_JS}..."
+nohup node "${APP_JS}" > output.log 2>&1 &
+echo "${APP_JS} started with PID: $!"
+
+# Start wsServer.js with nohup
+echo "Starting ${WS_SERVER_JS}..."
+nohup node "${WS_SERVER_JS}" > weblog.log 2>&1 &
+echo "${WS_SERVER_JS} started with PID: $!"
+
diff --git a/weblog.log b/weblog.log
new file mode 100644
index 0000000..2ac6636
--- /dev/null
+++ b/weblog.log
@@ -0,0 +1,22 @@
+node:internal/modules/cjs/loader:1143
+  throw err;
+  ^
+
+Error: Cannot find module './resources/firebase/yanawa-89d9d-firebase-adminsdk-d1inm-24566bf0b9.json'
+Require stack:
+- /home/ubuntu/webback/wsServer.js
+    at Module._resolveFilename (node:internal/modules/cjs/loader:1140:15)
+    at Module._load (node:internal/modules/cjs/loader:981:27)
+    at Module.require (node:internal/modules/cjs/loader:1231:19)
+    at require (node:internal/modules/helpers:177:18)
+    at Object.<anonymous> (/home/ubuntu/webback/wsServer.js:18:37)
+    at Module._compile (node:internal/modules/cjs/loader:1364:14)
+    at Module._extensions..js (node:internal/modules/cjs/loader:1422:10)
+    at Module.load (node:internal/modules/cjs/loader:1203:32)
+    at Module._load (node:internal/modules/cjs/loader:1019:12)
+    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:128:12) {
+  code: 'MODULE_NOT_FOUND',
+  requireStack: [ '/home/ubuntu/webback/wsServer.js' ]
+}
+
+Node.js v18.20.5
-- 
GitLab


From f75ebb14f06f1578c9f6d40204f3eaf6d633e31a Mon Sep 17 00:00:00 2001
From: Ubuntu <ubuntu@ip-172-31-1-27.ap-northeast-2.compute.internal>
Date: Tue, 3 Dec 2024 13:24:53 +0000
Subject: [PATCH 13/61] =?UTF-8?q?refactor:=20=EB=B0=B0=ED=8F=AC=EC=BD=94?=
 =?UTF-8?q?=EB=93=9C=20=EC=98=A4=EB=A5=98=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ...wa-89d9d-firebase-adminsdk-d1inm-24566bf0b9.json | 13 -------------
 1 file changed, 13 deletions(-)
 delete mode 100644 resources/firebase/yanawa-89d9d-firebase-adminsdk-d1inm-24566bf0b9.json

diff --git a/resources/firebase/yanawa-89d9d-firebase-adminsdk-d1inm-24566bf0b9.json b/resources/firebase/yanawa-89d9d-firebase-adminsdk-d1inm-24566bf0b9.json
deleted file mode 100644
index b397868..0000000
--- a/resources/firebase/yanawa-89d9d-firebase-adminsdk-d1inm-24566bf0b9.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-  "type": "service_account",
-  "project_id": "yanawa-89d9d",
-  "private_key_id": "24566bf0b90cae5dfabe6d1f4994f17d57a816a6",
-  "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCht11GDE9ixnOC\nVLgohfV53E6f4DxuOfaQ88ZIEo7gCgwI36XweE7swyLA3KLYGPEb5b6bmzPPZvcA\n+bTAGfcm+h8a94EqcKc+IrXvr2nQSj5A9RNvWAW7YcEMU/r/a43QXYG9zHczIvYr\nd/ay0uadJzAn5uMGgQsGSYwv+lgi3JjEkTQDhcUJIH94FjVBlgjSG0YSlgJ57mAJ\npt2kr1sjPeVAY4nmP+tHds9aufYjljC6ANVBHjRv2lC+deLIJYnzMy9RGQYB3rXO\nW/pPvp5MK2bHfxscvlPRs6xRCIhqkS7fO44xyW8yDo1ND5guQHjKqW/X+7n5yQ48\n3/9kfFjZAgMBAAECggEADbS/TIkNj2cXciPhCdo0sHPaHBXCuWrjOWzX0NL11goz\n8+qUo1lnAw0U3Hi2uo7+nGkv6vtP/FOTOrtvNNrehiiryzrP8TtkCVGizuI0myk3\ntoSu9YBl1/hUhsl1XAGPHupV7TKvpZ9gctWzjHtwfUBNhgw9EJeOSiWgoo5auvWJ\nwg5j9cDjAEJKKrTUsPIeE1v0RXXwYmSkoAP87NOF/vQxFJhhiKDszxRK/YU+ZtJc\nWKLOmmxB6pNnYpmEd05yUWw2WJ/JOsbtKFF7w/MYT1yaJ3spmblM01t+GvOc+Hda\noxxNA4pK58d654xg6co7oOfKgSkEHQLzS9Gii2SoAwKBgQDelr7UssQhcOVMGji9\n8VQIk5fnISLznR8BuKupDuW1zhKm75vbgHrwDDjN8hE9W0YhmQgKuj4dfWS2TqyA\nFgvV3PI/RJ/ZRJX4isC25l2VmzyNfjCqkLpNzLExMMaYB3OxTXFxgrEM7xb2vwJe\n7QYGoF88DjHvGBCc08F6gCCGJwKBgQC5/YOPT21I7m1HjcBdoRs3Xg8+hg2OAZCG\ni2TAW5pd8TeAXtylS2iZbk3Jpmg/ShwQMGGnsjpuVs2K28bwlosZX3y/nfJHmzG+\neWK1ZGhrUrVl/dJLui2dyFebzjWjC+xgz84GG5jb1yXUZ5nAArPBXMLAaEN0R5jE\nDvMiAd6I/wKBgENJKGidnYJKYVYu+wYYBIIPM7UPpEQmM/BORb32HeRmZecGuYOS\nBBe6ahV/XkzA4aNYYkDz6cD6Xc5qW+TgRTWh86zCbtu7yuX186mWW6XU5moTQlzd\nISRRgyLOjsn4PrXTJj7c9e5l+/gc53eQiOjJ4+AAnoGbMbJmpK8GOk6zAoGAN1tf\nNt5bFqPwXqWwJa333cjfHKrlieipTYJboG0jSuaqsEiLv57sKQ6NlIE08fFq3N6p\nkjIX9hNb5gJ3+c+04v5qsNWf8PQeICUc3gRel+LsHsknOGbXgOjKOpNrn3XDCyWO\nmn7IRlaI6elT97RWMC0dwgrGWOueamxQrUSFKZ0CgYEAzg0NYIl1PaygbqDY/F+K\ngOSIA/PblcQOTwdZE9TtTotjeqFrOYjIEjUVMNJaWAUXFmkHwjGNL+y3nwHokWpN\n0igbTAxxl6uHG24SJsIPG6GlvVgOWvHjQ2n10iXPJNOz4NsBVC+F1Wh7WU+2dhVH\nN0uplgmlvAItjFmCZK66pjc=\n-----END PRIVATE KEY-----\n",
-  "client_email": "firebase-adminsdk-d1inm@yanawa-89d9d.iam.gserviceaccount.com",
-  "client_id": "116723201622055361661",
-  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
-  "token_uri": "https://oauth2.googleapis.com/token",
-  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
-  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-d1inm%40yanawa-89d9d.iam.gserviceaccount.com",
-  "universe_domain": "googleapis.com"
-}
-- 
GitLab


From 4341f8d2c6355b6b778fb408cecb025d1b8c52e0 Mon Sep 17 00:00:00 2001
From: Ubuntu <ubuntu@ip-172-31-1-27.ap-northeast-2.compute.internal>
Date: Wed, 4 Dec 2024 05:38:10 +0000
Subject: [PATCH 14/61] =?UTF-8?q?refactor:=20=EB=8F=84=EB=A9=94=EC=9D=B8?=
 =?UTF-8?q?=EC=A0=81=EC=9A=A9=ED=95=9C=20=EC=84=B8=EC=85=98=EB=A1=9C?=
 =?UTF-8?q?=EA=B7=B8=EC=9D=B8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app.js         | 41 ++++++++++++++++++++++++++++++-----------
 output.log     | 19 +++++++++++++++++--
 routes/auth.js |  2 +-
 weblog.log     | 42 +++++++++++++++++++++---------------------
 4 files changed, 69 insertions(+), 35 deletions(-)

diff --git a/app.js b/app.js
index b749726..8fb70a5 100644
--- a/app.js
+++ b/app.js
@@ -17,14 +17,33 @@ const app = express();
 
 app.use(morgan('dev'));  //濡쒓퉭��
 // CORS �ㅼ젙
-app.use(
-  cors({
-    origin: process.env.FRONTEND_URL, 
-    methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
-    allowedHeaders: ['Content-Type', 'Authorization'],
-    credentials: true,
-  })
-);
+
+const corsOptions = {
+  origin: (origin, callback) => {
+    console.log('CORS Origin:', origin); // �붾쾭源낆슜 濡쒓렇
+    const allowedOrigins = [
+      'http://localhost:3000', // 濡쒖뺄 媛쒕컻 �섍꼍
+      'http://ec2-43-203-68-83.ap-northeast-2.compute.amazonaws.com', // EC2 諛깆뿏��
+    ];
+    if (!origin) return callback(null, true); // origin�� �놁쑝硫� �덉슜 (e.g., Postman)
+    if (allowedOrigins.includes(origin)) {
+      return callback(null, true);
+    }
+    console.log('CORS origin rejected:', origin); // 李⑤떒�� origin 濡쒓렇
+    return callback(new Error('Not allowed by CORS'));
+  },
+  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
+  allowedHeaders: ['Content-Type', 'Authorization'],
+  credentials: true, // 荑좏궎 �덉슜
+};
+
+// CORS 誘몃뱾�⑥뼱 �곸슜
+app.use(cors(corsOptions));
+
+// Preflight �붿껌 泥섎━
+app.options('*', cors(corsOptions));
+
+
 // 
 app.use(
   session({
@@ -36,7 +55,7 @@ app.use(
       httpOnly: true,
       secure: false, 
       maxAge: 60 * 60 * 1000, // 1�쒓컙
-      sameSite: 'lax', 
+      sameSite: 'raw', 
     },
   })
 );
@@ -55,7 +74,7 @@ app.use(flash());
 console.log('MongoDB URI:', process.env.MONGO_URI);
 //�쇱슦�� �깅줉 
 const authRoutes = require('./routes/auth');
-app.use('/auth', authRoutes);
+app.use('/api/auth',authRoutes);
 
 const scheduleRoutes = require('./routes/schedule');
 app.use('/api/schedule', scheduleRoutes);
@@ -92,4 +111,4 @@ const PORT = process.env.PORT || 3000;
     console.error('�� �쒕쾭 �쒖옉 以� �ㅻ쪟 諛쒖깮:', error);
     process.exit(1);
   }
-})();
\ No newline at end of file
+})();
diff --git a/output.log b/output.log
index 819b52d..18efc16 100644
--- a/output.log
+++ b/output.log
@@ -1,8 +1,23 @@
 MongoDB URI: mongodb+srv://admin:lim1234!!@goodmeeting.vkniz.mongodb.net/
-(node:44244) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:4343) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 (Use `node --trace-warnings ...` to show where the warning was created)
-(node:44244) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:4343) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 �� MongoDB �곌껐 �깃났
 Rdb�곗씠�곕쿋�댁뒪 �곌껐 �깃났.
 紐⑤뱺 紐⑤뜽�� �깃났�곸쑝濡� �숆린�붾릺�덉뒿�덈떎.
 Server is running on 8080
+CORS Origin: undefined
+GET /api/auth/login 302 7.657 ms - 0
+TypeError: option sameSite is invalid
+    at Object.serialize (/home/ubuntu/webback/node_modules/express-session/node_modules/cookie/index.js:290:15)
+    at setcookie (/home/ubuntu/webback/node_modules/express-session/index.js:665:21)
+    at ServerResponse.<anonymous> (/home/ubuntu/webback/node_modules/express-session/index.js:248:9)
+    at ServerResponse.writeHead (/home/ubuntu/webback/node_modules/on-headers/index.js:35:16)
+    at ServerResponse._implicitHeader (node:_http_server:338:8)
+    at writetop (/home/ubuntu/webback/node_modules/express-session/index.js:284:15)
+    at ServerResponse.end (/home/ubuntu/webback/node_modules/express-session/index.js:351:16)
+    at strategy.redirect (/home/ubuntu/webback/node_modules/passport/lib/middleware/authenticate.js:342:13)
+    at stored (/home/ubuntu/webback/node_modules/passport-oauth2/lib/strategy.js:285:14)
+    at NullStore.store (/home/ubuntu/webback/node_modules/passport-oauth2/lib/state/null.js:5:3)
+CORS Origin: undefined
+GET /api/schedule/all 401 3.524 ms - 44
diff --git a/routes/auth.js b/routes/auth.js
index 9e2c4c3..fcf2d3e 100644
--- a/routes/auth.js
+++ b/routes/auth.js
@@ -3,7 +3,7 @@ const passport = require('passport');
 
 const router = express.Router();
 
-// GET /auth/login
+// GET api/auth/login
 router.get('/login', (req, res, next) => {
   // �꾨줎�몄뿏�쒖뿉�� �꾨떖�� redirectUrl 媛��몄삤湲�
   const redirectUrl = req.query.redirectUrl || process.env.FRONTEND_URL || 'http://localhost:3000';
diff --git a/weblog.log b/weblog.log
index 2ac6636..38198c5 100644
--- a/weblog.log
+++ b/weblog.log
@@ -1,22 +1,22 @@
-node:internal/modules/cjs/loader:1143
-  throw err;
-  ^
-
-Error: Cannot find module './resources/firebase/yanawa-89d9d-firebase-adminsdk-d1inm-24566bf0b9.json'
-Require stack:
-- /home/ubuntu/webback/wsServer.js
-    at Module._resolveFilename (node:internal/modules/cjs/loader:1140:15)
-    at Module._load (node:internal/modules/cjs/loader:981:27)
-    at Module.require (node:internal/modules/cjs/loader:1231:19)
-    at require (node:internal/modules/helpers:177:18)
-    at Object.<anonymous> (/home/ubuntu/webback/wsServer.js:18:37)
-    at Module._compile (node:internal/modules/cjs/loader:1364:14)
-    at Module._extensions..js (node:internal/modules/cjs/loader:1422:10)
-    at Module.load (node:internal/modules/cjs/loader:1203:32)
-    at Module._load (node:internal/modules/cjs/loader:1019:12)
-    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:128:12) {
-  code: 'MODULE_NOT_FOUND',
-  requireStack: [ '/home/ubuntu/webback/wsServer.js' ]
+(node:4344) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(Use `node --trace-warnings ...` to show where the warning was created)
+(node:4344) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+MongoDB �곌껐 �ㅽ뙣: MongooseServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017
+    at _handleConnectionErrors (/home/ubuntu/webback/node_modules/mongoose/lib/connection.js:909:11)
+    at NativeConnection.openUri (/home/ubuntu/webback/node_modules/mongoose/lib/connection.js:860:11)
+    at async connectMongoDB (/home/ubuntu/webback/wsServer.js:28:5) {
+  reason: TopologyDescription {
+    type: 'Unknown',
+    servers: Map(1) { 'localhost:27017' => [ServerDescription] },
+    stale: false,
+    compatible: true,
+    heartbeatFrequencyMS: 10000,
+    localThresholdMS: 15,
+    setName: null,
+    maxElectionId: null,
+    maxSetVersion: null,
+    commonWireVersion: 0,
+    logicalSessionTimeoutMinutes: null
+  },
+  code: undefined
 }
-
-Node.js v18.20.5
-- 
GitLab


From 8a447bbda9408405c5c20cb645363daa8a3bc670 Mon Sep 17 00:00:00 2001
From: Ubuntu <ubuntu@ip-172-31-1-27.ap-northeast-2.compute.internal>
Date: Wed, 4 Dec 2024 05:41:29 +0000
Subject: [PATCH 15/61] =?UTF-8?q?refactor:=20=EB=8F=84=EB=A9=94=EC=9D=B8?=
 =?UTF-8?q?=EC=A0=81=EC=9A=A9=ED=95=9C=20=EC=84=B8=EC=85=98=EB=A1=9C?=
 =?UTF-8?q?=EA=B7=B8=EC=9D=B8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app.js     |  4 ++--
 output.log | 21 ++++++---------------
 weblog.log |  4 ++--
 3 files changed, 10 insertions(+), 19 deletions(-)

diff --git a/app.js b/app.js
index 8fb70a5..04fcb77 100644
--- a/app.js
+++ b/app.js
@@ -53,9 +53,9 @@ app.use(
     rolling: true,
     cookie: {
       httpOnly: true,
-      secure: false, 
+      secure: true, 
       maxAge: 60 * 60 * 1000, // 1�쒓컙
-      sameSite: 'raw', 
+      sameSite: 'none', 
     },
   })
 );
diff --git a/output.log b/output.log
index 18efc16..14b3255 100644
--- a/output.log
+++ b/output.log
@@ -1,23 +1,14 @@
 MongoDB URI: mongodb+srv://admin:lim1234!!@goodmeeting.vkniz.mongodb.net/
-(node:4343) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:4550) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 (Use `node --trace-warnings ...` to show where the warning was created)
-(node:4343) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:4550) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 �� MongoDB �곌껐 �깃났
 Rdb�곗씠�곕쿋�댁뒪 �곌껐 �깃났.
 紐⑤뱺 紐⑤뜽�� �깃났�곸쑝濡� �숆린�붾릺�덉뒿�덈떎.
 Server is running on 8080
 CORS Origin: undefined
-GET /api/auth/login 302 7.657 ms - 0
-TypeError: option sameSite is invalid
-    at Object.serialize (/home/ubuntu/webback/node_modules/express-session/node_modules/cookie/index.js:290:15)
-    at setcookie (/home/ubuntu/webback/node_modules/express-session/index.js:665:21)
-    at ServerResponse.<anonymous> (/home/ubuntu/webback/node_modules/express-session/index.js:248:9)
-    at ServerResponse.writeHead (/home/ubuntu/webback/node_modules/on-headers/index.js:35:16)
-    at ServerResponse._implicitHeader (node:_http_server:338:8)
-    at writetop (/home/ubuntu/webback/node_modules/express-session/index.js:284:15)
-    at ServerResponse.end (/home/ubuntu/webback/node_modules/express-session/index.js:351:16)
-    at strategy.redirect (/home/ubuntu/webback/node_modules/passport/lib/middleware/authenticate.js:342:13)
-    at stored (/home/ubuntu/webback/node_modules/passport-oauth2/lib/strategy.js:285:14)
-    at NullStore.store (/home/ubuntu/webback/node_modules/passport-oauth2/lib/state/null.js:5:3)
+GET /api/auth/login 302 7.628 ms - 0
 CORS Origin: undefined
-GET /api/schedule/all 401 3.524 ms - 44
+GET /api/schedule/all 401 3.639 ms - 44
+CORS Origin: undefined
+GET /api/schedule/all 401 1.347 ms - 44
diff --git a/weblog.log b/weblog.log
index 38198c5..20d8173 100644
--- a/weblog.log
+++ b/weblog.log
@@ -1,6 +1,6 @@
-(node:4344) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:4551) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 (Use `node --trace-warnings ...` to show where the warning was created)
-(node:4344) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:4551) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 MongoDB �곌껐 �ㅽ뙣: MongooseServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017
     at _handleConnectionErrors (/home/ubuntu/webback/node_modules/mongoose/lib/connection.js:909:11)
     at NativeConnection.openUri (/home/ubuntu/webback/node_modules/mongoose/lib/connection.js:860:11)
-- 
GitLab


From 1b9c733671c20f70ecbedf99aff6bb3e91d46be0 Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Wed, 4 Dec 2024 14:46:39 +0900
Subject: [PATCH 16/61] =?UTF-8?q?jwt=EA=B8=B0=EB=B0=98=20=EB=A1=9C?=
 =?UTF-8?q?=EA=B7=B8=EC=9D=B8=EC=9D=B8=EC=A6=9D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app.js | 39 ++++++++++-----------------------------
 1 file changed, 10 insertions(+), 29 deletions(-)

diff --git a/app.js b/app.js
index 04fcb77..bf2bd1d 100644
--- a/app.js
+++ b/app.js
@@ -17,33 +17,14 @@ const app = express();
 
 app.use(morgan('dev'));  //濡쒓퉭��
 // CORS �ㅼ젙
-
-const corsOptions = {
-  origin: (origin, callback) => {
-    console.log('CORS Origin:', origin); // �붾쾭源낆슜 濡쒓렇
-    const allowedOrigins = [
-      'http://localhost:3000', // 濡쒖뺄 媛쒕컻 �섍꼍
-      'http://ec2-43-203-68-83.ap-northeast-2.compute.amazonaws.com', // EC2 諛깆뿏��
-    ];
-    if (!origin) return callback(null, true); // origin�� �놁쑝硫� �덉슜 (e.g., Postman)
-    if (allowedOrigins.includes(origin)) {
-      return callback(null, true);
-    }
-    console.log('CORS origin rejected:', origin); // 李⑤떒�� origin 濡쒓렇
-    return callback(new Error('Not allowed by CORS'));
-  },
-  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
-  allowedHeaders: ['Content-Type', 'Authorization'],
-  credentials: true, // 荑좏궎 �덉슜
-};
-
-// CORS 誘몃뱾�⑥뼱 �곸슜
-app.use(cors(corsOptions));
-
-// Preflight �붿껌 泥섎━
-app.options('*', cors(corsOptions));
-
-
+app.use(
+  cors({
+    origin: process.env.FRONTEND_URL, 
+    methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
+    allowedHeaders: ['Content-Type', 'Authorization'],
+    credentials: true,
+  })
+);
 // 
 app.use(
   session({
@@ -74,7 +55,7 @@ app.use(flash());
 console.log('MongoDB URI:', process.env.MONGO_URI);
 //�쇱슦�� �깅줉 
 const authRoutes = require('./routes/auth');
-app.use('/api/auth',authRoutes);
+app.use('/auth', authRoutes);
 
 const scheduleRoutes = require('./routes/schedule');
 app.use('/api/schedule', scheduleRoutes);
@@ -111,4 +92,4 @@ const PORT = process.env.PORT || 3000;
     console.error('�� �쒕쾭 �쒖옉 以� �ㅻ쪟 諛쒖깮:', error);
     process.exit(1);
   }
-})();
+})();
\ No newline at end of file
-- 
GitLab


From 813eb395d9f2bd7b9a95c2ea3fe5ddf1a6e9d7cc Mon Sep 17 00:00:00 2001
From: Ubuntu <ubuntu@ip-172-31-1-27.ap-northeast-2.compute.internal>
Date: Wed, 4 Dec 2024 08:21:38 +0000
Subject: [PATCH 17/61] =?UTF-8?q?refactor:=20=ED=94=84=EB=A1=9D=EC=8B=9C?=
 =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EB=B0=8F=20https=20=EC=BF=A0=ED=82=A4?=
 =?UTF-8?q?=EC=84=A4=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app.js                     | 38 ++++++++++++--------------------------
 output.log                 | 10 ++--------
 passport/googleStrategy.js |  1 -
 routes/auth.js             | 26 ++++++++++++--------------
 weblog.log                 |  4 ++--
 5 files changed, 28 insertions(+), 51 deletions(-)

diff --git a/app.js b/app.js
index 04fcb77..4156dea 100644
--- a/app.js
+++ b/app.js
@@ -18,32 +18,16 @@ const app = express();
 app.use(morgan('dev'));  //濡쒓퉭��
 // CORS �ㅼ젙
 
-const corsOptions = {
-  origin: (origin, callback) => {
-    console.log('CORS Origin:', origin); // �붾쾭源낆슜 濡쒓렇
-    const allowedOrigins = [
-      'http://localhost:3000', // 濡쒖뺄 媛쒕컻 �섍꼍
-      'http://ec2-43-203-68-83.ap-northeast-2.compute.amazonaws.com', // EC2 諛깆뿏��
-    ];
-    if (!origin) return callback(null, true); // origin�� �놁쑝硫� �덉슜 (e.g., Postman)
-    if (allowedOrigins.includes(origin)) {
-      return callback(null, true);
-    }
-    console.log('CORS origin rejected:', origin); // 李⑤떒�� origin 濡쒓렇
-    return callback(new Error('Not allowed by CORS'));
-  },
-  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
-  allowedHeaders: ['Content-Type', 'Authorization'],
-  credentials: true, // 荑좏궎 �덉슜
-};
-
-// CORS 誘몃뱾�⑥뼱 �곸슜
-app.use(cors(corsOptions));
-
-// Preflight �붿껌 泥섎━
-app.options('*', cors(corsOptions));
-
 
+// CORS �ㅼ젙
+app.use(
+  cors({
+    origin: 'https://yanawa.shop',
+    methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
+    allowedHeaders: ['Content-Type', 'Authorization'],
+    credentials: true,
+  })
+);
 // 
 app.use(
   session({
@@ -60,7 +44,6 @@ app.use(
   })
 );
 
-
 // 誘몃뱾�⑥뼱 �ㅼ젙
 app.use(express.json());
 app.use(express.urlencoded({ extended: false }));
@@ -71,6 +54,9 @@ app.use(passport.session());
 
 
 app.use(flash());
+
+
+app.set('trust proxy', 1);
 console.log('MongoDB URI:', process.env.MONGO_URI);
 //�쇱슦�� �깅줉 
 const authRoutes = require('./routes/auth');
diff --git a/output.log b/output.log
index 14b3255..15aceb8 100644
--- a/output.log
+++ b/output.log
@@ -1,14 +1,8 @@
 MongoDB URI: mongodb+srv://admin:lim1234!!@goodmeeting.vkniz.mongodb.net/
-(node:4550) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:8604) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 (Use `node --trace-warnings ...` to show where the warning was created)
-(node:4550) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:8604) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 �� MongoDB �곌껐 �깃났
 Rdb�곗씠�곕쿋�댁뒪 �곌껐 �깃났.
 紐⑤뱺 紐⑤뜽�� �깃났�곸쑝濡� �숆린�붾릺�덉뒿�덈떎.
 Server is running on 8080
-CORS Origin: undefined
-GET /api/auth/login 302 7.628 ms - 0
-CORS Origin: undefined
-GET /api/schedule/all 401 3.639 ms - 44
-CORS Origin: undefined
-GET /api/schedule/all 401 1.347 ms - 44
diff --git a/passport/googleStrategy.js b/passport/googleStrategy.js
index ada1aef..6926dee 100644
--- a/passport/googleStrategy.js
+++ b/passport/googleStrategy.js
@@ -7,7 +7,6 @@ module.exports = new GoogleStrategy(
     clientID: process.env.GOOGLE_CLIENT_ID,
     clientSecret: process.env.GOOGLE_CLIENT_SECRET,
     callbackURL: process.env.CALLBACK_URL,
-    passReqToCallback: true, // req 媛앹껜瑜� 肄쒕갚�� �꾨떖
   },
   async (req, accessToken, refreshToken, profile, done) => {
     try {
diff --git a/routes/auth.js b/routes/auth.js
index fcf2d3e..576d376 100644
--- a/routes/auth.js
+++ b/routes/auth.js
@@ -6,13 +6,8 @@ const router = express.Router();
 // GET api/auth/login
 router.get('/login', (req, res, next) => {
   // �꾨줎�몄뿏�쒖뿉�� �꾨떖�� redirectUrl 媛��몄삤湲�
-  const redirectUrl = req.query.redirectUrl || process.env.FRONTEND_URL || 'http://localhost:3000';
-
-  // redirectUrl �좏슚�� 寃�利�
-  const allowedDomains = [process.env.FRONTEND_URL || 'http://localhost:3000'];
-  if (!allowedDomains.some((domain) => redirectUrl.startsWith(domain))) {
-    return res.status(400).json({ error: 'Invalid redirect URL' });
-  }
+  const redirectUrl = req.query.redirectUrl || process.env.FRONTEND_URL || 'https://yanawa.shop';
+	  // redirectUrl �좏슚�� 寃�利�
 
   // redirectUrl �몄뀡�� ����
   req.session.redirectUrl = redirectUrl;
@@ -20,20 +15,23 @@ router.get('/login', (req, res, next) => {
   // Google OAuth �몄쬆 �쒖옉
   passport.authenticate('google', { scope: ['profile', 'email'] })(req, res, next);
 });
-
-// GET /auth/google/callback
 router.get(
   '/google/callback',
   passport.authenticate('google', { failureRedirect: '/auth/login' }),
   (req, res) => {
-    // �몄뀡�먯꽌 redirectUrl 媛��몄삤湲�
-    const redirectUrl = req.session.redirectUrl || process.env.FRONTEND_URL || 'http://localhost:3000';
+    const redirectUrl = req.session.redirectUrl || 'https://yanawa.shop';
+
 
-    // �몄뀡�먯꽌 redirectUrl �쒓굅
     req.session.redirectUrl = null;
 
-    // �몄쬆 �꾨즺 �� �꾨줎�몄뿏�쒕줈 由щ떎�대젆��
-    res.redirect(redirectUrl);
+    req.session.save((err) => {
+      if (err) {
+        console.error('�몄뀡 ���� �ㅻ쪟:', err);
+        return res.status(500).json({ error: '�쒕쾭 �ㅻ쪟' });
+      }
+
+      res.redirect(redirectUrl);
+    });
   }
 );
 
diff --git a/weblog.log b/weblog.log
index 20d8173..e05bb44 100644
--- a/weblog.log
+++ b/weblog.log
@@ -1,6 +1,6 @@
-(node:4551) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:8605) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 (Use `node --trace-warnings ...` to show where the warning was created)
-(node:4551) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:8605) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 MongoDB �곌껐 �ㅽ뙣: MongooseServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017
     at _handleConnectionErrors (/home/ubuntu/webback/node_modules/mongoose/lib/connection.js:909:11)
     at NativeConnection.openUri (/home/ubuntu/webback/node_modules/mongoose/lib/connection.js:860:11)
-- 
GitLab


From d28f525aa80051b3f8e383c82251f6d3bdb5195e 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: Wed, 4 Dec 2024 18:45:58 +0900
Subject: [PATCH 18/61] =?UTF-8?q?refactor:=20=EC=8A=A4=EC=BC=80=EC=A4=84?=
 =?UTF-8?q?=20response=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EC=84=9C?=
 =?UTF-8?q?=EB=B9=84=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 dtos/ScheduleResponseDTO.js |  27 ++--
 services/scheduleService.js | 238 +++++++++++++++++++++++-------------
 2 files changed, 170 insertions(+), 95 deletions(-)

diff --git a/dtos/ScheduleResponseDTO.js b/dtos/ScheduleResponseDTO.js
index a75316e..7527621 100644
--- a/dtos/ScheduleResponseDTO.js
+++ b/dtos/ScheduleResponseDTO.js
@@ -1,14 +1,25 @@
 // dtos/ScheduleResponseDTO.js
 
 class ScheduleResponseDTO {
-  constructor(schedule) {
-      this.id = schedule.id;
-      this.user_id = schedule.user_id;
-      this.title = schedule.title;
-      this.time_idx = schedule.time_idx; // �덈줈�� time_idx �꾨뱶 異붽�
-      this.is_fixed = schedule.is_fixed;
-      this.createdAt = schedule.createdAt;
-      this.updatedAt = schedule.updatedAt;
+  static groupSchedules(schedules) {
+      const grouped = schedules.reduce((acc, schedule) => {
+          const key = `${schedule.title}-${schedule.is_fixed}`;
+          if (!acc[key]) {
+              acc[key] = {
+                  id: schedule.id,
+                  user_id: schedule.user_id,
+                  title: schedule.title,
+                  is_fixed: schedule.is_fixed,
+                  time_indices: [],
+                  createdAt: schedule.createdAt,
+                  updatedAt: schedule.updatedAt
+              };
+          }
+          acc[key].time_indices.push(schedule.time_idx);
+          return acc;
+      }, {});
+
+      return Object.values(grouped);
   }
 }
 
diff --git a/services/scheduleService.js b/services/scheduleService.js
index e664a49..abfb66e 100644
--- a/services/scheduleService.js
+++ b/services/scheduleService.js
@@ -9,158 +9,222 @@ 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;
-
-            // 以묐났 �ㅼ�以� 寃���
+    async createSchedules({ userId, title, is_fixed, time_indices }, transaction = null) {
+        // 以묐났 寃���
+        for (const time_idx of time_indices) {
             const overlap = await this.checkScheduleOverlap(userId, time_idx, transaction);
             if (overlap) {
-                throw new Error(`Schedule overlaps with existing schedule at time_idx ${time_idx}`);
+                throw new Error(`Schedule overlaps 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 = [];
+        const createdSchedules = await Promise.all(
+            time_indices.map(time_idx =>
+                Schedule.create({
+                    user_id: userId,
+                    title,
+                    time_idx,
+                    is_fixed
+                }, { transaction })
+            )
+        );
 
-        for (const update of updates) {
-            const { time_idx, title, is_fixed } = update;
+        return {
+            id: createdSchedules[0].id,
+            user_id: userId,
+            title,
+            is_fixed,
+            time_indices,
+            createdAt: createdSchedules[0].createdAt,
+            updatedAt: createdSchedules[0].updatedAt
+        };
+    }
 
-            const schedule = await Schedule.findOne({
-                where: { user_id: userId, time_idx },
-                transaction,
+    async getAllSchedules(userId) {
+        try {
+            const schedules = await Schedule.findAll({
+                where: { user_id: userId },
+                order: [['time_idx', 'ASC']]
             });
 
-            if (!schedule) {
-                throw new Error(`Schedule not found at time_idx ${time_idx}`);
-            }
+            return ScheduleResponseDTO.groupSchedules(schedules);
+        } catch (error) {
+            throw new Error(`Failed to fetch schedules: ${error.message}`);
+        }
+    }
+
+    async updateSchedules(userId, updates, transaction = null) {
+        const { originalTitle, title, is_fixed, time_indices } = updates;
 
-            const updatedData = {};
-            if (title !== undefined) updatedData.title = title;
-            if (is_fixed !== undefined) updatedData.is_fixed = is_fixed;
+        // 湲곗〈 �ㅼ�以� 議고쉶
+        const existingSchedules = await Schedule.findAll({
+            where: {
+                user_id: userId,
+                title: originalTitle
+            },
+            transaction
+        });
 
-            const updatedSchedule = await schedule.update(updatedData, { transaction });
-            updatedSchedules.push(new ScheduleResponseDTO(updatedSchedule));
+        if (existingSchedules.length === 0) {
+            throw new Error('Schedule not found');
         }
 
-        return updatedSchedules;
-    }
+        const existingTimeIndices = existingSchedules.map(s => s.time_idx); // 湲곗〈 �쒓컙��
+        const toDelete = existingTimeIndices.filter(idx => !time_indices.includes(idx)); // ��젣�� �쒓컙��
+        const toAdd = time_indices.filter(idx => !existingTimeIndices.includes(idx)); // 異붽��� �쒓컙��
+        const t = transaction || await sequelize.transaction();
 
-    /**
-     * �ㅼ�以� ��젣 (踰뚰겕)
-     * @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 = [];
+        try {
+            // ��젣
+            if (toDelete.length > 0) {
+                await Schedule.destroy({
+                    where: {
+                        user_id: userId,
+                        title: originalTitle,
+                        time_idx: {
+                            [Op.in]: toDelete
+                        }
+                    },
+                    transaction: t
+                });
+            }
 
-        for (const time_idx of time_idxs) {
-            const deletedCount = await Schedule.destroy({
-                where: { user_id: userId, time_idx },
-                transaction,
-            });
+            // �쒕ぉ, 怨좎젙/�좊룞 �낅뜲�댄듃
+            await Schedule.update(
+                {
+                    title,
+                    is_fixed
+                },
+                {
+                    where: {
+                        user_id: userId,
+                        title: originalTitle
+                    },
+                    transaction: t
+                }
+            );
+
+            // �덈줈�� time_indices 異붽�
+            if (toAdd.length > 0) {
+                await Promise.all(
+                    toAdd.map(time_idx =>
+                        Schedule.create({
+                            user_id: userId,
+                            title,
+                            time_idx,
+                            is_fixed
+                        }, { transaction: t })
+                    )
+                );
+            }
 
-            if (deletedCount === 0) {
-                throw new Error(`Schedule not found at time_idx ${time_idx}`);
+            if (!transaction) {
+                await t.commit();
             }
 
-            deleted_time_idxs.push(time_idx);
+            return {
+                id: existingSchedules[0].id,
+                user_id: userId,
+                title,
+                is_fixed,
+                time_indices,
+                createdAt: existingSchedules[0].createdAt,
+                updatedAt: new Date()
+            };
+
+        } catch (error) {
+            if (!transaction) {
+                await t.rollback();
+            }
+            throw error;
         }
+    }
+
+    async deleteSchedules(userId, title, transaction = null) {
+        const deletedSchedules = await Schedule.destroy({
+            where: {
+                user_id: userId,
+                title
+            },
+            transaction
+        });
 
-        return { deleted_time_idxs };
+        return { deletedCount: deletedSchedules };
     }
 
     /**
      * �뱀젙 time_idx濡� �ㅼ�以� 議고쉶
      */
     async getScheduleByTimeIdx(userId, time_idx) {
+        // �대떦 time_idx�� �ㅼ�以� 李얘린
         const schedule = await Schedule.findOne({
-            where: { user_id: userId, time_idx },
+            where: { user_id: userId, time_idx }
         });
 
         if (!schedule) {
             throw new Error('Schedule not found');
         }
 
-        return new ScheduleResponseDTO(schedule);
+        // 媛숈� �쒕ぉ�� 紐⑤뱺 �ㅼ�以� 李얘린
+        const relatedSchedules = await Schedule.findAll({
+            where: {
+                user_id: userId,
+                title: schedule.title,
+                is_fixed: schedule.is_fixed
+            },
+            order: [['time_idx', 'ASC']]
+        });
+
+        return ScheduleResponseDTO.groupSchedules(relatedSchedules)[0];
     }
 
-    /**
-     * 紐⑤뱺 �ㅼ�以� 議고쉶
-     */
     async getAllSchedules(userId) {
         try {
             const schedules = await Schedule.findAll({
                 where: { user_id: userId },
-                order: [['time_idx', 'ASC']],
+                order: [['time_idx', 'ASC']]
             });
-            return schedules.map((schedule) => new ScheduleResponseDTO(schedule));
+            return ScheduleResponseDTO.groupSchedules(schedules);
         } 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,
+            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({
+        const overlappingSchedules = await Schedule.findAll({
             where: {
                 user_id: userId,
                 time_idx: {
-                    [Op.between]: [time_idx_start, time_idx_end] 
+                    [Op.between]: [time_idx_start, time_idx_end]
                 }
             },
-            transaction,
+            transaction
         });
-         console.log(`以묐났 �ㅼ�以�: ${JSON.stringify(overlappingSchedule)}`);
-    const result = !!overlappingSchedule;
-    console.log(`�ㅼ�以� 異⑸룎 寃곌낵: ${result}`);
-    return result;
+
+        const groupedSchedules = ScheduleResponseDTO.groupSchedules(overlappingSchedules);
+        const result = groupedSchedules.length > 0;
+
+        console.log(`checkScheduleOverlapByTime �몄텧: userId=${userId}, time_idx_start=${time_idx_start}, time_idx_end=${time_idx_end}`);
+        console.log(`以묐났 �ㅼ�以�: ${JSON.stringify(groupedSchedules)}`);
+        console.log(`�ㅼ�以� 異⑸룎 寃곌낵: ${result}`);
+
+        return result;
     }
-    
 
-    /**
-     * 留뚮즺�� �ㅼ�以� ��젣
-     */
     async cleanExpiredSchedules() {
         try {
             const deletedCount = await Schedule.destroy({
-                where: { is_fixed: false },
+                where: { is_fixed: false }
             });
-            //console.log(`Deleted ${deletedCount} flexible schedules.`);
+            return { deletedCount };
         } catch (error) {
             console.error('Failed to clean expired schedules:', error);
             throw error;
-- 
GitLab


From 6958b3d4989e43895d887377097ea2cca8c8b9da 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: Wed, 4 Dec 2024 18:46:26 +0900
Subject: [PATCH 19/61] =?UTF-8?q?refactor:=20=EC=8A=A4=EC=BC=80=EC=A4=84?=
 =?UTF-8?q?=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=88=98=EC=A0=95=EC=97=90=20?=
 =?UTF-8?q?=EB=94=B0=EB=A5=B8=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC,=20?=
 =?UTF-8?q?=EB=AF=B8=ED=8C=85=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=88=98?=
 =?UTF-8?q?=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 controllers/scheduleController.js | 60 +++++++++++++++----------------
 services/meetingService.js        | 51 +++++++++++---------------
 2 files changed, 49 insertions(+), 62 deletions(-)

diff --git a/controllers/scheduleController.js b/controllers/scheduleController.js
index 4d43ee1..e2c7122 100644
--- a/controllers/scheduleController.js
+++ b/controllers/scheduleController.js
@@ -22,22 +22,19 @@ class scheduleController {
     async createSchedule(req, res) {
         try {
             const userId = req.user.id;
-            const scheduleRequestDTO = new ScheduleRequestDTO(req.body);
-            const validatedData = scheduleRequestDTO.validate('create'); // 'create' ���� 寃�利�
+            const { title, is_fixed, time_indices } = req.body;
 
-            const { title, is_fixed, events } = validatedData;
-
-            const schedules = await ScheduleService.createSchedules({
+            const schedule = await ScheduleService.createSchedules({
                 userId,
                 title,
                 is_fixed,
-                events
+                time_indices
             });
 
             return res.status(201).json({
                 success: true,
                 data: {
-                    schedules
+                    schedule
                 }
             });
         } catch (error) {
@@ -49,7 +46,7 @@ class scheduleController {
                 }
             });
         }
-    }
+    }   
 
     /**
      * �ㅼ�以� �섏젙
@@ -57,31 +54,32 @@ class scheduleController {
      * Bulk update 吏���
      * �붿껌 蹂몃Ц �덉떆:
      * {
-     *   updates: [
-     *     { time_idx: 36, title: 'New Title', is_fixed: true },
-     *     { time_idx: 44, title: 'Another Title' },
-     *     // ...
-     *   ]
+     *  "originalTitle": "�뚭퀬由ъ쬁 �ㅽ꽣��", // 湲곗〈 �ㅼ�以꾩쓽 �쒕ぉ
+     *  "title": "�뚭퀬由ъ쬁 �ㅽ꽣�� 2.0",     // 蹂�寃쏀븷 �쒕ぉ (�쒕ぉ 蹂�寃� �덊븷嫄곕㈃ 湲곗〈 �쒕ぉ�� �l뼱�쇳븿 * -> title濡� �숈씪 �ㅼ�以꾩쓣 李얠븘��)
+     *   "is_fixed": true,  
+     *   "time_indices": [36, 37, 38, 40]   // 蹂�寃쏀븷 time_indices 諛곗뿴
      * }
      */
     async updateSchedules(req, res) {
         try {
             const userId = req.user.id;
-            const scheduleRequestDTO = new ScheduleRequestDTO(req.body);
-            const validatedData = scheduleRequestDTO.validate('bulk_update'); // 'bulk_update' ���� 寃�利�
-
-            const { updates } = validatedData;
+            const { originalTitle, title, is_fixed, time_indices } = req.body;
 
-            const updatedSchedules = await ScheduleService.updateSchedules(userId, updates);
+            const updatedSchedule = await ScheduleService.updateSchedules(userId, {
+                originalTitle, 
+                title,         
+                is_fixed,
+                time_indices
+            });
 
             return res.status(200).json({
                 success: true,
                 data: {
-                    schedules: updatedSchedules
+                    schedule: updatedSchedule
                 }
             });
         } catch (error) {
-            if (error.code === 'SCHEDULE_NOT_FOUND') {
+            if (error.message === 'Schedule not found') {
                 return res.status(404).json({
                     success: false,
                     error: {
@@ -106,24 +104,21 @@ class scheduleController {
      * Bulk delete 吏���
      * �붿껌 蹂몃Ц �덉떆:
      * {
-     *   time_idxs: [36, 44, ...]
+     *  "title": "�뚭퀬由ъ쬁 �ㅽ꽣��"
      * }
      */
     async deleteSchedules(req, res) {
         try {
             const userId = req.user.id;
-            const scheduleRequestDTO = new ScheduleRequestDTO(req.body);
-            const validatedData = scheduleRequestDTO.validate('bulk_delete'); // 'bulk_delete' ���� 寃�利�
-
-            const { time_idxs } = validatedData;
+            const { title } = req.body;
 
-            const result = await ScheduleService.deleteSchedules(userId, time_idxs);
+            const result = await ScheduleService.deleteSchedules(userId, title);
 
             return res.status(200).json({
                 success: true,
                 data: {
-                    message: 'Schedules successfully deleted',
-                    deleted_time_idxs: result.deleted_time_idxs
+                    message: 'Schedule successfully deleted',
+                    deletedCount: result.deletedCount
                 }
             });
         } catch (error) {
@@ -136,7 +131,6 @@ class scheduleController {
             });
         }
     }
-
     /**
      * �대떦 �ъ슜�� �꾩껜 �ㅼ�以� 議고쉶
      * GET /api/schedule/all
@@ -148,7 +142,9 @@ class scheduleController {
 
             return res.status(200).json({
                 success: true,
-                data: schedules
+                data: {
+                    schedules
+                }
             });
         } catch (error) {
             return res.status(500).json({
@@ -175,7 +171,9 @@ class scheduleController {
 
             return res.status(200).json({
                 success: true,
-                data: schedule
+                data: {
+                    schedule
+                }
             });
         } catch (error) {
             if (error.message === 'Schedule not found') {
diff --git a/services/meetingService.js b/services/meetingService.js
index 24b9e67..746597d 100644
--- a/services/meetingService.js
+++ b/services/meetingService.js
@@ -118,20 +118,16 @@ class MeetingService {
                 { transaction }
             );
 
-            // �ㅼ�以� �앹꽦 (紐⑥엫 �쒓컙 踰붿쐞 �� 紐⑤뱺 time_idx�� ���� �앹꽦)
-            const events = [];
-            for (let idx = time_idx_start; idx <= time_idx_end; idx++) {
-                events.push({ time_idx: idx });
-            }
-            await ScheduleService.createSchedules(
-                {
-                    userId: created_by,
-                    title: `踰덇컻 紐⑥엫: ${title}`,
-                    is_fixed: false,
-                    events: events,
-                },
-                transaction
+            const time_indices = Array.from(
+                { length: time_idx_end - time_idx_start + 1 },
+                (_, i) => time_idx_start + i
             );
+            await ScheduleService.createSchedules({
+                userId: created_by,
+                title: `踰덇컻 紐⑥엫: ${title}`,
+                is_fixed: false,
+                time_indices: time_indices,
+            }, transaction);
 
             // 移쒓뎄 珥덈� 濡쒖쭅 �몄텧
             const invitedFriendIds = await this.sendInvites({
@@ -264,24 +260,17 @@ class MeetingService {
             { transaction }
           );
 
-          // �ㅼ�以� �앹꽦 (紐⑥엫 �쒓컙 踰붿쐞 �� 紐⑤뱺 time_idx�� ���� �앹꽦)
-          const events = [];
-          for (
-            let idx = meeting.time_idx_start;
-            idx <= meeting.time_idx_end;
-            idx++
-          ) {
-            events.push({ time_idx: idx });
-          }
-          await ScheduleService.createSchedules(
-            {
-              userId: userId,
-              title: `踰덇컻 紐⑥엫: ${meeting.title}`,
-              is_fixed: false,
-              events: events,
-            },
-            transaction
-          );
+        const time_indices = Array.from(
+            { length: meeting.time_idx_end - meeting.time_idx_start + 1 },
+            (_, i) => meeting.time_idx_start + i
+        );
+        
+        await ScheduleService.createSchedules({
+            userId: userId,
+            title: `踰덇컻 紐⑥엫: ${meeting.title}`,
+            is_fixed: false,
+            time_indices: time_indices,
+        }, transaction);
 
           // 梨꾪똿諛� 李멸� (MongoDB)
           const user = await User.findOne({
-- 
GitLab


From fcf95cd32be8629685b870f6a4e4ce462d716ad7 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: Wed, 4 Dec 2024 18:46:41 +0900
Subject: [PATCH 20/61] =?UTF-8?q?test:=20=EB=B3=80=EA=B2=BD=EB=90=9C=20?=
 =?UTF-8?q?=EC=8A=A4=EC=BC=80=EC=A4=84=20=EB=A1=9C=EC=A7=81=20=ED=85=8C?=
 =?UTF-8?q?=EC=8A=A4=ED=8A=B8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 services/modifyScheduleResponse.test.js | 187 ++++++++++++++++++++++++
 1 file changed, 187 insertions(+)
 create mode 100644 services/modifyScheduleResponse.test.js

diff --git a/services/modifyScheduleResponse.test.js b/services/modifyScheduleResponse.test.js
new file mode 100644
index 0000000..64ab78c
--- /dev/null
+++ b/services/modifyScheduleResponse.test.js
@@ -0,0 +1,187 @@
+// test/scheduleService.test.js
+const sequelize = require('../config/sequelize');
+const { Schedule, User, Meeting, MeetingParticipant, FcmToken } = require('../models');
+const ScheduleService = require('../services/scheduleService');
+const MeetingService = require('../services/meetingService');
+const ChatRooms = require('../schemas/chatRooms');
+
+describe('Schedule Service and Meeting Integration Tests', () => {
+    beforeAll(async () => {
+        await sequelize.sync({ force: true });
+    });
+
+    beforeEach(async () => {
+        await MeetingParticipant.destroy({ where: {} });
+        await Meeting.destroy({ where: {} });
+        await Schedule.destroy({ where: {} });
+        await User.destroy({ where: {} });
+        await FcmToken.destroy({ where: {} });
+
+        // �붾� �ъ슜�� �앹꽦
+        await User.bulkCreate([
+            { id: 1, name: 'Alice', email: 'alice@example.com' },
+            { id: 2, name: 'Bob', email: 'bob@example.com' },
+            { id: 3, name: 'Charlie', email: 'charlie@example.com' }
+        ]);
+
+        // ChatRooms Mock �ㅼ젙
+        jest.spyOn(ChatRooms.prototype, 'save').mockResolvedValue(undefined);
+        jest.spyOn(ChatRooms, 'findOne').mockResolvedValue({
+            participants: [],
+            isOnline: new Map(),
+            lastReadAt: new Map(),
+            lastReadLogId: new Map(),
+            save: jest.fn().mockResolvedValue(true)
+        });
+    });
+
+    afterAll(async () => {
+        await sequelize.close();
+    });
+
+    describe('Schedule Service Tests', () => {
+        test('should create schedule with time_indices', async () => {
+            const scheduleData = {
+                userId: 1,
+                title: 'Test Schedule',
+                is_fixed: true,
+                time_indices: [36, 37, 38]
+            };
+
+            const schedule = await ScheduleService.createSchedules(scheduleData);
+
+            expect(schedule).toBeDefined();
+            expect(schedule.title).toBe('Test Schedule');
+            expect(schedule.time_indices).toEqual([36, 37, 38]);
+
+            const dbSchedules = await Schedule.findAll({
+                where: { user_id: 1, title: 'Test Schedule' }
+            });
+            expect(dbSchedules.length).toBe(3);
+        });
+
+        test('should update schedule with new time_indices', async () => {
+            await ScheduleService.createSchedules({
+                userId: 1,
+                title: 'Original Schedule',
+                is_fixed: true,
+                time_indices: [36, 37, 38]
+            });
+
+            const updateData = {
+                originalTitle: 'Original Schedule',
+                title: 'Updated Schedule',
+                is_fixed: true,
+                time_indices: [36, 37, 38, 39]
+            };
+
+            const updatedSchedule = await ScheduleService.updateSchedules(1, updateData);
+
+            expect(updatedSchedule.title).toBe('Updated Schedule');
+            expect(updatedSchedule.time_indices).toEqual([36, 37, 38, 39]);
+        });
+
+        test('should delete schedule by title', async () => {
+            await ScheduleService.createSchedules({
+                userId: 1,
+                title: 'Schedule to Delete',
+                is_fixed: true,
+                time_indices: [40, 41, 42]
+            });
+
+            const result = await ScheduleService.deleteSchedules(1, 'Schedule to Delete');
+            expect(result.deletedCount).toBe(3);
+
+            const remainingSchedules = await Schedule.findAll({
+                where: { user_id: 1, title: 'Schedule to Delete' }
+            });
+            expect(remainingSchedules.length).toBe(0);
+        });
+    });
+
+    describe('Meeting Integration Tests', () => {
+        beforeEach(() => {
+            jest.spyOn(User, 'findOne').mockResolvedValue({
+                id: 1,
+                name: 'Alice',
+                email: 'alice@example.com',
+                fcmTokenList: []
+            });
+        });
+
+        test('should create meeting with correct schedules', async () => {
+            const meetingData = {
+                title: 'Test Meeting',
+                time_idx_start: 50,
+                time_idx_end: 52,
+                created_by: 1,
+                type: 'OPEN',
+                max_num: 5
+            };
+
+            const meeting = await MeetingService.createMeeting(meetingData);
+
+            const creatorSchedules = await Schedule.findAll({
+                where: {
+                    user_id: 1,
+                    title: `踰덇컻 紐⑥엫: ${meetingData.title}`
+                }
+            });
+
+            expect(creatorSchedules.length).toBe(3);
+            expect(creatorSchedules.map(s => s.time_idx).sort()).toEqual([50, 51, 52]);
+        });
+
+        test('should create correct schedules when joining meeting', async () => {
+            const meetingData = {
+                title: 'Join Test Meeting',
+                time_idx_start: 60,
+                time_idx_end: 62,
+                created_by: 1,
+                type: 'OPEN',
+                max_num: 5,
+                time_idx_deadline: 59 
+            };
+
+            const meeting = await MeetingService.createMeeting(meetingData);
+            jest.spyOn(MeetingService, 'getCurrentTimeIdx').mockReturnValue(58);
+
+            await MeetingService.joinMeeting(meeting.meeting_id, 2);
+
+            const participantSchedules = await Schedule.findAll({
+                where: {
+                    user_id: 2,
+                    title: `踰덇컻 紐⑥엫: ${meetingData.title}`
+                }
+            });
+
+            expect(participantSchedules.length).toBe(3);
+            expect(participantSchedules.map(s => s.time_idx).sort()).toEqual([60, 61, 62]);
+        });
+
+        test('should handle schedule conflicts correctly', async () => {
+            await ScheduleService.createSchedules({
+                userId: 2,
+                title: 'Existing Schedule',
+                is_fixed: true,
+                time_indices: [70, 71]
+            });
+
+            const meetingData = {
+                title: 'Conflict Test Meeting',
+                time_idx_start: 70,
+                time_idx_end: 72,
+                created_by: 1,
+                type: 'OPEN',
+                max_num: 5,
+                time_idx_deadline: 69 
+            };
+
+            const meeting = await MeetingService.createMeeting(meetingData);
+
+            await expect(
+                MeetingService.joinMeeting(meeting.meeting_id, 2)
+            ).rejects.toThrow('�ㅼ�以꾩씠 寃뱀묩�덈떎');
+        });
+    });
+});
\ No newline at end of file
-- 
GitLab


From b00d1dc8681a0c61d6fb2925e0354052917d6ff4 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: Wed, 4 Dec 2024 19:18:14 +0900
Subject: [PATCH 21/61] =?UTF-8?q?refactor:=20req=20body,=20param=20?=
 =?UTF-8?q?=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EC=B2=B4=ED=81=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 controllers/scheduleController.js | 29 +++++++++++++----------------
 dtos/ScheduleRequestDTO.js        | 31 ++++++++++++++++---------------
 2 files changed, 29 insertions(+), 31 deletions(-)

diff --git a/controllers/scheduleController.js b/controllers/scheduleController.js
index e2c7122..0f45d89 100644
--- a/controllers/scheduleController.js
+++ b/controllers/scheduleController.js
@@ -22,13 +22,12 @@ class scheduleController {
     async createSchedule(req, res) {
         try {
             const userId = req.user.id;
-            const { title, is_fixed, time_indices } = req.body;
+            const scheduleRequestDTO = new ScheduleRequestDTO(req.body);
+            const validatedData = scheduleRequestDTO.validate('create');
 
             const schedule = await ScheduleService.createSchedules({
                 userId,
-                title,
-                is_fixed,
-                time_indices
+                ...validatedData
             });
 
             return res.status(201).json({
@@ -63,15 +62,11 @@ class scheduleController {
     async updateSchedules(req, res) {
         try {
             const userId = req.user.id;
-            const { originalTitle, title, is_fixed, time_indices } = req.body;
-
-            const updatedSchedule = await ScheduleService.updateSchedules(userId, {
-                originalTitle, 
-                title,         
-                is_fixed,
-                time_indices
-            });
+            const scheduleRequestDTO = new ScheduleRequestDTO(req.body);
+            const validatedData = scheduleRequestDTO.validate('bulk_update');
 
+            const updatedSchedule = await ScheduleService.updateSchedules(userId, validatedData);
+            
             return res.status(200).json({
                 success: true,
                 data: {
@@ -110,9 +105,9 @@ class scheduleController {
     async deleteSchedules(req, res) {
         try {
             const userId = req.user.id;
-            const { title } = req.body;
-
-            const result = await ScheduleService.deleteSchedules(userId, title);
+            const scheduleRequestDTO = new ScheduleRequestDTO(req.body);
+            const validatedData = scheduleRequestDTO.validate('bulk_delete');
+            const result = await ScheduleService.deleteSchedules(userId, validatedData.title);
 
             return res.status(200).json({
                 success: true,
@@ -167,7 +162,9 @@ class scheduleController {
             const { time_idx } = req.params;
             const userId = req.user.id;
 
-            const schedule = await ScheduleService.getScheduleByTimeIdx(userId, parseInt(time_idx, 10));
+            const scheduleRequestDTO = new ScheduleRequestDTO({ time_idx: parseInt(time_idx, 10) });
+            const validatedData = scheduleRequestDTO.validate('get_by_time_idx');
+            const schedule = await ScheduleService.getScheduleByTimeIdx(userId, validatedData.time_idx);
 
             return res.status(200).json({
                 success: true,
diff --git a/dtos/ScheduleRequestDTO.js b/dtos/ScheduleRequestDTO.js
index 854bd3f..218f9e0 100644
--- a/dtos/ScheduleRequestDTO.js
+++ b/dtos/ScheduleRequestDTO.js
@@ -13,27 +13,28 @@ class ScheduleRequestDTO {
             schema = Joi.object({
                 title: Joi.string().min(1).max(255).required(),
                 is_fixed: Joi.boolean().required(),
-                events: Joi.array().items(
-                    Joi.object({
-                        time_idx: Joi.number().integer().min(0).max(671).required(),
-                    })
-                ).min(1).required()
+                time_indices: Joi.array()
+                    .items(Joi.number().integer().min(0).max(671))
+                    .min(1)
+                    .required()
             });
         } else if (type === 'bulk_update') {
             schema = Joi.object({
-                updates: Joi.array().items(
-                    Joi.object({
-                        time_idx: Joi.number().integer().min(0).max(671).required(),
-                        title: Joi.string().min(1).max(255).optional(),
-                        is_fixed: Joi.boolean().optional(),
-                    })
-                ).min(1).required()
+                originalTitle: Joi.string().min(1).max(255).required(),
+                title: Joi.string().min(1).max(255).required(),
+                is_fixed: Joi.boolean().required(),
+                time_indices: Joi.array()
+                    .items(Joi.number().integer().min(0).max(671))
+                    .min(1)
+                    .required()
             });
         } else if (type === 'bulk_delete') {
             schema = Joi.object({
-                time_idxs: Joi.array().items(
-                    Joi.number().integer().min(0).max(671).required()
-                ).min(1).required()
+                title: Joi.string().min(1).max(255).required()
+            });
+        } else if (type === 'get_by_time_idx') {
+            schema = Joi.object({
+                time_idx: Joi.number().integer().min(0).max(671).required()
             });
         }
 
-- 
GitLab


From eaa8bda81b501f85989de3e3bb6bca505a863740 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: Wed, 4 Dec 2024 19:34:51 +0900
Subject: [PATCH 22/61] =?UTF-8?q?test:=20=EC=84=B1=EB=8A=A5=20=EC=B8=A1?=
 =?UTF-8?q?=EC=A0=95=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EB=A1=9C=EC=A7=81=20?=
 =?UTF-8?q?=EC=B6=94=EA=B0=80=20(#23)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app.js                      |  3 ++
 routes/performanceRoute.js  | 14 +++++++++
 utils/performanceMonitor.js | 63 +++++++++++++++++++++++++++++++++++++
 3 files changed, 80 insertions(+)
 create mode 100644 routes/performanceRoute.js
 create mode 100644 utils/performanceMonitor.js

diff --git a/app.js b/app.js
index 952e375..aace954 100644
--- a/app.js
+++ b/app.js
@@ -66,6 +66,9 @@ app.use('/api/chat', chatRoutes);
 const memberRoutes = require('./routes/memberRoute');
 app.use('/api/member', memberRoutes);
 
+const memberRoutes = require('./routes/performanceRoute');
+app.use('/api/performance', performanceRoutes);
+
 // �ㅼ�以� �대━�� 珥덇린��
 initScheduleCleaner();
 
diff --git a/routes/performanceRoute.js b/routes/performanceRoute.js
new file mode 100644
index 0000000..eeab98c
--- /dev/null
+++ b/routes/performanceRoute.js
@@ -0,0 +1,14 @@
+// routes/performanceRoute.js
+const express = require('express');
+const router = express.Router();
+const performanceMonitor = require('../utils/performanceMonitor');
+
+router.get('/stats', (req, res) => {
+    const stats = performanceMonitor.getAllStats();
+    res.json({
+        success: true,
+        data: { stats }
+    });
+});
+
+module.exports = router;
diff --git a/utils/performanceMonitor.js b/utils/performanceMonitor.js
new file mode 100644
index 0000000..dfba985
--- /dev/null
+++ b/utils/performanceMonitor.js
@@ -0,0 +1,63 @@
+// utils/performanceMonitor.js
+const { performance, PerformanceObserver } = require('perf_hooks');
+
+class PerformanceMonitor {
+    constructor() {
+        this.measurements = new Map();
+        
+        // �깅뒫 愿�李곗옄 �ㅼ젙
+        this.observer = new PerformanceObserver((items) => {
+            items.getEntries().forEach((entry) => {
+                const measurements = this.measurements.get(entry.name) || [];
+                measurements.push(entry.duration);
+                this.measurements.set(entry.name, measurements);
+                
+                console.log(`Performance Measurement - ${entry.name}: ${entry.duration}ms`);
+            });
+        });
+        
+        this.observer.observe({ entryTypes: ['measure'] });
+    }
+
+    async measureAsync(name, fn) {
+        const start = performance.now();
+        try {
+            return await fn();
+        } finally {
+            const duration = performance.now() - start;
+            performance.measure(name, { 
+                start,
+                duration,
+                detail: { timestamp: new Date().toISOString() }
+            });
+        }
+    }
+
+    getStats(name) {
+        const measurements = this.measurements.get(name) || [];
+        if (measurements.length === 0) return null;
+
+        const sum = measurements.reduce((a, b) => a + b, 0);
+        const avg = sum / measurements.length;
+        const min = Math.min(...measurements);
+        const max = Math.max(...measurements);
+
+        return {
+            count: measurements.length,
+            average: avg,
+            min: min,
+            max: max,
+            total: sum
+        };
+    }
+
+    getAllStats() {
+        const stats = {};
+        for (const [name, measurements] of this.measurements.entries()) {
+            stats[name] = this.getStats(name);
+        }
+        return stats;
+    }
+}
+
+module.exports = new PerformanceMonitor();
\ No newline at end of file
-- 
GitLab


From 64c26d78b38c309501ec96a24f94617332a4adb4 Mon Sep 17 00:00:00 2001
From: Ubuntu <ubuntu@ip-172-31-1-27.ap-northeast-2.compute.internal>
Date: Wed, 4 Dec 2024 13:33:50 +0000
Subject: [PATCH 23/61] =?UTF-8?q?refactor:=20=EB=B0=B0=ED=8F=AC=20?=
 =?UTF-8?q?=EC=BD=94=EB=93=9C=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 output.log | 5 +++--
 weblog.log | 4 ++--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/output.log b/output.log
index 15aceb8..859d37e 100644
--- a/output.log
+++ b/output.log
@@ -1,8 +1,9 @@
 MongoDB URI: mongodb+srv://admin:lim1234!!@goodmeeting.vkniz.mongodb.net/
-(node:8604) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:17474) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 (Use `node --trace-warnings ...` to show where the warning was created)
-(node:8604) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:17474) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 �� MongoDB �곌껐 �깃났
 Rdb�곗씠�곕쿋�댁뒪 �곌껐 �깃났.
 紐⑤뱺 紐⑤뜽�� �깃났�곸쑝濡� �숆린�붾릺�덉뒿�덈떎.
 Server is running on 8080
+GET /api/ 404 6.385 ms - 143
diff --git a/weblog.log b/weblog.log
index e05bb44..b8fb89d 100644
--- a/weblog.log
+++ b/weblog.log
@@ -1,6 +1,6 @@
-(node:8605) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:17475) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 (Use `node --trace-warnings ...` to show where the warning was created)
-(node:8605) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:17475) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 MongoDB �곌껐 �ㅽ뙣: MongooseServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017
     at _handleConnectionErrors (/home/ubuntu/webback/node_modules/mongoose/lib/connection.js:909:11)
     at NativeConnection.openUri (/home/ubuntu/webback/node_modules/mongoose/lib/connection.js:860:11)
-- 
GitLab


From ac6b8561120a92391feeae30f78c2b3218c46725 Mon Sep 17 00:00:00 2001
From: Ubuntu <ubuntu@ip-172-31-1-27.ap-northeast-2.compute.internal>
Date: Wed, 4 Dec 2024 13:49:35 +0000
Subject: [PATCH 24/61] =?UTF-8?q?bugfix:=20=EB=B0=B0=ED=8F=AC=20=EC=BD=94?=
 =?UTF-8?q?=EB=93=9C=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app.js     | 11 +----------
 output.log | 24 +++++++++++++++---------
 weblog.log |  4 ++--
 3 files changed, 18 insertions(+), 21 deletions(-)

diff --git a/app.js b/app.js
index d504b5f..7d6603c 100644
--- a/app.js
+++ b/app.js
@@ -16,19 +16,10 @@ const app = express();
 
 
 app.use(morgan('dev'));  //濡쒓퉭��
-// CORS �ㅼ젙
-<<<<<<< HEAD
-app.use(
-  cors({
-    origin: process.env.FRONTEND_URL, 
-=======
-
-
 // CORS �ㅼ젙
 app.use(
   cors({
     origin: 'https://yanawa.shop',
->>>>>>> 64c26d78b38c309501ec96a24f94617332a4adb4
     methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
     allowedHeaders: ['Content-Type', 'Authorization'],
     credentials: true,
@@ -103,4 +94,4 @@ const PORT = process.env.PORT || 3000;
     console.error('�� �쒕쾭 �쒖옉 以� �ㅻ쪟 諛쒖깮:', error);
     process.exit(1);
   }
-})();
\ No newline at end of file
+})();
diff --git a/output.log b/output.log
index 859d37e..b18562f 100644
--- a/output.log
+++ b/output.log
@@ -1,9 +1,15 @@
-MongoDB URI: mongodb+srv://admin:lim1234!!@goodmeeting.vkniz.mongodb.net/
-(node:17474) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
-(Use `node --trace-warnings ...` to show where the warning was created)
-(node:17474) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
-�� MongoDB �곌껐 �깃났
-Rdb�곗씠�곕쿋�댁뒪 �곌껐 �깃났.
-紐⑤뱺 紐⑤뜽�� �깃났�곸쑝濡� �숆린�붾릺�덉뒿�덈떎.
-Server is running on 8080
-GET /api/ 404 6.385 ms - 143
+/home/ubuntu/webback/app.js:20
+<<<<<<< HEAD
+^^
+
+SyntaxError: Unexpected token '<<'
+    at internalCompileFunction (node:internal/vm:76:18)
+    at wrapSafe (node:internal/modules/cjs/loader:1283:20)
+    at Module._compile (node:internal/modules/cjs/loader:1328:27)
+    at Module._extensions..js (node:internal/modules/cjs/loader:1422:10)
+    at Module.load (node:internal/modules/cjs/loader:1203:32)
+    at Module._load (node:internal/modules/cjs/loader:1019:12)
+    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:128:12)
+    at node:internal/main/run_main_module:28:49
+
+Node.js v18.20.5
diff --git a/weblog.log b/weblog.log
index b8fb89d..c52b535 100644
--- a/weblog.log
+++ b/weblog.log
@@ -1,6 +1,6 @@
-(node:17475) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:23273) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 (Use `node --trace-warnings ...` to show where the warning was created)
-(node:17475) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:23273) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 MongoDB �곌껐 �ㅽ뙣: MongooseServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017
     at _handleConnectionErrors (/home/ubuntu/webback/node_modules/mongoose/lib/connection.js:909:11)
     at NativeConnection.openUri (/home/ubuntu/webback/node_modules/mongoose/lib/connection.js:860:11)
-- 
GitLab


From 5430e3ed2e096957e0949772e535791dc77b6764 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: Wed, 4 Dec 2024 19:37:11 +0900
Subject: [PATCH 25/61] =?UTF-8?q?test:=20=EC=8A=A4=EC=BC=80=EC=A4=84=20?=
 =?UTF-8?q?=EC=84=B1=EB=8A=A5=20=EC=B8=A1=EC=A0=95=20=ED=85=8C=EC=8A=A4?=
 =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1=20(#23)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 services/performance.test.js | 98 ++++++++++++++++++++++++++++++++++++
 1 file changed, 98 insertions(+)
 create mode 100644 services/performance.test.js

diff --git a/services/performance.test.js b/services/performance.test.js
new file mode 100644
index 0000000..9104525
--- /dev/null
+++ b/services/performance.test.js
@@ -0,0 +1,98 @@
+const axios = require('axios');
+const { performance } = require('perf_hooks');
+
+async function runPerformanceTest() {
+    const baseURL = 'http://localhost:3000/api';
+    const iterations = 100;
+    
+    // �뚯뒪�� �곗씠��
+    const testSchedule = {
+        title: 'Test Schedule',
+        is_fixed: true,
+        time_indices: [36, 37, 38]
+    };
+
+    console.log(`Starting performance test with ${iterations} iterations`);
+
+    // �뚯뒪�� 寃곌낵 ���μ슜 媛앹껜
+    const results = {
+        create: [],
+        update: [],
+        getAll: [],
+        getByTimeIdx: [],
+        delete: []
+    };
+
+    for (let i = 0; i < iterations; i++) {
+        try {
+            console.log(`Running iteration ${i + 1}/${iterations}`);
+
+            // Create
+            const createStart = performance.now();
+            await axios.post(`${baseURL}/schedule`, testSchedule);
+            results.create.push(performance.now() - createStart);
+            
+            // Get All Schedules
+            const getAllStart = performance.now();
+            await axios.get(`${baseURL}/schedule/all`);
+            results.getAll.push(performance.now() - getAllStart);
+
+            // Get Schedule by Time Index
+            const getByTimeIdxStart = performance.now();
+            await axios.get(`${baseURL}/schedule/36`);
+            results.getByTimeIdx.push(performance.now() - getByTimeIdxStart);
+            
+            // Update
+            const updateStart = performance.now();
+            await axios.put(`${baseURL}/schedule`, {
+                originalTitle: 'Test Schedule',
+                title: 'Updated Schedule',
+                is_fixed: true,
+                time_indices: [39, 40, 41]
+            });
+            results.update.push(performance.now() - updateStart);
+            
+            // Delete
+            const deleteStart = performance.now();
+            await axios.delete(`${baseURL}/schedule`, {
+                data: { title: 'Updated Schedule' }
+            });
+            results.delete.push(performance.now() - deleteStart);
+
+        } catch (error) {
+            console.error(`Iteration ${i} failed:`, error.message);
+        }
+    }
+
+    // 寃곌낵 遺꾩꽍
+    const analyzeResults = (times) => {
+        const avg = times.reduce((a, b) => a + b, 0) / times.length;
+        const min = Math.min(...times);
+        const max = Math.max(...times);
+        return {
+            average: avg.toFixed(2),
+            min: min.toFixed(2),
+            max: max.toFixed(2),
+            count: times.length
+        };
+    };
+
+    // �깅뒫 �듦퀎 異쒕젰
+    console.log('\nPerformance Results (ms):');
+    console.log('Create Schedule:', analyzeResults(results.create));
+    console.log('Get All Schedules:', analyzeResults(results.getAll));
+    console.log('Get Schedule by Time Index:', analyzeResults(results.getByTimeIdx));
+    console.log('Update Schedule:', analyzeResults(results.update));
+    console.log('Delete Schedule:', analyzeResults(results.delete));
+
+    // �깅뒫 �듦퀎 API �몄텧
+    try {
+        const stats = await axios.get(`${baseURL}/performance/stats`);
+        console.log('\nDetailed Performance Statistics:', JSON.stringify(stats.data, null, 2));
+    } catch (error) {
+        console.error('Failed to fetch performance stats:', error.message);
+    }
+}
+
+// �뚯뒪�� �ㅽ뻾
+runPerformanceTest().catch(console.error);
\ No newline at end of file
-- 
GitLab


From 205af1535638f5410880d3156662432429f51058 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: Fri, 6 Dec 2024 10:10:31 +0900
Subject: [PATCH 26/61] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?=
 =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95=20(#23)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 services/performance.test.js | 273 ++++++++++++++++++++++++-----------
 1 file changed, 189 insertions(+), 84 deletions(-)

diff --git a/services/performance.test.js b/services/performance.test.js
index 9104525..e987e86 100644
--- a/services/performance.test.js
+++ b/services/performance.test.js
@@ -1,98 +1,203 @@
-const axios = require('axios');
-const { performance } = require('perf_hooks');
-
-async function runPerformanceTest() {
-    const baseURL = 'http://localhost:3000/api';
-    const iterations = 100;
-    
-    // �뚯뒪�� �곗씠��
-    const testSchedule = {
-        title: 'Test Schedule',
-        is_fixed: true,
-        time_indices: [36, 37, 38]
-    };
-
-    console.log(`Starting performance test with ${iterations} iterations`);
-
-    // �뚯뒪�� 寃곌낵 ���μ슜 媛앹껜
-    const results = {
-        create: [],
-        update: [],
-        getAll: [],
-        getByTimeIdx: [],
-        delete: []
-    };
-
-    for (let i = 0; i < iterations; i++) {
+// services/performance.test.js
+require('dotenv').config();
+const { Op } = require('sequelize');
+const ScheduleService = require('./scheduleService');
+const sequelize = require('../config/sequelize');
+const Schedule = require('../models/schedule');
+
+class PerformanceTester {
+    constructor() {
+        this.testUserIds = [1, 2, 3, 4, 5];  // 5紐낆쓽 �뚯뒪�� �좎�留� �ъ슜
+        this.results = {
+            operations: {
+                createSchedules: [],
+                getAllSchedules: [],
+                updateSchedules: [],
+                deleteSchedules: []
+            },
+            summary: {}
+        };
+    }
+
+    async setup() {
         try {
-            console.log(`Running iteration ${i + 1}/${iterations}`);
-
-            // Create
-            const createStart = performance.now();
-            await axios.post(`${baseURL}/schedule`, testSchedule);
-            results.create.push(performance.now() - createStart);
-            
-            // Get All Schedules
-            const getAllStart = performance.now();
-            await axios.get(`${baseURL}/schedule/all`);
-            results.getAll.push(performance.now() - getAllStart);
-
-            // Get Schedule by Time Index
-            const getByTimeIdxStart = performance.now();
-            await axios.get(`${baseURL}/schedule/36`);
-            results.getByTimeIdx.push(performance.now() - getByTimeIdxStart);
-            
-            // Update
-            const updateStart = performance.now();
-            await axios.put(`${baseURL}/schedule`, {
-                originalTitle: 'Test Schedule',
-                title: 'Updated Schedule',
-                is_fixed: true,
-                time_indices: [39, 40, 41]
-            });
-            results.update.push(performance.now() - updateStart);
-            
-            // Delete
-            const deleteStart = performance.now();
-            await axios.delete(`${baseURL}/schedule`, {
-                data: { title: 'Updated Schedule' }
+            await sequelize.authenticate();
+            console.log('Database connection established successfully.');
+            await Schedule.destroy({ where: {}, force: true });
+            console.log('Test data cleaned successfully.');
+            console.log('Using existing user IDs:', this.testUserIds);
+        } catch (error) {
+            console.error('Setup failed:', error);
+            throw error;
+        }
+    }
+
+    async runLoadTest() {
+        console.log('Starting simplified test...');
+
+        const testSchedules = this.testUserIds.map((userId, i) => ({
+            userId,
+            title: `Test Schedule ${i}`,
+            is_fixed: true,
+            time_indices: [i * 2, i * 2 + 1]
+        }));
+
+        console.log('Test schedules:', testSchedules);
+
+        const transaction = await sequelize.transaction();
+        try {
+            // Create �뚯뒪��
+            console.log('\nTesting createSchedules...');
+            const createdSchedules = [];
+            for (const schedule of testSchedules) {
+                const result = await this.measureOperation('createSchedules', async () => {
+                    const created = await ScheduleService.createSchedules(schedule, transaction);
+                    console.log(`Created schedule for user ${schedule.userId}`);
+                    return created;
+                });
+                if (result) createdSchedules.push(result);
+            }
+            await transaction.commit();
+
+            // �앹꽦�� �ㅼ�以� �뺤씤
+            const verifySchedules = await Schedule.findAll({
+                where: {
+                    user_id: { [Op.in]: this.testUserIds }
+                },
+                raw: true
             });
-            results.delete.push(performance.now() - deleteStart);
+            console.log('\nVerified schedules:', verifySchedules);
+
+            // GetAll �뚯뒪��
+            console.log('\nTesting getAllSchedules...');
+            for (const userId of this.testUserIds) {
+                await this.measureOperation('getAllSchedules', async () => {
+                    return await ScheduleService.getAllSchedules(userId);
+                });
+            }
+
+            // Update �뚯뒪��
+            console.log('\nTesting updateSchedules...');
+            for (const schedule of createdSchedules) {
+                await this.measureOperation('updateSchedules', async () => {
+                    return await ScheduleService.updateSchedules(schedule.user_id, {
+                        originalTitle: schedule.title,
+                        title: `Updated ${schedule.title}`,
+                        is_fixed: schedule.is_fixed,
+                        time_indices: schedule.time_indices
+                    });
+                });
+            }
+
+            // Delete �뚯뒪��
+            console.log('\nTesting deleteSchedules...');
+            const deleteTransaction = await sequelize.transaction();
+            try {
+                for (const schedule of createdSchedules) {
+                    await this.measureOperation('deleteSchedules', async () => {
+                        return await ScheduleService.deleteSchedules(
+                            schedule.user_id,
+                            `Updated ${schedule.title}`,
+                            deleteTransaction
+                        );
+                    });
+                }
+                await deleteTransaction.commit();
+            } catch (error) {
+                await deleteTransaction.rollback();
+                throw error;
+            }
+        } catch (error) {
+            await transaction.rollback();
+            throw error;
+        }
 
+        this.analyzePerfResults();
+    }
+
+    async measureOperation(name, operation) {
+        const start = process.hrtime.bigint();
+        try {
+            const result = await operation();
+            const end = process.hrtime.bigint();
+            const duration = Number(end - start) / 1000000;
+            this.results.operations[name].push({ success: true, duration });
+            return result;
         } catch (error) {
-            console.error(`Iteration ${i} failed:`, error.message);
+            const end = process.hrtime.bigint();
+            const duration = Number(end - start) / 1000000;
+            this.results.operations[name].push({
+                success: false,
+                duration,
+                error: error.message
+            });
+            console.error(`Error in ${name}:`, error.message);
+            return null;
         }
     }
 
-    // 寃곌낵 遺꾩꽍
-    const analyzeResults = (times) => {
-        const avg = times.reduce((a, b) => a + b, 0) / times.length;
-        const min = Math.min(...times);
-        const max = Math.max(...times);
-        return {
-            average: avg.toFixed(2),
-            min: min.toFixed(2),
-            max: max.toFixed(2),
-            count: times.length
-        };
-    };
+    analyzePerfResults() {
+        Object.entries(this.results.operations).forEach(([operation, results]) => {
+            const successful = results.filter(r => r.success);
+            const failed = results.filter(r => !r.success);
+            if (successful.length > 0) {
+                const durations = successful.map(r => r.duration);
+                this.results.summary[operation] = {
+                    totalRequests: results.length,
+                    successCount: successful.length,
+                    failCount: failed.length,
+                    avgDuration: durations.reduce((a, b) => a + b, 0) / successful.length,
+                    minDuration: Math.min(...durations),
+                    maxDuration: Math.max(...durations),
+                    p95: this.calculatePercentile(durations, 95),
+                    p99: this.calculatePercentile(durations, 99)
+                };
+            }
+        });
+        this.printResults();
+    }
 
-    // �깅뒫 �듦퀎 異쒕젰
-    console.log('\nPerformance Results (ms):');
-    console.log('Create Schedule:', analyzeResults(results.create));
-    console.log('Get All Schedules:', analyzeResults(results.getAll));
-    console.log('Get Schedule by Time Index:', analyzeResults(results.getByTimeIdx));
-    console.log('Update Schedule:', analyzeResults(results.update));
-    console.log('Delete Schedule:', analyzeResults(results.delete));
+    calculatePercentile(array, percentile) {
+        const sorted = array.sort((a, b) => a - b);
+        const index = Math.ceil((percentile / 100) * sorted.length) - 1;
+        return sorted[index];
+    }
+
+    printResults() {
+        console.log('\n=== Performance Test Results ===');
+        Object.entries(this.results.summary).forEach(([operation, stats]) => {
+            console.log(`\n${operation}:`);
+            console.log(`Total Requests: ${stats.totalRequests}`);
+            console.log(`Success Rate: ${((stats.successCount / stats.totalRequests) * 100).toFixed(2)}%`);
+            console.log(`Average Duration: ${stats.avgDuration.toFixed(2)}ms`);
+            console.log(`Min Duration: ${stats.minDuration.toFixed(2)}ms`);
+            console.log(`Max Duration: ${stats.maxDuration.toFixed(2)}ms`);
+            console.log(`95th Percentile: ${stats.p95.toFixed(2)}ms`);
+            console.log(`99th Percentile: ${stats.p99.toFixed(2)}ms`);
+        });
+    }
+
+    async cleanup() {
+        try {
+            await Schedule.destroy({ where: {}, force: true });
+            console.log('Cleanup completed successfully.');
+        } catch (error) {
+            console.error('Cleanup failed:', error);
+        }
+    }
+}
 
-    // �깅뒫 �듦퀎 API �몄텧
+async function runTests() {
+    const tester = new PerformanceTester();
     try {
-        const stats = await axios.get(`${baseURL}/performance/stats`);
-        console.log('\nDetailed Performance Statistics:', JSON.stringify(stats.data, null, 2));
+        await tester.setup();
+        console.log('Starting performance tests...');
+        await tester.runLoadTest();
     } catch (error) {
-        console.error('Failed to fetch performance stats:', error.message);
+        console.error('Test failed:', error);
+    } finally {
+        await sequelize.close();
     }
 }
 
-// �뚯뒪�� �ㅽ뻾
-runPerformanceTest().catch(console.error);
\ No newline at end of file
+runTests();
\ No newline at end of file
-- 
GitLab


From 04fd4e448f4960ca95be3e517b718d7bcc5db039 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: Fri, 6 Dec 2024 10:10:55 +0900
Subject: [PATCH 27/61] =?UTF-8?q?refactor:=20=EC=8A=A4=EC=BC=80=EC=A4=84?=
 =?UTF-8?q?=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=EC=97=90=20=EC=84=B1?=
 =?UTF-8?q?=EB=8A=A5=20=EC=B8=A1=EC=A0=95=20=EB=AA=A8=EB=8B=88=ED=84=B0=20?=
 =?UTF-8?q?=EC=B6=94=EA=B0=80=20(#23)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 controllers/scheduleController.js | 115 +++++++++++++++++-------------
 1 file changed, 64 insertions(+), 51 deletions(-)

diff --git a/controllers/scheduleController.js b/controllers/scheduleController.js
index 0f45d89..8d19711 100644
--- a/controllers/scheduleController.js
+++ b/controllers/scheduleController.js
@@ -1,6 +1,7 @@
 // controllers/scheduleController.js
 const ScheduleService = require('../services/scheduleService');
 const ScheduleRequestDTO = require('../dtos/ScheduleRequestDTO');
+const performanceMonitor = require('../utils/performanceMonitor');
 
 class scheduleController {
     /**
@@ -21,20 +22,21 @@ class scheduleController {
      */
     async createSchedule(req, res) {
         try {
-            const userId = req.user.id;
-            const scheduleRequestDTO = new ScheduleRequestDTO(req.body);
-            const validatedData = scheduleRequestDTO.validate('create');
+            return await performanceMonitor.measureAsync('createSchedule', async () => {
+                const userId = 49;
+                // const userId = req.user.id;
+                const scheduleRequestDTO = new ScheduleRequestDTO(req.body);
+                const validatedData = scheduleRequestDTO.validate('create');
 
-            const schedule = await ScheduleService.createSchedules({
-                userId,
-                ...validatedData
-            });
+                const schedule = await ScheduleService.createSchedules({
+                    userId,
+                    ...validatedData
+                });
 
-            return res.status(201).json({
-                success: true,
-                data: {
-                    schedule
-                }
+                return res.status(201).json({
+                    success: true,
+                    data: { schedule }
+                });
             });
         } catch (error) {
             return res.status(400).json({
@@ -61,17 +63,18 @@ class scheduleController {
      */
     async updateSchedules(req, res) {
         try {
-            const userId = req.user.id;
-            const scheduleRequestDTO = new ScheduleRequestDTO(req.body);
-            const validatedData = scheduleRequestDTO.validate('bulk_update');
-
-            const updatedSchedule = await ScheduleService.updateSchedules(userId, validatedData);
-            
-            return res.status(200).json({
-                success: true,
-                data: {
-                    schedule: updatedSchedule
-                }
+            return await performanceMonitor.measureAsync('updateSchedules', async () => {
+                // const userId = req.user.id;
+                const userId = 49;
+                const scheduleRequestDTO = new ScheduleRequestDTO(req.body);
+                const validatedData = scheduleRequestDTO.validate('bulk_update');
+
+                const updatedSchedule = await ScheduleService.updateSchedules(userId, validatedData);
+
+                return res.status(200).json({
+                    success: true,
+                    data: { schedule: updatedSchedule }
+                });
             });
         } catch (error) {
             if (error.message === 'Schedule not found') {
@@ -104,17 +107,22 @@ class scheduleController {
      */
     async deleteSchedules(req, res) {
         try {
-            const userId = req.user.id;
-            const scheduleRequestDTO = new ScheduleRequestDTO(req.body);
-            const validatedData = scheduleRequestDTO.validate('bulk_delete');
-            const result = await ScheduleService.deleteSchedules(userId, validatedData.title);
-
-            return res.status(200).json({
-                success: true,
-                data: {
-                    message: 'Schedule successfully deleted',
-                    deletedCount: result.deletedCount
-                }
+            return await performanceMonitor.measureAsync('deleteSchedules', async () => {
+                // const userId = req.user.id;
+                const userId = 49;
+
+                const scheduleRequestDTO = new ScheduleRequestDTO(req.body);
+                const validatedData = scheduleRequestDTO.validate('bulk_delete');
+
+                const result = await ScheduleService.deleteSchedules(userId, validatedData.title);
+
+                return res.status(200).json({
+                    success: true,
+                    data: {
+                        message: 'Schedule successfully deleted',
+                        deletedCount: result.deletedCount
+                    }
+                });
             });
         } catch (error) {
             return res.status(404).json({
@@ -132,14 +140,16 @@ class scheduleController {
      */
     async getAllSchedules(req, res) {
         try {
-            const userId = req.user.id;
-            const schedules = await ScheduleService.getAllSchedules(userId);
+            return await performanceMonitor.measureAsync('getAllSchedules', async () => {
+                // const userId = req.user.id;
+                const userId = 49;
 
-            return res.status(200).json({
-                success: true,
-                data: {
-                    schedules
-                }
+                const schedules = await ScheduleService.getAllSchedules(userId);
+
+                return res.status(200).json({
+                    success: true,
+                    data: { schedules }
+                });
             });
         } catch (error) {
             return res.status(500).json({
@@ -159,18 +169,21 @@ class scheduleController {
      */
     async getScheduleByTimeIdx(req, res) {
         try {
-            const { time_idx } = req.params;
-            const userId = req.user.id;
+            return await performanceMonitor.measureAsync('getScheduleByTimeIdx', async () => {
+                const { time_idx } = req.params;
+                // const userId = req.user.id;
+                const userId = 49;
 
-            const scheduleRequestDTO = new ScheduleRequestDTO({ time_idx: parseInt(time_idx, 10) });
-            const validatedData = scheduleRequestDTO.validate('get_by_time_idx');
-            const schedule = await ScheduleService.getScheduleByTimeIdx(userId, validatedData.time_idx);
+                
+                const scheduleRequestDTO = new ScheduleRequestDTO({ time_idx: parseInt(time_idx, 10) });
+                const validatedData = scheduleRequestDTO.validate('get_by_time_idx');
 
-            return res.status(200).json({
-                success: true,
-                data: {
-                    schedule
-                }
+                const schedule = await ScheduleService.getScheduleByTimeIdx(userId, validatedData.time_idx);
+
+                return res.status(200).json({
+                    success: true,
+                    data: { schedule }
+                });
             });
         } catch (error) {
             if (error.message === 'Schedule not found') {
-- 
GitLab


From 7d66ec50a5c42bf230505539291678a99e4cb7ab 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: Fri, 6 Dec 2024 10:15:40 +0900
Subject: [PATCH 28/61] =?UTF-8?q?refactor:=20=EA=B0=9C=EB=B3=84=20?=
 =?UTF-8?q?=EC=A1=B0=ED=9A=8C/=EC=83=9D=EC=84=B1=20->=20=EB=8B=A8=EC=9D=BC?=
 =?UTF-8?q?=20=EC=BF=BC=EB=A6=AC/=EB=B2=8C=ED=81=AC=20=EC=B2=98=EB=A6=AC?=
 =?UTF-8?q?=20(#23)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 services/scheduleService.js | 80 ++++++++++++++++++++-----------------
 1 file changed, 43 insertions(+), 37 deletions(-)

diff --git a/services/scheduleService.js b/services/scheduleService.js
index abfb66e..5a6bcac 100644
--- a/services/scheduleService.js
+++ b/services/scheduleService.js
@@ -10,34 +10,46 @@ class ScheduleService {
      * @param {object} [transaction] - Sequelize �몃옖��뀡 媛앹껜 -> 誘명똿諛⑹뿉�� �곌린�꾪빐 �몃옖��뀡�� �섍꺼諛쏅뒗嫄� 異붽� 
      */
     async createSchedules({ userId, title, is_fixed, time_indices }, transaction = null) {
-        // 以묐났 寃���
-        for (const time_idx of time_indices) {
-            const overlap = await this.checkScheduleOverlap(userId, time_idx, transaction);
-            if (overlap) {
-                throw new Error(`Schedule overlaps at time_idx ${time_idx}`);
-            }
-        }
+        const overlaps = await Schedule.findAll({
+            where: {
+                user_id: userId,
+                time_idx: {
+                    [Op.in]: time_indices
+                }
+            },
+            transaction
+        });
 
-        const createdSchedules = await Promise.all(
-            time_indices.map(time_idx =>
-                Schedule.create({
-                    user_id: userId,
-                    title,
-                    time_idx,
-                    is_fixed
-                }, { transaction })
-            )
-        );
+        if (overlaps.length > 0) {
+            throw new Error(`Schedule overlaps at time_idx ${overlaps[0].time_idx}`);
+        }
 
-        return {
-            id: createdSchedules[0].id,
+        const scheduleData = time_indices.map(time_idx => ({
             user_id: userId,
             title,
-            is_fixed,
-            time_indices,
-            createdAt: createdSchedules[0].createdAt,
-            updatedAt: createdSchedules[0].updatedAt
-        };
+            time_idx,
+            is_fixed
+        }));
+
+        try {
+            const createdSchedules = await Schedule.bulkCreate(scheduleData, {
+                transaction,
+                returning: true,
+                validate: true
+            });
+
+            return {
+                id: createdSchedules[0].id,
+                user_id: userId,
+                title,
+                is_fixed,
+                time_indices,
+                createdAt: createdSchedules[0].createdAt,
+                updatedAt: createdSchedules[0].updatedAt
+            };
+        } catch (error) {
+            throw new Error(`Failed to bulk create schedules: ${error.message}`);
+        }
     }
 
     async getAllSchedules(userId) {
@@ -157,25 +169,19 @@ class ScheduleService {
      */
     async getScheduleByTimeIdx(userId, time_idx) {
         // �대떦 time_idx�� �ㅼ�以� 李얘린
-        const schedule = await Schedule.findOne({
-            where: { user_id: userId, time_idx }
-        });
-
-        if (!schedule) {
-            throw new Error('Schedule not found');
-        }
-
-        // 媛숈� �쒕ぉ�� 紐⑤뱺 �ㅼ�以� 李얘린
-        const relatedSchedules = await Schedule.findAll({
+        const schedules = await Schedule.findAll({
             where: {
                 user_id: userId,
-                title: schedule.title,
-                is_fixed: schedule.is_fixed
+                title: {
+                    [Op.in]: sequelize.literal(
+                        `(SELECT title FROM Schedules WHERE user_id = ${userId} AND time_idx = ${time_idx})`
+                    )
+                }
             },
             order: [['time_idx', 'ASC']]
         });
 
-        return ScheduleResponseDTO.groupSchedules(relatedSchedules)[0];
+        return ScheduleResponseDTO.groupSchedules(schedules)[0];
     }
 
     async getAllSchedules(userId) {
-- 
GitLab


From ed7f0b532f5e733236673f46b9c2d4a3817851fc 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: Fri, 6 Dec 2024 10:20:48 +0900
Subject: [PATCH 29/61] =?UTF-8?q?refactor:=20=EC=97=85=EB=8D=B0=EC=9D=B4?=
 =?UTF-8?q?=ED=8A=B8=20=EB=B3=91=EB=A0=AC=20=EC=B2=98=EB=A6=AC=20=EB=B0=8F?=
 =?UTF-8?q?=20=EB=B2=8C=ED=81=AC=20=EC=B2=98=EB=A6=AC=20(#23)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 services/scheduleService.js | 104 +++++++++++++++++++++---------------
 1 file changed, 62 insertions(+), 42 deletions(-)

diff --git a/services/scheduleService.js b/services/scheduleService.js
index 5a6bcac..6c66d7f 100644
--- a/services/scheduleService.js
+++ b/services/scheduleService.js
@@ -67,80 +67,100 @@ class ScheduleService {
 
     async updateSchedules(userId, updates, transaction = null) {
         const { originalTitle, title, is_fixed, time_indices } = updates;
-
-        // 湲곗〈 �ㅼ�以� 議고쉶
-        const existingSchedules = await Schedule.findAll({
-            where: {
-                user_id: userId,
-                title: originalTitle
-            },
-            transaction
-        });
-
-        if (existingSchedules.length === 0) {
-            throw new Error('Schedule not found');
-        }
-
-        const existingTimeIndices = existingSchedules.map(s => s.time_idx); // 湲곗〈 �쒓컙��
-        const toDelete = existingTimeIndices.filter(idx => !time_indices.includes(idx)); // ��젣�� �쒓컙��
-        const toAdd = time_indices.filter(idx => !existingTimeIndices.includes(idx)); // 異붽��� �쒓컙��
         const t = transaction || await sequelize.transaction();
 
         try {
-            // ��젣
-            if (toDelete.length > 0) {
-                await Schedule.destroy({
+            // 湲곗〈 �ㅼ�以� 議고쉶
+            const [existingSchedule, existingSchedules] = await Promise.all([
+                Schedule.findOne({
                     where: {
                         user_id: userId,
-                        title: originalTitle,
-                        time_idx: {
-                            [Op.in]: toDelete
-                        }
+                        title: originalTitle
                     },
                     transaction: t
-                });
-            }
-
-            // �쒕ぉ, 怨좎젙/�좊룞 �낅뜲�댄듃
-            await Schedule.update(
-                {
-                    title,
-                    is_fixed
-                },
-                {
+                }),
+                Schedule.findAll({
+                    attributes: ['time_idx'],
                     where: {
                         user_id: userId,
                         title: originalTitle
                     },
                     transaction: t
-                }
+                })
+            ]);
+
+            if (!existingSchedule) {
+                throw new Error('Schedule not found');
+            }
+
+            const existingTimeIndices = existingSchedules.map(s => s.time_idx);
+            const toDelete = existingTimeIndices.filter(idx => !time_indices.includes(idx));
+            const toAdd = time_indices.filter(idx => !existingTimeIndices.includes(idx));
+
+            // 踰뚰겕 �곗궛
+            const operations = [];
+
+            // ��젣 �곗궛
+            if (toDelete.length > 0) {
+                operations.push(
+                    Schedule.destroy({
+                        where: {
+                            user_id: userId,
+                            title: originalTitle,
+                            time_idx: {
+                                [Op.in]: toDelete
+                            }
+                        },
+                        transaction: t
+                    })
+                );
+            }
+
+            // �낅뜲�댄듃 �곗궛
+            operations.push(
+                Schedule.update(
+                    { title, is_fixed },
+                    {
+                        where: {
+                            user_id: userId,
+                            title: originalTitle
+                        },
+                        transaction: t
+                    }
+                )
             );
 
-            // �덈줈�� time_indices 異붽�
+            // �앹꽦 �곗궛
             if (toAdd.length > 0) {
-                await Promise.all(
-                    toAdd.map(time_idx =>
-                        Schedule.create({
+                operations.push(
+                    Schedule.bulkCreate(
+                        toAdd.map(time_idx => ({
                             user_id: userId,
                             title,
                             time_idx,
                             is_fixed
-                        }, { transaction: t })
+                        })),
+                        {
+                            transaction: t,
+                            validate: true
+                        }
                     )
                 );
             }
 
+            await Promise.all(operations); // 蹂묐젹 泥섎━
+
             if (!transaction) {
                 await t.commit();
             }
 
             return {
-                id: existingSchedules[0].id,
+                id: existingSchedule.id,
                 user_id: userId,
                 title,
                 is_fixed,
                 time_indices,
-                createdAt: existingSchedules[0].createdAt,
+                createdAt: existingSchedule.createdAt,
                 updatedAt: new Date()
             };
 
-- 
GitLab


From ab89042f21d958b579c9f74539b399ab27df5cc9 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: Fri, 6 Dec 2024 10:29:22 +0900
Subject: [PATCH 30/61] =?UTF-8?q?fix:=20=EC=9E=98=EB=AA=BB=EB=90=9C=20?=
 =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95=20(#23)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app.js                            |  3 ---
 controllers/scheduleController.js | 19 +++++--------------
 2 files changed, 5 insertions(+), 17 deletions(-)

diff --git a/app.js b/app.js
index aace954..952e375 100644
--- a/app.js
+++ b/app.js
@@ -66,9 +66,6 @@ app.use('/api/chat', chatRoutes);
 const memberRoutes = require('./routes/memberRoute');
 app.use('/api/member', memberRoutes);
 
-const memberRoutes = require('./routes/performanceRoute');
-app.use('/api/performance', performanceRoutes);
-
 // �ㅼ�以� �대━�� 珥덇린��
 initScheduleCleaner();
 
diff --git a/controllers/scheduleController.js b/controllers/scheduleController.js
index 8d19711..0855a84 100644
--- a/controllers/scheduleController.js
+++ b/controllers/scheduleController.js
@@ -23,8 +23,7 @@ class scheduleController {
     async createSchedule(req, res) {
         try {
             return await performanceMonitor.measureAsync('createSchedule', async () => {
-                const userId = 49;
-                // const userId = req.user.id;
+                const userId = req.user.id;
                 const scheduleRequestDTO = new ScheduleRequestDTO(req.body);
                 const validatedData = scheduleRequestDTO.validate('create');
 
@@ -64,8 +63,7 @@ class scheduleController {
     async updateSchedules(req, res) {
         try {
             return await performanceMonitor.measureAsync('updateSchedules', async () => {
-                // const userId = req.user.id;
-                const userId = 49;
+                const userId = req.user.id;
                 const scheduleRequestDTO = new ScheduleRequestDTO(req.body);
                 const validatedData = scheduleRequestDTO.validate('bulk_update');
 
@@ -108,9 +106,7 @@ class scheduleController {
     async deleteSchedules(req, res) {
         try {
             return await performanceMonitor.measureAsync('deleteSchedules', async () => {
-                // const userId = req.user.id;
-                const userId = 49;
-
+                const userId = req.user.id;
                 const scheduleRequestDTO = new ScheduleRequestDTO(req.body);
                 const validatedData = scheduleRequestDTO.validate('bulk_delete');
 
@@ -141,9 +137,7 @@ class scheduleController {
     async getAllSchedules(req, res) {
         try {
             return await performanceMonitor.measureAsync('getAllSchedules', async () => {
-                // const userId = req.user.id;
-                const userId = 49;
-
+                const userId = req.user.id;
                 const schedules = await ScheduleService.getAllSchedules(userId);
 
                 return res.status(200).json({
@@ -171,10 +165,7 @@ class scheduleController {
         try {
             return await performanceMonitor.measureAsync('getScheduleByTimeIdx', async () => {
                 const { time_idx } = req.params;
-                // const userId = req.user.id;
-                const userId = 49;
-
-                
+                const userId = req.user.id;
                 const scheduleRequestDTO = new ScheduleRequestDTO({ time_idx: parseInt(time_idx, 10) });
                 const validatedData = scheduleRequestDTO.validate('get_by_time_idx');
 
-- 
GitLab


From b6cb0889230dbb1fa7accbc673388e1c888b9b5b Mon Sep 17 00:00:00 2001
From: Ubuntu <ubuntu@ip-172-31-1-27.ap-northeast-2.compute.internal>
Date: Fri, 6 Dec 2024 05:19:43 +0000
Subject: [PATCH 31/61] =?UTF-8?q?refactor:=EC=84=9C=EB=B2=84=20=20deploy?=
 =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=8F=99=EA=B8=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app.js      |   4 +-
 output.log  | 150 ++++++++++++++++++++++++++++++++++++++++++++++------
 weblog.log  |  25 ++-------
 wsServer.js |   4 +-
 4 files changed, 143 insertions(+), 40 deletions(-)

diff --git a/app.js b/app.js
index 7d6603c..bf3e839 100644
--- a/app.js
+++ b/app.js
@@ -19,7 +19,7 @@ app.use(morgan('dev'));  //濡쒓퉭��
 // CORS �ㅼ젙
 app.use(
   cors({
-    origin: 'https://yanawa.shop',
+    origin:[ process.env.FROENT_URL,'https://yanawa.shop'],
     methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
     allowedHeaders: ['Content-Type', 'Authorization'],
     credentials: true,
@@ -57,7 +57,7 @@ app.set('trust proxy', 1);
 console.log('MongoDB URI:', process.env.MONGO_URI);
 //�쇱슦�� �깅줉 
 const authRoutes = require('./routes/auth');
-app.use('/auth', authRoutes);
+app.use('/api/auth', authRoutes);
 
 const scheduleRoutes = require('./routes/schedule');
 app.use('/api/schedule', scheduleRoutes);
diff --git a/output.log b/output.log
index b18562f..d9136a9 100644
--- a/output.log
+++ b/output.log
@@ -1,15 +1,135 @@
-/home/ubuntu/webback/app.js:20
-<<<<<<< HEAD
-^^
-
-SyntaxError: Unexpected token '<<'
-    at internalCompileFunction (node:internal/vm:76:18)
-    at wrapSafe (node:internal/modules/cjs/loader:1283:20)
-    at Module._compile (node:internal/modules/cjs/loader:1328:27)
-    at Module._extensions..js (node:internal/modules/cjs/loader:1422:10)
-    at Module.load (node:internal/modules/cjs/loader:1203:32)
-    at Module._load (node:internal/modules/cjs/loader:1019:12)
-    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:128:12)
-    at node:internal/main/run_main_module:28:49
-
-Node.js v18.20.5
+MongoDB URI: mongodb+srv://admin:lim1234!!@goodmeeting.vkniz.mongodb.net/
+(node:77051) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(Use `node --trace-warnings ...` to show where the warning was created)
+(node:77051) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+�� MongoDB �곌껐 �깃났
+Rdb�곗씠�곕쿋�댁뒪 �곌껐 �깃났.
+紐⑤뱺 紐⑤뜽�� �깃났�곸쑝濡� �숆린�붾릺�덉뒿�덈떎.
+Server is running on 8080
+GET /api/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php 404 9.005 ms - 193
+GET / 404 2.052 ms - 139
+GET / 404 1.179 ms - 139
+GET / 404 1.045 ms - 139
+GET / 404 1.827 ms - 139
+GET / 404 1.101 ms - 139
+GET /download/powershell/ 404 1.186 ms - 159
+GET /get.php 404 0.895 ms - 146
+GET / 404 1.429 ms - 139
+GET /api/im/v2/app/config 404 1.289 ms - 159
+GET /api/ 404 1.099 ms - 143
+GET /api/ 404 1.036 ms - 143
+GET /api/c/a 404 0.920 ms - 146
+GET /api/ping 404 0.873 ms - 147
+GET /api/notice 404 0.902 ms - 149
+GET /api/config 404 0.936 ms - 149
+GET /api/version 404 0.871 ms - 150
+GET /api/v1/config 404 1.131 ms - 152
+GET /api/index/web 404 0.706 ms - 152
+GET /api/Business/ 404 0.752 ms - 152
+GET /api/shop/getKF 404 1.018 ms - 153
+GET /api/index/init 404 0.893 ms - 153
+GET /api/Event/basic 404 0.632 ms - 154
+GET /api/apps/config 404 0.583 ms - 154
+GET /api/front/index 404 0.941 ms - 154
+GET /api/app/indexList 404 0.850 ms - 156
+GET /api/common/config 404 0.784 ms - 156
+GET /api/Home/videoNew 404 2.733 ms - 156
+GET /api/getCustomLink 404 0.672 ms - 156
+GET /api/uploads/apimap 404 0.584 ms - 157
+GET /api/v1/member/kefu 404 0.642 ms - 157
+GET /api/config/getkefu 404 0.684 ms - 157
+GET /api/site/getInfo.do 404 0.667 ms - 158
+GET /api/message/webInfo 404 0.595 ms - 158
+GET /api/index/webconfig 404 0.703 ms - 158
+GET /api/index/getConfig 404 0.745 ms - 158
+GET /api/index/grailindex 404 0.931 ms - 159
+GET /api/shares/hqStrList 404 0.770 ms - 159
+GET /api/user/ismustmobile 404 0.753 ms - 160
+GET /api/user/ismustmobile 404 0.697 ms - 160
+GET /api/user/ismustmobile 404 0.616 ms - 160
+GET /api/banner?appKey=bxefdn 404 1.134 ms - 149
+GET /api/Config/getShowConfig 404 0.590 ms - 163
+GET /api/home/customerService 404 2.229 ms - 163
+GET /api/client/app/config.do 404 0.698 ms - 163
+GET /api/product/getPointStore 404 0.703 ms - 164
+GET /api/currency/quotation_new 404 0.751 ms - 165
+GET /api/vue/transaction/config 404 0.821 ms - 165
+GET /api/predict-whole-panel.do 404 0.800 ms - 165
+GET /api/common/menus?lang=zh-Hans 404 0.767 ms - 155
+GET /api/appVersion?mobile_system=2 404 0.711 ms - 153
+GET /api/public/?service=Home.getConfig 404 0.797 ms - 150
+GET /api/unSecurity/app/listAppVersionInfo 404 0.793 ms - 176
+GET /api/stock/getSingleStock.do?code=002405 404 0.739 ms - 166
+GET /api/system/systemConfigs/getCustomerServiceLink 404 0.780 ms - 186
+GET /api/v/index/queryOfficePage?officeCode=customHomeLink 404 0.805 ms - 166
+GET /api/im/v2/app/config 404 2.524 ms - 159
+GET /api/ 404 0.739 ms - 143
+GET /api/ 404 0.792 ms - 143
+GET /api/c/a 404 0.761 ms - 146
+GET /api/ping 404 0.715 ms - 147
+GET /api/config 404 0.930 ms - 149
+POST /api/notice 404 24.787 ms - 150
+GET /api/version 404 0.963 ms - 150
+GET /api/v1/config 404 0.761 ms - 152
+GET /api/Business/ 404 0.618 ms - 152
+GET /api/index/web 404 0.595 ms - 152
+GET /api/shop/getKF 404 0.747 ms - 153
+GET /api/Event/basic 404 0.612 ms - 154
+GET /api/front/index 404 0.620 ms - 154
+GET /api/index/init 404 0.647 ms - 153
+GET /api/apps/config 404 0.657 ms - 154
+GET /api/app/indexList 404 0.925 ms - 156
+GET /api/common/config 404 0.645 ms - 156
+GET /api/Home/videoNew 404 2.724 ms - 156
+POST /api/getCustomLink 404 13.160 ms - 157
+GET /api/v1/member/kefu 404 0.575 ms - 157
+GET /api/uploads/apimap 404 0.538 ms - 157
+GET /api/config/getkefu 404 0.724 ms - 157
+GET /api/site/getInfo.do 404 0.511 ms - 158
+GET /api/message/webInfo 404 0.683 ms - 158
+GET /api/index/webconfig 404 0.714 ms - 158
+GET /api/index/getConfig 404 0.676 ms - 158
+GET /api/index/grailindex 404 0.676 ms - 159
+GET /api/shares/hqStrList 404 0.590 ms - 159
+POST /api/user/ismustmobile 404 0.950 ms - 161
+GET /api/user/ismustmobile 404 0.558 ms - 160
+POST /api/user/ismustmobile 404 0.805 ms - 161
+GET /api/banner?appKey=bxefdn 404 0.834 ms - 149
+GET /api/Config/getShowConfig 404 0.621 ms - 163
+GET /api/client/app/config.do 404 0.643 ms - 163
+GET /api/home/customerService 404 0.613 ms - 163
+GET /api/product/getPointStore 404 0.842 ms - 164
+GET /api/currency/quotation_new 404 0.812 ms - 165
+GET /api/vue/transaction/config 404 0.669 ms - 165
+GET /api/predict-whole-panel.do 404 1.121 ms - 165
+GET /api/common/menus?lang=zh-Hans 404 0.788 ms - 155
+GET /api/appVersion?mobile_system=2 404 1.182 ms - 153
+GET /api/public/?service=Home.getConfig 404 0.590 ms - 150
+GET /api/unSecurity/app/listAppVersionInfo 404 0.642 ms - 176
+GET /api/stock/getSingleStock.do?code=002405 404 2.576 ms - 166
+POST /api/system/systemConfigs/getCustomerServiceLink 404 0.816 ms - 187
+GET /api/v/index/queryOfficePage?officeCode=customHomeLink 404 0.642 ms - 166
+GET http://example.com/ 404 2.861 ms - 139
+GET http://example.com/ 404 0.862 ms - 139
+GET / 404 0.856 ms - 139
+GET /favicon.ico 404 0.860 ms - 150
+GET / 404 0.899 ms - 139
+GET / 404 0.812 ms - 139
+GET /manage/account/login 404 0.807 ms - 159
+GET /admin/index.html 404 0.875 ms - 155
+GET /index.html 404 0.870 ms - 149
+GET /+CSCOE+/logon.html 404 0.831 ms - 157
+GET /cgi-bin/login.cgi 404 0.864 ms - 156
+GET /logon.htm 404 0.788 ms - 148
+GET /login.jsp 404 0.845 ms - 148
+GET /doc/index.html 404 0.922 ms - 153
+GET / 404 0.801 ms - 139
+GET / 404 0.818 ms - 139
+GET / 404 0.938 ms - 139
+GET / 404 1.083 ms - 139
+GET / 404 0.872 ms - 139
+GET / 404 0.892 ms - 139
+GET / 404 0.871 ms - 139
+GET /api/.env 404 0.821 ms - 147
+POST /api/.env 404 1.818 ms - 148
+GET /api/index.php/v1/config/application?public=true 404 0.739 ms - 174
diff --git a/weblog.log b/weblog.log
index c52b535..4038042 100644
--- a/weblog.log
+++ b/weblog.log
@@ -1,22 +1,5 @@
-(node:23273) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:77052) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 (Use `node --trace-warnings ...` to show where the warning was created)
-(node:23273) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
-MongoDB �곌껐 �ㅽ뙣: MongooseServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017
-    at _handleConnectionErrors (/home/ubuntu/webback/node_modules/mongoose/lib/connection.js:909:11)
-    at NativeConnection.openUri (/home/ubuntu/webback/node_modules/mongoose/lib/connection.js:860:11)
-    at async connectMongoDB (/home/ubuntu/webback/wsServer.js:28:5) {
-  reason: TopologyDescription {
-    type: 'Unknown',
-    servers: Map(1) { 'localhost:27017' => [ServerDescription] },
-    stale: false,
-    compatible: true,
-    heartbeatFrequencyMS: 10000,
-    localThresholdMS: 15,
-    setName: null,
-    maxElectionId: null,
-    maxSetVersion: null,
-    commonWireVersion: 0,
-    logicalSessionTimeoutMinutes: null
-  },
-  code: undefined
-}
+(node:77052) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+MongoDB�� �깃났�곸쑝濡� �곌껐�섏뿀�듬땲��.
+WebSocket 梨꾪똿 �쒕쾭媛� 8081 �ы듃�먯꽌 �ㅽ뻾 以묒엯�덈떎.
diff --git a/wsServer.js b/wsServer.js
index e938ef8..16e8bf6 100644
--- a/wsServer.js
+++ b/wsServer.js
@@ -25,7 +25,7 @@ let chatRooms = {};
 // MongoDB �곌껐 �ㅼ젙
 async function connectMongoDB() {
   try {
-    await mongoose.connect('mongodb://localhost:27017/chat', {
+    await mongoose.connect(process.env.MONGO_URI, {
       useNewUrlParser: true,
       useUnifiedTopology: true,
     });
@@ -354,4 +354,4 @@ function constructReply(message) {
 }
 
 // MongoDB �곌껐 �� WebSocket �쒕쾭 �쒖옉
-connectMongoDB();
\ No newline at end of file
+connectMongoDB();
-- 
GitLab


From 271223300b0cfb6e0524ddf8065d008e19bd7356 Mon Sep 17 00:00:00 2001
From: Ubuntu <ubuntu@ip-172-31-1-27.ap-northeast-2.compute.internal>
Date: Fri, 6 Dec 2024 05:20:58 +0000
Subject: [PATCH 32/61] =?UTF-8?q?refactor:=EC=84=9C=EB=B2=84=20=20deploy?=
 =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=8F=99=EA=B8=B0=ED=99=94?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .gitignore | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/.gitignore b/.gitignore
index e8b5752..c95fa60 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,7 @@ node_modules/
 .env
 config.json/
 resources/
+app.js
+output.log
+weblog.log
+
-- 
GitLab


From e5b466ab4f8d7bf5ef27aea743fa5d5b0ff5ef57 Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Fri, 6 Dec 2024 16:15:43 +0900
Subject: [PATCH 33/61] =?UTF-8?q?feature:=20=EC=84=B8=EC=85=98=EC=83=81?=
 =?UTF-8?q?=ED=83=9C=20=ED=99=95=EC=9D=B8=ED=95=98=EB=8A=94=20=EB=9D=BC?=
 =?UTF-8?q?=EC=9A=B0=ED=84=B0=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app.js            | 3 +++
 routes/session.js | 0
 2 files changed, 3 insertions(+)
 create mode 100644 routes/session.js

diff --git a/app.js b/app.js
index bf3e839..0bbd702 100644
--- a/app.js
+++ b/app.js
@@ -74,6 +74,9 @@ app.use('/api/chat', chatRoutes);
 const memberRoutes = require('./routes/memberRoute');
 app.use('/api/member', memberRoutes);
 
+const sessionRouter = require('./routes/session');
+app.use('/api/session', sessionRouter);
+
 // �ㅼ�以� �대━�� 珥덇린��
 initScheduleCleaner();
 
diff --git a/routes/session.js b/routes/session.js
new file mode 100644
index 0000000..e69de29
-- 
GitLab


From 6e6a6531427221422d4b1bf2e896486d18e63902 Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Fri, 6 Dec 2024 16:18:42 +0900
Subject: [PATCH 34/61] =?UTF-8?q?feature:=20=EC=84=B8=EC=85=98=EC=83=81?=
 =?UTF-8?q?=ED=83=9C=20=ED=99=95=EC=9D=B8=ED=95=98=EB=8A=94=20=EB=9D=BC?=
 =?UTF-8?q?=EC=9A=B0=ED=84=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 routes/session.js | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/routes/session.js b/routes/session.js
index e69de29..09178cf 100644
--- a/routes/session.js
+++ b/routes/session.js
@@ -0,0 +1,23 @@
+const express = require('express');
+const router = express.Router();
+
+// GET /api/session/info
+router.get('/info', (req, res) => {
+  if (req.session && req.session.user) {
+    const { email, name } = req.session.user;
+
+    return res.status(200).json({
+      user: {
+        email,
+        name,
+      },
+    });
+  }
+
+  // �몄뀡�� 留뚮즺�섏뿀嫄곕굹 �ъ슜�� �뺣낫媛� �녿뒗 寃쎌슦
+  res.status(401).json({
+    message: '�몄뀡�� 留뚮즺�섏뿀嫄곕굹 �ъ슜�� �뺣낫媛� �놁뒿�덈떎.',
+  });
+});
+
+module.exports = router;
-- 
GitLab


From f201437a0e7b3baee7f1156865f0f1e1f16f18ec Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Fri, 6 Dec 2024 17:03:20 +0900
Subject: [PATCH 35/61] =?UTF-8?q?refactor:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?=
 =?UTF-8?q?=20=EC=B2=98=EB=A6=AC=EB=B0=A9=EC=8B=9D=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 routes/auth.js | 32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/routes/auth.js b/routes/auth.js
index 576d376..f7a418b 100644
--- a/routes/auth.js
+++ b/routes/auth.js
@@ -5,34 +5,38 @@ const router = express.Router();
 
 // GET api/auth/login
 router.get('/login', (req, res, next) => {
-  // �꾨줎�몄뿏�쒖뿉�� �꾨떖�� redirectUrl 媛��몄삤湲�
-  const redirectUrl = req.query.redirectUrl || process.env.FRONTEND_URL || 'https://yanawa.shop';
-	  // redirectUrl �좏슚�� 寃�利�
-
-  // redirectUrl �몄뀡�� ����
-  req.session.redirectUrl = redirectUrl;
-
-  // Google OAuth �몄쬆 �쒖옉
   passport.authenticate('google', { scope: ['profile', 'email'] })(req, res, next);
 });
 router.get(
   '/google/callback',
   passport.authenticate('google', { failureRedirect: '/auth/login' }),
   (req, res) => {
-    const redirectUrl = req.session.redirectUrl || 'https://yanawa.shop';
-
-
-    req.session.redirectUrl = null;
-
+    const redirectUrl = process.env.FRONT_URL;
     req.session.save((err) => {
       if (err) {
         console.error('�몄뀡 ���� �ㅻ쪟:', err);
         return res.status(500).json({ error: '�쒕쾭 �ㅻ쪟' });
       }
-
       res.redirect(redirectUrl);
     });
   }
 );
+// GET api/auth/logout
+router.get('/logout', (req, res) => {
+  if (req.session) {
+    req.session.destroy((err) => {
+      if (err) {
+        console.error('�몄뀡 ��젣 �ㅻ쪟:', err);
+        return res.status(500).json({ error: '�쒕쾭 �ㅻ쪟' });
+      }
+      const redirectUrl = process.env.FRONT_URL;
+      res.redirect(redirectUrl);
+    });
+  } else {
+    // �몄뀡�� �녿뒗 寃쎌슦�먮룄 由щ떎�대젆��
+    const redirectUrl = process.env.FRONT_URL;
+    res.redirect(redirectUrl);
+  }
+});
 
 module.exports = router;
-- 
GitLab


From fe3b8ae84342bd2dd27c4c0ef97631d064241b21 Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Sat, 7 Dec 2024 15:49:10 +0900
Subject: [PATCH 36/61] =?UTF-8?q?refactor:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?=
 =?UTF-8?q?=20=EC=8B=A4=ED=8C=A8=20=EB=A6=AC=EB=8B=A4=EC=9D=B4=EB=A0=89?=
 =?UTF-8?q?=ED=8A=B8=20=EA=B2=BD=EB=A1=9C=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 routes/auth.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/routes/auth.js b/routes/auth.js
index f7a418b..09174ab 100644
--- a/routes/auth.js
+++ b/routes/auth.js
@@ -5,7 +5,7 @@ const router = express.Router();
 
 // GET api/auth/login
 router.get('/login', (req, res, next) => {
-  passport.authenticate('google', { scope: ['profile', 'email'] })(req, res, next);
+  passport.authenticate('google', { failureRedirect: `${process.env.FRONT_URL}/login` }),
 });
 router.get(
   '/google/callback',
-- 
GitLab


From 96421e2ea2d6734f3762f07fc7abbfbbbf996d04 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: Sat, 7 Dec 2024 13:34:56 +0900
Subject: [PATCH 37/61] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=ED=83=88?=
 =?UTF-8?q?=ED=87=B4=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9D=BC,=20=EB=9D=BC?=
 =?UTF-8?q?=EC=9A=B0=ED=8A=B8,=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=B6=94?=
 =?UTF-8?q?=EA=B0=80=20(#23)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 controllers/meetingController.js | 23 ++++++++++++-----------
 routes/meetingRoute.js           |  7 +++++--
 services/meetingService.js       |  5 ++++-
 3 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/controllers/meetingController.js b/controllers/meetingController.js
index 6624622..9642db6 100644
--- a/controllers/meetingController.js
+++ b/controllers/meetingController.js
@@ -116,20 +116,21 @@ class MeetingController {
             res.status(500).json({ error: err.message || '紐⑥엫 �곸꽭 議고쉶 �ㅽ뙣' });
         }
     }
-    /*
-    Delete /api/meetings/:meetingId
-    */
-    async closeMeeting(req,res)
-    {
-    
+
+    /**
+     * 踰덇컻 紐⑥엫 �덊눜
+     * DELETE /api/meeting/:meetingId/leave
+     */
+    async leaveMeeting(req, res) {
         const { meetingId } = req.params;
-        const userid=req.user.id;  
+        const userId = req.user.id;
+        
         try {
-            const meetingDetail = await MeetingService.leaveMeeting(meetingId,userId);
-            res.status(200).json('紐⑥엫 ��젣�깃났!');
+            await MeetingService.leaveMeeting(meetingId, userId);
+            res.status(200).json({ message: '紐⑥엫 �덊눜 �깃났' }); 
         } catch (err) {
-            console.error('紐⑥엫 ��젣 �ㅻ쪟', err);
-            res.status(500).json({ error: err.message || '紐⑥엫��젣 �ㅽ뙣' });
+            console.error('紐⑥엫 �덊눜 �ㅻ쪟:', err);
+            res.status(500).json({ error: err.message || '紐⑥엫 �덊눜 �ㅽ뙣' });
         }
     }
 
diff --git a/routes/meetingRoute.js b/routes/meetingRoute.js
index a2788ca..af2ac33 100644
--- a/routes/meetingRoute.js
+++ b/routes/meetingRoute.js
@@ -2,10 +2,10 @@
 
 const express = require('express');
 const router = express.Router();
-const { isLoggedIn } = require('../middlewares/auth');
+// const { isLoggedIn } = require('../middlewares/auth');
 const MeetingController = require('../controllers/meetingController');
 
-router.use(isLoggedIn);
+// router.use(isLoggedIn);
 
 // 踰덇컻 紐⑥엫 �앹꽦
 router.post('/', MeetingController.createMeeting);
@@ -22,4 +22,7 @@ router.post('/:meetingId/join', MeetingController.joinMeeting);
 // 踰덇컻 紐⑥엫 �곸꽭 議고쉶
 router.get('/:meetingId', MeetingController.getMeetingDetail);
 
+// 踰덇컻 紐⑥엫 �덊눜
+router.delete('/:meetingId/leave', MeetingController.leaveMeeting);
+
 module.exports = router;
\ No newline at end of file
diff --git a/services/meetingService.js b/services/meetingService.js
index 746597d..746bcf1 100644
--- a/services/meetingService.js
+++ b/services/meetingService.js
@@ -598,7 +598,10 @@ class MeetingService {
             });
             if (chatRoom) {
                 const user = await User.findByPk(userId);
-                chatRoom.participants = chatRoom.participants.filter(p => p !== user.name);
+                chatRoom.participants = chatRoom.participants.filter(p => p.name !== user.name);
+                chatRoom.isOnline.delete(user.name);
+                chatRoom.lastReadAt.delete(user.name);
+                chatRoom.lastReadLogId.delete(user.name);
                 await chatRoom.save();
             }
     
-- 
GitLab


From 5b1f63035b82f9ec0d8ff93fdc787aa561ad0743 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: Sat, 7 Dec 2024 13:43:32 +0900
Subject: [PATCH 38/61] =?UTF-8?q?feat:=20=EB=82=B4=EA=B0=80=20=EC=B0=B8?=
 =?UTF-8?q?=EC=97=AC=ED=95=9C=20=EB=AF=B8=ED=8C=85=20=EC=A1=B0=ED=9A=8C=20?=
 =?UTF-8?q?=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC,=20=EB=9D=BC=EC=9A=B0?=
 =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80=20(#23)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 controllers/meetingController.js | 35 ++++++++++++++++++++++++++++++--
 routes/meetingRoute.js           |  7 +++++--
 2 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/controllers/meetingController.js b/controllers/meetingController.js
index 9642db6..78f4464 100644
--- a/controllers/meetingController.js
+++ b/controllers/meetingController.js
@@ -117,6 +117,37 @@ class MeetingController {
         }
     }
 
+    /**
+     * �닿� 李몄뿬�� 紐⑥엫 紐⑸줉 議고쉶
+     * GET /api/meetings/my
+     */
+    async getMyMeetings(req, res) {
+        try {
+            const userId = req.user.id;
+            const page = parseInt(req.query.page) || 0;
+            const size = parseInt(req.query.size) || 20;
+
+            const meetings = await MeetingService.getMyMeetings(userId, {
+                limit: size,
+                offset: page * size
+            });
+
+            res.status(200).json({
+                success: true,
+                data: {
+                    content: meetings.content,
+                    page: page,
+                    size: size,
+                    hasNext: meetings.hasNext
+                }
+            });
+        } catch (err) {
+            console.error('�� 紐⑥엫 紐⑸줉 議고쉶 �ㅻ쪟:', err);
+            res.status(500).json({ error: err.message || '�� 紐⑥엫 紐⑸줉 議고쉶 �ㅽ뙣' });
+        }
+    }
+
+
     /**
      * 踰덇컻 紐⑥엫 �덊눜
      * DELETE /api/meeting/:meetingId/leave
@@ -124,10 +155,10 @@ class MeetingController {
     async leaveMeeting(req, res) {
         const { meetingId } = req.params;
         const userId = req.user.id;
-        
+
         try {
             await MeetingService.leaveMeeting(meetingId, userId);
-            res.status(200).json({ message: '紐⑥엫 �덊눜 �깃났' }); 
+            res.status(200).json({ message: '紐⑥엫 �덊눜 �깃났' });
         } catch (err) {
             console.error('紐⑥엫 �덊눜 �ㅻ쪟:', err);
             res.status(500).json({ error: err.message || '紐⑥엫 �덊눜 �ㅽ뙣' });
diff --git a/routes/meetingRoute.js b/routes/meetingRoute.js
index af2ac33..9d2e26f 100644
--- a/routes/meetingRoute.js
+++ b/routes/meetingRoute.js
@@ -2,10 +2,10 @@
 
 const express = require('express');
 const router = express.Router();
-// const { isLoggedIn } = require('../middlewares/auth');
+const { isLoggedIn } = require('../middlewares/auth');
 const MeetingController = require('../controllers/meetingController');
 
-// router.use(isLoggedIn);
+router.use(isLoggedIn);
 
 // 踰덇컻 紐⑥엫 �앹꽦
 router.post('/', MeetingController.createMeeting);
@@ -25,4 +25,7 @@ router.get('/:meetingId', MeetingController.getMeetingDetail);
 // 踰덇컻 紐⑥엫 �덊눜
 router.delete('/:meetingId/leave', MeetingController.leaveMeeting);
 
+// �닿� 李몄뿬�� 紐⑥엫 紐⑸줉 議고쉶
+router.get('/my', MeetingController.getMyMeetings);
+
 module.exports = router;
\ No newline at end of file
-- 
GitLab


From 3245c633eadc602d6c66b9294b391f65882e74f8 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: Sat, 7 Dec 2024 18:07:30 +0900
Subject: [PATCH 39/61] =?UTF-8?q?refactor:=20=EC=B9=9C=EA=B5=AC=20?=
 =?UTF-8?q?=EC=9A=94=EC=B2=AD=20=EB=B3=B4=EB=82=B4=EA=B8=B0=20req=20?=
 =?UTF-8?q?=EC=88=98=EC=A0=95=20(#23)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 controllers/friendController.js | 168 +++++++++++++++++---------------
 services/friendService.js       |   2 +-
 2 files changed, 88 insertions(+), 82 deletions(-)

diff --git a/controllers/friendController.js b/controllers/friendController.js
index ce50caf..09cbf57 100644
--- a/controllers/friendController.js
+++ b/controllers/friendController.js
@@ -1,53 +1,59 @@
 const FriendService = require('../services/friendService');
 const { User } = require('../models');
+const performanceMonitor = require('../utils/performanceMonitor');
 
 class friendController {
-        /**
-         * 移쒓뎄 �붿껌 蹂대궡湲�
-         * �대씪�댁뼵�몃뒗 userId�� �붿껌�� 蹂대궪 �ъ슜�먯쓽 email�� �꾩넚
-         */
-        async sendFriendRequest(req, res, next) {
-            const { userId, email } = req.body;
-    
-            try {
+    /**
+     * 移쒓뎄 �붿껌 蹂대궡湲�
+     * �대씪�댁뼵�몃뒗 userId�� �붿껌�� 蹂대궪 �ъ슜�먯쓽 email�� �꾩넚
+     * POST /api/friend/request
+     * 
+     */
+    async sendFriendRequest(req, res) {
+        try {
+            return await performanceMonitor.measureAsync('sendFriendRequest', async () => {
+                const email  = req.body;
+                const userId = req.user.id;
 
                 if (!userId || !email) {
-                    return res.status(400).json({ message: 'userId�� email�� �꾩닔 �낅젰 ��ぉ�낅땲��.' });
+                    throw new Error('userId�� email�� �꾩닔 �낅젰 ��ぉ�낅땲��.');
                 }
-                // 移쒓뎄 �붿껌�� 諛쏆쓣 �ъ슜�먯쓽 �뺣낫 議고쉶 (�쒕퉬�ㅻ줈 遺꾨━�좎� �앷컖)
-                const receiver = await User.findOne({ where: { email: email } });
+
+                const receiver = await User.findOne({ where: { email } });
                 if (!receiver) {
-                    return res.status(404).json({ message: '�붿껌�� 諛쏆쓣 �ъ슜�먮� 李얠쓣 �� �놁뒿�덈떎.' });
+                    throw new Error('�붿껌�� 諛쏆쓣 �ъ슜�먮� 李얠쓣 �� �놁뒿�덈떎.');
                 }
-                const friendId = receiver.id;
-                // 移쒓뎄 �붿껌 蹂대궡湲� �쒕퉬�� �몄텧
-                const friendRequest = await FriendService.sendFriendRequest(userId, friendId);
+
+                const friendRequest = await FriendService.sendFriendRequest(userId, receiver.id);
                 return res.status(201).json({
-                    success:true,
-                    data:friendRequest
+                    success: true,
+                    data: friendRequest
                 });
-            } catch (error) {
-                // �좊땲�� �쒖빟議곌굔 �ㅻ쪟 泥섎━
-                if (error.message === 'Friend request already exists') {
-                    return res.status(409).json({ message: error.message });
+            });
+        } catch (error) {
+            return res.status(error.status || 500).json({
+                success: false,
+                error: {
+                    message: error.message,
+                    code: 'FRIEND_REQUEST_ERROR'
                 }
-
-                // �쇰컲 �ㅻ쪟 泥섎━
-                return res.status(500).json({ message: '�쒕쾭 �ㅻ쪟媛� 諛쒖깮�덉뒿�덈떎.', error: error.message });
-            }
+            });
         }
+    }
+
     /**
      * 諛쏆� 移쒓뎄 �붿껌 紐⑸줉 議고쉶
      * GET /api/friend/requests/received
      */
     async getReceivedRequests(req, res) {
         try {
-            const userId = req.user.id;
-            const requests = await FriendService.getReceivedRequests(userId);
-
-            return res.status(200).json({
-                success: true,
-                data: requests
+            return await performanceMonitor.measureAsync('getReceivedRequests', async () => {
+                const userId = req.user.id;
+                const requests = await FriendService.getReceivedRequests(userId);
+                return res.status(200).json({
+                    success: true,
+                    data: requests
+                });
             });
         } catch (error) {
             return res.status(500).json({
@@ -66,12 +72,13 @@ class friendController {
      */
     async getSentRequests(req, res) {
         try {
-            const userId = req.user.id;
-            const requests = await FriendService.getSentRequests(userId);
-
-            return res.status(200).json({
-                success: true,
-                data: requests
+            return await performanceMonitor.measureAsync('getSentRequests', async () => {
+                const userId = req.user.id;
+                const requests = await FriendService.getSentRequests(userId);
+                return res.status(200).json({
+                    success: true,
+                    data: requests
+                });
             });
         } catch (error) {
             return res.status(500).json({
@@ -83,21 +90,21 @@ class friendController {
             });
         }
     }
-    
     /**
      * 移쒓뎄 �붿껌 �섎씫
      * POST /api/friend/request/:friendId/accept
      */
     async acceptRequest(req, res) {
         try {
-            const userId = req.user.id;
-            const { friendId } = req.params;
-
-            const result = await FriendService.acceptFriendRequest(userId, friendId);
-
-            return res.status(200).json({
-                success: true,
-                data: result
+            return await performanceMonitor.measureAsync('acceptFriendRequest', async () => {
+                const userId = req.user.id;
+                const { friendId } = req.params;
+
+                const result = await FriendService.acceptFriendRequest(userId, friendId);
+                return res.status(200).json({
+                    success: true,
+                    data: result
+                });
             });
         } catch (error) {
             return res.status(400).json({
@@ -116,14 +123,15 @@ class friendController {
      */
     async rejectRequest(req, res) {
         try {
-            const userId = req.user.id;
-            const { friendId } = req.params;
-
-            const result = await FriendService.rejectFriendRequest(userId, friendId);
-
-            return res.status(200).json({
-                success: true,
-                data: result
+            return await performanceMonitor.measureAsync('rejectFriendRequest', async () => {
+                const userId = req.user.id;
+                const { friendId } = req.params;
+
+                const result = await FriendService.rejectFriendRequest(userId, friendId);
+                return res.status(200).json({
+                    success: true,
+                    data: result
+                });
             });
         } catch (error) {
             return res.status(400).json({
@@ -142,23 +150,20 @@ class friendController {
      */
     async getFriendList(req, res) {
         try {
-            const userId = req.user.id;
-            const page = parseInt(req.query.page) || 0;
-            const size = parseInt(req.query.size) || 20;
-            
-            const friends = await FriendService.getFriendList(userId, {
-                limit: size,
-                offset: page * size
-            });
+            return await performanceMonitor.measureAsync('getFriendList', async () => {
+                const userId = req.user.id;
+                const page = parseInt(req.query.page) || 0;
+                const size = parseInt(req.query.size) || 20;
+
+                const friends = await FriendService.getFriendList(userId, {
+                    limit: size,
+                    offset: page * size
+                });
 
-            return res.status(200).json({
-                success: true,
-                data: {
-                    content: friends,
-                    page: page,
-                    size: size,
-                    hasNext: friends.length === size 
-                }
+                return res.status(200).json({
+                    success: true,
+                    data: friends
+                });
             });
         } catch (error) {
             return res.status(500).json({
@@ -177,17 +182,18 @@ class friendController {
      */
     async deleteFriend(req, res) {
         try {
-            const userId = req.user.id;
-            const { friendId } = req.params;
-
-            const result = await FriendService.deleteFriend(userId, friendId);
-
-            return res.status(200).json({
-                success: true,
-                data: {
-                    message: 'Friend deleted successfully',
-                    result: result
-                }
+            return await performanceMonitor.measureAsync('deleteFriend', async () => {
+                const userId = req.user.id;
+                const { friendId } = req.params;
+
+                const result = await FriendService.deleteFriend(userId, friendId);
+                return res.status(200).json({
+                    success: true,
+                    data: {
+                        message: 'Friend deleted successfully',
+                        result: result
+                    }
+                });
             });
         } catch (error) {
             return res.status(400).json({
diff --git a/services/friendService.js b/services/friendService.js
index 4d61554..5e16524 100644
--- a/services/friendService.js
+++ b/services/friendService.js
@@ -210,7 +210,7 @@ class FriendService {
                 }
             ],
             order: [['id', 'ASC']],
-            limit: limit + 1, // �ㅼ쓬 �섏씠吏� 議댁옱 �щ� �뺤씤�� �꾪빐 1媛� �� 議고쉶
+            limit: limit + 1, 
             offset
         });
     
-- 
GitLab


From afe94b50e9cec4e234a67dfa9d08790c52c5f355 Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Sat, 7 Dec 2024 19:32:34 +0900
Subject: [PATCH 40/61] =?UTF-8?q?bugfix:=20=EB=9D=BC=EC=9A=B0=ED=84=B0?=
 =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 routes/auth.js | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/routes/auth.js b/routes/auth.js
index 09174ab..3df3214 100644
--- a/routes/auth.js
+++ b/routes/auth.js
@@ -4,9 +4,12 @@ const passport = require('passport');
 const router = express.Router();
 
 // GET api/auth/login
-router.get('/login', (req, res, next) => {
-  passport.authenticate('google', { failureRedirect: `${process.env.FRONT_URL}/login` }),
-});
+router.get('/login', 
+  passport.authenticate('google', { 
+    failureRedirect: `${process.env.FRONT_URL}/login` 
+  })
+);
+
 router.get(
   '/google/callback',
   passport.authenticate('google', { failureRedirect: '/auth/login' }),
-- 
GitLab


From 8200e5af0884036c8564cb6c897af622255c1642 Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Sat, 7 Dec 2024 19:39:27 +0900
Subject: [PATCH 41/61] =?UTF-8?q?bugfix:=20=EB=9D=BC=EC=9A=B0=ED=84=B0?=
 =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 routes/auth.js | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/routes/auth.js b/routes/auth.js
index 3df3214..2eb8e9a 100644
--- a/routes/auth.js
+++ b/routes/auth.js
@@ -3,16 +3,21 @@ const passport = require('passport');
 
 const router = express.Router();
 
-// GET api/auth/login
-router.get('/login', 
-  passport.authenticate('google', { 
-    failureRedirect: `${process.env.FRONT_URL}/login` 
+// Google OAuth 濡쒓렇�� �쇱슦��
+router.get(
+  '/login',
+  passport.authenticate('google', {
+    scope: ['profile', 'email'], // �ъ슜�� �뺣낫 �붿껌�� �꾪븳 scope 
+    failureRedirect: `${process.env.FRONT_URL}/login`
   })
 );
 
+// Google OAuth 肄쒕갚 �쇱슦��
 router.get(
   '/google/callback',
-  passport.authenticate('google', { failureRedirect: '/auth/login' }),
+  passport.authenticate('google', {
+    failureRedirect: '/auth/login'
+  }),
   (req, res) => {
     const redirectUrl = process.env.FRONT_URL;
     req.session.save((err) => {
@@ -24,7 +29,8 @@ router.get(
     });
   }
 );
-// GET api/auth/logout
+
+// 濡쒓렇�꾩썐 �쇱슦��
 router.get('/logout', (req, res) => {
   if (req.session) {
     req.session.destroy((err) => {
-- 
GitLab


From d2923e20d5170e30211d4643209e2d06086a095e Mon Sep 17 00:00:00 2001
From: Ubuntu <ubuntu@ip-172-31-1-27.ap-northeast-2.compute.internal>
Date: Sat, 7 Dec 2024 18:15:45 +0000
Subject: [PATCH 42/61] =?UTF-8?q?refactor:=20=EC=84=B8=EC=85=98=EC=98=A4?=
 =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 output.log        | 346 +++++++++++++++++++++++++++++-----------------
 routes/session.js |  11 +-
 weblog.log        |   4 +-
 3 files changed, 226 insertions(+), 135 deletions(-)

diff --git a/output.log b/output.log
index d9136a9..6df63b6 100644
--- a/output.log
+++ b/output.log
@@ -1,135 +1,223 @@
 MongoDB URI: mongodb+srv://admin:lim1234!!@goodmeeting.vkniz.mongodb.net/
-(node:77051) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:182036) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 (Use `node --trace-warnings ...` to show where the warning was created)
-(node:77051) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:182036) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 �� MongoDB �곌껐 �깃났
 Rdb�곗씠�곕쿋�댁뒪 �곌껐 �깃났.
 紐⑤뱺 紐⑤뜽�� �깃났�곸쑝濡� �숆린�붾릺�덉뒿�덈떎.
 Server is running on 8080
-GET /api/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php 404 9.005 ms - 193
-GET / 404 2.052 ms - 139
-GET / 404 1.179 ms - 139
-GET / 404 1.045 ms - 139
-GET / 404 1.827 ms - 139
-GET / 404 1.101 ms - 139
-GET /download/powershell/ 404 1.186 ms - 159
-GET /get.php 404 0.895 ms - 146
-GET / 404 1.429 ms - 139
-GET /api/im/v2/app/config 404 1.289 ms - 159
-GET /api/ 404 1.099 ms - 143
-GET /api/ 404 1.036 ms - 143
-GET /api/c/a 404 0.920 ms - 146
-GET /api/ping 404 0.873 ms - 147
-GET /api/notice 404 0.902 ms - 149
-GET /api/config 404 0.936 ms - 149
-GET /api/version 404 0.871 ms - 150
-GET /api/v1/config 404 1.131 ms - 152
-GET /api/index/web 404 0.706 ms - 152
-GET /api/Business/ 404 0.752 ms - 152
-GET /api/shop/getKF 404 1.018 ms - 153
-GET /api/index/init 404 0.893 ms - 153
-GET /api/Event/basic 404 0.632 ms - 154
-GET /api/apps/config 404 0.583 ms - 154
-GET /api/front/index 404 0.941 ms - 154
-GET /api/app/indexList 404 0.850 ms - 156
-GET /api/common/config 404 0.784 ms - 156
-GET /api/Home/videoNew 404 2.733 ms - 156
-GET /api/getCustomLink 404 0.672 ms - 156
-GET /api/uploads/apimap 404 0.584 ms - 157
-GET /api/v1/member/kefu 404 0.642 ms - 157
-GET /api/config/getkefu 404 0.684 ms - 157
-GET /api/site/getInfo.do 404 0.667 ms - 158
-GET /api/message/webInfo 404 0.595 ms - 158
-GET /api/index/webconfig 404 0.703 ms - 158
-GET /api/index/getConfig 404 0.745 ms - 158
-GET /api/index/grailindex 404 0.931 ms - 159
-GET /api/shares/hqStrList 404 0.770 ms - 159
-GET /api/user/ismustmobile 404 0.753 ms - 160
-GET /api/user/ismustmobile 404 0.697 ms - 160
-GET /api/user/ismustmobile 404 0.616 ms - 160
-GET /api/banner?appKey=bxefdn 404 1.134 ms - 149
-GET /api/Config/getShowConfig 404 0.590 ms - 163
-GET /api/home/customerService 404 2.229 ms - 163
-GET /api/client/app/config.do 404 0.698 ms - 163
-GET /api/product/getPointStore 404 0.703 ms - 164
-GET /api/currency/quotation_new 404 0.751 ms - 165
-GET /api/vue/transaction/config 404 0.821 ms - 165
-GET /api/predict-whole-panel.do 404 0.800 ms - 165
-GET /api/common/menus?lang=zh-Hans 404 0.767 ms - 155
-GET /api/appVersion?mobile_system=2 404 0.711 ms - 153
-GET /api/public/?service=Home.getConfig 404 0.797 ms - 150
-GET /api/unSecurity/app/listAppVersionInfo 404 0.793 ms - 176
-GET /api/stock/getSingleStock.do?code=002405 404 0.739 ms - 166
-GET /api/system/systemConfigs/getCustomerServiceLink 404 0.780 ms - 186
-GET /api/v/index/queryOfficePage?officeCode=customHomeLink 404 0.805 ms - 166
-GET /api/im/v2/app/config 404 2.524 ms - 159
-GET /api/ 404 0.739 ms - 143
-GET /api/ 404 0.792 ms - 143
-GET /api/c/a 404 0.761 ms - 146
-GET /api/ping 404 0.715 ms - 147
-GET /api/config 404 0.930 ms - 149
-POST /api/notice 404 24.787 ms - 150
-GET /api/version 404 0.963 ms - 150
-GET /api/v1/config 404 0.761 ms - 152
-GET /api/Business/ 404 0.618 ms - 152
-GET /api/index/web 404 0.595 ms - 152
-GET /api/shop/getKF 404 0.747 ms - 153
-GET /api/Event/basic 404 0.612 ms - 154
-GET /api/front/index 404 0.620 ms - 154
-GET /api/index/init 404 0.647 ms - 153
-GET /api/apps/config 404 0.657 ms - 154
-GET /api/app/indexList 404 0.925 ms - 156
-GET /api/common/config 404 0.645 ms - 156
-GET /api/Home/videoNew 404 2.724 ms - 156
-POST /api/getCustomLink 404 13.160 ms - 157
-GET /api/v1/member/kefu 404 0.575 ms - 157
-GET /api/uploads/apimap 404 0.538 ms - 157
-GET /api/config/getkefu 404 0.724 ms - 157
-GET /api/site/getInfo.do 404 0.511 ms - 158
-GET /api/message/webInfo 404 0.683 ms - 158
-GET /api/index/webconfig 404 0.714 ms - 158
-GET /api/index/getConfig 404 0.676 ms - 158
-GET /api/index/grailindex 404 0.676 ms - 159
-GET /api/shares/hqStrList 404 0.590 ms - 159
-POST /api/user/ismustmobile 404 0.950 ms - 161
-GET /api/user/ismustmobile 404 0.558 ms - 160
-POST /api/user/ismustmobile 404 0.805 ms - 161
-GET /api/banner?appKey=bxefdn 404 0.834 ms - 149
-GET /api/Config/getShowConfig 404 0.621 ms - 163
-GET /api/client/app/config.do 404 0.643 ms - 163
-GET /api/home/customerService 404 0.613 ms - 163
-GET /api/product/getPointStore 404 0.842 ms - 164
-GET /api/currency/quotation_new 404 0.812 ms - 165
-GET /api/vue/transaction/config 404 0.669 ms - 165
-GET /api/predict-whole-panel.do 404 1.121 ms - 165
-GET /api/common/menus?lang=zh-Hans 404 0.788 ms - 155
-GET /api/appVersion?mobile_system=2 404 1.182 ms - 153
-GET /api/public/?service=Home.getConfig 404 0.590 ms - 150
-GET /api/unSecurity/app/listAppVersionInfo 404 0.642 ms - 176
-GET /api/stock/getSingleStock.do?code=002405 404 2.576 ms - 166
-POST /api/system/systemConfigs/getCustomerServiceLink 404 0.816 ms - 187
-GET /api/v/index/queryOfficePage?officeCode=customHomeLink 404 0.642 ms - 166
-GET http://example.com/ 404 2.861 ms - 139
-GET http://example.com/ 404 0.862 ms - 139
-GET / 404 0.856 ms - 139
-GET /favicon.ico 404 0.860 ms - 150
-GET / 404 0.899 ms - 139
-GET / 404 0.812 ms - 139
-GET /manage/account/login 404 0.807 ms - 159
-GET /admin/index.html 404 0.875 ms - 155
-GET /index.html 404 0.870 ms - 149
-GET /+CSCOE+/logon.html 404 0.831 ms - 157
-GET /cgi-bin/login.cgi 404 0.864 ms - 156
-GET /logon.htm 404 0.788 ms - 148
-GET /login.jsp 404 0.845 ms - 148
-GET /doc/index.html 404 0.922 ms - 153
-GET / 404 0.801 ms - 139
-GET / 404 0.818 ms - 139
-GET / 404 0.938 ms - 139
-GET / 404 1.083 ms - 139
-GET / 404 0.872 ms - 139
-GET / 404 0.892 ms - 139
-GET / 404 0.871 ms - 139
-GET /api/.env 404 0.821 ms - 147
-POST /api/.env 404 1.818 ms - 148
-GET /api/index.php/v1/config/application?public=true 404 0.739 ms - 174
+GET /api/session/info 401 8.594 ms - 76
+GET /api/auth/login 302 3.050 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0ao8f60iPWO2lFPG-75VwKyiSOn5kXy7WYogowBYIKp-Rqv0m-ctgybXxfZXLTMFA&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&authuser=1&hd=ajou.ac.kr&prompt=none 302 532.811 ms - 48
+GET /api/session/info 200 7.414 ms - 60
+GET /api/session/info 200 4.780 ms - 60
+GET /api/schedule/all 304 19.397 ms - -
+Performance Measurement - getAllSchedules: 5.005846977233887ms
+GET /api/schedule/289 304 16.458 ms - -
+Performance Measurement - getScheduleByTimeIdx: 11.750297963619232ms
+GET /api/schedule/193 304 7.581 ms - -
+Performance Measurement - getScheduleByTimeIdx: 3.6492010354995728ms
+GET /api/schedule/193 304 7.722 ms - -
+Performance Measurement - getScheduleByTimeIdx: 3.8008620142936707ms
+GET /api/schedule/193 304 9.777 ms - -
+Performance Measurement - getScheduleByTimeIdx: 4.146169006824493ms
+GET /api/schedule/192 200 8.365 ms - 26
+Performance Measurement - getScheduleByTimeIdx: 4.420195996761322ms
+GET /api/schedule/7 200 7.684 ms - 26
+Performance Measurement - getScheduleByTimeIdx: 3.8003939986228943ms
+GET /api/schedule/103 304 8.917 ms - -
+Performance Measurement - getScheduleByTimeIdx: 3.626570999622345ms
+GET /api/schedule/4 200 7.304 ms - 26
+Performance Measurement - getScheduleByTimeIdx: 3.7574750185012817ms
+GET /api/schedule/102 304 9.324 ms - -
+Performance Measurement - getScheduleByTimeIdx: 4.2991169691085815ms
+GET /api/schedule/199 200 7.638 ms - 26
+Performance Measurement - getScheduleByTimeIdx: 3.934753954410553ms
+GET /api/schedule/196 200 7.331 ms - 26
+Performance Measurement - getScheduleByTimeIdx: 3.7636460065841675ms
+GET /api/schedule/99 304 8.753 ms - -
+Performance Measurement - getScheduleByTimeIdx: 3.7125409841537476ms
+GET /api/schedule/99 304 6.852 ms - -
+Performance Measurement - getScheduleByTimeIdx: 3.625138998031616ms
+GET /api/schedule/105 200 7.316 ms - 26
+Performance Measurement - getScheduleByTimeIdx: 3.6936269998550415ms
+GET /api/schedule/2 200 9.041 ms - 26
+Performance Measurement - getScheduleByTimeIdx: 3.845887005329132ms
+GET /api/schedule/1 200 7.427 ms - 26
+Performance Measurement - getScheduleByTimeIdx: 3.8853600025177ms
+GET /api/schedule/1 304 7.564 ms - -
+Performance Measurement - getScheduleByTimeIdx: 4.00413304567337ms
+GET /api/session/info 200 4.063 ms - 60
+GET /api/schedule/all 304 6.780 ms - -
+Performance Measurement - getAllSchedules: 2.9270060062408447ms
+GET /api/session/info 200 4.080 ms - 60
+GET /api/session/info 200 14.763 ms - 60
+GET /api/session/info 200 4.001 ms - 60
+GET /api/session/info 200 49.452 ms - 60
+GET /api/session/info 200 16.079 ms - 60
+GET /api/schedule/all 304 51.136 ms - -
+Performance Measurement - getAllSchedules: 3.047551989555359ms
+GET / 404 2.482 ms - 139
+GET /favicon.ico 404 1.030 ms - 150
+GET http://api.ipify.org/?format=json 404 2.130 ms - 139
+GET /geoserver/web/ 404 0.934 ms - 153
+GET /api/session/info 401 1.080 ms - 76
+GET /api/session/info 401 0.698 ms - 76
+GET /api/session/info 401 0.921 ms - 76
+GET /api/session/info 401 0.587 ms - 76
+OPTIONS /api/schedule/all 204 0.404 ms - 0
+OPTIONS /api/schedule/all 204 0.138 ms - 0
+GET / 404 1.220 ms - 139
+GET /api/session/info 401 0.925 ms - 76
+GET /api/session/info 401 0.677 ms - 76
+GET /api/session/info 401 0.849 ms - 76
+GET /api/session/info 401 0.638 ms - 76
+GET /api/session/info 401 0.855 ms - 76
+GET /api/session/info 401 0.648 ms - 76
+GET /api/session/info 401 0.968 ms - 76
+GET /api/session/info 401 0.655 ms - 76
+GET /api/session/info 401 0.887 ms - 76
+GET /api/session/info 401 0.656 ms - 76
+GET /api/session/info 401 0.819 ms - 76
+GET /api/session/info 401 1.715 ms - 76
+GET /api/session/info 401 0.859 ms - 76
+GET /api/session/info 401 0.650 ms - 76
+GET /api/session/info 401 0.920 ms - 76
+GET /api/session/info 401 0.627 ms - 76
+GET /api/session/info 401 0.831 ms - 76
+GET /api/session/info 401 0.645 ms - 76
+GET /api/session/info 401 0.845 ms - 76
+GET /api/session/info 401 0.624 ms - 76
+GET / 404 1.042 ms - 139
+GET /api/session/info 401 0.793 ms - 76
+GET /api/session/info 401 0.580 ms - 76
+GET /api/session/info 401 0.806 ms - 76
+GET /api/session/info 401 0.606 ms - 76
+GET /api/session/info 401 0.829 ms - 76
+GET /api/session/info 401 0.609 ms - 76
+OPTIONS /api/schedule/all 204 0.618 ms - 0
+OPTIONS /api/schedule/all 204 0.140 ms - 0
+GET /api/schedule/all 401 0.903 ms - 44
+GET /api/schedule/96 401 0.846 ms - 44
+GET /api/schedule/194 401 0.764 ms - 44
+GET /api/schedule/194 401 0.868 ms - 44
+GET /api/schedule/97 401 0.827 ms - 44
+GET /api/schedule/96 401 0.850 ms - 44
+OPTIONS /api/schedule/all 204 0.234 ms - 0
+OPTIONS /api/schedule/all 204 0.167 ms - 0
+OPTIONS /api/schedule/192 204 0.192 ms - 0
+OPTIONS /api/schedule/192 204 0.188 ms - 0
+OPTIONS /api/schedule/290 204 0.188 ms - 0
+OPTIONS /api/schedule/290 204 0.189 ms - 0
+OPTIONS /api/schedule/290 204 0.165 ms - 0
+OPTIONS /api/schedule/all 204 0.202 ms - 0
+OPTIONS /api/schedule/289 204 0.194 ms - 0
+OPTIONS /api/schedule/289 204 0.227 ms - 0
+OPTIONS /api/schedule/289 204 0.162 ms - 0
+OPTIONS /api/schedule/290 204 0.166 ms - 0
+OPTIONS /api/schedule/291 204 0.167 ms - 0
+OPTIONS /api/schedule/291 204 0.166 ms - 0
+OPTIONS /api/schedule/290 204 0.160 ms - 0
+OPTIONS /api/schedule/288 204 0.164 ms - 0
+OPTIONS /api/schedule/290 204 0.167 ms - 0
+OPTIONS /api/schedule/291 204 0.205 ms - 0
+OPTIONS /api/schedule/291 204 0.188 ms - 0
+OPTIONS /api/schedule/290 204 0.178 ms - 0
+OPTIONS /api/schedule/289 204 0.168 ms - 0
+OPTIONS /api/schedule/290 204 0.177 ms - 0
+OPTIONS /api/schedule/289 204 0.166 ms - 0
+OPTIONS /api/schedule 204 0.189 ms - 0
+OPTIONS /api/schedule/289 204 0.168 ms - 0
+OPTIONS /api/schedule/288 204 0.222 ms - 0
+OPTIONS /api/schedule/290 204 0.179 ms - 0
+OPTIONS /api/schedule/292 204 0.160 ms - 0
+OPTIONS /api/schedule/293 204 0.165 ms - 0
+OPTIONS /api/schedule/all 204 0.176 ms - 0
+OPTIONS /api/schedule/36 204 0.178 ms - 0
+OPTIONS /api/schedule/38 204 0.161 ms - 0
+OPTIONS /api/schedule/38 204 0.172 ms - 0
+OPTIONS /api/schedule/38 204 0.157 ms - 0
+OPTIONS /api/schedule/38 204 0.191 ms - 0
+OPTIONS /api/schedule/38 204 0.165 ms - 0
+OPTIONS /api/schedule/38 204 0.184 ms - 0
+OPTIONS /api/schedule/38 204 0.168 ms - 0
+OPTIONS /api/schedule/38 204 0.217 ms - 0
+OPTIONS /api/schedule/all 204 0.164 ms - 0
+OPTIONS /api/schedule/36 204 0.165 ms - 0
+OPTIONS /api/schedule/37 204 0.160 ms - 0
+OPTIONS /api/schedule/36 204 0.178 ms - 0
+GET /api/schedule/193 401 1.087 ms - 44
+GET /api/schedule/193 401 0.785 ms - 44
+GET /api/schedule/195 401 0.850 ms - 44
+GET /api/schedule/1 401 0.814 ms - 44
+GET /api/schedule/0 401 0.795 ms - 44
+GET /api/schedule/0 401 0.825 ms - 44
+GET /api/schedule/96 401 0.854 ms - 44
+GET /api/schedule/289 401 0.824 ms - 44
+GET /api/session/info 401 0.858 ms - 76
+GET /api/auth/login 302 1.424 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0a4gqvuMrxTHLniakI-_oHdDI0RHY_4-82ZXsaIAKdM53z4nPcgFGUOJjD4FJwRBw&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=1&hd=ajou.ac.kr&prompt=none 302 508.556 ms - 48
+GET /api/schedule/all 304 11.134 ms - -
+Performance Measurement - getAllSchedules: 5.014769017696381ms
+GET /api/schedule/97 304 10.607 ms - -
+Performance Measurement - getScheduleByTimeIdx: 7.154272973537445ms
+GET /api/schedule/101 200 6.849 ms - 26
+Performance Measurement - getScheduleByTimeIdx: 3.534310042858124ms
+GET /api/schedule/100 200 6.679 ms - 26
+Performance Measurement - getScheduleByTimeIdx: 3.2747740149497986ms
+GET /api/schedule/99 304 7.228 ms - -
+Performance Measurement - getScheduleByTimeIdx: 3.805077016353607ms
+GET /api/schedule/99 304 9.589 ms - -
+Performance Measurement - getScheduleByTimeIdx: 5.2810059785842896ms
+GET /api/schedule/99 304 6.405 ms - -
+Performance Measurement - getScheduleByTimeIdx: 3.1567789912223816ms
+GET /api/schedule/98 304 7.002 ms - -
+Performance Measurement - getScheduleByTimeIdx: 3.5950030088424683ms
+GET /api/schedule/97 304 6.705 ms - -
+Performance Measurement - getScheduleByTimeIdx: 3.2245330214500427ms
+GET /api/schedule/97 304 6.217 ms - -
+Performance Measurement - getScheduleByTimeIdx: 2.99965101480484ms
+GET /api/schedule/2 200 6.568 ms - 26
+Performance Measurement - getScheduleByTimeIdx: 3.2004200220108032ms
+OPTIONS /api/schedule/all 204 0.166 ms - 0
+OPTIONS /api/schedule 204 0.174 ms - 0
+OPTIONS /api/schedule 204 0.179 ms - 0
+OPTIONS /api/schedule 204 0.232 ms - 0
+OPTIONS /api/schedule/all 204 0.164 ms - 0
+OPTIONS /api/schedule/all 204 0.167 ms - 0
+GET / 404 1.022 ms - 139
+GET /api/session/info 401 0.816 ms - 76
+GET /api/session/info 401 1.325 ms - 76
+GET /api/session/info 401 0.832 ms - 76
+GET /api/session/info 401 0.603 ms - 76
+GET /api/session/info 401 0.819 ms - 76
+GET /api/session/info 401 0.556 ms - 76
+OPTIONS /api/schedule/all 204 0.161 ms - 0
+OPTIONS /api/schedule/all 204 0.124 ms - 0
+OPTIONS /api/schedule 204 0.164 ms - 0
+GET /api/session/info 401 0.837 ms - 76
+GET /api/session/info 401 0.648 ms - 76
+GET /api/session/info 401 0.810 ms - 76
+GET /api/auth/login 302 1.089 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0box5WHb-IhXbrmGgpDAMMr3rQ5vv45X8p-FJJM90Ts4qDwFayGUeisJmPZIsW9ew&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=0&hd=ajou.ac.kr&prompt=none 302 478.464 ms - 48
+GET /api/session/info 200 7.699 ms - 58
+GET /api/schedule/all 200 6.802 ms - 40
+Performance Measurement - getAllSchedules: 3.283160984516144ms
+POST /api/schedule 201 33.080 ms - 194
+Performance Measurement - createSchedule: 19.97666096687317ms
+PUT /api/schedule 200 44.680 ms - 202
+Performance Measurement - updateSchedules: 28.161078989505768ms
+Performance Measurement - deleteSchedules: 2.5363460183143616ms
+DELETE /api/schedule 404 7.058 ms - 115
+Performance Measurement - deleteSchedules: 0.8580690026283264ms
+DELETE /api/schedule 404 5.339 ms - 115
+Performance Measurement - deleteSchedules: 0.5973520278930664ms
+DELETE /api/schedule 404 5.281 ms - 115
+GET /api/schedule/all 200 38.467 ms - 205
+Performance Measurement - getAllSchedules: 12.194466054439545ms
+DELETE /api/schedule 200 14.795 ms - 84
+Performance Measurement - deleteSchedules: 10.980576992034912ms
+GET /api/schedule/all 200 5.511 ms - 40
+Performance Measurement - getAllSchedules: 2.713946044445038ms
+GET /api/session/info 200 50.557 ms - 58
+GET / 404 1.050 ms - 139
diff --git a/routes/session.js b/routes/session.js
index 09178cf..803e2ff 100644
--- a/routes/session.js
+++ b/routes/session.js
@@ -3,9 +3,11 @@ const router = express.Router();
 
 // GET /api/session/info
 router.get('/info', (req, res) => {
-  if (req.session && req.session.user) {
-    const { email, name } = req.session.user;
-
+  if (req.user) {
+    const { email, name } = req.user;
+  // 罹먯떛 鍮꾪솢�깊솕
+    res.set('Cache-Control', 'no-store');
+    res.set('Pragma', 'no-cache');	  
     return res.status(200).json({
       user: {
         email,
@@ -13,8 +15,9 @@ router.get('/info', (req, res) => {
       },
     });
   }
-
   // �몄뀡�� 留뚮즺�섏뿀嫄곕굹 �ъ슜�� �뺣낫媛� �녿뒗 寃쎌슦
+  res.set('Cache-Control', 'no-store');
+  res.set('Pragma', 'no-cache');
   res.status(401).json({
     message: '�몄뀡�� 留뚮즺�섏뿀嫄곕굹 �ъ슜�� �뺣낫媛� �놁뒿�덈떎.',
   });
diff --git a/weblog.log b/weblog.log
index 4038042..6725a76 100644
--- a/weblog.log
+++ b/weblog.log
@@ -1,5 +1,5 @@
-(node:77052) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:182037) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 (Use `node --trace-warnings ...` to show where the warning was created)
-(node:77052) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:182037) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 MongoDB�� �깃났�곸쑝濡� �곌껐�섏뿀�듬땲��.
 WebSocket 梨꾪똿 �쒕쾭媛� 8081 �ы듃�먯꽌 �ㅽ뻾 以묒엯�덈떎.
-- 
GitLab


From 39c45e32c5bf2a207e6dafdb2552db268457dc24 Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Sun, 8 Dec 2024 13:48:47 +0900
Subject: [PATCH 43/61] =?UTF-8?q?test:=20=EB=A1=9C=EC=BB=AC=ED=99=98?=
 =?UTF-8?q?=EA=B2=BD=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EC=9A=A9=20=EB=A6=AC?=
 =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app.js         | 39 ++++++++++++++++++++++-----------
 routes/auth.js | 58 ++++++++++++++++++++++++++++++++------------------
 2 files changed, 63 insertions(+), 34 deletions(-)

diff --git a/app.js b/app.js
index 952e375..594bdab 100644
--- a/app.js
+++ b/app.js
@@ -16,40 +16,50 @@ const app = express();
 
 
 app.use(morgan('dev'));  //濡쒓퉭��
-// CORS �ㅼ젙
+
+// CORS �ㅼ젙 (濡쒖뺄 �섍꼍��)
 app.use(
   cors({
-    origin: 'http://localhost:3000', 
-    methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
+    origin: process.env.FRONT_URL,
+    methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], 
     allowedHeaders: ['Content-Type', 'Authorization'],
-    credentials: true,
+    credentials: true, 
   })
 );
 
-
-// 誘몃뱾�⑥뼱 �ㅼ젙
-app.use(express.json());
-app.use(express.urlencoded({ extended: false }));
-
-// �몄뀡 �ㅼ젙
+// �몄뀡 �ㅼ젙 (濡쒖뺄 �뚯뒪�몄슜)
 app.use(
   session({
-    secret: 'your_session_secret', 
+    secret: 'your-secret-key', 
     resave: false,
     saveUninitialized: false,
+    rolling: true, 
+    cookie: {
+      httpOnly: true, 
+      secure: false, // HTTPS媛� �꾨땶 �섍꼍�먯꽌�� false濡� �ㅼ젙
+      maxAge: 60 * 60 * 1000, 
+      sameSite: 'lax', 
+    },
   })
 );
 
+// 誘몃뱾�⑥뼱 �ㅼ젙
+app.use(express.json());
+app.use(express.urlencoded({ extended: false }));
+
 // Passport 珥덇린�� 諛� �몄뀡 �곌껐
 app.use(passport.initialize());
 app.use(passport.session());
 
 
 app.use(flash());
+
+
+app.set('trust proxy', 1);
 console.log('MongoDB URI:', process.env.MONGO_URI);
 //�쇱슦�� �깅줉 
 const authRoutes = require('./routes/auth');
-app.use('/auth', authRoutes);
+app.use('/api/auth', authRoutes);
 
 const scheduleRoutes = require('./routes/schedule');
 app.use('/api/schedule', scheduleRoutes);
@@ -66,6 +76,9 @@ app.use('/api/chat', chatRoutes);
 const memberRoutes = require('./routes/memberRoute');
 app.use('/api/member', memberRoutes);
 
+const sessionRouter = require('./routes/session');
+app.use('/api/session', sessionRouter);
+
 // �ㅼ�以� �대━�� 珥덇린��
 initScheduleCleaner();
 
@@ -86,4 +99,4 @@ const PORT = process.env.PORT || 3000;
     console.error('�� �쒕쾭 �쒖옉 以� �ㅻ쪟 諛쒖깮:', error);
     process.exit(1);
   }
-})();
\ No newline at end of file
+})();
diff --git a/routes/auth.js b/routes/auth.js
index 7eda249..6583059 100644
--- a/routes/auth.js
+++ b/routes/auth.js
@@ -1,35 +1,51 @@
-// routes/auth.js
-
 const express = require('express');
 const passport = require('passport');
 
 const router = express.Router();
 
-// GET /auth/login
-router.get('/login', (req, res) => {
-  res.send('<a href="/auth/google">Log in with Google</a>');
-});
-
-// GET /auth/logout
-router.get('/logout', (req, res) => {
-  req.logout(() => {
-    res.redirect('/');
-  });
-});
-
-// GET /auth/google
+// Google OAuth 濡쒓렇�� �쇱슦��
 router.get(
-  '/google',
-  passport.authenticate('google', { scope: ['profile', 'email'] })
+  '/login',
+  passport.authenticate('google', {
+    scope: ['profile', 'email'], // �ъ슜�� �뺣낫 �붿껌�� �꾪븳 scope 
+    failureRedirect: `${process.env.FRONT_URL}/login`
+  })
 );
 
-// GET /auth/google/callback
+// Google OAuth 肄쒕갚 �쇱슦��
 router.get(
   '/google/callback',
-  passport.authenticate('google', { failureRedirect: '/auth/login' }),
+  passport.authenticate('google', {
+    failureRedirect: '/auth/login'
+  }),
   (req, res) => {
-    res.redirect('/');
+    const redirectUrl = process.env.FRONT_URL;
+    req.session.save((err) => {
+      if (err) {
+        console.error('�몄뀡 ���� �ㅻ쪟:', err);
+        return res.status(500).json({ error: '�쒕쾭 �ㅻ쪟' });
+      }
+      res.redirect(redirectUrl);
+    });
   }
 );
 
-module.exports = router;
+// 濡쒓렇�꾩썐 �쇱슦��
+router.get('/logout', (req, res) => {
+  if (req.session) {
+    req.session.destroy((err) => {
+      if (err) {
+        console.error('�몄뀡 ��젣 �ㅻ쪟:', err);
+        return res.status(500).json({ error: '�쒕쾭 �ㅻ쪟' });
+      }
+      const redirectUrl = process.env.FRONT_URL;
+      res.redirect(redirectUrl);
+    });
+  } else {
+    // �몄뀡�� �녿뒗 寃쎌슦�먮룄 由щ떎�대젆��
+    const redirectUrl = process.env.FRONT_URL;
+    res.redirect(redirectUrl);
+  }
+});
+
+module.exports = router;
\ No newline at end of file
-- 
GitLab


From 95f8e1239e80a809e746a19c2b8e36a9c6fbbd7f Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Sun, 8 Dec 2024 15:37:55 +0900
Subject: [PATCH 44/61] =?UTF-8?q?refactor:=20=EB=A1=9C=EC=BB=AC=ED=85=8C?=
 =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EC=9A=A9=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?=
 =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app.js                     |  2 +-
 middlewares/auth.js        | 13 +++++++------
 passport/googleStrategy.js |  8 ++++----
 routes/auth.js             |  3 +--
 routes/session.js          | 26 ++++++++++++++++++++++++++
 5 files changed, 39 insertions(+), 13 deletions(-)
 create mode 100644 routes/session.js

diff --git a/app.js b/app.js
index 594bdab..1841e8c 100644
--- a/app.js
+++ b/app.js
@@ -55,7 +55,7 @@ app.use(passport.session());
 app.use(flash());
 
 
-app.set('trust proxy', 1);
+//app.set('trust proxy', 1);
 console.log('MongoDB URI:', process.env.MONGO_URI);
 //�쇱슦�� �깅줉 
 const authRoutes = require('./routes/auth');
diff --git a/middlewares/auth.js b/middlewares/auth.js
index afc74ea..315edee 100644
--- a/middlewares/auth.js
+++ b/middlewares/auth.js
@@ -1,15 +1,16 @@
 // middlewares/auth.js
-
-exports.isLoggedIn = (req, res, next) => { //濡쒓렇�몃맂 �ъ슜�먯옄留� �묎렐�덉슜
+exports.isLoggedIn = (req, res, next) => { // 濡쒓렇�몃맂 �ъ슜�먮쭔 �묎렐 �덉슜
   if (req.isAuthenticated()) {
     return next();
   }
-  res.redirect('/auth/login');
+  // 由щ떎�대젆�� ���� 401 Unauthorized �곹깭 諛섑솚
+  res.status(401).json({ error: '濡쒓렇�� �섏��딆� �ъ슜��' });
 };
 
-exports.isNotLoggedIn = (req, res, next) => { //濡쒓렇�� �덈릺硫� 由щ떎�대젆�� 
+exports.isNotLoggedIn = (req, res, next) => { // 濡쒓렇�� �덈맂 �ъ슜�먮쭔 �묎렐 �덉슜
   if (!req.isAuthenticated()) {
     return next();
   }
-  res.redirect('/');
-};
+  // 由щ떎�대젆�� ���� 400 Bad Request �곹깭 諛섑솚 (�꾩슂�� �곕씪 蹂�寃� 媛���)
+  res.status(400).json({ error: '�대� 濡쒓렇�몃맂' });
+};
\ No newline at end of file
diff --git a/passport/googleStrategy.js b/passport/googleStrategy.js
index cd23c9d..f6698b3 100644
--- a/passport/googleStrategy.js
+++ b/passport/googleStrategy.js
@@ -1,15 +1,15 @@
 // passport/googleStrategy.js
-
 const { Strategy: GoogleStrategy } = require('passport-google-oauth20');
-const User = require('../models/user');
+const User = require('../models/user'); 
 
 module.exports = new GoogleStrategy(
   {
     clientID: process.env.GOOGLE_CLIENT_ID,
     clientSecret: process.env.GOOGLE_CLIENT_SECRET,
     callbackURL: process.env.CALLBACK_URL,
+    passReqToCallback: true, // req 媛앹껜瑜� 肄쒕갚�� �꾨떖
   },
-  async (accessToken, refreshToken, profile, done) => {
+  async (req, accessToken, refreshToken, profile, done) => {
     try {
       // �꾨줈�꾩뿉�� �ъ슜�� �뺣낫 異붿텧
       const email = profile.emails[0].value;
@@ -23,7 +23,7 @@ module.exports = new GoogleStrategy(
 
       return done(null, user);
     } catch (err) {
-      return done(err);
+      return done(err, null);
     }
   }
 );
diff --git a/routes/auth.js b/routes/auth.js
index 6583059..186b15d 100644
--- a/routes/auth.js
+++ b/routes/auth.js
@@ -12,11 +12,10 @@ router.get(
   })
 );
 
-// Google OAuth 肄쒕갚 �쇱슦��
 router.get(
   '/google/callback',
   passport.authenticate('google', {
-    failureRedirect: '/auth/login'
+    failureRedirect: `${process.env.FRONT_URL}/login` // �섏젙�� 遺�遺�
   }),
   (req, res) => {
     const redirectUrl = process.env.FRONT_URL;
diff --git a/routes/session.js b/routes/session.js
new file mode 100644
index 0000000..77a3b11
--- /dev/null
+++ b/routes/session.js
@@ -0,0 +1,26 @@
+const express = require('express');
+const router = express.Router();
+
+// GET /api/session/info
+router.get('/info', (req, res) => {
+  if (req.user) {
+    const { email, name } = req.user;
+  // 罹먯떛 鍮꾪솢�깊솕
+    res.set('Cache-Control', 'no-store');
+    res.set('Pragma', 'no-cache');        
+    return res.status(200).json({
+      user: {
+        email,
+        name,
+      },
+    });
+  }
+  // �몄뀡�� 留뚮즺�섏뿀嫄곕굹 �ъ슜�� �뺣낫媛� �녿뒗 寃쎌슦
+  res.set('Cache-Control', 'no-store');
+  res.set('Pragma', 'no-cache');
+  res.status(401).json({
+    message: '�몄뀡�� 留뚮즺�섏뿀嫄곕굹 �ъ슜�� �뺣낫媛� �놁뒿�덈떎.',
+  });
+});
+
+module.exports = router;
\ No newline at end of file
-- 
GitLab


From 1fec66e6413d0da8487cbbaff6cf2e0225b14733 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=8B=AC=EC=9E=AC=EC=97=BD?= <jysim0326@ajou.ac.kr>
Date: Sun, 8 Dec 2024 15:55:09 +0900
Subject: [PATCH 45/61] =?UTF-8?q?refactor:=20FcmToken=20=EC=97=B0=EA=B4=80?=
 =?UTF-8?q?=EA=B4=80=EA=B3=84=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 models/index.js | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/models/index.js b/models/index.js
index 5218166..7c656bc 100644
--- a/models/index.js
+++ b/models/index.js
@@ -29,6 +29,9 @@ User.hasMany(MeetingParticipant, { foreignKey: 'user_id', as: 'meetingParticipat
 Schedule.belongsTo(User, { foreignKey: 'user_id', as: 'user' });
 User.hasMany(Schedule, { foreignKey: 'user_id', as: 'schedules' });
 
+FcmToken.belongsTo(User, { foreignKey: 'userId', as: 'user' });
+User.hasMany(FcmToken, { foreignKey: 'userId', as: 'fcmTokenList' });
+
 Invite.belongsTo(Meeting, { foreignKey: 'meeting_id', as: 'meeting' });
 Invite.belongsTo(User, { foreignKey: 'inviter_id', as: 'inviter' }); // 珥덈��� �ъ슜��
 Invite.belongsTo(User, { foreignKey: 'invitee_id', as: 'invitee' }); // 珥덈�諛쏆� �ъ슜��
-- 
GitLab


From b923a078212c5a4c25d1263120c2e3f5022f2498 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=8B=AC=EC=9E=AC=EC=97=BD?= <jysim0326@ajou.ac.kr>
Date: Sun, 8 Dec 2024 15:55:29 +0900
Subject: [PATCH 46/61] =?UTF-8?q?feat:=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?=
 =?UTF-8?q?=EA=B3=B5=EC=A7=80=EC=82=AC=ED=95=AD=20=EA=B8=B0=EB=8A=A5=20?=
 =?UTF-8?q?=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 controllers/chatController.js | 63 +++++++++++++++++++++++++++
 routes/chatRoute.js           |  4 ++
 schemas/ChatRooms.js          |  7 ++-
 services/chatService.js       | 81 +++++++++++++++++++++++++++++++++++
 4 files changed, 153 insertions(+), 2 deletions(-)

diff --git a/controllers/chatController.js b/controllers/chatController.js
index 41a2d3c..bfcca38 100644
--- a/controllers/chatController.js
+++ b/controllers/chatController.js
@@ -91,4 +91,67 @@ exports.updateStatusAndLogId = async (req, res) => {
     console.error('Error updating user status and lastReadLogId:', err);
     res.status(500).json({ error: 'Failed to update user status and lastReadLogId' });
   }
+};
+
+// 怨듭� �깅줉
+exports.addNotice = async (req, res) => {
+  const { chatRoomId } = req.params;
+  const { sender, message } = req.body;
+
+  try {
+    const notice = await chatService.addNotice(chatRoomId, sender, message);
+    res.status(200).json(notice);
+  } catch (error) {
+    console.error('Error adding notice:', error.message);
+    res.status(500).json({ error: 'Failed to add notice' });
+  }
+};
+
+// 理쒖떊 怨듭� 議고쉶
+exports.getLatestNotice = async (req, res) => {
+  const { chatRoomId } = req.params;
+
+  try {
+    const latestNotice = await chatService.getLatestNotice(chatRoomId);
+    if (latestNotice) {
+      res.status(200).json(latestNotice);
+    } else {
+      res.status(404).json({ message: 'No notices found' });
+    }
+  } catch (error) {
+    console.error('Error fetching latest notice:', error.message);
+    res.status(500).json({ error: 'Failed to fetch latest notice' });
+  }
+};
+
+// 怨듭� �꾩껜 議고쉶
+exports.getAllNotices = async (req, res) => {
+  const { chatRoomId } = req.params;
+
+  try {
+    const notices = await chatService.getAllNotices(chatRoomId);
+    console.log(`[getAllNotices] Notices for chatRoomId ${chatRoomId}:`, notices); // 濡쒓렇 異붽�
+    res.status(200).json(notices);
+  } catch (error) {
+    console.error('Error fetching all notices:', error.message);
+    res.status(500).json({ error: 'Failed to fetch all notices' });
+  }
+};
+
+// 怨듭��ы빆 �곸꽭 議고쉶
+exports.getNoticeById = async (req, res) => {
+  const { chatRoomId, noticeId } = req.params;
+
+  try {
+    const notice = await chatService.getNoticeById(chatRoomId, noticeId);
+
+    if (!notice) {
+      return res.status(404).json({ error: 'Notice not found' });
+    }
+
+    res.status(200).json(notice);
+  } catch (error) {
+    console.error('Error fetching notice by ID:', error.message);
+    res.status(500).json({ error: 'Failed to fetch notice by ID' });
+  }
 };
\ No newline at end of file
diff --git a/routes/chatRoute.js b/routes/chatRoute.js
index 6ae03f1..e7c2769 100644
--- a/routes/chatRoute.js
+++ b/routes/chatRoute.js
@@ -10,5 +10,9 @@ router.get('/unread-messages/:nickname', chatController.getUnreadMessages);
 router.get('/unread-count/:chatRoomId', chatController.getUnreadCount);
 router.post('/update-status-and-logid', chatController.updateStatusAndLogId);
 router.post('/update-read-log-id', chatController.updateReadLogId);
+router.post('/:chatRoomId/notices', chatController.addNotice); 
+router.get('/:chatRoomId/notices/latest', chatController.getLatestNotice); 
+router.get('/:chatRoomId/notices', chatController.getAllNotices);
+router.get('/:chatRoomId/notices/:noticeId', chatController.getNoticeById);
 
 module.exports = router;
diff --git a/schemas/ChatRooms.js b/schemas/ChatRooms.js
index 323bb94..beaba10 100644
--- a/schemas/ChatRooms.js
+++ b/schemas/ChatRooms.js
@@ -1,7 +1,5 @@
-//schemas/chatRooms.js
 const mongoose = require('mongoose');
 
-// MongoDB 梨꾪똿諛� �ㅽ궎留� �섏젙 (FCM �좏겙�� 諛곗뿴濡� 愿�由�)
 const chatRoomsSchema = new mongoose.Schema({
   chatRoomId: { type: String, required: true, unique: true },
   chatRoomName: { type: String, required: true },
@@ -18,6 +16,11 @@ const chatRoomsSchema = new mongoose.Schema({
   lastReadAt: { type: Map, of: Date },
   lastReadLogId: { type: Map, of: String },
   isOnline: { type: Map, of: Boolean },
+  notices: [{ 
+    sender: { type: String },
+    message: { type: String },
+    timestamp: { type: Date, default: Date.now }, 
+  }]
 }, { collection: 'chatrooms' });
 
 const ChatRooms = mongoose.models.ChatRooms || mongoose.model('ChatRooms', chatRoomsSchema);
diff --git a/services/chatService.js b/services/chatService.js
index 0d462a5..f67ee42 100644
--- a/services/chatService.js
+++ b/services/chatService.js
@@ -209,6 +209,87 @@ class ChatService {
     }
   }
 
+  // 怨듭��ы빆 異붽�
+  async addNotice(chatRoomId, sender, message) {
+    try {
+      const newNotice = {
+        sender,
+        message,
+        timestamp: new Date(),
+      };
+
+      const updatedChatRoom = await ChatRooms.findOneAndUpdate(
+        { chatRoomId },
+        { $push: { notices: newNotice } }, // 怨듭��ы빆 諛곗뿴�� 異붽�
+        { new: true }
+      );
+
+      if (!updatedChatRoom) {
+        throw new Error('Chat room not found');
+      }
+
+      return newNotice;
+    } catch (error) {
+      console.error('Error adding notice:', error.message);
+      throw new Error('Failed to add notice');
+    }
+  }
+
+  // 理쒖떊 怨듭��ы빆 議고쉶
+  async getLatestNotice(chatRoomId) {
+    try {
+      const chatRoom = await ChatRooms.findOne(
+        { chatRoomId },
+        { notices: { $slice: -1 } } // 理쒖떊 怨듭� 1媛쒕쭔 媛��몄삤湲�
+      );
+
+      if (!chatRoom || chatRoom.notices.length === 0) {
+        return null;
+      }
+
+      return chatRoom.notices[0];
+    } catch (error) {
+      console.error('Error fetching latest notice:', error.message);
+      throw new Error('Failed to fetch latest notice');
+    }
+  }
+
+  // 怨듭��ы빆 �꾩껜 議고쉶
+  async getAllNotices(chatRoomId) {
+    try {
+      const chatRoom = await ChatRooms.findOne({ chatRoomId }, { notices: 1 });
+
+      if (!chatRoom) {
+        throw new Error('Chat room not found');
+      }
+
+      return chatRoom.notices;
+    } catch (error) {
+      console.error('Error fetching all notices:', error.message);
+      throw new Error('Failed to fetch all notices');
+    }
+  }
+
+  // 怨듭��ы빆 �곸꽭 議고쉶
+  async getNoticeById(chatRoomId, noticeId) {
+    try {
+      const chatRoom = await ChatRooms.findOne({ chatRoomId });
+      if (!chatRoom) {
+        throw new Error('Chat room not found');
+      }
+
+      const notice = chatRoom.notices.find(notice => notice._id.toString() === noticeId);
+      if (!notice) {
+        throw new Error('Notice not found');
+      }
+
+      return notice;
+    } catch (error) {
+      console.error('Error in getNoticeById:', error.message);
+      throw error;
+    }
+  }
+
 }
 
 module.exports = new ChatService();
\ No newline at end of file
-- 
GitLab


From 45d6eb5e8a069019e6087f2d36027295a73ee586 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=8B=AC=EC=9E=AC=EC=97=BD?= <jysim0326@ajou.ac.kr>
Date: Sun, 8 Dec 2024 15:56:04 +0900
Subject: [PATCH 47/61] =?UTF-8?q?refactor:=20=EC=A4=91=EB=B3=B5=20?=
 =?UTF-8?q?=EC=BD=94=EB=93=9C=20=ED=86=B5=ED=95=A9,=20rabbitmq=20=EC=97=B0?=
 =?UTF-8?q?=EA=B2=B0=20=EC=9C=A0=EC=A7=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 wsServer.js | 651 ++++++++++++++++++++++++++++++++--------------------
 1 file changed, 401 insertions(+), 250 deletions(-)

diff --git a/wsServer.js b/wsServer.js
index e938ef8..fa69548 100644
--- a/wsServer.js
+++ b/wsServer.js
@@ -5,22 +5,21 @@ const mongoose = require('mongoose');
 const admin = require('firebase-admin');
 const dotenv = require('dotenv');
 const amqp = require('amqplib'); // RabbitMQ �곌껐
-const ChatRoom = require('./schemas/chatRooms');
+const ChatRoom = require('./schemas/ChatRooms');
 
 // .env �뚯씪 濡쒕뱶
 dotenv.config();
 
-// �쒕퉬�� 怨꾩젙 �� �뚯씪 寃쎈줈瑜� �섍꼍 蹂��섏뿉�� 媛��몄삤湲�
-const serviceAccountPath = process.env.FIREBASE_CREDENTIAL_PATH;
+const HEARTBEAT_TIMEOUT = 10000; // 10珥� �� ���꾩븘��
 
-// Firebase Admin SDK 珥덇린��
-admin.initializeApp({
-  credential: admin.credential.cert(require(serviceAccountPath)),
-});
+// RabbitMQ �곌껐 �� �앹꽦
+let amqpConnection, amqpChannel;
 
 // WebSocket 愿��� �곗씠��
 let clients = [];
-let chatRooms = {};
+
+// �대씪�댁뼵�� �곹깭瑜� ���ν븯�� Map
+const clientHeartbeats = new Map();
 
 // MongoDB �곌껐 �ㅼ젙
 async function connectMongoDB() {
@@ -39,14 +38,35 @@ async function connectMongoDB() {
   }
 }
 
-// RabbitMQ 硫붿떆吏� 諛쒗뻾 �⑥닔
+// // RabbitMQ 硫붿떆吏� 諛쒗뻾 �⑥닔
+// async function publishToQueue(queue, message) {
+//   const connection = await amqp.connect(process.env.RABBITMQ_URL || 'amqp://localhost');
+//   const channel = await connection.createChannel();
+//   await channel.assertQueue(queue, { durable: true });
+//   channel.sendToQueue(queue, Buffer.from(JSON.stringify(message)));
+//   console.log(`Message sent to queue ${queue}:`, message);
+//   setTimeout(() => connection.close(), 500); // �곌껐 �リ린
+// }
+
+async function setupRabbitMQ() {
+  try {
+    amqpConnection = await amqp.connect(process.env.RABBITMQ_URL || 'amqp://localhost');
+    amqpChannel = await amqpConnection.createChannel();
+    console.log('RabbitMQ connection established');
+  } catch (err) {
+    logError('RabbitMQ Setup', err);
+    process.exit(1);
+  }
+}
+
 async function publishToQueue(queue, message) {
-  const connection = await amqp.connect(process.env.RABBITMQ_URL || 'amqp://localhost');
-  const channel = await connection.createChannel();
-  await channel.assertQueue(queue, { durable: true });
-  channel.sendToQueue(queue, Buffer.from(JSON.stringify(message)));
-  console.log(`Message sent to queue ${queue}:`, message);
-  setTimeout(() => connection.close(), 500); // �곌껐 �リ린
+  try {
+    await amqpChannel.assertQueue(queue, { durable: true });
+    amqpChannel.sendToQueue(queue, Buffer.from(JSON.stringify(message)));
+    console.log(`Message sent to queue ${queue}:`, message);
+  } catch (err) {
+    logError('RabbitMQ Publish', err);
+  }
 }
 
 // RabbitMQ瑜� �듯빐 �몄떆 �뚮┝ �붿껌�� �꾩넚�섎뒗 �⑥닔
@@ -67,237 +87,355 @@ async function getChatHistory(chatRoomId) {
   return chatRoom ? chatRoom.messages : [];
 }
 
-// WebSocket �쒕쾭 �앹꽦 諛� �몃뱶�곗씠�� 泥섎━
 function startWebSocketServer() {
-  const wsServer = http.createServer((req, res) => {
+  const server = http.createServer((req, res) => {
     res.writeHead(200, { 'Content-Type': 'text/plain' });
     res.end('WebSocket server is running');
   });
 
-  wsServer.on('upgrade', (req, socket, head) => {
-    const key = req.headers['sec-websocket-key'];
-    const acceptKey = generateAcceptValue(key);
-    const responseHeaders = [
-      'HTTP/1.1 101 Switching Protocols',
-      'Upgrade: websocket',
-      'Connection: Upgrade',
-      `Sec-WebSocket-Accept: ${acceptKey}`
-    ];
-    socket.write(responseHeaders.join('\r\n') + '\r\n\r\n');
-
-    // �대씪�댁뼵�몃� clients 諛곗뿴�� 異붽�
-    clients.push(socket);
-
-    let chatRoomId = null;
-    let nickname = null;
-
-    socket.on('data', async buffer => {
-      let message;
-      try {
-        message = parseMessage(buffer);
-        const parsedData = JSON.parse(message);
-        const { type, chatRoomId: clientChatRoomId, nickname: clientNickname, text } = parsedData;
-
-        console.log('�쒕쾭�먯꽌 �섏떊�� 硫붿떆吏�:', { type, clientChatRoomId, clientNickname, text });
-
-        if (type === 'join' || type === 'leave') {
-          await ChatRoom.updateOne(
-            { chatRoomId: clientChatRoomId },
-            { $set: { [`isOnline.${clientNickname}`]: type === 'join' } }
-          );
-
-          const statusMessage = {
-            type: 'status',
-            chatRoomId: clientChatRoomId,
-            nickname: clientNickname,
-            isOnline: type === 'join',
-          };
-
-          clients.forEach(client => {
-            client.write(constructReply(JSON.stringify(statusMessage)));
-          });
-        }
-
-        if (type === 'join') {
-          chatRoomId = clientChatRoomId;
-          nickname = clientNickname;
-
-          await ChatRoom.updateOne(
-            { chatRoomId },
-            {
-              $set: {
-                [`isOnline.${nickname}`]: true,
-                [`lastReadLogId.${nickname}`]: null,
-              },
-            }
-          );
-
-          if (!chatRooms[chatRoomId]) {
-            chatRooms[chatRoomId] = [];
-          }
-
-          const chatRoom = await ChatRoom.findOne({ chatRoomId });
-
-          // 李멸��� �뺤씤
-          const participantIndex = chatRoom.participants.findIndex(participant => participant.name === nickname);
-          if (participantIndex !== -1) {
-            const existingParticipant = chatRoom.participants[participantIndex];
-
-            // 李멸��� �곹깭 �낅뜲�댄듃
-            existingParticipant.isOnline = true;
-            existingParticipant.lastReadAt = new Date();
-
-            await chatRoom.save();
-          } else {
-            // �� 李멸��� 異붽�
-            const joinMessage = {
-              message: `${nickname}�섏씠 李멸��덉뒿�덈떎.`,
-              timestamp: new Date(),
-              type: 'join'
-            };
-
-            chatRoom.participants.push({
-              name: nickname,
-              fcmTokens: parsedData.fcmToken ? [parsedData.fcmToken] : [],
-              lastReadAt: new Date(),
-              lastReadLogId: null,
-              isOnline: true,
-            });
-
-            chatRoom.messages.push(joinMessage);
-
-            await chatRoom.save();
-
-            clients.forEach(client => {
-              client.write(constructReply(JSON.stringify(joinMessage)));
-            });
-
-            console.log(`${nickname} �� 李멸��먮줈 異붽�`);
-          }
-
-          try {
-            const previousMessages = await getChatHistory(chatRoomId);
-            if (previousMessages.length > 0) {
-              socket.write(constructReply(JSON.stringify({ type: 'previousMessages', messages: previousMessages })));
-              console.log(`�댁쟾 硫붿떆吏� �꾩넚: ${previousMessages.length}媛�`);
-            } 
-          } catch (err) {
-            console.error('�댁쟾 梨꾪똿 湲곕줉 遺덈윭�ㅺ린 以� �ㅻ쪟 諛쒖깮:', err);
-          }
-
-        } else if (type === 'message') {
-          const chatMessage = {
-            message: text,
-            timestamp: new Date(),
-            type: 'message',
-            sender: nickname
-          };
-
-
-          chatRooms[chatRoomId].push(chatMessage);
-
-          try {
-            // �덈줈�� 硫붿떆吏�瑜� messages 諛곗뿴�� 異붽�
-            const updatedChatRoom = await ChatRoom.findOneAndUpdate(
-              { chatRoomId }, 
-              { $push: { messages: chatMessage } },
-              { new: true, fields: { "messages": { $slice: -1 } } }  // 留덉�留� 異붽��� 硫붿떆吏�留� 媛��몄샂
-            );
-
-            // 留덉�留됱뿉 異붽��� 硫붿떆吏��� _id瑜� 媛��몄삤湲�
-            const savedMessage = updatedChatRoom.messages[updatedChatRoom.messages.length - 1];
-
-            // �덈줈�� 硫붿떆吏� �꾩넚: �대씪�댁뼵�몃줈 硫붿떆吏� 釉뚮줈�쒖틦�ㅽ듃
-            const messageData = {
-              type: 'message',
-              chatRoomId,
-              sender: nickname,
-              message: text,
-              timestamp: chatMessage.timestamp,
-              _id: savedMessage._id  // ���λ맂 硫붿떆吏��� _id �ъ슜
-            };
-
-            clients.forEach(client => {
-              client.write(constructReply(JSON.stringify(messageData)));
-              console.log('梨꾪똿 硫붿떆吏� �꾩넚:', messageData);
-            });
-
-            // �ㅽ봽�쇱씤 �ъ슜�먯뿉寃� FCM �몄떆 �뚮┝ �꾩넚
-            const chatRoom = await ChatRoom.findOne({ chatRoomId });
-            const offlineParticipants = chatRoom.participants.filter(participant => {
-            // isOnline �곹깭瑜� Map�먯꽌 媛��몄삤湲�
-            const isOnline = chatRoom.isOnline.get(participant.name);
-              return isOnline === false; // �뺥솗�� false�� �ъ슜�먮쭔 �꾪꽣留�
-            });
-
-            console.log("offlineParticipants", offlineParticipants);
-
-            // RabbitMQ�� �몄떆 �뚮┝ �붿껌 諛쒗뻾
-            await sendPushNotificationRequest(chatRoom.chatRoomName, clientNickname, text, offlineParticipants, chatRoomId);
-          } catch (err) {
-            console.error('MongoDB 梨꾪똿 硫붿떆吏� ���� �ㅻ쪟:', err);
-          }
-        } else if (type === 'leave') {
-          const leaveMessage = { 
-            message: `${nickname}�섏씠 �댁옣�덉뒿�덈떎.`, 
-            timestamp: new Date(),
-            type: 'leave'
-          };
-          
-          chatRooms[chatRoomId].push(leaveMessage);
-
-          await ChatRoom.updateOne(
-            { chatRoomId },
-            { $set: { [`isOnline.${nickname}`]: false } }
-          );
-
-          await ChatRoom.updateOne({ chatRoomId }, {
-            $push: { messages: leaveMessage },
-            $pull: { participants: nickname }
-          });
-
-          clients.forEach(client => {
-            client.write(constructReply(JSON.stringify(leaveMessage)));
-          });
-
-          clients = clients.filter(client => client !== socket);
-        }
-      } catch (err) {
-        console.error('硫붿떆吏� 泥섎━ 以� �ㅻ쪟 諛쒖깮:', err);
-      }
-    });
+  server.on('upgrade', (req, socket, head) => {
+    handleWebSocketUpgrade(req, socket);
+  });
 
-    socket.on('close', async () => {
-      if (nickname && chatRoomId) {
-        await ChatRoom.updateOne(
-          { chatRoomId },
-          { $set: { [`isOnline.${nickname}`]: false } }
-        );
-
-        const statusMessage = {
-          type: 'status',
-          chatRoomId,
-          nickname,
-          isOnline: false,
-        };
-
-        clients.forEach(client => {
-          client.write(constructReply(JSON.stringify(statusMessage)));
-        });
-      }
+  server.listen(8081, () => {
+    console.log('WebSocket 梨꾪똿 �쒕쾭媛� 8081 �ы듃�먯꽌 �ㅽ뻾 以묒엯�덈떎.');
+  });
+}
+
+function handleWebSocketUpgrade(req, socket) {
+  const key = req.headers['sec-websocket-key'];
+  const acceptKey = generateAcceptValue(key);
+  const responseHeaders = [
+    'HTTP/1.1 101 Switching Protocols',
+    'Upgrade: websocket',
+    'Connection: Upgrade',
+    `Sec-WebSocket-Accept: ${acceptKey}`
+  ];
+
+  socket.write(responseHeaders.join('\r\n') + '\r\n\r\n');
+
+  // �대씪�댁뼵�몃� clients 諛곗뿴�� 異붽�
+  clients.push(socket);
+
+  socket.on('data', async buffer => {
+    try {
+      message = parseMessage(buffer);
+      if (!message) return; // 硫붿떆吏�媛� 鍮꾩뼱 �덈뒗 寃쎌슦 臾댁떆
+
+      const parsedData = JSON.parse(message);
+      const { type, chatRoomId: clientChatRoomId, nickname: clientNickname, text } = parsedData;
+      await handleClientMessage(socket, parsedData);
+    } catch (err) {
+      console.error('Error processing message:', err);
+    }
+  });
+
+  socket.on('close', async () => {
+
+      console.log(`WebSocket �곌껐�� 醫낅즺�섏뿀�듬땲��: ${socket.nickname}, ${socket.chatRoomId}`);
+
+      // �대씪�댁뼵�� Heartbeat 留듭뿉�� �쒓굅
+      clientHeartbeats.delete(socket);
+
+      // �대씪�댁뼵�� 紐⑸줉�먯꽌 �쒓굅
+      clients = clients.filter((client) => client !== socket);
+
+
+      // �뚯폆 醫낅즺 ��, 李� �リ린 or hidden �뚮Ц�� �대� �⑤씪�� �곹깭 false濡� �� (以묐났 濡쒖쭅 二쇱꽍 泥섎━)
+      // if (socket.nickname && socket.chatRoomId) {
+      //   await ChatRoom.updateOne(
+      //     { chatRoomId: socket.chatRoomId },
+      //     { $set: { [`isOnline.${socket.nickname}`]: false } }
+      //   );
+      // }
+  });
+
+  socket.on('error', (err) => {
+    console.error(`WebSocket error: ${err}`);
+    clients = clients.filter((client) => client !== socket);
+  });
+
+}
+
+// 硫붿떆吏� ���� 泥섎━
+async function handleClientMessage(socket, data) {
+  const { type, chatRoomId, nickname, text, fcmToken } = data;
+
+  // ���꾩븘�껊맂 �뚯폆 李⑤떒
+  if (socket.isTimedOut) {
+    console.log(`���꾩븘�껊맂 �대씪�댁뼵�몄쓽 �ъ뿰寃곗쓣 李⑤떒: ${nickname}`);
+    return;
+  }
+
+  switch (type) {
+    case 'heartbeat':
+      // console.log(`Heartbeat received from ${nickname} in room ${chatRoomId}`);
+      clientHeartbeats.set(socket, Date.now());
+      break;
+    case 'join':
+      // WebSocket�� �ъ슜�� �뺣낫 ����
+      // socket.nickname = nickname;
+      // socket.chatRoomId = chatRoomId;
+      await handleJoin(socket, chatRoomId, nickname, fcmToken);
+      break;
+    case 'message':
+      await handleMessage(chatRoomId, nickname, text);
+      break;
+    case 'leave':
+      await handleLeave(chatRoomId, nickname);
+      break;
+    case 'notice':
+      await handleSetNotice(chatRoomId, nickname, text);
+      break;
+    default:
+      console.log(`Unknown message type: ${type}`);
+  }
+}
+
+// join - 李멸� 硫붿떆吏�
+async function handleJoin(socket, chatRoomId, nickname) {
+  if (socket.isTimedOut) {
+    console.log(`���꾩븘�껊맂 �대씪�댁뼵�몄쓽 �ъ갭�щ� 李⑤떒: ${nickname}`);
+    return;
+  }
+
+  // Set client properties
+  socket.chatRoomId = chatRoomId;
+  socket.nickname = nickname;
+
+  console.log(`Client joined room: ${chatRoomId}, nickname: ${nickname}`);
+
+  await ChatRoom.updateOne(
+    { chatRoomId: chatRoomId },
+    { $set: { [`isOnline.${nickname}`]:true } }
+  );
+
+  const statusMessage = {
+    type: 'status',
+    chatRoomId: chatRoomId,
+    nickname: nickname,
+    isOnline: true,
+  };
+
+  broadcastMessage(chatRoomId, statusMessage);
+
+  await ChatRoom.updateOne(
+    { chatRoomId },
+    { $set: {
+      [`isOnline.${nickname}`]: true,
+      [`lastReadLogId.${nickname}`]: null,
+      },
+    }
+  );
+
+  const chatRoom = await ChatRoom.findOne({ chatRoomId });
+
+  // 李멸��� �뺤씤
+  const participantIndex = chatRoom.participants.findIndex(participant => participant.name === nickname);
+  
+  if (participantIndex !== -1) {
+      const existingParticipant = chatRoom.participants[participantIndex];
+
+      // 李멸��� �곹깭 �낅뜲�댄듃
+      existingParticipant.isOnline = true;
+      existingParticipant.lastReadAt = new Date();
+
+      await chatRoom.save();
+    } else {
+      // �� 李멸��� 異붽�
+      const joinMessage = {
+        message: `${nickname}�섏씠 李멸��덉뒿�덈떎.`,
+        timestamp: new Date(),
+        type: 'join'
+      };
+
+      chatRoom.participants.push({
+        name: nickname,
+        fcmTokens: parsedData.fcmToken ? [parsedData.fcmToken] : [],
+        lastReadAt: new Date(),
+        lastReadLogId: null,
+        isOnline: true,
+      });
+
+      chatRoom.messages.push(joinMessage);
+
+      await chatRoom.save();
+
+      broadcastMessage(chatRoomId, joinMessage);
+
+      console.log(`${nickname} �� 李멸��먮줈 異붽�`);
+    }
+
+  const previousMessages = await getChatHistory(chatRoomId);
+  if (previousMessages.length > 0) {
+    socket.write(constructReply(JSON.stringify({ type: 'previousMessages', messages: previousMessages })));
+  }
+}
+
+// meessage - �쇰컲 硫붿떆吏�
+async function handleMessage(chatRoomId, nickname, text) {
+  const chatMessage = { message: text, timestamp: new Date(), type: 'message', sender: nickname };
+
+  try {
+    const updatedChatRoom = await ChatRoom.findOneAndUpdate(
+      { chatRoomId },
+      { $push: { messages: chatMessage } },
+      { new: true, fields: { messages: { $slice: -1 } } }
+    );
+
+    // 留덉�留됱뿉 異붽��� 硫붿떆吏��� _id瑜� 媛��몄삤湲�
+    const savedMessage = updatedChatRoom.messages[updatedChatRoom.messages.length - 1];
+
+    // �덈줈�� 硫붿떆吏� �꾩넚: �대씪�댁뼵�몃줈 硫붿떆吏� 釉뚮줈�쒖틦�ㅽ듃
+    const messageData = {
+      type: 'message',
+      chatRoomId,
+      sender: nickname,
+      message: text,
+      timestamp: chatMessage.timestamp,
+      _id: savedMessage._id  // ���λ맂 硫붿떆吏��� _id �ъ슜
+    };
+
+    console.log('梨꾪똿�먯꽌 Current clients:', clients.map(client => client.chatRoomId));
+
+    // broadcastMessage(chatRoomId, messageData);
+
+    clients.forEach(client => {
+      client.write(constructReply(JSON.stringify(messageData)));
+      console.log('梨꾪똿 硫붿떆吏� �꾩넚:', messageData);
     });
 
-    socket.on('error', (err) => {
-      console.error(`WebSocket error: ${err}`);
-      clients = clients.filter(client => client !== socket);
+    // �ㅽ봽�쇱씤 �ъ슜�먯뿉寃� FCM �몄떆 �뚮┝ �꾩넚
+    const chatRoom = await ChatRoom.findOne({ chatRoomId });
+    const offlineParticipants = chatRoom.participants.filter(participant => {
+      // isOnline �곹깭瑜� Map�먯꽌 媛��몄삤湲�
+      const isOnline = chatRoom.isOnline.get(participant.name);
+      return isOnline === false; // �뺥솗�� false�� �ъ슜�먮쭔 �꾪꽣留�
     });
+
+    console.log("offlineParticipants", offlineParticipants);
+
+    // RabbitMQ�� �몄떆 �뚮┝ �붿껌 諛쒗뻾
+    await sendPushNotificationRequest(chatRoom.chatRoomName, nickname, text, offlineParticipants, chatRoomId);
+    
+  } catch (err) {
+    console.error('Error saving message to MongoDB:', err);
+  }
+}
+
+// leave - �댁옣 硫붿떆吏�
+async function handleLeave(chatRoomId, nickname) {
+  await ChatRoom.updateOne(
+    { chatRoomId: clientChatRoomId },
+    { $set: { [`isOnline.${clientNickname}`]: type === 'leave' } }
+  );
+
+  const statusMessage = {
+    type: 'status',
+    chatRoomId: clientChatRoomId,
+    nickname: clientNickname,
+    isOnline: type === 'leave',
+  };
+
+  clients.forEach(client => {
+    client.write(constructReply(JSON.stringify(statusMessage)));
   });
 
-  wsServer.listen(8081, () => {
-    console.log('WebSocket 梨꾪똿 �쒕쾭媛� 8081 �ы듃�먯꽌 �ㅽ뻾 以묒엯�덈떎.');
+  const leaveMessage = { message: `${nickname} �섏씠 �댁옣�덉뒿�덈떎.`, timestamp: new Date(), type: 'leave' };
+  await ChatRoom.updateOne({ chatRoomId }, { $push: { messages: leaveMessage } });
+  broadcastMessage(chatRoomId, leaveMessage);
+}
+
+async function handleSetNotice(chatRoomId, sender, message) {
+  const notice = {
+    sender,
+    message,
+    timestamp: new Date(),
+  };
+
+  try {
+    // MongoDB�� 理쒖떊 怨듭� ����
+    await ChatRoom.updateOne(
+      { chatRoomId },
+      { $push: { notices: notice } }
+    );
+
+    // 紐⑤뱺 �대씪�댁뼵�몄뿉寃� 怨듭��ы빆 �낅뜲�댄듃 硫붿떆吏� �꾩넚
+    const noticeMessage = {
+      type: 'notice',
+      chatRoomId,
+      sender,
+      message,
+    };
+    
+    clients.forEach(client => {
+      client.write(constructReply(JSON.stringify(noticeMessage)));
+    });
+
+    // broadcastMessage(chatRoomId, noticeMessage);
+
+    console.log('怨듭��ы빆 �낅뜲�댄듃:', noticeMessage);
+  } catch (error) {
+    console.error('怨듭��ы빆 �낅뜲�댄듃 �ㅽ뙣:', error);
+  }
+}
+
+// Broadcast message to clients in the same chat room
+function broadcastMessage(chatRoomId, message) {
+  clients.forEach((client) => {
+    if (client.chatRoomId === chatRoomId) {
+      client.write(constructReply(JSON.stringify(message)));
+    }
   });
 }
 
+// 二쇨린�곸쑝濡� Heartbeat �곹깭 �뺤씤
+setInterval(async () => {
+  const now = Date.now();
+  for (const [socket, lastHeartbeat] of clientHeartbeats.entries()) {
+    if (now - lastHeartbeat > HEARTBEAT_TIMEOUT) {
+      console.log('���꾩븘�� ���� �대씪�댁뼵��:', {
+        nickname: socket.nickname,
+        chatRoomId: socket.chatRoomId,
+        lastHeartbeat: new Date(lastHeartbeat).toISOString(),
+      });
+
+      // Heartbeat 留듭뿉�� �쒓굅
+      clientHeartbeats.delete(socket);
+
+      // �곹깭 �뚮옒洹� �ㅼ젙
+      socket.isTimedOut = true;
+
+       // �뚯폆 �곌껐 醫낅즺
+      socket.end();
+
+      // �대씪�댁뼵�� 紐⑸줉�먯꽌 �쒓굅
+      clients = clients.filter((client) => client !== socket);
+
+      // �대씪�댁뼵�몃� �ㅽ봽�쇱씤�쇰줈 �ㅼ젙
+      console.log("Client timed out �� �ㅽ봽�쇱씤 �ㅼ젙");
+      await ChatRoom.updateOne(
+        { [`isOnline.${socket.nickname}`]: false },
+        { [`lastReadAt.${socket.nickname}`]: new Date() }
+      );
+
+      // �대씪�댁뼵�몄뿉寃� �곌껐 醫낅즺 硫붿떆吏� �꾩넚
+      const timeoutMessage = JSON.stringify({
+        type: 'status',
+        nickname: socket.nickname,
+        chatRoomId: socket.chatRoomId,
+        isOnline: false,
+      });
+      
+      clients.forEach(client => {
+        client.write(constructReply(timeoutMessage));
+      });
+
+      
+    }
+  }
+}, 5000); // 5珥덈쭏�� �곹깭 �뺤씤
+
 // Sec-WebSocket-Accept �ㅻ뜑 媛� �앹꽦 -> env泥섎━
 function generateAcceptValue(key) {
   return crypto.createHash('sha1').update(key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', 'binary').digest('base64');
@@ -305,27 +443,37 @@ function generateAcceptValue(key) {
 
 // WebSocket 硫붿떆吏� �뚯떛 �⑥닔
 function parseMessage(buffer) {
-  const byteArray = [...buffer];
-  const secondByte = byteArray[1];
-  let length = secondByte & 127;
-  let maskStart = 2;
-
-  if (length === 126) {
-    length = (byteArray[2] << 8) + byteArray[3];
-    maskStart = 4;
-  } else if (length === 127) {
-    length = 0;
-    for (let i = 0; i < 8; i++) {
-      length = (length << 8) + byteArray[2 + i];
+  try {
+    const byteArray = [...buffer];
+    const secondByte = byteArray[1];
+    let length = secondByte & 127;
+    let maskStart = 2;
+
+    if (length === 126) {
+      length = (byteArray[2] << 8) + byteArray[3];
+      maskStart = 4;
+    } else if (length === 127) {
+      length = 0;
+      for (let i = 0; i < 8; i++) {
+        length = (length << 8) + byteArray[2 + i];
+      }
+      maskStart = 10;
     }
-    maskStart = 10;
-  }
 
-  const dataStart = maskStart + 4;
-  const mask = byteArray.slice(maskStart, dataStart);
-  const data = byteArray.slice(dataStart, dataStart + length).map((byte, i) => byte ^ mask[i % 4]);
+    const dataStart = maskStart + 4;
+    const mask = byteArray.slice(maskStart, dataStart);
+    const data = byteArray.slice(dataStart, dataStart + length).map((byte, i) => byte ^ mask[i % 4]);
+
+    const decodedMessage = new TextDecoder('utf-8').decode(Uint8Array.from(data));
+
+    // JSON �좏슚�� 寃���
+    JSON.parse(decodedMessage);
 
-  return new TextDecoder('utf-8').decode(Uint8Array.from(data));
+    return decodedMessage;
+  } catch (err) {
+    console.error('Error parsing WebSocket message:', err.message);
+    return null; // �좏슚�섏� �딆� 硫붿떆吏��� 臾댁떆
+  }
 }
 
 // �대씪�댁뼵�� 硫붿떆吏� �묐떟 �앹꽦 �⑥닔
@@ -353,5 +501,8 @@ function constructReply(message) {
   return Buffer.concat([Buffer.from(reply), messageBuffer]);
 }
 
+// �쒕쾭 �쒖옉 �� RabbitMQ �ㅼ젙
+setupRabbitMQ();
+
 // MongoDB �곌껐 �� WebSocket �쒕쾭 �쒖옉
 connectMongoDB();
\ No newline at end of file
-- 
GitLab


From d2ea80ef71cb608cc0a0313cade825597a0b895b Mon Sep 17 00:00:00 2001
From: Ubuntu <ubuntu@ip-172-31-1-27.ap-northeast-2.compute.internal>
Date: Sun, 8 Dec 2024 07:17:53 +0000
Subject: [PATCH 48/61] =?UTF-8?q?refactor:=20=EC=84=9C=EB=B2=84=20?=
 =?UTF-8?q?=EB=B0=B0=ED=8F=AC=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .app2.js.swp      | Bin 0 -> 12288 bytes
 output.log        | 493 ++++++++++++++++++++++++++--------------------
 package-lock.json | 243 ++++++++++++++---------
 package.json      |   1 +
 weblog.log        |   4 +-
 5 files changed, 435 insertions(+), 306 deletions(-)
 create mode 100644 .app2.js.swp

diff --git a/.app2.js.swp b/.app2.js.swp
new file mode 100644
index 0000000000000000000000000000000000000000..d6adf66f7481c87e6cb0559f90b01bbe76f5cd3e
GIT binary patch
literal 12288
zcmeI2U2IfE6vqeoP(j3~55kKhknC2vA1zUuRxr>m(AakCe)u3U<#u=4Uf8{NxgVuV
zSwt;Z(11oLMO%cV;)BMN4@pVDk7#@{(fCAS^nv))-Aa5>6Jz3k?$_SkE<P9%LvlCy
z_1>Lx=FFKhXU<I1_J&_*@1#w^MuN{nge+T{>~HyPA!&JLA<=tvNz=LD-#=n5(6FH~
zu)ZPC5NO<Rd)))3!O&jT+bg7YhlE_NF}O>;eFsnCMZk-|or!?1^#z)iC)YPNgt@^r
ztDm5cJe<5UwmmCe1iT1%5%415MZk-I7XdE<UIe@d+!Ybfatp}I@bn(b+d=EOpz3LT
z^&VaXya;#^@FL(vz>9zv0WShx1iT1%5%415MZk-|T^Io&O~_jOvj5mZIFG;o+rR(+
zvVxE=zzOgiSOflgkdW(O5Cp&qFt?nL^WZo*1`2?IG)RID&<d7-ZyzA!Bsc)_U=ZkF
z8)yPyunJsRM#w059Vmc-BzP43y_Aq2!Pnp%&_Od;0e-)qkXdj8d<G7K6xa${KqFWO
zR)QP%5%LxI99#u6;C*ly>;hZBYH;gbLVg9`fb-x87zKl12Y3-|1uMZHOW*_e5}X2K
zfPrVhCa?tjyqJ)mz(?Q+7zHs<57vP{7ZLJ3_zrvmPJuBX0||71jo>M;3M>YTz%8ub
z4`2)&1N%S|SOXphD}k}bcVUkHFD@7A{B<pa(gL6~r^qR$szEj+YW@a8Kxs;rR5`<f
zOi^UT@4GqqCM}Ij6fcg@(i;<{GjG$<6d0c>elSjp(-WoFCYycr)X+9f)0Cj42B_a`
zqQk~e1<QKben#&1@4Pv2h{l;R$P_B7RM90#l=`VG(e7w0LDvrRM`5Sc7ynrk%!sPS
zBtLJjr~W#+ag#MbC{%WHYHsWZF@_cP3Zh2Uyp)Qid(Ej+3f0bh{P_-AIyF6eahlGZ
zK3STafxf2XVa+daeaHAb?e`D~cR;Wm5i-qmd1E=K(qPb-#s2-YDclrpAw-l!EuI=+
zX+6VQGfa?}!hPbdADt>)J6M_;p>wZXE}s9mI5J90mq%x3rsqzdAcW6cSDD|3|1J_k
zD%MPtB}CnNi^;mi6j(AHsc5AeslxW?qJrMRkis=p#{#-k+0L?TFH>OJd@(Gmj%9aa
zO~Wn)-+be#0YQUl{-`osZmMb45!W!9WlTfT7%m%cRi-Vu*;>=OTcgGReTvAWH0+x%
zRp#A|HLY9S=SM@eG69zD*DBkU%{8stDmDBTbZr2(`J>8ixv8d2qa*x9UKS^>mEN76
z8=0oXcP<pqO`7SVGR^PP6dg&A5;By>D7<>uS=yHo)B%5;d&W6IRdceU1+CmPq_(~z
z<oiPuGU7gF$T5Dm)vvr6P;-uB|IL&Rja&P-oWhPF*C@l34WVMBS-P3_2^p2q0{84r
zjcwauLpg<)QeDX~DJ5e#zcYp{+oj5qJ+X+XPqD*`mu4`bsnXe#xM=*R`rIi?{c_tD
zyPn;yKx5jd{I2p`XVp$aK=CQmLBsqM>YZ0gRUymbqQ;u3Pm(2u^>zuf!qDb^h@KA9
zC(R!X;c&P@MP(^nfeLbl)${thJ(1{+qwtQ;Uc6p9^%k$EAL5)j^LFw0X_x5%P0K~4
zOy270NK&%ATZBFHY@zrR>fHWnTE_9G!jY7m$*`1$>e+=UVLDc(#5Gx|npV2kRB;YT
z)bq}0*S2U++m@cL&7Bd7!fyAkiU?niqyiu2cTUFIT^^}?+-7Plpy5L>r7%Hb{_@Ne
zxQzN%9RgJtWJ#Qs_KvaByBr4OBXq2+FE?W?6sA?W7LUZ^?a{8Dc%(HJNf;B$%eoRU
zbpyK@wzw61duy2v+Uaiy`8j57Oe>xF%Gmb_e%|}|d0(BaBNt{beah<>*ESDq^pUVk
zmL|?f<IJwia(|@~ExvlWc;%p(Of<`NWt9ajB|0}gQ@S!?rZ@bo^Z_H^_UNx1)Lndz
zPR$)YTN=CUY+iGJnPVWvX(sV%rn*;7$YkWbEWMoxX{JE3!`CWHC{J1-k<al2^le7D
zmKAZIz?0PXk{R|aLu1;|-xf)5weD!#d?t-YTcjhBh;Tu)JAsvq+dW~bUz9MAI}^9Y
zqLHpdPcqhl4t$TP&7n|UkP!T!Iw0rF&M8?@k%!I_BW$hFSlpSeEy&7BzaaU2X*THN
zr4@R`a}%>y4>_7x1RNF6$8lp7Lw@fuo2|=P<w?XFkrI5_+q3-OpxOX4?s08`CiDs@
z<9)hhY-G!f>4n>h*}@ac9Ei`yE$83M(qUYt_UMcsKB$oumnL-Y6Z>&#vgDRyar?V{
z4%x%FbGN1?J3B2yRmo_Y8KyOEi`Aa#nwY_D&bmk_<=GfVuzPG6<vS{12+Df)iRo4i
zhV0g|p5dZVpxm0aQDZ*Uld&p+y-V!XHt()(D^^CJ*qGN^XTdB%4PEY-bE{3u*g!}<
LzSpr%JhT1*G7#nx

literal 0
HcmV?d00001

diff --git a/output.log b/output.log
index 6df63b6..2b17d41 100644
--- a/output.log
+++ b/output.log
@@ -1,223 +1,288 @@
 MongoDB URI: mongodb+srv://admin:lim1234!!@goodmeeting.vkniz.mongodb.net/
-(node:182036) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:212097) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 (Use `node --trace-warnings ...` to show where the warning was created)
-(node:182036) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:212097) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 �� MongoDB �곌껐 �깃났
 Rdb�곗씠�곕쿋�댁뒪 �곌껐 �깃났.
 紐⑤뱺 紐⑤뜽�� �깃났�곸쑝濡� �숆린�붾릺�덉뒿�덈떎.
 Server is running on 8080
-GET /api/session/info 401 8.594 ms - 76
-GET /api/auth/login 302 3.050 ms - 0
-GET /api/auth/google/callback?code=4%2F0AeanS0ao8f60iPWO2lFPG-75VwKyiSOn5kXy7WYogowBYIKp-Rqv0m-ctgybXxfZXLTMFA&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&authuser=1&hd=ajou.ac.kr&prompt=none 302 532.811 ms - 48
-GET /api/session/info 200 7.414 ms - 60
-GET /api/session/info 200 4.780 ms - 60
-GET /api/schedule/all 304 19.397 ms - -
-Performance Measurement - getAllSchedules: 5.005846977233887ms
-GET /api/schedule/289 304 16.458 ms - -
-Performance Measurement - getScheduleByTimeIdx: 11.750297963619232ms
-GET /api/schedule/193 304 7.581 ms - -
-Performance Measurement - getScheduleByTimeIdx: 3.6492010354995728ms
-GET /api/schedule/193 304 7.722 ms - -
-Performance Measurement - getScheduleByTimeIdx: 3.8008620142936707ms
-GET /api/schedule/193 304 9.777 ms - -
-Performance Measurement - getScheduleByTimeIdx: 4.146169006824493ms
-GET /api/schedule/192 200 8.365 ms - 26
-Performance Measurement - getScheduleByTimeIdx: 4.420195996761322ms
-GET /api/schedule/7 200 7.684 ms - 26
-Performance Measurement - getScheduleByTimeIdx: 3.8003939986228943ms
-GET /api/schedule/103 304 8.917 ms - -
-Performance Measurement - getScheduleByTimeIdx: 3.626570999622345ms
-GET /api/schedule/4 200 7.304 ms - 26
-Performance Measurement - getScheduleByTimeIdx: 3.7574750185012817ms
-GET /api/schedule/102 304 9.324 ms - -
-Performance Measurement - getScheduleByTimeIdx: 4.2991169691085815ms
-GET /api/schedule/199 200 7.638 ms - 26
-Performance Measurement - getScheduleByTimeIdx: 3.934753954410553ms
-GET /api/schedule/196 200 7.331 ms - 26
-Performance Measurement - getScheduleByTimeIdx: 3.7636460065841675ms
-GET /api/schedule/99 304 8.753 ms - -
-Performance Measurement - getScheduleByTimeIdx: 3.7125409841537476ms
-GET /api/schedule/99 304 6.852 ms - -
-Performance Measurement - getScheduleByTimeIdx: 3.625138998031616ms
-GET /api/schedule/105 200 7.316 ms - 26
-Performance Measurement - getScheduleByTimeIdx: 3.6936269998550415ms
-GET /api/schedule/2 200 9.041 ms - 26
-Performance Measurement - getScheduleByTimeIdx: 3.845887005329132ms
-GET /api/schedule/1 200 7.427 ms - 26
-Performance Measurement - getScheduleByTimeIdx: 3.8853600025177ms
-GET /api/schedule/1 304 7.564 ms - -
-Performance Measurement - getScheduleByTimeIdx: 4.00413304567337ms
-GET /api/session/info 200 4.063 ms - 60
-GET /api/schedule/all 304 6.780 ms - -
-Performance Measurement - getAllSchedules: 2.9270060062408447ms
-GET /api/session/info 200 4.080 ms - 60
-GET /api/session/info 200 14.763 ms - 60
-GET /api/session/info 200 4.001 ms - 60
-GET /api/session/info 200 49.452 ms - 60
-GET /api/session/info 200 16.079 ms - 60
-GET /api/schedule/all 304 51.136 ms - -
-Performance Measurement - getAllSchedules: 3.047551989555359ms
-GET / 404 2.482 ms - 139
-GET /favicon.ico 404 1.030 ms - 150
-GET http://api.ipify.org/?format=json 404 2.130 ms - 139
-GET /geoserver/web/ 404 0.934 ms - 153
-GET /api/session/info 401 1.080 ms - 76
-GET /api/session/info 401 0.698 ms - 76
-GET /api/session/info 401 0.921 ms - 76
-GET /api/session/info 401 0.587 ms - 76
-OPTIONS /api/schedule/all 204 0.404 ms - 0
-OPTIONS /api/schedule/all 204 0.138 ms - 0
-GET / 404 1.220 ms - 139
-GET /api/session/info 401 0.925 ms - 76
-GET /api/session/info 401 0.677 ms - 76
-GET /api/session/info 401 0.849 ms - 76
-GET /api/session/info 401 0.638 ms - 76
+GET /api/session/info 401 7.235 ms - 76
+GET /api/session/info 401 1.572 ms - 76
+GET /api/session/info 401 1.286 ms - 76
+GET /api/session/info 401 1.126 ms - 76
+GET /api/session/info 401 1.154 ms - 76
+GET /api/session/info 401 0.926 ms - 76
+GET /api/session/info 401 2.076 ms - 76
+GET /api/session/info 401 1.024 ms - 76
+GET / 404 2.809 ms - 139
+POST /sdk 404 2.633 ms - 143
+GET /nmaplowercheck1733630009 404 0.957 ms - 163
+GET / 404 0.955 ms - 139
+GET /HNAP1 404 1.213 ms - 144
+GET /evox/about 404 1.007 ms - 149
+GET / 404 1.171 ms - 139
+GET / 404 0.956 ms - 139
+GET /api/session/info 401 0.914 ms - 76
+GET /api/session/info 401 1.419 ms - 76
+GET /api/session/info 401 0.736 ms - 76
+GET /api/auth/login 302 3.018 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0Y8pXOIF2Ju3xckjh10Sjm1Kd0dcZycXQPzTOCxZrVv3oJM7H1v4TJfTlwRFxSDUw&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&authuser=0&hd=ajou.ac.kr&prompt=none 302 567.800 ms - 48
+GET /api/session/info 200 8.998 ms - 60
+GET /api/session/info 200 15.228 ms - 60
+GET /api/auth/logout 302 4.820 ms - 41
+GET /api/session/info 401 1.144 ms - 76
+GET /api/auth/login 302 1.160 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0aSNOTTxPm0d8V-mSO7PuFRiGZkFv1WWgoTGVqN41uFAQz8PupxFUtoSmm0ei6N1Q&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&authuser=0&hd=ajou.ac.kr&prompt=none 302 388.373 ms - 48
+GET /api/session/info 200 3.914 ms - 60
+GET /api/auth/logout 302 4.398 ms - 41
+GET /api/session/info 401 1.161 ms - 76
+GET /api/session/info 401 1.117 ms - 76
+GET /api/auth/login 302 1.137 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0bAWi6c7Y3IU6J6T4H5syJLynGlz8b0hEEMfcRCtXOzzE0Z_k9rNT2L2IV24m4Qbg&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=0&hd=ajou.ac.kr&prompt=none 302 418.058 ms - 48
+GET /api/session/info 200 4.195 ms - 60
+GET /api/session/info 200 17.752 ms - 60
+GET /api/session/info 200 5.411 ms - 60
+GET /api/auth/login 302 4.906 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0ZwocNVsHrI0WcG2DfMTBOziAdI5W13EEEqAxqK0GZkt9SYgmlB1YVor1Vd10yhOA&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=0&hd=ajou.ac.kr&prompt=none 302 445.216 ms - 48
+GET /api/session/info 200 5.122 ms - 60
+GET /api/session/info 200 4.660 ms - 60
+GET /api/session/info 200 4.893 ms - 60
+GET /api/auth/login 302 52.638 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0btwgAZvNqTiVMI1FzYcMyJpsq8zjkKCJWb86vQYUXKSpXG1nnJGdWjoJFSJ6ZIAw&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&authuser=0&hd=ajou.ac.kr&prompt=none 302 463.694 ms - 48
+GET /api/session/info 200 6.067 ms - 60
+GET /api/session/info 200 15.746 ms - 60
+GET /api/session/info 200 3.721 ms - 60
+GET /api/session/info 401 0.880 ms - 76
+GET /api/session/info 401 0.871 ms - 76
+GET /api/auth/login 302 0.936 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0aJ-WUyPAzU9TgwB3O4zrvADfrXVvIj7TZkKvtrnnYhpAlYTEfW3F_kLg1fwOBIpw&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=0&hd=ajou.ac.kr&prompt=none 302 420.759 ms - 48
+GET /api/session/info 200 3.693 ms - 60
+GET /api/session/info 401 0.963 ms - 76
+GET /api/session/info 401 0.876 ms - 76
+GET /api/session/info 401 0.904 ms - 76
+GET /api/session/info 401 0.898 ms - 76
+GET /api/auth/login 302 0.956 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0YORfunrW6DJxJDtYvArHupwZYA_YXrpxZ-ucXSoB7ablLuwez2PrdwMyDACWTfrg&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&authuser=0&hd=ajou.ac.kr&prompt=none 302 405.688 ms - 48
+GET /api/session/info 200 3.814 ms - 60
+GET /api/auth/logout 302 15.145 ms - 41
+GET /api/session/info 401 1.060 ms - 76
+GET /api/auth/login 302 1.116 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0at8xXw-_yVufE61kassBTRFn4ybVl2gUfWoEVEh4qMv1pV1_C3-tIXH_OVtqccXA&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&authuser=0&hd=ajou.ac.kr&prompt=none 302 416.504 ms - 48
+GET /api/session/info 200 3.844 ms - 60
+GET /api/session/info 401 1.087 ms - 76
+GET /api/session/info 401 0.899 ms - 76
+GET /api/auth/login 302 0.909 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0ayNExQE74cwz6uRTNs-Cl1t7nizv7EppTOoCMHdWhcmXC87ugbLXufp-YwfkKRCQ&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&authuser=0&hd=ajou.ac.kr&prompt=none 302 447.632 ms - 48
+GET /api/session/info 200 7.614 ms - 60
+GET /api/schedule/all 200 11.394 ms - 40
+Performance Measurement - getAllSchedules: 7.46108603477478ms
+POST /api/schedule 201 54.333 ms - 217
+Performance Measurement - createSchedule: 30.060553014278412ms
+GET /api/schedule/all 200 9.091 ms - 220
+Performance Measurement - getAllSchedules: 4.380231022834778ms
+GET /api/session/info 200 4.019 ms - 60
+GET /api/session/info 200 15.551 ms - 60
+GET /api/session/info 200 4.339 ms - 60
+GET /api/session/info 200 6.990 ms - 60
+GET /api/session/info 200 4.459 ms - 60
+GET /api/session/info 200 5.760 ms - 60
+GET /api/auth/logout 302 14.888 ms - 41
+GET /api/session/info 401 1.146 ms - 76
+GET /api/auth/login 302 1.211 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0ZdKVh0qL70I2shnUMx3d0bLsh0Ra1X-abqrZPtuPSHuLd7rt-MJwSdn5HQAvYPGg&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=0&hd=ajou.ac.kr&prompt=none 302 436.641 ms - 48
+GET /api/session/info 200 3.629 ms - 60
+GET /api/auth/logout 302 3.931 ms - 41
+GET /api/schedule/all 401 1.054 ms - 44
+GET /api/session/info 401 1.896 ms - 76
+GET /api/session/info 401 0.777 ms - 76
+GET /api/auth/login 302 0.908 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0ZCNp4N4szbUeXZ2lUSJCQxpMLt8eiqkPAjhEoU9PGzn5zCYFI1CgifDv2hyISYGg&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=1&hd=ajou.ac.kr&prompt=none 302 481.904 ms - 48
+GET /api/session/info 200 3.830 ms - 60
+GET /api/schedule/all 200 6.419 ms - 40
+Performance Measurement - getAllSchedules: 3.0510510206222534ms
+GET /api/session/info 401 0.905 ms - 76
+GET /api/schedule/all 401 0.796 ms - 44
+GET /api/session/info 401 0.844 ms - 76
+GET /api/auth/login 302 0.910 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0a7Trsso_Jp5vPrjVTErVMUoTS_hKhC3_yBILjE1k8rlhD-Av_WDxRh-DenfkBozg&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=3&hd=ajou.ac.kr&prompt=none 302 455.286 ms - 48
+GET /api/session/info 200 4.353 ms - 60
+GET /api/schedule/all 200 6.417 ms - 40
+Performance Measurement - getAllSchedules: 2.9196969866752625ms
+GET /api/schedule/all 304 56.513 ms - -
+Performance Measurement - getAllSchedules: 3.0346270203590393ms
+GET /api/session/info 200 49.415 ms - 60
+GET /api/auth/logout 302 5.237 ms - 41
+GET /api/session/info 401 1.066 ms - 76
+GET /api/auth/login 302 1.235 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0b5pX-wafAWt3GJaOQ0MuV8pxFpXzch7-iKJykw90KS3bg6rGS6c0jL_oCm0kHmfQ&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&authuser=1&hd=ajou.ac.kr&prompt=none 302 452.374 ms - 48
+GET /api/session/info 200 4.040 ms - 60
+GET /api/schedule/all 304 9.584 ms - -
+Performance Measurement - getAllSchedules: 3.8280670046806335ms
+POST /api/schedule 201 68.289 ms - 252
+Performance Measurement - createSchedule: 17.49489998817444ms
+PUT /api/schedule 200 45.097 ms - 245
+Performance Measurement - updateSchedules: 30.391826033592224ms
+GET /api/schedule/all 304 53.317 ms - -
+Performance Measurement - getAllSchedules: 3.174045979976654ms
+GET /api/session/info 200 3.974 ms - 60
+GET /api/schedule/all 304 79.820 ms - -
+Performance Measurement - getAllSchedules: 2.95797199010849ms
+GET /api/schedule/all 304 20.604 ms - -
+Performance Measurement - getAllSchedules: 3.0838510394096375ms
+GET /api/schedule/all 304 17.032 ms - -
+Performance Measurement - getAllSchedules: 2.8636720180511475ms
+GET /api/session/info 200 51.753 ms - 60
+GET /api/session/info 200 15.941 ms - 60
+GET /api/schedule/all 304 17.499 ms - -
+Performance Measurement - getAllSchedules: 2.9681079983711243ms
+GET /api/session/info 401 1.186 ms - 76
 GET /api/session/info 401 0.855 ms - 76
-GET /api/session/info 401 0.648 ms - 76
-GET /api/session/info 401 0.968 ms - 76
-GET /api/session/info 401 0.655 ms - 76
-GET /api/session/info 401 0.887 ms - 76
-GET /api/session/info 401 0.656 ms - 76
-GET /api/session/info 401 0.819 ms - 76
-GET /api/session/info 401 1.715 ms - 76
+GET /api/auth/login 302 0.895 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0Y7dXShRIVbgpwaSHziVczqtPoIhuOwyKJCOvJ_dIZDhiumR1rom85By8WaxxjpWg&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&authuser=0&hd=ajou.ac.kr&prompt=none 302 435.368 ms - 48
+GET /api/session/info 200 5.680 ms - 60
+GET /api/schedule/all 200 6.928 ms - 220
+Performance Measurement - getAllSchedules: 3.3638980388641357ms
+GET /api/session/info 200 3.905 ms - 60
+GET /api/schedule/all 200 6.618 ms - 220
+Performance Measurement - getAllSchedules: 3.098719000816345ms
+GET /api/session/info 200 4.208 ms - 60
+GET /api/schedule/all 200 6.312 ms - 220
+Performance Measurement - getAllSchedules: 3.0304319858551025ms
+GET /api/session/info 200 4.133 ms - 60
+GET /api/schedule/all 304 16.818 ms - -
+Performance Measurement - getAllSchedules: 2.7342900037765503ms
+GET /api/session/info 200 3.863 ms - 60
+GET /api/session/info 200 5.731 ms - 60
+GET /api/schedule/all 304 8.387 ms - -
+Performance Measurement - getAllSchedules: 4.900808036327362ms
+GET /api/session/info 200 3.961 ms - 60
+GET /api/schedule/all 304 53.173 ms - -
+Performance Measurement - getAllSchedules: 4.181941032409668ms
+GET /api/session/info 200 16.906 ms - 60
+GET /api/session/info 200 4.159 ms - 60
+GET /api/session/info 200 3.919 ms - 60
+GET /api/session/info 200 3.858 ms - 60
+GET /api/auth/logout 302 3.870 ms - 41
+GET /api/session/info 401 1.174 ms - 76
+GET /api/auth/login 302 1.067 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0ZFplLpLXFzjTreoRr9XOFIdylMGvmTIJ9Z-8W3v8J-PXsC1WR3mrhEDMP8u8ISwg&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=0&hd=ajou.ac.kr&prompt=none 302 456.648 ms - 48
+GET /api/session/info 200 3.714 ms - 60
+GET /api/schedule/all 304 8.904 ms - -
+Performance Measurement - getAllSchedules: 3.3655150532722473ms
+GET /api/session/info 200 3.904 ms - 60
+GET /api/schedule/all 304 6.538 ms - -
+Performance Measurement - getAllSchedules: 3.2424970269203186ms
+GET /api/session/info 200 4.546 ms - 60
+GET /api/session/info 200 14.706 ms - 60
+GET /api/auth/logout 302 3.760 ms - 41
+GET /api/auth/login 302 1.096 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0a9isaZiqiZyAFoW3OCrs683FSO5wYZOZICruNlDnpbD6zQOwT9wly7fZ3akJHglQ&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=3&hd=ajou.ac.kr&prompt=none 302 416.843 ms - 48
+GET /api/session/info 200 3.936 ms - 60
+GET /api/schedule/all 304 6.114 ms - -
+Performance Measurement - getAllSchedules: 2.7020570039749146ms
+POST /api/schedule 201 32.875 ms - 238
+Performance Measurement - createSchedule: 17.89035999774933ms
+POST /api/schedule 201 27.971 ms - 251
+Performance Measurement - createSchedule: 14.455415964126587ms
+POST /api/schedule 201 24.014 ms - 277
+Performance Measurement - createSchedule: 10.122812986373901ms
+DELETE /api/schedule 200 28.079 ms - 84
+Performance Measurement - deleteSchedules: 13.639528036117554ms
+GET /api/schedule/all 200 6.512 ms - 456
+Performance Measurement - getAllSchedules: 3.6543020009994507ms
+POST /api/schedule 201 26.599 ms - 237
+Performance Measurement - createSchedule: 12.827956020832062ms
+GET /api/session/info 200 51.064 ms - 60
+GET /api/schedule/all 200 16.479 ms - 657
+Performance Measurement - getAllSchedules: 3.5523930191993713ms
+GET /api/session/info 200 21.419 ms - 60
+GET /api/session/info 200 26.999 ms - 60
+GET /api/chat/rooms 200 34.768 ms - 2
+GET /api/session/info 200 4.844 ms - 60
+GET /api/chat/rooms 304 11.480 ms - -
+GET /api/session/info 200 4.055 ms - 60
+GET /api/session/info 200 4.097 ms - 60
+GET /api/session/info 200 7.407 ms - 60
+GET /api/session/info 200 6.633 ms - 60
+GET /api/session/info 200 7.149 ms - 60
+GET /api/schedule/all 200 6.983 ms - 220
+Performance Measurement - getAllSchedules: 3.386197030544281ms
+GET /api/session/info 200 6.139 ms - 60
+GET /api/chat/rooms 200 13.986 ms - 2
+POST /api/schedule 201 17.101 ms - 202
+Performance Measurement - createSchedule: 13.091067969799042ms
+POST /api/schedule 201 14.599 ms - 205
+Performance Measurement - createSchedule: 10.717601954936981ms
+GET /api/schedule 404 17.100 ms - 151
+GET /api/session/info 200 16.750 ms - 60
+GET /api/chat/rooms 200 23.408 ms - 2
+GET /api/schedule/all 200 7.910 ms - 220
+Performance Measurement - getAllSchedules: 3.159197986125946ms
+GET /api/meeting 401 0.827 ms - 44
+GET /api/auth/logout 302 0.911 ms - 41
+GET /api/session/info 401 0.855 ms - 76
+GET /api/auth/login 302 0.998 ms - 0
+GET /api/session/info 200 16.747 ms - 60
+GET /api/session/info 200 9.338 ms - 60
+GET /api/chat/rooms 200 15.884 ms - 2
+GET /api/schedule/all 200 8.682 ms - 220
+Performance Measurement - getAllSchedules: 5.216198980808258ms
+GET /api/session/info 200 17.533 ms - 60
+GET /api/chat/rooms 200 22.089 ms - 2
+GET /api/session/info 401 0.888 ms - 76
+GET /api/session/info 401 0.773 ms - 76
+GET /api/session/info 401 0.844 ms - 76
+GET /api/session/info 401 0.632 ms - 76
+GET /api/session/info 200 46.849 ms - 60
+GET /api/chat/rooms 200 56.198 ms - 2
+GET /api/session/info 401 0.963 ms - 76
+GET /api/session/info 401 0.604 ms - 76
 GET /api/session/info 401 0.859 ms - 76
-GET /api/session/info 401 0.650 ms - 76
+GET /api/session/info 401 0.639 ms - 76
+GET /api/session/info 401 0.846 ms - 76
+GET /api/session/info 401 0.662 ms - 76
+GET /api/session/info 401 0.844 ms - 76
+GET /api/session/info 401 0.957 ms - 76
+GET /api/session/info 401 0.788 ms - 76
+GET /api/session/info 401 0.617 ms - 76
+GET /api/session/info 401 0.870 ms - 76
+GET /api/session/info 401 0.857 ms - 76
+GET /api/session/info 401 0.886 ms - 76
+GET /api/session/info 401 0.687 ms - 76
+GET /api/session/info 401 0.870 ms - 76
+GET /api/session/info 401 0.659 ms - 76
+GET /api/session/info 401 0.922 ms - 76
 GET /api/session/info 401 0.920 ms - 76
-GET /api/session/info 401 0.627 ms - 76
-GET /api/session/info 401 0.831 ms - 76
-GET /api/session/info 401 0.645 ms - 76
-GET /api/session/info 401 0.845 ms - 76
-GET /api/session/info 401 0.624 ms - 76
-GET / 404 1.042 ms - 139
-GET /api/session/info 401 0.793 ms - 76
-GET /api/session/info 401 0.580 ms - 76
-GET /api/session/info 401 0.806 ms - 76
-GET /api/session/info 401 0.606 ms - 76
-GET /api/session/info 401 0.829 ms - 76
-GET /api/session/info 401 0.609 ms - 76
-OPTIONS /api/schedule/all 204 0.618 ms - 0
-OPTIONS /api/schedule/all 204 0.140 ms - 0
-GET /api/schedule/all 401 0.903 ms - 44
-GET /api/schedule/96 401 0.846 ms - 44
-GET /api/schedule/194 401 0.764 ms - 44
-GET /api/schedule/194 401 0.868 ms - 44
-GET /api/schedule/97 401 0.827 ms - 44
-GET /api/schedule/96 401 0.850 ms - 44
-OPTIONS /api/schedule/all 204 0.234 ms - 0
-OPTIONS /api/schedule/all 204 0.167 ms - 0
-OPTIONS /api/schedule/192 204 0.192 ms - 0
-OPTIONS /api/schedule/192 204 0.188 ms - 0
-OPTIONS /api/schedule/290 204 0.188 ms - 0
-OPTIONS /api/schedule/290 204 0.189 ms - 0
-OPTIONS /api/schedule/290 204 0.165 ms - 0
-OPTIONS /api/schedule/all 204 0.202 ms - 0
-OPTIONS /api/schedule/289 204 0.194 ms - 0
-OPTIONS /api/schedule/289 204 0.227 ms - 0
-OPTIONS /api/schedule/289 204 0.162 ms - 0
-OPTIONS /api/schedule/290 204 0.166 ms - 0
-OPTIONS /api/schedule/291 204 0.167 ms - 0
-OPTIONS /api/schedule/291 204 0.166 ms - 0
-OPTIONS /api/schedule/290 204 0.160 ms - 0
-OPTIONS /api/schedule/288 204 0.164 ms - 0
-OPTIONS /api/schedule/290 204 0.167 ms - 0
-OPTIONS /api/schedule/291 204 0.205 ms - 0
-OPTIONS /api/schedule/291 204 0.188 ms - 0
-OPTIONS /api/schedule/290 204 0.178 ms - 0
-OPTIONS /api/schedule/289 204 0.168 ms - 0
-OPTIONS /api/schedule/290 204 0.177 ms - 0
-OPTIONS /api/schedule/289 204 0.166 ms - 0
-OPTIONS /api/schedule 204 0.189 ms - 0
-OPTIONS /api/schedule/289 204 0.168 ms - 0
-OPTIONS /api/schedule/288 204 0.222 ms - 0
-OPTIONS /api/schedule/290 204 0.179 ms - 0
-OPTIONS /api/schedule/292 204 0.160 ms - 0
-OPTIONS /api/schedule/293 204 0.165 ms - 0
-OPTIONS /api/schedule/all 204 0.176 ms - 0
-OPTIONS /api/schedule/36 204 0.178 ms - 0
-OPTIONS /api/schedule/38 204 0.161 ms - 0
-OPTIONS /api/schedule/38 204 0.172 ms - 0
-OPTIONS /api/schedule/38 204 0.157 ms - 0
-OPTIONS /api/schedule/38 204 0.191 ms - 0
-OPTIONS /api/schedule/38 204 0.165 ms - 0
-OPTIONS /api/schedule/38 204 0.184 ms - 0
-OPTIONS /api/schedule/38 204 0.168 ms - 0
-OPTIONS /api/schedule/38 204 0.217 ms - 0
-OPTIONS /api/schedule/all 204 0.164 ms - 0
-OPTIONS /api/schedule/36 204 0.165 ms - 0
-OPTIONS /api/schedule/37 204 0.160 ms - 0
-OPTIONS /api/schedule/36 204 0.178 ms - 0
-GET /api/schedule/193 401 1.087 ms - 44
-GET /api/schedule/193 401 0.785 ms - 44
-GET /api/schedule/195 401 0.850 ms - 44
-GET /api/schedule/1 401 0.814 ms - 44
-GET /api/schedule/0 401 0.795 ms - 44
-GET /api/schedule/0 401 0.825 ms - 44
-GET /api/schedule/96 401 0.854 ms - 44
-GET /api/schedule/289 401 0.824 ms - 44
-GET /api/session/info 401 0.858 ms - 76
-GET /api/auth/login 302 1.424 ms - 0
-GET /api/auth/google/callback?code=4%2F0AeanS0a4gqvuMrxTHLniakI-_oHdDI0RHY_4-82ZXsaIAKdM53z4nPcgFGUOJjD4FJwRBw&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=1&hd=ajou.ac.kr&prompt=none 302 508.556 ms - 48
-GET /api/schedule/all 304 11.134 ms - -
-Performance Measurement - getAllSchedules: 5.014769017696381ms
-GET /api/schedule/97 304 10.607 ms - -
-Performance Measurement - getScheduleByTimeIdx: 7.154272973537445ms
-GET /api/schedule/101 200 6.849 ms - 26
-Performance Measurement - getScheduleByTimeIdx: 3.534310042858124ms
-GET /api/schedule/100 200 6.679 ms - 26
-Performance Measurement - getScheduleByTimeIdx: 3.2747740149497986ms
-GET /api/schedule/99 304 7.228 ms - -
-Performance Measurement - getScheduleByTimeIdx: 3.805077016353607ms
-GET /api/schedule/99 304 9.589 ms - -
-Performance Measurement - getScheduleByTimeIdx: 5.2810059785842896ms
-GET /api/schedule/99 304 6.405 ms - -
-Performance Measurement - getScheduleByTimeIdx: 3.1567789912223816ms
-GET /api/schedule/98 304 7.002 ms - -
-Performance Measurement - getScheduleByTimeIdx: 3.5950030088424683ms
-GET /api/schedule/97 304 6.705 ms - -
-Performance Measurement - getScheduleByTimeIdx: 3.2245330214500427ms
-GET /api/schedule/97 304 6.217 ms - -
-Performance Measurement - getScheduleByTimeIdx: 2.99965101480484ms
-GET /api/schedule/2 200 6.568 ms - 26
-Performance Measurement - getScheduleByTimeIdx: 3.2004200220108032ms
-OPTIONS /api/schedule/all 204 0.166 ms - 0
-OPTIONS /api/schedule 204 0.174 ms - 0
-OPTIONS /api/schedule 204 0.179 ms - 0
-OPTIONS /api/schedule 204 0.232 ms - 0
-OPTIONS /api/schedule/all 204 0.164 ms - 0
-OPTIONS /api/schedule/all 204 0.167 ms - 0
-GET / 404 1.022 ms - 139
-GET /api/session/info 401 0.816 ms - 76
-GET /api/session/info 401 1.325 ms - 76
-GET /api/session/info 401 0.832 ms - 76
-GET /api/session/info 401 0.603 ms - 76
-GET /api/session/info 401 0.819 ms - 76
-GET /api/session/info 401 0.556 ms - 76
-OPTIONS /api/schedule/all 204 0.161 ms - 0
-OPTIONS /api/schedule/all 204 0.124 ms - 0
-OPTIONS /api/schedule 204 0.164 ms - 0
-GET /api/session/info 401 0.837 ms - 76
-GET /api/session/info 401 0.648 ms - 76
-GET /api/session/info 401 0.810 ms - 76
-GET /api/auth/login 302 1.089 ms - 0
-GET /api/auth/google/callback?code=4%2F0AeanS0box5WHb-IhXbrmGgpDAMMr3rQ5vv45X8p-FJJM90Ts4qDwFayGUeisJmPZIsW9ew&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=0&hd=ajou.ac.kr&prompt=none 302 478.464 ms - 48
-GET /api/session/info 200 7.699 ms - 58
-GET /api/schedule/all 200 6.802 ms - 40
-Performance Measurement - getAllSchedules: 3.283160984516144ms
-POST /api/schedule 201 33.080 ms - 194
-Performance Measurement - createSchedule: 19.97666096687317ms
-PUT /api/schedule 200 44.680 ms - 202
-Performance Measurement - updateSchedules: 28.161078989505768ms
-Performance Measurement - deleteSchedules: 2.5363460183143616ms
-DELETE /api/schedule 404 7.058 ms - 115
-Performance Measurement - deleteSchedules: 0.8580690026283264ms
-DELETE /api/schedule 404 5.339 ms - 115
-Performance Measurement - deleteSchedules: 0.5973520278930664ms
-DELETE /api/schedule 404 5.281 ms - 115
-GET /api/schedule/all 200 38.467 ms - 205
-Performance Measurement - getAllSchedules: 12.194466054439545ms
-DELETE /api/schedule 200 14.795 ms - 84
-Performance Measurement - deleteSchedules: 10.980576992034912ms
-GET /api/schedule/all 200 5.511 ms - 40
-Performance Measurement - getAllSchedules: 2.713946044445038ms
-GET /api/session/info 200 50.557 ms - 58
-GET / 404 1.050 ms - 139
+GET /api/session/info 401 0.857 ms - 76
+GET /api/session/info 401 0.602 ms - 76
+GET /api/session/info 401 0.960 ms - 76
+GET /api/session/info 401 0.651 ms - 76
+GET /api/session/info 401 0.834 ms - 76
+GET /api/session/info 401 0.878 ms - 76
+GET /api/session/info 401 0.900 ms - 76
+GET /api/session/info 401 0.896 ms - 76
+GET /api/meeting 401 0.845 ms - 44
+GET /api/session/info 401 0.916 ms - 76
+GET /api/session/info 401 0.865 ms - 76
+GET /api/session/info 401 0.855 ms - 76
+GET / 404 0.919 ms - 139
+GET /api/session/info 401 0.801 ms - 76
+GET /api/session/info 401 0.893 ms - 76
+GET /api/session/info 401 0.859 ms - 76
+GET /api/session/info 401 0.874 ms - 76
+GET /api/session/info 401 0.813 ms - 76
+GET /api/session/info 401 0.822 ms - 76
+GET /api/session/info 401 0.904 ms - 76
+GET /api/session/info 401 0.874 ms - 76
+GET /api/session/info 401 0.792 ms - 76
+OPTIONS /api/schedule/all 204 0.443 ms - 0
+OPTIONS /api/schedule/all 204 0.139 ms - 0
+OPTIONS /api/schedule 204 0.190 ms - 0
+GET /api/session/info 401 0.877 ms - 76
+GET /api/session/info 401 0.634 ms - 76
+GET /api/session/info 401 0.906 ms - 76
+GET /api/session/info 401 0.744 ms - 76
+GET /api/session/info 401 0.853 ms - 76
+GET /api/session/info 401 0.637 ms - 76
+GET /api/session/info 401 0.931 ms - 76
+GET /api/session/info 401 2.110 ms - 76
diff --git a/package-lock.json b/package-lock.json
index 606fda2..802c64f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,6 +11,7 @@
       "dependencies": {
         "amqplib": "^0.10.5",
         "connect-flash": "^0.1.1",
+        "connect-mongo": "^5.1.0",
         "cookie-parser": "^1.4.7",
         "cors": "^2.8.5",
         "dotenv": "^16.4.5",
@@ -253,7 +254,7 @@
       "version": "5.2.0",
       "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz",
       "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-crypto/sha256-js": "^5.2.0",
@@ -269,7 +270,7 @@
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz",
       "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "tslib": "^2.6.2"
@@ -282,7 +283,7 @@
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz",
       "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/is-array-buffer": "^2.2.0",
@@ -296,7 +297,7 @@
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz",
       "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/util-buffer-from": "^2.2.0",
@@ -310,7 +311,7 @@
       "version": "5.2.0",
       "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz",
       "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-crypto/util": "^5.2.0",
@@ -325,7 +326,7 @@
       "version": "5.2.0",
       "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz",
       "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "tslib": "^2.6.2"
@@ -335,7 +336,7 @@
       "version": "5.2.0",
       "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz",
       "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/types": "^3.222.0",
@@ -347,7 +348,7 @@
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz",
       "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "tslib": "^2.6.2"
@@ -360,7 +361,7 @@
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz",
       "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/is-array-buffer": "^2.2.0",
@@ -374,7 +375,7 @@
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz",
       "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/util-buffer-from": "^2.2.0",
@@ -443,7 +444,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.693.0.tgz",
       "integrity": "sha512-WfycTcylmrSOnCN8x/xeIjHa4gIV4UhG85LWLZ3M4US8+HJQ8l4c4WUf+pUoTaSxN86vhbXlz0iRvA89nF854Q==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-crypto/sha256-browser": "5.2.0",
@@ -496,7 +497,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.693.0.tgz",
       "integrity": "sha512-QEynrBC26x6TG9ZMzApR/kZ3lmt4lEIs2D+cHuDxt6fDGzahBUsQFBwJqhizzsM97JJI5YvmJhmihoYjdSSaXA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-crypto/sha256-browser": "5.2.0",
@@ -546,7 +547,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.693.0.tgz",
       "integrity": "sha512-UEDbYlYtK/e86OOMyFR4zEPyenIxDzO2DRdz3fwVW7RzZ94wfmSwBh/8skzPTuY1G7sI064cjHW0b0QG01Sdtg==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-crypto/sha256-browser": "5.2.0",
@@ -600,7 +601,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.693.0.tgz",
       "integrity": "sha512-4S2y7VEtvdnjJX4JPl4kDQlslxXEZFnC50/UXVUYSt/AMc5A/GgspFNA5FVz4E3Gwpfobbf23hR2NBF8AGvYoQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-crypto/sha256-browser": "5.2.0",
@@ -652,7 +653,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.693.0.tgz",
       "integrity": "sha512-v6Z/kWmLFqRLDPEwl9hJGhtTgIFHjZugSfF1Yqffdxf4n1AWgtHS7qSegakuMyN5pP4K2tvUD8qHJ+gGe2Bw2A==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/types": "3.692.0",
@@ -675,7 +676,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.693.0.tgz",
       "integrity": "sha512-hlpV3tkOhpFl87aToH6Q6k7JBNNuARBPk+irPMtgE8ZqpYRP9tJ/RXftirzZ7CqSzc7NEWe/mnbJzRXw7DfgVQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/client-cognito-identity": "3.693.0",
@@ -692,7 +693,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.693.0.tgz",
       "integrity": "sha512-hMUZaRSF7+iBKZfBHNLihFs9zvpM1CB8MBOTnTp5NGCVkRYF3SB2LH+Kcippe0ats4qCyB1eEoyQX99rERp2iQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/core": "3.693.0",
@@ -709,7 +710,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.693.0.tgz",
       "integrity": "sha512-sL8MvwNJU7ZpD7/d2VVb3by1GknIJUxzTIgYtVkDVA/ojo+KRQSSHxcj0EWWXF5DTSh2Tm+LrEug3y1ZyKHsDA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/core": "3.693.0",
@@ -731,7 +732,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.693.0.tgz",
       "integrity": "sha512-kvaa4mXhCCOuW7UQnBhYqYfgWmwy7WSBSDClutwSLPZvgrhYj2l16SD2lN4IfYdxARYMJJ1lFYp3/jJG/9Yk4Q==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/core": "3.693.0",
@@ -758,7 +759,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.693.0.tgz",
       "integrity": "sha512-42WMsBjTNnjYxYuM3qD/Nq+8b7UdMopUq5OduMDxoM3mFTV6PXMMnfI4Z1TNnR4tYRvPXAnuNltF6xmjKbSJRA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/credential-provider-env": "3.693.0",
@@ -782,7 +783,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.693.0.tgz",
       "integrity": "sha512-cvxQkrTWHHjeHrPlj7EWXPnFSq8x7vMx+Zn1oTsMpCY445N9KuzjfJTkmNGwU2GT6rSZI9/0MM02aQvl5bBBTQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/core": "3.693.0",
@@ -800,7 +801,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.693.0.tgz",
       "integrity": "sha512-479UlJxY+BFjj3pJFYUNC0DCMrykuG7wBAXfsvZqQxKUa83DnH5Q1ID/N2hZLkxjGd4ZW0AC3lTOMxFelGzzpQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/client-sso": "3.693.0",
@@ -820,7 +821,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.693.0.tgz",
       "integrity": "sha512-8LB210Pr6VeCiSb2hIra+sAH4KUBLyGaN50axHtIgufVK8jbKIctTZcVY5TO9Se+1107TsruzeXS7VeqVdJfFA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/core": "3.693.0",
@@ -840,7 +841,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.693.0.tgz",
       "integrity": "sha512-0CCH8GuH1E41Kpq52NujErbUIRewDWLkdbYO8UJGybDbUQ8KC5JG1tP7K20tKYHmVgJGXDHo+XUIG7ogHD6/JA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/client-cognito-identity": "3.693.0",
@@ -869,7 +870,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.693.0.tgz",
       "integrity": "sha512-BCki6sAZ5jYwIN/t3ElCiwerHad69ipHwPsDCxJQyeiOnJ8HG+lEpnVIfrnI8A0fLQNSF3Gtx6ahfBpKiv1Oug==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/types": "3.692.0",
@@ -885,7 +886,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.693.0.tgz",
       "integrity": "sha512-dXnXDPr+wIiJ1TLADACI1g9pkSB21KkMIko2u4CJ2JCBoxi5IqeTnVoa6YcC8GdFNVRl+PorZ3Zqfmf1EOTC6w==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/types": "3.692.0",
@@ -900,7 +901,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.693.0.tgz",
       "integrity": "sha512-0LDmM+VxXp0u3rG0xQRWD/q6Ubi7G8I44tBPahevD5CaiDZTkmNTrVUf0VEJgVe0iCKBppACMBDkLB0/ETqkFw==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/types": "3.692.0",
@@ -916,7 +917,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.693.0.tgz",
       "integrity": "sha512-/KUq/KEpFFbQmNmpp7SpAtFAdViquDfD2W0QcG07zYBfz9MwE2ig48ALynXm5sMpRmnG7sJXjdvPtTsSVPfkiw==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/core": "3.693.0",
@@ -935,7 +936,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.693.0.tgz",
       "integrity": "sha512-YLUkMsUY0GLW/nfwlZ69cy1u07EZRmsv8Z9m0qW317/EZaVx59hcvmcvb+W4bFqj5E8YImTjoGfE4cZ0F9mkyw==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/types": "3.692.0",
@@ -953,7 +954,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.693.0.tgz",
       "integrity": "sha512-nDBTJMk1l/YmFULGfRbToOA2wjf+FkQT4dMgYCv+V9uSYsMzQj8A7Tha2dz9yv4vnQgYaEiErQ8d7HVyXcVEoA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/types": "3.692.0",
@@ -973,7 +974,7 @@
       "version": "3.692.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.692.0.tgz",
       "integrity": "sha512-RpNvzD7zMEhiKgmlxGzyXaEcg2khvM7wd5sSHVapOcrde1awQSOMGI4zKBQ+wy5TnDfrm170ROz/ERLYtrjPZA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/types": "^3.7.0",
@@ -987,7 +988,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.693.0.tgz",
       "integrity": "sha512-eo4F6DRQ/kxS3gxJpLRv+aDNy76DxQJL5B3DPzpr9Vkq0ygVoi4GT5oIZLVaAVIJmi6k5qq9dLsYZfWLUxJJSg==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/types": "3.692.0",
@@ -1003,7 +1004,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.693.0.tgz",
       "integrity": "sha512-ttrag6haJLWABhLqtg1Uf+4LgHWIMOVSYL+VYZmAp2v4PUGOwWmWQH0Zk8RM7YuQcLfH/EoR72/Yxz6A4FKcuw==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "tslib": "^2.6.2"
@@ -1016,7 +1017,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.693.0.tgz",
       "integrity": "sha512-6EUfuKOujtddy18OLJUaXfKBgs+UcbZ6N/3QV4iOkubCUdeM1maIqs++B9bhCbWeaeF5ORizJw5FTwnyNjE/mw==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/types": "3.692.0",
@@ -1029,7 +1030,7 @@
       "version": "3.693.0",
       "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.693.0.tgz",
       "integrity": "sha512-td0OVX8m5ZKiXtecIDuzY3Y3UZIzvxEr57Hp21NOwieqKCG2UeyQWWeGPv0FQaU7dpTkvFmVNI+tx9iB8V/Nhg==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/middleware-user-agent": "3.693.0",
@@ -3816,7 +3817,6 @@
       "version": "1.1.9",
       "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz",
       "integrity": "sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "sparse-bitfield": "^3.0.3"
@@ -5616,7 +5616,7 @@
       "version": "3.1.8",
       "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.8.tgz",
       "integrity": "sha512-+3DOBcUn5/rVjlxGvUPKc416SExarAQ+Qe0bqk30YSUjbepwpS7QN0cyKUSifvLJhdMZ0WPzPP5ymut0oonrpQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/types": "^3.7.1",
@@ -5630,7 +5630,7 @@
       "version": "3.0.12",
       "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.12.tgz",
       "integrity": "sha512-YAJP9UJFZRZ8N+UruTeq78zkdjUHmzsY62J4qKWZ4SXB4QXJ/+680EfXXgkYA2xj77ooMqtUY9m406zGNqwivQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/node-config-provider": "^3.1.11",
@@ -5647,7 +5647,7 @@
       "version": "2.5.3",
       "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.5.3.tgz",
       "integrity": "sha512-96uW8maifUSmehaeW7uydWn7wBc98NEeNI3zN8vqakGpyCQgzyJaA64Z4FCOUmAdCJkhppd/7SZ798Fo4Xx37g==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/middleware-serde": "^3.0.10",
@@ -5667,7 +5667,7 @@
       "version": "3.2.7",
       "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.7.tgz",
       "integrity": "sha512-cEfbau+rrWF8ylkmmVAObOmjbTIzKyUC5TkBL58SbLywD0RCBC4JAUKbmtSm2w5KUJNRPGgpGFMvE2FKnuNlWQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/node-config-provider": "^3.1.11",
@@ -5684,7 +5684,7 @@
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.1.tgz",
       "integrity": "sha512-bH7QW0+JdX0bPBadXt8GwMof/jz0H28I84hU1Uet9ISpzUqXqRQ3fEZJ+ANPOhzSEczYvANNl3uDQDYArSFDtA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/protocol-http": "^4.1.7",
@@ -5698,7 +5698,7 @@
       "version": "3.0.10",
       "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.10.tgz",
       "integrity": "sha512-3zWGWCHI+FlJ5WJwx73Mw2llYR8aflVyZN5JhoqLxbdPZi6UyKSdCeXAWJw9ja22m6S6Tzz1KZ+kAaSwvydi0g==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/types": "^3.7.1",
@@ -5714,7 +5714,7 @@
       "version": "3.0.10",
       "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.10.tgz",
       "integrity": "sha512-Lp2L65vFi+cj0vFMu2obpPW69DU+6O5g3086lmI4XcnRCG8PxvpWC7XyaVwJCxsZFzueHjXnrOH/E0pl0zikfA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/types": "^3.7.1",
@@ -5725,7 +5725,7 @@
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz",
       "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "tslib": "^2.6.2"
@@ -5760,7 +5760,7 @@
       "version": "3.0.12",
       "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.12.tgz",
       "integrity": "sha512-1mDEXqzM20yywaMDuf5o9ue8OkJ373lSPbaSjyEvkWdqELhFMyNNgKGWL/rCSf4KME8B+HlHKuR8u9kRj8HzEQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/protocol-http": "^4.1.7",
@@ -5775,7 +5775,7 @@
       "version": "3.2.3",
       "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.3.tgz",
       "integrity": "sha512-Hdl9296i/EMptaX7agrSzJZDiz5Y8XPUeBbctTmMtnCguGpqfU3jVsTUan0VLaOhsnquqWLL8Bl5HrlbVGT1og==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/core": "^2.5.3",
@@ -5795,7 +5795,7 @@
       "version": "3.0.27",
       "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.27.tgz",
       "integrity": "sha512-H3J/PjJpLL7Tt+fxDKiOD25sMc94YetlQhCnYeNmina2LZscAdu0ZEZPas/kwePHABaEtqp7hqa5S4UJgMs1Tg==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/node-config-provider": "^3.1.11",
@@ -5816,7 +5816,7 @@
       "version": "9.0.1",
       "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
       "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
-      "dev": true,
+      "devOptional": true,
       "funding": [
         "https://github.com/sponsors/broofa",
         "https://github.com/sponsors/ctavan"
@@ -5830,7 +5830,7 @@
       "version": "3.0.10",
       "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.10.tgz",
       "integrity": "sha512-MnAuhh+dD14F428ubSJuRnmRsfOpxSzvRhaGVTvd/lrUDE3kxzCCmH8lnVTvoNQnV2BbJ4c15QwZ3UdQBtFNZA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/types": "^3.7.1",
@@ -5844,7 +5844,7 @@
       "version": "3.0.10",
       "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.10.tgz",
       "integrity": "sha512-grCHyoiARDBBGPyw2BeicpjgpsDFWZZxptbVKb3CRd/ZA15F/T6rZjCCuBUjJwdck1nwUuIxYtsS4H9DDpbP5w==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/types": "^3.7.1",
@@ -5858,7 +5858,7 @@
       "version": "3.1.11",
       "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.11.tgz",
       "integrity": "sha512-URq3gT3RpDikh/8MBJUB+QGZzfS7Bm6TQTqoh4CqE8NBuyPkWa5eUXj0XFcFfeZVgg3WMh1u19iaXn8FvvXxZw==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/property-provider": "^3.1.10",
@@ -5874,7 +5874,7 @@
       "version": "3.3.1",
       "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.1.tgz",
       "integrity": "sha512-fr+UAOMGWh6bn4YSEezBCpJn9Ukp9oR4D32sCjCo7U81evE11YePOQ58ogzyfgmjIO79YeOdfXXqr0jyhPQeMg==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/abort-controller": "^3.1.8",
@@ -5891,7 +5891,7 @@
       "version": "3.1.10",
       "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.10.tgz",
       "integrity": "sha512-n1MJZGTorTH2DvyTVj+3wXnd4CzjJxyXeOgnTlgNVFxaaMeT4OteEp4QrzF8p9ee2yg42nvyVK6R/awLCakjeQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/types": "^3.7.1",
@@ -5905,7 +5905,7 @@
       "version": "4.1.7",
       "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.7.tgz",
       "integrity": "sha512-FP2LepWD0eJeOTm0SjssPcgqAlDFzOmRXqXmGhfIM52G7Lrox/pcpQf6RP4F21k0+O12zaqQt5fCDOeBtqY6Cg==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/types": "^3.7.1",
@@ -5919,7 +5919,7 @@
       "version": "3.0.10",
       "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.10.tgz",
       "integrity": "sha512-nT9CQF3EIJtIUepXQuBFb8dxJi3WVZS3XfuDksxSCSn+/CzZowRLdhDn+2acbBv8R6eaJqPupoI/aRFIImNVPQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/types": "^3.7.1",
@@ -5934,7 +5934,7 @@
       "version": "3.0.10",
       "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.10.tgz",
       "integrity": "sha512-Oa0XDcpo9SmjhiDD9ua2UyM3uU01ZTuIrNdZvzwUTykW1PM8o2yJvMh1Do1rY5sUQg4NDV70dMi0JhDx4GyxuQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/types": "^3.7.1",
@@ -5948,7 +5948,7 @@
       "version": "3.0.10",
       "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.10.tgz",
       "integrity": "sha512-zHe642KCqDxXLuhs6xmHVgRwy078RfqxP2wRDpIyiF8EmsWXptMwnMwbVa50lw+WOGNrYm9zbaEg0oDe3PTtvQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/types": "^3.7.1"
@@ -5961,7 +5961,7 @@
       "version": "3.1.11",
       "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.11.tgz",
       "integrity": "sha512-AUdrIZHFtUgmfSN4Gq9nHu3IkHMa1YDcN+s061Nfm+6pQ0mJy85YQDB0tZBCmls0Vuj22pLwDPmL92+Hvfwwlg==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/types": "^3.7.1",
@@ -5975,7 +5975,7 @@
       "version": "4.2.3",
       "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.2.3.tgz",
       "integrity": "sha512-pPSQQ2v2vu9vc8iew7sszLd0O09I5TRc5zhY71KA+Ao0xYazIG+uLeHbTJfIWGO3BGVLiXjUr3EEeCcEQLjpWQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/is-array-buffer": "^3.0.0",
@@ -5995,7 +5995,7 @@
       "version": "3.4.4",
       "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.4.4.tgz",
       "integrity": "sha512-dPGoJuSZqvirBq+yROapBcHHvFjChoAQT8YPWJ820aPHHiowBlB3RL1Q4kPT1hx0qKgJuf+HhyzKi5Gbof4fNA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/core": "^2.5.3",
@@ -6014,7 +6014,7 @@
       "version": "3.7.1",
       "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.1.tgz",
       "integrity": "sha512-XKLcLXZY7sUQgvvWyeaL/qwNPp6V3dWcUjqrQKjSb+tzYiCy340R/c64LV5j+Tnb2GhmunEX0eou+L+m2hJNYA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "tslib": "^2.6.2"
@@ -6027,7 +6027,7 @@
       "version": "3.0.10",
       "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.10.tgz",
       "integrity": "sha512-j90NUalTSBR2NaZTuruEgavSdh8MLirf58LoGSk4AtQfyIymogIhgnGUU2Mga2bkMkpSoC9gxb74xBXL5afKAQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/querystring-parser": "^3.0.10",
@@ -6039,7 +6039,7 @@
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz",
       "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/util-buffer-from": "^3.0.0",
@@ -6054,7 +6054,7 @@
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz",
       "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "tslib": "^2.6.2"
@@ -6064,7 +6064,7 @@
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz",
       "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "tslib": "^2.6.2"
@@ -6077,7 +6077,7 @@
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz",
       "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/is-array-buffer": "^3.0.0",
@@ -6091,7 +6091,7 @@
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz",
       "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "tslib": "^2.6.2"
@@ -6104,7 +6104,7 @@
       "version": "3.0.27",
       "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.27.tgz",
       "integrity": "sha512-GV8NvPy1vAGp7u5iD/xNKUxCorE4nQzlyl057qRac+KwpH5zq8wVq6rE3lPPeuFLyQXofPN6JwxL1N9ojGapiQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/property-provider": "^3.1.10",
@@ -6121,7 +6121,7 @@
       "version": "3.0.27",
       "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.27.tgz",
       "integrity": "sha512-7+4wjWfZqZxZVJvDutO+i1GvL6bgOajEkop4FuR6wudFlqBiqwxw3HoH6M9NgeCd37km8ga8NPp2JacQEtAMPg==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/config-resolver": "^3.0.12",
@@ -6140,7 +6140,7 @@
       "version": "2.1.6",
       "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.6.tgz",
       "integrity": "sha512-mFV1t3ndBh0yZOJgWxO9J/4cHZVn5UG1D8DeCc6/echfNkeEJWu9LD7mgGH5fHrEdR7LDoWw7PQO6QiGpHXhgA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/node-config-provider": "^3.1.11",
@@ -6155,7 +6155,7 @@
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz",
       "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "tslib": "^2.6.2"
@@ -6168,7 +6168,7 @@
       "version": "3.0.10",
       "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.10.tgz",
       "integrity": "sha512-eJO+/+RsrG2RpmY68jZdwQtnfsxjmPxzMlQpnHKjFPwrYqvlcT+fHdT+ZVwcjlWSrByOhGr9Ff2GG17efc192A==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/types": "^3.7.1",
@@ -6182,7 +6182,7 @@
       "version": "3.0.10",
       "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.10.tgz",
       "integrity": "sha512-1l4qatFp4PiU6j7UsbasUHL2VU023NRB/gfaa1M0rDqVrRN4g3mCArLRyH3OuktApA4ye+yjWQHjdziunw2eWA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/service-error-classification": "^3.0.10",
@@ -6197,7 +6197,7 @@
       "version": "3.3.1",
       "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.3.1.tgz",
       "integrity": "sha512-Ff68R5lJh2zj+AUTvbAU/4yx+6QPRzg7+pI7M1FbtQHcRIp7xvguxVsQBKyB3fwiOwhAKu0lnNyYBaQfSW6TNw==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/fetch-http-handler": "^4.1.1",
@@ -6217,7 +6217,7 @@
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz",
       "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "tslib": "^2.6.2"
@@ -6230,7 +6230,7 @@
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz",
       "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@smithy/util-buffer-from": "^3.0.0",
@@ -7287,14 +7287,12 @@
       "version": "7.0.3",
       "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz",
       "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/@types/whatwg-url": {
       "version": "11.0.5",
       "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz",
       "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@types/webidl-conversions": "*"
@@ -8305,6 +8303,18 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/asn1.js": {
+      "version": "5.4.1",
+      "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
+      "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
+      "license": "MIT",
+      "dependencies": {
+        "bn.js": "^4.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
     "node_modules/ast-module-types": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-5.0.0.tgz",
@@ -8813,6 +8823,12 @@
       "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
       "license": "MIT"
     },
+    "node_modules/bn.js": {
+      "version": "4.12.1",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
+      "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
+      "license": "MIT"
+    },
     "node_modules/body-parser": {
       "version": "1.20.3",
       "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
@@ -8848,7 +8864,7 @@
       "version": "2.11.0",
       "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz",
       "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==",
-      "dev": true,
+      "devOptional": true,
       "license": "MIT"
     },
     "node_modules/brace-expansion": {
@@ -8927,7 +8943,6 @@
       "version": "6.9.0",
       "resolved": "https://registry.npmjs.org/bson/-/bson-6.9.0.tgz",
       "integrity": "sha512-X9hJeyeM0//Fus+0pc5dSUMhhrrmWwQUtdavaQeF3Ta6m69matZkGWV/MrBcnwUeLC8W9kwwc2hfkZgUuCX3Ig==",
-      "dev": true,
       "license": "Apache-2.0",
       "engines": {
         "node": ">=16.20.1"
@@ -9896,6 +9911,46 @@
         "node": ">= 0.4.0"
       }
     },
+    "node_modules/connect-mongo": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/connect-mongo/-/connect-mongo-5.1.0.tgz",
+      "integrity": "sha512-xT0vxQLqyqoUTxPLzlP9a/u+vir0zNkhiy9uAdHjSCcUUf7TS5b55Icw8lVyYFxfemP3Mf9gdwUOgeF3cxCAhw==",
+      "license": "MIT",
+      "dependencies": {
+        "debug": "^4.3.1",
+        "kruptein": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=12.9.0"
+      },
+      "peerDependencies": {
+        "express-session": "^1.17.1",
+        "mongodb": ">= 5.1.0 < 7"
+      }
+    },
+    "node_modules/connect-mongo/node_modules/debug": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+      "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+      "license": "MIT",
+      "dependencies": {
+        "ms": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/connect-mongo/node_modules/ms": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+      "license": "MIT"
+    },
     "node_modules/console-control-strings": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
@@ -12050,7 +12105,6 @@
       "version": "5.3.0",
       "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.3.0.tgz",
       "integrity": "sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w==",
-      "dev": true,
       "license": "Apache-2.0",
       "optional": true,
       "peer": true,
@@ -12066,7 +12120,6 @@
       "version": "5.1.3",
       "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.1.3.tgz",
       "integrity": "sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA==",
-      "dev": true,
       "license": "Apache-2.0",
       "optional": true,
       "peer": true,
@@ -15677,6 +15730,18 @@
         "node": ">=6"
       }
     },
+    "node_modules/kruptein": {
+      "version": "3.0.7",
+      "resolved": "https://registry.npmjs.org/kruptein/-/kruptein-3.0.7.tgz",
+      "integrity": "sha512-vTftnEjfbqFHLqxDUMQCj6gBo5lKqjV4f0JsM8rk8rM3xmvFZ2eSy4YALdaye7E+cDKnEj7eAjFR3vwh8a4PgQ==",
+      "license": "MIT",
+      "dependencies": {
+        "asn1.js": "^5.4.1"
+      },
+      "engines": {
+        "node": ">8"
+      }
+    },
     "node_modules/lazystream": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz",
@@ -16090,7 +16155,6 @@
       "version": "1.5.0",
       "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
       "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/merge-descriptors": {
@@ -16197,6 +16261,12 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/minimalistic-assert": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+      "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+      "license": "ISC"
+    },
     "node_modules/minimatch": {
       "version": "9.0.1",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
@@ -16578,7 +16648,6 @@
       "version": "6.10.0",
       "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.10.0.tgz",
       "integrity": "sha512-gP9vduuYWb9ZkDM546M+MP2qKVk5ZG2wPF63OvSRuUbqCR+11ZCAE1mOfllhlAG0wcoJY5yDL/rV3OmYEwXIzg==",
-      "dev": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@mongodb-js/saslprep": "^1.1.5",
@@ -16625,7 +16694,6 @@
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz",
       "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==",
-      "dev": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@types/whatwg-url": "^11.0.2",
@@ -18396,7 +18464,6 @@
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
       "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=6"
@@ -19625,7 +19692,6 @@
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
       "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "memory-pager": "^1.0.2"
@@ -21095,7 +21161,6 @@
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz",
       "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "punycode": "^2.3.0"
@@ -21680,7 +21745,6 @@
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
       "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
-      "dev": true,
       "license": "BSD-2-Clause",
       "engines": {
         "node": ">=12"
@@ -21749,7 +21813,6 @@
       "version": "13.0.0",
       "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz",
       "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "tr46": "^4.1.1",
diff --git a/package.json b/package.json
index 8e51516..aa8c29f 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
   "dependencies": {
     "amqplib": "^0.10.5",
     "connect-flash": "^0.1.1",
+    "connect-mongo": "^5.1.0",
     "cookie-parser": "^1.4.7",
     "cors": "^2.8.5",
     "dotenv": "^16.4.5",
diff --git a/weblog.log b/weblog.log
index 6725a76..a44117d 100644
--- a/weblog.log
+++ b/weblog.log
@@ -1,5 +1,5 @@
-(node:182037) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:212098) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 (Use `node --trace-warnings ...` to show where the warning was created)
-(node:182037) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:212098) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 MongoDB�� �깃났�곸쑝濡� �곌껐�섏뿀�듬땲��.
 WebSocket 梨꾪똿 �쒕쾭媛� 8081 �ы듃�먯꽌 �ㅽ뻾 以묒엯�덈떎.
-- 
GitLab


From b124ee3cd3b25e6e762f822298cd57177e842fd3 Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Sun, 8 Dec 2024 17:57:45 +0900
Subject: [PATCH 49/61] =?UTF-8?q?refactor:=20=EC=84=B8=EC=85=98=EB=A1=9C?=
 =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EB=B0=98=ED=99=98=ED=98=95=ED=83=9C=20?=
 =?UTF-8?q?=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 routes/session.js | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/routes/session.js b/routes/session.js
index 803e2ff..7765943 100644
--- a/routes/session.js
+++ b/routes/session.js
@@ -9,10 +9,7 @@ router.get('/info', (req, res) => {
     res.set('Cache-Control', 'no-store');
     res.set('Pragma', 'no-cache');	  
     return res.status(200).json({
-      user: {
-        email,
-        name,
-      },
+      email,name
     });
   }
   // �몄뀡�� 留뚮즺�섏뿀嫄곕굹 �ъ슜�� �뺣낫媛� �녿뒗 寃쎌슦
-- 
GitLab


From 110c8109f1aba80bbded1ffb913e7d1df833d156 Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Sun, 8 Dec 2024 18:44:14 +0900
Subject: [PATCH 50/61] =?UTF-8?q?refacotr:=20cascading=20=EC=97=B0?=
 =?UTF-8?q?=EA=B4=80=20=EA=B4=80=EA=B3=84=20=EC=84=A4=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 models/index.js | 116 +++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 95 insertions(+), 21 deletions(-)

diff --git a/models/index.js b/models/index.js
index 5218166..e76f633 100644
--- a/models/index.js
+++ b/models/index.js
@@ -10,32 +10,106 @@ const Invite =require('./invite')
 const MeetingParticipant = require('./meetingParticipant');
 // const ChatRooms = require('./ChatRooms');
 
-// 愿�怨� �ㅼ젙
-Friend.belongsTo(User, { foreignKey: 'requester_id', as: 'requester' }); // 移쒓뎄 �붿껌�� 蹂대궦 �ъ슜��
-Friend.belongsTo(User, { foreignKey: 'receiver_id', as: 'receiver' });   // 移쒓뎄 �붿껌�� 諛쏆� �ъ슜��
+// Friend 愿�怨� �ㅼ젙
+Friend.belongsTo(User, {
+  foreignKey: 'requester_id',
+  as: 'requester',
+  onDelete: 'CASCADE',
+});
+Friend.belongsTo(User, {
+  foreignKey: 'receiver_id',
+  as: 'receiver',
+  onDelete: 'CASCADE',
+});
+User.hasMany(Friend, {
+  foreignKey: 'requester_id',
+  as: 'sentRequests',
+  onDelete: 'CASCADE',
+});
+User.hasMany(Friend, {
+  foreignKey: 'receiver_id',
+  as: 'receivedRequests',
+  onDelete: 'CASCADE',
+});
 
-User.hasMany(Friend, { foreignKey: 'requester_id', as: 'sentRequests' }); // 移쒓뎄 �붿껌�� 蹂대궦 紐⑸줉
-User.hasMany(Friend, { foreignKey: 'receiver_id', as: 'receivedRequests' }); // 移쒓뎄 �붿껌�� 諛쏆� 紐⑸줉
-// �곌� 愿�怨� �ㅼ젙
-Meeting.belongsTo(User, { foreignKey: 'created_by', as: 'creator' });
-User.hasMany(Meeting, { foreignKey: 'created_by', as: 'meetings' });
+// Meeting 愿�怨� �ㅼ젙
+Meeting.belongsTo(User, {
+  foreignKey: 'created_by',
+  as: 'creator',
+  onDelete: 'SET NULL', // Meetings might persist even if the creator is deleted
+});
+User.hasMany(Meeting, {
+  foreignKey: 'created_by',
+  as: 'meetings',
+  onDelete: 'SET NULL',
+});
 
-MeetingParticipant.belongsTo(Meeting, { foreignKey: 'meeting_id', as: 'meeting' });
-Meeting.hasMany(MeetingParticipant, { foreignKey: 'meeting_id', as: 'participants' });
+// MeetingParticipant 愿�怨� �ㅼ젙
+MeetingParticipant.belongsTo(Meeting, {
+  foreignKey: 'meeting_id',
+  as: 'meeting',
+  onDelete: 'CASCADE',
+});
+Meeting.hasMany(MeetingParticipant, {
+  foreignKey: 'meeting_id',
+  as: 'participants',
+  onDelete: 'CASCADE',
+});
+MeetingParticipant.belongsTo(User, {
+  foreignKey: 'user_id',
+  as: 'user',
+  onDelete: 'CASCADE',
+});
+User.hasMany(MeetingParticipant, {
+  foreignKey: 'user_id',
+  as: 'meetingParticipations',
+  onDelete: 'CASCADE',
+});
 
-MeetingParticipant.belongsTo(User, { foreignKey: 'user_id', as: 'user' });
-User.hasMany(MeetingParticipant, { foreignKey: 'user_id', as: 'meetingParticipations' });
+// Schedule 愿�怨� �ㅼ젙
+Schedule.belongsTo(User, {
+  foreignKey: 'user_id',
+  as: 'user',
+  onDelete: 'CASCADE',
+});
+User.hasMany(Schedule, {
+  foreignKey: 'user_id',
+  as: 'schedules',
+  onDelete: 'CASCADE',
+});
 
-Schedule.belongsTo(User, { foreignKey: 'user_id', as: 'user' });
-User.hasMany(Schedule, { foreignKey: 'user_id', as: 'schedules' });
+// Invite 愿�怨� �ㅼ젙
+Invite.belongsTo(Meeting, {
+  foreignKey: 'meeting_id',
+  as: 'meeting',
+  onDelete: 'CASCADE',
+});
+Invite.belongsTo(User, {
+  foreignKey: 'inviter_id',
+  as: 'inviter',
+  onDelete: 'CASCADE',
+});
+Invite.belongsTo(User, {
+  foreignKey: 'invitee_id',
+  as: 'invitee',
+  onDelete: 'CASCADE',
+});
+User.hasMany(Invite, {
+  foreignKey: 'inviter_id',
+  as: 'sentInvites',
+  onDelete: 'CASCADE',
+});
+User.hasMany(Invite, {
+  foreignKey: 'invitee_id',
+  as: 'receivedInvites',
+  onDelete: 'CASCADE',
+});
+Meeting.hasMany(Invite, {
+  foreignKey: 'meeting_id',
+  as: 'invites',
+  onDelete: 'CASCADE',
+});
 
-Invite.belongsTo(Meeting, { foreignKey: 'meeting_id', as: 'meeting' });
-Invite.belongsTo(User, { foreignKey: 'inviter_id', as: 'inviter' }); // 珥덈��� �ъ슜��
-Invite.belongsTo(User, { foreignKey: 'invitee_id', as: 'invitee' }); // 珥덈�諛쏆� �ъ슜��
-
-User.hasMany(Invite, { foreignKey: 'inviter_id', as: 'sentInvites' }); // 蹂대궦 珥덈� 紐⑸줉
-User.hasMany(Invite, { foreignKey: 'invitee_id', as: 'receivedInvites' }); // 諛쏆� 珥덈� 紐⑸줉
-Meeting.hasMany(Invite, { foreignKey: 'meeting_id', as: 'invites' }); // �대떦 誘명똿�� 紐⑤뱺 珥덈�
 
 module.exports = {
     sequelize,
-- 
GitLab


From 6fd4ae8b771d37d0d66cd31caf440fe61e14c91c Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Sun, 8 Dec 2024 18:56:44 +0900
Subject: [PATCH 51/61] =?UTF-8?q?refactor:=20=EC=97=B0=EA=B4=80=EA=B4=80?=
 =?UTF-8?q?=EA=B3=84=20=EC=BA=90=EC=8A=A4=EC=BA=90=EC=9D=B4=EB=94=A9=20?=
 =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80(#25)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 models/index.js | 119 ++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 95 insertions(+), 24 deletions(-)

diff --git a/models/index.js b/models/index.js
index 7c656bc..7caa672 100644
--- a/models/index.js
+++ b/models/index.js
@@ -10,35 +10,106 @@ const Invite =require('./invite')
 const MeetingParticipant = require('./meetingParticipant');
 // const ChatRooms = require('./ChatRooms');
 
-// 愿�怨� �ㅼ젙
-Friend.belongsTo(User, { foreignKey: 'requester_id', as: 'requester' }); // 移쒓뎄 �붿껌�� 蹂대궦 �ъ슜��
-Friend.belongsTo(User, { foreignKey: 'receiver_id', as: 'receiver' });   // 移쒓뎄 �붿껌�� 諛쏆� �ъ슜��
+// Friend 愿�怨� �ㅼ젙
+Friend.belongsTo(User, {
+  foreignKey: 'requester_id',
+  as: 'requester',
+  onDelete: 'CASCADE',
+});
+Friend.belongsTo(User, {
+  foreignKey: 'receiver_id',
+  as: 'receiver',
+  onDelete: 'CASCADE',
+});
+User.hasMany(Friend, {
+  foreignKey: 'requester_id',
+  as: 'sentRequests',
+  onDelete: 'CASCADE',
+});
+User.hasMany(Friend, {
+  foreignKey: 'receiver_id',
+  as: 'receivedRequests',
+  onDelete: 'CASCADE',
+});
 
-User.hasMany(Friend, { foreignKey: 'requester_id', as: 'sentRequests' }); // 移쒓뎄 �붿껌�� 蹂대궦 紐⑸줉
-User.hasMany(Friend, { foreignKey: 'receiver_id', as: 'receivedRequests' }); // 移쒓뎄 �붿껌�� 諛쏆� 紐⑸줉
-// �곌� 愿�怨� �ㅼ젙
-Meeting.belongsTo(User, { foreignKey: 'created_by', as: 'creator' });
-User.hasMany(Meeting, { foreignKey: 'created_by', as: 'meetings' });
+// Meeting 愿�怨� �ㅼ젙
+Meeting.belongsTo(User, {
+  foreignKey: 'created_by',
+  as: 'creator',
+  onDelete: 'SET NULL', 
+});
+User.hasMany(Meeting, {
+  foreignKey: 'created_by',
+  as: 'meetings',
+  onDelete: 'SET NULL',
+});
 
-MeetingParticipant.belongsTo(Meeting, { foreignKey: 'meeting_id', as: 'meeting' });
-Meeting.hasMany(MeetingParticipant, { foreignKey: 'meeting_id', as: 'participants' });
+// MeetingParticipant 愿�怨� �ㅼ젙
+MeetingParticipant.belongsTo(Meeting, {
+  foreignKey: 'meeting_id',
+  as: 'meeting',
+  onDelete: 'CASCADE',
+});
+Meeting.hasMany(MeetingParticipant, {
+  foreignKey: 'meeting_id',
+  as: 'participants',
+  onDelete: 'CASCADE',
+});
+MeetingParticipant.belongsTo(User, {
+  foreignKey: 'user_id',
+  as: 'user',
+  onDelete: 'CASCADE',
+});
+User.hasMany(MeetingParticipant, {
+  foreignKey: 'user_id',
+  as: 'meetingParticipations',
+  onDelete: 'CASCADE',
+});
 
-MeetingParticipant.belongsTo(User, { foreignKey: 'user_id', as: 'user' });
-User.hasMany(MeetingParticipant, { foreignKey: 'user_id', as: 'meetingParticipations' });
+// Schedule 愿�怨� �ㅼ젙
+Schedule.belongsTo(User, {
+  foreignKey: 'user_id',
+  as: 'user',
+  onDelete: 'CASCADE',
+});
+User.hasMany(Schedule, {
+  foreignKey: 'user_id',
+  as: 'schedules',
+  onDelete: 'CASCADE',
+});
 
-Schedule.belongsTo(User, { foreignKey: 'user_id', as: 'user' });
-User.hasMany(Schedule, { foreignKey: 'user_id', as: 'schedules' });
+// Invite 愿�怨� �ㅼ젙
+Invite.belongsTo(Meeting, {
+  foreignKey: 'meeting_id',
+  as: 'meeting',
+  onDelete: 'CASCADE',
+});
+Invite.belongsTo(User, {
+  foreignKey: 'inviter_id',
+  as: 'inviter',
+  onDelete: 'CASCADE',
+});
+Invite.belongsTo(User, {
+  foreignKey: 'invitee_id',
+  as: 'invitee',
+  onDelete: 'CASCADE',
+});
+User.hasMany(Invite, {
+  foreignKey: 'inviter_id',
+  as: 'sentInvites',
+  onDelete: 'CASCADE',
+});
+User.hasMany(Invite, {
+  foreignKey: 'invitee_id',
+  as: 'receivedInvites',
+  onDelete: 'CASCADE',
+});
+Meeting.hasMany(Invite, {
+  foreignKey: 'meeting_id',
+  as: 'invites',
+  onDelete: 'CASCADE',
+});
 
-FcmToken.belongsTo(User, { foreignKey: 'userId', as: 'user' });
-User.hasMany(FcmToken, { foreignKey: 'userId', as: 'fcmTokenList' });
-
-Invite.belongsTo(Meeting, { foreignKey: 'meeting_id', as: 'meeting' });
-Invite.belongsTo(User, { foreignKey: 'inviter_id', as: 'inviter' }); // 珥덈��� �ъ슜��
-Invite.belongsTo(User, { foreignKey: 'invitee_id', as: 'invitee' }); // 珥덈�諛쏆� �ъ슜��
-
-User.hasMany(Invite, { foreignKey: 'inviter_id', as: 'sentInvites' }); // 蹂대궦 珥덈� 紐⑸줉
-User.hasMany(Invite, { foreignKey: 'invitee_id', as: 'receivedInvites' }); // 諛쏆� 珥덈� 紐⑸줉
-Meeting.hasMany(Invite, { foreignKey: 'meeting_id', as: 'invites' }); // �대떦 誘명똿�� 紐⑤뱺 珥덈�
 
 module.exports = {
     sequelize,
-- 
GitLab


From a7f956dfcf9cea482f59733a697ba037a1029c25 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: Sun, 8 Dec 2024 19:58:29 +0900
Subject: [PATCH 52/61] =?UTF-8?q?refactor:=20=EB=82=B4=20=EB=AF=B8?=
 =?UTF-8?q?=ED=8C=85/=20=EC=A0=84=EC=B2=B4=20=EB=AF=B8=ED=8C=85=20?=
 =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=88=98?=
 =?UTF-8?q?=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 services/meetingService.js | 225 +++++++++++++++++++------------------
 1 file changed, 117 insertions(+), 108 deletions(-)

diff --git a/services/meetingService.js b/services/meetingService.js
index 746bcf1..dd1eaca 100644
--- a/services/meetingService.js
+++ b/services/meetingService.js
@@ -314,130 +314,139 @@ class MeetingService {
     
     async getMeetings(userId, pagination) {
         const { limit = 20, offset = 0 } = pagination;
-
-        const meetings = await Meeting.findAll({
-            attributes: [
-                'id',
-                'title',
-                'description',
-                'time_idx_start',
-                'time_idx_end',
-                'location',
-                'time_idx_deadline',
-                'type',
-                'max_num',
-                'cur_num',
-            ],
-            include: [
-                {
-                    model: MeetingParticipant,
-                    as: 'participants',
-                    required: false, 
-                    attributes: [],
-                },
-                {
-                    model: User,
-                    as: 'creator',
-                    attributes: ['name'],
-                }
-            ],
-            order: [['createdAt', 'DESC']],
-            offset
-        });
     
-        const hasNext = meetings.length > limit;
-        const content = await Promise.all(
-            meetings.slice(0, limit).map(async (meeting) => {
-                const isParticipant = await MeetingParticipant.findOne({
-                    where: {
-                        meeting_id: meeting.id,
-                        user_id: userId
+        try {
+            const meetings = await Meeting.findAll({
+                attributes: [
+                    'id', 'title', 'description',
+                    'time_idx_start', 'time_idx_end',
+                    'location', 'time_idx_deadline',
+                    'type', 'max_num', 'cur_num',
+                    'created_at' 
+                ],
+                include: [
+                    {
+                        model: MeetingParticipant,
+                        as: 'participants',
+                        required: false,
+                        where: { user_id: userId },
+                        attributes: []
+                    },
+                    {
+                        model: User,
+                        as: 'creator',
+                        attributes: ['name'],
+                        required: false
                     }
-                });
+                ],
+                where: {
+                    [Op.or]: [
+                        { created_by: userId },
+                        { '$participants.meeting_id$': { [Op.col]: 'Meeting.id' } },
+                        { '$participants.user_id$': userId }
+                    ]
+                },
+                subQuery: false,
+                order: [['created_at', 'DESC']],
+                limit: limit + 1,
+                offset,
+                distinct: true
+            });
     
-                const hasConflict = await ScheduleService.checkScheduleOverlapByTime(
-                    userId,
-                    meeting.time_idx_start,
-                    meeting.time_idx_end
-                );
+            const hasNext = meetings.length > limit;
+            const content = await Promise.all(
+                meetings.slice(0, limit).map(async (meeting) => {
+                    const isParticipant = true;  
+                    const hasConflict = await ScheduleService.checkScheduleOverlapByTime(
+                        userId,
+                        meeting.time_idx_start,
+                        meeting.time_idx_end
+                    );
     
-                const creatorName = meeting.creator ? meeting.creator.name : 'Unknown';
-                return new MeetingResponseDTO(meeting, !!isParticipant, hasConflict, creatorName);
-            })
-        );
+                    return new MeetingResponseDTO(
+                        meeting,
+                        isParticipant,
+                        hasConflict,
+                        meeting.creator?.name || 'Unknown'
+                    );
+                })
+            );
     
-        return {
-            content,
-            hasNext
-        };
+            return { content, hasNext };
+        } catch (error) {
+            console.error('getMeetings error:', error);
+            throw new Error('Failed to fetch meetings');
+        }
     }
 
     async getMyMeetings(userId, pagination) {
         const { limit = 20, offset = 0 } = pagination;
     
-        const meetings = await Meeting.findAll({
-            attributes: [
-                'id',
-                'title',
-                'description',
-                'time_idx_start',
-                'time_idx_end',
-                'location',
-                'time_idx_deadline',
-                'type',
-                'max_num',
-                'cur_num',
-            ],
-            include: [
-                {
-                    model: MeetingParticipant,
-                    as: 'participants',
-                    where: { user_id: userId }, 
-                    attributes: [],
+        try {
+            const meetings = await Meeting.findAll({
+                attributes: [
+                    'id', 'title', 'description', 'time_idx_start',
+                    'time_idx_end', 'location', 'time_idx_deadline',
+                    'type', 'max_num', 'cur_num',
+                ],
+                include: [
+                    {
+                        model: MeetingParticipant,
+                        as: 'participants',
+                        required: false,
+                        attributes: []
+                    },
+                    {
+                        model: User,
+                        as: 'creator',
+                        attributes: ['name']
+                    }
+                ],
+                where: {
+                    [Op.or]: [
+                        { created_by: userId },
+                        { '$participants.meeting_id$': { [Op.col]: 'Meeting.id' } },
+                        { '$participants.user_id$': userId }
+                    ]
                 },
-                {
-                    model: User,
-                    as: 'creator',
-                    attributes: ['name'],
-                }
-            ],
-            where: {
-                [Op.or]: [
-                    { created_by: userId },  
-                    { '$participants.user_id$': userId }  
-                ]
-            },
-            order: [['createdAt', 'DESC']],
-            offset
-        });
+                subQuery: false,
+                order: [['created_at', 'DESC']],
+                limit: limit + 1,
+                offset,
+                distinct: true
+            });
     
-        const hasNext = meetings.length > limit;
-        const content = await Promise.all(
-            meetings.slice(0, limit).map(async (meeting) => {
-                const isParticipant = await MeetingParticipant.findOne({
-                    where: {
-                        meeting_id: meeting.id,
-                        user_id: userId
-                    }
-                });
+            const hasNext = meetings.length > limit;
+            const content = await Promise.all(
+                meetings.slice(0, limit).map(async (meeting) => {
+                    const isParticipant = await MeetingParticipant.findOne({
+                        where: {
+                            meeting_id: meeting.id,
+                            user_id: userId
+                        }
+                    });
     
-                const hasConflict = await ScheduleService.checkScheduleOverlapByTime(
-                    userId,
-                    meeting.time_idx_start,
-                    meeting.time_idx_end
-                );
+                    const hasConflict = await ScheduleService.checkScheduleOverlapByTime(
+                        userId,
+                        meeting.time_idx_start,
+                        meeting.time_idx_end
+                    );
     
-                const creatorName = meeting.creator ? meeting.creator.name : 'Unknown';
-                return new MeetingResponseDTO(meeting, !!isParticipant, hasConflict, creatorName);
-            })
-        );
+                    return {
+                        ...meeting.toJSON(),
+                        isParticipant: !!isParticipant,
+                        hasConflict,
+                        creatorName: meeting.creator?.name || 'Unknown'
+                    };
+                })
+            );
     
-        return {
-            content,
-            hasNext
-        };
+            return { content, hasNext };
+        } catch (error) {
+            console.error('getMyMeetings error:', error);
+            throw new Error('Failed to fetch my meetings');
+        }
     }
-
     async getMeetingDetail(meetingId, userId) {
         const meeting = await Meeting.findByPk(meetingId, {
             include: [
-- 
GitLab


From e6169bf9f843919b2ce191455073e3b48432c89c 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: Sun, 8 Dec 2024 19:58:59 +0900
Subject: [PATCH 53/61] =?UTF-8?q?bugfix:=20=EC=83=81=EC=84=B8=20=EC=A1=B0?=
 =?UTF-8?q?=ED=9A=8C=20/=20=EB=82=B4=20=EB=AF=B8=ED=8C=85=20=EC=A1=B0?=
 =?UTF-8?q?=ED=9A=8C=20=EC=88=9C=EC=84=9C=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 routes/meetingRoute.js | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/routes/meetingRoute.js b/routes/meetingRoute.js
index 9d2e26f..a85d202 100644
--- a/routes/meetingRoute.js
+++ b/routes/meetingRoute.js
@@ -7,6 +7,9 @@ const MeetingController = require('../controllers/meetingController');
 
 router.use(isLoggedIn);
 
+// �닿� 李몄뿬�� 紐⑥엫 紐⑸줉 議고쉶
+router.get('/my', MeetingController.getMyMeetings);
+
 // 踰덇컻 紐⑥엫 �앹꽦
 router.post('/', MeetingController.createMeeting);
 
@@ -25,7 +28,6 @@ router.get('/:meetingId', MeetingController.getMeetingDetail);
 // 踰덇컻 紐⑥엫 �덊눜
 router.delete('/:meetingId/leave', MeetingController.leaveMeeting);
 
-// �닿� 李몄뿬�� 紐⑥엫 紐⑸줉 議고쉶
-router.get('/my', MeetingController.getMyMeetings);
+
 
 module.exports = router;
\ No newline at end of file
-- 
GitLab


From 311fd6023510ff45b2eb1e04325764156ef5052c Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Sun, 8 Dec 2024 20:11:14 +0900
Subject: [PATCH 54/61] =?UTF-8?q?feature:=20=ED=9A=8C=EC=9B=90=20=ED=83=88?=
 =?UTF-8?q?=ED=87=B4=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80(#25)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app.js                                     |  8 +--
 routes/auth.js                             | 50 -------------
 routes/authRoute.js                        | 84 ++++++++++++++++++++++
 routes/{friend.js => friendRoute.js}       |  0
 routes/{inviteRoutes.js => inviteRoute.js} |  0
 routes/{schedule.js => scheduleRoute.js}   |  0
 routes/{session.js => sessionRoute.js}     |  0
 7 files changed, 88 insertions(+), 54 deletions(-)
 delete mode 100644 routes/auth.js
 create mode 100644 routes/authRoute.js
 rename routes/{friend.js => friendRoute.js} (100%)
 rename routes/{inviteRoutes.js => inviteRoute.js} (100%)
 rename routes/{schedule.js => scheduleRoute.js} (100%)
 rename routes/{session.js => sessionRoute.js} (100%)

diff --git a/app.js b/app.js
index 1841e8c..941531d 100644
--- a/app.js
+++ b/app.js
@@ -58,13 +58,13 @@ app.use(flash());
 //app.set('trust proxy', 1);
 console.log('MongoDB URI:', process.env.MONGO_URI);
 //�쇱슦�� �깅줉 
-const authRoutes = require('./routes/auth');
+const authRoutes = require('./routes/authRoute');
 app.use('/api/auth', authRoutes);
 
-const scheduleRoutes = require('./routes/schedule');
+const scheduleRoutes = require('./routes/scheduleRoute');
 app.use('/api/schedule', scheduleRoutes);
 
-const friendRoutes = require('./routes/friend');
+const friendRoutes = require('./routes/friendRoute');
 app.use('/api/friend', friendRoutes);
 
 const meetingRoutes = require('./routes/meetingRoute');
@@ -76,7 +76,7 @@ app.use('/api/chat', chatRoutes);
 const memberRoutes = require('./routes/memberRoute');
 app.use('/api/member', memberRoutes);
 
-const sessionRouter = require('./routes/session');
+const sessionRouter = require('./routes/sessionRoute');
 app.use('/api/session', sessionRouter);
 
 // �ㅼ�以� �대━�� 珥덇린��
diff --git a/routes/auth.js b/routes/auth.js
deleted file mode 100644
index 186b15d..0000000
--- a/routes/auth.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const express = require('express');
-const passport = require('passport');
-
-const router = express.Router();
-
-// Google OAuth 濡쒓렇�� �쇱슦��
-router.get(
-  '/login',
-  passport.authenticate('google', {
-    scope: ['profile', 'email'], // �ъ슜�� �뺣낫 �붿껌�� �꾪븳 scope 
-    failureRedirect: `${process.env.FRONT_URL}/login`
-  })
-);
-
-router.get(
-  '/google/callback',
-  passport.authenticate('google', {
-    failureRedirect: `${process.env.FRONT_URL}/login` // �섏젙�� 遺�遺�
-  }),
-  (req, res) => {
-    const redirectUrl = process.env.FRONT_URL;
-    req.session.save((err) => {
-      if (err) {
-        console.error('�몄뀡 ���� �ㅻ쪟:', err);
-        return res.status(500).json({ error: '�쒕쾭 �ㅻ쪟' });
-      }
-      res.redirect(redirectUrl);
-    });
-  }
-);
-
-// 濡쒓렇�꾩썐 �쇱슦��
-router.get('/logout', (req, res) => {
-  if (req.session) {
-    req.session.destroy((err) => {
-      if (err) {
-        console.error('�몄뀡 ��젣 �ㅻ쪟:', err);
-        return res.status(500).json({ error: '�쒕쾭 �ㅻ쪟' });
-      }
-      const redirectUrl = process.env.FRONT_URL;
-      res.redirect(redirectUrl);
-    });
-  } else {
-    // �몄뀡�� �녿뒗 寃쎌슦�먮룄 由щ떎�대젆��
-    const redirectUrl = process.env.FRONT_URL;
-    res.redirect(redirectUrl);
-  }
-});
-
-module.exports = router;
\ No newline at end of file
diff --git a/routes/authRoute.js b/routes/authRoute.js
new file mode 100644
index 0000000..e6f2d55
--- /dev/null
+++ b/routes/authRoute.js
@@ -0,0 +1,84 @@
+  const express = require('express');
+  const passport = require('passport');
+
+  const router = express.Router();
+
+  // Google OAuth 濡쒓렇�� �쇱슦��
+  router.get(
+    '/login',
+    passport.authenticate('google', {
+      scope: ['profile', 'email'], // �ъ슜�� �뺣낫 �붿껌�� �꾪븳 scope 
+      failureRedirect: `${process.env.FRONT_URL}/login`
+    })
+  );
+
+  router.get(
+    '/google/callback',
+    passport.authenticate('google', {
+      failureRedirect: `${process.env.FRONT_URL}/login` 
+    }),
+    (req, res) => {
+      const redirectUrl = process.env.FRONT_URL;
+      req.session.save((err) => {
+        if (err) {
+          console.error('�몄뀡 ���� �ㅻ쪟:', err);
+          return res.status(500).json({ error: '�쒕쾭 �ㅻ쪟' });
+        }
+        res.redirect(redirectUrl);
+      });
+    }
+  );
+
+  // 濡쒓렇�꾩썐 �쇱슦��
+  router.get('/logout', (req, res) => {
+    if (req.session) {
+      req.session.destroy((err) => {
+        if (err) {
+          console.error('�몄뀡 ��젣 �ㅻ쪟:', err);
+          return res.status(500).json({ error: '�쒕쾭 �ㅻ쪟' });
+        }
+        const redirectUrl = process.env.FRONT_URL;
+        res.redirect(redirectUrl);
+      });
+    } else {
+      // �몄뀡�� �녿뒗 寃쎌슦�먮룄 由щ떎�대젆��
+      const redirectUrl = process.env.FRONT_URL;
+      res.redirect(redirectUrl);
+    }
+  });
+  
+  // �ъ슜�� ��젣 �쇱슦��
+router.delete('/leave', async (req, res) => {
+  try {
+    // �몄쬆�� �ъ슜�� �뺤씤
+    if (!req.user) {
+      return res.status(401).json({ error: '�몄쬆�섏� �딆� �ъ슜�먯엯�덈떎.' });
+    }
+
+    const userId = req.user.id;
+
+    // �ъ슜�� ��젣
+    const deleted = await User.destroy({
+      where: { id: userId }
+    });
+
+    if (!deleted) {
+      return res.status(404).json({ error: '�ъ슜�먮� 李얠쓣 �� �놁뒿�덈떎.' });
+    }
+
+    // �몄뀡 ��젣
+    req.session.destroy((err) => {
+      if (err) {
+        console.error('�몄뀡 ��젣 �ㅻ쪟:', err);
+        return res.status(500).json({ error: '�쒕쾭 �ㅻ쪟' });
+      }
+      // �깃났 硫붿떆吏� 諛섑솚 (由щ떎�대젆�� ���� JSON �묐떟)
+      res.status(200).json({ message: '�ъ슜�� 怨꾩젙�� �깃났�곸쑝濡� ��젣�섏뿀�듬땲��.' });
+    });
+  } catch (error) {
+    console.error('�ъ슜�� ��젣 �ㅻ쪟:', error);
+    res.status(500).json({ error: '�쒕쾭 �ㅻ쪟' });
+  }
+});
+
+  module.exports = router;
\ No newline at end of file
diff --git a/routes/friend.js b/routes/friendRoute.js
similarity index 100%
rename from routes/friend.js
rename to routes/friendRoute.js
diff --git a/routes/inviteRoutes.js b/routes/inviteRoute.js
similarity index 100%
rename from routes/inviteRoutes.js
rename to routes/inviteRoute.js
diff --git a/routes/schedule.js b/routes/scheduleRoute.js
similarity index 100%
rename from routes/schedule.js
rename to routes/scheduleRoute.js
diff --git a/routes/session.js b/routes/sessionRoute.js
similarity index 100%
rename from routes/session.js
rename to routes/sessionRoute.js
-- 
GitLab


From 67c2a54b99797797a446d97193d786c45c9ab4fb 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: Sun, 8 Dec 2024 20:20:02 +0900
Subject: [PATCH 55/61] =?UTF-8?q?bugfix:=20=EB=AF=B8=ED=8C=85=20=EC=A1=B0?=
 =?UTF-8?q?=ED=9A=8C=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 services/meetingService.js | 80 +++++++++++++-------------------------
 1 file changed, 26 insertions(+), 54 deletions(-)

diff --git a/services/meetingService.js b/services/meetingService.js
index dd1eaca..bc7b7f7 100644
--- a/services/meetingService.js
+++ b/services/meetingService.js
@@ -322,16 +322,9 @@ class MeetingService {
                     'time_idx_start', 'time_idx_end',
                     'location', 'time_idx_deadline',
                     'type', 'max_num', 'cur_num',
-                    'created_at' 
+                    'created_at'
                 ],
                 include: [
-                    {
-                        model: MeetingParticipant,
-                        as: 'participants',
-                        required: false,
-                        where: { user_id: userId },
-                        attributes: []
-                    },
                     {
                         model: User,
                         as: 'creator',
@@ -339,14 +332,6 @@ class MeetingService {
                         required: false
                     }
                 ],
-                where: {
-                    [Op.or]: [
-                        { created_by: userId },
-                        { '$participants.meeting_id$': { [Op.col]: 'Meeting.id' } },
-                        { '$participants.user_id$': userId }
-                    ]
-                },
-                subQuery: false,
                 order: [['created_at', 'DESC']],
                 limit: limit + 1,
                 offset,
@@ -356,7 +341,13 @@ class MeetingService {
             const hasNext = meetings.length > limit;
             const content = await Promise.all(
                 meetings.slice(0, limit).map(async (meeting) => {
-                    const isParticipant = true;  
+                    const isParticipant = await MeetingParticipant.findOne({
+                        where: {
+                            meeting_id: meeting.id,
+                            user_id: userId
+                        }
+                    });
+    
                     const hasConflict = await ScheduleService.checkScheduleOverlapByTime(
                         userId,
                         meeting.time_idx_start,
@@ -365,7 +356,7 @@ class MeetingService {
     
                     return new MeetingResponseDTO(
                         meeting,
-                        isParticipant,
+                        !!isParticipant,
                         hasConflict,
                         meeting.creator?.name || 'Unknown'
                     );
@@ -385,31 +376,26 @@ class MeetingService {
         try {
             const meetings = await Meeting.findAll({
                 attributes: [
-                    'id', 'title', 'description', 'time_idx_start',
-                    'time_idx_end', 'location', 'time_idx_deadline',
+                    'id', 'title', 'description',
+                    'time_idx_start', 'time_idx_end',
+                    'location', 'time_idx_deadline',
                     'type', 'max_num', 'cur_num',
+                    'created_at'
                 ],
                 include: [
                     {
                         model: MeetingParticipant,
                         as: 'participants',
-                        required: false,
-                        attributes: []
+                        where: { user_id: userId },
+                        required: true
                     },
                     {
                         model: User,
                         as: 'creator',
-                        attributes: ['name']
+                        attributes: ['name'],
+                        required: false
                     }
                 ],
-                where: {
-                    [Op.or]: [
-                        { created_by: userId },
-                        { '$participants.meeting_id$': { [Op.col]: 'Meeting.id' } },
-                        { '$participants.user_id$': userId }
-                    ]
-                },
-                subQuery: false,
                 order: [['created_at', 'DESC']],
                 limit: limit + 1,
                 offset,
@@ -417,29 +403,14 @@ class MeetingService {
             });
     
             const hasNext = meetings.length > limit;
-            const content = await Promise.all(
-                meetings.slice(0, limit).map(async (meeting) => {
-                    const isParticipant = await MeetingParticipant.findOne({
-                        where: {
-                            meeting_id: meeting.id,
-                            user_id: userId
-                        }
-                    });
-    
-                    const hasConflict = await ScheduleService.checkScheduleOverlapByTime(
-                        userId,
-                        meeting.time_idx_start,
-                        meeting.time_idx_end
-                    );
-    
-                    return {
-                        ...meeting.toJSON(),
-                        isParticipant: !!isParticipant,
-                        hasConflict,
-                        creatorName: meeting.creator?.name || 'Unknown'
-                    };
-                })
-            );
+            const content = meetings.slice(0, limit).map(meeting => {
+                return new MeetingResponseDTO(
+                    meeting,
+                    true,  // 李몄뿬�먮줈 議고쉶�덉쑝誘�濡� ��긽 true
+                    false, // �대� 李몄뿬 以묒씤 誘명똿�대�濡� 異⑸룎 泥댄겕 遺덊븘��
+                    meeting.creator?.name || 'Unknown'
+                );
+            });
     
             return { content, hasNext };
         } catch (error) {
@@ -447,6 +418,7 @@ class MeetingService {
             throw new Error('Failed to fetch my meetings');
         }
     }
+    
     async getMeetingDetail(meetingId, userId) {
         const meeting = await Meeting.findByPk(meetingId, {
             include: [
-- 
GitLab


From d6d6d3e616848140240e24fd96dd1cc1e8dcdf55 Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Sun, 8 Dec 2024 20:46:44 +0900
Subject: [PATCH 56/61] bugfix

---
 middlewares/auth.js | 1 -
 1 file changed, 1 deletion(-)

diff --git a/middlewares/auth.js b/middlewares/auth.js
index 10118d7..52eb397 100644
--- a/middlewares/auth.js
+++ b/middlewares/auth.js
@@ -1,5 +1,4 @@
 // middlewares/auth.js
-exports.isLoggedIn = (req, res, next) => { // 濡쒓렇�몃맂 �ъ슜�먮쭔 �묎렐 �덉슜
 exports.isLoggedIn = (req, res, next) => { // 濡쒓렇�몃맂 �ъ슜�먮쭔 �묎렐 �덉슜
   if (req.isAuthenticated()) {
     return next();
-- 
GitLab


From e0f82b7b1b29f9debed7035bceda5888ff568a2b Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Sun, 8 Dec 2024 20:49:57 +0900
Subject: [PATCH 57/61] =?UTF-8?q?bugfix:=20=EB=B3=91=ED=95=A9=EC=B6=9C?=
 =?UTF-8?q?=EB=8F=99=20=ED=95=B4=EA=B2=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app.js            |  2 +-
 routes/auth.js    | 51 -----------------------------------------------
 routes/session.js | 23 ---------------------
 3 files changed, 1 insertion(+), 75 deletions(-)
 delete mode 100644 routes/auth.js
 delete mode 100644 routes/session.js

diff --git a/app.js b/app.js
index c01d340..7fa87fe 100644
--- a/app.js
+++ b/app.js
@@ -57,7 +57,7 @@ app.use(flash());
 app.set('trust proxy', 1);
 console.log('MongoDB URI:', process.env.MONGO_URI);
 //�쇱슦�� �깅줉 
-const authRoutes = require('./routes/auth');
+const authRoutes = require('./routes/authRoute');
 app.use('/api/auth', authRoutes);
 
 const scheduleRoutes = require('./routes/scheduleRoute');
diff --git a/routes/auth.js b/routes/auth.js
deleted file mode 100644
index 2eb8e9a..0000000
--- a/routes/auth.js
+++ /dev/null
@@ -1,51 +0,0 @@
-const express = require('express');
-const passport = require('passport');
-
-const router = express.Router();
-
-// Google OAuth 濡쒓렇�� �쇱슦��
-router.get(
-  '/login',
-  passport.authenticate('google', {
-    scope: ['profile', 'email'], // �ъ슜�� �뺣낫 �붿껌�� �꾪븳 scope 
-    failureRedirect: `${process.env.FRONT_URL}/login`
-  })
-);
-
-// Google OAuth 肄쒕갚 �쇱슦��
-router.get(
-  '/google/callback',
-  passport.authenticate('google', {
-    failureRedirect: '/auth/login'
-  }),
-  (req, res) => {
-    const redirectUrl = process.env.FRONT_URL;
-    req.session.save((err) => {
-      if (err) {
-        console.error('�몄뀡 ���� �ㅻ쪟:', err);
-        return res.status(500).json({ error: '�쒕쾭 �ㅻ쪟' });
-      }
-      res.redirect(redirectUrl);
-    });
-  }
-);
-
-// 濡쒓렇�꾩썐 �쇱슦��
-router.get('/logout', (req, res) => {
-  if (req.session) {
-    req.session.destroy((err) => {
-      if (err) {
-        console.error('�몄뀡 ��젣 �ㅻ쪟:', err);
-        return res.status(500).json({ error: '�쒕쾭 �ㅻ쪟' });
-      }
-      const redirectUrl = process.env.FRONT_URL;
-      res.redirect(redirectUrl);
-    });
-  } else {
-    // �몄뀡�� �녿뒗 寃쎌슦�먮룄 由щ떎�대젆��
-    const redirectUrl = process.env.FRONT_URL;
-    res.redirect(redirectUrl);
-  }
-});
-
-module.exports = router;
diff --git a/routes/session.js b/routes/session.js
deleted file mode 100644
index 7765943..0000000
--- a/routes/session.js
+++ /dev/null
@@ -1,23 +0,0 @@
-const express = require('express');
-const router = express.Router();
-
-// GET /api/session/info
-router.get('/info', (req, res) => {
-  if (req.user) {
-    const { email, name } = req.user;
-  // 罹먯떛 鍮꾪솢�깊솕
-    res.set('Cache-Control', 'no-store');
-    res.set('Pragma', 'no-cache');	  
-    return res.status(200).json({
-      email,name
-    });
-  }
-  // �몄뀡�� 留뚮즺�섏뿀嫄곕굹 �ъ슜�� �뺣낫媛� �녿뒗 寃쎌슦
-  res.set('Cache-Control', 'no-store');
-  res.set('Pragma', 'no-cache');
-  res.status(401).json({
-    message: '�몄뀡�� 留뚮즺�섏뿀嫄곕굹 �ъ슜�� �뺣낫媛� �놁뒿�덈떎.',
-  });
-});
-
-module.exports = router;
-- 
GitLab


From afc12f54b46a57ac956b47b73ef7c3ff66cffe10 Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Sun, 8 Dec 2024 21:07:51 +0900
Subject: [PATCH 58/61] =?UTF-8?q?refactor:=20=EC=84=B8=EC=85=98=EC=A1=B0?=
 =?UTF-8?q?=ED=9A=8C=20json=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .app2.js.swp           | Bin 12288 -> 0 bytes
 routes/sessionRoute.js |   5 +----
 2 files changed, 1 insertion(+), 4 deletions(-)
 delete mode 100644 .app2.js.swp

diff --git a/.app2.js.swp b/.app2.js.swp
deleted file mode 100644
index d6adf66f7481c87e6cb0559f90b01bbe76f5cd3e..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 12288
zcmeI2U2IfE6vqeoP(j3~55kKhknC2vA1zUuRxr>m(AakCe)u3U<#u=4Uf8{NxgVuV
zSwt;Z(11oLMO%cV;)BMN4@pVDk7#@{(fCAS^nv))-Aa5>6Jz3k?$_SkE<P9%LvlCy
z_1>Lx=FFKhXU<I1_J&_*@1#w^MuN{nge+T{>~HyPA!&JLA<=tvNz=LD-#=n5(6FH~
zu)ZPC5NO<Rd)))3!O&jT+bg7YhlE_NF}O>;eFsnCMZk-|or!?1^#z)iC)YPNgt@^r
ztDm5cJe<5UwmmCe1iT1%5%415MZk-I7XdE<UIe@d+!Ybfatp}I@bn(b+d=EOpz3LT
z^&VaXya;#^@FL(vz>9zv0WShx1iT1%5%415MZk-|T^Io&O~_jOvj5mZIFG;o+rR(+
zvVxE=zzOgiSOflgkdW(O5Cp&qFt?nL^WZo*1`2?IG)RID&<d7-ZyzA!Bsc)_U=ZkF
z8)yPyunJsRM#w059Vmc-BzP43y_Aq2!Pnp%&_Od;0e-)qkXdj8d<G7K6xa${KqFWO
zR)QP%5%LxI99#u6;C*ly>;hZBYH;gbLVg9`fb-x87zKl12Y3-|1uMZHOW*_e5}X2K
zfPrVhCa?tjyqJ)mz(?Q+7zHs<57vP{7ZLJ3_zrvmPJuBX0||71jo>M;3M>YTz%8ub
z4`2)&1N%S|SOXphD}k}bcVUkHFD@7A{B<pa(gL6~r^qR$szEj+YW@a8Kxs;rR5`<f
zOi^UT@4GqqCM}Ij6fcg@(i;<{GjG$<6d0c>elSjp(-WoFCYycr)X+9f)0Cj42B_a`
zqQk~e1<QKben#&1@4Pv2h{l;R$P_B7RM90#l=`VG(e7w0LDvrRM`5Sc7ynrk%!sPS
zBtLJjr~W#+ag#MbC{%WHYHsWZF@_cP3Zh2Uyp)Qid(Ej+3f0bh{P_-AIyF6eahlGZ
zK3STafxf2XVa+daeaHAb?e`D~cR;Wm5i-qmd1E=K(qPb-#s2-YDclrpAw-l!EuI=+
zX+6VQGfa?}!hPbdADt>)J6M_;p>wZXE}s9mI5J90mq%x3rsqzdAcW6cSDD|3|1J_k
zD%MPtB}CnNi^;mi6j(AHsc5AeslxW?qJrMRkis=p#{#-k+0L?TFH>OJd@(Gmj%9aa
zO~Wn)-+be#0YQUl{-`osZmMb45!W!9WlTfT7%m%cRi-Vu*;>=OTcgGReTvAWH0+x%
zRp#A|HLY9S=SM@eG69zD*DBkU%{8stDmDBTbZr2(`J>8ixv8d2qa*x9UKS^>mEN76
z8=0oXcP<pqO`7SVGR^PP6dg&A5;By>D7<>uS=yHo)B%5;d&W6IRdceU1+CmPq_(~z
z<oiPuGU7gF$T5Dm)vvr6P;-uB|IL&Rja&P-oWhPF*C@l34WVMBS-P3_2^p2q0{84r
zjcwauLpg<)QeDX~DJ5e#zcYp{+oj5qJ+X+XPqD*`mu4`bsnXe#xM=*R`rIi?{c_tD
zyPn;yKx5jd{I2p`XVp$aK=CQmLBsqM>YZ0gRUymbqQ;u3Pm(2u^>zuf!qDb^h@KA9
zC(R!X;c&P@MP(^nfeLbl)${thJ(1{+qwtQ;Uc6p9^%k$EAL5)j^LFw0X_x5%P0K~4
zOy270NK&%ATZBFHY@zrR>fHWnTE_9G!jY7m$*`1$>e+=UVLDc(#5Gx|npV2kRB;YT
z)bq}0*S2U++m@cL&7Bd7!fyAkiU?niqyiu2cTUFIT^^}?+-7Plpy5L>r7%Hb{_@Ne
zxQzN%9RgJtWJ#Qs_KvaByBr4OBXq2+FE?W?6sA?W7LUZ^?a{8Dc%(HJNf;B$%eoRU
zbpyK@wzw61duy2v+Uaiy`8j57Oe>xF%Gmb_e%|}|d0(BaBNt{beah<>*ESDq^pUVk
zmL|?f<IJwia(|@~ExvlWc;%p(Of<`NWt9ajB|0}gQ@S!?rZ@bo^Z_H^_UNx1)Lndz
zPR$)YTN=CUY+iGJnPVWvX(sV%rn*;7$YkWbEWMoxX{JE3!`CWHC{J1-k<al2^le7D
zmKAZIz?0PXk{R|aLu1;|-xf)5weD!#d?t-YTcjhBh;Tu)JAsvq+dW~bUz9MAI}^9Y
zqLHpdPcqhl4t$TP&7n|UkP!T!Iw0rF&M8?@k%!I_BW$hFSlpSeEy&7BzaaU2X*THN
zr4@R`a}%>y4>_7x1RNF6$8lp7Lw@fuo2|=P<w?XFkrI5_+q3-OpxOX4?s08`CiDs@
z<9)hhY-G!f>4n>h*}@ac9Ei`yE$83M(qUYt_UMcsKB$oumnL-Y6Z>&#vgDRyar?V{
z4%x%FbGN1?J3B2yRmo_Y8KyOEi`Aa#nwY_D&bmk_<=GfVuzPG6<vS{12+Df)iRo4i
zhV0g|p5dZVpxm0aQDZ*Uld&p+y-V!XHt()(D^^CJ*qGN^XTdB%4PEY-bE{3u*g!}<
LzSpr%JhT1*G7#nx

diff --git a/routes/sessionRoute.js b/routes/sessionRoute.js
index 77a3b11..7ecd292 100644
--- a/routes/sessionRoute.js
+++ b/routes/sessionRoute.js
@@ -9,10 +9,7 @@ router.get('/info', (req, res) => {
     res.set('Cache-Control', 'no-store');
     res.set('Pragma', 'no-cache');        
     return res.status(200).json({
-      user: {
-        email,
-        name,
-      },
+      email,name
     });
   }
   // �몄뀡�� 留뚮즺�섏뿀嫄곕굹 �ъ슜�� �뺣낫媛� �녿뒗 寃쎌슦
-- 
GitLab


From 3e21b728cc7db1f538d9435c33ada985145d020b Mon Sep 17 00:00:00 2001
From: tpgus2603 <kakaneymar2424@gmail.com>
Date: Sun, 8 Dec 2024 21:13:09 +0900
Subject: [PATCH 59/61] =?UTF-8?q?refactor:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?=
 =?UTF-8?q?=20=EB=B0=98=ED=99=98=EA=B0=9D=EC=B2=B4=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 wsServer.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/wsServer.js b/wsServer.js
index 26b8d3e..00628e8 100644
--- a/wsServer.js
+++ b/wsServer.js
@@ -5,7 +5,7 @@ const mongoose = require('mongoose');
 const admin = require('firebase-admin');
 const dotenv = require('dotenv');
 const amqp = require('amqplib'); // RabbitMQ �곌껐
-const ChatRoom = require('./schemas/ChatRooms');
+const ChatRoom = require('./schemas/chatRooms');
 
 // .env �뚯씪 濡쒕뱶
 dotenv.config();
-- 
GitLab


From 0ab72462b02f83221c55bf231a748a38a30c6a47 Mon Sep 17 00:00:00 2001
From: tpgus2603 <tpgus2604@ajou.ac.kr>
Date: Sun, 8 Dec 2024 13:08:49 +0000
Subject: [PATCH 60/61] =?UTF-8?q?bugfix:=20=EC=9B=B9=EC=86=8C=EC=BC=93=20?=
 =?UTF-8?q?=EC=97=90=EB=9F=AC=20=ED=95=B4=EA=B2=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 output.log  | 366 ++++++++++++----------------------------------------
 weblog.log  |   5 +-
 wsServer.js |   2 +-
 3 files changed, 89 insertions(+), 284 deletions(-)

diff --git a/output.log b/output.log
index 2b17d41..f50856d 100644
--- a/output.log
+++ b/output.log
@@ -1,288 +1,92 @@
 MongoDB URI: mongodb+srv://admin:lim1234!!@goodmeeting.vkniz.mongodb.net/
-(node:212097) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:237546) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 (Use `node --trace-warnings ...` to show where the warning was created)
-(node:212097) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:237546) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 �� MongoDB �곌껐 �깃났
 Rdb�곗씠�곕쿋�댁뒪 �곌껐 �깃났.
 紐⑤뱺 紐⑤뜽�� �깃났�곸쑝濡� �숆린�붾릺�덉뒿�덈떎.
 Server is running on 8080
-GET /api/session/info 401 7.235 ms - 76
-GET /api/session/info 401 1.572 ms - 76
-GET /api/session/info 401 1.286 ms - 76
-GET /api/session/info 401 1.126 ms - 76
-GET /api/session/info 401 1.154 ms - 76
-GET /api/session/info 401 0.926 ms - 76
-GET /api/session/info 401 2.076 ms - 76
-GET /api/session/info 401 1.024 ms - 76
-GET / 404 2.809 ms - 139
-POST /sdk 404 2.633 ms - 143
-GET /nmaplowercheck1733630009 404 0.957 ms - 163
-GET / 404 0.955 ms - 139
-GET /HNAP1 404 1.213 ms - 144
-GET /evox/about 404 1.007 ms - 149
-GET / 404 1.171 ms - 139
-GET / 404 0.956 ms - 139
-GET /api/session/info 401 0.914 ms - 76
-GET /api/session/info 401 1.419 ms - 76
-GET /api/session/info 401 0.736 ms - 76
-GET /api/auth/login 302 3.018 ms - 0
-GET /api/auth/google/callback?code=4%2F0AeanS0Y8pXOIF2Ju3xckjh10Sjm1Kd0dcZycXQPzTOCxZrVv3oJM7H1v4TJfTlwRFxSDUw&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&authuser=0&hd=ajou.ac.kr&prompt=none 302 567.800 ms - 48
-GET /api/session/info 200 8.998 ms - 60
-GET /api/session/info 200 15.228 ms - 60
-GET /api/auth/logout 302 4.820 ms - 41
-GET /api/session/info 401 1.144 ms - 76
-GET /api/auth/login 302 1.160 ms - 0
-GET /api/auth/google/callback?code=4%2F0AeanS0aSNOTTxPm0d8V-mSO7PuFRiGZkFv1WWgoTGVqN41uFAQz8PupxFUtoSmm0ei6N1Q&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&authuser=0&hd=ajou.ac.kr&prompt=none 302 388.373 ms - 48
-GET /api/session/info 200 3.914 ms - 60
-GET /api/auth/logout 302 4.398 ms - 41
-GET /api/session/info 401 1.161 ms - 76
-GET /api/session/info 401 1.117 ms - 76
-GET /api/auth/login 302 1.137 ms - 0
-GET /api/auth/google/callback?code=4%2F0AeanS0bAWi6c7Y3IU6J6T4H5syJLynGlz8b0hEEMfcRCtXOzzE0Z_k9rNT2L2IV24m4Qbg&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=0&hd=ajou.ac.kr&prompt=none 302 418.058 ms - 48
-GET /api/session/info 200 4.195 ms - 60
-GET /api/session/info 200 17.752 ms - 60
-GET /api/session/info 200 5.411 ms - 60
-GET /api/auth/login 302 4.906 ms - 0
-GET /api/auth/google/callback?code=4%2F0AeanS0ZwocNVsHrI0WcG2DfMTBOziAdI5W13EEEqAxqK0GZkt9SYgmlB1YVor1Vd10yhOA&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=0&hd=ajou.ac.kr&prompt=none 302 445.216 ms - 48
-GET /api/session/info 200 5.122 ms - 60
-GET /api/session/info 200 4.660 ms - 60
-GET /api/session/info 200 4.893 ms - 60
-GET /api/auth/login 302 52.638 ms - 0
-GET /api/auth/google/callback?code=4%2F0AeanS0btwgAZvNqTiVMI1FzYcMyJpsq8zjkKCJWb86vQYUXKSpXG1nnJGdWjoJFSJ6ZIAw&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&authuser=0&hd=ajou.ac.kr&prompt=none 302 463.694 ms - 48
-GET /api/session/info 200 6.067 ms - 60
-GET /api/session/info 200 15.746 ms - 60
-GET /api/session/info 200 3.721 ms - 60
-GET /api/session/info 401 0.880 ms - 76
-GET /api/session/info 401 0.871 ms - 76
-GET /api/auth/login 302 0.936 ms - 0
-GET /api/auth/google/callback?code=4%2F0AeanS0aJ-WUyPAzU9TgwB3O4zrvADfrXVvIj7TZkKvtrnnYhpAlYTEfW3F_kLg1fwOBIpw&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=0&hd=ajou.ac.kr&prompt=none 302 420.759 ms - 48
-GET /api/session/info 200 3.693 ms - 60
-GET /api/session/info 401 0.963 ms - 76
-GET /api/session/info 401 0.876 ms - 76
-GET /api/session/info 401 0.904 ms - 76
-GET /api/session/info 401 0.898 ms - 76
-GET /api/auth/login 302 0.956 ms - 0
-GET /api/auth/google/callback?code=4%2F0AeanS0YORfunrW6DJxJDtYvArHupwZYA_YXrpxZ-ucXSoB7ablLuwez2PrdwMyDACWTfrg&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&authuser=0&hd=ajou.ac.kr&prompt=none 302 405.688 ms - 48
-GET /api/session/info 200 3.814 ms - 60
-GET /api/auth/logout 302 15.145 ms - 41
-GET /api/session/info 401 1.060 ms - 76
-GET /api/auth/login 302 1.116 ms - 0
-GET /api/auth/google/callback?code=4%2F0AeanS0at8xXw-_yVufE61kassBTRFn4ybVl2gUfWoEVEh4qMv1pV1_C3-tIXH_OVtqccXA&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&authuser=0&hd=ajou.ac.kr&prompt=none 302 416.504 ms - 48
-GET /api/session/info 200 3.844 ms - 60
-GET /api/session/info 401 1.087 ms - 76
-GET /api/session/info 401 0.899 ms - 76
-GET /api/auth/login 302 0.909 ms - 0
-GET /api/auth/google/callback?code=4%2F0AeanS0ayNExQE74cwz6uRTNs-Cl1t7nizv7EppTOoCMHdWhcmXC87ugbLXufp-YwfkKRCQ&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&authuser=0&hd=ajou.ac.kr&prompt=none 302 447.632 ms - 48
-GET /api/session/info 200 7.614 ms - 60
-GET /api/schedule/all 200 11.394 ms - 40
-Performance Measurement - getAllSchedules: 7.46108603477478ms
-POST /api/schedule 201 54.333 ms - 217
-Performance Measurement - createSchedule: 30.060553014278412ms
-GET /api/schedule/all 200 9.091 ms - 220
-Performance Measurement - getAllSchedules: 4.380231022834778ms
-GET /api/session/info 200 4.019 ms - 60
-GET /api/session/info 200 15.551 ms - 60
-GET /api/session/info 200 4.339 ms - 60
-GET /api/session/info 200 6.990 ms - 60
-GET /api/session/info 200 4.459 ms - 60
-GET /api/session/info 200 5.760 ms - 60
-GET /api/auth/logout 302 14.888 ms - 41
-GET /api/session/info 401 1.146 ms - 76
-GET /api/auth/login 302 1.211 ms - 0
-GET /api/auth/google/callback?code=4%2F0AeanS0ZdKVh0qL70I2shnUMx3d0bLsh0Ra1X-abqrZPtuPSHuLd7rt-MJwSdn5HQAvYPGg&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=0&hd=ajou.ac.kr&prompt=none 302 436.641 ms - 48
-GET /api/session/info 200 3.629 ms - 60
-GET /api/auth/logout 302 3.931 ms - 41
-GET /api/schedule/all 401 1.054 ms - 44
-GET /api/session/info 401 1.896 ms - 76
-GET /api/session/info 401 0.777 ms - 76
-GET /api/auth/login 302 0.908 ms - 0
-GET /api/auth/google/callback?code=4%2F0AeanS0ZCNp4N4szbUeXZ2lUSJCQxpMLt8eiqkPAjhEoU9PGzn5zCYFI1CgifDv2hyISYGg&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=1&hd=ajou.ac.kr&prompt=none 302 481.904 ms - 48
-GET /api/session/info 200 3.830 ms - 60
-GET /api/schedule/all 200 6.419 ms - 40
-Performance Measurement - getAllSchedules: 3.0510510206222534ms
-GET /api/session/info 401 0.905 ms - 76
-GET /api/schedule/all 401 0.796 ms - 44
-GET /api/session/info 401 0.844 ms - 76
-GET /api/auth/login 302 0.910 ms - 0
-GET /api/auth/google/callback?code=4%2F0AeanS0a7Trsso_Jp5vPrjVTErVMUoTS_hKhC3_yBILjE1k8rlhD-Av_WDxRh-DenfkBozg&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=3&hd=ajou.ac.kr&prompt=none 302 455.286 ms - 48
-GET /api/session/info 200 4.353 ms - 60
-GET /api/schedule/all 200 6.417 ms - 40
-Performance Measurement - getAllSchedules: 2.9196969866752625ms
-GET /api/schedule/all 304 56.513 ms - -
-Performance Measurement - getAllSchedules: 3.0346270203590393ms
-GET /api/session/info 200 49.415 ms - 60
-GET /api/auth/logout 302 5.237 ms - 41
-GET /api/session/info 401 1.066 ms - 76
-GET /api/auth/login 302 1.235 ms - 0
-GET /api/auth/google/callback?code=4%2F0AeanS0b5pX-wafAWt3GJaOQ0MuV8pxFpXzch7-iKJykw90KS3bg6rGS6c0jL_oCm0kHmfQ&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&authuser=1&hd=ajou.ac.kr&prompt=none 302 452.374 ms - 48
-GET /api/session/info 200 4.040 ms - 60
-GET /api/schedule/all 304 9.584 ms - -
-Performance Measurement - getAllSchedules: 3.8280670046806335ms
-POST /api/schedule 201 68.289 ms - 252
-Performance Measurement - createSchedule: 17.49489998817444ms
-PUT /api/schedule 200 45.097 ms - 245
-Performance Measurement - updateSchedules: 30.391826033592224ms
-GET /api/schedule/all 304 53.317 ms - -
-Performance Measurement - getAllSchedules: 3.174045979976654ms
-GET /api/session/info 200 3.974 ms - 60
-GET /api/schedule/all 304 79.820 ms - -
-Performance Measurement - getAllSchedules: 2.95797199010849ms
-GET /api/schedule/all 304 20.604 ms - -
-Performance Measurement - getAllSchedules: 3.0838510394096375ms
-GET /api/schedule/all 304 17.032 ms - -
-Performance Measurement - getAllSchedules: 2.8636720180511475ms
-GET /api/session/info 200 51.753 ms - 60
-GET /api/session/info 200 15.941 ms - 60
-GET /api/schedule/all 304 17.499 ms - -
-Performance Measurement - getAllSchedules: 2.9681079983711243ms
-GET /api/session/info 401 1.186 ms - 76
-GET /api/session/info 401 0.855 ms - 76
-GET /api/auth/login 302 0.895 ms - 0
-GET /api/auth/google/callback?code=4%2F0AeanS0Y7dXShRIVbgpwaSHziVczqtPoIhuOwyKJCOvJ_dIZDhiumR1rom85By8WaxxjpWg&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&authuser=0&hd=ajou.ac.kr&prompt=none 302 435.368 ms - 48
-GET /api/session/info 200 5.680 ms - 60
-GET /api/schedule/all 200 6.928 ms - 220
-Performance Measurement - getAllSchedules: 3.3638980388641357ms
-GET /api/session/info 200 3.905 ms - 60
-GET /api/schedule/all 200 6.618 ms - 220
-Performance Measurement - getAllSchedules: 3.098719000816345ms
-GET /api/session/info 200 4.208 ms - 60
-GET /api/schedule/all 200 6.312 ms - 220
-Performance Measurement - getAllSchedules: 3.0304319858551025ms
-GET /api/session/info 200 4.133 ms - 60
-GET /api/schedule/all 304 16.818 ms - -
-Performance Measurement - getAllSchedules: 2.7342900037765503ms
-GET /api/session/info 200 3.863 ms - 60
-GET /api/session/info 200 5.731 ms - 60
-GET /api/schedule/all 304 8.387 ms - -
-Performance Measurement - getAllSchedules: 4.900808036327362ms
-GET /api/session/info 200 3.961 ms - 60
-GET /api/schedule/all 304 53.173 ms - -
-Performance Measurement - getAllSchedules: 4.181941032409668ms
-GET /api/session/info 200 16.906 ms - 60
-GET /api/session/info 200 4.159 ms - 60
-GET /api/session/info 200 3.919 ms - 60
-GET /api/session/info 200 3.858 ms - 60
-GET /api/auth/logout 302 3.870 ms - 41
-GET /api/session/info 401 1.174 ms - 76
-GET /api/auth/login 302 1.067 ms - 0
-GET /api/auth/google/callback?code=4%2F0AeanS0ZFplLpLXFzjTreoRr9XOFIdylMGvmTIJ9Z-8W3v8J-PXsC1WR3mrhEDMP8u8ISwg&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=0&hd=ajou.ac.kr&prompt=none 302 456.648 ms - 48
-GET /api/session/info 200 3.714 ms - 60
-GET /api/schedule/all 304 8.904 ms - -
-Performance Measurement - getAllSchedules: 3.3655150532722473ms
-GET /api/session/info 200 3.904 ms - 60
-GET /api/schedule/all 304 6.538 ms - -
-Performance Measurement - getAllSchedules: 3.2424970269203186ms
-GET /api/session/info 200 4.546 ms - 60
-GET /api/session/info 200 14.706 ms - 60
-GET /api/auth/logout 302 3.760 ms - 41
-GET /api/auth/login 302 1.096 ms - 0
-GET /api/auth/google/callback?code=4%2F0AeanS0a9isaZiqiZyAFoW3OCrs683FSO5wYZOZICruNlDnpbD6zQOwT9wly7fZ3akJHglQ&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=3&hd=ajou.ac.kr&prompt=none 302 416.843 ms - 48
-GET /api/session/info 200 3.936 ms - 60
-GET /api/schedule/all 304 6.114 ms - -
-Performance Measurement - getAllSchedules: 2.7020570039749146ms
-POST /api/schedule 201 32.875 ms - 238
-Performance Measurement - createSchedule: 17.89035999774933ms
-POST /api/schedule 201 27.971 ms - 251
-Performance Measurement - createSchedule: 14.455415964126587ms
-POST /api/schedule 201 24.014 ms - 277
-Performance Measurement - createSchedule: 10.122812986373901ms
-DELETE /api/schedule 200 28.079 ms - 84
-Performance Measurement - deleteSchedules: 13.639528036117554ms
-GET /api/schedule/all 200 6.512 ms - 456
-Performance Measurement - getAllSchedules: 3.6543020009994507ms
-POST /api/schedule 201 26.599 ms - 237
-Performance Measurement - createSchedule: 12.827956020832062ms
-GET /api/session/info 200 51.064 ms - 60
-GET /api/schedule/all 200 16.479 ms - 657
-Performance Measurement - getAllSchedules: 3.5523930191993713ms
-GET /api/session/info 200 21.419 ms - 60
-GET /api/session/info 200 26.999 ms - 60
-GET /api/chat/rooms 200 34.768 ms - 2
-GET /api/session/info 200 4.844 ms - 60
-GET /api/chat/rooms 304 11.480 ms - -
-GET /api/session/info 200 4.055 ms - 60
-GET /api/session/info 200 4.097 ms - 60
-GET /api/session/info 200 7.407 ms - 60
-GET /api/session/info 200 6.633 ms - 60
-GET /api/session/info 200 7.149 ms - 60
-GET /api/schedule/all 200 6.983 ms - 220
-Performance Measurement - getAllSchedules: 3.386197030544281ms
-GET /api/session/info 200 6.139 ms - 60
-GET /api/chat/rooms 200 13.986 ms - 2
-POST /api/schedule 201 17.101 ms - 202
-Performance Measurement - createSchedule: 13.091067969799042ms
-POST /api/schedule 201 14.599 ms - 205
-Performance Measurement - createSchedule: 10.717601954936981ms
-GET /api/schedule 404 17.100 ms - 151
-GET /api/session/info 200 16.750 ms - 60
-GET /api/chat/rooms 200 23.408 ms - 2
-GET /api/schedule/all 200 7.910 ms - 220
-Performance Measurement - getAllSchedules: 3.159197986125946ms
-GET /api/meeting 401 0.827 ms - 44
-GET /api/auth/logout 302 0.911 ms - 41
-GET /api/session/info 401 0.855 ms - 76
-GET /api/auth/login 302 0.998 ms - 0
-GET /api/session/info 200 16.747 ms - 60
-GET /api/session/info 200 9.338 ms - 60
-GET /api/chat/rooms 200 15.884 ms - 2
-GET /api/schedule/all 200 8.682 ms - 220
-Performance Measurement - getAllSchedules: 5.216198980808258ms
-GET /api/session/info 200 17.533 ms - 60
-GET /api/chat/rooms 200 22.089 ms - 2
-GET /api/session/info 401 0.888 ms - 76
-GET /api/session/info 401 0.773 ms - 76
-GET /api/session/info 401 0.844 ms - 76
-GET /api/session/info 401 0.632 ms - 76
-GET /api/session/info 200 46.849 ms - 60
-GET /api/chat/rooms 200 56.198 ms - 2
-GET /api/session/info 401 0.963 ms - 76
-GET /api/session/info 401 0.604 ms - 76
-GET /api/session/info 401 0.859 ms - 76
-GET /api/session/info 401 0.639 ms - 76
-GET /api/session/info 401 0.846 ms - 76
-GET /api/session/info 401 0.662 ms - 76
-GET /api/session/info 401 0.844 ms - 76
-GET /api/session/info 401 0.957 ms - 76
-GET /api/session/info 401 0.788 ms - 76
-GET /api/session/info 401 0.617 ms - 76
-GET /api/session/info 401 0.870 ms - 76
-GET /api/session/info 401 0.857 ms - 76
-GET /api/session/info 401 0.886 ms - 76
-GET /api/session/info 401 0.687 ms - 76
-GET /api/session/info 401 0.870 ms - 76
-GET /api/session/info 401 0.659 ms - 76
-GET /api/session/info 401 0.922 ms - 76
-GET /api/session/info 401 0.920 ms - 76
-GET /api/session/info 401 0.857 ms - 76
-GET /api/session/info 401 0.602 ms - 76
-GET /api/session/info 401 0.960 ms - 76
-GET /api/session/info 401 0.651 ms - 76
-GET /api/session/info 401 0.834 ms - 76
-GET /api/session/info 401 0.878 ms - 76
-GET /api/session/info 401 0.900 ms - 76
-GET /api/session/info 401 0.896 ms - 76
-GET /api/meeting 401 0.845 ms - 44
-GET /api/session/info 401 0.916 ms - 76
-GET /api/session/info 401 0.865 ms - 76
-GET /api/session/info 401 0.855 ms - 76
-GET / 404 0.919 ms - 139
-GET /api/session/info 401 0.801 ms - 76
-GET /api/session/info 401 0.893 ms - 76
-GET /api/session/info 401 0.859 ms - 76
-GET /api/session/info 401 0.874 ms - 76
-GET /api/session/info 401 0.813 ms - 76
-GET /api/session/info 401 0.822 ms - 76
-GET /api/session/info 401 0.904 ms - 76
+GET /api/session/info 401 9.962 ms - 76
+GET /api/chat/unread-messages/%EC%9E%84%EC%84%B8%ED%98%84 200 18.575 ms - 2
+GET /api/chat/rooms 304 71.212 ms - -
+GET /api/session/info 401 1.954 ms - 76
+GET /api/auth/login 302 3.293 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0bo56K9bp52E_K4k1_MsLy3ISx6PmunHrrE1MlEYKczIMg2thRYYgY7Fk-YzLgDLA&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=1&hd=ajou.ac.kr&prompt=none 302 453.008 ms - 48
+GET /api/session/info 200 6.112 ms - 51
+GET /api/session/info 200 16.234 ms - 51
+GET /api/chat/unread-messages/%EC%9E%84%EC%84%B8%ED%98%84 304 22.679 ms - -
+GET /api/chat/rooms 304 23.630 ms - -
+GET /api/session/info 200 6.990 ms - 51
+GET /api/session/info 200 7.645 ms - 51
+GET /api/chat/rooms 304 16.225 ms - -
+GET /api/chat/unread-messages/%EC%9E%84%EC%84%B8%ED%98%84 304 11.814 ms - -
+GET /api/schedule/all 304 9.932 ms - -
+Performance Measurement - getAllSchedules: 5.537642002105713ms
+GET /api/session/info 200 7.587 ms - 51
+GET /api/chat/rooms 304 16.365 ms - -
+GET /api/chat/unread-messages/%EC%9E%84%EC%84%B8%ED%98%84 304 11.954 ms - -
+GET /api/schedule/all 304 19.858 ms - -
+Performance Measurement - getAllSchedules: 4.0661240220069885ms
+POST /api/schedule 201 57.019 ms - 254
+Performance Measurement - createSchedule: 32.22604298591614ms
+POST /api/schedule 201 18.985 ms - 209
+Performance Measurement - createSchedule: 14.478051960468292ms
+GET /api/session/info 401 1.989 ms - 76
+GET /api/session/info 200 18.484 ms - 51
+GET /api/meeting/my?page=0&size=20 200 27.169 ms - 73
+GET /api/friend/all?page=0&size=10 200 12.508 ms - 73
+Performance Measurement - getFriendList: 8.078101992607117ms
+GET /api/friend/requests/received 200 21.379 ms - 26
+Performance Measurement - getReceivedRequests: 12.82328200340271ms
+GET /api/session/info 200 5.489 ms - 51
+GET /api/session/info 200 8.371 ms - 51
+GET /api/meeting/my?page=0&size=20 304 16.133 ms - -
+GET /api/friend/all?page=0&size=10 304 29.121 ms - -
+Performance Measurement - getFriendList: 6.826422989368439ms
+GET /api/friend/requests/received 304 32.139 ms - -
+Performance Measurement - getReceivedRequests: 5.952132999897003ms
+GET /api/session/info 200 22.840 ms - 51
+GET /api/session/info 200 9.178 ms - 51
+GET /api/meeting/my?page=0&size=20 304 14.669 ms - -
+OPTIONS /api/schedule/all 204 0.464 ms - 0
+OPTIONS /api/schedule/all 204 0.141 ms - 0
+OPTIONS /api/schedule/all 204 0.210 ms - 0
+OPTIONS /api/schedule/all 204 0.142 ms - 0
+GET /api/session/info 401 0.925 ms - 76
+GET /api/session/info 401 1.223 ms - 76
+GET /api/chat/rooms 304 8.083 ms - -
+GET /api/chat/unread-messages/%EC%8B%AC%EC%9E%AC%EC%97%BD 304 4.635 ms - -
 GET /api/session/info 401 0.874 ms - 76
-GET /api/session/info 401 0.792 ms - 76
-OPTIONS /api/schedule/all 204 0.443 ms - 0
-OPTIONS /api/schedule/all 204 0.139 ms - 0
-OPTIONS /api/schedule 204 0.190 ms - 0
-GET /api/session/info 401 0.877 ms - 76
-GET /api/session/info 401 0.634 ms - 76
-GET /api/session/info 401 0.906 ms - 76
-GET /api/session/info 401 0.744 ms - 76
-GET /api/session/info 401 0.853 ms - 76
-GET /api/session/info 401 0.637 ms - 76
-GET /api/session/info 401 0.931 ms - 76
-GET /api/session/info 401 2.110 ms - 76
+GET /api/auth/login? 302 0.917 ms - 0
+GET /api/auth/google/callback?code=4%2F0AeanS0bOw-YtdxF3OtlXlNJwNPikLk99RTj2hA5DEUqDh90OVHztLhrKtkMXUSWpI-uqyQ&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=0&hd=ajou.ac.kr&prompt=none 302 474.318 ms - 48
+GET /api/session/info 200 3.726 ms - 51
+GET /api/session/info 200 14.662 ms - 51
+GET /api/chat/rooms 304 21.626 ms - -
+GET /api/chat/unread-messages/%EC%8B%AC%EC%9E%AC%EC%97%BD 304 22.687 ms - -
+GET /api/session/info 200 6.551 ms - 51
+GET /api/meeting/my?page=0&size=20 304 8.614 ms - -
+GET /api/session/info 200 5.132 ms - 51
+GET /api/chat/rooms 304 13.220 ms - -
+GET /api/chat/unread-messages/%EC%8B%AC%EC%9E%AC%EC%97%BD 304 8.728 ms - -
+OPTIONS /api/schedule/all 204 0.184 ms - 0
+OPTIONS /api/schedule/all 204 0.134 ms - 0
+OPTIONS /api/schedule/all 204 0.192 ms - 0
+OPTIONS /api/schedule/all 204 0.235 ms - 0
+GET /api/friend/requests/received 304 52.485 ms - -
+Performance Measurement - getReceivedRequests: 6.246300995349884ms
+GET /api/friend/all?page=0&size=10 304 49.049 ms - -
+Performance Measurement - getFriendList: 4.844668984413147ms
+GET /api/session/info 200 3.957 ms - 51
+GET /api/session/info 200 5.007 ms - 51
+GET /api/meeting/my?page=0&size=20 304 7.817 ms - -
+OPTIONS /api/schedule/all 204 0.228 ms - 0
+OPTIONS /api/schedule/all 204 0.145 ms - 0
+OPTIONS /api/schedule/all 204 0.194 ms - 0
+OPTIONS /api/schedule/all 204 0.158 ms - 0
+OPTIONS /api/schedule/all 204 0.198 ms - 0
+OPTIONS /api/schedule/all 204 0.135 ms - 0
+GET /api/session/info 401 0.856 ms - 76
+GET /api/session/info 401 0.662 ms - 76
+OPTIONS /api/schedule/all 204 0.377 ms - 0
+OPTIONS /api/schedule/all 204 0.478 ms - 0
+OPTIONS /api/schedule/all 204 0.194 ms - 0
diff --git a/weblog.log b/weblog.log
index a44117d..dbd9d95 100644
--- a/weblog.log
+++ b/weblog.log
@@ -1,5 +1,6 @@
-(node:212098) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:237547) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 (Use `node --trace-warnings ...` to show where the warning was created)
-(node:212098) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
+(node:237547) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
 MongoDB�� �깃났�곸쑝濡� �곌껐�섏뿀�듬땲��.
 WebSocket 梨꾪똿 �쒕쾭媛� 8081 �ы듃�먯꽌 �ㅽ뻾 以묒엯�덈떎.
+RabbitMQ connection established
diff --git a/wsServer.js b/wsServer.js
index 00628e8..79e7b6d 100644
--- a/wsServer.js
+++ b/wsServer.js
@@ -54,7 +54,7 @@ async function setupRabbitMQ() {
     amqpChannel = await amqpConnection.createChannel();
     console.log('RabbitMQ connection established');
   } catch (err) {
-    logError('RabbitMQ Setup', err);
+    console.error('RabbitMQ Setup', err);
     process.exit(1);
   }
 }
-- 
GitLab


From 005228caaa6922f4cbb934e402fc170410752a3a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=8B=AC=EC=9E=AC=EC=97=BD?= <jysim0326@ajou.ac.kr>
Date: Sun, 8 Dec 2024 22:14:55 +0900
Subject: [PATCH 61/61] =?UTF-8?q?refactor:=20fcmToken=20=EB=93=B1=EB=A1=9D?=
 =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 routes/authRoute.js       | 113 +++++++++++++++++++++++---------------
 routes/chatRoute.js       |   4 ++
 services/memberService.js |   2 +-
 3 files changed, 74 insertions(+), 45 deletions(-)

diff --git a/routes/authRoute.js b/routes/authRoute.js
index e6f2d55..a83f6d4 100644
--- a/routes/authRoute.js
+++ b/routes/authRoute.js
@@ -1,53 +1,78 @@
-  const express = require('express');
-  const passport = require('passport');
+const express = require('express');
+const passport = require('passport');
+const MemberService = require('../services/memberService');
 
-  const router = express.Router();
+const router = express.Router();
 
-  // Google OAuth 濡쒓렇�� �쇱슦��
-  router.get(
-    '/login',
-    passport.authenticate('google', {
-      scope: ['profile', 'email'], // �ъ슜�� �뺣낫 �붿껌�� �꾪븳 scope 
-      failureRedirect: `${process.env.FRONT_URL}/login`
-    })
-  );
+// Google OAuth 濡쒓렇�� �쇱슦��
+router.get(
+  '/login',
+  (req, res, next) => {
+    const { state } = req.query; // �대씪�댁뼵�몄뿉�� �꾨떖�� state(fcmToken)
+    console.log("State received at /login:", state);
 
-  router.get(
-    '/google/callback',
-    passport.authenticate('google', {
-      failureRedirect: `${process.env.FRONT_URL}/login` 
-    }),
-    (req, res) => {
-      const redirectUrl = process.env.FRONT_URL;
-      req.session.save((err) => {
-        if (err) {
-          console.error('�몄뀡 ���� �ㅻ쪟:', err);
-          return res.status(500).json({ error: '�쒕쾭 �ㅻ쪟' });
-        }
-        res.redirect(redirectUrl);
-      });
+    passport.authenticate("google", {
+      scope: ["profile", "email"], // �붿껌�� �ъ슜�� �뺣낫
+      state, // �꾨떖諛쏆� fcmToken�� state濡� �ㅼ젙
+    })(req, res, next);
+  }
+);
+
+router.get(
+  '/google/callback',
+  passport.authenticate('google', {
+    failureRedirect: `${process.env.FRONT_URL}/login`
+  }),
+  async (req, res) => {
+    // Google OAuth �몄쬆 �깃났 �� state �뚮씪誘명꽣濡� �꾨떖�� fcmToken 媛��몄삤湲�
+    const fcmToken = req.query.state;
+    console.log("諛쏆븘�� fcmToken", fcmToken);
+    const userEmail = req.user.email; // Google 濡쒓렇�몄뿉�� 媛��몄삩 email
+    const redirectUrl = process.env.FRONT_URL;
+    req.session.userEmail = userEmail; // �몄뀡�� �ъ슜�� �대찓�� ����
+
+    try {
+      if (fcmToken) {
+        // FCM �좏겙 �깅줉
+        await MemberService.registerToken(userEmail, fcmToken);
+        console.log(`FCM token registered for user: ${userEmail}`);
+      } else {
+        console.warn("No FCM token provided during login");
+      }
+    } catch (error) {
+      console.error("Error registering FCM token during login:", error);
     }
-  );
 
-  // 濡쒓렇�꾩썐 �쇱슦��
-  router.get('/logout', (req, res) => {
-    if (req.session) {
-      req.session.destroy((err) => {
-        if (err) {
-          console.error('�몄뀡 ��젣 �ㅻ쪟:', err);
-          return res.status(500).json({ error: '�쒕쾭 �ㅻ쪟' });
-        }
-        const redirectUrl = process.env.FRONT_URL;
-        res.redirect(redirectUrl);
-      });
-    } else {
-      // �몄뀡�� �녿뒗 寃쎌슦�먮룄 由щ떎�대젆��
+    req.session.save((err) => {
+      if (err) {
+        console.error('�몄뀡 ���� �ㅻ쪟:', err);
+        return res.status(500).json({ error: '�쒕쾭 �ㅻ쪟' });
+      }
+      res.redirect(redirectUrl);
+
+    });
+  }
+);
+
+// 濡쒓렇�꾩썐 �쇱슦��
+router.get('/logout', (req, res) => {
+  if (req.session) {
+    req.session.destroy((err) => {
+      if (err) {
+        console.error('�몄뀡 ��젣 �ㅻ쪟:', err);
+        return res.status(500).json({ error: '�쒕쾭 �ㅻ쪟' });
+      }
       const redirectUrl = process.env.FRONT_URL;
       res.redirect(redirectUrl);
-    }
-  });
-  
-  // �ъ슜�� ��젣 �쇱슦��
+    });
+  } else {
+    // �몄뀡�� �녿뒗 寃쎌슦�먮룄 由щ떎�대젆��
+    const redirectUrl = process.env.FRONT_URL;
+    res.redirect(redirectUrl);
+  }
+});
+
+// �ъ슜�� ��젣 �쇱슦��
 router.delete('/leave', async (req, res) => {
   try {
     // �몄쬆�� �ъ슜�� �뺤씤
@@ -81,4 +106,4 @@ router.delete('/leave', async (req, res) => {
   }
 });
 
-  module.exports = router;
\ No newline at end of file
+module.exports = router;
\ No newline at end of file
diff --git a/routes/chatRoute.js b/routes/chatRoute.js
index e7c2769..ed55aa5 100644
--- a/routes/chatRoute.js
+++ b/routes/chatRoute.js
@@ -1,6 +1,7 @@
 const express = require('express');
 const router = express.Router();
 const chatController = require('../controllers/chatController');
+const { isLoggedIn } = require('../middlewares/auth');
 
 router.post('/create-room', chatController.createChatRoom);
 router.get('/rooms', chatController.getChatRooms);
@@ -10,6 +11,9 @@ router.get('/unread-messages/:nickname', chatController.getUnreadMessages);
 router.get('/unread-count/:chatRoomId', chatController.getUnreadCount);
 router.post('/update-status-and-logid', chatController.updateStatusAndLogId);
 router.post('/update-read-log-id', chatController.updateReadLogId);
+
+router.use(isLoggedIn);
+
 router.post('/:chatRoomId/notices', chatController.addNotice); 
 router.get('/:chatRoomId/notices/latest', chatController.getLatestNotice); 
 router.get('/:chatRoomId/notices', chatController.getAllNotices);
diff --git a/services/memberService.js b/services/memberService.js
index 0435672..ebe4fe1 100644
--- a/services/memberService.js
+++ b/services/memberService.js
@@ -25,7 +25,7 @@ class MemberService {
     }
 
     // 3. MongoDB�먯꽌 愿��� 梨꾪똿諛⑹쓽 FCM �좏겙 �낅뜲�댄듃
-    const existingChatRooms = await ChatRoom.find({ "participants.name": user.name });
+    const existingChatRooms = await ChatRooms.find({ "participants.name": user.name });
     for (const room of existingChatRooms) {
       room.participants = room.participants.map((participant) => {
         if (participant.name === user.name) {
-- 
GitLab