송용우

Merge branch 'develop' into feature/frontend_page

......@@ -28,16 +28,19 @@ POST http://facerain.dcom.club/profile/getprofile
| group | description | method | URL | Detail | Auth |
| --------- | -------------------------------------- | ------ | -------------------------- | -------------------------------------- | --------- |
| profile | 유저가 푼 문제 조회(백준) | GET | api/profile/solvedBJ:id | [바로가기](/src/api/profile/README.md) | None |
| profile | 유저가 푼 문제 동기화(백준) | PATCH | api/profile/syncBJ | [바로가기](/src/api/profile/README.md) | None |
| profile | 유저 정보 수정 | POST | api/profile/setprofile | [바로가기](/src/api/profile/README.md) | JWT TOKEN |
| profile | 유저 정보 받아오기 | POST | api/profile/getprofile | [바로가기](/src/api/profile/README.md) | JWT |
| profile | 추천 문제 조회 | POST | api/profile/recommend | [바로가기](/src/api/profile/README.md) | None |
| profile | 친구 추가 | POST | /api/profile/addfriend | [바로가기](/src/api/profile/README.md) | JWT TOKEN |
| notify | 슬랙 메시지 전송 요청 (목표 성취 여부) | POST | api/notify/goal | [바로가기](/src/api/notify/README.md) | Jwt Token |
| notify | 슬랙 메시지 전송 요청 (문제 추천) | POST | api/notify/recommend | [바로가기](/src/api/notify/README.md) | None |
| auth | 로그인 | POST | api/auth/login | [바로가기](/src/api/auth/README.md) | None |
| auth | 로그아웃 | POST | api/auth/logout | [바로가기](/src/api/auth/README.md) | JWT Token |
| auth | 회원가입 | POST | api/auth/register | [바로가기](/src/api/auth/README.md) | None |
| auth | 로그인 확인 | GET | api/auth/check | [바로가기](/src/api/auth/README.md) | None |
| challenge | 특정 챌린지 조회(이름) | POST | api/challenge/getChallenge | [바로가기]() | None |
| profile | 유저가 푼 문제 조회(백준) | GET | api/profile/solvedBJ:id | [바로가기](/src/api/profile/README.md) | None |
| profile | 유저가 푼 문제 동기화(백준) | PATCH | api/profile/syncBJ | [바로가기](/src/api/profile/README.md) | None |
| profile | 유저 정보 수정 | POST | api/profile/setprofile | [바로가기](/src/api/profile/README.md) | JWT |
| profile | 유저 정보 받아오기 | POST | api/profile/getprofile | [바로가기](/src/api/profile/README.md) | JWT |
| profile | 추천 문제 조회 | POST | api/profile/recommend | [바로가기](/src/api/profile/README.md) | None |
| profile | 친구 추가 | POST | api/profile/addfriend | [바로가기](/src/api/profile/README.md) | JWT |
| notify | 슬랙 메시지 전송 요청 (목표 성취 여부) | POST | api/notify/goal | [바로가기](/src/api/notify/README.md) | JWT |
| notify | 슬랙 메시지 전송 요청 (문제 추천) | POST | api/notify/recommend | [바로가기](/src/api/notify/README.md) | None |
| auth | 로그인 | POST | api/auth/login | [바로가기](/src/api/auth/README.md) | None |
| auth | 로그아웃 | POST | api/auth/logout | [바로가기](/src/api/auth/README.md) | JWT |
| auth | 회원가입 | POST | api/auth/register | [바로가기](/src/api/auth/README.md) | None |
| auth | 로그인 확인 | GET | api/auth/check | [바로가기](/src/api/auth/README.md) | None |
| challenge | 특정 챌린지 조회(이름) | POST | api/challenge/getChallenge | [바로가기](/src/api/challenge/README.md)| None |
| challenge | 챌린지 추가 | POST | api/challenge/addChallenge | [바로가기](/src/api/challenge/README.md) | None |
| challenge | 챌린지 목록 조회 | GET | api/challenge/list | [바로가기](/src/api/challenge/README.md) | None |
| challenge | 챌린지 참가 | POST | api/challenge/participate | [바로가기](/src/api/challenge/README.md) | None |
\ No newline at end of file
......
# API Documentation - Challenge
1. POST /api/challenge/getChallenge
- 챌린지 상세 정보 조회
- input(body)
```javascript
{
"challengeName": String
}
```
1. POST /api/challenge/addChallenge
- 챌린지 추가
- input(body)
```javascript
{
"challengeName":String,
"startDate":Date,
"endDate":Date,
"durationPerSession": String, // "1d"=1 day, "2w"=2 weeks, "3m"=3 months
"goalPerSession":Number
}
```
1. GET /api/challenge/list/:status
- 챌린지 목록 조회
- input(parameter)
```
status=(one of ["all","enrolled","progress","end"])
```
1. POST /api/challenge/participate
- 챌린지 참가
- input(body)
```javascript
{
"username":String,
"challengeName":String
}
```
\ No newline at end of file
......@@ -13,14 +13,12 @@ const Joi = require("joi");
exports.getChallenge = async (ctx) => {
try {
const { challengeName } = ctx.request.body;
const challenge = await Challenge.findByChallengeName(challengeName).select(
"-_id"
);
const challenge = await Challenge.findByChallengeName(challengeName);
if (!challenge) {
ctx.status = 401;
return;
}
ctx.body = challenge;
ctx.body = challenge.serialize();
} catch (e) {
ctx.throw(500, e);
}
......@@ -60,9 +58,7 @@ exports.addChallenge = async (ctx) => {
} = ctx.request.body;
try {
const isChallengeExist = await Challenge.findByChallengeName(
challengeName
).select("-_id");
const isChallengeExist = await Challenge.findByChallengeName(challengeName);
if (isChallengeExist) {
ctx.status = 409;
......@@ -122,26 +118,24 @@ exports.addChallenge = async (ctx) => {
s_date = new Date(e_date);
s_date.setMinutes(s_date.getMinutes() + 1);
}
ctx.body = challenge;
ctx.body = challenge.serialize();
} catch (e) {
ctx.throw(500, e);
}
};
/* GET /api/challenge/list?status
query string status can be in ['all','enrolled','progress','end']
/* GET /api/challenge/list/:status
parameter status can be in ['all','enrolled','progress','end']
*/
exports.list = async (ctx) => {
try {
const status = ctx.query.status;
const status = ctx.params.status;
if (status !== "all") {
const challenges = await Challenge.find({ status: status }).select(
"-_id"
);
ctx.body = challenges;
const challenges = await Challenge.find({ status: status });
ctx.body = challenges.serialize();
} else {
const challenges = await Challenge.find({}).select("-_id");
ctx.body = challenges;
const challenges = await Challenge.find({});
ctx.body = challenges.serialize();
}
} catch (e) {
ctx.throw(500, e);
......@@ -168,6 +162,7 @@ exports.participate = async (ctx) => {
const user = await User.findByUsername(username);
const user_id = user._id;
const newGroup = new Group({
groupName: `${user.username}${challengeName} 그룹`,
members: [user_id],
});
let newGroup_id = "";
......@@ -184,6 +179,7 @@ exports.participate = async (ctx) => {
problems: [],
});
await newParticipation.save();
ctx.body = newParticipation.serialize();
});
});
} catch (e) {
......
......@@ -4,7 +4,7 @@ const challengeCtrl = require('./challege.ctrl');
challenge.post("/getchallenge",challengeCtrl.getChallenge);
challenge.post("/addchallenge",challengeCtrl.addChallenge);
challenge.get("/list",challengeCtrl.list);
challenge.get("/list/:status",challengeCtrl.list);
challenge.post("/participate",challengeCtrl.participate);
module.exports = challenge;
\ No newline at end of file
......
......@@ -7,6 +7,7 @@ const notify = require("./notify");
const user = require("./user");
const profile = require("./profile");
const challenge = require("./challenge");
const session = require("./session");
api.use("/auth", auth.routes());
api.use("/friend", friend.routes());
......@@ -14,5 +15,6 @@ api.use("/notify", notify.routes());
api.use("/user", user.routes());
api.use("/profile", profile.routes());
api.use("/challenge",challenge.routes());
api.use("/session",session.routes());
module.exports = api;
......
......@@ -30,7 +30,7 @@ exports.getProfile = async (ctx) => {
ctx.status = 401;
return;
}
ctx.body = profile;
ctx.body = profile.serialize();
} catch (e) {
ctx.throw(500, e);
}
......@@ -71,7 +71,7 @@ exports.setProfile = async (ctx) => {
ctx.status = 404;
return;
}
ctx.body = profile;
ctx.body = profile.serialize();
} catch (e) {
ctx.throw(500, e);
}
......@@ -104,7 +104,7 @@ exports.syncBJ = async function (ctx) {
{ solvedBJ: BJdata, solvedBJ_date: BJdata_date },
{ new: true }
).exec();
ctx.body = updateprofile;
ctx.body = updateprofile.serialize();
} catch (e) {
ctx.throw(500, e);
}
......
const Router = require('koa-router');
const session = new Router();
const sessionCtrl = require('./session.ctrl');
session.post("/createproblem/:how",sessionCtrl.createProblem);
module.exports = session;
\ No newline at end of file
/* POST /api/session/createproblem/:how
{
problemList:[Number]
}
*/
exports.createProblem = async (ctx)=>{
try{
const how=ctx.params.how;
if(how==='self'){
}
else if(how==='recommend'){
}
}
catch(e){
ctx.throw(500,e);
}
};
\ No newline at end of file
......@@ -42,7 +42,9 @@ ChallengeSchema.methods.getStatus=function(){
}
ChallengeSchema.methods.serialize=function(){
return this.toJSON();
let challengeJSON = this.toJSON();
delete challengeJSON._id;
return challengeJSON;
}
const Challenge = mongoose.model('Challenge', ChallengeSchema);
......
......@@ -3,12 +3,17 @@ const mongoose = require("mongoose");
const { Schema } = mongoose;
const GroupSchema = new Schema({
groupName: { type: String },
members: [{ type: Schema.Types.ObjectId, ref: 'User' }]
},{
collection: 'group'
});
GroupSchema.methods.addGroupMemeber=function(user){
GroupSchema.statics.findByGroupName=function(groupName){
return this.find({groupName:groupName});
}
GroupSchema.methods.addGroupMember=function(user){
this.members.push(user._id);
return this.save();
}
......@@ -18,7 +23,9 @@ GroupSchema.methods.getMembers=function(){
}
GroupSchema.methods.serialize=function(){
return this.toJSON();
let groupJSON=this.toJSON();
delete groupJSON._id;
return groupJSON;
}
const Group = mongoose.model('Group',GroupSchema);
......
......@@ -29,5 +29,11 @@ ParticipationSchema.methods.addProblem=function(problem){
this.problems.push({problemNum:problem.problemNum,isSolved:problem.isSolved});
}
ParticipationSchema.methods.serialize=function(){
let participationJSON=this.toJSON();
delete participationJSON._id;
return participationJSON;
}
const Participation = mongoose.model('Participation', ParticipationSchema);
module.exports = Participation;
\ No newline at end of file
......
......@@ -58,7 +58,9 @@ ProblemSchema.methods.getCategory=function(){
}
ProblemSchema.methods.serialize=function(){
return this.toJSON();
let problemJSON=this.toJSON();
delete problemJSON._id;
return problemJSON;
}
const Problem = mongoose.model('Problem',ProblemSchema);
......
......@@ -28,7 +28,9 @@ SessionSchema.methods.getStatus=function(){
}
SessionSchema.methods.serialize=function(){
return this.toJSON();
let sessionJSON=this.toJSON();
delete sessionJSON._id;
return sessionJSON;
}
const Session = mongoose.model('Session', SessionSchema);
......
......@@ -38,13 +38,14 @@ UserSchema.methods.checkPassword = async function (password) {
UserSchema.methods.serialize = function () {
const data = this.toJSON();
delete data.hashedPassword;
delete data._id;
return data;
};
UserSchema.methods.generateToken = function () {
const token = jwt.sign(
{
_id: this.id,
_id: this._id,
username: this.username,
},
process.env.JWT_SECRET,
......