From 22a155b527613b486b53514348857071b9bf55df Mon Sep 17 00:00:00 2001 From: Derick Pascual Date: Sat, 2 Nov 2024 14:09:12 -0500 Subject: [PATCH 1/6] Added duration branch --- server/models/duration.ts | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 server/models/duration.ts diff --git a/server/models/duration.ts b/server/models/duration.ts new file mode 100644 index 0000000..fe86db2 --- /dev/null +++ b/server/models/duration.ts @@ -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); \ No newline at end of file From 2f3c09662fd6358f970941c6b29e7da7a90a0d61 Mon Sep 17 00:00:00 2001 From: Derick Pascual Date: Sat, 2 Nov 2024 14:30:05 -0500 Subject: [PATCH 2/6] Added routers, controllers, validation structure for duration --- server/controllers/duration.controller.ts | 27 +++++++++++++++++++++++ server/controllers/index.ts | 6 ++++- server/routes/duration.router.ts | 13 +++++++++++ server/routes/index.ts | 4 ++++ server/routes/student.router.ts | 12 ++++++++++ server/validations/duration.validation.ts | 19 ++++++++++++++++ 6 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 server/controllers/duration.controller.ts create mode 100644 server/routes/duration.router.ts create mode 100644 server/routes/student.router.ts create mode 100644 server/validations/duration.validation.ts diff --git a/server/controllers/duration.controller.ts b/server/controllers/duration.controller.ts new file mode 100644 index 0000000..a654403 --- /dev/null +++ b/server/controllers/duration.controller.ts @@ -0,0 +1,27 @@ +import { NextFunction, Request, Response } from "express"; +const HttpStatus = require("http-status-codes"); +const {ErrorResponse} = require("../helper"); + +class DurationController { + async create(req: Request, res: Response, next: NextFunction) { + + } + + async update(req: Request, res: Response, next: NextFunction) { + + } + + async delete(req: Request, res: Response, next: NextFunction) { + + } + + async findAll(req: Request, res: Response, next: NextFunction) { + + } + + async findById(req: Request, res: Response, next: NextFunction) { + + } +} + +module.exports = new DurationController(); \ No newline at end of file diff --git a/server/controllers/index.ts b/server/controllers/index.ts index ef6c85e..f025e4c 100644 --- a/server/controllers/index.ts +++ b/server/controllers/index.ts @@ -1,5 +1,9 @@ const authController = require("./auth.controller"); +const studentController = require("./student.controller") +const durationController = require("./duration.controller") module.exports = { - authController + authController, + studentController, + durationController } \ No newline at end of file diff --git a/server/routes/duration.router.ts b/server/routes/duration.router.ts new file mode 100644 index 0000000..5bf9ee8 --- /dev/null +++ b/server/routes/duration.router.ts @@ -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.findById, wrapController(durationValidation.findById))); + +module.exports = router; \ No newline at end of file diff --git a/server/routes/index.ts b/server/routes/index.ts index 5bc9b15..2f7097b 100644 --- a/server/routes/index.ts +++ b/server/routes/index.ts @@ -1,7 +1,11 @@ const authRouter = require("./auth.router"); +const studentRouter = require("./student.router"); +const durationRouter = require("./duration.router"); import express from "express"; const router = express.Router(); router.use("/auth", authRouter); +router.use("/student", studentRouter); +router.use("/duration", durationRouter); module.exports = router; \ No newline at end of file diff --git a/server/routes/student.router.ts b/server/routes/student.router.ts new file mode 100644 index 0000000..7e30786 --- /dev/null +++ b/server/routes/student.router.ts @@ -0,0 +1,12 @@ +import express from "express"; +const router = express.Router(); +const {wrapMiddleware, wrapController} = require("../helper"); +const {studentController} = require("../controllers"); +const studentValidation = require("../validations/student.validation"); + +router.post("/create", wrapMiddleware(studentValidation.post), wrapController(studentController.create)); +router.put("/:id", wrapMiddleware(studentValidation.put), wrapController(studentController.update)); +router.delete("/:id", wrapMiddleware(studentValidation.delete), wrapController(studentController.delete)) +router.get("/:id", wrapMiddleware(studentValidation.get), wrapController(studentController.findById)); + +module.exports = router; \ No newline at end of file diff --git a/server/validations/duration.validation.ts b/server/validations/duration.validation.ts new file mode 100644 index 0000000..6e21d1a --- /dev/null +++ b/server/validations/duration.validation.ts @@ -0,0 +1,19 @@ +import Joi from "joi" + +module.exports = { + create: Joi.object({ + + }), + update: Joi.object({ + + }), + delete: Joi.object({ + + }), + findAll: Joi.object({ + + }), + findById: Joi.object({ + + }) +}; \ No newline at end of file From 3d8bca5f91bdc721cc1d5684f8239e455b1fbc74 Mon Sep 17 00:00:00 2001 From: Derick Pascual Date: Sat, 2 Nov 2024 14:54:21 -0500 Subject: [PATCH 3/6] Added validation --- server/validations/duration.validation.ts | 82 ++++++++++++++++++++--- 1 file changed, 74 insertions(+), 8 deletions(-) diff --git a/server/validations/duration.validation.ts b/server/validations/duration.validation.ts index 6e21d1a..3b08dd7 100644 --- a/server/validations/duration.validation.ts +++ b/server/validations/duration.validation.ts @@ -1,19 +1,85 @@ -import Joi from "joi" +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({ + 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({ + 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({ - }), - findById: Joi.object({ + 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(), + }), }; \ No newline at end of file From 117ce06f9ad369867e8e901c80008b372e14674e Mon Sep 17 00:00:00 2001 From: Derick Pascual Date: Sat, 9 Nov 2024 14:23:23 -0600 Subject: [PATCH 4/6] changes --- server/controllers/duration.controller.ts | 15 +++++++++++++-- server/routes/duration.router.ts | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/server/controllers/duration.controller.ts b/server/controllers/duration.controller.ts index a654403..d6278e1 100644 --- a/server/controllers/duration.controller.ts +++ b/server/controllers/duration.controller.ts @@ -1,14 +1,25 @@ 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; + } catch (err: any) { + throw err; + } } async update(req: Request, res: Response, next: NextFunction) { + const id = req.params.student_id; + const newData = req.body; } async delete(req: Request, res: Response, next: NextFunction) { @@ -19,7 +30,7 @@ class DurationController { } - async findById(req: Request, res: Response, next: NextFunction) { + async findByStudentId(req: Request, res: Response, next: NextFunction) { } } diff --git a/server/routes/duration.router.ts b/server/routes/duration.router.ts index 5bf9ee8..1ca0ff6 100644 --- a/server/routes/duration.router.ts +++ b/server/routes/duration.router.ts @@ -8,6 +8,6 @@ router.post("/create", wrapMiddleware(durationValidation.create), wrapController 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.findById, wrapController(durationValidation.findById))); +router.get("/:student_id", wrapMiddleware(durationValidation.findByStudentId, wrapController(durationValidation.findById))); module.exports = router; \ No newline at end of file From e0a066130b7d61992f98e35c5c2fde1cb6075a4b Mon Sep 17 00:00:00 2001 From: Derick Pascual Date: Sat, 9 Nov 2024 15:17:34 -0600 Subject: [PATCH 5/6] Some duration changes --- server/controllers/duration.controller.ts | 43 +++++++++++++++++++++-- server/controllers/index.ts | 2 -- server/routes/index.ts | 2 -- server/routes/student.router.ts | 12 ------- 4 files changed, 41 insertions(+), 18 deletions(-) delete mode 100644 server/routes/student.router.ts diff --git a/server/controllers/duration.controller.ts b/server/controllers/duration.controller.ts index d6278e1..e34658a 100644 --- a/server/controllers/duration.controller.ts +++ b/server/controllers/duration.controller.ts @@ -17,13 +17,52 @@ class DurationController { } async update(req: Request, res: Response, next: NextFunction) { - const id = req.params.student_id; + 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; + } catch (err: any) { + throw err; + } - const newData = req.body; } async delete(req: Request, res: Response, next: NextFunction) { + try { + const studentId = req.params.student_id; + + if (!mongoose.Types.ObjectId.isValid(studentId)) { + throw new ErrorResponse({ + statusCode: HttpStatus.StatusCodes.BAD_REQUEST, + message: `Invalid studentId format: ${studentId}.` + }); + } + + 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; + } catch (err: any) { + + } } async findAll(req: Request, res: Response, next: NextFunction) { diff --git a/server/controllers/index.ts b/server/controllers/index.ts index f025e4c..a08fb37 100644 --- a/server/controllers/index.ts +++ b/server/controllers/index.ts @@ -1,9 +1,7 @@ const authController = require("./auth.controller"); -const studentController = require("./student.controller") const durationController = require("./duration.controller") module.exports = { authController, - studentController, durationController } \ No newline at end of file diff --git a/server/routes/index.ts b/server/routes/index.ts index 2f7097b..3a91d12 100644 --- a/server/routes/index.ts +++ b/server/routes/index.ts @@ -1,11 +1,9 @@ const authRouter = require("./auth.router"); -const studentRouter = require("./student.router"); const durationRouter = require("./duration.router"); import express from "express"; const router = express.Router(); router.use("/auth", authRouter); -router.use("/student", studentRouter); router.use("/duration", durationRouter); module.exports = router; \ No newline at end of file diff --git a/server/routes/student.router.ts b/server/routes/student.router.ts deleted file mode 100644 index 7e30786..0000000 --- a/server/routes/student.router.ts +++ /dev/null @@ -1,12 +0,0 @@ -import express from "express"; -const router = express.Router(); -const {wrapMiddleware, wrapController} = require("../helper"); -const {studentController} = require("../controllers"); -const studentValidation = require("../validations/student.validation"); - -router.post("/create", wrapMiddleware(studentValidation.post), wrapController(studentController.create)); -router.put("/:id", wrapMiddleware(studentValidation.put), wrapController(studentController.update)); -router.delete("/:id", wrapMiddleware(studentValidation.delete), wrapController(studentController.delete)) -router.get("/:id", wrapMiddleware(studentValidation.get), wrapController(studentController.findById)); - -module.exports = router; \ No newline at end of file From 41542b4567b75731de4bd301578ba777f4c71369 Mon Sep 17 00:00:00 2001 From: Derick Pascual Date: Sat, 9 Nov 2024 15:51:31 -0600 Subject: [PATCH 6/6] finished duration controller --- server/controllers/duration.controller.ts | 43 +++++++++++++++++------ 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/server/controllers/duration.controller.ts b/server/controllers/duration.controller.ts index e34658a..608e870 100644 --- a/server/controllers/duration.controller.ts +++ b/server/controllers/duration.controller.ts @@ -10,7 +10,7 @@ class DurationController { const duration = new Duration(req.body); const savedDuration = await duration.save(); - return savedDuration; + return savedDuration._doc; } catch (err: any) { throw err; } @@ -32,7 +32,7 @@ class DurationController { }) } - return updatedDuration; + return updatedDuration._doc; } catch (err: any) { throw err; } @@ -43,13 +43,6 @@ class DurationController { try { const studentId = req.params.student_id; - if (!mongoose.Types.ObjectId.isValid(studentId)) { - throw new ErrorResponse({ - statusCode: HttpStatus.StatusCodes.BAD_REQUEST, - message: `Invalid studentId format: ${studentId}.` - }); - } - const deletedDuration = await Duration.findOneAndDelete({ student_id: studentId }); if (!deletedDuration) { @@ -59,18 +52,46 @@ class DurationController { }); } - return deletedDuration; + 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; + } } }