Skip to content

Commit

Permalink
Feat: Add endpoints to retrieve site and device details by ID
Browse files Browse the repository at this point in the history
  • Loading branch information
Baalmart committed Feb 11, 2025
1 parent d970a18 commit 1425080
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 13 deletions.
21 changes: 21 additions & 0 deletions src/device-registry/controllers/device.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,27 @@ function handleResponse({
}

const device = {
getDeviceDetailsById: async (req, res, next) => {
try {
const { id } = req.params;
const defaultTenant = constants.DEFAULT_TENANT || "airqo";
req.query.tenant = isEmpty(req.query.tenant)
? defaultTenant
: req.query.tenant;

const result = await createDeviceUtil.getDeviceById(req, next); // Call the utility function
handleResponse({ result, res });
} catch (error) {
logger.error(`🐛🐛 Internal Server Error ${error.message}`);
next(
new HttpError(
"Internal Server Error",
httpStatus.INTERNAL_SERVER_ERROR,
{ message: error.message }
)
);
}
},
bulkCreate: async (req, res, next) => {
try {
return res.status(httpStatus.NOT_IMPLEMENTED).json({
Expand Down
23 changes: 23 additions & 0 deletions src/device-registry/controllers/site.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,28 @@ function handleResponse({
}

const manageSite = {
getSiteDetailsById: async (req, res, next) => {
try {
const { id } = req.params;
const defaultTenant = constants.DEFAULT_TENANT || "airqo";
req.query.tenant = isEmpty(req.query.tenant)
? defaultTenant
: req.query.tenant;

const result = await createSiteUtil.getSiteById(req, next);

handleResponse({ result, res });
} catch (error) {
logger.error(`🐛🐛 Internal Server Error ${error.message}`);
next(
new HttpError(
"Internal Server Error",
httpStatus.INTERNAL_SERVER_ERROR,
{ message: error.message }
)
);
}
},
bulkCreate: async (req, res, next) => {
try {
return res.status(httpStatus.NOT_IMPLEMENTED).json({
Expand Down Expand Up @@ -597,6 +619,7 @@ const manageSite = {
return;
}
},

findNearestSite: async (req, res, next) => {
try {
logText("list all sites by coordinates...");
Expand Down
11 changes: 11 additions & 0 deletions src/device-registry/routes/v2/devices.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ const {
validateListDevices,
validateArrayBody,
validateBulkUpdateDevices,
validateDeviceIdParam,
} = require("@validators/device.validators");

const { validate } = require("@validators/common");

router.use(headers);

// Decrypt key route
Expand Down Expand Up @@ -146,4 +149,12 @@ router.put(
validateBulkUpdateDevices,
deviceController.updateManyDevicesOnPlatform
);

router.get(
"/:id",
validateTenant,
validateDeviceIdParam,
validate,
deviceController.getDeviceDetailsById
);
module.exports = router;
9 changes: 9 additions & 0 deletions src/device-registry/routes/v2/sites.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const {
validateSiteQueryParams,
validateMandatorySiteIdentifier,
validateCreateSite,
validateSiteIdParam,
validateSiteMetadata,
validateUpdateSite,
validateRefreshSite,
Expand All @@ -16,6 +17,7 @@ const {
validateNearestSite,
validateBulkUpdateSites,
} = require("@validators/site.validators");
const { validate } = require("@validators/common");
const { headers, pagination } = require("@validators/common");

router.use(headers);
Expand Down Expand Up @@ -99,4 +101,11 @@ router.get(
siteController.findNearestSite
);
router.put("/bulk", validateBulkUpdateSites, siteController.updateManySites);
router.get(
"/:id",
validateTenant,
validateSiteIdParam,
validate,
siteController.getSiteDetailsById
);
module.exports = router;
32 changes: 32 additions & 0 deletions src/device-registry/utils/device.util.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,38 @@ const kafka = new Kafka({
});

const createDevice = {
getDeviceById: async (req, next) => {
try {
const { id } = req.params;
const { tenant } = req.query;

const device = await DeviceModel(tenant.toLowerCase()).findById(id);

if (!device) {
throw new HttpError("Device not found", httpStatus.NOT_FOUND);
}

return {
success: true,
message: "Device details fetched successfully",
data: device,
status: httpStatus.OK,
};
} catch (error) {
if (error instanceof HttpError) {
next(error);
return;
}
logger.error(`🐛🐛 Internal Server Error ${error.message}`);
next(
new HttpError(
"Internal Server Error",
httpStatus.INTERNAL_SERVER_ERROR,
{ message: error.message }
)
);
}
},
doesDeviceSearchExist: async (request, next) => {
try {
const { filter, tenant } = request;
Expand Down
33 changes: 32 additions & 1 deletion src/device-registry/utils/site.util.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,38 @@ const kafka = new Kafka({
});

const createSite = {
getSiteById: async (req, next) => {
try {
const { id } = req.params;
const { tenant } = req.query;

const site = await SiteModel(tenant.toLowerCase()).findById(id);

if (!site) {
throw new HttpError("site not found", httpStatus.NOT_FOUND);
}

return {
success: true,
message: "site details fetched successfully",
data: site,
status: httpStatus.OK,
};
} catch (error) {
if (error instanceof HttpError) {
next(error);
return;
}
logger.error(`🐛🐛 Internal Server Error ${error.message}`);
next(
new HttpError(
"Internal Server Error",
httpStatus.INTERNAL_SERVER_ERROR,
{ message: error.message }
)
);
}
},
fetchSiteDetails: async (tenant, req, next) => {
const filter = generateFilter.sites(req, next);
logObject("the filter being used to filter", filter);
Expand Down Expand Up @@ -79,7 +111,6 @@ const createSite = {

return request;
},

fetchAdditionalSiteDetails: async (tenant, id, next) => {
const baseQuery = { query: { tenant, id } };
const additionalDetails = {};
Expand Down
15 changes: 14 additions & 1 deletion src/device-registry/validators/device.validators.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { query, body, oneOf } = require("express-validator");
const { query, body, oneOf, param } = require("express-validator");
const constants = require("@config/constants");
const mongoose = require("mongoose");
const ObjectId = mongoose.Types.ObjectId;
Expand Down Expand Up @@ -76,6 +76,18 @@ const validateDeviceIdentifier = oneOf([
.withMessage("the device names do not have spaces in them"),
]);

const validateDeviceIdParam = [
param("id")
.exists()
.withMessage("The device ID is missing in the request path.")
.bail()
.trim()
.isMongoId()
.withMessage("Invalid device ID. Must be a valid MongoDB ObjectId.")
.bail()
.customSanitizer((value) => ObjectId(value)),
];

const validateCreateDevice = [
oneOf([
body("name")
Expand Down Expand Up @@ -813,6 +825,7 @@ module.exports = {
validateArrayBody,
validateCreateDevice,
validateUpdateDevice,
validateDeviceIdParam,
validateEncryptKeys,
validateListDevices,
validateDecryptKeys,
Expand Down
49 changes: 38 additions & 11 deletions src/device-registry/validators/site.validators.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { query, body, oneOf } = require("express-validator");
const { query, body, oneOf, param } = require("express-validator");
const constants = require("@config/constants");
const mongoose = require("mongoose");
const ObjectId = mongoose.Types.ObjectId;
Expand Down Expand Up @@ -60,19 +60,38 @@ const createMongoIdValidation = (field, options = {}) => {
isOptional = false,
existsMessage = `the ${field} identifier is missing in request`,
isQuery = true,
isParam = false,
isBody = false, // Add isBody option
} = options;

const validationChain = isQuery
? isOptional
? query(field).optional()
: query(field)
let validationChain;

if (isParam) {
validationChain = isOptional
? param(field).optional()
: param(field)
.exists()
.withMessage(existsMessage)
: isOptional
? body(field).optional()
: body(field)
.exists()
.withMessage(existsMessage);
.withMessage(existsMessage);
} else if (isBody) {
validationChain = isOptional
? body(field).optional()
: body(field)
.exists()
.withMessage(existsMessage);
} else {
// Default to query parameter validation
validationChain = isQuery
? isOptional
? query(field).optional()
: query(field)
.exists()
.withMessage(existsMessage)
: isOptional
? body(field).optional()
: body(field)
.exists()
.withMessage(existsMessage);
}

return validationChain
.notEmpty()
Expand Down Expand Up @@ -169,6 +188,13 @@ const siteIdentifierChains = [
.trim(),
];

const validateSiteIdParam = oneOf([
createMongoIdValidation("id", {
isParam: true,
existsMessage: "The site ID is missing in the request path.",
}),
]);

// Composed Validation Middleware
const validateSiteIdentifier = siteIdentifierChains;

Expand Down Expand Up @@ -464,5 +490,6 @@ module.exports = {
validateGetApproximateCoordinates,
validateNearestSite,
validateBulkUpdateSites,
validateSiteIdParam,
validateCategoryField,
};

0 comments on commit 1425080

Please sign in to comment.