---
# System prepended metadata

title: Untitled

---


## 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
```