Skip to content

Conversation

@renczesstefan
Copy link
Member

@renczesstefan renczesstefan commented Aug 21, 2025

Description

Replaced the deprecated stringId field with the new id field throughout the codebase, maintaining backward compatibility by merging both fields during queries. Updated ImmediateField and its references to simplify type handling, and moved it to a more appropriate package. These changes improve clarity, support future deprecation, and ensure smooth transitions.

Dependencies

No new dependencies were introduced

Third party dependencies

No new dependencies were introduced

Blocking Pull requests

There are no dependencies on other PR

How Has Been This Tested?

This was tested manually.

Test Configuration

Name Tested on
OS macOS Sequoia 15.3.1
Runtime Java 21
Dependency Manager Maven 3.9.9n
Framework version Spring Boot 3.2.5
Run parameters
Other configuration

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • My changes have been checked, personally or remotely, with @...
  • I have commented my code, particularly in hard-to-understand areas
  • I have resolved all conflicts with the target branch of the PR
  • I have updated and synced my code with the target branch
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing tests pass locally with my changes:
    • Lint test
    • Unit tests
    • Integration tests
  • I have checked my contribution with code analysis tools:
  • I have made corresponding changes to the documentation:
    • Developer documentation
    • User Guides
    • Migration Guides

Summary by CodeRabbit

  • New Features
    • Case search now supports an id parameter (single value or list) for filtering cases.
  • Improvements
    • Filtering by case identifiers is more reliable: requests can include id and legacy stringId values.
  • Deprecations
    • stringId in search requests is deprecated; use id instead.
  • Documentation
    • API docs updated to reflect id parameter and stringId deprecation.
  • Behavior Changes
    • Case/task date serialization now uses default date-time handling.

Replaced the deprecated `stringId` field with the new `id` field throughout the codebase, maintaining backward compatibility by merging both fields during queries. Updated `ImmediateField` and its references to simplify type handling, and moved it to a more appropriate package. These changes improve clarity, support future deprecation, and ensure smooth transitions.
@renczesstefan renczesstefan self-assigned this Aug 21, 2025
@renczesstefan renczesstefan added the bugfix A change that fixes a bug label Aug 21, 2025
@coderabbitai
Copy link

coderabbitai bot commented Aug 21, 2025

Walkthrough

Adds CaseSearchRequest.id (deprecates stringId); ElasticCaseService now combines request.id and request.stringId to build a terms query on Elasticsearch document _id; ImmediateField moved to elastic.domain and its type changed from FieldType to String; removed an unused import in ElasticCase.

Changes

Cohort / File(s) Summary
Elasticsearch case search service logic
application-engine/.../elastic/service/ElasticCaseService.java
Combine request.id and deprecated request.stringId into a single validIds list; build a terms filter against Elasticsearch document field _id using FieldValue.of(...); update local variable names and Javadoc/examples accordingly.
Search request model updates
application-engine/.../elastic/web/requestbodies/CaseSearchRequest.java
Add public List<String> id with @JsonFormat(ACCEPT_SINGLE_VALUE_AS_ARRAY); mark existing stringId as deprecated via Javadoc and @Deprecated(since = "7.0.0").
Elastic domain types
nae-object-library/.../objects/elastic/domain/ImmediateField.java, nae-object-library/.../objects/elastic/domain/ElasticCase.java
Move ImmediateField into objects.elastic.domain; change its type field from FieldType to String and set via field.getType().getName(); remove unused ImmediateField import from ElasticCase.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Client
  participant Request as CaseSearchRequest
  participant Service as ElasticCaseService
  participant ES as Elasticsearch

  Client->>Request: submit search payload (id[] and/or stringId[] )
  Client->>Service: call search(request)
  Service->>Service: validIds = concat(request.id, request.stringId) // Optional-safe
  alt validIds empty
    Service-->>Client: continue without ID terms filter / or return no filter
  else validIds present
    Service->>ES: terms query on _id with validIds (FieldValue.of(...))
    ES-->>Service: hits
    Service-->>Client: results
  end
  Note over Request,Service: `stringId` retained for backward compatibility (deprecated)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 275df2d and 222fc3b.

📒 Files selected for processing (1)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticTask.java (0 hunks)
💤 Files with no reviewable changes (1)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticTask.java
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/elastic_search_by_string_id

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

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • 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.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

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

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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.

@coderabbitai coderabbitai bot added improvement A change that improves on an existing feature Large labels Aug 21, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
application-engine/src/main/java/com/netgrif/application/engine/elastic/web/requestbodies/CaseSearchRequest.java (1)

98-104: Map-based constructor ignores id (functional gap vs. JSON binding)

When CaseSearchRequest is constructed via the Map constructor, id is never populated (only stringId is). This breaks parity with the Jackson path and can make id-based queries no-op for callers that use the Map route.

Apply this diff to support both id and stringId (and to accept a single string as well as a list, mirroring ACCEPT_SINGLE_VALUE_AS_ARRAY):

-        if (request.containsKey("stringId") && request.get("stringId") instanceof List) {
-            this.stringId = (List<String>) request.get("stringId");
-        }
+        if (request.containsKey("stringId")) {
+            Object rawStringId = request.get("stringId");
+            if (rawStringId instanceof List) {
+                this.stringId = (List<String>) rawStringId;
+            } else if (rawStringId instanceof String) {
+                this.stringId = List.of((String) rawStringId);
+            }
+        }
+        if (request.containsKey("id")) {
+            Object rawId = request.get("id");
+            if (rawId instanceof List) {
+                this.id = (List<String>) rawId;
+            } else if (rawId instanceof String) {
+                this.id = List.of((String) rawId);
+            }
+        }

If desired, we can also add a DEBUG log when stringId is present to help track deprecation usage.

Would you like me to add a small unit test to verify the Map constructor populates id for both String and List inputs?

🧹 Nitpick comments (5)
application-engine/src/main/java/com/netgrif/application/engine/elastic/web/requestbodies/CaseSearchRequest.java (1)

50-55: Deprecation metadata looks right; consider communicating removal timeline

The @deprecated(since = "7.0.0") and Javadoc are clear. As a minor improvement, you may want to add a brief note on the planned removal version to set expectations for clients.

application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseService.java (1)

426-444: Fix JSON examples (missing colon) in Javadoc

Minor docs nit: the array examples are missing a colon after the field name.

Apply this doc-only diff:

-     *     "id" [
+     *     "id": [
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ImmediateField.java (3)

4-4: Avoid coupling ES projection to domain Field<?>; prefer a factory/mapper

Importing and accepting Field<?> here creates a dependency from the ES DTO to the domain model. That coupling makes reindexing/migrations harder.

Move the conversion to a mapper and keep this class as a plain DTO:

// Keep the POJO constructor
public ImmediateField(String stringId, I18nString name, String type) {
    this.stringId = stringId;
    this.name = name;
    this.type = type;
}

// Mapper (elsewhere, not in this DTO)
public static ImmediateField from(Field<?> field) {
    return new ImmediateField(field.getStringId(), field.getName(),
        field.getType() != null ? field.getType().getName() : null);
}

This keeps elastic.domain free of higher-level dependencies, easing maintenance and future index schema changes.


18-18: “type” as a free-form String: ensure ES mapping is keyword and consider a clearer property name

Switching to String is fine, but:

  • Make sure the ES mapping for this field is keyword to avoid analyzer bloat and accidental full-text behavior.
  • Optional: rename to fieldType to avoid ambiguity with ES “type” terminology and improve readability.

Apply if you want the clearer name:

-    private String type;
+    private String fieldType;
@@
-        this.type = field.getType().getName();
+        this.fieldType = field.getType().getName();

Please confirm the index template/mapping defines this field as keyword (not text). If not, you’ll want to adjust the template and reindex.

Also applies to: 26-26


23-27: Defensive null-safety in constructor

field and field.getType() may be null depending on upstream data. A small guard prevents an NPE during indexing.

Apply:

-    public ImmediateField(Field<?> field) {
-        this.stringId = field.getStringId();
-        this.name = field.getName();
-        this.type = field.getType().getName();
-    }
+    public ImmediateField(Field<?> field) {
+        java.util.Objects.requireNonNull(field, "field");
+        this.stringId = field.getStringId();
+        this.name = field.getName();
+        var ft = field.getType();
+        this.type = (ft != null) ? ft.getName() : null;
+    }

Given the PR’s broader “stringId → id” migration for cases/tasks (per prior learnings), confirm that keeping stringId here is intentional for fields. If unifying naming is desired, we can rename to id and adapt upstream mappers accordingly. I can prep that change if needed.

📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between bc21e3c and 275df2d.

📒 Files selected for processing (4)
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseService.java (1 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/web/requestbodies/CaseSearchRequest.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java (0 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ImmediateField.java (2 hunks)
💤 Files with no reviewable changes (1)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: renczesstefan
PR: netgrif/application-engine#339
File: application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy:341-341
Timestamp: 2025-08-19T20:07:15.621Z
Learning: In the Elasticsearch migration, the stringId property was removed from ElasticCase and ElasticTask, with the id property now containing the MongoDB case/task object ID directly. This consolidation eliminates redundancy and simplifies the data model.
Learnt from: renczesstefan
PR: netgrif/application-engine#339
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java:16-16
Timestamp: 2025-08-19T20:13:40.087Z
Learning: In CaseField.java, fulltextValue is mapped as a keyword field type in Elasticsearch (for exact matches, filtering, aggregations), while the separate caseValue field serves different Elasticsearch query requirements, allowing the system to support multiple query patterns on the same data through different field mappings.
Learnt from: renczesstefan
PR: netgrif/application-engine#339
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java:16-16
Timestamp: 2025-08-19T20:07:43.748Z
Learning: In CaseField.java, the separate caseValue field (List<String>) is intentionally maintained alongside fulltextValue for specific Elasticsearch query requirements, rather than being derived on-the-fly from fulltextValue.
📚 Learning: 2025-08-19T20:07:15.621Z
Learnt from: renczesstefan
PR: netgrif/application-engine#339
File: application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy:341-341
Timestamp: 2025-08-19T20:07:15.621Z
Learning: In the Elasticsearch migration, the stringId property was removed from ElasticCase and ElasticTask, with the id property now containing the MongoDB case/task object ID directly. This consolidation eliminates redundancy and simplifies the data model.

Applied to files:

  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseService.java
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/web/requestbodies/CaseSearchRequest.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: Build
🔇 Additional comments (1)
application-engine/src/main/java/com/netgrif/application/engine/elastic/web/requestbodies/CaseSearchRequest.java (1)

47-49: Good addition of id with tolerant JSON deserialization

Accepting single values as arrays on id aligns well with existing request patterns and keeps the API ergonomic.

coderabbitai[bot]
coderabbitai bot previously approved these changes Aug 21, 2025
Replaced the deprecated `stringId` field with the new `id` field throughout the codebase, maintaining backward compatibility by merging both fields during queries. Updated `ImmediateField` and its references to simplify type handling, and moved it to a more appropriate package. These changes improve clarity, support future deprecation, and ensure smooth transitions.
machacjozef
machacjozef previously approved these changes Aug 21, 2025
The `@JsonSerialize` and `@JsonDeserialize` annotations were removed from the `startDate` field. This change promotes default serialization and deserialization behavior, simplifying the code and improving maintainability.
@machacjozef machacjozef merged commit 1c23685 into release/7.0.0-rev6 Aug 21, 2025
6 of 7 checks passed
@machacjozef machacjozef deleted the fix/elastic_search_by_string_id branch August 21, 2025 14:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix A change that fixes a bug improvement A change that improves on an existing feature Large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants