From 6437e8e9bf54b55a4e51151e77c75b67e89bf6d9 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Wed, 29 May 2024 10:59:29 -0700 Subject: [PATCH 1/3] implemented DB operations for Checks --- Server/controllers/checkController.js | 62 +++++++++++++++++++++++---- Server/db/MongoDB.js | 48 +++++++++++---------- Server/validation/joi.js | 58 +++++++++++++++++++++---- 3 files changed, 127 insertions(+), 41 deletions(-) diff --git a/Server/controllers/checkController.js b/Server/controllers/checkController.js index ef1a1a071..7734da45b 100644 --- a/Server/controllers/checkController.js +++ b/Server/controllers/checkController.js @@ -1,29 +1,73 @@ -var jwt = require("jsonwebtoken"); +const { + createCheckParamValidation, + createCheckBodyValidation, + getChecksParamValidation, + deleteChecksParamValidation, +} = require("../validation/joi"); const SERVICE_NAME = "check"; -const createCheck = (req, res, next) => { +const createCheck = async (req, res, next) => { try { - req.db.createCheck(req, res); + await createCheckParamValidation.validateAsync(req.params); + await createCheckBodyValidation.validateAsync(req.body); + } catch (error) { + error.status = 422; + error.service = SERVICE_NAME; + error.message = error.details[0].message; + next(error); + return; + } + + try { + const checkData = { ...req.body }; + const check = await req.db.createCheck(checkData); + return res + .status(200) + .json({ success: true, msg: "Check created", data: check }); } catch (error) { error.service = SERVICE_NAME; next(error); } }; -const getChecks = (req, res, next) => { +const getChecks = async (req, res, next) => { try { - req.db.getChecks(req, res); - // Return all checks for a monitor + await getChecksParamValidation.validateAsync(req.params); + } catch (error) { + error.status = 422; + error.service = SERVICE_NAME; + error.message = error.details[0].message; + next(error); + return; + } + + try { + const checks = await req.db.getChecks(req.params.monitorId); + return res + .status(200) + .json({ success: true, msg: "Checks retrieved", data: checks }); } catch (error) { error.service = SERVICE_NAME; next(error); } }; -const deleteChecks = (req, res, next) => { +const deleteChecks = async (req, res, next) => { try { - req.db.deleteChecks(req, res); - // Delete all checks for a monitor + await deleteChecksParamValidation.validateAsync(req.params); + } catch (error) { + error.status = 422; + error.service = SERVICE_NAME; + error.message = error.details[0].message; + next(error); + return; + } + + try { + const deletedCount = await req.db.deleteChecks(req.params.monitorId); + return res + .status(200) + .json({ success: true, msg: "Checks deleted", data: { deletedCount } }); } catch (error) { error.service = SERVICE_NAME; next(error); diff --git a/Server/db/MongoDB.js b/Server/db/MongoDB.js index 32d5d33f7..cc73f060d 100644 --- a/Server/db/MongoDB.js +++ b/Server/db/MongoDB.js @@ -1,6 +1,7 @@ const Monitor = require("../models/Monitor"); const mongoose = require("mongoose"); const UserModel = require("../models/user"); +const Check = require("../models/Check"); const verifyId = (userId, monitorId) => { return userId.toString() === monitorId.toString(); @@ -209,17 +210,20 @@ const editMonitor = async (req, res) => { /** * Create a check for a monitor * @async - * @param {Express.Request} req - * @param {Express.Response} res + * @param {Object} checkData + * @param {string} checkData.monitorId + * @param {boolean} checkData.status + * @param {number} checkData.responseTime + * @param {number} checkData.statusCode + * @param {string} checkData.message + * @returns {Promise} * @throws {Error} */ -const createCheck = async (req, res) => { +const createCheck = async (checkData) => { try { - // Create check with monitor id - res - .status(200) - .json({ success: true, msg: "Create check", data: req.params.monitorId }); + const check = await new Check({ ...checkData }).save(); + return check; } catch (error) { throw error; } @@ -228,17 +232,15 @@ const createCheck = async (req, res) => { /** * Get all checks for a monitor * @async - * @param {Express.Request} req - * @param {Express.Response} res + * @param {string} monitorId + * @returns {Promise>} * @throws {Error} */ -const getChecks = async (req, res) => { +const getChecks = async (monitorId) => { try { - // TODO get all checks for a monitor from DB - res - .status(200) - .json({ success: true, msg: "Get checks", data: req.params.monitorId }); + const checks = await Check.find({ monitorId }); + return checks; } catch (error) { throw error; } @@ -247,19 +249,19 @@ const getChecks = async (req, res) => { /** * Delete all checks for a monitor * @async - * @param {Express.Request} req - * @param {Express.Response} res + * @param {string} monitorId + * @returns {boolean} * @throws {Error} */ -const deleteChecks = async (req, res) => { +const deleteChecks = async (monitorId) => { try { - // TODO Delete all checks for a monitor - res.status(200).json({ - success: true, - msg: "Deleted checks", - data: req.params.monitorId, - }); + const result = await Check.deleteMany({ monitorId }); + if (result.deletedCount > 0) { + return result.deletedCount; + } else { + throw new Error(`No checks found for monitor with id ${monitorId}`); + } } catch (error) { throw error; } diff --git a/Server/validation/joi.js b/Server/validation/joi.js index 01a0d0ada..75cd48cd1 100644 --- a/Server/validation/joi.js +++ b/Server/validation/joi.js @@ -1,5 +1,9 @@ const joi = require("joi"); +//**************************************** +// Auth +//**************************************** + const loginValidation = joi.object({ email: joi.string().email().required(), password: joi.string().min(8).required(), @@ -11,6 +15,20 @@ const registerValidation = joi.object({ password: joi.string().min(8).required(), }); +const editUserParamValidation = joi.object({ + userId: joi.string().required(), +}); + +const editUserBodyValidation = joi.object({ + firstname: joi.string(), + lastname: joi.string(), + profilePicUrl: joi.string(), +}); + +//**************************************** +// Monitors +//**************************************** + const getMonitorByIdValidation = joi.object({ monitorId: joi.string().required(), }); @@ -29,15 +47,9 @@ const monitorValidation = joi.object({ interval: joi.number(), }); -const editUserParamValidation = joi.object({ - userId: joi.string().required(), -}); - -const editUserBodyValidation = joi.object({ - firstname: joi.string(), - lastname: joi.string(), - profilePicUrl: joi.string(), -}); +//**************************************** +// Alerts +//**************************************** const createAlertParamValidation = joi.object({ monitorId: joi.string().required(), @@ -80,6 +92,30 @@ const deleteAlertParamValidation = joi.object({ alertId: joi.string().required(), }); +//**************************************** +// Checks +//**************************************** + +const createCheckParamValidation = joi.object({ + monitorId: joi.string().required(), +}); + +const createCheckBodyValidation = joi.object({ + monitorId: joi.string().required(), + status: joi.boolean().required(), + responseTime: joi.number().required(), + statusCode: joi.number().required(), + message: joi.string().required(), +}); + +const getChecksParamValidation = joi.object({ + monitorId: joi.string().required(), +}); + +const deleteChecksParamValidation = joi.object({ + monitorId: joi.string().required(), +}); + module.exports = { loginValidation, registerValidation, @@ -96,4 +132,8 @@ module.exports = { editAlertParamValidation, editAlertBodyValidation, deleteAlertParamValidation, + createCheckParamValidation, + createCheckBodyValidation, + getChecksParamValidation, + deleteChecksParamValidation, }; From 247153a133cf90bf9f25351f7858a5fcc9a5f14a Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Wed, 29 May 2024 11:07:17 -0700 Subject: [PATCH 2/3] Updated readme --- README.md | 97 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 82 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index dfc57064d..80c950307 100644 --- a/README.md +++ b/README.md @@ -655,22 +655,54 @@ curl --request POST \ ###### Response Payload -> | Type | Notes | -> | ---- | ------------------- | -> | None | No payload returned | +> | Type | Notes | +> | ------- | --------------------------- | +> | `Check` | Returns newly created check | ###### Body +> | Name | Type | Notes | +> | ------------ | --------- | -------------------------------------- | +> | monitorId | `string` | Monitor associated with Check | +> | status | `boolean` | `true` for up and `false` for down | +> | responseTime | `number` | How long it took the server to respond | +> | statusCode | `number` | HTTP Status code of response | +> | message | `string` | | + ##### Sample CURL request ``` - +curl --request POST \ + --url http://localhost:5000/api/v1/checks/66562414035c4ce6a8a610ac \ + --header 'Authorization: ' \ + --header 'Content-Type: application/json' \ + --data '{ + "monitorId": "66562414035c4ce6a8a610ac", + "status": true, + "responseTime": 1, + "statusCode": 200, + "message": "good" +}' ``` ###### Sample Response ```json - +{ + "success": true, + "msg": "Check created", + "data": { + "monitorId": "66562414035c4ce6a8a610ac", + "status": true, + "responseTime": 1, + "statusCode": 200, + "message": "good", + "_id": "66576decba9f70148ea1f354", + "createdAt": "2024-05-29T18:03:24.445Z", + "updatedAt": "2024-05-29T18:03:24.445Z", + "__v": 0 + } +} ``` @@ -682,7 +714,7 @@ curl --request POST \ > | Method/Headers | Value | > | -------------- | ----- | -> | Method | POST | +> | Method | GET | ###### Response Payload @@ -693,13 +725,42 @@ curl --request POST \ ##### Sample CURL request ``` - +curl --request GET \ + --url http://localhost:5000/api/v1/checks/66562414035c4ce6a8a610ac \ + --header 'Authorization: ' \ ``` ###### Sample Response ```json - +{ + "success": true, + "msg": "Checks retrieved", + "data": [ + { + "_id": "66576c0194e11c0d4409d3c1", + "monitorId": "66562414035c4ce6a8a610ac", + "status": true, + "responseTime": 1, + "statusCode": 200, + "message": "good", + "createdAt": "2024-05-29T17:55:13.581Z", + "updatedAt": "2024-05-29T17:55:13.581Z", + "__v": 0 + }, + { + "_id": "66576c0994e11c0d4409d3c5", + "monitorId": "66562414035c4ce6a8a610ac", + "status": true, + "responseTime": 2, + "statusCode": 200, + "message": "good", + "createdAt": "2024-05-29T17:55:21.127Z", + "updatedAt": "2024-05-29T17:55:21.127Z", + "__v": 0 + } + ] +} ``` @@ -715,22 +776,28 @@ curl --request POST \ ###### Response Payload -> | Type | Notes | -> | ---- | ------------------- | -> | None | No payload returned | - -###### Body +> | Type | Notes | +> | -------- | -------------------------------------------------------------------- | +> | `Object` | `{deletedCount: n}` Returns an object showing how many items deleted | ##### Sample CURL request ``` - +curl --request POST \ + --url http://localhost:5000/api/v1/checks/delete/66562414035c4ce6a8a610ac \ + --header 'Authorization: ' \ ``` ###### Sample Response ```json - +{ + "success": true, + "msg": "Checks deleted", + "data": { + "deletedCount": 3 + } +} ``` From 5fc4b018f98474e7e5d8cfad07b872d73f37d6e3 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Wed, 29 May 2024 12:15:59 -0700 Subject: [PATCH 3/3] Fixed return type for deleteChecks --- Server/db/MongoDB.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Server/db/MongoDB.js b/Server/db/MongoDB.js index cc73f060d..a410e7dfa 100644 --- a/Server/db/MongoDB.js +++ b/Server/db/MongoDB.js @@ -250,7 +250,7 @@ const getChecks = async (monitorId) => { * Delete all checks for a monitor * @async * @param {string} monitorId - * @returns {boolean} + * @returns {number} * @throws {Error} */