Merge pull request #82 from bluewave-labs/feat/alert-routes

Feat/alert routes, resolves #74
This commit is contained in:
Alexander Holliday authored and GitHub committed 2024-05-28 14:25:55 -07:00
commit 4563f30fc3
7 files changed
+541 -12

No files matched your search

+199 -10
View File
@@ -25,6 +25,13 @@ BlueWave uptime monitoring application
- <code>POST</code> [/api/v1/checks/{monitorId}](#post-checks)
- <code>GET</code> [/api/v1/checks/{monitorId}](#get-checks)
- <code>POST</code> [/api/v1/checks/delete/{monitorId}](#delete-checks)
###### Alerts
- <code>POST</code> [/api/v1/alerts/{monitorId}](#create-alert)
- <code>GET</code> [/api/v1/alerts/user/{userId}](#get-alerts-user-id)
- <code>GET</code> [/api/v1/alerts/monitor/{monitorId}](#get-alerts-monitor-id)
- <code>GET</code> [/api/v1/alerts/{alertId}](#get-alert-alert-id)
- <code>POST</code> [/api/v1/alerts/edit/{alertId}](#edit-alert)
- <code>POST</code> [/api/v1/alerts/delete/{alertId}](#delete-alert)
5. [Error Handling](#error-handling)
6. [Contributors](#contributors)
@@ -333,9 +340,9 @@ curl --request POST \
##### Response Payload
> | Type | Notes |
> | ---------------- | ----------------- |
> | `Array[Monitor]` | Array of monitors |
> | Type | Notes |
> | ---------------- | --------------------- |
> | `Array<Monitor>` | Array of all monitors |
###### Sample cURL Request
@@ -439,9 +446,9 @@ curl --request GET \
###### Response Payload
> | Type | Notes |
> | ---------------- | ------------------------------------------------------------------ |
> | `Array[Monitor]` | Array of monitors created by user with userId specified in request |
> | Type | Notes |
> | ---------------- | ------------------------------------------------------- |
> | `Array<Monitor>` | Array of monitors created by user with specified UserID |
###### Sample cURL Request
@@ -499,9 +506,9 @@ curl --request GET \
###### Response Payload
> | Type | Notes |
> | --------- | --------------------------------- |
> | `Monitor` | Newly created monitor is returned |
> | Type | Notes |
> | --------- | ------------------------------- |
> | `Monitor` | Returns newly created `Monitor` |
##### Sample CURL request
@@ -681,7 +688,7 @@ curl --request POST \
> | Type | Notes |
> | --------------- | ------------------------ |
> | `Array[Checks]` | Array of `Check` objects |
> | `Array<Checks>` | Array of `Check` objects |
##### Sample CURL request
@@ -730,6 +737,188 @@ curl --request POST \
---
###### Alerts
<details>
<summary id='create-alert'><code>POST</code><b>/api/v1/alerts/{monitorId}</b></summary>
###### Method/Headers
> | Method/Headers | Value |
> | -------------- | ----- |
> | Method | POST |
###### Response Payload
> | Type | Notes |
> | ------- | ----------------------------- |
> | `Alert` | Returns newly created `Alert` |
###### Body
##### Sample CURL request
```
```
###### Sample Response
```json
```
</details>
<details>
<summary id='get-alerts-user-id'><code>GET</code><b>/api/v1/alerts/user/{userId}</b></summary>
###### Method/Headers
> | Method/Headers | Value |
> | -------------- | ----- |
> | Method | GET |
###### Response Payload
> | Type | Notes |
> | -------------- | --------------------------------------- |
> | `Array<Alert>` | Returns all `Alert` created by a `User` |
##### Sample CURL request
```
```
###### Sample Response
```json
```
</details>
<details>
<summary id='get-alerts-monitor-id'><code>GET</code><b>/api/v1/alerts/monitor/{monitorId}</b></summary>
###### Method/Headers
> | Method/Headers | Value |
> | -------------- | ----- |
> | Method | GET |
###### Response Payload
> | Type | Notes |
> | -------------- | -------------------------------------------------------------- |
> | `Array<Alert>` | Returns an array of `Alert` belonging to a specified `Monitor` |
##### Sample CURL request
```
```
###### Sample Response
```json
```
</details>
<details>
<summary id='get-alert-alert-id'><code>GET</code><b>/api/v1/alerts/{alertId}</b></summary>
###### Method/Headers
> | Method/Headers | Value |
> | -------------- | ----- |
> | Method | GET |
###### Response Payload
> | Type | Notes |
> | ------- | ------------------------- |
> | `Alert` | Returns specified `Alert` |
##### Sample CURL request
```
```
###### Sample Response
```json
```
</details>
<details>
<summary id='edit-alert'><code>POST</code><b>/api/v1/alerts/edit/{alertId}</b></summary>
###### Method/Headers
> | Method/Headers | Value |
> | -------------- | ----- |
> | Method | POST |
###### Response Payload
> | Type | Notes |
> | ------- | -------------------- |
> | `Alert` | Returns edited alert |
###### Body
##### Sample CURL request
```
```
###### Sample Response
```json
```
</details>
<details>
<summary id='delete-alert'><code>POST</code><b>/api/v1/alerts/delete/{alertId}</b></summary>
###### Method/Headers
> | Method/Headers | Value |
> | -------------- | ----- |
> | Method | POST |
###### Response Payload
> | Type | Notes |
> | ---- | ------------------- |
> | None | No payload returned |
###### Body
##### Sample CURL request
```
```
###### Sample Response
```json
```
</details>
---
### Error handling {#error-handling}
Errors are returned in a standard format:
+139
View File
@@ -0,0 +1,139 @@
const express = require("express");
const logger = require("../utils/logger");
require("dotenv").config();
const {
createAlertParamValidation,
createAlertBodyValidation,
getAlertsByUserIdParamValidation,
getAlertsByMonitorIdParamValidation,
getAlertByIdParamValidation,
editAlertParamValidation,
editAlertBodyValidation,
deleteAlertParamValidation,
} = require("../validation/joi");
const SERVICE_NAME = "alerts";
/**
* Creates an alert for a monitor
* @async
* @param {Express.Request} req
* @param {Express.Response} res
* @returns {Promise<Express.Response>}
* @throws {Error}
*/
const createAlert = async (req, res, next) => {
try {
await createAlertParamValidation.validateAsync(req.params);
await createAlertBodyValidation.validateAsync(req.body);
} catch (error) {
error.status = 422;
error.message = error.details[0].message;
error.service = SERVICE_NAME;
next(error);
return;
}
try {
req.db.createAlert(req, res);
} catch (error) {
error.service = SERVICE_NAME;
next(error);
}
};
/**
* Gets all alerts for a user
* @async
* @param {Express.Request} req
* @param {Express.Response} res
* @returns {Promise<Express.Response>}
* @throws {Error}
*/
const getAlertsByUserId = async (req, res, next) => {
try {
await getAlertsByUserIdParamValidation.validateAsync(req.params);
} catch (error) {
error.status = 422;
error.message = error.details[0].message;
error.service = SERVICE_NAME;
next(error);
return;
}
try {
req.db.getAlertsByUserId(req, res);
} catch (error) {
error.service = SERVICE_NAME;
next(error);
}
};
const getAlertsByMonitorId = async (req, res, next) => {
try {
await getAlertsByMonitorIdParamValidation.validateAsync(req.params);
res.status(200).json({
success: true,
msg: "Get Alerts By MonitorID",
data: req.params.monitorId,
});
} catch (error) {
error.status = 422;
res.status(200).json({ success: true, msg: "Edit alert" });
error.message = error.details[0].message;
error.service = SERVICE_NAME;
next(error);
return;
}
};
const getAlertById = async (req, res, next) => {
try {
await getAlertByIdParamValidation.validateAsync(req.params);
res.status(200).json({
success: true,
msg: "Get Alert By alertID",
data: req.params.alertId,
});
} catch (error) {
error.status = 422;
error.message = error.details[0].message;
error.service = SERVICE_NAME;
next(error);
return;
}
};
const editAlert = async (req, res, next) => {
try {
await editAlertParamValidation(req.params);
await editAlertBodyValidation(req.body);
res.status(200).json({ success: true, msg: "Edit alert" });
} catch (error) {
error.status = 422;
error.message = error.details[0].message;
error.service = SERVICE_NAME;
next(error);
return;
}
};
const deleteAlert = async (req, res, next) => {
try {
await deleteAlertParamValidation(req.params);
res.status(200).json({ success: true, msg: "Delete alert" });
} catch (error) {
error.status = 422;
error.message = error.details[0].message;
error.service = SERVICE_NAME;
next(error);
return;
}
};
module.exports = {
createAlert,
getAlertsByUserId,
getAlertsByMonitorId,
getAlertById,
editAlert,
deleteAlert,
};
+2 -2
View File
@@ -17,7 +17,7 @@ const SERVICE_NAME = "auth";
* @returns {String}
*/
const issueToken = (payload) => {
return jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: "1h" });
return jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: "99d" });
};
/**
@@ -31,7 +31,7 @@ const registerController = async (req, res, next) => {
try {
await registerValidation.validateAsync(req.body);
} catch (error) {
error.status = 400;
error.status = 422;
error.service = SERVICE_NAME;
error.message = error.details[0].message;
next(error);
+123
View File
@@ -265,6 +265,123 @@ const deleteChecks = async (req, res) => {
}
};
//****************************************
// Alerts
//****************************************
/**
* Creates an Alert associated with a Monitor and User
* @async
* @param {Express.Request} req
* @param {Express.Response} res
* @returns {<Promise<Alert>>}
* @throws {Error}
*/
const createAlert = async (req, res) => {
try {
res
.status(200)
.json({ success: true, msg: "Create Alert", data: req.params.monitorId });
} catch (error) {
throw error;
}
};
/**
* Gets all alerts a User has set
* @async
* @param {Express.Request} req
* @param {Express.Response} res
* @returns {<Promise<Array<Alert>>}
* @throws {Error}
*/
const getAlertsByUserId = async (req, res) => {
try {
res.status(200).json({
success: true,
msg: "Get Alerts By UserID",
data: req.params.userId,
});
} catch (error) {
throw error;
}
};
/**
* Gets all alerts a for an associated Monitor
* @async
* @param {Express.Request} req
* @param {Express.Response} res
* @returns {<Promise<Array<Alert>>}
* @throws {Error}
*/
const getAlertsByMonitorId = async (req, res) => {
try {
res.status(200).json({
success: true,
msg: "Get Alerts By MonitorID",
data: req.params.monitorId,
});
} catch (error) {
throw error;
}
};
/**
* Gets an alert with specified ID
* @async
* @param {Express.Request} req
* @param {Express.Response} res
* @returns {Promise<Alert>}
* @throws {Error}
*/
const getAlertById = async (req, res) => {
try {
res.status(200).json({
success: true,
msg: "Get Alert By alertID",
data: req.params.alertId,
});
} catch (error) {
throw error;
}
};
/**
* Returns an edited monitor with the specified ID
* @async
* @param {Express.Request} req
* @param {Express.Response} res
* @returns {Promise<Alert>>}
* @throws {Error}
*/
const editAlert = async (req, res) => {
try {
res
.status(200)
.json({ success: true, msg: "Edit alert", data: req.params.alertId });
} catch (error) {
throw error;
}
};
/**
* Deletes a monitor with the specified ID
* @async
* @param {Express.Request} req
* @param {Express.Response} res
* @throws {Error}
*/
const deleteAlert = async (req, res) => {
try {
res
.status(200)
.json({ success: true, msg: "Delete alert", data: req.params.alertId });
} catch (error) {
throw error;
}
};
module.exports = {
connect,
insertUser,
@@ -279,4 +396,10 @@ module.exports = {
createCheck,
getChecks,
deleteChecks,
createAlert,
getAlertsByUserId,
getAlertsByMonitorId,
getAlertById,
editAlert,
deleteAlert,
};
+2
View File
@@ -4,6 +4,7 @@ const cors = require("cors");
const authRouter = require("./routes/authRoute");
const monitorRouter = require("./routes/monitorRoute");
const checkRouter = require("./routes/checkRoute");
const alertRouter = require("./routes/alertRoute");
const { connectDbAndRunServer } = require("./configs/db");
require("dotenv").config();
const logger = require("./utils/logger");
@@ -64,6 +65,7 @@ app.use((req, res, next) => {
app.use("/api/v1/auth", authRouter);
app.use("/api/v1/monitors", verifyJWT, monitorRouter);
app.use("/api/v1/checks", verifyJWT, checkRouter);
app.use("/api/v1/alerts", verifyJWT, alertRouter);
// Testing email service
// app.use('/sendEmail', async (req, res) => {
+27
View File
@@ -0,0 +1,27 @@
const router = require("express").Router();
const alertController = require("../controllers/alertController");
const { verifyOwnership } = require("../middleware/verifyOwnership");
const Alert = require("../models/Alert");
// Create alert
router.post("/:monitorId", alertController.createAlert);
// Get all alerts for a user
router.get("/user/:userId", alertController.getAlertsByUserId);
// Get all alerts for a monitor
router.get("/monitor/:monitorId", alertController.getAlertsByMonitorId);
// Get a single alert
router.get("/:alertId", alertController.getAlertById);
// Edit
router.post(
"/edit/:alertId",
verifyOwnership(Alert, "alertId"),
alertController.editAlert
);
//Delete
router.post(
"/delete/:alertId",
verifyOwnership(Alert, "alertId"),
alertController.deleteAlert
);
module.exports = router;
+49
View File
@@ -39,6 +39,47 @@ const editUserBodyValidation = joi.object({
profilePicUrl: joi.string(),
});
const createAlertParamValidation = joi.object({
monitorId: joi.string().required(),
});
const createAlertBodyValidation = joi.object({
checkId: joi.string().required(),
monitorId: joi.string().required(),
userId: joi.string().required(),
status: joi.boolean(),
message: joi.string(),
notifiedStatus: joi.boolean(),
acknowledgeStatus: joi.boolean(),
});
const getAlertsByUserIdParamValidation = joi.object({
userId: joi.string().required(),
});
const getAlertsByMonitorIdParamValidation = joi.object({
monitorId: joi.string().required(),
});
const getAlertByIdParamValidation = joi.object({
alertId: joi.string().required(),
});
const editAlertParamValidation = joi.object({
alertId: joi.string().required(),
});
const editAlertBodyValidation = joi.object({
status: joi.boolean(),
message: joi.string(),
notifiedStatus: joi.boolean(),
acknowledgeStatus: joi.boolean(),
});
const deleteAlertParamValidation = joi.object({
alertId: joi.string().required(),
});
module.exports = {
loginValidation,
registerValidation,
@@ -47,4 +88,12 @@ module.exports = {
monitorValidation,
editUserParamValidation,
editUserBodyValidation,
createAlertParamValidation,
createAlertBodyValidation,
getAlertsByUserIdParamValidation,
getAlertsByMonitorIdParamValidation,
getAlertByIdParamValidation,
editAlertParamValidation,
editAlertBodyValidation,
deleteAlertParamValidation,
};