## Models
*sffs*
```jsx
const mongoose = require("mongoose")
const Schema = mongoose.Schema
const taskSchema = Schema({
name: { type: String, require: true },
description: { type: String, require: true },
tag: {
important: { type: Boolean, require: true, default: false },
urgent: { type: Boolean, require: true, default: false }
},
status: {
type: String,
enum: ["pending", "working", "review", "done", "archive"],
default: "pending"
},
assigner: { type: mongoose.ObjectId, ref: "User", require: true },
assignee: [{ type: mongoose.ObjectId, ref: "User", require: true }],
reviewDueAt: { type: Date, require: true },
reviewAt: [{ type: Date }],
doneDueAt: { type: Date, require: true },
doneAt: { type: Date },
isDeleted: { type: Boolean, require: true, default: false }
}, {
timestamps: true
})
const Task = mongoose.model("Task", taskSchema)
module.exports = Task
```
```jsx
const mongoose = require("mongoose")
const Schema = mongoose.Schema
const userSchema = Schema({
name: { type: String, require: true },
role: { type: String, enum: ["assigner", "assignee"], require: true, default: "assignee" },
isDeleted: { type: Boolean, require: true, default: false }
}, {
timestamps: true
})
const User = mongoose.model("User", userSchema)
module.exports = User
```
## Task controller
```jsx
const Task = require("../model/Task");
const User = require("../model/User");
const taskController = {}
taskController.getTasks = async (req, res, next) => {
try {
const assignerId = req.headers.authorization
if (!assignerId) {
const exception = new Error("Login required")
exception.statusCode = 401
throw exception
}
const tasks = await Task.find({ isDeleted: false })
res.status(200).send(tasks);
} catch (error) {
next(error)
}
}
taskController.getTaskById = async (req, res, next) => {
try {
const taskId = req.params.id
const userId = req.headers.authorization
if (!userId) {
const exception = new Error("Login required")
exception.statusCode = 401
throw exception
}
const task = await Task.findById(taskId)
res.status(200).send(task);
} catch (error) {
next(error)
}
}
taskController.createTask = async (req, res, next) => {
try {
const assignerId = req.headers.authorization
const { name, description, tag, status, assignee, reviewDueAt, doneDueAt } = req.body
if (!assignerId) {
const exception = new Error("Login required")
exception.statusCode = 401
throw exception
}
const assigner = await User.findById(assignerId)
if (assigner.role !== "assigner") {
const exception = new Error("Only assigner can assign task.")
exception.statusCode = 401
throw exception
}
if (!name || !description || !assignee || !reviewDueAt || !doneDueAt) {
const exception = new Error("Missing information")
exception.statusCode = 404
throw exception
}
await Task.create({
name,
description,
tag,
status,
assignee,
assigner: assignerId,
reviewDueAt,
doneDueAt
})
res.status(200).send({ message: "New task created" });
} catch (err) {
next(err)
}
}
taskController.updateTask = async (req, res, next) => {
try {
const taskId = req.params.id
const userId = req.headers.authorization
let { name, description, tag, status, assignee, assigner, reviewDueAt, doneDueAt } = req.body
if (!userId) {
const exception = new Error("Login required")
exception.statusCode = 401
throw exception
}
let task = await Task.findById(taskId)
if (!task) {
const exception = new Error("Task not found")
exception.statusCode = 404
throw exception
}
const user = await User.findById(userId)
console.log("first", task.assignee.includes(mongoose.Types.ObjectId(userId)))
if (user.role !== "assigner" & !task.assignee.includes(mongoose.Types.ObjectId(userId))) {
const exception = new Error("Can't change status of task that is not yours")
exception.statusCode = 401
throw exception
}
switch (user.role) {
case "assigner":
if (task.status === "archive") {
console.log("here")
const exception = new Error("Can't touch archived tasks")
exception.statusCode = 401
throw exception
}
break;
default: //assignee
if (task.status === "done" || task.status === "archive"
|| status === "done" || status === "archive") {
const exception = new Error("Can't touch the task at this status")
exception.statusCode = 401
throw exception
}
break;
}
if (!name || !description || !assignee?.length || !reviewDueAt || !doneDueAt) {
const exception = new Error("Missing information")
exception.statusCode = 404
throw exception
}
let reviewAt
const basicTask = {
name,
description,
tag,
status,
assignee,
assigner,
reviewDueAt,
doneDueAt,
}
switch (status) {
case "review":
task = await Task.findByIdAndUpdate(taskId, {
...basicTask,
$push: { reviewAt: Date.now() }
}, { new: true })
break;
case "done":
task = await Task.findByIdAndUpdate(taskId, {
...basicTask,
doneAt: Date.now()
}, { new: true })
break;
default:
task = await Task.findByIdAndUpdate(taskId, basicTask, { new: true })
break;
}
res.status(200).send(task);
} catch (error) {
next(error)
}
}
taskController.deleteTask = async (req, res, next) => {
try {
const id = req.params.id
const userId = req.headers.authorization
if (!userId) {
const exception = new Error("Login required")
exception.statusCode = 401
throw exception
}
let task = await Task.findById(id)
if (!task) {
const exception = new Error("Task not found")
exception.statusCode = 404
throw exception
}
await Task.findByIdAndUpdate(id, {
isDeleted: true
})
res.status(200).send({ message: "the task is deleted" });
} catch (error) {
next(error)
}
}
module.exports = taskController
```
## User controller
```jsx
const Task = require("../model/Task")
const User = require("../model/User")
const userController = {}
userController.getUsers = async (req, res, next) => {
try {
//get the userId from header of request
const userId = req.headers.authorization
//if there is no userId in header, throw exception that the user must login for authorization
if (!userId) {
const exception = new Error("Login required")
exception.statusCode = 401
throw exception
}
//check if user exists
const assigner = await User.findById(userId)
if (!assigner) {
const exception = new Error("User not found")
exception.statusCode = 404
throw exception
}
const users = await User.find()
res.status(200).send({ data: users, total: users.length });
} catch (error) {
next(error)
}
}
userController.getUserById = async (req, res, next) => {
try {
const userId = req.headers.authorization
const id = req.params.id
if (!userId) {
const exception = new Error("Login required")
exception.statusCode = 401
throw exception
}
const assigner = await User.findById(userId)
if (!assigner) {
const exception = new Error("User not found")
exception.statusCode = 404
throw exception
}
const user = await User.findById(id)
res.status(200).send(user);
} catch (error) {
next(error)
}
}
userController.createUser = async (req, res, next) => {
try {
const { name, role } = req.body
//get the userId from header of request
const userId = req.headers.authorization
//if there is no userId in header, throw exception
if (!userId) {
const exception = new Error("Login required")
exception.statusCode = 401
throw exception
}
//check if user exists
const assigner = await User.findById(userId)
if (!assigner) {
const exception = new Error("User not found")
exception.statusCode = 404
throw exception
}
//check if user's role is assigner
if (assigner.role !== "assigner") {
const exception = new Error("Only assigner can create new user")
exception.statusCode = 401
throw exception
}
if (!name || !role) {
const exception = new Error("Missing information")
exception.statusCode = 404
throw exception
}
await User.create({ name, role })
res.status(200).send({ message: "New user created" });
} catch (err) {
next(err)
}
}
module.exports = userController
```