diff --git a/controllers/friendController.js b/controllers/friendController.js index ce50caf5463a7095f3516a27fc14c7a0c114f7f4..09cbf577aa6ce94f6e9bc4ac52d902c5d97e6ae5 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/controllers/meetingController.js b/controllers/meetingController.js index 66246226712c26021bbb19c241ac5ac396e21240..78f4464ff4d7bebb4c3a425ce3154bb4c1e5c042 100644 --- a/controllers/meetingController.js +++ b/controllers/meetingController.js @@ -116,20 +116,52 @@ class MeetingController { res.status(500).json({ error: err.message || '모임 상세 조회 실패' }); } } - /* - Delete /api/meetings/:meetingId - */ - async closeMeeting(req,res) - { - + + /** + * 내가 참여한 모임 목록 조회 + * 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 + */ + 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 a2788cad0c127f0b8014ffe20ccca7f86b061b9b..9d2e26f8bc0dcfa8fee321d29632b1a2b97e4c0c 100644 --- a/routes/meetingRoute.js +++ b/routes/meetingRoute.js @@ -22,4 +22,10 @@ router.post('/:meetingId/join', MeetingController.joinMeeting); // 번개 모임 상세 조회 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 diff --git a/services/friendService.js b/services/friendService.js index 4d61554624b77f0e7fc0b0bd0c21749520529c83..5e1652459a2276272c5559d997137e238db0178e 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 }); diff --git a/services/meetingService.js b/services/meetingService.js index 746597dcf5123cc7802ae8087e763a028b3d34cc..746bcf1c8ff6d0b0f68d9ba14d0b878125941847 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(); }