From e70f61695111bdae39e74467a97c266ca2866aee Mon Sep 17 00:00:00 2001 From: youngkwon02 Date: Mon, 10 Jan 2022 20:06:45 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20=EC=B0=B8=EC=97=AC=EC=BD=94?= =?UTF-8?q?=EB=93=9C=EB=A1=9C=20=EB=8C=80=EA=B8=B0=EB=B0=A9=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20api=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- functions/api/routes/room/index.js | 1 + functions/api/routes/room/roomCodeGET.js | 66 ++++++++++++++++++++++++ functions/constants/responseMessage.js | 4 ++ functions/db/room.js | 29 ++++++++++- 4 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 functions/api/routes/room/roomCodeGET.js diff --git a/functions/api/routes/room/index.js b/functions/api/routes/room/index.js index 9963ec3..e7e16ee 100644 --- a/functions/api/routes/room/index.js +++ b/functions/api/routes/room/index.js @@ -2,5 +2,6 @@ const express = require('express'); const router = express.Router(); router.post('', require('./roomPOST')); +router.get('/code/:code', require('./roomCodeGET')); module.exports = router; diff --git a/functions/api/routes/room/roomCodeGET.js b/functions/api/routes/room/roomCodeGET.js new file mode 100644 index 0000000..751c3af --- /dev/null +++ b/functions/api/routes/room/roomCodeGET.js @@ -0,0 +1,66 @@ +/** + * @코드로 대기 방 정보 확인 + * @route GET /room/code:code + * @error + * 1. 참여 코드가 전달되지 않음 + */ + +const functions = require('firebase-functions'); +const util = require('../../../lib/util'); +const statusCode = require('../../../constants/statusCode'); +const responseMessage = require('../../../constants/responseMessage'); +const db = require('../../../db/db'); +const { userDB, roomDB } = require('../../../db'); + +module.exports = async (req, res) => { + const { code } = req.params; + if (!code) { + return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.NULL_VALUE)); + } + + let client; + + try { + client = await db.connect(req); + + const room = await roomDB.getRoomByCode(client, code); + if (!room) { + return res.status(statusCode.OK).send(util.success(statusCode.OK, responseMessage.GET_WAITROOM_DATA_NULL)); + } + + if (room.isStarted) { + return res.status(statusCode.OK).send(util.success(statusCode.OK, responseMessage.GET_WAITROOM_DATA_ALREADY)); + } + + const creator = await userDB.getUserById(client, room.creator); + const entries = await roomDB.getEntriesByRoomId(client, room.roomId); + const imageNum = 3; + let profileImgs = []; + + for (let i = 0; i < imageNum; i++) { + if (i >= entries.length) { + break; + } + + let user = await userDB.getUserById(client, entries[i].userId); + profileImgs.push(user.profileImg); + } + + const data = { + roomId: room.roomId, + roomName: room.roomName, + creatorName: creator.nickname, + createrImg: creator.profileImg, + profileImgs, + totalNums: entries.length, + }; + + res.status(statusCode.OK).send(util.success(statusCode.OK, responseMessage.READ_ONE_POST_SUCCESS, data)); + } catch (error) { + functions.logger.error(`[ERROR] [${req.method.toUpperCase()}] ${req.originalUrl}`, `[CONTENT] ${error}`); + console.log(error); + res.status(statusCode.INTERNAL_SERVER_ERROR).send(util.fail(statusCode.INTERNAL_SERVER_ERROR, responseMessage.INTERNAL_SERVER_ERROR)); + } finally { + client.release(); + } +}; diff --git a/functions/constants/responseMessage.js b/functions/constants/responseMessage.js index 4f677a5..aef6efb 100644 --- a/functions/constants/responseMessage.js +++ b/functions/constants/responseMessage.js @@ -21,4 +21,8 @@ module.exports = { // Room CREATE_ROOM_SUCCESS: '습관 방 생성 성공', CREATE_ROOM_FAIL: '습관 방 생성 실패', + GET_WAITROOM_DATA_SUCCESS: '대기방 정보 확인 완료', + GET_WAITROOM_DATA_NULL: '참여코드와 일치하는 습관 방이 존재하지 않습니다', + GET_WAITROOM_DATA_ALREADY: '이미 습관 형성에 도전중인 방입니다', + GET_WAITROOM_DATA_FAIL: '대기방 정보 확인 실패', }; diff --git a/functions/db/room.js b/functions/db/room.js index e7d277a..8cba41e 100644 --- a/functions/db/room.js +++ b/functions/db/room.js @@ -30,4 +30,31 @@ const isCodeUnique = async (client, code) => { return false; }; -module.exports = { addRoom, isCodeUnique }; +const getRoomByCode = async (client, code) => { + const { rows } = await client.query( + ` + SELECT * FROM spark.room + WHERE code = $1 + AND is_deleted = FALSE + `, + [code], + ); + return convertSnakeToCamel.keysToCamel(rows[0]); +}; + +const getEntriesByRoomId = async (client, roomId) => { + const { rows } = await client.query( + ` + SELECT * FROM spark.entry + WHERE room_id = $1 + AND is_out = FALSE + AND is_kicked = FALSE + AND is_deleted = FALSE + ORDER BY created_at + `, + [roomId], + ); + return convertSnakeToCamel.keysToCamel(rows); +}; + +module.exports = { addRoom, isCodeUnique, getRoomByCode, getEntriesByRoomId }; From 752361099eb3c6a23fe14117953a50eae47d22c4 Mon Sep 17 00:00:00 2001 From: youngkwon02 Date: Mon, 10 Jan 2022 20:07:52 +0900 Subject: [PATCH 2/7] =?UTF-8?q?comment:=20=EC=B0=B8=EC=97=AC=EC=BD=94?= =?UTF-8?q?=EB=93=9C=EB=A1=9C=20=EB=8C=80=EA=B8=B0=EB=B0=A9=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20api=20annotation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- functions/api/routes/room/roomCodeGET.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions/api/routes/room/roomCodeGET.js b/functions/api/routes/room/roomCodeGET.js index 751c3af..abd4e2a 100644 --- a/functions/api/routes/room/roomCodeGET.js +++ b/functions/api/routes/room/roomCodeGET.js @@ -1,5 +1,5 @@ /** - * @코드로 대기 방 정보 확인 + * @코드로_대기_방_정보_확인 * @route GET /room/code:code * @error * 1. 참여 코드가 전달되지 않음 From 0eaf7db2f5efae0c313cd64d0d5cc0972dec9413 Mon Sep 17 00:00:00 2001 From: youngkwon02 Date: Mon, 10 Jan 2022 20:21:34 +0900 Subject: [PATCH 3/7] =?UTF-8?q?comment:=20=EC=B0=B8=EC=97=AC=EC=BD=94?= =?UTF-8?q?=EB=93=9C=EB=A1=9C=20=EB=8C=80=EA=B8=B0=EB=B0=A9=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20api=20error=20case=20=EC=A3=BC=EC=84=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- functions/api/routes/room/roomCodeGET.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/functions/api/routes/room/roomCodeGET.js b/functions/api/routes/room/roomCodeGET.js index abd4e2a..c9e8f7d 100644 --- a/functions/api/routes/room/roomCodeGET.js +++ b/functions/api/routes/room/roomCodeGET.js @@ -14,6 +14,8 @@ const { userDB, roomDB } = require('../../../db'); module.exports = async (req, res) => { const { code } = req.params; + + // @error 1. 참여 코드가 전달되지 않음 if (!code) { return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.NULL_VALUE)); } @@ -24,10 +26,13 @@ module.exports = async (req, res) => { client = await db.connect(req); const room = await roomDB.getRoomByCode(client, code); + + // 참여 코드에 일치하는 방이 없음 if (!room) { return res.status(statusCode.OK).send(util.success(statusCode.OK, responseMessage.GET_WAITROOM_DATA_NULL)); } + // 참여 코드에 해당하는 방은 이미 습관 시작한 방임 if (room.isStarted) { return res.status(statusCode.OK).send(util.success(statusCode.OK, responseMessage.GET_WAITROOM_DATA_ALREADY)); } From b7d7a64292f970d38c14861bb7c9cce857082601 Mon Sep 17 00:00:00 2001 From: youngkwon02 Date: Mon, 10 Jan 2022 20:25:02 +0900 Subject: [PATCH 4/7] =?UTF-8?q?fix:=20=EC=B0=B8=EC=97=AC=EC=BD=94=EB=93=9C?= =?UTF-8?q?=EB=A1=9C=20=EB=8C=80=EA=B8=B0=EB=B0=A9=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EC=A3=BC=EC=84=9D=20Typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- functions/api/routes/room/roomCodeGET.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions/api/routes/room/roomCodeGET.js b/functions/api/routes/room/roomCodeGET.js index c9e8f7d..4b5b775 100644 --- a/functions/api/routes/room/roomCodeGET.js +++ b/functions/api/routes/room/roomCodeGET.js @@ -1,6 +1,6 @@ /** * @코드로_대기_방_정보_확인 - * @route GET /room/code:code + * @route GET /room/code/:code * @error * 1. 참여 코드가 전달되지 않음 */ From b8127a571440dabc55b00eaaca1ab30c6fe70c79 Mon Sep 17 00:00:00 2001 From: youngkwon02 Date: Mon, 10 Jan 2022 20:47:10 +0900 Subject: [PATCH 5/7] =?UTF-8?q?refactor:=20=EB=8C=80=EA=B8=B0=EB=B0=A9=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20api=20/=20=EC=9D=B4=EB=AF=B8=20=EC=B0=B8?= =?UTF-8?q?=EC=97=AC=EC=A4=91=EC=9D=B8=20=EA=B2=BD=EC=9A=B0=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- functions/api/routes/room/roomCodeGET.js | 30 +++++++++++++++++------- functions/constants/responseMessage.js | 3 ++- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/functions/api/routes/room/roomCodeGET.js b/functions/api/routes/room/roomCodeGET.js index 4b5b775..5ee0dd8 100644 --- a/functions/api/routes/room/roomCodeGET.js +++ b/functions/api/routes/room/roomCodeGET.js @@ -2,7 +2,8 @@ * @코드로_대기_방_정보_확인 * @route GET /room/code/:code * @error - * 1. 참여 코드가 전달되지 않음 + * 1. 요청 권한이 없음 (회원가입 되지 않은 사용자이거나, 권한이 없는 회원) + * 2. 참여 코드가 전달되지 않음 */ const functions = require('firebase-functions'); @@ -15,7 +16,15 @@ const { userDB, roomDB } = require('../../../db'); module.exports = async (req, res) => { const { code } = req.params; - // @error 1. 참여 코드가 전달되지 않음 + // @FIXME: 실제 user는 AccessToken을 통해 파악된 사용자 + const userId = 1; + // @error 1. 요청 권한이 없음 (등록되지 않은 사용쟈) + // let hasAuth = userDB.checkExistById(userId); + // if (!hasAuth) { + // // 등록된 회원이 아니라는 Response + // } + + // @error 2. 참여 코드가 전달되지 않음 if (!code) { return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.NULL_VALUE)); } @@ -29,12 +38,12 @@ module.exports = async (req, res) => { // 참여 코드에 일치하는 방이 없음 if (!room) { - return res.status(statusCode.OK).send(util.success(statusCode.OK, responseMessage.GET_WAITROOM_DATA_NULL)); + return res.status(statusCode.OK).send(util.fail(statusCode.OK, responseMessage.GET_WAITROOM_DATA_NULL)); } // 참여 코드에 해당하는 방은 이미 습관 시작한 방임 if (room.isStarted) { - return res.status(statusCode.OK).send(util.success(statusCode.OK, responseMessage.GET_WAITROOM_DATA_ALREADY)); + return res.status(statusCode.OK).send(util.fail(statusCode.OK, responseMessage.GET_WAITROOM_DATA_STARTED)); } const creator = await userDB.getUserById(client, room.creator); @@ -42,13 +51,16 @@ module.exports = async (req, res) => { const imageNum = 3; let profileImgs = []; - for (let i = 0; i < imageNum; i++) { - if (i >= entries.length) { - break; + for (let i = 0; i < entries.length; i++) { + if (i < imageNum) { + let user = await userDB.getUserById(client, entries[i].userId); + profileImgs.push(user.profileImg); } - let user = await userDB.getUserById(client, entries[i].userId); - profileImgs.push(user.profileImg); + // 이미 해당 습관에 참여중인 사용자 + if (userId == entries[i].userId) { + return res.status(statusCode.OK).send(util.fail(statusCode.OK, responseMessage.GET_WAITROOM_DATA_ALREADY)); + } } const data = { diff --git a/functions/constants/responseMessage.js b/functions/constants/responseMessage.js index aef6efb..6b650c3 100644 --- a/functions/constants/responseMessage.js +++ b/functions/constants/responseMessage.js @@ -23,6 +23,7 @@ module.exports = { CREATE_ROOM_FAIL: '습관 방 생성 실패', GET_WAITROOM_DATA_SUCCESS: '대기방 정보 확인 완료', GET_WAITROOM_DATA_NULL: '참여코드와 일치하는 습관 방이 존재하지 않습니다', - GET_WAITROOM_DATA_ALREADY: '이미 습관 형성에 도전중인 방입니다', + GET_WAITROOM_DATA_STARTED: '이미 습관 형성에 도전중인 방입니다', + GET_WAITROOM_DATA_ALREADY: '이미 사용자가 참가중인 방입니다', GET_WAITROOM_DATA_FAIL: '대기방 정보 확인 실패', }; From e726a6b420caac604577871b3caa31fd971944f9 Mon Sep 17 00:00:00 2001 From: youngkwon02 Date: Tue, 11 Jan 2022 14:49:38 +0900 Subject: [PATCH 6/7] refactor: roomCodeGET API auth middleware apply --- functions/api/routes/room/index.js | 3 ++- functions/api/routes/room/roomCodeGET.js | 15 ++++----------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/functions/api/routes/room/index.js b/functions/api/routes/room/index.js index e7e16ee..5d5d554 100644 --- a/functions/api/routes/room/index.js +++ b/functions/api/routes/room/index.js @@ -1,7 +1,8 @@ const express = require('express'); const router = express.Router(); +const { checkUser } = require('../../../middlewares/auth'); router.post('', require('./roomPOST')); -router.get('/code/:code', require('./roomCodeGET')); +router.get('/code/:code', checkUser, require('./roomCodeGET')); module.exports = router; diff --git a/functions/api/routes/room/roomCodeGET.js b/functions/api/routes/room/roomCodeGET.js index 5ee0dd8..d9a4af3 100644 --- a/functions/api/routes/room/roomCodeGET.js +++ b/functions/api/routes/room/roomCodeGET.js @@ -2,8 +2,7 @@ * @코드로_대기_방_정보_확인 * @route GET /room/code/:code * @error - * 1. 요청 권한이 없음 (회원가입 되지 않은 사용자이거나, 권한이 없는 회원) - * 2. 참여 코드가 전달되지 않음 + * 1. 참여 코드가 전달되지 않음 */ const functions = require('firebase-functions'); @@ -15,16 +14,10 @@ const { userDB, roomDB } = require('../../../db'); module.exports = async (req, res) => { const { code } = req.params; + const user = req.user; + const userId = user.userId; - // @FIXME: 실제 user는 AccessToken을 통해 파악된 사용자 - const userId = 1; - // @error 1. 요청 권한이 없음 (등록되지 않은 사용쟈) - // let hasAuth = userDB.checkExistById(userId); - // if (!hasAuth) { - // // 등록된 회원이 아니라는 Response - // } - - // @error 2. 참여 코드가 전달되지 않음 + // @error 1. 참여 코드가 전달되지 않음 if (!code) { return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.NULL_VALUE)); } From c7dab1e2b4d5202aada548ca4998dd43ad1ee469 Mon Sep 17 00:00:00 2001 From: youngkwon02 Date: Tue, 11 Jan 2022 15:11:52 +0900 Subject: [PATCH 7/7] refactor: roomCodeGET API res error cases --- functions/api/routes/room/roomCodeGET.js | 24 +++++++++++++++++------- functions/constants/responseMessage.js | 1 + functions/db/room.js | 16 +++++++++++++++- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/functions/api/routes/room/roomCodeGET.js b/functions/api/routes/room/roomCodeGET.js index d9a4af3..b2236ea 100644 --- a/functions/api/routes/room/roomCodeGET.js +++ b/functions/api/routes/room/roomCodeGET.js @@ -3,6 +3,10 @@ * @route GET /room/code/:code * @error * 1. 참여 코드가 전달되지 않음 + * 2. 참여코드에 일치하는 방이 없는 경우 + * 3. 이미 시작된 습관방인 경우 + * 4. 이미 참여중인 방인 경우 + * 5. 한번 내보내진 사용자인 경우 */ const functions = require('firebase-functions'); @@ -29,14 +33,20 @@ module.exports = async (req, res) => { const room = await roomDB.getRoomByCode(client, code); - // 참여 코드에 일치하는 방이 없음 + // @error 2. 참여 코드에 일치하는 방이 없음 if (!room) { - return res.status(statusCode.OK).send(util.fail(statusCode.OK, responseMessage.GET_WAITROOM_DATA_NULL)); + return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.GET_WAITROOM_DATA_NULL)); } - // 참여 코드에 해당하는 방은 이미 습관 시작한 방임 + // @error 3. 참여 코드에 해당하는 방은 이미 습관 시작한 방임 if (room.isStarted) { - return res.status(statusCode.OK).send(util.fail(statusCode.OK, responseMessage.GET_WAITROOM_DATA_STARTED)); + return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.GET_WAITROOM_DATA_STARTED)); + } + + // @error 5. 한번 내보내진 사용자인 경우 + const isKicked = await roomDB.checkKickedByRoomIdAndUserId(client, room.roomId, userId); + if (isKicked) { + return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.GET_WAITROOM_DATA_KICKED)); } const creator = await userDB.getUserById(client, room.creator); @@ -50,9 +60,9 @@ module.exports = async (req, res) => { profileImgs.push(user.profileImg); } - // 이미 해당 습관에 참여중인 사용자 - if (userId == entries[i].userId) { - return res.status(statusCode.OK).send(util.fail(statusCode.OK, responseMessage.GET_WAITROOM_DATA_ALREADY)); + // @error 4. 이미 해당 습관에 참여중인 사용자 + if (userId === entries[i].userId) { + return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.GET_WAITROOM_DATA_ALREADY)); } } diff --git a/functions/constants/responseMessage.js b/functions/constants/responseMessage.js index 6b650c3..088e28e 100644 --- a/functions/constants/responseMessage.js +++ b/functions/constants/responseMessage.js @@ -26,4 +26,5 @@ module.exports = { GET_WAITROOM_DATA_STARTED: '이미 습관 형성에 도전중인 방입니다', GET_WAITROOM_DATA_ALREADY: '이미 사용자가 참가중인 방입니다', GET_WAITROOM_DATA_FAIL: '대기방 정보 확인 실패', + GET_WAITROOM_DATA_KICKED: '습관 방 생성자에 의해 내보내진 방입니다', }; diff --git a/functions/db/room.js b/functions/db/room.js index 8cba41e..e4c466e 100644 --- a/functions/db/room.js +++ b/functions/db/room.js @@ -57,4 +57,18 @@ const getEntriesByRoomId = async (client, roomId) => { return convertSnakeToCamel.keysToCamel(rows); }; -module.exports = { addRoom, isCodeUnique, getRoomByCode, getEntriesByRoomId }; +const checkKickedByRoomIdAndUserId = async (client, roomId, userId) => { + const { rows } = await client.query( + ` + SELECT * FROM spark.entry + WHERE room_id = $1 + AND user_id = $2 + AND is_kicked = TRUE + AND is_deleted = FALSE + `, + [roomId, userId], + ); + return convertSnakeToCamel.keysToCamel(rows); +}; + +module.exports = { addRoom, isCodeUnique, getRoomByCode, getEntriesByRoomId, checkKickedByRoomIdAndUserId };