Skip to content

Commit

Permalink
Merge branch 'develop' into feature/#36
Browse files Browse the repository at this point in the history
  • Loading branch information
youngkwon02 authored Jan 15, 2022
2 parents 64e11df + 69d8849 commit a0079b9
Show file tree
Hide file tree
Showing 11 changed files with 310 additions and 18 deletions.
3 changes: 3 additions & 0 deletions functions/api/routes/room/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ router.get('/code/:code', checkUser, require('./roomCodeGET'));
router.post('', checkUser, require('./roomPOST'));
router.post('/:roomId/enter', checkUser, require('./roomEnterPOST'));
router.patch('/:roomId/purpose', checkUser, require('./roomPurposePATCH'));
router.get('/:roomId/waiting', checkUser, require('./roomWaitingGET'));
router.get('/:roomId', checkUser, require('./roomDetailGET'));
router.get('', checkUser, require('./roomListGET'));
router.get('/:roomId/waiting/member', checkUser, require('./roomWaitingMemberGET'));
router.post('/:roomId/start', checkUser, require('./roomStartPOST'));

module.exports = router;
2 changes: 1 addition & 1 deletion functions/api/routes/room/roomEnterPOST.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ module.exports = async (req, res) => {
}

// error 3. 정원이 가득찬 습관방
const entries = roomDB.getEntriesByRoomId(client, roomId);
const entries = await roomDB.getEntriesByRoomId(client, roomId);
if (entries.length > 9) {
return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.GET_WAITROOM_DATA_FULL));
}
Expand Down
66 changes: 66 additions & 0 deletions functions/api/routes/room/roomStartPOST.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
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 { roomDB, recordDB } = require('../../../db');

/**
* @습관방_시작
* @route POST /room/:roomId/start
* @body
* @error
* 1. 유효하지 않은 roomId
* 2. 권한이 없는 사용자로부터의 요청
* 3. 이미 시작된 방
*/

module.exports = async (req, res) => {
const { roomId } = req.params;
const user = req.user;
const userId = user.userId;

let client;

try {
client = await db.connect(req);

let room = await roomDB.getRoomById(client, roomId);

// @error 1. 유효하지 않은 roomId
if (!room) {
return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.ROOM_ID_NOT_FOUND));
}

// @error 2. 권한이 없는 사용자로부터의 요청
if (userId !== room.creator) {
return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.PRIV_NOT_FOUND));
}

// 습관방 status ONGOING으로 변경
room = await roomDB.startRoomById(client, roomId);

// @error 3. 이미 시작된 방
if (!room) {
return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.START_ROOM_ALREADY));
}

// 참여자들의 0일차 record 생성
const entries = await roomDB.getEntriesByRoomId(client, roomId);

for (let i = 0; i < entries.length; i++) {
await recordDB.insertRecordById(client, entries[i].entryId, room.startAt);
}

// @TODO: Send Notification !!

res.status(statusCode.OK).send(util.success(statusCode.OK, responseMessage.START_ROOM_SUCCESS));
} 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();
}
};
83 changes: 83 additions & 0 deletions functions/api/routes/room/roomWaitingGET.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
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');

/**
* @대기_방_조회
* @route GET /room/:roomId/waiting
* @error
* 1. 유효하지 않은 roomId
* 2. 권한이 없는 사용자로부터의 요청
*/

module.exports = async (req, res) => {
const { roomId } = req.params;
const user = req.user;
console.log(user);
const userId = user.userId;

let client;

try {
client = await db.connect(req);

const room = await roomDB.getRoomById(client, roomId);

// @error 1. 유효하지 않은 roomId
if (!room) {
return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.ROOM_ID_NOT_FOUND));
}

const selfEntry = await roomDB.getEntryByIds(client, roomId, userId);

// error 2. 권한이 없는 사용자로부터의 요청
if (!selfEntry) {
return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.PRIV_NOT_FOUND));
}

// 요청을 보낸 사용자 본인 data
const reqUser = {
userId,
nickname: user.nickname,
profileImg: user.profileImg,
isPurposeSet: selfEntry.moment !== null && selfEntry.purpose !== null,
moment: selfEntry.moment,
purpose: selfEntry.purpose,
isHost: room.creator === userId,
};

// 요청을 보낸 사용자를 제외한 member list
const friendsEntries = await roomDB.getFriendsByIds(client, roomId, userId);
const friendsIds = friendsEntries.map((f) => f.userId);
const users = await userDB.getUsersByIds(client, friendsIds);
let members = [];

users.map((u) =>
members.push({
userId: u.userId,
nickname: u.nickname,
profileImg: u.profileImg,
}),
);

const data = {
roomId,
roomName: room.roomName,
roomCode: room.code,
fromStart: room.fromStart,
reqUser,
members,
};

res.status(statusCode.OK).send(util.success(statusCode.OK, responseMessage.GET_WAITROOM_DATA_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();
}
};
62 changes: 62 additions & 0 deletions functions/api/routes/room/roomWaitingMemberGET.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
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');

/**
* @대기_방_인원_조회
* @route GET /room/:roomId/waiting/member
* @error
* 1. 유효하지 않은 roomId
* 2. 권한이 없는 사용자로부터의 요청
*/

module.exports = async (req, res) => {
const { roomId } = req.params;
const user = req.user;
const userId = user.userId;

let client;

try {
client = await db.connect(req);

const room = await roomDB.getRoomById(client, roomId);

// @error 1. 유효하지 않은 roomId
if (!room) {
return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.ROOM_ID_NOT_FOUND));
}

const selfEntry = await roomDB.getEntryByIds(client, roomId, userId);

// error 2. 권한이 없는 사용자로부터의 요청
if (!selfEntry) {
return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.PRIV_NOT_FOUND));
}

// 요청을 보낸 사용자를 제외한 member list
const friendsEntries = await roomDB.getFriendsByIds(client, roomId, userId);
const friendsIds = friendsEntries.map((f) => f.userId);
const users = await userDB.getUsersByIds(client, friendsIds);
let members = [];

users.map((u) =>
members.push({
userId: u.userId,
nickname: u.nickname,
profileImg: u.profileImg,
}),
);

res.status(statusCode.OK).send(util.success(statusCode.OK, responseMessage.GET_WAITROOM_DATA_SUCCESS, { members }));
} 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();
}
};
4 changes: 3 additions & 1 deletion functions/constants/responseMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ module.exports = {
ENTER_ROOM_ALREADY: '이미 참여중인 습관 방입니다',
ROOM_ID_INVALID: '올바르지 않은 roomId입니다',
PURPOSE_SET_SUCCESS: '목표 설정 성공',
ROOM_ID_NOT_FOUND: '유효하지 않은 roomId입니다',
GET_ROOM_DATA_FAIL: '존재하지 않는 습관방입니다',
NOT_ONGOING_ROOM: '현재 진행중인 습관방이 아닙니다',
NOT_MEMBER: '참여중인 습관방이 아닙니다',
GET_ROOM_LIST_SUCCESS: '참여중인 습관방 조회 완료',

START_ROOM_SUCCESS: '습관 방 시작 완료',
START_ROOM_ALREADY: '이미 시작된 방입니다',

// Notice
SERVICE_READ_SUCCESS: '서비스 알림 읽음처리 완료',
Expand Down
1 change: 1 addition & 0 deletions functions/db/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ module.exports = {
roomDB: require('./room'),
sparkDB: require('./spark'),
noticeDB: require('./notice'),
recordDB: require('./record'),
};
23 changes: 23 additions & 0 deletions functions/db/record.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const dayjs = require('dayjs');
const _ = require('lodash');
const convertSnakeToCamel = require('../lib/convertSnakeToCamel');

const insertRecordById = async (client, entryId, roomStartAt) => {
const now = dayjs().add(9, 'hour');
const today = now.startOf('d');
const day = today.diff(roomStartAt, 'd');
const { rows } = await client.query(
`
INSERT INTO spark.record
(entry_id, date, day)
VALUES
($1, $2, $3)
RETURNING *
`,
[entryId, today, day],
);

return convertSnakeToCamel.keysToCamel(rows[0]);
};

module.exports = { insertRecordById };
64 changes: 50 additions & 14 deletions functions/db/room.js
Original file line number Diff line number Diff line change
Expand Up @@ -247,19 +247,55 @@ const enterById = async (client, roomId, userId) => {
}
};

module.exports = {
addRoom,
isCodeUnique,
getRoomById,
const getFriendsByIds = async (client, roomId, userId) => {
const { rows } = await client.query(
`
SELECT * FROM spark.entry
WHERE room_id = $1
AND user_id != $2
AND is_deleted = FALSE
AND is_out = FALSE
AND is_kicked = FALSE
ORDER BY created_at
`,
[roomId, userId],
);
return convertSnakeToCamel.keysToCamel(rows);
};

const startRoomById = async (client, roomId) => {
const now = dayjs().add(9, 'hour');
const startAt = now.startOf('d');
const endAt = now.add(66, 'day').startOf('d');
console.log(endAt.diff(startAt, 'd'));
const { rows } = await client.query(
`
UPDATE spark.room
SET status = 'ONGOING', updated_at = $2, start_at = $3, end_at = $4
WHERE room_id = $1
AND status != 'ONGOING'
RETURNING *
`,
[roomId, now, startAt, endAt],
);
return convertSnakeToCamel.keysToCamel(rows[0]);
};

module.exports = {
addRoom,
isCodeUnique,
getRoomById,
getRoomsByIds,
getRoomByCode,
getEntriesByRoomId,
kickedHistoryByIds,
getEntryByIds,
updatePurposeByEntryId,
getRecordsByDay,
checkEnteredById,
enterById,
getUserProfilesByRoomIds,
getRoomsByUserId
getRoomByCode,
getEntriesByRoomId,
getRoomsByUserId,
getUserProfilesByRoomIds,
kickedHistoryByIds,
getEntryByIds,
updatePurposeByEntryId,
getRecordsByDay,
checkEnteredById,
enterById,
getFriendsByIds,
startRoomById,
};
15 changes: 13 additions & 2 deletions functions/db/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,18 @@ const getUserById = async (client, userId) => {
[userId],
);
return convertSnakeToCamel.keysToCamel(rows[0]);
}
};

const getUsersByIds = async (client, userIds) => {
const { rows } = await client.query(
`
SELECT * FROM spark.user
WHERE user_id in (${userIds.join()})
AND is_deleted = FALSE
`,
);
return convertSnakeToCamel.keysToCamel(rows);
};

const getUserBySocialId = async (client, socialId) => {
const { rows } = await client.query(
Expand Down Expand Up @@ -52,7 +63,7 @@ const addUser = async (client, socialId, nickname, profileImg) => {
module.exports = {
getAllUsers,
getUserById,
getUsersByIds,
getUserBySocialId,
addUser
};

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"dayjs": "^1.10.7"
}
}

0 comments on commit a0079b9

Please sign in to comment.