Skip to content

Conversation

@visz11
Copy link

@visz11 visz11 commented Nov 10, 2025

CodeAnt-AI Description

Expose commit report details via GraphQL with filters and pagination

What Changed

  • Introduces a new GraphQL query that returns commit report details (commit metrics) for an organization.
  • Query accepts a metric name and supports filtering by assignees, repositories, PR IDs, sprint-based date ranges, and timezone.
  • Results are returned in a paginated form (page number and page size).

Impact

✅ Retrieve commit reports via GraphQL
✅ Paginated commit detail responses
✅ Filter commits by PR IDs and sprint date range

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Summary by CodeRabbit

  • New Features
    • Added capability to retrieve commit report details with filtering by metrics, granularity, and custom parameters, including pagination support for analyzing commit data across projects and assignees.

@codeant-ai
Copy link

codeant-ai bot commented Nov 10, 2025

CodeAnt AI is reviewing your PR.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai
Copy link

coderabbitai bot commented Nov 10, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

A new GraphQL query resolver class DataDetailsQuery has been introduced that orchestrates multiple services and repositories to expose commit report details. The resolver initializes date ranges, resolves metric configurations, derives assignee and project lists, and delegates to a custom repository to retrieve paginated commit metric details.

Changes

Cohort / File(s) Summary
GraphQL Query Resolver
DataDetailsQuery.java
New Spring component implementing GraphQLQueryResolver. Exposes getCommitReportDetail() method that accepts metric name, granularity, filter, pagination parameters. Orchestrates metric resolution, date range initialization, assignee/project derivation, and delegates to gitUnitPrCustomRepo to retrieve paginated CommitMetricDetails. Wires multiple autowired dependencies including repositories, services, and exception handler.

Sequence Diagram

sequenceDiagram
    participant Client as GraphQL Client
    participant Resolver as DataDetailsQuery
    participant MetricService as MetricService
    participant Repo as gitUnitPrCustomRepo
    participant Response as Response

    Client->>Resolver: getCommitReportDetail(metric, granularity, filter, pageNumber, pageSize)
    
    rect rgb(240, 248, 255)
        Note over Resolver: Initialization Phase
        Resolver->>Resolver: Initialize date range from filter
        Resolver->>MetricService: Resolve MetricConfig by metric name
        MetricService-->>Resolver: MetricConfig
        Resolver->>Resolver: Convert metric string to Metric enum
        Resolver->>Resolver: Derive assignee & project lists from filter & config
        Resolver->>Resolver: Build prIds list from filter (if present)
    end
    
    rect rgb(230, 245, 230)
        Note over Resolver: Data Retrieval Phase
        Resolver->>Repo: getCommitReportDetailList(orgId, metricType, dateRange, assignees, repos, prIds, timeZone, pageNumber, pageSize)
        Repo-->>Resolver: CommitMetricDetails
    end
    
    Resolver->>Response: Return CommitMetricDetails
    Response-->>Client: GraphQL Response
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10–15 minutes

  • Single new file with straightforward orchestration pattern
  • Delegates to existing repositories and services without introducing complex business logic
  • Primary review focus: verify correct parameter passing through the delegation chain and ensure date range/metric resolution logic aligns with expected behavior

Poem

🐰✨ A query resolver hops into view,
Stitching services with threads so true,
Metrics and commits in harmony dance,
Paginated details get their sweet chance!
— Fluffy the Code Rabbit 🌟

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: introducing a new DataDetailsQuery class for GraphQL queries, which matches the raw_summary content.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch Add-DataDetailsQuery-class-for-GraphQL-queries

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link

Summary of Changes

Hello @visz11, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a new GraphQL query component, DataDetailsQuery.java, which is responsible for exposing detailed analytical data, particularly focusing on commit report metrics. By integrating various existing data access layers and business logic services, this new class provides a structured and filterable interface for retrieving comprehensive commit-related information via GraphQL.

Highlights

  • New GraphQL Query Class: A new Java class, DataDetailsQuery, has been added to serve as a GraphQL query resolver. This class extends BaseQuery and implements GraphQLQueryResolver.
  • Commit Report Details Endpoint: The DataDetailsQuery class introduces a new GraphQL endpoint, getCommitReportDetail, which allows for fetching detailed commit report metrics based on various filters such as metric type, granularity, organization ID, date ranges, assignees, repositories, and PR IDs.
  • Extensive Dependency Injection: The new query class is heavily reliant on Spring's dependency injection, autowiring numerous custom repository implementations (e.g., IssueUnitCustomRepoImpl, GitUnitPrCustomRepoImpl) and service components (e.g., ContributorService, CustomMetricService) to gather and process data for the GraphQL queries.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@codeant-ai codeant-ai bot added the size:M This PR changes 30-99 lines, ignoring generated files label Nov 10, 2025
@visz11
Copy link
Author

visz11 commented Nov 10, 2025

/refacto-visz

@codeant-ai
Copy link

codeant-ai bot commented Nov 10, 2025

CodeAnt AI finished reviewing your PR.

@refacto-visz
Copy link

refacto-visz bot commented Nov 10, 2025

Refacto is reviewing this PR. Please wait for the review comments to be posted.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request adds a new DataDetailsQuery class for GraphQL queries. My review focuses on improving maintainability, robustness, and code clarity. The main points include removing a large number of unused dependencies, adopting constructor injection over field injection, improving error handling, and other minor code refinements. Addressing these points will make the code cleaner and more robust.

Comment on lines +40 to +78
@Autowired
IssueUnitCustomRepoImpl issueUnitCustomRepo;
@Autowired
BuildDeploymentUnitCustomRepo buildDeploymentUnitCustomRepo;

@Autowired
GitUnitPrCustomRepoImpl gitUnitPrCustomRepo;

@Autowired
VulnerabilityUnitsCustomRepo vulnerabilityUnitsCustomRepo;

@Autowired
EventLogGitCustomRepoImpl eventLogGitCustomRepo;

@Autowired
ContributorService contributorService;

@Autowired
Games24X7CustomRepoImpl games24X7CustomRepo;

@Autowired
TeamService teamService;
@Autowired
private CustomMetricService customMetricService;
@Autowired
private GlobalExceptionHandler globalExceptionHandler;

@Autowired
private WorkBreakdownCustomRepo workBreakdownCustomRepo;
@Autowired
private MetricsMetadataService metricsMetadataService;
@Autowired
private RecruitCRMCustomQueryRepoImpl recruitCRMCustomQueryRepo;
@Autowired
private DeliverableService deliverableService;
@Autowired
private GitMetricCalculationStrategy gitMetricCalculationStrategy;
@Autowired
private SprintCustomRepoImpl sprintCustomRepo;

Choose a reason for hiding this comment

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

high

This class injects a large number of dependencies, but only gitUnitPrCustomRepo is actually used. This violates the YAGNI (You Ain't Gonna Need It) principle and makes the class harder to maintain. Additionally, it's a best practice to use constructor injection instead of field injection. Constructor injection makes dependencies explicit, improves testability, and helps ensure objects are always in a valid state. Please remove all unused dependencies and use constructor injection for the required ones.

Suggested change
@Autowired
IssueUnitCustomRepoImpl issueUnitCustomRepo;
@Autowired
BuildDeploymentUnitCustomRepo buildDeploymentUnitCustomRepo;
@Autowired
GitUnitPrCustomRepoImpl gitUnitPrCustomRepo;
@Autowired
VulnerabilityUnitsCustomRepo vulnerabilityUnitsCustomRepo;
@Autowired
EventLogGitCustomRepoImpl eventLogGitCustomRepo;
@Autowired
ContributorService contributorService;
@Autowired
Games24X7CustomRepoImpl games24X7CustomRepo;
@Autowired
TeamService teamService;
@Autowired
private CustomMetricService customMetricService;
@Autowired
private GlobalExceptionHandler globalExceptionHandler;
@Autowired
private WorkBreakdownCustomRepo workBreakdownCustomRepo;
@Autowired
private MetricsMetadataService metricsMetadataService;
@Autowired
private RecruitCRMCustomQueryRepoImpl recruitCRMCustomQueryRepo;
@Autowired
private DeliverableService deliverableService;
@Autowired
private GitMetricCalculationStrategy gitMetricCalculationStrategy;
@Autowired
private SprintCustomRepoImpl sprintCustomRepo;
private final GitUnitPrCustomRepoImpl gitUnitPrCustomRepo;
@Autowired
public DataDetailsQuery(GitUnitPrCustomRepoImpl gitUnitPrCustomRepo) {
this.gitUnitPrCustomRepo = gitUnitPrCustomRepo;
}

@Autowired
private SprintCustomRepoImpl sprintCustomRepo;

public CommitMetricDetails getCommitReportDetail(String metric, String granularity, Filter filter, Integer pageNumber, Integer pageSize) throws Exception {

Choose a reason for hiding this comment

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

medium

The granularity parameter is not used within the getCommitReportDetail method. It should be removed to simplify the method signature and avoid confusion.

Suggested change
public CommitMetricDetails getCommitReportDetail(String metric, String granularity, Filter filter, Integer pageNumber, Integer pageSize) throws Exception {
public CommitMetricDetails getCommitReportDetail(String metric, Filter filter, Integer pageNumber, Integer pageSize) throws Exception {

@Autowired
private SprintCustomRepoImpl sprintCustomRepo;

public CommitMetricDetails getCommitReportDetail(String metric, String granularity, Filter filter, Integer pageNumber, Integer pageSize) throws Exception {

Choose a reason for hiding this comment

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

medium

The method signature declares throws Exception, which is too broad and can hide specific issues. It's better to declare the specific checked exceptions that the method can throw, or handle them inside the method. This makes error handling more robust and explicit for the callers of this method.

public CommitMetricDetails getCommitReportDetail(String metric, String granularity, Filter filter, Integer pageNumber, Integer pageSize) throws Exception {
setDateRangeFromSprintId(filter);
MetricConfig metricConfig = getMetricConfig(metric);
Metric metricType = Metric.valueOf(metric);

Choose a reason for hiding this comment

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

medium

Metric.valueOf(metric) will throw an IllegalArgumentException if the input metric string does not match any enum constant. This is an unchecked exception that will result in a server error if not handled. It's better to validate the input or catch the exception to provide a more graceful error response to the client, for example, a GraphQL error indicating a bad request.

Example:

try {
    Metric metricType = Metric.valueOf(metric);
} catch (IllegalArgumentException e) {
    // It's good practice to throw a specific GraphQL exception
    // that will be translated into a proper error response.
    throw new GraphQLException("Invalid 'metric' parameter provided.");
}

Pair<List<String>, List<String>> assigneeAndProjectList = getAssigneeAndProjectList(filter, metricConfig);
List<String> repoList = assigneeAndProjectList.getRight();
List<String> assignees = assigneeAndProjectList.getLeft();
List<String> prIds = filter.getPrViewFilters() != null && CollectionUtils.isNotEmpty(filter.getPrViewFilters().getPrIds()) ? filter.getPrViewFilters().getPrIds() : new ArrayList<>();

Choose a reason for hiding this comment

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

medium

This line can be slightly improved. Using Collections.emptyList() is generally preferred over new ArrayList<>() for creating an empty list, as it avoids allocating a new object when no PR IDs are provided.

Suggested change
List<String> prIds = filter.getPrViewFilters() != null && CollectionUtils.isNotEmpty(filter.getPrViewFilters().getPrIds()) ? filter.getPrViewFilters().getPrIds() : new ArrayList<>();
List<String> prIds = filter.getPrViewFilters() != null && CollectionUtils.isNotEmpty(filter.getPrViewFilters().getPrIds()) ? filter.getPrViewFilters().getPrIds() : Collections.emptyList();

List<String> assignees = assigneeAndProjectList.getLeft();
List<String> prIds = filter.getPrViewFilters() != null && CollectionUtils.isNotEmpty(filter.getPrViewFilters().getPrIds()) ? filter.getPrViewFilters().getPrIds() : new ArrayList<>();

CommitMetricDetails commitMetricDetails = gitUnitPrCustomRepo.getCommitReportDetailList(filter.getOrgId(), metricType, filter.getLocalStartDateFromEndDate(), filter.getEndDate(),assignees, repoList, prIds, filter.getTimeZone(), pageNumber, pageSize);

Choose a reason for hiding this comment

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

medium

The method getCommitReportDetailList is assigned to a variable of type CommitMetricDetails, which seems to be a single object, not a list. The List suffix in the method name is misleading. If the method returns a single object, consider renaming it in GitUnitPrCustomRepoImpl to something like getCommitReportDetails to improve clarity.

@refacto-visz
Copy link

refacto-visz bot commented Nov 10, 2025

Code Review: GraphQL Query Implementation

👍 Well Done
Clean GraphQL Implementation

Well-structured GraphQL query resolver with proper inheritance pattern and clear service separation

Proper Dependency Injection

Appropriate use of @Autowired annotations enabling testability and loose coupling

📁 Selected files for review (1)
  • DataDetailsQuery.java
🎯 Custom Instructions
✅ Applied Instructions
Organization Guidelines
  • Keep pull requests small and focused (prefer < 400 lines of code).
  • All CI/CD checks, linting, and unit tests must pass before merge.
  • Use feature flags for new functionality and include a clear rollback plan.
  • Follow the company security checklist:
    • No hard-coded secrets or credentials.
    • Validate all external inputs.
    • Use parameterized queries for DB access.

Scope: All files

📝 Additional Comments
DataDetailsQuery.java (5)
Broad Exception Handling

Method declares generic Exception in throws clause which can mask specific security errors and lead to information disclosure. Broad exception handling prevents proper error categorization and may expose sensitive system information to attackers through error messages.

Standards:

  • CWE-209
  • OWASP-A09
  • NIST-SSDF-RV.1
Exception Handling Overhead

Generic Exception declaration forces callers to handle broad exception types, potentially masking specific error conditions. This can lead to inefficient error handling paths and reduced performance in error scenarios.

Standards:

  • ISO-IEC-25010-Performance-Efficiency-Time-Behavior
  • Exception-Handling-Optimization
Potential Null Dereference

Logic checks getPrViewFilters() for null but calls getPrViewFilters().getPrIds() twice without caching result. Second call could return null if object state changes between calls creating race condition.

Standards:

  • Algorithm-Correctness-State-Consistency
  • Logic-Verification-Race-Conditions
  • Business-Rule-Object-Safety
Constructor Injection Opportunity

Field injection reduces testability and makes dependencies implicit. Constructor injection would make dependencies explicit, enable immutable fields, and improve test setup by allowing mock injection without reflection.

Standards:

  • SOLID-DIP
  • Clean-Code-Dependencies
  • Maintainability-Quality-Testability
Collection Initialization Optimization

ArrayList creation without initial capacity may cause multiple resize operations if the collection grows. Consider using Collections.emptyList() for immutable empty collections or specify initial capacity if size is predictable.

Standards:

  • ISO-IEC-25010-Performance-Efficiency-Resource-Utilization
  • Memory-Allocation-Optimization

List<String> assignees = assigneeAndProjectList.getLeft();
List<String> prIds = filter.getPrViewFilters() != null && CollectionUtils.isNotEmpty(filter.getPrViewFilters().getPrIds()) ? filter.getPrViewFilters().getPrIds() : new ArrayList<>();

CommitMetricDetails commitMetricDetails = gitUnitPrCustomRepo.getCommitReportDetailList(filter.getOrgId(), metricType, filter.getLocalStartDateFromEndDate(), filter.getEndDate(),assignees, repoList, prIds, filter.getTimeZone(), pageNumber, pageSize);
Copy link

Choose a reason for hiding this comment

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

SQL Injection Risk

Multiple user-controlled parameters passed to database query method without visible input validation. Filter parameters like orgId, date ranges, assignees, and prIds could contain malicious payloads leading to SQL injection if not properly sanitized in the repository layer.

Standards
  • CWE-89
  • OWASP-A03
  • Org-Guideline-Validate all external inputs

@Autowired
private SprintCustomRepoImpl sprintCustomRepo;

public CommitMetricDetails getCommitReportDetail(String metric, String granularity, Filter filter, Integer pageNumber, Integer pageSize) throws Exception {
Copy link

Choose a reason for hiding this comment

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

Missing Input Validation

GraphQL query method accepts user input parameters without validation checks. Missing validation on metric name, pagination parameters, and filter objects could lead to injection attacks or application errors.

Standards
  • CWE-20
  • OWASP-A03
  • Org-Guideline-Validate all external inputs

Comment on lines +80 to +83
public CommitMetricDetails getCommitReportDetail(String metric, String granularity, Filter filter, Integer pageNumber, Integer pageSize) throws Exception {
setDateRangeFromSprintId(filter);
MetricConfig metricConfig = getMetricConfig(metric);
Metric metricType = Metric.valueOf(metric);
Copy link

Choose a reason for hiding this comment

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

Null Parameter Risk

Method parameters used without null validation before processing operations. Null filter parameter passed to setDateRangeFromSprintId() or null metric parameter to Metric.valueOf() causes NullPointerException.

Standards
  • ISO-IEC-25010-Reliability-Fault-Tolerance
  • DbC-Preconditions
  • ISO-IEC-25010-Functional-Correctness-Appropriateness

public CommitMetricDetails getCommitReportDetail(String metric, String granularity, Filter filter, Integer pageNumber, Integer pageSize) throws Exception {
setDateRangeFromSprintId(filter);
MetricConfig metricConfig = getMetricConfig(metric);
Metric metricType = Metric.valueOf(metric);
Copy link

Choose a reason for hiding this comment

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

Enum Conversion Failure

Metric.valueOf() throws IllegalArgumentException for invalid metric string values without exception handling. Invalid metric parameter causes uncaught runtime exception terminating GraphQL query processing.

Standards
  • ISO-IEC-25010-Reliability-Fault-Tolerance
  • ISO-IEC-25010-Functional-Correctness-Appropriateness
  • SRE-Error-Handling

import java.util.stream.Collectors;

@Component
public class DataDetailsQuery extends BaseQuery implements GraphQLQueryResolver {
Copy link

Choose a reason for hiding this comment

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

God Object Pattern

Class violates Single Responsibility Principle with 14 injected dependencies handling diverse concerns (issues, builds, vulnerabilities, git, contributors, games, teams, metrics, exceptions, work breakdown, recruitment, deliverables, sprints). This creates excessive coupling and makes the class fragile to changes across multiple domains.

@Component
public class DataDetailsQuery extends BaseQuery implements GraphQLQueryResolver {

    @Autowired
    private CommitReportService commitReportService;

    public CommitMetricDetails getCommitReportDetail(String metric, String granularity, Filter filter, Integer pageNumber, Integer pageSize) throws Exception {
        return commitReportService.getCommitReportDetail(metric, granularity, filter, pageNumber, pageSize);
    }
}
Commitable Suggestion
Suggested change
public class DataDetailsQuery extends BaseQuery implements GraphQLQueryResolver {
@Component
public class DataDetailsQuery extends BaseQuery implements GraphQLQueryResolver {
@Autowired
private CommitReportService commitReportService;
public CommitMetricDetails getCommitReportDetail(String metric, String granularity, Filter filter, Integer pageNumber, Integer pageSize) throws Exception {
return commitReportService.getCommitReportDetail(metric, granularity, filter, pageNumber, pageSize);
}
}
Standards
  • SOLID-SRP
  • Clean-Code-Class-Organization
  • Maintainability-Quality-Coupling

Comment on lines +40 to +46
@Autowired
IssueUnitCustomRepoImpl issueUnitCustomRepo;
@Autowired
BuildDeploymentUnitCustomRepo buildDeploymentUnitCustomRepo;

@Autowired
GitUnitPrCustomRepoImpl gitUnitPrCustomRepo;
Copy link

Choose a reason for hiding this comment

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

Field Injection Pattern

Field injection creates dependencies that are difficult to test and may cause initialization order issues. Constructor injection provides better testability, immutability, and fail-fast behavior during application startup.

Standards
  • ISO-IEC-25010-Performance-Efficiency-Resource-Utilization
  • Dependency-Injection-Best-Practices

Comment on lines +40 to +42
@Autowired
IssueUnitCustomRepoImpl issueUnitCustomRepo;
@Autowired
Copy link

Choose a reason for hiding this comment

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

Inconsistent Field Visibility

Inconsistent field visibility mixing package-private and private access modifiers for dependency injection. Some fields lack private modifier while others include it, creating unclear encapsulation boundaries.

Standards
  • Clean-Code-Encapsulation
  • SOLID-OCP
  • Maintainability-Quality-Consistency

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

🧹 Nitpick comments (1)
DataDetailsQuery.java (1)

40-78: Consider using constructor injection instead of field injection.

Field injection via @Autowired makes the class harder to test and hides dependencies. Constructor injection is the preferred approach for better testability and explicit dependency declaration.

Example refactor (showing pattern for a few dependencies):

-    @Autowired
-    GitUnitPrCustomRepoImpl gitUnitPrCustomRepo;
-
-    @Autowired
-    private GlobalExceptionHandler globalExceptionHandler;
+    private final GitUnitPrCustomRepoImpl gitUnitPrCustomRepo;
+    private final GlobalExceptionHandler globalExceptionHandler;
+
+    @Autowired
+    public DataDetailsQuery(
+        GitUnitPrCustomRepoImpl gitUnitPrCustomRepo,
+        GlobalExceptionHandler globalExceptionHandler
+    ) {
+        this.gitUnitPrCustomRepo = gitUnitPrCustomRepo;
+        this.globalExceptionHandler = globalExceptionHandler;
+    }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e184110 and 25c60b1.

📒 Files selected for processing (1)
  • DataDetailsQuery.java (1 hunks)

Comment on lines +40 to +78
@Autowired
IssueUnitCustomRepoImpl issueUnitCustomRepo;
@Autowired
BuildDeploymentUnitCustomRepo buildDeploymentUnitCustomRepo;

@Autowired
GitUnitPrCustomRepoImpl gitUnitPrCustomRepo;

@Autowired
VulnerabilityUnitsCustomRepo vulnerabilityUnitsCustomRepo;

@Autowired
EventLogGitCustomRepoImpl eventLogGitCustomRepo;

@Autowired
ContributorService contributorService;

@Autowired
Games24X7CustomRepoImpl games24X7CustomRepo;

@Autowired
TeamService teamService;
@Autowired
private CustomMetricService customMetricService;
@Autowired
private GlobalExceptionHandler globalExceptionHandler;

@Autowired
private WorkBreakdownCustomRepo workBreakdownCustomRepo;
@Autowired
private MetricsMetadataService metricsMetadataService;
@Autowired
private RecruitCRMCustomQueryRepoImpl recruitCRMCustomQueryRepo;
@Autowired
private DeliverableService deliverableService;
@Autowired
private GitMetricCalculationStrategy gitMetricCalculationStrategy;
@Autowired
private SprintCustomRepoImpl sprintCustomRepo;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Remove unused autowired dependencies.

Most of the 16 autowired dependencies appear unused in this class. Only gitUnitPrCustomRepo is directly referenced in the getCommitReportDetail method. The others (issueUnitCustomRepo, buildDeploymentUnitCustomRepo, vulnerabilityUnitsCustomRepo, eventLogGitCustomRepo, contributorService, games24X7CustomRepo, teamService, customMetricService, globalExceptionHandler, workBreakdownCustomRepo, metricsMetadataService, recruitCRMCustomQueryRepo, deliverableService, gitMetricCalculationStrategy, sprintCustomRepo) should be removed unless they're used by inherited methods in BaseQuery.

Run the following script to verify which dependencies are actually used:


🏁 Script executed:

#!/bin/bash
# Description: Check if each autowired dependency is referenced in DataDetailsQuery.java

echo "Checking dependency usage in DataDetailsQuery.java..."

for dep in "issueUnitCustomRepo" "buildDeploymentUnitCustomRepo" "vulnerabilityUnitsCustomRepo" \
           "eventLogGitCustomRepo" "contributorService" "games24X7CustomRepo" \
           "teamService" "customMetricService" "globalExceptionHandler" \
           "workBreakdownCustomRepo" "metricsMetadataService" "recruitCRMCustomQueryRepo" \
           "deliverableService" "gitMetricCalculationStrategy" "sprintCustomRepo"; do
  echo "---"
  echo "Dependency: $dep"
  rg -n "\b$dep\b" --type java DataDetailsQuery.java | grep -v "@Autowired" || echo "  NOT USED in DataDetailsQuery.java"
done

Length of output: 1496


The web search provides context about Spring GraphQL architecture but not specifics about this codebase. Let me generate shell scripts to verify the actual usage of these dependencies in the repository.


🏁 Script executed:

#!/bin/bash
# Find DataDetailsQuery.java and display full content
echo "=== Finding DataDetailsQuery.java ==="
fd -e java -i "datadetailsquery" --exec cat {} \;

Length of output: 4016


🏁 Script executed:

#!/bin/bash
# Find BaseQuery.java 
echo "=== Finding BaseQuery.java ==="
fd -e java -i "basequery" --exec cat {} \;

Length of output: 30


🏁 Script executed:

#!/bin/bash
# Search for usages of gitUnitPrCustomRepo across the codebase
echo "=== Checking gitUnitPrCustomRepo usage in full repository ==="
rg -n "gitUnitPrCustomRepo" --type java -C2 | head -50

Length of output: 888


🏁 Script executed:

#!/bin/bash
# Check if any other dependencies are used in the entire codebase
echo "=== Checking if unused dependencies are referenced elsewhere in codebase ==="
for dep in "issueUnitCustomRepo" "buildDeploymentUnitCustomRepo" "vulnerabilityUnitsCustomRepo" \
           "eventLogGitCustomRepo" "contributorService" "games24X7CustomRepo" \
           "teamService" "customMetricService" "globalExceptionHandler" \
           "workBreakdownCustomRepo" "metricsMetadataService" "recruitCRMCustomQueryRepo" \
           "deliverableService" "gitMetricCalculationStrategy" "sprintCustomRepo"; do
  count=$(rg -c "\b$dep\b" --type java 2>/dev/null | awk -F: '{sum+=$2} END {print sum}')
  if [ "$count" -gt 1 ]; then
    echo "$dep: used $count times (likely in multiple files)"
  fi
done

Length of output: 76


Remove unused autowired dependencies from DataDetailsQuery.java (lines 40-78).

Verification confirms 14 of the 15 autowired dependencies are completely unused in this class. The getCommitReportDetail() method only uses gitUnitPrCustomRepo directly, and delegates to inherited BaseQuery methods for other logic. Remove the following unused dependencies:

  • issueUnitCustomRepo (line 41)
  • buildDeploymentUnitCustomRepo (line 43)
  • vulnerabilityUnitsCustomRepo (line 49)
  • eventLogGitCustomRepo (line 52)
  • contributorService (line 55)
  • games24X7CustomRepo (line 58)
  • teamService (line 61)
  • customMetricService (line 63)
  • globalExceptionHandler (line 65)
  • workBreakdownCustomRepo (line 68)
  • metricsMetadataService (line 70)
  • recruitCRMCustomQueryRepo (line 72)
  • deliverableService (line 74)
  • gitMetricCalculationStrategy (line 76)
  • sprintCustomRepo (line 78)

Retain only gitUnitPrCustomRepo (line 46), which is actively used in the method body at line 89.

Comment on lines +80 to +91
public CommitMetricDetails getCommitReportDetail(String metric, String granularity, Filter filter, Integer pageNumber, Integer pageSize) throws Exception {
setDateRangeFromSprintId(filter);
MetricConfig metricConfig = getMetricConfig(metric);
Metric metricType = Metric.valueOf(metric);
Pair<List<String>, List<String>> assigneeAndProjectList = getAssigneeAndProjectList(filter, metricConfig);
List<String> repoList = assigneeAndProjectList.getRight();
List<String> assignees = assigneeAndProjectList.getLeft();
List<String> prIds = filter.getPrViewFilters() != null && CollectionUtils.isNotEmpty(filter.getPrViewFilters().getPrIds()) ? filter.getPrViewFilters().getPrIds() : new ArrayList<>();

CommitMetricDetails commitMetricDetails = gitUnitPrCustomRepo.getCommitReportDetailList(filter.getOrgId(), metricType, filter.getLocalStartDateFromEndDate(), filter.getEndDate(),assignees, repoList, prIds, filter.getTimeZone(), pageNumber, pageSize);
return commitMetricDetails;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add input validation for method parameters.

The method lacks validation for its parameters, which can lead to runtime exceptions and security issues:

  1. No null check on filter - Line 81 will throw NPE if filter is null
  2. No validation on pageNumber and pageSize - Negative, zero, or excessively large values could cause issues
  3. No validation on metric - Line 83's Metric.valueOf(metric) will throw IllegalArgumentException for invalid values

Add validation at the beginning of the method:

 public CommitMetricDetails getCommitReportDetail(String metric, String granularity, Filter filter, Integer pageNumber, Integer pageSize) throws Exception {
+    if (filter == null) {
+        throw new IllegalArgumentException("Filter cannot be null");
+    }
+    if (StringUtils.isBlank(metric)) {
+        throw new IllegalArgumentException("Metric cannot be null or empty");
+    }
+    if (pageNumber == null || pageNumber < 1) {
+        throw new IllegalArgumentException("Page number must be greater than 0");
+    }
+    if (pageSize == null || pageSize < 1 || pageSize > 1000) {
+        throw new IllegalArgumentException("Page size must be between 1 and 1000");
+    }
+    
     setDateRangeFromSprintId(filter);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public CommitMetricDetails getCommitReportDetail(String metric, String granularity, Filter filter, Integer pageNumber, Integer pageSize) throws Exception {
setDateRangeFromSprintId(filter);
MetricConfig metricConfig = getMetricConfig(metric);
Metric metricType = Metric.valueOf(metric);
Pair<List<String>, List<String>> assigneeAndProjectList = getAssigneeAndProjectList(filter, metricConfig);
List<String> repoList = assigneeAndProjectList.getRight();
List<String> assignees = assigneeAndProjectList.getLeft();
List<String> prIds = filter.getPrViewFilters() != null && CollectionUtils.isNotEmpty(filter.getPrViewFilters().getPrIds()) ? filter.getPrViewFilters().getPrIds() : new ArrayList<>();
CommitMetricDetails commitMetricDetails = gitUnitPrCustomRepo.getCommitReportDetailList(filter.getOrgId(), metricType, filter.getLocalStartDateFromEndDate(), filter.getEndDate(),assignees, repoList, prIds, filter.getTimeZone(), pageNumber, pageSize);
return commitMetricDetails;
}
public CommitMetricDetails getCommitReportDetail(String metric, String granularity, Filter filter, Integer pageNumber, Integer pageSize) throws Exception {
if (filter == null) {
throw new IllegalArgumentException("Filter cannot be null");
}
if (StringUtils.isBlank(metric)) {
throw new IllegalArgumentException("Metric cannot be null or empty");
}
if (pageNumber == null || pageNumber < 1) {
throw new IllegalArgumentException("Page number must be greater than 0");
}
if (pageSize == null || pageSize < 1 || pageSize > 1000) {
throw new IllegalArgumentException("Page size must be between 1 and 1000");
}
setDateRangeFromSprintId(filter);
MetricConfig metricConfig = getMetricConfig(metric);
Metric metricType = Metric.valueOf(metric);
Pair<List<String>, List<String>> assigneeAndProjectList = getAssigneeAndProjectList(filter, metricConfig);
List<String> repoList = assigneeAndProjectList.getRight();
List<String> assignees = assigneeAndProjectList.getLeft();
List<String> prIds = filter.getPrViewFilters() != null && CollectionUtils.isNotEmpty(filter.getPrViewFilters().getPrIds()) ? filter.getPrViewFilters().getPrIds() : new ArrayList<>();
CommitMetricDetails commitMetricDetails = gitUnitPrCustomRepo.getCommitReportDetailList(filter.getOrgId(), metricType, filter.getLocalStartDateFromEndDate(), filter.getEndDate(),assignees, repoList, prIds, filter.getTimeZone(), pageNumber, pageSize);
return commitMetricDetails;
}
🤖 Prompt for AI Agents
In DataDetailsQuery.java around lines 80 to 91, the method getCommitReportDetail
lacks input validation: add an explicit null check for filter and throw
IllegalArgumentException with a clear message if null; validate metric is
non-null/non-empty and safely parse it (catch IllegalArgumentException from
Metric.valueOf and rethrow a descriptive IllegalArgumentException); validate
pageNumber and pageSize (non-null, >0, and enforce a sensible max like 1000 or
use defaults) and throw IllegalArgumentException for invalid values; after
validation proceed to call setDateRangeFromSprintId and the rest so downstream
calls cannot cause NPEs or unexpected exceptions.

@Autowired
private SprintCustomRepoImpl sprintCustomRepo;

public CommitMetricDetails getCommitReportDetail(String metric, String granularity, Filter filter, Integer pageNumber, Integer pageSize) throws Exception {
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix unused parameter and overly broad exception declaration.

Two critical issues with the method signature:

  1. The granularity parameter is never used in the method body, suggesting either incomplete implementation or that it should be removed.
  2. Declaring throws Exception is too broad and considered an anti-pattern. Throw specific exceptions (e.g., ConfigurationException) or let Spring's exception handling deal with unchecked exceptions.

Apply this diff to remove the unused parameter and narrow the exception type:

-public CommitMetricDetails getCommitReportDetail(String metric, String granularity, Filter filter, Integer pageNumber, Integer pageSize) throws Exception {
+public CommitMetricDetails getCommitReportDetail(String metric, Filter filter, Integer pageNumber, Integer pageSize) throws ConfigurationException {

If granularity is actually needed, please implement its usage in the method body.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In DataDetailsQuery.java around line 80, the method signature declares an unused
parameter 'granularity' and broadly throws Exception; remove the unused
'granularity' parameter from the method signature (or if it is required,
implement its logic in the method body where metrics are computed/filtered) and
replace the broad throws Exception with specific checked exceptions (e.g.,
ConfigurationException, IOException) or remove the throws clause entirely and
let unchecked exceptions propagate so the controller/Spring exception handler
handles them; update any callers to match the new signature.

public CommitMetricDetails getCommitReportDetail(String metric, String granularity, Filter filter, Integer pageNumber, Integer pageSize) throws Exception {
setDateRangeFromSprintId(filter);
MetricConfig metricConfig = getMetricConfig(metric);
Metric metricType = Metric.valueOf(metric);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add error handling for enum conversion.

The Metric.valueOf(metric) call will throw an IllegalArgumentException if the metric string doesn't match any enum constant. This could expose internal implementation details to GraphQL clients.

Wrap the conversion with proper error handling:

-    Metric metricType = Metric.valueOf(metric);
+    Metric metricType;
+    try {
+        metricType = Metric.valueOf(metric);
+    } catch (IllegalArgumentException e) {
+        throw new ConfigurationException(ErrorCode.INVALID_METRIC, "Invalid metric: " + metric);
+    }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In DataDetailsQuery.java around line 83, Metric.valueOf(metric) can throw
IllegalArgumentException for invalid input; wrap the conversion in a try-catch
that catches IllegalArgumentException, log the invalid metric (without sensitive
internals), and rethrow a safe GraphQL-friendly exception (e.g. new
IllegalArgumentException or a DataFetchingException/GraphQLException with a
sanitized message like "Invalid metric specified") so callers get a clear,
non-sensitive error; optionally consider using a case-insensitive lookup or
EnumUtils to normalize before conversion.

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

Labels

size:M This PR changes 30-99 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants