Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions DataDetailsQuery.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.flecso.employer.graphql.query;

import com.coxautodev.graphql.tools.GraphQLQueryResolver;
import com.flecso.employer.central.entity.AccountStateType;
import com.flecso.employer.dto.DependencyVulDetails;
import com.flecso.employer.dto.InProgressWorkItems;
import com.flecso.employer.dto.analytics.*;
import com.flecso.employer.dto.analytics.build.BuildDetails;
import com.flecso.employer.dto.analytics.build.BuildStageDetails;
import com.flecso.employer.dto.analytics.prmetricdetail.PRMetricDetails;
import com.flecso.employer.dto.filters.IssueFilterConditions;
import com.flecso.employer.entity.*;
import com.flecso.employer.central.entity.MetricConfig;
import com.flecso.employer.exception.ConfigurationException;
import com.flecso.employer.exception.ErrorCode;
import com.flecso.employer.exception.GlobalExceptionHandler;
import com.flecso.employer.repository.*;
import com.flecso.employer.service.ContributorService;
import com.flecso.employer.service.CustomMetricService;
import com.flecso.employer.service.DateUtil;
import com.flecso.employer.service.MetricsMetadataService;
import com.flecso.employer.service.TeamService;
import com.flecso.employer.service.deliverable.DeliverableService;
import com.flecso.employer.strategy.GitMetricCalculationStrategy;
import com.flecso.employer.util.Constants;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.util.*;
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


@Autowired
IssueUnitCustomRepoImpl issueUnitCustomRepo;
@Autowired
Comment on lines +40 to +42
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

BuildDeploymentUnitCustomRepo buildDeploymentUnitCustomRepo;

@Autowired
GitUnitPrCustomRepoImpl gitUnitPrCustomRepo;
Comment on lines +40 to +46
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


@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;
Comment on lines +40 to +78

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;
}

Comment on lines +40 to +78
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.


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 {

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.

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

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.

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.");
}

Comment on lines +80 to +83
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

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

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.

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();


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.

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

return commitMetricDetails;
}
Comment on lines +80 to +91
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.

}