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

Feat: Add endpoints to retrieve site and device details by ID #4407

Closed
wants to merge 1 commit into from

Conversation

Baalmart
Copy link
Contributor

@Baalmart Baalmart commented Feb 11, 2025

Description

This pull request introduces new API endpoints to retrieve detailed information for both sites and devices using their respective IDs. These endpoints enhance the API's functionality by allowing clients to directly access specific site and device records.

Changes Made

  • Added GET /api/sites/:id endpoint to retrieve site details by ID.
  • Implemented getSiteDetailsById controller method for handling site ID requests.
  • Created getSiteById utility function in site.util.js for data access.
  • Added validateSiteIdParam validator in site.validators.js to validate site IDs.
  • Added GET /api/devices/:id endpoint to retrieve device details by ID.
  • Implemented getDeviceDetailsById controller method for handling device ID requests.
  • Created getDeviceById utility function in device.util.js for data access.
  • Added validateDeviceIdParam validator in device.validators.js to validate device IDs.
  • Updated API documentation to include the new endpoints.
  • Added comprehensive error handling for invalid IDs and not found scenarios (400 and 404 responses).

Testing

  • Tested locally
  • Tested against staging environment
  • Relevant tests passed: [List test names]

Affected Services

  • Which services were modified:
    • Device Registry

Endpoints Ready for Testing

  • New endpoints ready for testing:
    • Get device information
    • Get site information

API Documentation Updated?

  • Yes, API documentation was updated
  • No, API documentation does not need updating

Summary by CodeRabbit

  • New Features
    • Introduced new endpoints for retrieving device and site details using unique identifiers.
    • Enabled lookup of the nearest site based on provided coordinates.
    • Enhanced validations to ensure necessary identifier parameters are present.
    • Improved error handling to offer a smoother experience when retrieving details.

Copy link
Contributor

coderabbitai bot commented Feb 11, 2025

📝 Walkthrough

Walkthrough

This PR adds new asynchronous methods to fetch device and site details by ID and to find the nearest site. In the controllers, methods are added that check for an optional tenant parameter, call corresponding utility functions, and handle errors via HttpError. New GET endpoints are introduced in the routes with middleware validations for tenant and parameter formats. Additionally, utility functions are provided to retrieve database records for devices and sites, and validators using express-validator have been enhanced for proper ObjectId checks.

Changes

File(s) Change Summary
src/.../device.controller.js, src/.../site.controller.js Added async methods getDeviceDetailsById (device) and getSiteDetailsById, findNearestSite (site) with tenant checks, utility function calls, and error handling via HttpError.
src/.../devices.routes.js, src/.../sites.routes.js Introduced new GET /:id endpoints with middleware validations (tenant, ID parameters) linked to their respective controller methods.
src/.../device.util.js, src/.../site.util.js Added async functions getDeviceById and getSiteById for database retrieval; both include error handling to return appropriate HTTP responses.
src/.../device.validators.js, src/.../site.validators.js Added validateDeviceIdParam and validateSiteIdParam using express-validator’s param method to ensure proper ObjectId validation in route parameters.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Server
    participant DC as DeviceController
    participant DU as DeviceUtil
    participant DB as DeviceModel

    Client->>Server: GET /devices/:id
    Server->>DC: getDeviceDetailsById(req, res, next)
    DC->>DU: getDeviceById(req, next)
    DU->>DB: Query device by ID
    alt Device Found
        DB-->>DU: Return device details
        DU-->>DC: Return details
        DC->>Server: handleResponse(details)
        Server-->>Client: 200 OK with device details
    else Error/Not Found
        DB-->>DU: Return error
        DU-->>DC: Propagate error
        DC->>Server: next(HttpError)
        Server-->>Client: Error response
    end
Loading
sequenceDiagram
    participant Client
    participant Server
    participant SC as SiteController
    participant SU as SiteUtil
    participant DB as SiteModel

    Client->>Server: GET /sites/:id
    Server->>SC: getSiteDetailsById(req, res, next)
    SC->>SU: getSiteById(req, next)
    SU->>DB: Query site by ID
    alt Site Found
        DB-->>SU: Return site details
        SU-->>SC: Return details
        SC->>Server: handleResponse(details)
        Server-->>Client: 200 OK with site details
    else Error/Not Found
        DB-->>SU: Return error
        SU-->>SC: Propagate error
        SC->>Server: next(HttpError)
        Server-->>Client: Error response
    end
Loading

Possibly related issues

  • (None – the provided issue regarding enhancing PUT endpoint tests does not directly relate to the new GET endpoints and associated validations.)

Possibly related PRs

Poem

In the realm of code, a spark ignites,
Routes and controllers join in graceful flights.
Validators and utils now shine so bright,
Fetching details with asynchronous might.
Errors tamed with care, our code feels light,
Celebrating new endpoints through day and night!

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • JIRA integration encountered authorization issues. Please disconnect and reconnect the integration in the CodeRabbit UI.
✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

codecov bot commented Feb 11, 2025

Codecov Report

Attention: Patch coverage is 22.22222% with 42 lines in your changes missing coverage. Please review.

Project coverage is 11.24%. Comparing base (d970a18) to head (1425080).
Report is 39 commits behind head on staging.

Files with missing lines Patch % Lines
src/device-registry/utils/device.util.js 0.00% 12 Missing ⚠️
src/device-registry/utils/site.util.js 0.00% 12 Missing ⚠️
...c/device-registry/controllers/device.controller.js 0.00% 8 Missing ⚠️
src/device-registry/controllers/site.controller.js 0.00% 8 Missing ⚠️
...rc/device-registry/validators/device.validators.js 66.66% 1 Missing ⚠️
src/device-registry/validators/site.validators.js 85.71% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           staging    #4407      +/-   ##
===========================================
+ Coverage    11.22%   11.24%   +0.01%     
===========================================
  Files          156      156              
  Lines        17955    18006      +51     
  Branches       388      388              
===========================================
+ Hits          2016     2025       +9     
- Misses       15937    15979      +42     
  Partials         2        2              
Files with missing lines Coverage Δ
src/device-registry/routes/v2/devices.routes.js 100.00% <100.00%> (ø)
src/device-registry/routes/v2/sites.routes.js 100.00% <100.00%> (ø)
...rc/device-registry/validators/device.validators.js 22.34% <66.66%> (+0.60%) ⬆️
src/device-registry/validators/site.validators.js 34.90% <85.71%> (+2.23%) ⬆️
...c/device-registry/controllers/device.controller.js 2.91% <0.00%> (-0.06%) ⬇️
src/device-registry/controllers/site.controller.js 2.74% <0.00%> (-0.07%) ⬇️
src/device-registry/utils/device.util.js 4.91% <0.00%> (-0.18%) ⬇️
src/device-registry/utils/site.util.js 4.25% <0.00%> (-0.12%) ⬇️

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (5)
src/device-registry/routes/v2/devices.routes.js (1)

153-159: LGTM! Consider adding JSDoc comments.

The new route implementation follows the established pattern and includes proper validation middleware. To improve maintainability, consider adding JSDoc comments to document the route's purpose, parameters, and response format.

Add JSDoc comments above the route:

+/**
+ * @route GET /api/devices/:id
+ * @description Retrieve device details by ID
+ * @param {string} id - The device ID
+ * @param {string} [tenant] - Optional tenant parameter
+ * @returns {Object} Device details
+ */
router.get(
  "/:id",
  validateTenant,
  validateDeviceIdParam,
  validate,
  deviceController.getDeviceDetailsById
);
src/device-registry/controllers/device.controller.js (1)

53-73: LGTM! Consider adding input validation.

The controller implementation follows the established pattern with proper error handling and consistent response format. However, consider adding input validation for the extracted parameters before processing.

Add parameter validation:

 getDeviceDetailsById: async (req, res, next) => {
   try {
     const { id } = req.params;
+    if (!id) {
+      throw new HttpError("Device ID is required", httpStatus.BAD_REQUEST);
+    }
     const defaultTenant = constants.DEFAULT_TENANT || "airqo";
     req.query.tenant = isEmpty(req.query.tenant)
       ? defaultTenant
       : req.query.tenant;
src/device-registry/utils/device.util.js (1)

22-53: LGTM! Consider adding debug logging.

The utility implementation follows best practices with proper error handling and consistent response format. Adding debug logging would help with troubleshooting.

Add debug logging:

 getDeviceById: async (req, next) => {
   try {
     const { id } = req.params;
     const { tenant } = req.query;
+    logger.debug(`Fetching device with ID: ${id} for tenant: ${tenant}`);

     const device = await DeviceModel(tenant.toLowerCase()).findById(id);
+    logger.debug(`Device found: ${!!device}`);

     if (!device) {
       throw new HttpError("Device not found", httpStatus.NOT_FOUND);
     }
src/device-registry/controllers/site.controller.js (1)

47-68: Consider enhancing error handling with specific error types.

While the error handling is good, consider differentiating between different types of errors (e.g., validation errors, not found errors) for better client-side error handling.

Apply this diff to improve error handling:

 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}`);
+    if (error instanceof HttpError) {
+      next(error);
+      return;
+    }
     next(
       new HttpError(
         "Internal Server Error",
         httpStatus.INTERNAL_SERVER_ERROR,
         { message: error.message }
       )
     );
   }
 },
src/device-registry/utils/site.util.js (1)

32-63: Consider adding field selection for better performance.

The current implementation fetches all fields from the database. Consider selecting only the required fields to optimize performance.

Apply this diff to optimize the database query:

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

-    const site = await SiteModel(tenant.toLowerCase()).findById(id);
+    const site = await SiteModel(tenant.toLowerCase())
+      .findById(id)
+      .select('name latitude longitude status created_at updated_at'); // Add required fields

     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 }
       )
     );
   }
 },
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 84c959f and 1425080.

📒 Files selected for processing (8)
  • src/device-registry/controllers/device.controller.js (1 hunks)
  • src/device-registry/controllers/site.controller.js (2 hunks)
  • src/device-registry/routes/v2/devices.routes.js (2 hunks)
  • src/device-registry/routes/v2/sites.routes.js (3 hunks)
  • src/device-registry/utils/device.util.js (1 hunks)
  • src/device-registry/utils/site.util.js (1 hunks)
  • src/device-registry/validators/device.validators.js (3 hunks)
  • src/device-registry/validators/site.validators.js (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: build-push-deploy-device-registry
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (4)
src/device-registry/validators/device.validators.js (1)

79-89: LGTM! Well-structured validator implementation.

The validator follows best practices with proper existence checks, format validation, and clear error messages. The use of customSanitizer to convert the ID to ObjectId is a good practice.

src/device-registry/routes/v2/sites.routes.js (1)

104-110: LGTM! Well-structured route with proper validation middleware.

The route follows RESTful conventions and includes necessary validations for tenant and site ID parameters.

src/device-registry/validators/site.validators.js (2)

63-64: LGTM! Well-implemented parameter validation logic.

The validation logic properly handles route parameters while maintaining compatibility with existing query and body validation.

Also applies to: 69-94


191-196: LGTM! Clear and concise site ID parameter validation.

The validator ensures the site ID is present in the request path and is a valid MongoDB ObjectId.

@Baalmart Baalmart closed this Feb 11, 2025
@Baalmart Baalmart deleted the feat/get-site-device-by-id branch February 11, 2025 01:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant