송용우

Merge branch 'develop' into feature/frontend_page

...@@ -30,14 +30,17 @@ POST http://facerain.dcom.club/profile/getprofile ...@@ -30,14 +30,17 @@ POST http://facerain.dcom.club/profile/getprofile
30 | --------- | -------------------------------------- | ------ | -------------------------- | -------------------------------------- | --------- | 30 | --------- | -------------------------------------- | ------ | -------------------------- | -------------------------------------- | --------- |
31 | profile | 유저가 푼 문제 조회(백준) | GET | api/profile/solvedBJ:id | [바로가기](/src/api/profile/README.md) | None | 31 | profile | 유저가 푼 문제 조회(백준) | GET | api/profile/solvedBJ:id | [바로가기](/src/api/profile/README.md) | None |
32 | profile | 유저가 푼 문제 동기화(백준) | PATCH | api/profile/syncBJ | [바로가기](/src/api/profile/README.md) | None | 32 | profile | 유저가 푼 문제 동기화(백준) | PATCH | api/profile/syncBJ | [바로가기](/src/api/profile/README.md) | None |
33 -| profile | 유저 정보 수정 | POST | api/profile/setprofile | [바로가기](/src/api/profile/README.md) | JWT TOKEN | 33 +| profile | 유저 정보 수정 | POST | api/profile/setprofile | [바로가기](/src/api/profile/README.md) | JWT |
34 | profile | 유저 정보 받아오기 | POST | api/profile/getprofile | [바로가기](/src/api/profile/README.md) | JWT | 34 | profile | 유저 정보 받아오기 | POST | api/profile/getprofile | [바로가기](/src/api/profile/README.md) | JWT |
35 | profile | 추천 문제 조회 | POST | api/profile/recommend | [바로가기](/src/api/profile/README.md) | None | 35 | profile | 추천 문제 조회 | POST | api/profile/recommend | [바로가기](/src/api/profile/README.md) | None |
36 -| profile | 친구 추가 | POST | /api/profile/addfriend | [바로가기](/src/api/profile/README.md) | JWT TOKEN | 36 +| profile | 친구 추가 | POST | api/profile/addfriend | [바로가기](/src/api/profile/README.md) | JWT |
37 -| notify | 슬랙 메시지 전송 요청 (목표 성취 여부) | POST | api/notify/goal | [바로가기](/src/api/notify/README.md) | Jwt Token | 37 +| notify | 슬랙 메시지 전송 요청 (목표 성취 여부) | POST | api/notify/goal | [바로가기](/src/api/notify/README.md) | JWT |
38 | notify | 슬랙 메시지 전송 요청 (문제 추천) | POST | api/notify/recommend | [바로가기](/src/api/notify/README.md) | None | 38 | notify | 슬랙 메시지 전송 요청 (문제 추천) | POST | api/notify/recommend | [바로가기](/src/api/notify/README.md) | None |
39 | auth | 로그인 | POST | api/auth/login | [바로가기](/src/api/auth/README.md) | None | 39 | auth | 로그인 | POST | api/auth/login | [바로가기](/src/api/auth/README.md) | None |
40 -| auth | 로그아웃 | POST | api/auth/logout | [바로가기](/src/api/auth/README.md) | JWT Token | 40 +| auth | 로그아웃 | POST | api/auth/logout | [바로가기](/src/api/auth/README.md) | JWT |
41 | auth | 회원가입 | POST | api/auth/register | [바로가기](/src/api/auth/README.md) | None | 41 | auth | 회원가입 | POST | api/auth/register | [바로가기](/src/api/auth/README.md) | None |
42 | auth | 로그인 확인 | GET | api/auth/check | [바로가기](/src/api/auth/README.md) | None | 42 | auth | 로그인 확인 | GET | api/auth/check | [바로가기](/src/api/auth/README.md) | None |
43 -| challenge | 특정 챌린지 조회(이름) | POST | api/challenge/getChallenge | [바로가기]() | None | 43 +| challenge | 특정 챌린지 조회(이름) | POST | api/challenge/getChallenge | [바로가기](/src/api/challenge/README.md)| None |
44 +| challenge | 챌린지 추가 | POST | api/challenge/addChallenge | [바로가기](/src/api/challenge/README.md) | None |
45 +| challenge | 챌린지 목록 조회 | GET | api/challenge/list | [바로가기](/src/api/challenge/README.md) | None |
46 +| challenge | 챌린지 참가 | POST | api/challenge/participate | [바로가기](/src/api/challenge/README.md) | None |
...\ No newline at end of file ...\ No newline at end of file
......
1 +# API Documentation - Challenge
2 +
3 +1. POST /api/challenge/getChallenge
4 +- 챌린지 상세 정보 조회
5 +- input(body)
6 +```javascript
7 +{
8 + "challengeName": String
9 +}
10 +```
11 +1. POST /api/challenge/addChallenge
12 +- 챌린지 추가
13 +- input(body)
14 +```javascript
15 +{
16 + "challengeName":String,
17 + "startDate":Date,
18 + "endDate":Date,
19 + "durationPerSession": String, // "1d"=1 day, "2w"=2 weeks, "3m"=3 months
20 + "goalPerSession":Number
21 +}
22 +```
23 +1. GET /api/challenge/list/:status
24 +- 챌린지 목록 조회
25 +- input(parameter)
26 +```
27 +status=(one of ["all","enrolled","progress","end"])
28 +```
29 +1. POST /api/challenge/participate
30 +- 챌린지 참가
31 +- input(body)
32 +```javascript
33 +{
34 + "username":String,
35 + "challengeName":String
36 +}
37 +```
...\ No newline at end of file ...\ No newline at end of file
...@@ -13,14 +13,12 @@ const Joi = require("joi"); ...@@ -13,14 +13,12 @@ const Joi = require("joi");
13 exports.getChallenge = async (ctx) => { 13 exports.getChallenge = async (ctx) => {
14 try { 14 try {
15 const { challengeName } = ctx.request.body; 15 const { challengeName } = ctx.request.body;
16 - const challenge = await Challenge.findByChallengeName(challengeName).select( 16 + const challenge = await Challenge.findByChallengeName(challengeName);
17 - "-_id"
18 - );
19 if (!challenge) { 17 if (!challenge) {
20 ctx.status = 401; 18 ctx.status = 401;
21 return; 19 return;
22 } 20 }
23 - ctx.body = challenge; 21 + ctx.body = challenge.serialize();
24 } catch (e) { 22 } catch (e) {
25 ctx.throw(500, e); 23 ctx.throw(500, e);
26 } 24 }
...@@ -60,9 +58,7 @@ exports.addChallenge = async (ctx) => { ...@@ -60,9 +58,7 @@ exports.addChallenge = async (ctx) => {
60 } = ctx.request.body; 58 } = ctx.request.body;
61 59
62 try { 60 try {
63 - const isChallengeExist = await Challenge.findByChallengeName( 61 + const isChallengeExist = await Challenge.findByChallengeName(challengeName);
64 - challengeName
65 - ).select("-_id");
66 62
67 if (isChallengeExist) { 63 if (isChallengeExist) {
68 ctx.status = 409; 64 ctx.status = 409;
...@@ -122,26 +118,24 @@ exports.addChallenge = async (ctx) => { ...@@ -122,26 +118,24 @@ exports.addChallenge = async (ctx) => {
122 s_date = new Date(e_date); 118 s_date = new Date(e_date);
123 s_date.setMinutes(s_date.getMinutes() + 1); 119 s_date.setMinutes(s_date.getMinutes() + 1);
124 } 120 }
125 - ctx.body = challenge; 121 + ctx.body = challenge.serialize();
126 } catch (e) { 122 } catch (e) {
127 ctx.throw(500, e); 123 ctx.throw(500, e);
128 } 124 }
129 }; 125 };
130 126
131 -/* GET /api/challenge/list?status 127 +/* GET /api/challenge/list/:status
132 -query string status can be in ['all','enrolled','progress','end'] 128 +parameter status can be in ['all','enrolled','progress','end']
133 */ 129 */
134 exports.list = async (ctx) => { 130 exports.list = async (ctx) => {
135 try { 131 try {
136 - const status = ctx.query.status; 132 + const status = ctx.params.status;
137 if (status !== "all") { 133 if (status !== "all") {
138 - const challenges = await Challenge.find({ status: status }).select( 134 + const challenges = await Challenge.find({ status: status });
139 - "-_id" 135 + ctx.body = challenges.serialize();
140 - );
141 - ctx.body = challenges;
142 } else { 136 } else {
143 - const challenges = await Challenge.find({}).select("-_id"); 137 + const challenges = await Challenge.find({});
144 - ctx.body = challenges; 138 + ctx.body = challenges.serialize();
145 } 139 }
146 } catch (e) { 140 } catch (e) {
147 ctx.throw(500, e); 141 ctx.throw(500, e);
...@@ -168,6 +162,7 @@ exports.participate = async (ctx) => { ...@@ -168,6 +162,7 @@ exports.participate = async (ctx) => {
168 const user = await User.findByUsername(username); 162 const user = await User.findByUsername(username);
169 const user_id = user._id; 163 const user_id = user._id;
170 const newGroup = new Group({ 164 const newGroup = new Group({
165 + groupName: `${user.username}${challengeName} 그룹`,
171 members: [user_id], 166 members: [user_id],
172 }); 167 });
173 let newGroup_id = ""; 168 let newGroup_id = "";
...@@ -184,6 +179,7 @@ exports.participate = async (ctx) => { ...@@ -184,6 +179,7 @@ exports.participate = async (ctx) => {
184 problems: [], 179 problems: [],
185 }); 180 });
186 await newParticipation.save(); 181 await newParticipation.save();
182 + ctx.body = newParticipation.serialize();
187 }); 183 });
188 }); 184 });
189 } catch (e) { 185 } catch (e) {
......
...@@ -4,7 +4,7 @@ const challengeCtrl = require('./challege.ctrl'); ...@@ -4,7 +4,7 @@ const challengeCtrl = require('./challege.ctrl');
4 4
5 challenge.post("/getchallenge",challengeCtrl.getChallenge); 5 challenge.post("/getchallenge",challengeCtrl.getChallenge);
6 challenge.post("/addchallenge",challengeCtrl.addChallenge); 6 challenge.post("/addchallenge",challengeCtrl.addChallenge);
7 -challenge.get("/list",challengeCtrl.list); 7 +challenge.get("/list/:status",challengeCtrl.list);
8 challenge.post("/participate",challengeCtrl.participate); 8 challenge.post("/participate",challengeCtrl.participate);
9 9
10 module.exports = challenge; 10 module.exports = challenge;
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -7,6 +7,7 @@ const notify = require("./notify"); ...@@ -7,6 +7,7 @@ const notify = require("./notify");
7 const user = require("./user"); 7 const user = require("./user");
8 const profile = require("./profile"); 8 const profile = require("./profile");
9 const challenge = require("./challenge"); 9 const challenge = require("./challenge");
10 +const session = require("./session");
10 11
11 api.use("/auth", auth.routes()); 12 api.use("/auth", auth.routes());
12 api.use("/friend", friend.routes()); 13 api.use("/friend", friend.routes());
...@@ -14,5 +15,6 @@ api.use("/notify", notify.routes()); ...@@ -14,5 +15,6 @@ api.use("/notify", notify.routes());
14 api.use("/user", user.routes()); 15 api.use("/user", user.routes());
15 api.use("/profile", profile.routes()); 16 api.use("/profile", profile.routes());
16 api.use("/challenge",challenge.routes()); 17 api.use("/challenge",challenge.routes());
18 +api.use("/session",session.routes());
17 19
18 module.exports = api; 20 module.exports = api;
......
...@@ -30,7 +30,7 @@ exports.getProfile = async (ctx) => { ...@@ -30,7 +30,7 @@ exports.getProfile = async (ctx) => {
30 ctx.status = 401; 30 ctx.status = 401;
31 return; 31 return;
32 } 32 }
33 - ctx.body = profile; 33 + ctx.body = profile.serialize();
34 } catch (e) { 34 } catch (e) {
35 ctx.throw(500, e); 35 ctx.throw(500, e);
36 } 36 }
...@@ -71,7 +71,7 @@ exports.setProfile = async (ctx) => { ...@@ -71,7 +71,7 @@ exports.setProfile = async (ctx) => {
71 ctx.status = 404; 71 ctx.status = 404;
72 return; 72 return;
73 } 73 }
74 - ctx.body = profile; 74 + ctx.body = profile.serialize();
75 } catch (e) { 75 } catch (e) {
76 ctx.throw(500, e); 76 ctx.throw(500, e);
77 } 77 }
...@@ -104,7 +104,7 @@ exports.syncBJ = async function (ctx) { ...@@ -104,7 +104,7 @@ exports.syncBJ = async function (ctx) {
104 { solvedBJ: BJdata, solvedBJ_date: BJdata_date }, 104 { solvedBJ: BJdata, solvedBJ_date: BJdata_date },
105 { new: true } 105 { new: true }
106 ).exec(); 106 ).exec();
107 - ctx.body = updateprofile; 107 + ctx.body = updateprofile.serialize();
108 } catch (e) { 108 } catch (e) {
109 ctx.throw(500, e); 109 ctx.throw(500, e);
110 } 110 }
......
1 +const Router = require('koa-router');
2 +const session = new Router();
3 +const sessionCtrl = require('./session.ctrl');
4 +
5 +session.post("/createproblem/:how",sessionCtrl.createProblem);
6 +
7 +module.exports = session;
...\ No newline at end of file ...\ No newline at end of file
1 +/* POST /api/session/createproblem/:how
2 +{
3 + problemList:[Number]
4 +}
5 +*/
6 +exports.createProblem = async (ctx)=>{
7 + try{
8 + const how=ctx.params.how;
9 + if(how==='self'){
10 +
11 + }
12 + else if(how==='recommend'){
13 +
14 + }
15 + }
16 + catch(e){
17 + ctx.throw(500,e);
18 + }
19 +};
...\ No newline at end of file ...\ No newline at end of file
...@@ -42,7 +42,9 @@ ChallengeSchema.methods.getStatus=function(){ ...@@ -42,7 +42,9 @@ ChallengeSchema.methods.getStatus=function(){
42 } 42 }
43 43
44 ChallengeSchema.methods.serialize=function(){ 44 ChallengeSchema.methods.serialize=function(){
45 - return this.toJSON(); 45 + let challengeJSON = this.toJSON();
46 + delete challengeJSON._id;
47 + return challengeJSON;
46 } 48 }
47 49
48 const Challenge = mongoose.model('Challenge', ChallengeSchema); 50 const Challenge = mongoose.model('Challenge', ChallengeSchema);
......
...@@ -3,12 +3,17 @@ const mongoose = require("mongoose"); ...@@ -3,12 +3,17 @@ const mongoose = require("mongoose");
3 const { Schema } = mongoose; 3 const { Schema } = mongoose;
4 4
5 const GroupSchema = new Schema({ 5 const GroupSchema = new Schema({
6 + groupName: { type: String },
6 members: [{ type: Schema.Types.ObjectId, ref: 'User' }] 7 members: [{ type: Schema.Types.ObjectId, ref: 'User' }]
7 },{ 8 },{
8 collection: 'group' 9 collection: 'group'
9 }); 10 });
10 11
11 -GroupSchema.methods.addGroupMemeber=function(user){ 12 +GroupSchema.statics.findByGroupName=function(groupName){
13 + return this.find({groupName:groupName});
14 +}
15 +
16 +GroupSchema.methods.addGroupMember=function(user){
12 this.members.push(user._id); 17 this.members.push(user._id);
13 return this.save(); 18 return this.save();
14 } 19 }
...@@ -18,7 +23,9 @@ GroupSchema.methods.getMembers=function(){ ...@@ -18,7 +23,9 @@ GroupSchema.methods.getMembers=function(){
18 } 23 }
19 24
20 GroupSchema.methods.serialize=function(){ 25 GroupSchema.methods.serialize=function(){
21 - return this.toJSON(); 26 + let groupJSON=this.toJSON();
27 + delete groupJSON._id;
28 + return groupJSON;
22 } 29 }
23 30
24 const Group = mongoose.model('Group',GroupSchema); 31 const Group = mongoose.model('Group',GroupSchema);
......
...@@ -29,5 +29,11 @@ ParticipationSchema.methods.addProblem=function(problem){ ...@@ -29,5 +29,11 @@ ParticipationSchema.methods.addProblem=function(problem){
29 this.problems.push({problemNum:problem.problemNum,isSolved:problem.isSolved}); 29 this.problems.push({problemNum:problem.problemNum,isSolved:problem.isSolved});
30 } 30 }
31 31
32 +ParticipationSchema.methods.serialize=function(){
33 + let participationJSON=this.toJSON();
34 + delete participationJSON._id;
35 + return participationJSON;
36 +}
37 +
32 const Participation = mongoose.model('Participation', ParticipationSchema); 38 const Participation = mongoose.model('Participation', ParticipationSchema);
33 module.exports = Participation; 39 module.exports = Participation;
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -58,7 +58,9 @@ ProblemSchema.methods.getCategory=function(){ ...@@ -58,7 +58,9 @@ ProblemSchema.methods.getCategory=function(){
58 } 58 }
59 59
60 ProblemSchema.methods.serialize=function(){ 60 ProblemSchema.methods.serialize=function(){
61 - return this.toJSON(); 61 + let problemJSON=this.toJSON();
62 + delete problemJSON._id;
63 + return problemJSON;
62 } 64 }
63 65
64 const Problem = mongoose.model('Problem',ProblemSchema); 66 const Problem = mongoose.model('Problem',ProblemSchema);
......
...@@ -28,7 +28,9 @@ SessionSchema.methods.getStatus=function(){ ...@@ -28,7 +28,9 @@ SessionSchema.methods.getStatus=function(){
28 } 28 }
29 29
30 SessionSchema.methods.serialize=function(){ 30 SessionSchema.methods.serialize=function(){
31 - return this.toJSON(); 31 + let sessionJSON=this.toJSON();
32 + delete sessionJSON._id;
33 + return sessionJSON;
32 } 34 }
33 35
34 const Session = mongoose.model('Session', SessionSchema); 36 const Session = mongoose.model('Session', SessionSchema);
......
...@@ -38,13 +38,14 @@ UserSchema.methods.checkPassword = async function (password) { ...@@ -38,13 +38,14 @@ UserSchema.methods.checkPassword = async function (password) {
38 UserSchema.methods.serialize = function () { 38 UserSchema.methods.serialize = function () {
39 const data = this.toJSON(); 39 const data = this.toJSON();
40 delete data.hashedPassword; 40 delete data.hashedPassword;
41 + delete data._id;
41 return data; 42 return data;
42 }; 43 };
43 44
44 UserSchema.methods.generateToken = function () { 45 UserSchema.methods.generateToken = function () {
45 const token = jwt.sign( 46 const token = jwt.sign(
46 { 47 {
47 - _id: this.id, 48 + _id: this._id,
48 username: this.username, 49 username: this.username,
49 }, 50 },
50 process.env.JWT_SECRET, 51 process.env.JWT_SECRET,
......