From 39c13360bf5ba48cdb2ec3661642053c39ae1703 Mon Sep 17 00:00:00 2001 From: kkoon9 Date: Fri, 11 Dec 2020 01:32:23 +0900 Subject: [PATCH 1/2] =?UTF-8?q?database=20map=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _dummyData/sprints.json | 30 ++++++++++++++++++------------ src/models/sprintModel.js | 3 ++- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/_dummyData/sprints.json b/_dummyData/sprints.json index a2bea4b..40fdf46 100644 --- a/_dummyData/sprints.json +++ b/_dummyData/sprints.json @@ -13,15 +13,15 @@ { "title" : "운전 면허증 따기", "percentage" : 100, - "score" : [0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3] + "score" : {"2020-11-30": 0,"2020-12-01": 0,"2020-12-02": 0,"2020-12-03": 5,"2020-12-04": 3,"2020-12-05": 0,"2020-12-06": -3} }, { "title" : "자격증 따기", "percentage" : 53, - "score" : [0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3] + "score" : {"2020-11-30": 0,"2020-12-01": 0,"2020-12-02": 0,"2020-12-03": 5,"2020-12-04": 3,"2020-12-05": 0,"2020-12-06": -3} }, { "title" : "학점 4.0 넘기", "percentage" : 42, - "score" : [0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3] + "score" : {"2020-11-30": 0,"2020-12-01": 0,"2020-12-02": 0,"2020-12-03": 5,"2020-12-04": 3,"2020-12-05": 0,"2020-12-06": -3} } ], "review": [ @@ -103,15 +103,15 @@ { "title" : "운전 면허증 따기", "percentage" : 0, - "score" : [0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3] + "score" : {"2020-11-30": 0,"2020-12-01": 0,"2020-12-02": 0,"2020-12-03": 5,"2020-12-04": 3,"2020-12-05": 0,"2020-12-06": -3} }, { "title" : "자격증 따기", "percentage" : 0, - "score" : [0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3] + "score" : {"2020-11-30": 0,"2020-12-01": 0,"2020-12-02": 0,"2020-12-03": 5,"2020-12-04": 3,"2020-12-05": 0,"2020-12-06": -3} }, { "title" : "학점 4.0 넘기", "percentage" : 0, - "score" : [0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3] + "score" : {"2020-11-30": 0,"2020-12-01": 0,"2020-12-02": 0,"2020-12-03": 5,"2020-12-04": 3,"2020-12-05": 0,"2020-12-06": -3} } ], "review": [ @@ -192,13 +192,16 @@ "goal": [ { "title" : "운전 면허증 따기", - "score" : [0,0,0,5,3,0,-3] + "percentage" : 0, + "score" : {"2020-11-30": 0,"2020-12-01": 0,"2020-12-02": 0,"2020-12-03": 5,"2020-12-04": 3,"2020-12-05": 0,"2020-12-06": -3} }, { "title" : "자격증 따기", - "score" : [0,0,0,5,3,0,-3] + "percentage" : 0, + "score" : {"2020-11-30": 0,"2020-12-01": 0,"2020-12-02": 0,"2020-12-03": 5,"2020-12-04": 3,"2020-12-05": 0,"2020-12-06": -3} }, { "title" : "학점 4.0 넘기", - "score" : [0,0,0,5,3,0,-3] + "percentage" : 0, + "score" : {"2020-11-30": 0,"2020-12-01": 0,"2020-12-02": 0,"2020-12-03": 5,"2020-12-04": 3,"2020-12-05": 0,"2020-12-06": -3} } ], "review": [ @@ -277,13 +280,16 @@ "goal": [ { "title" : "운전 면허증 따기", - "score" : [0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3] + "percentage" : 0, + "score" : {"2020-11-30": 0,"2020-12-01": 0,"2020-12-02": 0,"2020-12-03": 5,"2020-12-04": 3,"2020-12-05": 0,"2020-12-06": -3} }, { "title" : "자격증 따기", - "score" : [0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3] + "percentage" : 0, + "score" : {"2020-11-30": 0,"2020-12-01": 0,"2020-12-02": 0,"2020-12-03": 5,"2020-12-04": 3,"2020-12-05": 0,"2020-12-06": -3} }, { "title" : "학점 4.0 넘기", - "score" : [0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3,0,0,0,5,3,0,-3,-5,5,3] + "percentage" : 0, + "score" : {"2020-11-30": 0,"2020-12-01": 0,"2020-12-02": 0,"2020-12-03": 5,"2020-12-04": 3,"2020-12-05": 0,"2020-12-06": -3} } ], "review": [ diff --git a/src/models/sprintModel.js b/src/models/sprintModel.js index 4c0f899..7278601 100644 --- a/src/models/sprintModel.js +++ b/src/models/sprintModel.js @@ -44,7 +44,8 @@ const SprintSchema = new mongoose.Schema({ default: 0, }, score: { - type: [Number], + type: Map, + of: String, }, }], review: [{ From cd0839f46f79a26ed7ff6d821101a909b68f24a9 Mon Sep 17 00:00:00 2001 From: kkoon9 Date: Fri, 11 Dec 2020 21:06:12 +0900 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=EC=A0=90=EC=88=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20=ED=9A=8C=EA=B3=A0=EB=A1=9D=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/routes/sprints.js | 49 +++++++++++++++++++++++++++++++++- src/modules/date.js | 17 +++++++++++- src/modules/responseMessage.js | 5 +++- src/services/sprint.js | 21 +++++++++++++++ 4 files changed, 89 insertions(+), 3 deletions(-) diff --git a/src/apis/routes/sprints.js b/src/apis/routes/sprints.js index d4c367d..76cfed8 100644 --- a/src/apis/routes/sprints.js +++ b/src/apis/routes/sprints.js @@ -2,6 +2,7 @@ import express from 'express'; import SprintService from '../../services/sprint.js'; import asyncHandler from '../../modules/async.js'; import date from '../../modules/date.js'; +import sprint from '../../services/sprint.js'; const router = express.Router(); @@ -44,8 +45,9 @@ router.post('/', asyncHandler(async (req, res) => { // The actual responsability of the route layer. const sprintDTO = req.body; + const score = await date.getScoreDateMap(sprintDTO.startTime, sprintDTO.endTime); sprintDTO.goal = await sprintDTO.goals.map((g) => { - return {title: g, percentage:0, socre:[]} + return {title: g, percentage:0, score:score} }); const review = await date.getReviewDate(sprintDTO.nextReviewTime, sprintDTO.endTime, sprintDTO.day); sprintDTO.review = await review.map((date) => { @@ -60,4 +62,49 @@ router.post('/', }) ); +router.post('/', + // validators.getSprint, // this middleware take care of validation + asyncHandler(async (req, res) => { + // The actual responsability of the route layer. + const sprintDTO = req.body; + const score = await date.getScoreDateMap(sprintDTO.startTime, sprintDTO.endTime); + sprintDTO.goal = await sprintDTO.goals.map((g) => { + return {title: g, percentage:0, score:score} + }); + const review = await date.getReviewDate(sprintDTO.nextReviewTime, sprintDTO.endTime, sprintDTO.day); + sprintDTO.review = await review.map((date) => { + return {reviewTime: date, averageAchievement:0, comments:[]} + }); + // Call to service layer. + // Abstraction on how to access the data layer and the business logic. + const { success, message, data } = await SprintService.CreateService(sprintDTO); + + // Return a response to client. + return res.json({ success, message, data }); + }) +); + +router.put('/score/:id', + asyncHandler(async (req, res) => { + const id = req.params.id; + const {day, scores} = req.body; + + const { success, message, data } = await SprintService.InsertScore({id, day, scores}); + + // Return a response to client. + return res.json({ success, message, data }); + }) +); + +router.get('/review/:id', + asyncHandler(async (req, res) => { + const id = req.params.id; + + const { success, message, data } = await SprintService.GetReview(id); + + // Return a response to client. + return res.json({ success, message, data }); + }) +); + export default router; diff --git a/src/modules/date.js b/src/modules/date.js index 836ea03..939c52a 100644 --- a/src/modules/date.js +++ b/src/modules/date.js @@ -36,5 +36,20 @@ export default { nextTime = await this.getFormatDate(nextDate); } return reviewDateArray; - } + }, + + async getScoreDateMap(startTime, endTime) { + const initScore = -1; + const scoreDateArray = [[startTime, initScore]]; + let nextDate = this.getDateType(startTime); + nextDate.setDate(nextDate.getDate() + 1); + let nextTime = await this.getFormatDate(nextDate); + while(nextTime <= endTime ) { + scoreDateArray.push([nextTime, initScore]); + nextDate = this.getDateType(nextTime); + nextDate.setDate(nextDate.getDate() + 1); + nextTime = await this.getFormatDate(nextDate); + } + return new Map(scoreDateArray); + }, }; diff --git a/src/modules/responseMessage.js b/src/modules/responseMessage.js index 3bcd39a..d2ba74e 100644 --- a/src/modules/responseMessage.js +++ b/src/modules/responseMessage.js @@ -13,5 +13,8 @@ export default { NO_SPRINT: '현재 진행중인 스프린트가 없습니다.', SPRINT_CREATE_SUCCESS: '스프린트 추가에 성공했습니다.', SPRINT_CREATE_FAIL: '스프린트 추가에 실패했습니다.', - + SPRINT_SCORE_SUCCESS: '스프린트 점수 입력에 성공했습니다.', + SPRINT_SCORE_FAIL: '스프린트 점수 입력에 실패했습니다.', + SPRINT_REVIEW_READ_SUCCESS: '해당 스프린트의 회고 정보 조회에 성공했습니다.', + SPRINT_REVIEW_READ_FAIL: '해당 스프린트의 회고 정보 조회에 실패했습니다.', }; diff --git a/src/services/sprint.js b/src/services/sprint.js index 9ce9e79..272193b 100644 --- a/src/services/sprint.js +++ b/src/services/sprint.js @@ -20,4 +20,25 @@ export default { } return { success: true, message: message.SPRINT_CREATE_SUCCESS, data: sprintRecord }; }, + + async InsertScore({id, day, scores}) { + const sprint = await SprintModel.findById(id).select('-review -question'); + if (!sprint) { + return { success: false, message: message.SPRINT_SCORE_FAIL, data: null }; + } + scores.map((score, i) => { + sprint.goal[i].score.set(day, score); + }) + sprint.save(); + return { success: true, message: message.SPRINT_SCORE_SUCCESS, data: sprint }; + }, + + async GetReview(id) { + const sprintReview = await SprintModel.findById(id).select('-goal -question'); + // If the user is not an admin, they can only add one bootcamp + if (sprintReview && !sprintReview.progress) { + return { success: false, message: message.SPRINT_REVIEW_READ_FAIL, data: null }; + } + return { success: true, message: message.SPRINT_REVIEW_READ_SUCCESS, data: sprintReview }; + }, };