Commit fcd3766a authored by rlacko's avatar rlacko 💬
Browse files

Solution endpoint

parent a8424c6e
Pipeline #4668 passed with stages
in 1 minute and 30 seconds
......@@ -6,6 +6,8 @@ const pickedKeys = ['_id', 'activity', 'user', 'state', 'comment']
exports.default = crudControllers(Attendance, pickedKeys)
// On create update activity
exports.default.getOne = async (req, res) => {
try {
const attendance = await Attendance.findOne({ _id: req.params.id })
......
......@@ -95,6 +95,7 @@ exports.default.updateOne = async (req, res) => {
}
}
// TODO on delete remove from other models
exports.default.removeOne = async (req, res) => {
try {
const comment = await Comment.findById({ _id: req.params.id })
......
const { crudControllers } = require('../../utils/crud')
const { Solution } = require('./solutionModel')
const { Task } = require('../task/taskModel')
const { pick } = require('lodash')
exports.default = crudControllers(Solution)
exports.default.createOne = async (req, res) => {
try {
let solution = await Solution.create({
title: req.body.title,
description: req.body.description,
file: req.body.file,
user: req.user._id,
isAccept: false,
})
const task = await Task.findById(req.body.task)
let solution
if (req.user.role === 'mentor' && req.body.creator) {
// Mentor Creates/Updates a Solution to someone
solution = await Solution.findOneAndUpdate(
{ creator: req.body.creator, task: req.body.task },
{ ...req.body },
{
upsert: true, // Create new One if there is no match
returnOriginal: false,
setDefaultsOnInsert: true,
runValidators: true,
}
)
.lean()
.exec()
} else {
// Someone creates a solution
if (req.user.role != 'mentor') {
delete req.body.isAccepted
delete req.body.comment
}
if (task.deadline < new Date())
return res.status(400).json({
message: `Can't create new Solution! End date was ${task.deadline.toDateString()}`,
})
solution = await Solution.findOneAndUpdate(
{ creator: req.user.schacc, task: req.body.task },
{ ...req.body },
{
upsert: true, // Create new One if there is no match
returnOriginal: false,
setDefaultsOnInsert: true,
runValidators: true,
}
)
.lean()
.exec()
}
if (task.solutions.indexOf(solution._id) == -1) {
task.solutions.push(solution._id)
task.save()
}
let retSolution = await Solution.findById({ _id: solution._id })
.populate('user', '-_id fullName nickName')
.populate('comment', '-_id text creator createdAt')
.populate({
path: 'comment',
populate: { path: 'creator', select: '-_id fullName nickName' },
})
.populate('_creator', '-_id fullName nickName schacc')
.populate('comment', 'text creator createdAt')
.lean()
.exec()
return res.status(200).json({ data: retSolution })
retSolution.creator = retSolution._creator
return res.status(200).json({
data: pick(retSolution, [
'_id',
'creator',
'title',
'description',
'file',
'task',
'comment',
'createdAt',
'updatedAt',
'isAccepted',
]),
})
} catch (err) {
if (err.name == 'ValidationError') {
// Throwed by Mongoose
let messages = []
for (field in err.errors) {
messages.push(err.errors[field].message)
}
return res.status(422).json({ messages })
}
console.error(err)
return res.status(500).json({ message: err.message })
}
}
......@@ -33,33 +91,48 @@ exports.default.getMany = async (req, res) => {
try {
let solutions = undefined
if (req.user.role === 'mentor') {
if (req.user.role === 'mentor')
solutions = await Solution.find()
.populate('user', '-_id fullName nickName')
.populate('comment', '-_id text creator createdAt')
.populate({
path: 'comment',
populate: { path: 'creator', select: '-_id fullName nickName' },
})
.select('-_id -__v')
.populate('_creator', '-_id fullName nickName schacc')
.populate('comment', 'text creator createdAt')
.select('-__v')
.lean()
.exec()
}
if (req.user.role === 'normal') {
else
solutions = await Solution.find({ user: req.user._id })
.populate('user', '-_id fullName nickName')
.populate('_creator', '-_id fullName nickName')
.populate('comment', '-_id text creator createdAt')
.populate({
path: 'comment',
populate: { path: 'creator', select: '-_id fullName nickName' },
})
.select('-_id -__v')
.select('-__v')
.lean()
.exec()
return res.status(200).json({ data: solutions }).end()
}
return res.status(200).json({
data: solutions.map((e) => {
e.creator = e._creator
return pick(e, [
'_id',
'creator',
'title',
'description',
'file',
'task',
'comment',
'createdAt',
'updatedAt',
'isAccepted',
])
}),
})
} catch (err) {
if (err.name == 'ValidationError') {
// Throwed by Mongoose
let messages = []
for (field in err.errors) {
messages.push(err.errors[field].message)
}
return res.status(422).json({ messages })
}
console.error(err)
return res.status(500).json({ message: err.message })
}
}
......@@ -67,49 +140,49 @@ exports.default.getMany = async (req, res) => {
exports.default.getOne = async (req, res) => {
try {
let solution = await Solution.findById({ _id: req.params.id })
.populate('user', '_id fullName nickName')
.select('-_id -__v')
.populate('_creator', '-_id fullName nickName')
.populate('comment', 'text creator createdAt')
.select('-__v')
.lean()
.exec()
if (req.user._id !== solution.user._id && req.user.role !== 'mentor') {
if (!solution)
return res.status(404).json({ messages: ['No such solution.'] })
if (req.user.schacc !== solution.creator && req.user.role !== 'mentor') {
return res
.status(403)
.json({ message: `You don't have permission for this solution.` })
}
return res.status(200).json({ data: solution })
return res.status(200).json({
data: pick(solution, [
'_id',
'creator',
'title',
'description',
'file',
'task',
'comment',
'createdAt',
'updatedAt',
'isAccepted',
]),
})
} catch (err) {
if (err.name == 'ValidationError') {
// Throwed by Mongoose
let messages = []
for (field in err.errors) {
messages.push(err.errors[field].message)
}
return res.status(422).json({ messages })
}
console.error(err)
return res.status(500).json({ message: err.message })
}
}
exports.default.removeOne = async (req, res) => {
exports.default.notSupported = async (req, res) => {
res.status(404).json({ data: { message: 'Not supported operation!' } })
}
exports.default.updateOne = async (req, res) => {
try {
let solution = await Solution.findById(req.params.id)
.populate('user')
.lean()
.exec()
if (solution.user._id !== req.user._id && req.user.role !== 'mentor') {
return res
.status(403)
.json({ message: 'This is not one of your solution.' })
}
let newSolution = await Solution.findOneAndUpdate(
{ _id: req.params.id },
{ file: req.body.file },
{ new: true }
)
.lean()
.exec()
return res.status(200).json({ data: newSolution })
} catch (err) {
return res.status(500).json({ message: err.message })
}
}
......@@ -2,6 +2,11 @@ const mongoose = require('mongoose')
const SolutionSchema = new mongoose.Schema(
{
task: {
type: mongoose.Schema.Types.ObjectId,
ref: 'task',
required: true,
},
title: {
type: String,
required: true,
......@@ -14,9 +19,8 @@ const SolutionSchema = new mongoose.Schema(
type: String,
required: true,
},
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user',
creator: {
type: String,
required: true,
},
comment: [
......@@ -28,13 +32,19 @@ const SolutionSchema = new mongoose.Schema(
],
isAccepted: {
type: Boolean,
required: true,
default: false,
},
},
{ timestamps: true }
)
// Careful with the docs, there are some deprecated ones
// https://mongoosejs.com/docs/guide.html
SolutionSchema.virtual('_creator', {
ref: 'user',
localField: 'creator',
foreignField: 'schacc',
justOne: true,
})
const Solution = mongoose.model('solution', SolutionSchema)
......
const { Router } = require('express')
const controllers = require('./solutionControllers')
const { isLoggedIn, isAcceptedOrMentor } = require('../../middlewares/auth')
const router = Router()
// /api/item
router
.route('/')
.get(controllers.default.getMany)
.post(controllers.default.createOne)
.get(isLoggedIn, isAcceptedOrMentor, controllers.default.getMany)
.post(isLoggedIn, isAcceptedOrMentor, controllers.default.createOne)
// /api/item/:id
router
.route('/:id')
.get(controllers.default.getOne)
.put(controllers.default.updateOne)
.delete(controllers.default.removeOne)
.get(isLoggedIn, isAcceptedOrMentor, controllers.default.getOne)
.delete(isLoggedIn, isAcceptedOrMentor, controllers.default.notSupported)
.put(isLoggedIn, isAcceptedOrMentor, controllers.default.notSupported)
exports.default = router
......@@ -32,6 +32,7 @@ exports.default.getOne = async (req, res) => {
'createData',
'bit',
'creator',
'solutions',
]),
})
} else {
......@@ -69,6 +70,7 @@ exports.default.getMany = async (req, res) => {
'createData',
'bit',
'creator',
'solutions',
])
}),
})
......@@ -87,6 +89,7 @@ exports.default.createOne = async (req, res) => {
'createData',
'bit',
'creator',
'solutions',
])
)
res.status(201).json({
......@@ -98,6 +101,7 @@ exports.default.createOne = async (req, res) => {
'createData',
'bit',
'creator',
'solutions',
]),
})
} catch (err) {
......
......@@ -25,6 +25,13 @@ const TaskSchema = new mongoose.Schema(
creator: {
type: String,
},
solutions: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'solution',
required: true,
},
],
},
{ timestamps: true }
)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment