Skip to content

Conversation

@UlisesGascon
Copy link
Member

@UlisesGascon UlisesGascon commented May 1, 2025

Related #219

Summary by CodeRabbit

  • New Features

    • Added a health check endpoint to the API for monitoring service status.
    • Introduced an endpoint to generate static reports, with improved handling for clearing previous reports.
    • Added a utility to verify database connectivity before starting the server.
  • Improvements

    • Enhanced server startup and shutdown processes for better reliability and error handling.
    • Improved report generation workflow with clearer options and success/failure feedback.
  • Refactor

    • Streamlined API routing and server initialization for maintainability.
    • Renamed and updated report generation functions and exports for clarity.
  • Tests

    • Updated and reorganized test suite for the HTTP server, adding new tests and improving setup/teardown.

@UlisesGascon UlisesGascon requested a review from Copilot May 1, 2025 16:10
@UlisesGascon UlisesGascon self-assigned this May 1, 2025
@coderabbitai
Copy link

coderabbitai bot commented May 1, 2025

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

📥 Commits

Reviewing files that changed from the base of the PR and between 26b69cf and db903b7.

📒 Files selected for processing (4)
  • __tests__/httpServer.test.js (1 hunks)
  • src/httpServer/apiV1.js (1 hunks)
  • src/httpServer/index.js (2 hunks)
  • src/reports/index.js (3 hunks)
 ____________________________________________________________________________________________________________________________________
< Contrary to popular belief, Unix is user friendly. It just happens to be very selective about who it decides to make friends with. >
 ------------------------------------------------------------------------------------------------------------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ

Walkthrough

This update refactors the HTTP server and report generation workflow to improve modularity and control over server lifecycle. The server startup and shutdown are now asynchronous, with explicit start and stop methods. The API router is modularized into a separate file, introducing endpoints for health checks and report generation. The report generation function is renamed and enhanced to support clearing previous reports. Test suites are updated to reflect these changes, including improved setup/teardown and endpoint coverage. Utility functions for database connection checks are added, and related imports and exports are updated throughout the codebase.

Changes

File(s) Change Summary
src/httpServer/apiV1.js New module exporting createApiRouter, setting up /__health and /generate-reports endpoints with report generation and error handling logic.
src/httpServer/index.js Refactored server initialization to use modular API router, asynchronous start/stop methods, and database connectivity checks. Export updated to provide these methods.
src/reports/index.js Renamed generateReports to generateStaticReports; added optional clearPreviousReports flag to delete previous reports before generation; updated export.
src/cli/workflows.js Updated import and workflow reference to use generateStaticReports instead of generateReports.
src/utils/index.js Added and exported new checkDatabaseConnection utility for verifying database connectivity.
server.js Changed server startup to use async IIFE and await the new start() method from the server interface.
__tests__/httpServer.test.js Refactored tests for async server lifecycle, improved organization, mocked report generation, and added/updated endpoint tests. Removed 404 test.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant ExpressApp
    participant ApiRouter
    participant ReportsModule
    participant Database
    participant Logger

    Client->>ExpressApp: GET /__health
    ExpressApp->>ApiRouter: /__health
    ApiRouter-->>Client: { status: "ok", timestamp }

    Client->>ExpressApp: GET /api/v1/generate-reports
    ExpressApp->>ApiRouter: /generate-reports
    ApiRouter->>ReportsModule: generateStaticReports(knex, { clearPreviousReports: true })
    ReportsModule->>Database: Fetch data, etc.
    ReportsModule-->>ApiRouter: Success/Failure
    ApiRouter-->>Client: { status: "completed"/"failed", timestamp }
    ApiRouter-->>Logger: Log errors if any
Loading
sequenceDiagram
    participant Main
    participant Server
    participant Database
    participant Logger

    Main->>Server: start()
    Server->>Database: checkDatabaseConnection()
    Database-->>Server: Success/Failure
    alt Success
        Server->>Main: Server listening
    else Failure
        Server->>Logger: Log error
        Server->>Main: Exit process
    end

    Main->>Server: stop()
    Server->>Database: Destroy connection
    Server->>Main: Server stopped
Loading

Possibly related PRs

  • OpenPathfinder/visionBoard#221: Refactored the HTTP server API, introduced Express-based API with a health check endpoint, which is directly built upon and extended in this PR.

Poem

In the warren, code hops anew,
Server starts and stops on cue.
Reports now clear the old with glee,
Health checks chirp, “All’s well, you see!”
Async flows and routers split,
Rabbits thump for code well knit.
🐇✨

✨ Finishing Touches
  • 📝 Docstrings were successfully generated. (🔄 Check again to generate docstrings again)

🪧 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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @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

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces a new endpoint GET /api/v1/generate-reports to generate reports and integrates database connectivity checks at server startup. Key changes include:

  • Adding an asynchronous database connection check utility.
  • Refactoring the report generation function to clear previous reports if specified.
  • Updating server initialization and API router configuration to use the new functions.

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/utils/index.js Added checkDatabaseConnection utility and updated module exports
src/reports/index.js Renamed generateReports to generateStaticReports with option handling
src/httpServer/index.js Integrated database connection check and updated API router usage
src/httpServer/apiV1.js Updated API router to use generateStaticReports and handle errors
src/cli/workflows.js Updated CLI workflows to call generateStaticReports
server.js Modified startup to asynchronously start and stop the server
tests/httpServer.test.js Updated tests to accommodate asynchronous server start/stop and new API
Comments suppressed due to low confidence (1)

src/reports/index.js:44

  • The variable 'destinationFolder' is used without being declared. Please define 'destinationFolder' or pass it as a parameter to avoid runtime errors when clearing previous reports.
await rm(destinationFolder, { recursive: true, force: true })

@UlisesGascon UlisesGascon mentioned this pull request May 1, 2025
7 tasks
coderabbitai[bot]

This comment was marked as resolved.

@UlisesGascon UlisesGascon changed the title feat: add endpoint GET /api/v1/generate-reports feat: add endpoint POST /api/v1/generate-reports May 1, 2025
@UlisesGascon
Copy link
Member Author

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented May 1, 2025

✅ Actions performed

Full review triggered.

@UlisesGascon UlisesGascon merged commit 84fc89f into main May 1, 2025
6 checks passed
Copy link

@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: 1

♻️ Duplicate comments (1)
server.js (1)

1-6: Improved server lifecycle management.

The server startup has been refactored to use an async IIFE pattern, which allows for better control over the server lifecycle. This approach properly handles the asynchronous nature of the server start process and aligns with the updated server interface.

Using an IIFE is the correct approach here since Node.js doesn't support top-level await in CommonJS modules, as discussed in previous comments.

🧹 Nitpick comments (7)
server.js (2)

3-6: Consider adding error handling.

While the async initialization is good, it would be better to add error handling to catch and log any startup failures.

(async () => {
  const serverInstance = server()
-  await serverInstance.start()
+  try {
+    await serverInstance.start()
+    console.log('Server started successfully')
+  } catch (error) {
+    console.error('Failed to start server:', error)
+    process.exit(1)
+  }
})()

1-6: Consider adding graceful shutdown.

You should consider adding handlers for process termination signals (SIGTERM, SIGINT) to gracefully shut down the server.

(async () => {
  const serverInstance = server()
  await serverInstance.start()
+  
+  // Handle graceful shutdown
+  const shutdown = async (signal) => {
+    console.log(`Received ${signal}, shutting down gracefully...`)
+    try {
+      await serverInstance.stop()
+      console.log('Server stopped successfully')
+      process.exit(0)
+    } catch (error) {
+      console.error('Error during shutdown:', error)
+      process.exit(1)
+    }
+  }
+  
+  process.on('SIGTERM', () => shutdown('SIGTERM'))
+  process.on('SIGINT', () => shutdown('SIGINT'))
})()
src/httpServer/index.js (2)

55-58: Guard stop() when the server was never started

If start() failed before server.listen() executed (e.g. DB down), server.close() will throw 'Not running'.
Consider short-circuiting when server.listening is false.


7-12: Instantiate knex lazily to improve test isolation

Because the knex client is created at module load time, requiring this module twice in the same process (common in Jest’s parallel runners) reuses a single connection pool and may trigger “pool destroyed” errors after stop().
Moving the knex creation inside start() (and passing the instance to the router afterwards) avoids cross-test leakage.

Also applies to: 18-18

__tests__/httpServer.test.js (2)

2-3: Import after jest.mock for clearer intent

Jest hoists jest.mock, so the current code works, but importing the mocked module before the mock reads oddly to many contributors.
Switching the order clarifies test flow and avoids ESLint false-positives.

Also applies to: 8-12


56-61: Use .getTime() for explicit date comparison

Date objects coerce to numbers, but the intent is clearer (and type-safe) if you compare epoch milliseconds.

-      expect(finishedAt >= startedAt).toBe(true)
+      expect(finishedAt.getTime()).toBeGreaterThanOrEqual(startedAt.getTime())

Also applies to: 74-79

src/httpServer/apiV1.js (1)

11-28: Expose a status location to make 202 truly helpful

A 202 Accepted without a way to poll progress forces clients to busy-wait or guess completion time.
Consider returning a Location header (or statusUrl field) that clients can query to obtain the final state.

Example minimal change:

-      res.status(202).json({
+      res.status(202)
+        .set('Location', '/api/v1/generate-reports/status') // placeholder
+        .json({
           status: 'completed',
           startedAt: startTs,
           finishedAt: new Date().toISOString()
         })

You could also push the task ID into Redis / DB so the status endpoint can report ongoing or completed jobs.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 8a2f2d1 and db903b7.

📒 Files selected for processing (7)
  • __tests__/httpServer.test.js (1 hunks)
  • server.js (1 hunks)
  • src/cli/workflows.js (2 hunks)
  • src/httpServer/apiV1.js (1 hunks)
  • src/httpServer/index.js (2 hunks)
  • src/reports/index.js (3 hunks)
  • src/utils/index.js (2 hunks)
🔇 Additional comments (9)
src/utils/index.js (2)

126-134: Well-implemented database connection check utility.

The checkDatabaseConnection function is a clean implementation of a database connectivity check. It follows good practices by using async/await with proper error handling and returning clear boolean responses.


145-145: Function exported correctly.

The new utility function is properly added to the module exports.

src/reports/index.js (5)

3-3: Import updated to include the rm function.

The rm function from node:fs.promises is now properly imported to support clearing previous reports.


40-46: Good implementation of report cleanup option.

The renaming to generateStaticReports and addition of the clearPreviousReports option improves the function's flexibility. The implementation correctly removes existing reports when requested using the rm function with appropriate options.


49-69: Performance improvement using Promise.all.

Excellent optimization by running database queries in parallel with Promise.all instead of sequential awaits. This can significantly improve performance, especially with multiple independent database operations.


121-121: Added success log for better observability.

Adding a success log message at the end of report generation improves observability and makes it easier to track execution flow.


125-125: Updated export to reflect function rename.

The module export is correctly updated to use the new function name.

src/cli/workflows.js (2)

4-4: Import updated to use the renamed function.

The import statement has been updated to reflect the renaming of generateReports to generateStaticReports.


31-31: Workflow reference updated to use the renamed function.

The workflow property of the generate-reports command has been updated to use the renamed function.

coderabbitai bot added a commit that referenced this pull request May 1, 2025
Docstrings generation was requested by @UlisesGascon.

* #223 (comment)

The following files were modified:

* `src/httpServer/apiV1.js`
@coderabbitai
Copy link

coderabbitai bot commented May 1, 2025

Note

Generated docstrings for this pull request at #224

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants