Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HCMPRE-585] [HCMPRE-590] [HCMPRE-588] -- Create Plan Facility API #914

Open
wants to merge 9 commits into
base: microplanning-dev
Choose a base branch
from

Conversation

Taniya-eGov
Copy link
Collaborator

@Taniya-eGov Taniya-eGov commented Sep 26, 2024

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new controller for handling plan facility requests.
    • Added new classes for managing plan facility creation, validation, and enrichment.
    • Implemented new configuration properties for facility and project factory services.
    • Created a new database table to support plan facility linkages.
    • Added new classes CampaignSearchReq, Product, Boundary, and CampaignDetail for structured campaign search requests and product representation.
  • Improvements

    • Enhanced error handling and validation messaging for facility-related operations.
    • Added pagination support for facility search criteria.
  • Documentation

    • Updated application properties to include new service endpoints.

Copy link
Contributor

coderabbitai bot commented Sep 26, 2024

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The changes introduce multiple new Java classes and configuration properties related to plan facilities and project factories. Key additions include classes for handling requests and responses, validation, and utility functions. Configuration properties for service endpoints and a new SQL migration for creating a plan_facility_linkage table are also included, enhancing the application's data management capabilities.

Changes

File Change Summary
.../Configuration.java Added new configuration properties for facility and project factory services, including topics and endpoints.
.../ServiceConstants.java Introduced constants for error handling and validation messages related to facilities and campaigns.
.../PlanFacilityRepository.java Created a new interface PlanFacilityRepository with a method for creating plan facility records.
.../PlanFacilityRepositoryImpl.java Implemented PlanFacilityRepository to push requests to a Kafka topic for plan facility creation.
.../PlanFacilityService.java Added PlanFacilityService to manage the creation of plan facilities, including validation and enrichment of requests.
.../PlanFacilityEnrichementService.java Introduced a service to enrich plan facility creation requests with additional details.
.../PlanFacilityValidator.java Created a validator for plan facility requests, ensuring data integrity and compliance with business rules.
.../CampaignUtil.java Added utility class for fetching campaign data from an external service.
.../FacilityUtil.java Introduced utility class for retrieving facility data based on given criteria.
.../PlanFacilityController.java Created a controller to handle HTTP requests related to plan facilities.
.../Pagination.java Added a class for managing pagination details in API responses.
.../PlanFacility.java Introduced a model class for representing plan facility data.
.../PlanFacilityRequest.java Added a request model for plan facility creation, encapsulating request metadata and facility details.
.../PlanFacilityResponse.java Created a response model for returning plan facility data.
.../facility/.../Facility.java Introduced a model class for representing facility entities.
.../facility/.../FacilityDetail.java Added a class to encapsulate detailed information about a facility.
.../facility/.../FacilityResponse.java Created a response model for facility-related data.
.../facility/.../FacilitySearchCriteria.java Introduced a class for encapsulating search criteria for facilities.
.../facility/.../FacilitySearchRequest.java Added a request model for searching facilities.
.../projectFactory/.../Boundary.java Introduced a class to represent project boundaries.
.../projectFactory/.../CampaignDetail.java Added a class for encapsulating campaign details.
.../projectFactory/.../CampaignResponse.java Created a response model for campaign-related data.
.../projectFactory/.../CampaignSearchCriteria.java Introduced a class for defining search criteria for campaigns.
.../projectFactory/.../CampaignSearchReq.java Added a request model for searching campaigns.
.../projectFactory/.../Condition.java Introduced a class for defining conditions related to project factory operations.
.../projectFactory/.../DeliveryRule.java Added a class to represent delivery rules with various attributes.
.../projectFactory/.../Product.java Introduced a class to represent product attributes.
.../projectFactory/.../Resource.java Added a class for representing resources in the project factory context.
.../application.properties Updated to include new configuration properties for facility and project factory services, including endpoints and topics.
.../db/migration/main/V20240923113045__plan_facility_create_ddl.sql Created a migration script to establish the plan_facility_linkage table with necessary columns and constraints.

Possibly related PRs

  • HCMPRE-218 adding validation for plan config name  #844: This PR introduces a new class Product in the same package (digit.web.models.projectFactory) as the CampaignSearchReq class from the main PR, indicating a potential relationship in terms of shared functionality or data structures related to campaign and product management.

🐰 In the garden of code, new classes take flight,
CampaignSearchReq and Product shine bright!
With fields and properties, they dance and they play,
Helping us search and manage in a structured way.
So let’s hop with joy, for the changes are here,
A world of new features, let’s give a cheer! 🎉


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

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

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

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai 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.

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.

@Taniya-eGov
Copy link
Collaborator Author

@coderabbitai review

Copy link
Contributor

coderabbitai bot commented Sep 26, 2024

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Inline review comments failed to post

🛑 Comments failed to post (83)
health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java (3)

1-3: 🛠️ Refactor suggestion

Consider relocating PlanFacilityRequest to a more appropriate package.

The PlanFacilityRequest is imported from digit.web.models, which is unusual for a class used in the repository layer. Typically, repository interfaces work with domain entities or data transfer objects (DTOs) rather than web models.

Consider moving PlanFacilityRequest to a more appropriate package such as digit.domain or digit.dto, or create a separate domain entity for the repository layer.


6-8: 🛠️ Refactor suggestion

Refine the create method signature.

The current method signature has a few areas for improvement:

  1. The public modifier is redundant in interfaces as all methods are implicitly public.
  2. Returning void from a create operation is unusual. Consider returning the created entity or its identifier.

Consider refactoring the method signature as follows:

PlanFacility create(PlanFacilityRequest planFacilityRequest);

or

String create(PlanFacilityRequest planFacilityRequest);

This assumes that PlanFacility is the domain entity corresponding to PlanFacilityRequest, or that the ID is a String. Adjust the return type as appropriate for your domain model.


6-8: 🛠️ Refactor suggestion

Consider adding other common repository operations.

The PlanFacilityRepository interface currently only defines a create operation. While this might be intentional, repositories typically include other basic CRUD (Create, Read, Update, Delete) operations.

Consider adding other common repository methods such as:

PlanFacility findById(String id);
List<PlanFacility> findAll();
PlanFacility update(PlanFacility planFacility);
void delete(String id);

Adjust the method signatures and return types as appropriate for your specific use case and domain model.

health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchReq.java (2)

9-14: 🧹 Nitpick (assertive)

LGTM: Class structure is well-defined. Consider enhancing the Javadoc.

The class structure and annotations are appropriate. The use of Lombok's @Data and @Builder annotations helps reduce boilerplate code, improving maintainability.

Consider expanding the Javadoc comment to provide more details about the purpose and usage of the CampaignSearchReq class. For example:

/**
 * CampaignSearchReq
 * 
 * This class represents a request object for searching campaigns.
 * It encapsulates the request information and search criteria used
 * for querying campaign details.
 */

20-21: 🧹 Nitpick (assertive)

Consider adjusting the JSON property name and adding @Valid annotation.

The campaignSearchCriteria field is well-declared, but there are two points to consider:

  1. The @JsonProperty value "CampaignDetails" doesn't match the field name. This might lead to confusion. Consider changing it to "CampaignSearchCriteria" for consistency:
@JsonProperty("CampaignSearchCriteria")
private CampaignSearchCriteria campaignSearchCriteria;
  1. For consistency with the requestInfo field and to ensure nested validation, consider adding the @Valid annotation:
@JsonProperty("CampaignSearchCriteria")
@Valid
private CampaignSearchCriteria campaignSearchCriteria;
health-services/plan-service/src/main/java/digit/web/models/projectFactory/Product.java (2)

9-11: 🧹 Nitpick (assertive)

Enhance class documentation for better clarity.

While the class is well-structured, it would benefit from more comprehensive documentation. Consider adding a detailed class-level Javadoc comment explaining:

  1. The purpose of this class in the context of the project.
  2. How and where it's intended to be used.
  3. Any important considerations for developers working with this class.

Example:

/**
 * Represents a product in the health campaign service.
 * 
 * This class is used as a data transfer object (DTO) for product information
 * in the plan facility API. It encapsulates the essential attributes of a product
 * including its name, count, and associated value.
 *
 * @see [related class or interface, if any]
 */
public class Product {
    // ... existing code ...
}

Also applies to: 16-16


21-22: 🧹 Nitpick (assertive)

LGTM: 'count' field is well-defined, but consider using primitive type.

The 'count' field is correctly defined and properly annotated with @JsonProperty for JSON handling. However, consider using the primitive type 'int' instead of 'Integer' if null values are not needed for this field. This can improve performance and reduce memory usage.

-    private Integer count;
+    private int count;
📝 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.

    @JsonProperty("count")
    private int count;
health-services/plan-service/src/main/java/digit/web/models/facility/FacilitySearchRequest.java (1)

10-14: 🧹 Nitpick (assertive)

LGTM: Class declaration and Lombok annotations are well-used.

The class name is clear and descriptive, following Java naming conventions. Lombok annotations are used appropriately, reducing boilerplate code and improving readability and maintainability.

Consider adding @EqualsAndHashCode(callSuper = false) annotation if this class is intended to be extended in the future. This ensures that the equals and hashCode methods are correctly implemented for inheritance scenarios.

health-services/plan-service/src/main/java/digit/web/models/projectFactory/Condition.java (3)

9-16: 🧹 Nitpick (assertive)

Improve the class-level Javadoc comment.

The use of Lombok annotations (@Data, @AllArgsConstructor, @NoArgsConstructor, @Builder) is appropriate and helps reduce boilerplate code. However, the class-level Javadoc comment could be more informative.

Consider expanding the Javadoc comment to provide more context about the purpose and usage of the Condition class. For example:

/**
 * Represents a condition used in project factory operations.
 * This class encapsulates the components of a condition: value, operator, and attribute.
 */

18-25: 🧹 Nitpick (assertive)

Consider using an enum for the operator property.

The properties and their @JsonProperty annotations are correctly implemented. However, the operator property might benefit from being more strongly typed.

Consider using an enum for the operator property to restrict it to a predefined set of valid operators. This would improve type safety and make the code more self-documenting. For example:

public enum Operator {
    EQUALS, NOT_EQUALS, GREATER_THAN, LESS_THAN, // Add other operators as needed
}

@JsonProperty("operator")
private Operator operator;

This change would require updating any code that sets or reads the operator property, but it would provide better compile-time checks and clearer documentation of valid values.


1-27: 🛠️ Refactor suggestion

Consider adding validation for property values.

The Condition class is well-structured and effectively uses Lombok and Jackson annotations. To further enhance its robustness, consider the following suggestions:

  1. Add validation annotations (e.g., from Jakarta Validation) to ensure property values meet certain criteria. For example:
import jakarta.validation.constraints.NotBlank;

@NotBlank(message = "Value cannot be blank")
@JsonProperty("value")
private String value;

@NotBlank(message = "Attribute cannot be blank")
@JsonProperty("attribute")
private String attribute;
  1. If you implement the enum suggestion for the operator property, you can use @NotNull to ensure it's always set:
@NotNull(message = "Operator must be specified")
@JsonProperty("operator")
private Operator operator;

These additions would help ensure that Condition objects always contain valid data, catching potential issues earlier in the development process.

health-services/plan-service/src/main/java/digit/web/models/facility/FacilityResponse.java (1)

1-22: 🧹 Nitpick (assertive)

LGTM: Well-structured response class with a minor suggestion.

The FacilityResponse class is well-designed and follows Java and JSON best practices. It effectively uses Lombok annotations to reduce boilerplate code and provides a clear structure for facility-related API responses.

Consider adding Javadoc comments to the class and its fields to provide more context and improve documentation. For example:

/**
 * Represents the response structure for facility-related API calls.
 */
public class FacilityResponse {
    /**
     * Contains metadata about the response.
     */
    @JsonProperty("ResponseInfo")
    private ResponseInfo responseInfo;

    /**
     * List of facilities included in the response.
     */
    @JsonProperty("Facilities")
    private List<Facility> facilities;
}
health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql (3)

1-17: 🧹 Nitpick (assertive)

Overall structure looks good, consider adding NOT NULL constraints

The table structure is well-designed and covers necessary information for plan facility linkage. Here are some observations and suggestions:

  1. The use of JSONB for additional_details provides flexibility for storing varied information.
  2. Consider adding NOT NULL constraints to important columns like tenant_id, plan_configuration_id, and facility_id if they are always required.
  3. The service_boundaries column has a larger size limit (varchar(2048)). Ensure this size is necessary, or consider using a more appropriate data type if it's expected to store complex data.
  4. You might want to add an index on plan_configuration_id to improve query performance when joining with the plan_configuration table.

Here's a suggested modification to add NOT NULL constraints and an index:

CREATE TABLE plan_facility_linkage (
  id varchar(64) NOT NULL,
  tenant_id varchar(64) NOT NULL,
  plan_configuration_id varchar(64) NOT NULL,
  facility_id varchar(64) NOT NULL,
  residing_boundary varchar(64),
  service_boundaries varchar(2048),
  additional_details JSONB,
  active boolean NOT NULL,
  created_by varchar(64) NOT NULL,
  created_time bigint NOT NULL,
  last_modified_by varchar(64),
  last_modified_time bigint,
  CONSTRAINT uk_plan_facility_linkage_id PRIMARY KEY (id),
  CONSTRAINT fk_plan_facility_linkage_plan_configuration FOREIGN KEY (plan_configuration_id) REFERENCES plan_configuration(id)
);

CREATE INDEX idx_plan_facility_linkage_plan_configuration_id ON plan_facility_linkage(plan_configuration_id);

This modification adds NOT NULL constraints to essential columns and creates an index on plan_configuration_id for better query performance.


15-16: 🛠️ Refactor suggestion

Consider adding a unique constraint on tenant_id and facility_id

The primary key and foreign key constraints are correctly defined. However, to ensure data integrity and prevent duplicate entries, consider adding a unique constraint on the combination of tenant_id and facility_id. This would prevent multiple linkages for the same facility within a tenant.

Add the following constraint to the table definition:

CONSTRAINT uk_plan_facility_linkage_tenant_facility UNIQUE (tenant_id, facility_id)

This constraint will ensure that each facility can only be linked once within a tenant, maintaining data consistency.


12-12: 🛠️ Refactor suggestion

Consider using TIMESTAMP or TIMESTAMPTZ for time columns

The current table uses bigint for created_time and last_modified_time columns. While this works, it's more conventional and often more convenient to use TIMESTAMP or TIMESTAMPTZ (timestamp with time zone) in PostgreSQL for date and time data.

Consider changing the data type for these columns:

created_time TIMESTAMPTZ NOT NULL,
last_modified_time TIMESTAMPTZ,

Using TIMESTAMPTZ ensures that the timestamps are stored with timezone information, which can be crucial for applications dealing with users or data from different time zones. It also allows for easier querying and manipulation of date/time data using PostgreSQL's built-in date/time functions.

Also applies to: 14-14

health-services/plan-service/src/main/java/digit/web/models/projectFactory/Boundary.java (2)

9-16: 🧹 Nitpick (assertive)

Approve class structure with a suggestion for improvement.

The class structure and Lombok annotations are well-chosen, reducing boilerplate code and improving maintainability. However, the class lacks a comprehensive Javadoc comment.

Consider adding a more detailed Javadoc comment for the Boundary class. For example:

/**
 * Represents a boundary within the project structure.
 * This class encapsulates information about a boundary, including its code, type,
 * root status, child inclusion, and parent relationship.
 */

18-31: 🛠️ Refactor suggestion

Consider using primitive boolean and adding field validations.

The fields and their annotations are generally well-defined. However, there are a couple of suggestions for improvement:

  1. For isRoot and includeAllChildren, consider using the primitive boolean instead of Boolean if null values are not meaningful in this context. This change would prevent potential null pointer exceptions and make the intent clearer.

  2. Add validation annotations to ensure data integrity. For example:

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

public class Boundary {
    @NotBlank
    @JsonProperty("code")
    private String code;

    @NotBlank
    @JsonProperty("type")
    private String type;

    @NotNull
    @JsonProperty("isRoot")
    private boolean isRoot;

    @NotNull
    @JsonProperty("includeAllChildren")
    private boolean includeAllChildren;

    @JsonProperty("parent")
    private String parent; // Assuming parent can be null for root boundaries
}

These changes will improve type safety and data validation.

health-services/plan-service/src/main/java/digit/web/models/projectFactory/Resource.java (3)

9-16: 🧹 Nitpick (assertive)

Enhance the class-level Javadoc comment.

While the class structure and annotations look good, the Javadoc comment for the Resource class could be more informative. Consider expanding it to include:

  • A brief description of what a Resource represents in your system.
  • An explanation of when and how this class is typically used.
  • Any important notes about the fields or usage of this class.

Example:

/**
 * Represents a resource in the project factory system.
 * This class is used to encapsulate information about various types of resources,
 * such as files or documents, that can be associated with projects or tasks.
 * It includes details like the resource type, filename, and various IDs for tracking and storage.
 */

18-31: 🧹 Nitpick (assertive)

LGTM: Fields are well-defined, with a minor suggestion.

The fields and their annotations are correctly implemented:

  • Each field is private and uses the appropriate @JsonProperty annotation.
  • Field names are clear and descriptive.

However, consider the following suggestion:

  • Evaluate if all fields should be of type String. For instance, resourceId or filestoreId might be better represented as UUID or Long, depending on your system's design.

Example:

@JsonProperty("resourceId")
private UUID resourceId;

@JsonProperty("filestoreId")
private Long filestoreId;

This change could provide better type safety and potentially improve performance in database operations.


16-32: 🛠️ Refactor suggestion

Consider adding field validation.

To improve data integrity and catch potential issues early, consider adding validation annotations to the fields. This can help ensure that the data meets certain criteria before it's processed further in your application.

Examples of validations you might want to add:

import javax.validation.constraints.*;

public class Resource {
    @NotBlank(message = "Type is required")
    @JsonProperty("type")
    private String type;

    @NotBlank(message = "Filename is required")
    @JsonProperty("filename")
    private String filename;

    @Pattern(regexp = "^[a-zA-Z0-9-]+$", message = "Resource ID must be alphanumeric")
    @JsonProperty("resourceId")
    private String resourceId;

    // Add similar validations for filestoreId and createResourceId
}

These validations can help catch issues early and improve the overall robustness of your application.

health-services/plan-service/src/main/java/digit/web/models/facility/FacilitySearchCriteria.java (1)

22-26: 🧹 Nitpick (assertive)

LGTM: name and isDeleted fields are well-defined, with a suggestion.

The name and isDeleted fields are appropriately typed and annotated:

  • name as a String allows for facility name searches.
  • isDeleted as a Boolean enables filtering by deletion status.
  • Both use @JsonProperty for proper JSON handling.

Consider using Boolean instead of boolean for isDeleted to allow for a null state, which could represent "don't filter by deletion status" in the search criteria. If this is already the case (hard to tell from the builder pattern), then this suggestion can be ignored.

health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.java (2)

21-23: 🧹 Nitpick (assertive)

LGTM: The requestInfo property is well-defined, with a minor suggestion.

The requestInfo property is correctly annotated with @JsonProperty for proper JSON mapping and @Valid for cascading validation.

Consider initializing requestInfo with a default non-null value, such as new RequestInfo(), to avoid potential null pointer exceptions. This approach aligns with the principle of failing fast and can simplify null checks in the service layer.


1-30: 🧹 Nitpick (assertive)

Overall, the PlanFacilityRequest class is well-structured and follows good practices.

The class effectively uses Lombok annotations to reduce boilerplate code, and properly implements validation and JSON mapping. The structure is clean and adheres to Java conventions.

To further improve the class:

  1. Consider adding documentation comments for the class and its properties to enhance code readability and maintainability.
  2. If this class is part of a larger API, ensure it follows the established naming conventions and structure of other request classes in the project for consistency.
health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignResponse.java (3)

12-18: 🧹 Nitpick (assertive)

Enhance the class-level documentation.

While the class structure and annotations look good, the class-level comment could be more informative. Consider expanding it to describe the purpose of the CampaignResponse class and its role in the project.

Here's a suggested improvement for the class-level comment:

/**
 * CampaignResponse
 * 
 * This class represents the response structure for campaign-related API calls.
 * It encapsulates the response information, a list of campaign details,
 * and the total count of campaigns available.
 */

20-30: 🧹 Nitpick (assertive)

Remove redundant null initializations and consider using a primitive type for totalCount.

The field declarations look good overall, but there are a couple of minor improvements we can make:

  1. Remove the redundant null initializations. In Java, reference types are automatically initialized to null.
  2. Consider using the primitive int instead of Integer for totalCount if it's never expected to be null.

Here's the suggested improvement:

 @JsonProperty("ResponseInfo")
 @Valid
-private ResponseInfo responseInfo = null;
+private ResponseInfo responseInfo;

 @JsonProperty("CampaignDetails")
 @Valid
-private List<CampaignDetail> campaignDetails = null;
+private List<CampaignDetail> campaignDetails;

 @JsonProperty("totalCount")
 @Valid
-private Integer totalCount = null;
+private int totalCount;

If totalCount might be null in some cases, keep it as Integer but still remove the null initialization.

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

    @JsonProperty("ResponseInfo")
    @Valid
    private ResponseInfo responseInfo;

    @JsonProperty("CampaignDetails")
    @Valid
    private List<CampaignDetail> campaignDetails;

    @JsonProperty("totalCount")
    @Valid
    private int totalCount;

1-31: 🧹 Nitpick (assertive)

LGTM: Well-designed response class with a minor suggestion.

The CampaignResponse class is well-structured and follows good practices for API response objects. The use of Lombok annotations helps reduce boilerplate code, and the field annotations ensure proper JSON handling and validation.

For consistency with other response classes in your project, consider the following minor suggestion:

  1. Capitalize the first letter of JSON property names to match the field names:
-@JsonProperty("ResponseInfo")
+@JsonProperty("responseInfo")

-@JsonProperty("CampaignDetails")
+@JsonProperty("campaignDetails")

This change would make the JSON keys consistent with typical Java naming conventions while maintaining the capitalized field names in the Java code.

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

package digit.web.models.projectFactory;

import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.egov.common.contract.response.ResponseInfo;

import java.util.List;

/**
 * CampaignResponse
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CampaignResponse {

    @JsonProperty("responseInfo")
    @Valid
    private ResponseInfo responseInfo = null;

    @JsonProperty("campaignDetails")
    @Valid
    private List<CampaignDetail> campaignDetails = null;

    @JsonProperty("totalCount")
    @Valid
    private Integer totalCount = null;
}
health-services/plan-service/src/main/java/digit/web/models/Pagination.java (3)

12-19: 🧹 Nitpick (assertive)

Improve the class-level Javadoc comment.

The class-level annotations and structure look good. However, the Javadoc comment could be more informative.

Consider expanding the Javadoc comment to provide more details about the purpose and usage of the Pagination class. For example:

/**
 * Represents pagination parameters for API requests.
 * This class encapsulates sorting and limiting options for paginated results.
 */

21-34: 🧹 Nitpick (assertive)

LGTM: Fields and annotations are well-defined.

The fields and their annotations are appropriately defined:

  • sortBy and sortOrder are correctly ignored in JSON serialization.
  • limit has proper constraints (1 to 50) to prevent excessive data retrieval.
  • offset has a correct minimum value of 0.

Consider adding a default value for the limit field to improve usability. For example:

@JsonProperty("limit")
@Min(1)
@Max(50)
private Integer limit = 10; // Default to 10 items per page

1-35: 🧹 Nitpick (assertive)

LGTM: Well-designed pagination class.

The Pagination class is well-structured and follows good design principles:

  • It has a single responsibility (handling pagination parameters).
  • It uses Lombok to reduce boilerplate code.
  • It includes appropriate JSON serialization control and validation constraints.

Consider adding a method to calculate the total number of pages based on the total count of items and the limit. This could enhance the usability of the class. For example:

public int getTotalPages(long totalCount) {
    return (int) Math.ceil((double) totalCount / limit);
}
health-services/plan-service/src/main/java/digit/web/models/projectFactory/DeliveryRule.java (3)

12-19: 🧹 Nitpick (assertive)

LGTM: Class structure and annotations are appropriate. Consider enhancing the Javadoc.

The use of Lombok annotations (@DaTa, @AllArgsConstructor, @NoArgsConstructor, @builder) is appropriate and helps reduce boilerplate code. The class structure as a POJO is correct.

Consider expanding the Javadoc comment to provide more details about the purpose of the DeliveryRule class, its usage, and any important considerations. For example:

/**
 * Represents a delivery rule in the project factory.
 * This class encapsulates information about product delivery,
 * including timing, conditions, and associated products.
 */

21-42: 🧹 Nitpick (assertive)

LGTM: Fields and annotations are well-defined. Consider adding validations.

The fields are appropriately defined with correct types and @JsonProperty annotations for JSON handling. The use of @Valid for List fields ensures proper validation of nested objects.

Consider adding validation annotations to ensure data integrity:

  1. For date fields (startDate and endDate):

    @JsonProperty("startDate")
    @NotNull
    private Long startDate;
    
    @JsonProperty("endDate")
    @NotNull
    private Long endDate;
  2. For numeric fields:

    @JsonProperty("cycleNumber")
    @NotNull
    @Min(1)
    private Integer cycleNumber;
    
    @JsonProperty("deliveryNumber")
    @NotNull
    @Min(1)
    private Integer deliveryNumber;
    
    @JsonProperty("deliveryRuleNumber")
    @NotNull
    @Min(1)
    private Integer deliveryRuleNumber;
  3. For list fields:

    @JsonProperty("products")
    @Valid
    @NotEmpty
    private List<Product> products;
    
    @JsonProperty("conditions")
    @Valid
    @NotEmpty
    private List<Condition> conditions;

These validations will ensure that the fields contain valid data and improve the robustness of the DeliveryRule class.


1-43: 🧹 Nitpick (assertive)

Consider enhancing the class for production readiness.

The DeliveryRule class is well-structured and serves its primary purpose. However, consider the following enhancements to improve its production readiness:

  1. Add version control field:

    @Version
    private Long version;
  2. Include auditing fields:

    @CreatedDate
    private Instant createdAt;
    
    @LastModifiedDate
    private Instant updatedAt;
  3. Implement equals() and hashCode() methods (if not already generated by Lombok) based on a business key or unique identifier.

  4. Consider adding a toString() method (if not already generated by Lombok) that includes key fields for logging purposes.

  5. If this class is likely to be extended, consider making it abstract or adding the final keyword to prevent inheritance, depending on your design requirements.

These additions will improve traceability, concurrency control, and overall robustness of the DeliveryRule class in a production environment.

health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java (3)

1-36: 🧹 Nitpick (assertive)

Consider future extensibility of the PlanFacilityRepository.

The current implementation is good for creating plan facilities. As the project evolves, consider the following architectural advice:

  1. Implement read operations to retrieve plan facility data.
  2. Add update and delete operations if required by the business logic.
  3. Consider implementing a caching mechanism to improve read performance if frequent reads are expected.

These suggestions will help ensure that the repository can handle all CRUD operations efficiently as the project grows.


14-20: 🧹 Nitpick (assertive)

Consider making private fields final for immutability.

The private fields and constructor look good, but consider making the fields final to ensure immutability.

Apply this diff to improve immutability:

-    private Producer producer;
-    private Configuration config;
+    private final Producer producer;
+    private final Configuration config;
📝 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.

    private final Producer producer;
    private final Configuration config;

    public PlanFacilityRepositoryImpl(Producer producer, Configuration config) {
        this.producer = producer;
        this.config = config;
    }

22-33: ⚠️ Potential issue

Improve exception handling and Javadoc for the create method.

While the implementation is generally correct, there are a few areas for improvement:

  1. Exception handling:

    • Use ERROR log level instead of INFO for exceptions.
    • Consider rethrowing the exception or returning a status to notify the caller of the failure.
  2. Javadoc:

    • Include information about potential exceptions that might be thrown.

Apply these changes to improve the method:

     /**
      * This method emits an event to the persister for it to save the plan facility linkage in the database.
-     * @param planFacilityRequest
+     * @param planFacilityRequest The request containing plan facility data to be persisted.
+     * @throws RuntimeException if there's an error pushing the message to Kafka.
      */
     @Override
     public void create(PlanFacilityRequest planFacilityRequest) {
         try {
             producer.push(config.getPlanFacilityCreateTopic(), planFacilityRequest);
         } catch (Exception e) {
-            log.info("Pushing message to topic " + config.getPlanFacilityCreateTopic() + " failed.", e);
+            log.error("Failed to push message to topic {}.", config.getPlanFacilityCreateTopic(), e);
+            throw new RuntimeException("Failed to create plan facility", e);
         }
     }
📝 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.

    /**
     * This method emits an event to the persister for it to save the plan facility linkage in the database.
     * @param planFacilityRequest The request containing plan facility data to be persisted.
     * @throws RuntimeException if there's an error pushing the message to Kafka.
     */
    @Override
    public void create(PlanFacilityRequest planFacilityRequest) {
        try {
            producer.push(config.getPlanFacilityCreateTopic(), planFacilityRequest);
        } catch (Exception e) {
            log.error("Failed to push message to topic {}.", config.getPlanFacilityCreateTopic(), e);
            throw new RuntimeException("Failed to create plan facility", e);
        }
    }
health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java (3)

32-43: 🧹 Nitpick (assertive)

LGTM: Methods follow the builder pattern effectively.

The responseInfo() and addPlanFacilityItem() methods are well-implemented, allowing for fluent method chaining. The null check in addPlanFacilityItem() is a good practice.

Consider adding a method to set the entire planFacility list at once, which could be useful in some scenarios:

public PlanFacilityResponse planFacility(List<PlanFacility> planFacility) {
    this.planFacility = planFacility;
    return this;
}

This addition would provide more flexibility in setting the planFacility field.


1-44: 🧹 Nitpick (assertive)

LGTM: Well-structured and implemented response model.

The PlanFacilityResponse class is well-designed and effectively serves its purpose as a response model for plan facilities. It makes good use of annotations to reduce boilerplate code and enable validation. The implementation of the builder pattern provides flexibility in object creation and manipulation.

To further improve the class, consider adding more detailed JavaDoc comments for the class and its methods. This would enhance the documentation and make it easier for other developers to understand and use the class correctly.

Example:

/**
 * Represents the response for a plan facility request.
 * This class encapsulates the response information and a list of plan facilities.
 */
public class PlanFacilityResponse {
    // ... existing code ...

    /**
     * Sets the response information and returns the current instance.
     *
     * @param responseInfo the response information to set
     * @return the current PlanFacilityResponse instance
     */
    public PlanFacilityResponse responseInfo(ResponseInfo responseInfo) {
        // ... existing code ...
    }

    // ... add similar comments for other methods ...
}

Adding these comments would improve the overall documentation of your codebase.


25-30: 🧹 Nitpick (assertive)

LGTM: Fields are well-defined, but consider standardizing JSON property names.

The fields are correctly declared with appropriate types and annotations. The use of @Valid for nested validation is a good practice. However, for consistency, consider standardizing the JSON property names to camelCase:

- @JsonProperty("ResponseInfo")
+ @JsonProperty("responseInfo")

- @JsonProperty("PlanFacility")
+ @JsonProperty("planFacility")

This change would align the JSON property names with common Java and JSON conventions, improving consistency across your API.

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

    @JsonProperty("responseInfo")
    private ResponseInfo responseInfo = null;

    @JsonProperty("planFacility")
    @Valid
    private List<PlanFacility> planFacility = null;
health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchCriteria.java (3)

26-32: 🧹 Nitpick (assertive)

LGTM: ids and tenantId fields are well-defined with appropriate validations.

The ids and tenantId fields are correctly implemented with proper validation constraints. The @Size annotations ensure that the ids list is not empty and the tenantId has an appropriate length.

Consider adding a @NotNull annotation to both fields if they are required for every search operation. This would provide an additional layer of validation and make the API contract more explicit.


34-47: 🧹 Nitpick (assertive)

LGTM: @JsonIgnore fields are appropriately defined for internal use.

The fields annotated with @JsonIgnore (status, createdBy, campaignsIncludeDates, startDate, and endDate) are correctly implemented for internal use or filtering purposes.

  1. Consider renaming campaignsIncludeDates to a more descriptive name like includeDateRangeInSearch for clarity.
  2. For the startDate and endDate fields, consider using java.time.LocalDate or java.time.Instant instead of Integer for better date handling and type safety.

1-52: 🧹 Nitpick (assertive)

Overall, the CampaignSearchCriteria class is well-implemented and fit for purpose.

The class structure, field definitions, and annotations are appropriate for a search criteria model. The use of Lombok annotations reduces boilerplate code, and the validation constraints ensure data integrity. The suggested improvements (adding @NotNull annotations, renaming a field, and using more appropriate date types) are minor and can be considered for enhancing code clarity and type safety.

Consider implementing a builder pattern for this class to make it easier to create instances with only the required fields set. This can improve the usability of the class, especially when used in complex search scenarios.

health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnrichementService.java (4)

14-19: 🧹 Nitpick (assertive)

Enhance Javadoc for better documentation.

While the current Javadoc provides basic information, it could be more descriptive to improve code documentation.

Consider expanding the Javadoc as follows:

/**
 * Enriches the plan facility create request by generating a UUID,
 * setting audit details, and activating the plan facility.
 *
 * @param planFacilityRequest The request object containing plan facility details to be enriched
 * @throws IllegalArgumentException if the plan facility details are missing in the request
 */
public void enrichPlanFacilityCreate(@Valid PlanFacilityRequest planFacilityRequest) {

24-32: ⚠️ Potential issue

Add exception handling for utility method calls.

The current implementation doesn't handle potential exceptions that might be thrown by the utility methods. Consider wrapping these calls in a try-catch block to handle exceptions gracefully.

Here's a suggested implementation:

try {
    // Generate id for plan facility
    UUIDEnrichmentUtil.enrichRandomUuid(planFacilityRequest.getPlanFacility(), "id");

    // Enrich audit details
    planFacilityRequest.getPlanFacility().setAuditDetails(AuditDetailsEnrichmentUtil
            .prepareAuditDetails(planFacilityRequest.getPlanFacility().getAuditDetails(), planFacilityRequest.getRequestInfo(), Boolean.TRUE));

    //Set Active
    boolean isActive = planFacilityRequest.getPlanFacility().getActive() != null 
        ? planFacilityRequest.getPlanFacility().getActive() 
        : true; // Default to true if not specified
    planFacilityRequest.getPlanFacility().setActive(isActive);
} catch (Exception e) {
    log.error("Error while enriching plan facility: ", e);
    throw new RuntimeException("Failed to enrich plan facility", e);
}

10-12: ⚠️ Potential issue

Fix typo in class name.

The class name contains a typo: "Enrichement" should be "Enrichment".

Please apply the following change:

-public class PlanFacilityEnrichementService {
+public class PlanFacilityEnrichmentService {
📝 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.

@Component
@Slf4j
public class PlanFacilityEnrichmentService {

31-32: 🛠️ Refactor suggestion

Consider making the active status configurable.

Setting the active status to true by default might not be suitable for all use cases. Consider making this configurable or based on the input request.

You could modify the code as follows:

-planFacilityRequest.getPlanFacility().setActive(true);
+boolean isActive = planFacilityRequest.getPlanFacility().getActive() != null 
+    ? planFacilityRequest.getPlanFacility().getActive() 
+    : true; // Default to true if not specified
+planFacilityRequest.getPlanFacility().setActive(isActive);
📝 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.

        //Set Active
        boolean isActive = planFacilityRequest.getPlanFacility().getActive() != null 
            ? planFacilityRequest.getPlanFacility().getActive() 
            : true; // Default to true if not specified
        planFacilityRequest.getPlanFacility().setActive(isActive);
health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java (3)

1-37: 🧹 Nitpick (assertive)

Consider implementing additional CRUD operations if needed.

The controller is well-structured for handling the creation of plan facilities. However, it currently only implements the create operation.

If the plan facility resource requires full CRUD functionality, consider adding methods for reading, updating, and deleting plan facilities. This would typically involve adding new methods with appropriate @RequestMapping annotations for GET, PUT/PATCH, and DELETE HTTP methods.

For example:

@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<PlanFacilityResponse> getPlanFacility(@PathVariable String id) {
    // Implementation
}

@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public ResponseEntity<PlanFacilityResponse> updatePlanFacility(@PathVariable String id, @Valid @RequestBody PlanFacilityRequest request) {
    // Implementation
}

@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Void> deletePlanFacility(@PathVariable String id) {
    // Implementation
}

If these operations are not required or are planned for future implementation, please disregard this suggestion.


26-36: 🧹 Nitpick (assertive)

Method implementation is good, but consider using HTTP status 201 (Created).

The planFacilityCreatePost method is well-implemented with proper request mapping, input validation, and use of ResponseEntity for the response. However, the HTTP status code could be improved.

Consider using HTTP status 201 (Created) instead of 202 (Accepted) for the response. Status 201 is more appropriate for immediate resource creation operations, while 202 is typically used for asynchronous operations. Here's the suggested change:

-        return ResponseEntity.status(HttpStatus.ACCEPTED).body(planFacilityResponse);
+        return ResponseEntity.status(HttpStatus.CREATED).body(planFacilityResponse);

This change more accurately reflects the immediate creation of the plan facility resource.

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

    /**
     * Request handler for serving plan facility create requests
     *
     * @param planFacilityRequest
     * @return
     */
    @RequestMapping(value = "/_create", method = RequestMethod.POST)
    public ResponseEntity<PlanFacilityResponse> planFacilityCreatePost(@Valid @RequestBody PlanFacilityRequest planFacilityRequest) {
        PlanFacilityResponse planFacilityResponse = planFacilityService.createPlanFacility(planFacilityRequest);
        return ResponseEntity.status(HttpStatus.CREATED).body(planFacilityResponse);
    }

20-24: 🧹 Nitpick (assertive)

LGTM: Field declaration and constructor are well-implemented.

The planFacilityService field is correctly declared as private, and constructor injection is used for dependency injection, which is a good practice in Spring.

Consider adding the @Autowired annotation to the constructor for explicit dependency injection, although it's optional in newer Spring versions for single-constructor classes:

+    @Autowired
     public PlanFacilityController(PlanFacilityService planFacilityService) {
         this.planFacilityService = planFacilityService;
     }
📝 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.

    private PlanFacilityService planFacilityService;

    @Autowired
    public PlanFacilityController(PlanFacilityService planFacilityService) {
        this.planFacilityService = planFacilityService;
    }
health-services/plan-service/src/main/java/digit/web/models/facility/Facility.java (3)

15-61: 🧹 Nitpick (assertive)

LGTM: Comprehensive field declarations with room for enhancements.

The field declarations cover a wide range of attributes for a facility and are properly annotated with @JsonProperty for JSON serialization/deserialization. However, consider the following suggestions for improvement:

  1. Add validation annotations (e.g., @NotNull, @SiZe) where appropriate to ensure data integrity.
  2. Consider using more specific types for certain fields:
    • storageCapacity could be a Double or BigDecimal for more precise capacity representation.
    • usage could be an enum if there's a fixed set of possible values.
  3. The additionalFields and clientAuditDetails are declared as String. Consider using a more structured type (e.g., Map or custom object) if they represent complex data.

45-46: 🧹 Nitpick (assertive)

Suggestion: Adjust boolean field names to follow Java conventions.

The boolean fields 'isPermanent' and 'isDeleted' don't follow the common Java convention for boolean naming. In Java, it's typical to name boolean fields without the 'is' prefix, as getter methods will automatically add this prefix.

Consider renaming these fields as follows:

-    @JsonProperty("isPermanent")
-    private boolean isPermanent;
+    @JsonProperty("permanent")
+    private boolean permanent;

-    @JsonProperty("isDeleted")
-    private boolean isDeleted;
+    @JsonProperty("deleted")
+    private boolean deleted;

This change will make the code more idiomatic and prevent potential issues with some frameworks that rely on Java bean naming conventions.

Also applies to: 60-61


1-62: 🧹 Nitpick (assertive)

Consider security implications when handling Facility data.

While the Facility class itself doesn't contain obvious security-sensitive information, it's important to consider the following security aspects when using this class:

  1. Ensure that access to facility data is properly authenticated and authorized in the service layer.
  2. Be cautious when logging or serializing the entire Facility object, as it may contain sensitive information depending on its usage in the application.
  3. If any of the fields (e.g., additionalFields) may contain sensitive data, consider implementing data masking or encryption strategies.
  4. Implement input validation and sanitization when populating Facility objects from external sources to prevent injection attacks.
health-services/plan-service/src/main/java/digit/config/Configuration.java (2)

47-68: 🧹 Nitpick (assertive)

Summary: New configuration fields added for plan facility, facility, and project factory services.

The changes introduce new configuration fields for plan facility creation, facility host and endpoint, and project factory host and search endpoint. These additions are consistent with the existing code structure and naming conventions (with a minor suggestion for projectFactorySearchEndPoint).

To ensure smooth integration and usage of these new configurations:

  1. Verify that these new properties are properly documented in the project's configuration guide or README.
  2. Ensure that the corresponding properties are set in the appropriate application properties files (e.g., application.properties, application-dev.properties, etc.).
  3. Update any deployment scripts or configuration management tools to include these new properties when deploying the service.

67-68: 🧹 Nitpick (assertive)

LGTM with a minor suggestion: New configuration field for project factory search endpoint.

The addition of projectFactorySearchEndPoint is consistent with the existing pattern in the class and appears to be correctly configured for injecting the value of egov.project.factory.search.endpoint property.

However, for better consistency with other endpoint-related fields in this class (e.g., facilityEndPoint), consider renaming it to projectFactorySearchEndpoint (lowercase 'p' in "endpoint").

-    private String projectFactorySearchEndPoint;
+    private String projectFactorySearchEndpoint;
📝 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.

    @Value("${egov.project.factory.search.endpoint}")
    private String projectFactorySearchEndpoint;
health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java (7)

57-58: 🧹 Nitpick (assertive)

Consider adding @Valid annotation to 'auditDetails' field.

The 'auditDetails' field of type AuditDetails is likely used for tracking changes. To ensure that any validations defined in the AuditDetails class are enforced, consider adding the @Valid annotation to this field.

Here's a suggested improvement:

    @JsonProperty("auditDetails")
+   @Valid
    private AuditDetails auditDetails = null;

This change will ensure that if AuditDetails has its own validation rules, they will be checked when validating a PlanFacility object.

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

    @JsonProperty("auditDetails")
    @Valid
    private AuditDetails auditDetails = null;

35-41: 🧹 Nitpick (assertive)

Consider adding @nullable annotation to optional fields.

The 'planConfigurationId' and 'facilityId' fields are correctly defined with appropriate size constraints. However, to improve code clarity and API documentation, consider adding the @nullable annotation to explicitly indicate that these fields are optional.

Here's a suggested improvement:

    @JsonProperty("planConfigurationId")
    @Size(max = 64)
+   @Nullable
    private String planConfigurationId = null;

    @JsonProperty("facilityId")
    @Size(max = 64)
+   @Nullable
    private String facilityId = null;

This change will make it clear to other developers and API consumers that these fields can be null.

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

    @JsonProperty("planConfigurationId")
    @Size(max = 64)
    @Nullable
    private String planConfigurationId = null;

    @JsonProperty("facilityId")
    @Size(max = 64)
    @Nullable
    private String facilityId = null;

43-45: 🧹 Nitpick (assertive)

Consider adding @NotNull to 'residingBoundary' if it's a required field.

The 'residingBoundary' field has an appropriate size constraint ensuring it's not empty and has a reasonable maximum length. However, if this field is required for all PlanFacility objects, consider adding the @NotNull annotation to enforce this at the validation level.

If 'residingBoundary' is indeed a required field, here's a suggested improvement:

    @JsonProperty("residingBoundary")
    @Size(min = 1, max = 64)
+   @NotNull
    private String residingBoundary = null;

This change will ensure that the field is both present and non-empty.

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

    @JsonProperty("residingBoundary")
    @Size(min = 1, max = 64)
    @NotNull
    private String residingBoundary = null;

51-52: 🛠️ Refactor suggestion

Consider improving type safety for 'additionalDetails' field.

The 'additionalDetails' field of type Object provides flexibility but may lead to type safety issues and make the API less clear for consumers.

Consider the following improvements:

  1. If the structure of additional details is known, use a specific type instead of Object.
  2. If the structure is truly dynamic, consider using Map<String, Object> for better type hinting.
  3. Add Javadoc comments to describe the expected structure or usage of this field.

Example:

+   /**
+    * Additional details for the plan facility.
+    * This can include any extra information that doesn't fit into other fields.
+    * The structure of this object may vary based on specific requirements.
+    */
    @JsonProperty("additionalDetails")
-   private Object additionalDetails = null;
+   private Map<String, Object> additionalDetails = new HashMap<>();

This change improves type safety while maintaining flexibility, and the added documentation helps API consumers understand the field's purpose.

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

    /**
     * Additional details for the plan facility.
     * This can include any extra information that doesn't fit into other fields.
     * The structure of this object may vary based on specific requirements.
     */
    @JsonProperty("additionalDetails")
    private Map<String, Object> additionalDetails = new HashMap<>();

27-28: 🛠️ Refactor suggestion

Consider enhancing the 'id' field for better uniqueness and immutability.

While the current implementation is functional, consider the following improvements:

  1. Make the field final to ensure immutability after object creation.
  2. Use UUID instead of String for better uniqueness guarantee.
  3. Add a @NotNull annotation if the id should never be null.

Here's a suggested improvement:

-    @JsonProperty("id")
-    private String id = null;
+    @JsonProperty("id")
+    @NotNull
+    private final UUID id;

Remember to update the constructor and any related methods if you make this change.

Committable suggestion was skipped due to low confidence.


54-55: 🛠️ Refactor suggestion

Clarify the intention of the 'active' field and consider using a primitive boolean.

The 'active' field is currently defined as a Boolean object, which allows for a tri-state value (true, false, null). This might be intentional, but it's worth considering if a null state is actually needed for this field.

If a null state is not required, consider changing to a primitive boolean with a default value:

    @JsonProperty("active")
-   private Boolean active = null;
+   private boolean active = true;  // or false, depending on your default requirement

If the tri-state is intentional, please add a comment explaining the meaning of each state (true, false, null) to improve code clarity.

    @JsonProperty("active")
+   // null: status unknown, true: active, false: inactive
    private Boolean active = null;

This change will either improve type safety (if using primitive) or clarify the intention (if keeping the tri-state).

Committable suggestion was skipped due to low confidence.


47-67: 🛠️ Refactor suggestion

Consider initializing 'serviceBoundaries' with an empty list and improving the helper method.

The 'serviceBoundaries' field is correctly annotated with @Valid for nested validation. However, initializing it with an empty list instead of null can lead to safer operations and reduce the need for null checks.

Here are some suggested improvements:

  1. Initialize the list with an empty ArrayList:
    @JsonProperty("serviceBoundaries")
    @Valid
-   private List<String> serviceBoundaries = null;
+   private List<String> serviceBoundaries = new ArrayList<>();
  1. Simplify the addServiceBoundariesItem method:
    public PlanFacility addServiceBoundariesItem(String serviceBoundariesItem) {
-       if (this.serviceBoundaries == null) {
-           this.serviceBoundaries = new ArrayList<>();
-       }
        this.serviceBoundaries.add(serviceBoundariesItem);
        return this;
    }

These changes will make the code more robust and easier to use, reducing the risk of NullPointerExceptions.

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

    @JsonProperty("serviceBoundaries")
    @Valid
    private List<String> serviceBoundaries = new ArrayList<>();

    @JsonProperty("additionalDetails")
    private Object additionalDetails = null;

    @JsonProperty("active")
    private Boolean active = null;

    @JsonProperty("auditDetails")
    private AuditDetails auditDetails = null;


    public PlanFacility addServiceBoundariesItem(String serviceBoundariesItem) {
        this.serviceBoundaries.add(serviceBoundariesItem);
        return this;
    }
health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignDetail.java (5)

14-21: 🧹 Nitpick (assertive)

Enhance the class-level Javadoc comment.

While the Lombok annotations (@DaTa, @AllArgsConstructor, @NoArgsConstructor, @builder) are appropriately used for this data model class, the Javadoc comment could be more informative.

Consider expanding the Javadoc to provide more context about the purpose and usage of the CampaignDetail class. For example:

/**
 * Represents the details of a campaign in the health services project.
 * This class encapsulates all relevant information about a campaign,
 * including its identification, status, temporal aspects, and associated rules.
 */

23-28: 🧹 Nitpick (assertive)

Consider adding a size constraint to the tenantId field.

While the @NotNull annotation ensures that tenantId is not null, it might be beneficial to add a size constraint to prevent excessively long tenant IDs.

Consider adding a @Size annotation:

@NotNull
@Size(max = 256) // Adjust the max value as per your requirements
private String tenantId;

30-31: 🧹 Nitpick (assertive)

Add documentation for status and action fields.

The status and action fields could benefit from some documentation to clarify their purpose and possible values.

Consider adding Javadoc comments to these fields:

/**
 * Represents the current status of the campaign.
 * Possible values could be: DRAFT, ACTIVE, COMPLETED, etc.
 */
@JsonProperty("status")
private String status;

/**
 * Represents the action to be taken on the campaign.
 * Possible values could be: CREATE, UPDATE, DELETE, etc.
 */
@JsonProperty("action")
private String action;

Also applies to: 33-34


60-64: 🛠️ Refactor suggestion

Consider using java.time.LocalDateTime for date fields.

The startDate and endDate fields are currently using Long type, presumably to store timestamps. It might be more appropriate to use java.time.LocalDateTime for better date-time handling.

Consider refactoring these fields:

import java.time.LocalDateTime;

// ...

@JsonProperty("startDate")
private LocalDateTime startDate;

@JsonProperty("endDate")
private LocalDateTime endDate;

If you need to keep the Long type for compatibility reasons, consider adding a comment explaining the time unit (e.g., milliseconds since epoch) and possibly using a custom serializer/deserializer.


66-68: 🧹 Nitpick (assertive)

Clarify the purpose of the additionalDetails field.

The additionalDetails field of type Object is very generic. While this provides flexibility, it may lead to inconsistencies in usage.

Consider adding a comment to clarify its intended use:

/**
 * Holds any additional details about the campaign that don't fit into other fields.
 * This could be used for extensibility, but consider creating specific fields for
 * commonly used additional details in the future.
 */
@JsonProperty("additionalDetails")
@Valid
private Object additionalDetails;
health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java (4)

28-32: 🧹 Nitpick (assertive)

Improve the Javadoc comment for better documentation.

The current Javadoc comment is incomplete. Consider expanding it to include more details about the method's purpose, parameters, and return value.

Here's a suggested improvement:

/**
 * Processes requests for creating plan facilities.
 * This method validates the request, enriches it with additional data,
 * creates the plan facility, and returns a response.
 *
 * @param planFacilityRequest The request containing plan facility details
 * @return PlanFacilityResponse containing the created plan facility and response info
 * @throws SomeSpecificException if validation fails or creation encounters an error
 */

Replace SomeSpecificException with the actual exception(s) that this method might throw.


33-50: 🧹 Nitpick (assertive)

Consider adding explicit error handling.

The method currently doesn't have any visible error handling. Consider adding try-catch blocks or throwing specific exceptions for different scenarios (e.g., validation failure, database errors).

Here's a suggested structure:

public PlanFacilityResponse createPlanFacility(PlanFacilityRequest planFacilityRequest) {
    try {
        planFacilityValidator.validatePlanFacilityCreate(planFacilityRequest);
        planFacilityEnricher.enrichPlanFacilityCreate(planFacilityRequest);
        planFacilityRepository.create(planFacilityRequest);

        return PlanFacilityResponse.builder()
                .planFacility(Collections.singletonList(planFacilityRequest.getPlanFacility()))
                .responseInfo(responseInfoFactory
                        .createResponseInfoFromRequestInfo(planFacilityRequest.getRequestInfo(), true))
                .build();
    } catch (ValidationException e) {
        // Handle validation errors
    } catch (DatabaseException e) {
        // Handle database errors
    } catch (Exception e) {
        // Handle unexpected errors
    }
}

Replace ValidationException and DatabaseException with the actual exception types used in your project.

LGTM: Overall method structure is clear and logical.

The method follows a clear and logical flow: validate, enrich, create, and respond. This structure makes the code easy to understand and maintain.


1-51: 🧹 Nitpick (assertive)

Consider future expansion of the service.

The current implementation is well-structured and follows good practices. As the project evolves, you might want to add more methods to handle other operations related to plan facilities.

Consider adding a TODO comment for potential future methods:

// TODO: Add methods for updating, deleting, and retrieving plan facilities as needed.

This will serve as a reminder for future development and help maintain a comprehensive service class.


13-19: 🧹 Nitpick (assertive)

LGTM: Class declaration and dependencies are well-structured.

The @Service annotation and dependency declarations are appropriate. Good job on keeping the fields private.

Consider adding the final keyword to the fields to make them immutable, which is a good practice for dependency-injected fields:

- private PlanFacilityValidator planFacilityValidator;
- private ResponseInfoFactory responseInfoFactory;
- private PlanFacilityEnrichementService planFacilityEnricher;
- private PlanFacilityRepository planFacilityRepository;
+ private final PlanFacilityValidator planFacilityValidator;
+ private final ResponseInfoFactory responseInfoFactory;
+ private final PlanFacilityEnrichementService planFacilityEnricher;
+ private final PlanFacilityRepository planFacilityRepository;
📝 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.

@Service
public class PlanFacilityService {

    private final PlanFacilityValidator planFacilityValidator;
    private final ResponseInfoFactory responseInfoFactory;
    private final PlanFacilityEnrichementService planFacilityEnricher;
    private final PlanFacilityRepository planFacilityRepository;
health-services/plan-service/src/main/java/digit/util/CampaignUtil.java (3)

35-47: 🛠️ Refactor suggestion

Improve error handling and URI construction in fetchCampaignData.

The method is well-structured, but there are a few areas for improvement:

  1. URI Construction: Consider using UriComponentsBuilder for more robust URI construction.
  2. Exception Handling: The catch block could be more specific. Consider catching HttpClientErrorException or RestClientException instead of a generic Exception.
  3. Error Response: Instead of returning null on exception, consider throwing a custom exception or returning an error response.

Here's a suggested refactoring:

public CampaignResponse fetchCampaignData(RequestInfo requestInfo, String campaignId, String tenantId) {
    URI uri = UriComponentsBuilder.fromHttpUrl(configs.getProjectFactoryHost())
            .path(configs.getProjectFactorySearchEndPoint())
            .build()
            .toUri();

    CampaignSearchReq campaignSearchReq = getSearchReq(requestInfo, campaignId, tenantId);
    try {
        return restTemplate.postForObject(uri, campaignSearchReq, CampaignResponse.class);
    } catch (HttpClientErrorException | RestClientException e) {
        log.error("Error while fetching data from project factory: {}", e.getMessage(), e);
        throw new ServiceException("CAMPAIGN_DATA_FETCH_ERROR", "Failed to fetch campaign data", e);
    }
}

Note: You'll need to import org.springframework.web.util.UriComponentsBuilder and create a custom ServiceException class if it doesn't already exist.


49-61: 🧹 Nitpick (assertive)

LGTM: getSearchReq method is well-implemented.

The method effectively uses the builder pattern to construct the request objects. The use of configuration values for pagination is a good practice for flexibility.

Consider extracting the creation of CampaignSearchCriteria into a separate private method for improved readability:

private CampaignSearchReq getSearchReq(RequestInfo requestInfo, String campaignId, String tenantId) {
    return CampaignSearchReq.builder()
            .requestInfo(requestInfo)
            .campaignSearchCriteria(createSearchCriteria(campaignId, tenantId))
            .build();
}

private CampaignSearchCriteria createSearchCriteria(String campaignId, String tenantId) {
    Pagination pagination = Pagination.builder()
            .limit(configs.getDefaultLimit())
            .offset(configs.getDefaultOffset())
            .build();
    return CampaignSearchCriteria.builder()
            .ids(Collections.singletonList(campaignId))
            .tenantId(tenantId)
            .pagination(pagination)
            .build();
}

15-21: 🧹 Nitpick (assertive)

LGTM: Class structure and annotations are appropriate.

The use of @Slf4j and @Component annotations is appropriate for this utility class. The dependencies (RestTemplate and Configuration) are well-chosen for the class's purpose.

Consider making the restTemplate and configs fields final to ensure they cannot be modified after initialization:

-    private RestTemplate restTemplate;
-    private Configuration configs;
+    private final RestTemplate restTemplate;
+    private final Configuration configs;
📝 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.

@Slf4j
@Component
public class CampaignUtil {

    private final RestTemplate restTemplate;

    private final Configuration configs;
health-services/plan-service/src/main/resources/application.properties (1)

51-64: 🧹 Nitpick (assertive)

Summary: Configuration additions for Plan Facility API integration

The new properties added to the application.properties file are well-structured and follow existing conventions. They appear to be setting up integration points for the Plan Facility API with both a facility service and a project factory service.

To enhance the review process and ensure alignment with the PR objectives:

  1. Could you provide a brief overview of how the facility service and project factory service interact within the context of the Plan Facility API?
  2. Are there any additional configuration changes or dependencies required for these integrations that are not captured in this file?

These clarifications will help reviewers better understand the scope and impact of these changes.

health-services/plan-service/src/main/java/digit/util/FacilityUtil.java (4)

21-33: 🧹 Nitpick (assertive)

Class structure is well-organized, but consider constructor injection for ObjectMapper.

The class structure and annotations are appropriate. The use of constructor injection for RestTemplate and Configuration is a good practice. However, consider including ObjectMapper in the constructor injection instead of using field injection with @Autowired. This would make the dependencies more explicit and easier to test.

Consider modifying the constructor to include ObjectMapper:

public FacilityUtil(RestTemplate restTemplate, Configuration configs, ObjectMapper mapper) {
    this.restTemplate = restTemplate;
    this.configs = configs;
    this.mapper = mapper;
}

This change would eliminate the need for the @Autowired annotation on the mapper field.


35-61: 🛠️ Refactor suggestion

Consider refactoring fetchFacilityData for improved type safety and readability.

The method is well-structured but could benefit from some improvements:

  1. Instead of using Object as the return type for restTemplate.postForObject, consider using a more specific type like Map<String, Object>. This would provide better type safety.

  2. The method is quite long. Consider extracting the URI construction and the API call into separate private methods for better readability and maintainability.

  3. The error logging could be more informative by including the facilityId and tenantId in the log message.

Here's a suggested refactoring:

public FacilityResponse fetchFacilityData(RequestInfo requestInfo, String facilityId, String tenantId) {
    String uri = constructUri(tenantId);
    FacilitySearchRequest facilitySearchRequest = getSearchReq(requestInfo, facilityId);
    
    try {
        Map<String, Object> response = makeApiCall(uri, facilitySearchRequest);
        return mapper.convertValue(response, FacilityResponse.class);
    } catch (Exception e) {
        log.error("Error while fetching facility data for facilityId: {}, tenantId: {}", facilityId, tenantId, e);
        return new FacilityResponse(); // Consider if returning an empty response is appropriate
    }
}

private String constructUri(String tenantId) {
    return UriComponentsBuilder.fromHttpUrl(configs.getFacilityHost() + configs.getFacilityEndPoint())
            .queryParam("tenantId", tenantId)
            .queryParam("limit", configs.getDefaultLimit())
            .queryParam("offset", configs.getDefaultOffset())
            .toUriString();
}

private Map<String, Object> makeApiCall(String uri, FacilitySearchRequest request) {
    return restTemplate.postForObject(uri, request, Map.class);
}

This refactoring improves readability and separates concerns, making the code easier to maintain and test.


63-72: 🧹 Nitpick (assertive)

getSearchReq method looks good, but consider supporting multiple facility IDs.

The method is well-implemented using the builder pattern. However, wrapping the facilityId in a singleton list suggests that the API might support multiple IDs. Consider modifying the method to accept a list of facility IDs for more flexibility.

Here's a suggested modification:

private FacilitySearchRequest getSearchReq(RequestInfo requestInfo, List<String> facilityIds) {
    FacilitySearchCriteria searchCriteria = FacilitySearchCriteria.builder()
            .id(facilityIds)
            .build();

    return FacilitySearchRequest.builder()
            .requestInfo(requestInfo)
            .facilitySearchCriteria(searchCriteria)
            .build();
}

This change would allow the method to handle both single and multiple facility IDs, making it more versatile.


1-76: 🧹 Nitpick (assertive)

Overall, FacilityUtil is well-structured but has room for improvement.

The FacilityUtil class provides a good foundation for fetching facility data. It follows Spring best practices with dependency injection and uses appropriate annotations. The use of RestTemplate for HTTP requests and ObjectMapper for JSON conversion is appropriate.

Positive aspects:

  1. Good use of Spring annotations and dependency injection.
  2. Proper use of logging.
  3. Exception handling is implemented.

Areas for improvement:

  1. Consider using constructor injection for all dependencies, including ObjectMapper.
  2. Refactor the fetchFacilityData method for better readability and maintainability.
  3. Enhance error handling and logging with more context.
  4. Consider making the getSearchReq method more flexible to handle multiple facility IDs.

To further improve this class:

  1. Consider implementing retry logic for transient network issues.
  2. Add unit tests to ensure the correct behavior of the methods.
  3. Implement a caching mechanism to reduce the number of API calls for frequently accessed facility data.
  4. Consider using a circuit breaker pattern to handle potential downstream service failures gracefully.
health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java (6)

57-63: 🛠️ Refactor suggestion

Provide detailed parameter descriptions in Javadoc comments

The Javadoc for the method validatePlanFacilityCreate has an empty @param description for planFacilityRequest. Providing a detailed description enhances readability and understanding of the code.


67-75: 🛠️ Refactor suggestion

Eliminate redundant plan configuration existence checks

The method validatePlanFacilityCreate performs duplicate checks for the existence of a plan configuration:

  1. Lines 67-71: Searches for plan configurations and throws an exception if none are found.
  2. Line 74: Calls validatePlanConfigurationExistence(planFacilityRequest), which performs the same validation.

Consider removing one of these checks to avoid redundancy and improve efficiency.


214-215: 🧹 Nitpick (assertive)

Use constants for error codes and messages

The error code "FACILITY_NOT_FOUND" and the corresponding message are hardcoded. For consistency and maintainability, consider extracting them into constants in ServiceConstants.


145-148: ⚠️ Potential issue

Log exception details when encountering errors

When catching exceptions, it's good practice to log the exception details. This aids in debugging by providing more context about the error.

Apply this diff to log the caught exception:

     try {
         hierarchyConfigList = JsonPath.read(mdmsData, jsonPathForHierarchy);
     } catch (Exception e) {
+        log.error("Error reading hierarchy config from MDMS data", e);
         throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE);
     }
📝 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.

            hierarchyConfigList = JsonPath.read(mdmsData, jsonPathForHierarchy);
        } catch (Exception e) {
            log.error("Error reading hierarchy config from MDMS data", e);
            throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE);
        }

143-147: ⚠️ Potential issue

Replace System.out.println with proper logging

Using System.out.println is not recommended in production code. Instead, utilize the logger provided by @Slf4j for better control over logging levels and output destinations.

Apply this diff to replace the System.out.println with a debug log statement:

     List<Map<String, Object>> hierarchyConfigList = null;
-    System.out.println("Jsonpath for hierarchy config -> " + jsonPathForHierarchy);
+    log.debug("JsonPath for hierarchy config: {}", jsonPathForHierarchy);
     try {
         hierarchyConfigList = JsonPath.read(mdmsData, jsonPathForHierarchy);
📝 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.

        List<Map<String, Object>> hierarchyConfigList = null;
        log.debug("JsonPath for hierarchy config: {}", jsonPathForHierarchy);
        try {
            hierarchyConfigList = JsonPath.read(mdmsData, jsonPathForHierarchy);
        } catch (Exception e) {
            throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE);

177-184: ⚠️ Potential issue

Add null check for serviceBoundaries before streaming

In the method validateServiceBoundaries, ensure that planFacility.getServiceBoundaries() is not null before calling .stream(). This prevents a potential NullPointerException if getServiceBoundaries() returns null.

Apply this diff to add a null check:

+    if (planFacility.getServiceBoundaries() == null) {
+        throw new CustomException("SERVICE_BOUNDARIES_NULL", "Service boundaries cannot be null.");
+    }
     planFacility.getServiceBoundaries().stream()
         .forEach(service -> {
             if (!boundaryCode.contains(service)) {
📝 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.

    private void validateServiceBoundaries(Set<String> boundaryCode, PlanFacility planFacility) {
        if (planFacility.getServiceBoundaries() == null) {
            throw new CustomException("SERVICE_BOUNDARIES_NULL", "Service boundaries cannot be null.");
        }
        planFacility.getServiceBoundaries().stream()
                .forEach(service -> {
                    if (!boundaryCode.contains(service)) {
                        throw new CustomException(INVALID_SERVICE_BOUNDARY_CODE, INVALID_SERVICE_BOUNDARY_MESSAGE);
                    }
                });
    }

@Taniya-eGov
Copy link
Collaborator Author

@coderabbitai review

Copy link
Contributor

coderabbitai bot commented Sep 26, 2024

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Taniya-eGov
Copy link
Collaborator Author

@coderabbitai[bot] review

Copy link
Contributor

coderabbitai bot commented Sep 26, 2024

@Taniya-eGov: I will review the changes.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Taniya-eGov
Copy link
Collaborator Author

@coderabbitai review

Copy link
Contributor

coderabbitai bot commented Sep 26, 2024

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE

📥 Commits

Files that changed from the base of the PR and between 8d56f1e and db27a90.

📒 Files selected for processing (2)
  • health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchReq.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/web/models/projectFactory/Product.java (1 hunks)
🔇 Additional comments (5)
health-services/plan-service/src/main/java/digit/web/models/projectFactory/Product.java (2)

1-7: LGTM: Package declaration and imports are correct.

The package declaration and imports are appropriate for the class. The use of Jackson for JSON processing and Lombok for reducing boilerplate code is a good practice.


1-27: Overall, the Product class is well-implemented with room for minor enhancements.

The class is concise, uses appropriate annotations, and follows good Java practices. The suggested improvements (expanding Javadoc and reconsidering field types) are minor and aimed at enhancing maintainability and data representation.

Great job on creating a clean and functional data model!

health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchReq.java (3)

1-8: LGTM: Package declaration and imports are appropriate.

The package name follows Java naming conventions, and the imports are relevant to the class's functionality. The use of Jakarta validation suggests this is a Jakarta EE project, which is a modern approach.


16-18: LGTM: The requestInfo field is well-defined.

The field is properly annotated with @JsonProperty("RequestInfo") for correct JSON mapping and @Valid for nested validation, which ensures data integrity. The use of RequestInfo type, presumably from a common contract, promotes consistency across the application.


1-23: Overall, the CampaignSearchReq class is well-implemented.

The class structure is clean, uses appropriate annotations, and follows good Java practices. The use of Lombok annotations reduces boilerplate code, improving maintainability. The fields are properly defined with validation annotations, ensuring data integrity.

Minor suggestions were made to enhance the Javadoc and align the JSON property name with the field name for campaignSearchCriteria. These improvements, while not critical, would further increase the code's clarity and consistency.

Great job on implementing this request model for campaign searches!

@Taniya-eGov
Copy link
Collaborator Author

@coderabbitai full review

Copy link
Contributor

coderabbitai bot commented Sep 26, 2024

✅ Actions performed

Full review triggered.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 76

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE

📥 Commits

Files that changed from the base of the PR and between 096c580 and db27a90.

📒 Files selected for processing (30)
  • health-services/plan-service/src/main/java/digit/config/Configuration.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/config/ServiceConstants.java (3 hunks)
  • health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnrichementService.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/util/CampaignUtil.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/util/FacilityUtil.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/web/models/Pagination.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/web/models/facility/Facility.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/web/models/facility/FacilityDetail.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/web/models/facility/FacilityResponse.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/web/models/facility/FacilitySearchCriteria.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/web/models/facility/FacilitySearchRequest.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/web/models/projectFactory/Boundary.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignDetail.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignResponse.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchCriteria.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchReq.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/web/models/projectFactory/Condition.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/web/models/projectFactory/DeliveryRule.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/web/models/projectFactory/Product.java (1 hunks)
  • health-services/plan-service/src/main/java/digit/web/models/projectFactory/Resource.java (1 hunks)
  • health-services/plan-service/src/main/resources/application.properties (1 hunks)
  • health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql (1 hunks)
🧰 Additional context used
📓 Learnings (3)
health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java (1)
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java:10-12
Timestamp: 2024-09-26T08:10:11.360Z
Learning: In this codebase, `update` methods in repositories are designed not to return any value.
health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java (1)
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java:10-12
Timestamp: 2024-09-26T08:10:11.360Z
Learning: In this codebase, `update` methods in repositories are designed not to return any value.
health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java (1)
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#902
File: health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java:553-553
Timestamp: 2024-09-25T08:41:31.377Z
Learning: The plan-service project is using Java 17.
🔇 Additional comments (79)
health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java (2)

1-1: LGTM: Package declaration is correct and follows conventions.

The package declaration digit.repository is consistent with the file path and follows Java naming conventions.


3-3: LGTM: Import statement is correct and specific.

The import of PlanFacilityRequest is necessary for the method parameter and follows the best practice of using specific imports.

health-services/plan-service/src/main/java/digit/web/models/facility/FacilityDetail.java (2)

1-8: LGTM: Package declaration and imports are correct.

The package declaration is consistent with the file path, and all necessary imports for the used annotations are present. There are no unused imports.


13-19: LGTM: Class structure is clear, but some clarifications needed.

The class structure is simple and well-defined. The @JsonProperty annotations ensure proper JSON handling.

Please clarify the following:

  1. The Facility type is not imported. Is it in the same package? If not, please add the import.
  2. The purpose of additionalInfo is not clear. Consider adding a comment explaining its usage or renaming it to be more descriptive.

To verify the Facility class location, run:

✅ Verification successful

: The Facility class is located within the same package, so no import statement is needed.

To clarify the purpose of additionalInfo, please provide more context or consider adding comments explaining its usage.

To further investigate, run the following script to find all references to additionalInfo:

#!/bin/bash
# Search for usages of 'additionalInfo' in the codebase
rg 'additionalInfo'
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for the Facility class definition
rg --type java -g '!FacilityDetail.java' 'class Facility'

Length of output: 4176

health-services/plan-service/src/main/java/digit/web/models/projectFactory/Product.java (4)

1-8: LGTM: Package declaration and imports are appropriate.

The package declaration and imports are correctly set up for the Product class, including necessary Jackson and Lombok annotations.


9-16: Good use of Lombok annotations, but Javadoc could be improved.

The Lombok annotations (@DaTa, @AllArgsConstructor, @NoArgsConstructor, @builder) are excellent for reducing boilerplate code. However, the Javadoc comment for the class is minimal and could be more informative.

As suggested in a previous review, consider expanding the Javadoc to provide more details about the purpose of the Product class and its usage. For example:

/**
 * Represents a product in the plan facility.
 * This class encapsulates the basic information about a product,
 * including its name, count, and value.
 */

18-25: Consider type adjustments for better data representation.

The fields and their @JsonProperty annotations are correctly implemented. However, as suggested in a previous review, consider the following improvements:

  1. The 'count' field is currently an int. For products that might have large quantities, consider using long instead.
  2. The 'value' field is a String. If this represents a monetary value, consider using BigDecimal for precise calculations.

Here's a suggested refactoring:

 @JsonProperty("count")
-private int count;
+private long count;

 @JsonProperty("value")
-private String value;
+private BigDecimal value;

If you decide to use BigDecimal, don't forget to add the import:

import java.math.BigDecimal;

1-27: LGTM: Overall class structure is well-designed.

The Product class is well-structured, making good use of Lombok annotations to reduce boilerplate code. The class follows Java conventions and has a clear purpose of representing a product with its associated attributes.

health-services/plan-service/src/main/java/digit/web/models/facility/FacilitySearchRequest.java (3)

1-9: LGTM: Import statements are appropriate and complete.

The import statements include all necessary classes for the functionality of this class, including Jackson for JSON processing, Lombok for code generation, and the custom RequestInfo class. There are no unused imports.


10-14: LGTM: Class declaration and Lombok annotations are well-structured.

The class name FacilitySearchRequest accurately reflects its purpose. Lombok annotations (@DaTa, @builder, @NoArgsConstructor, @AllArgsConstructor) are used appropriately to reduce boilerplate code and provide flexibility in object creation and manipulation.


1-20: Overall, the FacilitySearchRequest class is well-implemented.

The class is well-structured, uses Lombok effectively to reduce boilerplate code, and properly annotates JSON properties. It serves its purpose as a search request model for facilities. The only suggestion for improvement is to consider renaming the JSON property for facilitySearchCriteria to better reflect its content.

health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchReq.java (5)

1-8: LGTM: Package declaration and imports are appropriate.

The package declaration and imports are correctly defined for the CampaignSearchReq class. All necessary dependencies are included.


9-14: LGTM: Class structure is well-defined. Consider enhancing the Javadoc.

The use of Lombok annotations @Data and @Builder is appropriate, reducing boilerplate code and improving maintainability. However, the Javadoc comment is still minimal.

As suggested in the previous review, consider expanding the Javadoc comment to provide more details about the class's purpose and usage. For example:

/**
 * CampaignSearchReq
 * 
 * This class represents the request structure for searching campaigns.
 * It encapsulates the request information and search criteria used for querying campaign data.
 */

16-18: LGTM: requestInfo field is well-defined.

The requestInfo field is correctly defined with appropriate annotations:

  • @JsonProperty("RequestInfo") ensures proper JSON serialization/deserialization.
  • @Valid annotation ensures nested validation, which is a good practice for complex objects.

20-22: LGTM with a suggestion: Consider aligning the JSON property name with the field name.

The campaignSearchCriteria field is well-defined with proper annotations. However, there's still an inconsistency between the field name and its JSON representation.

Consider changing the @JsonProperty value to match the field name for consistency:

@JsonProperty("campaignSearchCriteria")
@Valid
private CampaignSearchCriteria campaignSearchCriteria;

This change would make the JSON representation more intuitive and consistent with the Java field name.


1-23: Overall, the CampaignSearchReq class is well-structured and follows good practices.

The class effectively encapsulates the request structure for searching campaigns. It uses Lombok annotations to reduce boilerplate code and includes proper validation annotations. The suggested improvements (enhancing Javadoc and aligning JSON property names) are minor and do not affect functionality but would enhance code quality and maintainability.

health-services/plan-service/src/main/java/digit/web/models/projectFactory/Condition.java (2)

1-7: LGTM: Package declaration and imports are correct.

The package declaration follows Java naming conventions, and all necessary imports for Jackson and Lombok annotations are present without any unused imports.


1-27: Overall, the code is well-structured and follows good practices.

The Condition class is concise, focused, and effectively uses Lombok and Jackson annotations. It provides a clear structure for representing conditions in the project factory context.

Summary of suggestions:

  1. Enhance the class-level Javadoc for better documentation.
  2. Consider using more specific types for properties, especially an enum for the operator.

These minor improvements would further enhance the code's robustness and maintainability.

health-services/plan-service/src/main/java/digit/web/models/facility/FacilityResponse.java (4)

1-10: LGTM: Package declaration and imports are correct.

The package declaration and imports are well-organized and include all necessary dependencies for the class implementation.


12-15: LGTM: Appropriate use of Lombok annotations.

The Lombok annotations (@DaTa, @builder, @NoArgsConstructor, @AllArgsConstructor) are well-chosen for this response model class. They will generate the necessary boilerplate code, making the class concise and easy to use.


16-22: LGTM: Well-structured response class with appropriate fields.

The FacilityResponse class is well-defined with two relevant fields: responseInfo and facilities. The use of @JsonProperty annotations ensures correct JSON serialization/deserialization.

Note: The JSON property names use PascalCase ("ResponseInfo", "Facilities") while the Java field names use camelCase. This is likely intentional to match API conventions, but ensure it's consistent with other response models in the project.


1-22: LGTM: Well-implemented response model for facility API.

This FacilityResponse class is a well-structured and clean implementation of a response model for facility-related API endpoints. It effectively uses Lombok annotations to reduce boilerplate code and Jackson annotations for proper JSON handling. The class design is appropriate for its purpose and follows Java best practices.

health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql (1)

1-17: Overall table structure looks good, consider the suggested improvements.

The plan_facility_linkage table is well-structured and includes necessary fields for linking plans and facilities. The primary key and foreign key constraints are correctly implemented, ensuring data integrity.

While the current structure is functional, consider the following suggestions for potential improvements:

  1. Using native timestamp types for created_time and last_modified_time.
  2. Adding a unique constraint for tenant_id and plan_configuration_id if it aligns with business logic.
  3. Using a more structured data type for service_boundaries.
  4. Adding a default value for the active column.

These changes could enhance the table's functionality and data management capabilities.

health-services/plan-service/src/main/java/digit/web/models/projectFactory/Boundary.java (2)

1-8: LGTM: Package declaration and imports are correct.

The package declaration and imports are appropriate for the class. The use of Jackson for JSON processing and Lombok for reducing boilerplate code is a good practice.


1-32: Verify if additional logic or interface implementations are needed.

The current implementation of the Boundary class is a simple data model using Lombok annotations, which is a good practice for reducing boilerplate code. However, consider the following points:

  1. Verify if this class needs to implement any interfaces or extend any base classes based on your project's architecture.
  2. Determine if any additional validation logic is required for the fields, such as ensuring non-null values or specific formats for the code or type fields.
  3. Consider if any custom business logic methods should be added to this class, depending on how it's used within the project.

To help verify the usage and potential needs for this class, you can run the following script:

This script will help identify how the Boundary class is used, if there are any related interfaces or base classes, and common validation patterns in the project.

health-services/plan-service/src/main/java/digit/web/models/projectFactory/Resource.java (1)

1-7: LGTM: Package declaration and imports are appropriate.

The package name follows Java naming conventions, and the necessary imports for Jackson and Lombok annotations are correctly included.

health-services/plan-service/src/main/java/digit/web/models/facility/FacilitySearchCriteria.java (8)

11-15: LGTM! Class annotations are appropriate.

The Lombok annotations (@DaTa, @builder, @NoArgsConstructor, @AllArgsConstructor) are well-chosen for this class. They will generate necessary boilerplate code, improving maintainability and reducing the chance of errors.


16-17: LGTM! The tenantId field is well-defined.

The tenantId field is correctly annotated with @JsonProperty and has an appropriate type (String) for an ID field.


19-20: LGTM! The id field is well-defined and flexible.

The id field is correctly annotated with @JsonProperty and uses List, allowing for searches with multiple facility IDs.


22-23: LGTM! The name field is properly defined.

The name field is correctly annotated with @JsonProperty and has an appropriate type (String) for a name field.


25-26: LGTM! The isDeleted field is well-defined.

The isDeleted field is correctly annotated with @JsonProperty and uses Boolean, allowing for a nullable state. The field name follows the "is" prefix convention for boolean properties.


1-30: Great job! The FacilitySearchCriteria class is well-designed and implemented.

The class structure, annotations, and fields are all appropriate for its purpose as a search criteria model. The use of Lombok annotations reduces boilerplate code, and the Jackson annotations ensure proper JSON serialization/deserialization. The class follows Java naming conventions and best practices.

A few points to consider for future enhancements:

  1. Consider adding validation annotations (e.g., from Jakarta Validation) to enforce constraints on the fields if needed.
  2. If this class is part of a public API, consider adding Javadoc comments to describe the purpose and usage of each field.

Overall, this is a solid implementation that should serve its purpose well in the facility search functionality.


1-10: LGTM! Package and imports look good.

The package declaration and imports are correctly structured and include all necessary dependencies for Jackson and Lombok annotations.

To ensure the Pagination class is properly defined, let's verify its existence and structure:

✅ Verification successful

Pagination Class Verified

The Pagination class in the digit.web.models package is properly defined and includes the necessary annotations. No issues found.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the existence and structure of the Pagination class

# Test: Search for the Pagination class definition
rg --type java -g '*.java' -A 10 'class Pagination'

Length of output: 3663


28-29: LGTM! The pagination field is well-structured.

The pagination field is correctly annotated with @JsonProperty and uses a custom Pagination type, which is a good practice for managing complex pagination logic.

To ensure the Pagination class is properly defined and contains the expected fields, let's verify its structure:

✅ Verification successful

Verified: The pagination field in FacilitySearchCriteria.java correctly imports and utilizes the Pagination class from digit.web.models.Pagination. All relevant annotations and field definitions are appropriate.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the structure of the Pagination class

# Test: Search for the Pagination class definition and its fields
rg --type java -g '*.java' -A 15 'class Pagination'

Length of output: 5261


Script:

#!/bin/bash
# Description: Verify which Pagination class is imported in FacilitySearchCriteria.java

rg 'import .*Pagination;' health-services/plan-service/src/main/java/digit/web/models/facility/FacilitySearchCriteria.java

Length of output: 160

health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.java (3)

1-11: LGTM: Package declaration and imports are appropriate.

The package name follows Java conventions, and the imports are relevant to the class's functionality, including JSON processing, validation, and Lombok for reducing boilerplate code.


20-20: LGTM: Class declaration is appropriate.

The class name PlanFacilityRequest is descriptive and follows Java naming conventions. Its public visibility is suitable for a request model.


1-30: Overall, the PlanFacilityRequest class is well-structured and follows good practices.

The class effectively uses annotations for validation, JSON mapping, and reducing boilerplate code. It serves its purpose as a request model for plan facility operations.

To further improve the class:

  1. Consider adding @JsonIgnoreProperties(ignoreUnknown = true) for better API flexibility.
  2. Evaluate the use of @NotNull or Optional<> for properties based on your application's requirements.

These changes would enhance the robustness and clarity of the class.

health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignResponse.java (1)

1-10: LGTM: Package declaration and imports are well-organized.

The package declaration is correct, and all necessary imports are present without any unused ones. This demonstrates good code organization.

health-services/plan-service/src/main/java/digit/web/models/Pagination.java (2)

1-11: LGTM: Package declaration and imports are appropriate.

The package declaration follows Java naming conventions, and all imports are relevant to the class functionality. No unused imports are present.


21-34: Review field annotations and types.

The field annotations are generally appropriate, but there are a few points to consider:

  1. The @JsonIgnore on sortBy and sortOrder prevents these fields from being serialized to JSON. Ensure this is the intended behavior, as it might affect API responses.

  2. The constraints on limit (1 to 50) and offset (non-negative) are good practices.

  3. Consider using primitive int instead of Integer for limit and offset if null values are not needed. This would prevent potential NullPointerExceptions.

To ensure consistent usage of the Pagination class, run the following script:

This script will help verify if the @JsonIgnore annotations on sortBy and sortOrder are consistent with the class usage throughout the project.

✅ Verification successful

Pagination Annotations Verified Successfully.

The usage of @JsonIgnore on sortBy and sortOrder is consistent across the codebase, and no custom JSON serialization overrides this behavior. The annotations are correctly implemented, ensuring these fields are excluded from JSON responses as intended.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of Pagination class and its fields

# Check for usage of Pagination class
echo "Checking usage of Pagination class:"
rg --type java "Pagination" -C 3

# Check for usage of sortBy and sortOrder fields
echo "\nChecking usage of sortBy and sortOrder fields:"
rg --type java "sortBy|sortOrder" -C 3

# Check for any custom JSON serialization of Pagination
echo "\nChecking for custom JSON serialization of Pagination:"
rg --type java "ObjectMapper.*Pagination" -C 3

Length of output: 49872

health-services/plan-service/src/main/java/digit/web/models/projectFactory/DeliveryRule.java (3)

1-11: LGTM: Package declaration and imports are appropriate.

The package name follows Java naming conventions, and the imports are relevant to the class's functionality. Good job on keeping the imports clean and focused.


24-26: LGTM: products field is well-defined with proper validation.

The use of @Valid annotation ensures that the Product objects within the list are also validated. This is a good practice for nested object validation.


31-33: LGTM: conditions field is well-defined with proper validation.

The use of @Valid annotation ensures that the Condition objects within the list are also validated. This is a good practice for nested object validation.

health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java (1)

1-12: LGTM: Class structure and annotations are appropriate.

The class is correctly annotated with @Repository and @Slf4j, and it implements the PlanFacilityRepository interface. The package name follows the convention digit.repository.impl, which is consistent with Spring best practices.

health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java (4)

1-14: LGTM: Package declaration and imports are appropriate.

The package name follows Java naming conventions, and the imports are relevant to the class functionality. No unused imports are present.


18-23: LGTM: Class-level annotations are well-chosen.

The combination of @Validated, @Data, @AllArgsConstructor, @NoArgsConstructor, and @Builder annotations provides a good balance of validation, code reduction, and flexibility in object creation.


32-35: LGTM: The responseInfo method is well-implemented.

This method correctly implements the builder pattern, allowing for fluent method chaining. It's consistent with the class design and annotations.


1-44: Overall, the PlanFacilityResponse class is well-implemented.

The class structure, annotations, and methods are appropriate for a response model. The use of Lombok annotations reduces boilerplate code, and the builder pattern implementation allows for flexible object creation. The suggested improvements for null handling are minor and can further enhance the robustness of the class.

health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchCriteria.java (3)

1-15: LGTM: Package declaration and imports are appropriate.

The package declaration and imports are well-organized and relevant to the class's functionality. Good job on maintaining clean imports without any unused ones.


26-32: LGTM: Appropriate use of JSON and validation annotations.

The use of @JsonProperty, @JsonIgnore, @Size, and @Valid annotations is well-implemented. These annotations provide proper control over JSON serialization and input validation, which is crucial for maintaining data integrity and API consistency.

Also applies to: 49-51


1-52: Overall, well-structured class with minor suggestions for improvement.

The CampaignSearchCriteria class is well-designed and follows good practices for a search criteria object. The use of appropriate annotations for JSON handling and validation is commendable. To further improve the code:

  1. Enhance the class-level Javadoc comment to provide more context about the class's purpose and usage.
  2. Consider using LocalDate or Instant for startDate and endDate instead of Integer.
  3. Use Boolean object instead of primitive boolean for campaignsIncludeDates to allow for null values.

These changes will make the class more robust and easier to use in various contexts.

health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnrichementService.java (2)

1-9: LGTM: Package declaration and imports are appropriate.

The package declaration and imports are well-organized and relevant to the class's functionality. The use of Jakarta validation, Lombok for logging, and Spring annotations indicates good practices for input validation, logging, and dependency injection.


1-35: Overall assessment: Good implementation with minor improvements suggested.

The PlanFacilityEnrichmentService provides a solid foundation for enriching plan facility creation requests. The code is well-structured, uses appropriate annotations, and follows good practices for input validation and data enrichment.

Key points:

  1. Fix the typo in the class name.
  2. Enhance the method documentation for better clarity.
  3. Consider making the default active status configurable for increased flexibility.

These improvements will enhance the code quality and maintainability of the service.

health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java (1)

1-14: LGTM: Package declaration and imports are appropriate.

The package declaration and imports are well-organized and include all necessary classes and annotations for the controller's functionality. The use of Jakarta validation is a good practice for input validation.

health-services/plan-service/src/main/java/digit/web/models/facility/Facility.java (2)

3-9: LGTM: Import statements are appropriate and concise.

The import statements are well-organized and include only the necessary classes and annotations for the Facility class.


10-14: LGTM: Appropriate use of Lombok annotations.

The Lombok annotations (@DaTa, @builder, @NoArgsConstructor, @AllArgsConstructor) are well-chosen to reduce boilerplate code and provide necessary functionality for the Facility class.

health-services/plan-service/src/main/java/digit/config/Configuration.java (5)

47-48: LGTM: New configuration field for plan facility create topic.

The addition of planFacilityCreateTopic is consistent with the existing pattern and naming convention in the class. It's correctly annotated for property injection.


57-58: LGTM: New configuration field for facility host.

The addition of facilityHost is consistent with the existing pattern and naming convention in the class. It's correctly annotated for property injection.


64-65: LGTM: New configuration field for project factory host.

The addition of projectFactoryHost is consistent with the existing pattern and naming convention in the class. It's correctly annotated for property injection.


67-68: LGTM: New configuration field for project factory search endpoint.

The addition of projectFactorySearchEndPoint is consistent with the existing pattern and naming convention in the class. It's correctly annotated for property injection.


47-68: Summary: New configuration fields added for plan facility, facility, and project factory.

The changes introduce five new configuration fields to the Configuration class:

  1. planFacilityCreateTopic
  2. facilityHost
  3. facilityEndPoint
  4. projectFactoryHost
  5. projectFactorySearchEndPoint

These additions enhance the configuration capabilities of the class, allowing for more flexible setup of plan facilities, facilities, and project factories. The changes are well-implemented and consistent with the existing code structure.

To ensure these new configuration properties are properly set, please verify that the corresponding properties are added to the application's configuration files (e.g., application.properties or application.yml). Run the following script to check for the presence of these properties:

✅ Verification successful

Verification: New configuration properties are present in configuration files.

All new configuration properties defined in Configuration.java are present in health-services/plan-service/src/main/resources/application.properties:

  • plan.facility.create.topic
  • plan.default.offset
  • plan.default.limit
  • egov.facility.host
  • egov.facility.search.endpoint
  • egov.project.factory.host
  • egov.project.factory.search.endpoint

No issues were found regarding the presence of these configuration properties.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for the presence of new configuration properties

# Test: Search for new configuration properties
echo "Searching for new configuration properties..."
rg --type yaml --type properties "plan\.facility\.create\.topic|egov\.facility\.host|egov\.facility\.search\.endpoint|egov\.project\.factory\.host|egov\.project\.factory\.search\.endpoint"

echo "If no results are shown above, please ensure that these properties are added to the appropriate configuration files."

Length of output: 569


Script:

#!/bin/bash
# Description: Check for the presence of new configuration properties in .properties, .yaml, and .yml files

# Test: Search for new configuration properties
echo "Searching for new configuration properties in .properties, .yaml, and .yml files..."
rg "plan\.facility\.create\.topic|plan\.default\.offset|plan\.default\.limit|egov\.facility\.host|egov\.facility\.search\.endpoint|egov\.project\.factory\.host|egov\.project\.factory\.search\.endpoint" --glob "*.properties" --glob "*.yaml" --glob "*.yml"

echo "If no results are shown above, please ensure that these properties are added to the appropriate configuration files."

Length of output: 2602

health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java (3)

27-58: LGTM! Fields and annotations are well-defined.

The class fields are appropriately defined with proper JSON property names and validation constraints. The use of @NotNull and @Size annotations ensures data integrity. The @Valid annotation on the serviceBoundaries list is a good practice for nested validation.


61-67: LGTM! The addServiceBoundariesItem method is well-implemented.

The method correctly handles the case where the list is null by initializing it. Returning this allows for method chaining, which is a good practice for builder-like methods.


3-15: LGTM! Import statements are appropriate and concise.

All necessary classes are imported, and there are no unused or redundant imports. The use of specific imports rather than wildcard imports is a good practice.

health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignDetail.java (2)

1-12: LGTM: Package declaration and imports are well-organized.

The package declaration and imports are correctly structured and include all necessary dependencies for the class implementation. Good job on keeping the imports clean and relevant.


33-34: Clarify the purpose and usage of the 'action' field.

The action field is present without any context or constraints. It's unclear what values it can take or what its purpose is in the campaign detail.

Could you provide more information about the intended use and possible values for the action field? Consider adding documentation or constraints if applicable.

health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java (3)

1-12: LGTM: Package declaration and imports are correct and complete.

The package declaration is appropriate for a service class, and all necessary imports are present without any unused ones.


21-26: LGTM: Constructor is well-implemented with proper dependency injection.

The constructor correctly initializes all dependencies using constructor injection, which is a recommended practice in Spring for mandatory dependencies.


1-51: Overall, the PlanFacilityService class is well-implemented and follows Spring best practices.

The class structure, dependency injection, and method implementation are all well-done. The code is clean, readable, and follows a logical flow. To further improve the code quality, consider implementing the following suggestions:

  1. Add the final modifier to the private fields to make them immutable.
  2. Implement error handling in the createPlanFacility method to make it more robust.

These changes will enhance the overall quality and reliability of the service.

health-services/plan-service/src/main/resources/application.properties (5)

51-51: LGTM: New Kafka topic for plan facility creation.

The new property plan.facility.create.topic=save-plan-facility is correctly added and follows the existing naming convention for Kafka topics in this configuration file.


60-60: LGTM: New endpoint configuration for facility search.

The new property egov.facility.search.endpoint=/facility/v1/_search is correctly added and follows the existing naming convention for endpoint configurations. The inclusion of API versioning (v1) in the endpoint is a good practice.


64-64: LGTM: New endpoint configuration for project factory search.

The new property egov.project.factory.search.endpoint=/project-factory/v1/project-type/search is correctly added and follows the existing naming convention for endpoint configurations. The inclusion of API versioning (v1) in the endpoint is a good practice.


59-59: LGTM: New host configuration for facility service.

The new property egov.facility.host=https://unified-dev.digit.org is correctly added and follows the existing naming convention for host configurations.

Please verify that this URL is the correct development environment for the facility service. Also, ensure that there's a plan to update this URL for different deployment environments (e.g., staging, production).

#!/bin/bash
# Description: Check for environment-specific configuration files

# Test: Look for environment-specific property files
echo "Checking for environment-specific configuration files:"
fd -e properties -e yaml -e yml | grep -i "application-.*\.(properties|ya?ml)"

51-64: Overall changes look good, but verify integration with new services.

The new properties added for plan facility creation and integration with facility and project factory services are well-structured and follow existing conventions. These additions suggest that the application is being extended to interact with new services or new functionalities are being added.

Please ensure that there are corresponding code changes in the application to utilize these new configurations. Also, verify that the integration with these new services (facility and project factory) has been properly implemented and tested.

#!/bin/bash
# Description: Check for usage of new properties in the codebase

# Test: Look for occurrences of the new property names in Java files
echo "Occurrences of new properties in Java files:"
rg "plan\.facility\.create\.topic|egov\.facility\.host|egov\.facility\.search\.endpoint|egov\.project\.factory\.host|egov\.project\.factory\.search\.endpoint" --type java
health-services/plan-service/src/main/java/digit/config/ServiceConstants.java (5)

133-134: LGTM: Constants for invalid residing boundary.

The new constants INVALID_RESIDING_BOUNDARY_CODE and INVALID_RESIDING_BOUNDARY_MESSAGE are well-defined and follow the existing naming convention. They provide clear error identification for invalid residing boundaries.


190-190: LGTM: Constant for facility fetching error.

The new constant ERROR_WHILE_FETCHING_FROM_FACILITY is well-defined and consistent with other error message constants in the file. It clearly describes the nature of the exception that occurred.


191-191: LGTM: Constant for project factory fetching error.

The new constant ERROR_WHILE_FETCHING_FROM_PROJECT_FACTORY is well-defined and consistent with other error message constants in the file. It clearly describes the nature of the exception that occurred when fetching campaign details.


193-194: LGTM: Constants for campaign details not found error.

The new constants NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE and NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE are well-defined and follow the existing naming convention. They provide clear error identification and a descriptive message for scenarios where campaign details are not found for a given campaign ID.


Line range hint 1-198: Overall assessment: Well-structured additions to ServiceConstants.

The new constants added to the ServiceConstants class are well-defined, follow existing naming conventions, and provide clear error codes and messages for various scenarios. These additions seem to support new features or enhanced error handling related to boundaries, campaigns, and hierarchies.

A few minor suggestions have been made for improved consistency and readability. Overall, the changes to this file are appropriate and maintain the existing code quality standards.

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.

1 participant