Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/duration #18

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions server/controllers/duration.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { NextFunction, Request, Response } from "express";
import mongoose from "mongoose";
const Duration = require("../models/duration");
const HttpStatus = require("http-status-codes");
const {ErrorResponse} = require("../helper");

class DurationController {
async create(req: Request, res: Response, next: NextFunction) {
try {
const duration = new Duration(req.body);
const savedDuration = await duration.save();

return savedDuration._doc;
} catch (err: any) {
throw err;
}
}

async update(req: Request, res: Response, next: NextFunction) {
try {
const studentId = req.params.student_id;
const newData = req.body;
const updatedDuration = await Duration.findOneAndUpdate(
{ student_id: studentId },
newData
);

if (!updatedDuration) {
throw new ErrorResponse({
statusCode: HttpStatus.StatusCodes.NOT_FOUND,
message: `Student with id ${studentId} not found.`
})
}

return updatedDuration._doc;
} catch (err: any) {
throw err;
}

}

async delete(req: Request, res: Response, next: NextFunction) {
try {
const studentId = req.params.student_id;

const deletedDuration = await Duration.findOneAndDelete({ student_id: studentId });

if (!deletedDuration) {
throw new ErrorResponse({
statusCode: HttpStatus.StatusCodes.NOT_FOUND,
message: `Student with id ${studentId} not found.`,
});
}

return deletedDuration._doc;
} catch (err: any) {
throw err;
}
}

async findAll(req: Request, res: Response, next: NextFunction) {
try {
const students = await Duration.findAll();

if (!students) {
throw new ErrorResponse({
statusCode: HttpStatus.StatusCodes.NOT_FOUND,
message: `Students not found.`
});
}

return students._doc;
} catch (err) {
throw err;
}
}

async findByStudentId(req: Request, res: Response, next: NextFunction) {
try {
const studentId = req.params.student_id;

const student = await Duration.findOne({ student_id: studentId })

if (!student) {
throw new ErrorResponse({
statusCode: HttpStatus.StatusCodes.NOT_FOUND,
message: `Student with id ${studentId} not found.`
});
}

return student._doc;
} catch (err) {
throw err;
}
}
}

module.exports = new DurationController();
4 changes: 3 additions & 1 deletion server/controllers/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const authController = require("./auth.controller");
const durationController = require("./duration.controller")

module.exports = {
authController
authController,
durationController
}
36 changes: 36 additions & 0 deletions server/models/duration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import mongoose, { model } from 'mongoose';
const { Schema } = mongoose;

const durationSchema = new Schema({
student_id: {
type: Schema.Types.ObjectId,
ref: 'Student',
required: true
},
date: {
type: Date,
required: true
},
time_started: {
type: Date,
required: true
},
time_ended: {
type: Date,
required: true
},
time_total: {
type: Number, // Assume that we will retrieve this using time_started - time_ended
required: true
},
activity: {
type: String,
required: true
},
notes: {
type: String,
required: true
}
});

module.exports = mongoose.model('Duration', durationSchema);
13 changes: 13 additions & 0 deletions server/routes/duration.router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import express from "express";
const router = express.Router();
const {wrapMiddleware, wrapController} = require("../helper");
const {durationController} = require("../controllers");
const durationValidation = require("../validations/duration.validation");

router.post("/create", wrapMiddleware(durationValidation.create), wrapController(durationController.create));
router.put("/:student_id", wrapMiddleware(durationValidation.update), wrapController(durationController.update));
router.delete("/:student_id", wrapMiddleware(durationValidation.delete), wrapController(durationController.delete));
router.get("/all", wrapMiddleware(durationValidation.findAll), wrapController(durationController.findAll));
router.get("/:student_id", wrapMiddleware(durationValidation.findByStudentId, wrapController(durationValidation.findById)));

module.exports = router;
2 changes: 2 additions & 0 deletions server/routes/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
const authRouter = require("./auth.router");
const durationRouter = require("./duration.router");
import express from "express";
const router = express.Router();

router.use("/auth", authRouter);
router.use("/duration", durationRouter);

module.exports = router;
85 changes: 85 additions & 0 deletions server/validations/duration.validation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { CustomHelpers } from "joi";

const Joi = require('joi');
const mongoose = require('mongoose');

// Define the schema for each route validation
module.exports = {
create: Joi.object({
student_id: Joi.string()
.custom((value: string, helpers: CustomHelpers) => {
if (!mongoose.Types.ObjectId.isValid(value)) {
return helpers.error('Invalid student ID');
}
return value;
})
.required(),
date: Joi.date().required(),
time_started: Joi.date().required(),
time_ended: Joi.date()
.greater(Joi.ref('time_started'))
.required()
.messages({
"date.greater": "time_ended must be later than time_started",
}),
time_total: Joi.number()
.positive()
.required()
.messages({
"number.positive": "time_total must be a positive number",
}),
activity: Joi.string().required(),
notes: Joi.string().required().allow(null, ''),
}),

update: Joi.object({
student_id: Joi.string()
.custom((value: string, helpers: CustomHelpers) => {
if (!mongoose.Types.ObjectId.isValid(value)) {
return helpers.error('Invalid student ID');
}
return value;
})
.required(),
date: Joi.date().required(),
time_started: Joi.date().required(),
time_ended: Joi.date()
.greater(Joi.ref('time_started'))
.required()
.messages({
"date.greater": "time_ended must be later than time_started",
}),
time_total: Joi.number()
.positive()
.required()
.messages({
"number.positive": "time_total must be a positive number",
}),
activity: Joi.string().required(),
notes: Joi.string().required().allow(null, ''),
}),

delete: Joi.object({
student_id: Joi.string()
.custom((value: string, helpers: CustomHelpers) => {
if (!mongoose.Types.ObjectId.isValid(value)) {
return helpers.error('Invalid student ID');
}
return value;
})
.required(),
}),

findAll: Joi.object({}),

findByStudentId: Joi.object({
student_id: Joi.string()
.custom((value: string, helpers: CustomHelpers) => {
if (!mongoose.Types.ObjectId.isValid(value)) {
return helpers.error('Invalid student ID');
}
return value;
})
.required(),
}),
};