diff --git a/functions/api/routes/room/roomTimelineGET.js b/functions/api/routes/room/roomTimelineGET.js index 4eb1cb0..a15b9f3 100644 --- a/functions/api/routes/room/roomTimelineGET.js +++ b/functions/api/routes/room/roomTimelineGET.js @@ -54,20 +54,35 @@ module.exports = async (req, res) => { let timelines = await lifeTimelineDB.getLifeTimeline(client, roomId, user.userId); timelines = timelines.map((t) => { - const timeline = {}; - const { title, content } = timelineMessage.LIFE_DECREASE(t.decreaseCount); - - let createdAt = dayjs(t.createdAt); - const passedDay = now.diff(createdAt, 'd'); - const profiles = [t.profile_1, t.profile_2].filter((profile) => profile !== 'null'); - - timeline['title'] = title; - timeline['content'] = content; - timeline['profiles'] = profiles; - timeline['day'] = passedDayToStr(passedDay); - timeline['isNew'] = !t.isRead; - - return timeline; + if (t.isDecrease) { + const timeline = {}; + const { title, content } = timelineMessage.LIFE_DECREASE(t.decreaseCount); + + let createdAt = dayjs(t.createdAt); + const passedDay = now.diff(createdAt, 'd'); + const profiles = [t.profile_1, t.profile_2].filter((profile) => profile !== 'null'); + + timeline['title'] = title; + timeline['content'] = content; + timeline['profiles'] = profiles; + timeline['day'] = passedDayToStr(passedDay); + timeline['isNew'] = !t.isRead; + + return timeline; + } else { + const timeline = {}; + const { title, content } = timelineMessage.LIFE_FILL(t.termDay); + + let createdAt = dayjs(t.createdAt); + const passedDay = now.diff(createdAt, 'd'); + + timeline['title'] = title; + timeline['content'] = content; + timeline['day'] = passedDayToStr(passedDay); + timeline['isNew'] = !t.isRead; + + return timeline; + } }); await lifeTimelineDB.readLifeTimeline(client, roomId, user.userId); diff --git a/functions/constants/lifeTimelineMessage.js b/functions/constants/lifeTimelineMessage.js index 53dca0b..0b0ced4 100644 --- a/functions/constants/lifeTimelineMessage.js +++ b/functions/constants/lifeTimelineMessage.js @@ -4,6 +4,26 @@ const LIFE_DECREASE = (count) => { return { title, content }; }; +const LIFE_FILL = (termDay) => { + const title = `생명 충전 완료🔋`; + let content = ''; + + if (termDay === 1) { + content = '66일의 도전을 시작했네요. 인증하고 생명을 지켜요!'; + } else if (termDay === 4) { + content = '3일 달성 선물로 생명이 충전됐어요. 잘하고 있어요!'; + } else if (termDay === 8) { + content = '7일 달성 선물로 생명이 충전됐어요. 더 힘내봐요!'; + } else if (termDay === 34) { + content = '33일 달성 선물로 생명이 충전됐어요. 할 수 있어요!'; + } else if (termDay === 60) { + content = '마지막 7일 선물로 생명이 충전됐어요. 끝까지 힘내요!'; + } + + return { title, content }; +}; + module.exports = { LIFE_DECREASE, + LIFE_FILL, }; diff --git a/functions/constants/termList.js b/functions/constants/termList.js new file mode 100644 index 0000000..08f84f5 --- /dev/null +++ b/functions/constants/termList.js @@ -0,0 +1,5 @@ +const termList = [1, 4, 8, 34, 60]; + +module.exports = { + termList, +}; diff --git a/functions/db/lifeTimeline.js b/functions/db/lifeTimeline.js index 2c117a0..d8bbf21 100644 --- a/functions/db/lifeTimeline.js +++ b/functions/db/lifeTimeline.js @@ -1,8 +1,6 @@ -const dayjs = require('dayjs'); -const _ = require('lodash'); const convertSnakeToCamel = require('../lib/convertSnakeToCamel'); -const addLifeTimeline = async (client, timelines) => { +const addDecreaseTimelines = async (client, timelines) => { const { rows } = await client.query( ` INSERT INTO spark.life_timeline @@ -15,6 +13,19 @@ const addLifeTimeline = async (client, timelines) => { return convertSnakeToCamel.keysToCamel(rows[0]); }; +const addFillTimelines = async (client, timelines) => { + const { rows } = await client.query( + ` + INSERT INTO spark.life_timeline + (receiver_id, room_id, is_decrease, term_day) + VALUES + ${timelines.join()} + RETURNING * + `, + ); + return convertSnakeToCamel.keysToCamel(rows[0]); +}; + const getLifeTimeline = async (client, roomId, userId) => { const { rows } = await client.query( ` @@ -43,7 +54,8 @@ const readLifeTimeline = async (client, roomId, userId) => { }; module.exports = { - addLifeTimeline, + addDecreaseTimelines, + addFillTimelines, getLifeTimeline, readLifeTimeline, }; diff --git a/functions/db/room.js b/functions/db/room.js index 8a0278f..dbcee45 100644 --- a/functions/db/room.js +++ b/functions/db/room.js @@ -734,6 +734,20 @@ const endById = async (client, roomId) => { return convertSnakeToCamel.keysToCamel(rows); }; +const fillLifeByRoomIds = async (client, roomIds) => { + const now = dayjs().add(9, 'hour'); + const { rows } = await client.query( + ` + UPDATE spark.room + SET life = 3, updated_at = $1 + WHERE room_id in (${roomIds.join()}) + RETURNING * + `, + [now], + ); + return convertSnakeToCamel.keysToCamel(rows); +}; + module.exports = { addRoom, isCodeUnique, @@ -775,4 +789,5 @@ module.exports = { getMemberIdsByEntryIds, endById, outByUserId, + fillLifeByRoomIds, }; diff --git a/functions/scheduler/funcs.js b/functions/scheduler/funcs.js index 6c56b5e..c2c9b9e 100644 --- a/functions/scheduler/funcs.js +++ b/functions/scheduler/funcs.js @@ -5,6 +5,7 @@ const dayjs = require('dayjs'); const slackAPI = require('../middlewares/slackAPI'); const alarmMessage = require('../constants/alarmMessage'); const pushAlarm = require('../lib/pushAlarm'); +const { termList } = require('../constants/termList'); const checkLife = async () => { let client; @@ -103,7 +104,7 @@ const checkLife = async () => { // 생명 감소시 Time Line Insert if (decreaseMessage.length) { - await lifeTimelineDB.addLifeTimeline(client, decreaseMessage); + await lifeTimelineDB.addDecreaseTimelines(client, decreaseMessage); } // 살아남은 방 없으면 return @@ -114,24 +115,41 @@ const checkLife = async () => { const survivedRoomIds = _.difference(successRoomIds, completeRoomIds); const ongoingEntries = await roomDB.getEntriesByRoomIds(client, survivedRoomIds); // 성공한 방들의 entry 불러오기 - // 추가해줄 record들의 속성들 빚어주기 - const insertEntries = ongoingEntries.map((o) => { - const startDate = dayjs(o.startAt); - const day = dayjs(today).diff(startDate, 'day') + 1; - const queryParameter = '(' + o.entryId + ",'" + now.format('YYYY-MM-DD') + "'," + day + ')'; + // 추가해줄 records + let insertEntries = []; - return queryParameter; - }); + // 추가해줄 lifeTimelines + let insertTimelines = []; + + // 생명 충전해줄 RoomIds + let fillLifeRoomIds = new Set(); + + for (let i = 0; i < ongoingEntries.length; i++) { + // insert할 record 값들 생성 + const entry = ongoingEntries[i]; + const day = dayjs(today).diff(dayjs(entry.startAt), 'day') + 1; + const queryParameter = '(' + entry.entryId + ",'" + now.format('YYYY-MM-DD') + "'," + day + ')'; + insertEntries.push(queryParameter); + + if (termList.includes(day)) { + fillLifeRoomIds.add(entry.roomId); + insertTimelines.push(`('${entry.userId}', '${entry.roomId}', false, ${day})`); + } + } + + fillLifeRoomIds = Array.from(fillLifeRoomIds); + + await recordDB.insertRecords(client, insertEntries); // record 추가! + await lifeTimelineDB.addFillTimelines(client, insertTimelines); // lifeTimeline 추가! + await roomDB.fillLifeByRoomIds(client, fillLifeRoomIds); // 생명 충전 - const resultRecords = await recordDB.insertRecords(client, insertEntries); // record 추가! - const slackMessage = `폭파된 방 목록: ${failRoomIds} \n 살아남은 방 목록: ${survivedRoomIds}`; + const slackMessage = `폭파된 방 목록: ${failRoomIds} \n 생명 충전 방 목록: ${fillLifeRoomIds} \n 살아남은 방 목록: ${survivedRoomIds}`; slackAPI.sendMessageToSlack(slackMessage, slackAPI.DEV_WEB_HOOK_ERROR_MONITORING); } catch (error) { console.log(error); const slackMessage = `[ERROR] ${error} ${JSON.stringify(error)}`; slackAPI.sendMessageToSlack(slackMessage, slackAPI.DEV_WEB_HOOK_ERROR_MONITORING); } finally { - console.log('relase'); client.release(); } };