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

feat: support "is" and "contains" condition in issue search #1400

Merged
merged 17 commits into from
Mar 28, 2025

Conversation

jihun
Copy link
Contributor

@jihun jihun commented Mar 19, 2025

  • support IS condition in feedback issue search (exact match in multiselect field)
  • change search payload
    • should describe field key and value explicitly
  • fix potential integration test error

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Introduced a new environment variable for secondary MySQL connection URLs.
    • Enhanced integration tests with tenant management functionality for user-related operations.
    • Added a new MultiSelectSearchInput component for improved multi-selection capabilities.
  • Refactor

    • Streamlined the query structure across various DTOs for improved clarity and consistency.
    • Updated validation process for queries to support more complex structures.
    • Improved query handling in services for better clarity and maintainability.
    • Consolidated handling of the createdAt condition in query processing logic for users and feedback.
    • Updated the structure of query parameters in various UI components to utilize a key-value format for enhanced clarity.
    • Introduced a new SearchQuery type for better type safety in query handling.
    • Expanded matching criteria for issue IDs in feedback management functionality.
    • Added a new condition value BETWEEN to the query conditions enumeration.

@jihun jihun requested a review from chiol March 19, 2025 05:17
Copy link

coderabbitai bot commented Mar 19, 2025

Walkthrough

This pull request refactors the structure of query objects across various DTOs and service files. The dynamic index signatures and shorthand property syntax have been replaced with explicit key and value pairs. Deprecated properties such as createdAt and updatedAt have been removed or restructured, while new properties (e.g., ids) are introduced where needed. Additionally, service methods in the MySQL and OpenSearch layers are updated to process these new query formats, and a new validateQueryV2 method is added in the feedback service to enforce the revised structure.

Changes

File(s) Change Summary
apps/api/integration-test/test-specs/feedback.integration-spec.ts Updated test spec to reflect explicit key/value pairs in the queries array, replacing shorthand notation.
apps/api/src/domains/admin/feedback/dtos/find-feedbacks-by-channel-id-v2.dto.ts
apps/api/src/domains/admin/feedback/dtos/generate-excel.dto.ts
apps/api/src/domains/admin/feedback/dtos/scroll-feedbacks-v2.dto.ts
apps/api/src/domains/admin/feedback/dtos/requests/find-feedbacks-by-channel-id-request-v2.dto.ts
Refactored queries property: removed optional createdAt/updatedAt, replaced dynamic index signatures with explicit key and value fields, and added new properties such as ids where applicable.
apps/api/src/domains/admin/project/issue/dtos/find-issues-by-project-id-v2.dto
apps/api/src/domains/admin/project/issue/dtos/requests/find-issues-by-project-id-request-v2.dto
Modified DTOs to enforce a structured query format by replacing dynamic key definitions with explicit key/value pairs.
apps/api/src/domains/admin/feedback/feedback.mysql.service.ts Altered query processing logic to extract conditions using explicit key lookups (e.g., checking for query.key === 'createdAt') and simplified iteration over queries.
apps/api/src/domains/admin/feedback/feedback.os.service.ts Updated query builder logic and modified the issueIdsToFeedbackIds method (added a condition parameter) to support the new explicit query structure.
apps/api/src/domains/admin/feedback/feedback.service.ts Introduced a new validateQueryV2 method for validating arrays of query objects and replaced previous validations in methods like findByChannelIdV2 and generateFile.
apps/api/integration-test/global.setup.ts Added a new environment variable MYSQL_SECONDARY_URLS for secondary MySQL connection URLs.
apps/api/integration-test/test-specs/user.integration-spec.ts Introduced tenant management functionality by adding tenantRepo and tenantService variables and updating the setup process.

Possibly related PRs

  • support multiselect conditions #1375: The changes in the main PR, which involve restructuring the queries property to use key and value pairs, are directly related to the modifications in the retrieved PR that also introduce the QueryV2ConditionsEnum and enhance the handling of multi-select conditions, as both PRs focus on improving the query structure and processing logic.
  • feat: update column sizes and integrate js-base64 for encoding/decoding in feedback and issue components #1397: The changes in the main PR, which involve restructuring the queries array in various DTOs to use a key and value format, are related to the changes in the retrieved PR that also modify how query parameters are encoded and structured, specifically using the js-base64 library for encoding in the feedback-detail-sheet and issue-detail-sheet components. Both PRs focus on enhancing the clarity and structure of query handling.
  • release: 7.2511.79 #1392: The changes in the main PR regarding the restructuring of the queries array to use explicit key and value properties are related to the modifications in the retrieved PR, which also involves changes to how query parameters are constructed, specifically transitioning from a simpler structure to a more explicit format with key and value.

Suggested reviewers

  • chiol
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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 generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

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

CodeRabbit Configuration File (.coderabbit.yaml)

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

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🔭 Outside diff range comments (1)
apps/api/src/domains/admin/feedback/feedback.service.ts (1)

94-168: 💡 Verification agent

🧩 Analysis chain

Consider deprecating the old validation method.

The old validateQuery method still exists but appears to be replaced by validateQueryV2 in two locations. Consider adding a deprecation notice or removing it if it's no longer used elsewhere in the codebase.

-  private validateQuery(
+  /**
+   * @deprecated Use validateQueryV2 instead
+   */
+  private validateQuery(

🏁 Script executed:

#!/bin/bash
# Check if validateQuery is still used elsewhere in the codebase
echo "Searching for validateQuery usage in the codebase..."
rg -A 1 -B 1 "validateQuery\(" --glob "!feedback.service.ts"

Length of output: 177


Below is a proposed rewritten review comment. However, before finalizing, please run the following additional shell script to double-check that there are no external references to validateQuery outside of feedback.service.ts:

If this complete repository search confirms no other usages, then you can safely add a deprecation notice.


Deprecate the legacy validateQuery method

It appears that validateQuery is no longer used outside of its own file—replaced in two locations by validateQueryV2. Please add a deprecation notice to the method (or remove it entirely if it’s not needed any longer). For example:

-  private validateQuery(
+  /**
+   * @deprecated Use validateQueryV2 instead
+   */
+  private validateQuery(
  • Action required: Manually verify with the provided shell script that there are no external references to validateQuery.

🏁 Script executed:

#!/bin/bash
echo "Searching for validateQuery usage in the entire repository..."
rg -A 1 -B 1 "validateQuery\("

Length of output: 630


Deprecate legacy validateQuery method in feedback.service.ts

It appears that the validateQuery method is used exclusively within this file—its only reference being the call at this.validateQuery(dto.query ?? {}, fields);. Since you've introduced validateQueryV2 in its place in other parts of the codebase, please add a deprecation notice to help steer future usage away from the old method. Also, review the call site to ensure it’s updated to use validateQueryV2 where appropriate.

-  private validateQuery(
+  /**
+   * @deprecated Use validateQueryV2 instead.
+   */
+  private validateQuery(
  • Action required:
    • Add the deprecation annotation to the validateQuery method.
    • Verify and, if applicable, update the call site(s) within feedback.service.ts to use validateQueryV2.
🧹 Nitpick comments (3)
apps/api/src/domains/admin/project/issue/dtos/requests/find-issues-by-project-id-request-v2.dto.ts (1)

39-40: Consider removing redundant properties

While the explicit key/value structure is good, the class still maintains separate createdAt and updatedAt properties (lines 29 and 37) which are now redundant with this new structure. These properties could be removed since they can be represented using the generic key/value pair structure.

apps/api/src/domains/admin/feedback/dtos/requests/find-feedbacks-by-channel-id-request-v2.dto.ts (1)

32-39: Update API property description to reflect the new query structure.

The current API description still references createdAt and updatedAt as examples, but these fields are no longer part of the query structure. Consider updating the description to reflect the new approach with explicit key and value properties.

  @ApiProperty({
    required: false,
    description:
-      "You can query by key-value with this object. (createdAt, updatedAt are kind of examples) If you want to search by text, you can use 'searchText' key.",
+      "You can query using the key and value properties. The key represents the field to query, and value contains the search criteria. For text searches, use 'searchText' as the key.",
    type: [QueryV2],
  })
apps/api/src/domains/admin/feedback/feedback.os.service.ts (1)

507-507: Avoid using the delete operator for performance reasons.

Static analysis suggests assigning undefined or null to the property instead of using the delete operator. For instance:

- delete queries[i].value;
+ queries[i].value = undefined;

This approach tends to be more optimized in JavaScript engines and avoids hidden class deoptimizations.

Also applies to: 596-596

🧰 Tools
🪛 Biome (1.9.4)

[error] 507-507: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7daa88f and 553d335.

📒 Files selected for processing (10)
  • apps/api/integration-test/test-specs/feedback.integration-spec.ts (2 hunks)
  • apps/api/src/domains/admin/feedback/dtos/find-feedbacks-by-channel-id-v2.dto.ts (1 hunks)
  • apps/api/src/domains/admin/feedback/dtos/generate-excel.dto.ts (1 hunks)
  • apps/api/src/domains/admin/feedback/dtos/requests/find-feedbacks-by-channel-id-request-v2.dto.ts (1 hunks)
  • apps/api/src/domains/admin/feedback/dtos/scroll-feedbacks-v2.dto.ts (1 hunks)
  • apps/api/src/domains/admin/feedback/feedback.mysql.service.ts (2 hunks)
  • apps/api/src/domains/admin/feedback/feedback.os.service.ts (6 hunks)
  • apps/api/src/domains/admin/feedback/feedback.service.ts (3 hunks)
  • apps/api/src/domains/admin/project/issue/dtos/find-issues-by-project-id-v2.dto.ts (1 hunks)
  • apps/api/src/domains/admin/project/issue/dtos/requests/find-issues-by-project-id-request-v2.dto.ts (1 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
apps/api/src/domains/admin/feedback/feedback.service.ts (1)
apps/api/src/domains/admin/feedback/dtos/find-feedbacks-by-channel-id-v2.dto.ts (1) (1)
  • FindFeedbacksByChannelIdDtoV2 (21-32)
🪛 Biome (1.9.4)
apps/api/src/domains/admin/feedback/feedback.os.service.ts

[error] 507-507: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)


[error] 596-596: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: integration-test
🔇 Additional comments (15)
apps/api/src/domains/admin/project/issue/dtos/find-issues-by-project-id-v2.dto.ts (1)

29-30: Structure alignment for query conditions

The explicit key and value properties create a clearer structure for query conditions, which aligns well with the PR objective of supporting the IS condition for exact match multiselect options. This approach makes the query structure more explicit and easier to validate.

apps/api/src/domains/admin/feedback/dtos/generate-excel.dto.ts (1)

24-25: Standardized query structure improves code consistency

The change to use explicit key and value properties instead of an index signature provides better type safety and makes the structure more consistent with other DTOs in the system. This is a good improvement.

apps/api/integration-test/test-specs/feedback.integration-spec.ts (2)

209-211: Test correctly implements the new query structure

The test has been properly updated to use the new explicit key/value structure along with the IS condition as specified in the PR objectives. This helps validate that the new condition works as expected for exact matching.


386-392:

❓ Verification inconclusive

Verify date range handling with IS condition

The test is using the IS condition with a date range, which is interesting since IS typically implies exact matching. Make sure this is the intended behavior for date ranges and that the backend properly handles this combination.


🏁 Script executed:

#!/bin/bash
# Check how IS condition is used with date ranges in the codebase
rg -A 3 "IS.*date|TimeRange.*IS" --type ts

Length of output: 680


Revisit Date Range Matching Logic

The test at apps/api/integration-test/test-specs/feedback.integration-spec.ts (lines 386–392) uses the QueryV2ConditionsEnum.IS condition with a date range for the createdAt field. Since the IS condition usually implies an exact match, please confirm that the backend is intended to interpret this combination (with gte and lt boundaries) correctly. There wasn’t additional evidence in the codebase (e.g., from migration or other query handling logic) that clarifies an alternate interpretation for date ranges with IS.

  • Action: Verify that the query logic in the API handles the IS condition for date ranges as intended. If this behavior is deliberate, consider adding documentation or inline comments to clarify the design choice.
apps/api/src/domains/admin/feedback/dtos/find-feedbacks-by-channel-id-v2.dto.ts (1)

24-26: Improved type safety with explicit key-value structure.

The change from dynamic index signatures to explicit key and value properties enhances type safety and code clarity. This restructuring aligns with the PR objective of supporting the IS condition for exact match multiselect options in the feedback issue search functionality.

apps/api/src/domains/admin/feedback/feedback.service.ts (3)

170-241: Well-implemented validation method for the new query structure.

The validateQueryV2 method is appropriately designed to validate the new query structure with explicit key and value properties. The method follows the same pattern as the existing validateQuery method, making it easy to understand while supporting the new format needed for the IS condition.


622-622: Correct implementation of the new validation method.

The validation call has been properly updated to use the new validateQueryV2 method, ensuring consistency with the updated DTO structure.


789-789: Consistent implementation of the new validation method.

The validation call in the generateFile method has been correctly updated to use the new validateQueryV2 method, maintaining consistency across the service.

apps/api/src/domains/admin/feedback/dtos/scroll-feedbacks-v2.dto.ts (1)

23-26: Consistent implementation of the explicit key-value structure.

The changes to the queries property maintain consistency with other DTOs in the codebase, enhancing type safety and maintainability. The structure now clearly defines what constitutes a valid query object.

apps/api/src/domains/admin/feedback/dtos/requests/find-feedbacks-by-channel-id-request-v2.dto.ts (1)

23-26: Enhanced query structure with added IDs support.

The transition to explicit key and value properties improves type safety, and the addition of the ids property provides a way to query by ID directly, which enhances the API's functionality.

apps/api/src/domains/admin/feedback/feedback.mysql.service.ts (2)

312-316: Confirm the date boundary logic for createdAt.

You're currently applying >= :gte and < :lt. If you intended to include records exactly at the boundary time, consider whether < :lt should be <= :lt instead. Otherwise, carefully verify that the current exclusivity aligns with your product requirements.


345-355: Verify performance implications of JSON aggregation in the HAVING clause.

Using JSON_ARRAYAGG within HAVING can be costly on large datasets. Consider indexing or alternative approaches (e.g., precomputed columns or join relationships) if performance becomes an issue.

apps/api/src/domains/admin/feedback/feedback.os.service.ts (3)

39-39: No issues found with the import change.


60-63: Good addition of condition parameter.

Allowing a default QueryV2ConditionsEnum.CONTAINS provides flexibility for different matching behaviors.


499-505: Logic for merging issueIds into ids looks appropriate.

Ensuring that we remove the original issueIds property and unify it into queries[i].ids is a clean approach. No concerns noted with the new condition handling.

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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 553d335 and 2b8d198.

📒 Files selected for processing (3)
  • apps/api/integration-test/global.setup.ts (1 hunks)
  • apps/api/integration-test/test-specs/user.integration-spec.ts (3 hunks)
  • apps/api/src/domains/admin/feedback/feedback.os.service.ts (6 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
apps/api/src/domains/admin/feedback/feedback.os.service.ts

[error] 506-506: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)


[error] 595-595: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: integration-test
🔇 Additional comments (5)
apps/api/src/domains/admin/feedback/feedback.os.service.ts (3)

39-39: No issues with the new import.


276-279: Date range logic looks good.
No concerns with this condition block; it appears consistent with the new query structure.


318-372: Multi-select IS condition logic is consistent.
The advanced approach for exact matching, including the script check for matching array lengths, looks correct and aligns with your requirements.

apps/api/integration-test/global.setup.ts (1)

25-27: Environment variable setup looks correct for integration tests.
Defining secondary URLs for MySQL in a test environment is reasonable. No concerns here.

apps/api/integration-test/test-specs/user.integration-spec.ts (1)

30-39: Tenant setup logic is properly integrated.
Adding the tenant repository and service, clearing repositories, and creating a tenant in the test setup all appear coherent and maintainable.

Also applies to: 50-76

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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2b8d198 and 70bab73.

📒 Files selected for processing (1)
  • apps/api/src/domains/admin/feedback/feedback.os.service.ts (6 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: integration-test
🔇 Additional comments (5)
apps/api/src/domains/admin/feedback/feedback.os.service.ts (5)

60-76: Multiple database queries can be combined for better performance.

You're executing two consecutive database queries for the same feedback IDs, which is unnecessary and impacts performance. Consider consolidating these into a single query.


78-90: Well-implemented IS condition filtering.

The condition-based filtering works correctly by checking both the length equality and ensuring every issue ID exists in the feedback. This implements the exact match functionality as required for the IS condition.


319-356: Good implementation of exact match filtering for multiSelect fields.

Your implementation properly handles the IS condition for multiSelect fields using both terms_set with minimum_should_match_script and an additional script check to ensure exact length matching. The empty array case is also handled correctly.


276-279: Improved query structure with explicit key-value pairs.

The updated approach of checking for conditions using query.key === 'createdAt' instead of direct property access aligns well with the refactored query structure. This change supports the PR objective of making field keys and values more explicit.


39-39: Updated import statement.

Changed from type import to regular import, indicating that Feedback is now used as a value rather than just a type.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🔭 Outside diff range comments (1)
apps/api/src/domains/admin/user/dtos/requests/get-all-users-request.dto.ts (1)

19-24: ⚠️ Potential issue

Remove unused import

The pipeline flagged an unused import.

import {
  IsEnum,
- IsNumber,
  IsOptional,
  IsString,
  ValidateNested,
} from 'class-validator';
🧰 Tools
🪛 GitHub Check: lint

[failure] 20-20:
'IsNumber' is defined but never used. Allowed unused vars must match /^_/u

🪛 GitHub Actions: CI

[error] 20-20: 'IsNumber' is defined but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars

🧹 Nitpick comments (1)
apps/api/src/domains/admin/project/issue/dtos/requests/find-issues-by-project-id-request-v2.dto.ts (1)

54-62: Update example to match the new QueryV2 structure.

The example in the @ApiProperty decorator for the queries property doesn't reflect the new structure with explicit key, value, and condition properties.

  @ApiProperty({
    required: false,
    description: 'You can query by key-value with this object.',
-   example: { name: 'issue name' },
+   example: [{ key: 'name', value: 'issue name', condition: 'EQ' }],
    type: [QueryV2],
  })
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 57afa6d and 2670f46.

📒 Files selected for processing (8)
  • apps/api/src/domains/admin/feedback/dtos/requests/find-feedbacks-by-channel-id-request-v2.dto.ts (1 hunks)
  • apps/api/src/domains/admin/project/issue/dtos/requests/find-issues-by-project-id-request-v2.dto.ts (2 hunks)
  • apps/api/src/domains/admin/project/member/dtos/find-all-members.dto.ts (1 hunks)
  • apps/api/src/domains/admin/project/member/dtos/requests/get-all-member-request.dto.ts (1 hunks)
  • apps/api/src/domains/admin/project/member/member.service.ts (1 hunks)
  • apps/api/src/domains/admin/user/dtos/find-all-users.dto.ts (1 hunks)
  • apps/api/src/domains/admin/user/dtos/requests/get-all-users-request.dto.ts (2 hunks)
  • apps/api/src/domains/admin/user/user.service.ts (2 hunks)
🧰 Additional context used
🪛 GitHub Actions: CI
apps/api/src/domains/admin/user/dtos/requests/get-all-users-request.dto.ts

[error] 20-20: 'IsNumber' is defined but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: integration-test
🔇 Additional comments (20)
apps/api/src/domains/admin/project/issue/dtos/requests/find-issues-by-project-id-request-v2.dto.ts (4)

17-17: LGTM: Necessary import addition.

The import statement is correctly updated to include IsEnum and IsString from class-validator, which are needed for the new validation decorators used in the QueryV2 class.


20-20: LGTM: Added required enum import.

The import for QueryV2ConditionsEnum is necessary for validating the condition property and documenting it in the API schema.


39-44: Good restructuring of the QueryV2 class.

The change from using an index signature to explicit key and value properties improves type safety and makes the API contract more clear. The validation decorator @IsString() for the key property ensures proper data validation.


46-51: Good addition of API documentation and validation for condition.

Adding the @ApiProperty decorator with enum information and the @IsEnum validation improves both API documentation and ensures that only valid enum values are accepted.

apps/api/src/domains/admin/feedback/dtos/requests/find-feedbacks-by-channel-id-request-v2.dto.ts (4)

17-21: Good enhancement of import statements to support the new query structure.

The additional imports properly support the new QueryV2 structure with enum types and validation decorators. The IsNullable decorator is appropriately imported from the user domain to handle nullable values.


24-27: Well-defined ids array property.

Adding the ids array property with proper validation via @IsArray() provides a clear way to filter by specific feedback IDs, enhancing the search capabilities.


29-35: Good implementation of explicit key-value structure.

The replacement of dynamic index signatures with explicit key and value properties improves type safety and makes the API contract more clear. The value type supports multiple data types to accommodate different search scenarios.


37-42: Excellent addition of the condition property with IS support.

The introduction of the condition property using QueryV2ConditionsEnum properly implements the requirement to support the IS condition for exact matching, as specified in the PR objectives.

apps/api/src/domains/admin/project/member/dtos/find-all-members.dto.ts (1)

24-27: Well-structured query interface with explicit key-value pairs.

The refactored query structure with explicit key and value properties aligns with the project-wide standardization of query objects. This approach provides better type safety and makes the API contract more clear.

apps/api/src/domains/admin/user/dtos/find-all-users.dto.ts (1)

24-26: Improved query structure with comprehensive value type support.

The refactored query structure now properly supports multiple value types, including string arrays and number arrays. This enhancement allows for more flexible and powerful queries when searching for users.

apps/api/src/domains/admin/project/member/member.service.ts (3)

115-119: Good refactoring to support the new key-value query structure.

The refactored code properly destructures the new query structure, extracting key, value, and condition properties for use in the query builder.


119-159: Well-implemented IS condition support for multiple fields.

The code now properly handles both the IS condition (exact match) and the default LIKE condition (partial match) for the member fields including role, name, email, and department. The ternary operators effectively handle the different query conditions.


159-171: Good improvement in date range handling within the main query loop.

The date range handling for createdAt has been nicely integrated into the main query loop, making the code more maintainable and consistent. The check for the value being an object and the extraction of gte and lt properties are handled properly.

apps/api/src/domains/admin/project/member/dtos/requests/get-all-member-request.dto.ts (2)

17-18: Import refactoring looks good

The updated imports properly support the new DTO structure with the addition of IsNullable from the user decorators and explicit validation imports.

Also applies to: 21-21


24-37: New query structure enhances API flexibility

The refactoring from specific field properties to a generic key-value structure with explicit condition support aligns with the PR objectives to support the IS condition for exact matching. The implementation properly enforces type validation using appropriate decorators.

apps/api/src/domains/admin/user/user.service.ts (3)

23-23: New import for TimeRange looks good

The TimeRange import is correctly added to support the refactored query structure.


63-89: Query processing logic improved

The refactored query processing logic properly handles the new key-value structure and adds support for the IS condition. The implementation correctly:

  • Extracts key, value, and condition from each query
  • Processes different field types appropriately
  • Uses exact matching (=) for IS condition and partial matching (LIKE) for other conditions
  • Handles TimeRange objects for date filtering

This implementation fully supports the PR objectives for enhancing search with the IS condition.


93-93: Empty line formatting looks good

The added empty line improves code readability by separating the query building logic from the ordering logic.

apps/api/src/domains/admin/user/dtos/requests/get-all-users-request.dto.ts (2)

28-28: Import path change looks good

The relative import path for IsNullable is correctly updated.


39-52: Enhanced query structure with proper validation

The refactored UserSearchQuery class now properly supports the new key-value structure with appropriate validation:

  • Required key property with string validation
  • Required value property that supports multiple data types (string, arrays, TimeRange, null)
  • Updated condition property to use the QueryV2ConditionsEnum

This implementation aligns with the PR objectives and enhances type safety.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (6)
apps/api/src/common/enums/query-v2-conditions.enum.ts (1)

16-20: Consider adding JSDoc comments to improve enum documentation.

While the enum values are self-explanatory, adding JSDoc comments explaining the purpose of each condition would improve code maintainability and assist developers who are new to the codebase.

 export enum QueryV2ConditionsEnum {
+  /**
+   * Checks if a field contains the specified value
+   */
   CONTAINS = 'CONTAINS',
+  /**
+   * Checks for exact match with the specified value(s)
+   */
   IS = 'IS',
+  /**
+   * Checks if a value falls within a specified range
+   */
   BETWEEN = 'BETWEEN',
 }
apps/web/src/widgets/issue-table/lib/use-issue-query-converter.ts (3)

34-41: Consider adding error handling for the async request.
The toQuery function’s issue property awaits a network call without retry or error handling. If the request fails, this code might throw unhandled exceptions.

issue: async (value) => {
  try {
    const { data } = await client.post({
      path: '/api/admin/projects/{projectId}/issues/search',
      pathParams: { projectId },
      body: {
-       queries: [{ key: 'name', value, condition: 'IS' }] as SearchQuery[],
+       queries: [
+         { key: 'name', value, condition: 'IS' }
+       ] as SearchQuery[],
      },
    });
    const result = data?.items.find((v) => v.name === value);
    return result ? [result.id] : [];
  } catch (err) {
    // Handle error or return a default value
    return [];
  }
},

61-65: Wrap decode and JSON.parse in a try-catch.
A malformed query string or base64 data could cause runtime errors. Handling parse failures more gracefully would improve robustness.

parse: (value) => {
  try {
-   return JSON.parse(decode(value)) as SearchQuery[];
+   const decoded = decode(value);
+   return JSON.parse(decoded) as SearchQuery[];
  } catch (error) {
    console.error('Failed to parse query:', error);
    return [];
  }
},

139-141: Consider error handling around dynamic filter conversions.
When calling toQuery(projectId)[format](value), an unexpected format or a failure in the async logic (like for issue) could raise exceptions.

tableFilters.map(async ({ condition, format, key, value }) => {
  try {
    return {
      key,
      value: await toQuery(projectId)[format](value),
      condition,
    };
  } catch (error) {
    // Handle gracefully
    return { key, value: null, condition };
  }
});
apps/web/src/entities/feedback/lib/use-feedback-query-converter.ts (2)

70-74: Wrap decoding logic in a try/catch for robustness.
Similar to the other file, unhandled decoding or parsing errors could break the UI.

parse: (value) => {
  try {
-   return JSON.parse(decode(value)) as SearchQuery[];
+   const decoded = decode(value);
+   return JSON.parse(decoded) as SearchQuery[];
  } catch (error) {
    console.error('Failed to parse query:', error);
    return [];
  }
},

140-141: Validate async conversions for the feedback converter.
Similar to the issue converter, consider try/catch in toQuery(projectId)[format](value) calls.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5df5d9c and 5b8fdee.

📒 Files selected for processing (28)
  • apps/api/src/common/enums/query-v2-conditions.enum.ts (1 hunks)
  • apps/web/src/entities/dashboard/ui/issue-bar-chart.ui.tsx (1 hunks)
  • apps/web/src/entities/dashboard/ui/issue-feedback-line-chart.ui.tsx (1 hunks)
  • apps/web/src/entities/dashboard/ui/issue-rank.ui.tsx (2 hunks)
  • apps/web/src/entities/feedback/lib/use-feedback-query-converter.ts (7 hunks)
  • apps/web/src/entities/feedback/lib/use-feedback-search.ts (2 hunks)
  • apps/web/src/entities/feedback/ui/feedback-detail-sheet.ui.tsx (1 hunks)
  • apps/web/src/entities/feedback/ui/feedback-table-download.ui.tsx (1 hunks)
  • apps/web/src/entities/feedback/ui/issue-cell.tsx (2 hunks)
  • apps/web/src/entities/issue/lib/use-issue-search-infinite.ts (2 hunks)
  • apps/web/src/entities/issue/lib/use-issue-search.ts (2 hunks)
  • apps/web/src/entities/issue/ui/issue-select-box.ui.tsx (1 hunks)
  • apps/web/src/entities/member/ui/member-form-dialog.ui.tsx (1 hunks)
  • apps/web/src/entities/member/ui/member-name-cell.ui.tsx (1 hunks)
  • apps/web/src/entities/user/ui/user-management-table.ui.tsx (2 hunks)
  • apps/web/src/features/create-project/ui/input-members-step.ui.tsx (1 hunks)
  • apps/web/src/shared/types/api.type.ts (3 hunks)
  • apps/web/src/shared/types/index.ts (1 hunks)
  • apps/web/src/shared/types/search-query.type.ts (1 hunks)
  • apps/web/src/shared/ui/category-table-row.ui.tsx (3 hunks)
  • apps/web/src/shared/ui/category-table.ui.tsx (1 hunks)
  • apps/web/src/shared/ui/table-filter-popover/table-filter-popover.type.ts (1 hunks)
  • apps/web/src/shared/ui/table-filter-popover/table-filter-popover.ui.tsx (2 hunks)
  • apps/web/src/widgets/issue-table/lib/use-issue-query-converter.ts (8 hunks)
  • apps/web/src/widgets/issue-table/ui/issue-detail-sheet.ui.tsx (4 hunks)
  • apps/web/src/widgets/issue-table/ui/issue-kanban-column.ui.tsx (3 hunks)
  • apps/web/src/widgets/issue-table/ui/issue-kanban.ui.tsx (2 hunks)
  • apps/web/src/widgets/project-settings/ui/member-setting.ui.tsx (2 hunks)
🧰 Additional context used
🧬 Code Definitions (13)
apps/web/src/entities/user/ui/user-management-table.ui.tsx (1)
apps/web/src/shared/types/search-query.type.ts (1)
  • SearchQuery (16-20)
apps/web/src/widgets/issue-table/ui/issue-detail-sheet.ui.tsx (1)
apps/web/src/shared/types/search-query.type.ts (1)
  • SearchQuery (16-20)
apps/web/src/widgets/issue-table/ui/issue-kanban-column.ui.tsx (1)
apps/web/src/shared/types/search-query.type.ts (1)
  • SearchQuery (16-20)
apps/web/src/shared/ui/category-table-row.ui.tsx (1)
apps/web/src/shared/types/search-query.type.ts (1)
  • SearchQuery (16-20)
apps/web/src/entities/feedback/lib/use-feedback-search.ts (1)
apps/web/src/shared/types/search-query.type.ts (1)
  • SearchQuery (16-20)
apps/web/src/entities/issue/lib/use-issue-search.ts (1)
apps/web/src/shared/types/search-query.type.ts (1)
  • SearchQuery (16-20)
apps/web/src/widgets/project-settings/ui/member-setting.ui.tsx (1)
apps/web/src/shared/types/search-query.type.ts (1)
  • SearchQuery (16-20)
apps/web/src/entities/issue/lib/use-issue-search-infinite.ts (1)
apps/web/src/shared/types/search-query.type.ts (1)
  • SearchQuery (16-20)
apps/web/src/entities/feedback/ui/feedback-table-download.ui.tsx (1)
apps/web/src/shared/types/search-query.type.ts (1)
  • SearchQuery (16-20)
apps/web/src/widgets/issue-table/lib/use-issue-query-converter.ts (2)
apps/web/src/shared/ui/table-filter-popover/table-filter-popover.type.ts (1)
  • TableFilterFieldFotmat (16-16)
apps/web/src/shared/types/search-query.type.ts (1)
  • SearchQuery (16-20)
apps/web/src/shared/ui/category-table.ui.tsx (1)
apps/web/src/shared/types/search-query.type.ts (1)
  • SearchQuery (16-20)
apps/web/src/widgets/issue-table/ui/issue-kanban.ui.tsx (1)
apps/web/src/shared/types/search-query.type.ts (1)
  • SearchQuery (16-20)
apps/web/src/entities/feedback/lib/use-feedback-query-converter.ts (1)
apps/web/src/shared/types/search-query.type.ts (1)
  • SearchQuery (16-20)
🔇 Additional comments (63)
apps/api/src/common/enums/query-v2-conditions.enum.ts (1)

19-19: Added BETWEEN condition to support range queries.

The addition of the BETWEEN condition in the QueryV2ConditionsEnum will help support range-based searches, enhancing the query capabilities. This aligns with the PR's objective to improve the feedback issue search functionality.

apps/web/src/shared/types/search-query.type.ts (1)

16-20: Well-structured type definition for SearchQuery

The new SearchQuery type is clearly defined with appropriate property types:

  • key: string for field identifiers
  • value: unknown provides flexibility while maintaining type-safety (better than any)
  • condition as a union type with 'IS', 'CONTAINS', and 'BETWEEN' options

This structure aligns well with the PR objective to support the IS condition for exact match multiselect options.

apps/web/src/shared/types/index.ts (1)

24-24: Export addition maintains consistent pattern

Properly exporting the new SearchQuery type from the index file makes it easily accessible throughout the application, following the established pattern of the codebase.

apps/web/src/entities/feedback/ui/feedback-detail-sheet.ui.tsx (1)

150-152: URL query structure updated to match new SearchQuery type

The URL construction now correctly uses the key, value, and condition structure for the query parameters instead of the previous dynamic property approach. This ensures consistency with the new query format throughout the application.

apps/web/src/entities/issue/ui/issue-select-box.ui.tsx (1)

39-39: Query structure updated to match new SearchQuery type

The search query now correctly uses the key, value, and condition structure for consistent query formatting throughout the application. This aligns with the new query format and enhances code clarity by explicitly defining what field is being searched.

apps/web/src/shared/ui/table-filter-popover/table-filter-popover.type.ts (1)

70-71: Required property enhances type safety

The change from value?: unknown to value: unknown makes the value property required in the TableFilter interface, which aligns with the PR objective of enforcing explicit field key and value in search parameters. This ensures more consistent data structure across filter operations.

apps/web/src/features/create-project/ui/input-members-step.ui.tsx (1)

51-54: Search query structure updated to support IS condition

The query structure has been updated to use explicit key, value, and condition properties. This enhances the search functionality by clearly specifying that you want an exact match with the IS condition for the GENERAL type.

apps/web/src/entities/member/ui/member-name-cell.ui.tsx (1)

29-31: Query format updated to use explicit key-value structure

The query structure has been updated to use explicit key, value, and condition properties. This makes the search criteria more clear and consistent with the new search payload format used throughout the application.

apps/web/src/entities/dashboard/ui/issue-feedback-line-chart.ui.tsx (1)

103-108: Issue search query updated to use structured format with CONTAINS condition

The query structure has been updated to use explicit key, value, and condition properties with a CONTAINS condition for the name field. This provides more flexibility in how searches are performed and maintains consistency with the new search payload format.

apps/web/src/entities/dashboard/ui/issue-bar-chart.ui.tsx (1)

56-60: Improved query structure format

The query structure has been updated to use explicit key, value, and condition properties instead of the previous shorthand format. This change aligns with the PR objective to improve search functionality with explicit query structures.

apps/web/src/shared/ui/table-filter-popover/table-filter-popover.ui.tsx (2)

84-84: Initialized value property in filter object

Added the value: undefined property to ensure consistent filter object structure. This aligns with the standardized query format using key-value pairs.


99-101: Consistent filter object structure in resetFilters

Added the value: undefined property to maintain consistency with the updated filter object format throughout the codebase.

apps/web/src/widgets/issue-table/ui/issue-detail-sheet.ui.tsx (4)

38-38: Added SearchQuery type import

Imported the SearchQuery type to ensure type safety for the query structure changes.


112-117: Updated search query structure with type safety

Modified the query structure to use explicit key, value, and condition properties along with type assertion to SearchQuery[]. This improves code clarity and ensures type safety.


227-233: Standardized query format in URL parameters

Updated the URL query parameter structure to use the standardized format with explicit key, value, and condition properties. This ensures consistency in how queries are formatted across the application.


191-191: Updated URL query encoding format

Modified the clipboard copy URL to use the new query format with explicit key, value, and condition properties.

apps/web/src/entities/member/ui/member-form-dialog.ui.tsx (1)

64-66: Standardized user search query format

Updated the query structure in the useUserSearch hook to use explicit key and value properties, aligning with the standardized query format across the application.

apps/web/src/entities/feedback/ui/feedback-table-download.ui.tsx (2)

32-32: Improved type import for better query structure.

This change properly imports the SearchQuery type, which defines the structure for query objects with key, value, and condition properties.


40-40: Enhanced type safety with explicit query structure.

The type for the queries property has been updated from a generic Record<string, unknown>[] to the more specific SearchQuery[]. This aligns with the PR objective of introducing support for the IS condition and ensuring the query structure is clear and type-safe.

apps/web/src/widgets/issue-table/ui/issue-kanban.ui.tsx (2)

28-28: Improved type import for better query structure.

Importing the SearchQuery type provides a well-defined structure for search queries, improving type safety.


39-39: Enhanced type safety with explicit query structure.

Updating the type from a generic Record<string, unknown>[] to the specific SearchQuery[] ensures that all query objects follow the expected structure with key, value, and condition properties. This supports the PR's objective of adding the IS condition for exact match multiselect options.

apps/web/src/shared/ui/category-table-row.ui.tsx (3)

34-34: Added import for SearchQuery type.

This import supports the improved query structure implementation.


49-49: Enhanced type safety with explicit query structure.

The type for the queries property has been updated from a generic Record<string, unknown>[] to the more specific SearchQuery[], ensuring consistency in query object structure.


86-88: Implemented IS condition for exact category matching.

This is a practical example of using the new SearchQuery structure with the IS condition for exact matching. The code correctly adds a category filter to the existing queries using the explicit key-value-condition format.

apps/web/src/entities/feedback/lib/use-feedback-search.ts (2)

23-23: Added SearchQuery type import.

This import supports the improved query structure implementation.


40-40: Enhanced type safety with explicit query structure.

Updating the queries property type in the IBody interface ensures that all search queries conform to the expected structure with key, value, and condition properties. This change maintains consistency with the API expectations and aligns with the PR objective of supporting the IS condition.

apps/web/src/entities/user/ui/user-management-table.ui.tsx (2)

29-29: Updated import to include SearchQuery type

The import statement now includes the SearchQuery type, which is used to provide better type safety for the query structure.


61-71: Improved type safety with explicit key-value structure

The code now uses the SearchQuery type with explicit key, value, and condition properties, replacing the previous dynamic key approach. This provides better type safety and aligns with the IS condition support for exact match multiselect options.

apps/web/src/shared/ui/category-table.ui.tsx (2)

23-23: Added SearchQuery type import

Added import for the SearchQuery type from the types module, which is used to provide better type safety for the query structure.


30-30: Enhanced type safety with SearchQuery type

Updated the queries prop type from the generic Record<string, unknown>[] to the more specific SearchQuery[] type, improving type safety and making the expected data structure more explicit.

apps/web/src/widgets/issue-table/ui/issue-kanban-column.ui.tsx (3)

27-27: Updated import to include SearchQuery type

The import statement now includes the SearchQuery type, which is used to provide better type safety for the query structure.


50-50: Enhanced type safety with SearchQuery type

Updated the queries prop type from the generic Record<string, unknown>[] to the more specific SearchQuery[] type, improving type safety and making the expected data structure more explicit.


74-76: Updated query concatenation to use structured format

Modified the query concatenation to use the new SearchQuery format with explicit key, value, and condition properties. This change supports the IS condition and provides a more consistent query structure throughout the application.

apps/web/src/entities/issue/lib/use-issue-search.ts (2)

19-23: Updated imports to include SearchQuery type

Added the SearchQuery type to the imports, which is used to provide better type safety for the query structure in the IBody interface.


36-36: Enhanced type safety with SearchQuery type

Updated the queries property in the IBody interface from the generic Record<string, unknown>[] to the more specific SearchQuery[] type. This improves type safety and aligns with the application-wide shift to a more structured query format that supports the new IS condition.

apps/web/src/entities/feedback/ui/issue-cell.tsx (2)

71-74: Well-structured query format for feedback search.

The change to use explicit key, value, and condition properties in the query object improves code clarity and consistency with the new search API format. The IS condition correctly enables exact matching for feedback ID.


98-98: Consistent query format for issue search.

This modification follows the same pattern of explicit key, value, and condition properties, providing a consistent interface across all search queries in the application.

apps/web/src/entities/issue/lib/use-issue-search-infinite.ts (2)

18-22: Good addition of SearchQuery type import.

Adding the SearchQuery type to the imports helps enforce type safety for the query structure used in this component.


35-35: Enhanced type safety with SearchQuery array.

Changing from a generic Record<string, unknown>[] to the more specific SearchQuery[] improves type safety and ensures consistent query structure throughout the application. This change aligns with the PR objective of making field keys and values more explicit.

apps/web/src/widgets/project-settings/ui/member-setting.ui.tsx (2)

31-31: Appropriate SearchQuery type import.

The addition of the SearchQuery type import prepares for its usage in the queries implementation.


72-78: Well-structured query object transformation.

The modified implementation now explicitly constructs objects with key, value, and condition properties instead of using dynamic property names. This enhances code readability and ensures consistent query structure throughout the application.

apps/web/src/entities/dashboard/ui/issue-rank.ui.tsx (2)

73-73: Consistent query format in issue link.

The query structure has been updated to use explicit key, value, and condition properties, which provides consistency with the rest of the application and supports the new search functionality.


134-136: Standardized query structure in issue status filter.

The query format has been properly updated to use the explicit key, value, and condition properties. This change contributes to a consistent query structure across the application and supports the IS condition for exact matching.

apps/web/src/widgets/issue-table/lib/use-issue-query-converter.ts (6)

24-24: Good introduction of the SearchQuery type.
Using a single, well-defined interface for query objects promotes type-safety and consistency across the codebase.


92-94: Appropriate date range clearing.
Removing the createdAt query if the user clears the date range is straightforward and correct.


99-102: Check appropriateness of 'IS' for the new date query.
As above, confirm whether 'BETWEEN' is preferable if you intend to capture a baseline date range.


116-120: Effective filtration of createdAt from table filters.
Excluding date-based filters in the table UI is consistent with your date handling logic. This approach prevents duplication or conflicting filters.


149-152: Repeated 'IS' usage for date range.
Same verification needed for the date filter’s condition when reapplying createdAt.


74-76:

❓ Verification inconclusive

Refactor usage of 'IS' for date ranges if needed.
Here, you store { gte, lt } under the 'createdAt' key while using condition: 'IS'. Confirm whether 'BETWEEN' better represents the intended range semantics.


🌐 Web query:

When using a date range for queries with fields like "createdAt", is it more appropriate to use a "BETWEEN" condition instead of "IS" in your system?

💡 Result:

When working with date ranges in SQL queries, the choice between using BETWEEN and comparison operators (>= and <) depends on how date-time values are stored and the specific requirements of your query. Here's a breakdown:

Key Considerations for Date Range Queries

  1. Inclusivity of BETWEEN:

    • The BETWEEN operator is inclusive, meaning it includes both the start and end values in the range. For example:
      WHERE createdAt BETWEEN '2025-03-01' AND '2025-03-25'
      This will include all rows where createdAt is between March 1, 00:00:00 and March 25, 00:00:00. If your createdAt field includes time components (e.g., 2025-03-25 14:30:00), this query excludes any times after midnight on March 25[1][2][5].
  2. Time Component Handling:

    • If your date field includes time data (e.g., DATETIME type), BETWEEN can unintentionally exclude records. For example, entries on March 25 after 00:00:00 will not be included in the above query. Instead, use:
      WHERE createdAt >= '2025-03-01' AND createdAt < '2025-03-26'
      This captures all times up to (but not including) March 26, ensuring full coverage of March 25[2][5].
  3. Database and Regional Settings:

    • Date formats (e.g., MM/DD/YYYY vs. YYYY-MM-DD) can affect query accuracy. For consistency, use unambiguous formats like YYYY-MM-DD and platform-specific delimiters (e.g., # in Access)[5].
    • In Microsoft Access, explicit timestamp handling is critical. For example:
      WHERE createdAt BETWEEN #2025-03-01# AND #2025-03-25 23:59:59#
      ensures the entire day of March 25 is included[4][5].

When to Use BETWEEN vs. Comparison Operators

Scenario Recommended Approach
Dates without time components Use BETWEEN for simplicity[1][3].
Dates with time components Use >= and < to avoid cutoff[2][5].
Dynamic ranges (e.g., "last week") Combine >= and < with date functions (e.g., DateAdd() in Access)[4].
Cross-database consistency Prefer >= and < to avoid dialect-specific edge cases[2][6].

Example Queries

-- Includes March 25 up to 00:00:00 (excludes times):
SELECT * FROM orders
WHERE order_date BETWEEN '2025-03-01' AND '2025-03-25';

-- Includes all times on March 25:
SELECT * FROM orders
WHERE order_date >= '2025-03-01' AND order_date < '2025-03-26';

-- Access-specific example with explicit time:
SELECT * FROM orders
WHERE order_date BETWEEN #2025-03-01# AND #2025-03-25 23:59:59#;

Summary

  • Use BETWEEN only if your dates lack time components or if you explicitly set the end value to include the maximum time (e.g., 23:59:59).
  • Prefer >= and < for datetime fields to avoid cutoff errors and ensure compatibility across SQL dialects. This approach is more robust when dealing with time-sensitive data[2][5][6].

Always validate the date format and time-storage logic of your database system to choose the optimal method.

Citations:


Action: Verify and adjust the date range condition for 'createdAt'.
It appears that you’re currently storing a range (i.e., { gte, lt }) under the 'createdAt' key while applying the condition: 'IS', which is typically used for single-value equality. Based on common SQL practices:

  • If the createdAt field contains only date values, a BETWEEN condition can clearly express an inclusive date range.
  • If createdAt includes time components, using separated operators (i.e., >= and <) is safer to avoid cutoff errors.

Please review the underlying database schema and the intended query semantics, then adjust the condition accordingly.

apps/web/src/entities/feedback/lib/use-feedback-query-converter.ts (10)

24-24: Good introduction of SearchQuery here as well.
Ensures consistency with the new structured query type used across the codebase.


43-43: Validate 'IS' usage for the 'name' condition.
While 'IS' might be correct for exact name matches, confirm consistency when other fields might require 'CONTAINS' or 'BETWEEN'.


80-80: Thoughtful defaulting with createdAt.
Providing a default date range query can improve user experience if searching by date is a common scenario.


85-87: Consistent approach to extracting date range queries.
Using .find((v) => v.key === 'createdAt') aligns with the new SearchQuery struct’s key property.


100-100: Correctly removing createdAt from queries.
The filter approach matches the code in the other converter file. This maintains parity and clarity.


105-106: Re-adding the date query: verify 'IS' usage for range.
As previously stated, ensure that 'IS' accurately reflects your date range semantics.


118-120: Offsetting date-based queries from other table filters.
Skipping createdAt ensures it does not conflict with the standard filter logic.


146-148: Graceful fallback to default date query.
When all queries are removed, automatically re-adding 'createdAt' ensures coverage. Nicely done.


156-159: Same 'IS' vs 'BETWEEN' question for date ranges.
Watch out for the range semantics.


176-176: Good defensive filtering of extraneous queries.
Ensuring that only recognized filterFields and createdAt remain fosters a cleaner query state.

apps/web/src/shared/types/api.type.ts (4)

1048-1048: Useful enumerated conditions.
Defining 'CONTAINS' | 'IS' | 'BETWEEN' clarifies query usage across the codebase.


1050-1052: Streamlined UserSearchQuery structure.
Switching to key/value/condition fosters consistency and standardization in user search queries.


1234-1237: Refined QueryV2 with optional ids.
Making ids optional while enforcing key, value, and condition is a solid approach for flexible queries.


1348-1350: Alignment of MemberSearchQuery with the new pattern.
All data now follows a uniform shape, making the code more maintainable.

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

♻️ Duplicate comments (1)
apps/api/src/domains/admin/feedback/feedback.os.service.ts (1)

60-91: 🛠️ Refactor suggestion

Improve the issueIdsToFeedbackIds method by eliminating duplicate database queries.

The method performs two consecutive database queries to fetch the same data - once to get feedbacks by issue IDs and then again to get feedbacks by the previously fetched feedback IDs. This is inefficient and could potentially impact performance.

Consider simplifying this to a single query:

 private async issueIdsToFeedbackIds(
   issueIds: number[],
   condition: QueryV2ConditionsEnum = QueryV2ConditionsEnum.CONTAINS,
 ) {
-  let feedbacks = await this.feedbackRepository.find({
-    relations: ['issues'],
-    where: {
-      issues: { id: In(issueIds) },
-    },
-  });
-
-  feedbacks = await this.feedbackRepository.find({
-    relations: ['issues'],
-    where: {
-      id: In(feedbacks.map((feedback) => feedback.id)),
-    },
-  });
+  const feedbacks = await this.feedbackRepository.find({
+    relations: ['issues'],
+    where: {
+      issues: { id: In(issueIds) },
+    },
+  });

   if (condition === QueryV2ConditionsEnum.IS) {
     return feedbacks
       .filter((feedback) => {
         const feedbackIssueIds = feedback.issues.map((issue) => issue.id);
         return (
           feedbackIssueIds.length === issueIds.length &&
           issueIds.every((id) => feedbackIssueIds.includes(id))
         );
       })
       .map((feedback) => feedback.id);
   } else {
     return feedbacks.map((feedback) => feedback.id);
   }
 }
🧹 Nitpick comments (1)
apps/api/src/domains/admin/project/issue/dtos/requests/find-issues-by-project-id-request-v2.dto.ts (1)

22-36: Good update to the QueryV2 class with proper validation.

The changes to the QueryV2 class properly implement the new query structure with explicit key and value properties, along with appropriate validation decorators. This enhances both type safety and API documentation.

One thing to note: The example in @ApiProperty decorator for queries (line 42) still shows the old format { name: 'issue name' }. Consider updating it to reflect the new structure.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5b8fdee and 5d75583.

📒 Files selected for processing (4)
  • apps/api/src/domains/admin/feedback/feedback.os.service.ts (7 hunks)
  • apps/api/src/domains/admin/project/issue/dtos/find-issues-by-project-id-v2.dto.ts (1 hunks)
  • apps/api/src/domains/admin/project/issue/dtos/requests/find-issues-by-project-id-request-v2.dto.ts (1 hunks)
  • apps/api/src/domains/admin/project/issue/issue.service.ts (2 hunks)
🔇 Additional comments (8)
apps/api/src/domains/admin/project/issue/dtos/find-issues-by-project-id-v2.dto.ts (1)

25-28: Great job standardizing the query structure with explicit key-value pairs!

The refactoring improves type safety by explicitly defining the query structure with key and value properties, which aligns with the PR objective of enhancing the search functionality. This change will make the code more maintainable and prevent potential runtime errors from dynamic property access.

apps/api/src/domains/admin/project/issue/issue.service.ts (3)

185-192: Clean implementation of the refactored query structure.

The change properly adapts to the new query structure by checking for query.key === 'createdAt' instead of directly accessing properties, maintaining consistency with the DTO changes.


194-205: Good handling of the categoryId condition.

The implementation includes a proper type check and special handling for the categoryId value of 0. This is a robust approach that prevents potential runtime errors.


213-252: Well-implemented support for the IS condition.

The code now properly handles the IS condition for status and externalIssueId fields, as well as a more flexible handling for name, description, and category fields based on the condition type. This directly implements the PR objective of supporting exact match queries.

apps/api/src/domains/admin/feedback/feedback.os.service.ts (4)

276-286: Good handling of the createdAt condition with the new query structure.

The code properly adapts to the new query structure by checking for query.key === 'createdAt' and accessing the value correctly.


328-380: Excellent implementation of the IS condition for multiSelect fields.

The implementation correctly handles the exact match requirement for the IS condition using a combination of terms_set and script queries in OpenSearch. This ensures that the field contains exactly the specified values (no more, no less), directly addressing the PR objective of supporting exact match multiselect options.


508-513: Good update to pass condition to issueIdsToFeedbackIds in findByChannelIdV2.

The code now properly passes the condition to the issueIdsToFeedbackIds method, ensuring consistent behavior based on whether the condition is IS or CONTAINS.


599-604: Good update to pass condition to issueIdsToFeedbackIds in scrollV2.

Similar to the update in findByChannelIdV2, the code now properly passes the condition to the issueIdsToFeedbackIds method in the scrollV2 method as well, ensuring consistent behavior.

chiol
chiol previously approved these changes Mar 25, 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: 0

🧹 Nitpick comments (1)
apps/web/src/shared/ui/tables/draggable-row.ui.tsx (1)

57-65: Great improvement to the TableCell className logic.

This change enhances the component's flexibility by allowing column-specific control over text truncation. The implementation correctly uses the cn utility for conditional class name composition and ensures overflow-hidden is always applied, while making the truncate class configurable through column metadata.

Consider simplifying the conditional logic using optional chaining:

className={cn('overflow-hidden', {
  truncate:
-    (
-      cell.column.columnDef.meta &&
-      'truncate' in cell.column.columnDef.meta
-    ) ?
-      cell.column.columnDef.meta.truncate !== false
-    : true,
+    cell.column.columnDef.meta?.truncate !== false,
})}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between dab3655 and 4bf6c5f.

📒 Files selected for processing (6)
  • apps/web/package.json (1 hunks)
  • apps/web/src/entities/feedback/feedback-table-columns.tsx (1 hunks)
  • apps/web/src/entities/field/field-columns.tsx (4 hunks)
  • apps/web/src/entities/member/member-columns.tsx (2 hunks)
  • apps/web/src/entities/user/user-columns.tsx (5 hunks)
  • apps/web/src/shared/ui/tables/draggable-row.ui.tsx (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: integration-test
🔇 Additional comments (14)
apps/web/package.json (1)

9-9: Inclusion of Turbopack in the Dev Command

The updated dev script "next dev --turbopack" is clear and should improve development build performance. Please verify that your Next.js version (^15.0.0) fully supports Turbopack and that no additional configuration changes (e.g., in next.config.js) are needed to avoid unexpected issues.

apps/web/src/entities/feedback/feedback-table-columns.tsx (1)

115-121: Improve table column display with metadata configuration

The added meta property with conditional truncation setting improves the display behavior of different field formats. By explicitly specifying that select, multiSelect, and images formats shouldn't be truncated, their content will be displayed fully, enhancing readability for these specific field types.

apps/web/src/entities/field/field-columns.tsx (4)

41-41: Consistent metadata for drag handle column display

Adding meta: { truncate: false } ensures that the drag handle UI element isn't truncated in the table, improving usability.


73-73: Improved options column display

Setting truncate: false for the options column ensures that the option list popover displays properly without being cut off, enhancing the user experience.


86-86: Better property tag display

Adding meta: { truncate: false } to the property column ensures that the Tag component displays completely without truncation.


99-99: Enhanced status badge visibility

Setting truncate: false for the status column ensures that status badges remain fully visible in the table.

apps/web/src/entities/user/user-columns.tsx (5)

22-22: Removed unused import

The displayString function has been removed from imports as it's no longer used in this file.


48-48: Improved checkbox column display

Adding meta: { truncate: false } ensures that the checkbox UI element displays properly.


72-73: Enhanced department display with badge component

The department cell rendering has been improved to use a Badge component, and truncate: false ensures it displays properly. This change creates visual consistency with other badge-based columns.

Also applies to: 76-76


88-88: Better type badge visibility

Adding meta: { truncate: false } to the type column ensures that type badges display properly without truncation.


109-109: Enhanced project badges display

Setting truncate: false for the members column ensures that project badges display completely, improving readability.

apps/web/src/entities/member/member-columns.tsx (3)

48-48: Improved checkbox column display

Adding meta: { truncate: false } ensures that the checkbox UI element displays properly in the table.


73-73: Better department badge display

Setting truncate: false for the department column ensures that department badges display completely without truncation.


78-78: Enhanced role badge visibility

Adding meta: { truncate: false } to the role column ensures that role badges remain fully visible in the table.

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

🧹 Nitpick comments (4)
apps/web/src/entities/feedback/lib/use-feedback-query-converter.ts (4)

33-74: Typo in function parameter name

There's a typo in the toQuery function parameter: valeu should be value.

-const toQuery = (
-  projectId: number,
-): Record<TableFilterFieldFotmat, (valeu: unknown) => unknown> => ({
+const toQuery = (
+  projectId: number,
+): Record<TableFilterFieldFotmat, (value: unknown) => unknown> => ({

21-28: Typo in type name

There's a typo in the imported type name: TableFilterFieldFotmat should be TableFilterFieldFormat.


152-186: Typo in function name

There's a typo in the function name: onChageTableFilters should be onChangeTableFilters.


189-201: Typo in function name in returned object

In the returned object, updateDateRage should be updateDateRange.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4bf6c5f and fcefbbe.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (11)
  • apps/web/package.json (1 hunks)
  • apps/web/src/entities/dashboard/ui/issue-bar-chart.ui.tsx (1 hunks)
  • apps/web/src/entities/dashboard/ui/issue-rank.ui.tsx (2 hunks)
  • apps/web/src/entities/feedback/lib/use-feedback-query-converter.ts (7 hunks)
  • apps/web/src/entities/feedback/ui/feedback-detail-sheet.ui.tsx (1 hunks)
  • apps/web/src/entities/issue/ui/issue-select-box.ui.tsx (1 hunks)
  • apps/web/src/shared/ui/inputs/index.ts (1 hunks)
  • apps/web/src/shared/ui/inputs/multi-select-search-input.ui.tsx (1 hunks)
  • apps/web/src/shared/ui/table-filter-popover/table-filter-popover-input.ui.tsx (1 hunks)
  • apps/web/src/widgets/issue-table/lib/use-issue-query-converter.ts (7 hunks)
  • apps/web/src/widgets/issue-table/ui/issue-detail-sheet.ui.tsx (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • apps/web/package.json
  • apps/web/src/widgets/issue-table/ui/issue-detail-sheet.ui.tsx
  • apps/web/src/entities/feedback/ui/feedback-detail-sheet.ui.tsx
  • apps/web/src/entities/dashboard/ui/issue-bar-chart.ui.tsx
  • apps/web/src/entities/dashboard/ui/issue-rank.ui.tsx
  • apps/web/src/widgets/issue-table/lib/use-issue-query-converter.ts
🧰 Additional context used
🧬 Code Definitions (1)
apps/web/src/entities/feedback/lib/use-feedback-query-converter.ts (1)
apps/web/src/shared/types/search-query.type.ts (1)
  • SearchQuery (16-20)
🪛 Biome (1.9.4)
apps/web/src/shared/ui/inputs/multi-select-search-input.ui.tsx

[error] 81-81: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: integration-test
🔇 Additional comments (19)
apps/web/src/entities/feedback/lib/use-feedback-query-converter.ts (8)

21-28: Type import enhances code clarity and type safety

The addition of the SearchQuery type import is a positive change that provides better type safety for the query objects throughout the file.


38-67: Successfully implemented IS condition for issue search

The implementation correctly uses the new SearchQuery structure with explicit key, value, and condition properties. The 'IS' condition allows for exact matching in issue searches, which aligns with the PR objectives.


90-98: Type safety improved for query state management

The useQueryState hook now correctly uses the SearchQuery[] type and provides a properly structured default value. This ensures type consistency throughout the component.


101-103: Query structure update for date range handling

The date range logic has been appropriately updated to work with the new query structure by using key property for identification instead of direct property access.


115-129: Date range update logic maintains structure consistency

The function correctly filters out existing date queries using the key property and adds a new one with the proper structure, maintaining consistency with the new SearchQuery format.


131-150: Table filters logic correctly adapted to new query structure

The table filters logic has been properly updated to extract properties using the new structure. The code is more explicit and easier to understand with the key-value approach.


152-187: Consistent implementation of table filter changes

The function for changing table filters has been consistently updated to work with the new query structure, ensuring that all query manipulations follow the same pattern throughout the component.


189-193: Return filter logic properly updated

The query filtering in the return statement has been updated to use the key property, maintaining consistency with the rest of the changes.

apps/web/src/shared/ui/inputs/multi-select-search-input.ui.tsx (3)

37-49: Good implementation of Props interface with optional properties.

The interface provides a well-structured set of props with appropriate types, making the component flexible and reusable. The use of optional properties (marked with ?) allows for more versatile usage patterns.


97-116: Well-implemented option selection logic.

The component correctly handles the addition and removal of selected items by checking if they already exist in the value array. The rendering of the component is optimized with appropriate checks for selected state.


118-121: Good implementation of infinite scrolling.

The integration with the InfiniteScrollArea component allows for efficient loading of large datasets, enhancing the user experience when dealing with many options.

apps/web/src/shared/ui/inputs/index.ts (1)

21-21: Good modular approach for exporting the new component.

Exporting the MultiSelectSearchInput from the barrel file makes it easily accessible alongside other input components, following the project's established pattern.

apps/web/src/shared/ui/table-filter-popover/table-filter-popover-input.ui.tsx (1)

194-194: Improved handling of issue selection values.

The code now properly handles multiple issue selections by ensuring the value is always treated as a string array. The nullish coalescing operator provides an empty array as a fallback when value is null or undefined.

apps/web/src/entities/issue/ui/issue-select-box.ui.tsx (6)

21-21: Good use of imports for the new MultiSelectSearchInput component.

The import statement correctly brings in the new component that supports multiple selections.


25-28: Props interface updated to support multiple selections.

The interface has been correctly modified to handle arrays of strings instead of single string values, which aligns with the new multi-select functionality.


33-33: State variable renamed to reflect plural nature.

The state variable was appropriately renamed from issueName to issueNames to better represent its new purpose as an array of names.


39-39: Query structure updated to use explicit key-value format.

The search query now follows the structured format with key, value, and condition properties, which aligns with the PR objective to enhance clarity in search parameters.


48-59: Improved issue name fetching with Promise.all.

The code now efficiently fetches multiple issue names in parallel using Promise.all, properly handling the asynchronous nature of the API calls.


62-74: Updated to use MultiSelectSearchInput component.

The component now correctly uses the new MultiSelectSearchInput instead of the previous SelectSearchInput, passing the appropriate props for multiple selection functionality.

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

🧹 Nitpick comments (5)
apps/web/src/shared/ui/inputs/multi-select-search-input.ui.tsx (5)

37-49: Props interface looks good, but consider default value handling

The Props interface is well-defined with appropriate types. The value prop is defined as string[] | null, which requires careful handling in the component logic.

Consider providing a default empty array for value to simplify the component logic:

interface Props {
  label?: string;
-  value: string[] | null;
+  value: string[];
  onChange: (value: string[]) => void;
  options: { label: string; value: string }[];
  required?: boolean;
  disabled?: boolean;
  error?: string;
  fetchNextPage?: () => void;
  hasNextPage?: boolean;
  inputValue?: string;
  setInputValue?: (value: string) => void;
}

95-95: Translate hardcoded error message

The "No results found" message is hardcoded in English instead of using the translation function.

Use the translation function for consistency:

- <ComboboxEmpty>No results found.</ComboboxEmpty>
+ <ComboboxEmpty>{t('v2.common.noResultsFound', 'No results found.')}</ComboboxEmpty>

98-109: Improve type safety and simplify the selection logic

The current implementation has some unnecessary optional chaining and could be simplified.

Simplify the selection logic:

{options.map((option) => {
-  const isChecked = value?.some((v) => v === option.value);
+  const isChecked = value ? value.includes(option.value) : false;
  return (
    <ComboboxSelectItem
      key={option.value}
      value={option.value}
      checked={isChecked}
      onSelect={() => {
        onChange(
-         isChecked ?
-           (value?.filter((v) => v !== option.value) ?? [])
-         : [...(value ?? []), option.value],
+         isChecked 
+           ? (value || []).filter((v) => v !== option.value)
+           : [...(value || []), option.value],
        );
        setOpen(false);
      }}
    >

118-121: Check if fetchNextPage is defined before passing to InfiniteScrollArea

The fetchNextPage prop is optional but passed directly to the InfiniteScrollArea component, which might cause issues if it's undefined.

Add a conditional check:

<InfiniteScrollArea
  hasNextPage={hasNextPage}
-  fetchNextPage={fetchNextPage}
+  fetchNextPage={fetchNextPage ?? (() => {})}
/>

70-127: Consider adding ARIA attributes for better accessibility

The component could benefit from additional accessibility attributes to improve usability for screen readers.

For example, you could add aria-label, aria-required, and aria-invalid attributes to the appropriate elements to improve accessibility.

<Combobox open={open} onOpenChange={setOpen}>
-  <ComboboxTrigger disabled={disabled} className="font-normal">
+  <ComboboxTrigger 
+    disabled={disabled} 
+    className="font-normal"
+    aria-required={required || false}
+    aria-invalid={!!error}
+    aria-label={label || t('v2.common.select')}
+  >
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between fcefbbe and 7115092.

📒 Files selected for processing (7)
  • apps/web/package.json (0 hunks)
  • apps/web/src/entities/feedback/lib/use-feedback-query-converter.ts (7 hunks)
  • apps/web/src/entities/feedback/ui/feedback-cell.tsx (1 hunks)
  • apps/web/src/entities/feedback/ui/feedback-detail-cell.ui.tsx (1 hunks)
  • apps/web/src/shared/ui/inputs/multi-select-search-input.ui.tsx (1 hunks)
  • apps/web/src/widgets/issue-table/lib/use-issue-query-converter.ts (8 hunks)
  • tooling/eslint/react.js (1 hunks)
💤 Files with no reviewable changes (1)
  • apps/web/package.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/src/widgets/issue-table/lib/use-issue-query-converter.ts
🧰 Additional context used
🧬 Code Definitions (1)
apps/web/src/entities/feedback/lib/use-feedback-query-converter.ts (1)
apps/web/src/shared/types/search-query.type.ts (1)
  • SearchQuery (16-20)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: integration-test
🔇 Additional comments (11)
tooling/eslint/react.js (1)

18-18: Great addition of the react/jsx-key rule!

Setting the react/jsx-key rule to 'error' enforces a critical React best practice by requiring unique key props on JSX elements in arrays and iterators. This improves rendering performance and helps React efficiently identify changes in list items, which aligns well with the PR's goal of enhancing query parameter structure with explicit key-value pairs.

apps/web/src/entities/feedback/lib/use-feedback-query-converter.ts (8)

22-24: Type import enhancement for query structure

Good addition of the SearchQuery type import. This enhances type safety by providing a clear structure for query objects.


38-67: Refactored issue search to use explicit key-value structure

The refactoring of the issue search functionality now properly implements the IS condition with explicit key and value properties in the query structure. This aligns with the PR objective of supporting exact match multiselect options.


90-97: Updated query state with type-safe structure

Good update to the query state definition. The typed SearchQuery[] provides better type safety than the previous Record<string, unknown>[] and the default query now uses the explicit key-value structure.


100-113: Updated dateRange calculation with key-based access

The dateRange calculation has been properly updated to use the key-based query structure. This ensures consistency with the new query format.


115-129: Refactored date range handling to use key-value structure

The date range handling now correctly implements the key-value structure in the query objects, maintaining the same functionality while using the new format.


132-150: Updated tableFilters logic to use key-value structure

The tableFilters calculation has been properly modified to extract key and value from the new query structure, maintaining consistency throughout the codebase.


152-187: Refactored table filter update logic

The table filter update logic has been properly updated to use the key-value structure, ensuring that all parts of the code work together consistently with the new query format.


189-204: Updated return structure with consistent filtering

The return object's filtering logic has been updated to use key-based property access, ensuring consistent behavior with the new query structure throughout the component.

apps/web/src/entities/feedback/ui/feedback-cell.tsx (1)

58-59: Added key prop to Badge component

Good addition of the key prop to the Badge component. This follows React's best practices for list rendering and helps React efficiently update the DOM when the list changes.

apps/web/src/entities/feedback/ui/feedback-detail-cell.ui.tsx (1)

50-51: Added key prop to Badge component

Good addition of the key prop to the Badge component. This follows React's best practices for list rendering and helps React efficiently update the DOM when the list changes.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🔭 Outside diff range comments (1)
apps/api/src/domains/admin/feedback/feedback.os.service.ts (1)

528-543: 🛠️ Refactor suggestion

Inconsistent query properties usage

While most of the codebase has migrated to a structured key/value approach, this section still uses the ids property to store feedback IDs after processing. This creates inconsistency and potential confusion.

if (queries?.[i].key === 'issueIds') {
  const condition = queries[i].condition;

  const feedbackIds = await this.issueIdsToFeedbackIds(
    queries[i].value as number[],
    condition,
  );

- if (queries[i].ids) {
-   queries[i].ids = [...(queries[i].ids ?? []), ...feedbackIds];
- } else {
-   queries[i].ids = feedbackIds;
- }
+ queries[i].value = feedbackIds;
+ queries[i].key = 'ids';
}

Apply the same pattern in the scrollV2 method (lines 619-634).

♻️ Duplicate comments (1)
apps/api/src/domains/admin/feedback/feedback.os.service.ts (1)

293-310: ⚠️ Potential issue

Action Required: Update issueIds Filter Handling in OS Query Builder

In this block, you're using query.ids instead of query.value—inconsistent with the refactored query structure which uses key and value properties.

-if (fieldKey === 'issueIds' && query.ids) {
+if (fieldKey === 'issueIds' && query.value) {
  osQuery.bool.must.push({
    ids: {
-     values: query.ids.map((id) => id.toString()),
+     values: query.value.map((id) => id.toString()),
    },
  });
  // ...
🧹 Nitpick comments (1)
apps/api/src/domains/admin/feedback/feedback.os.service.ts (1)

78-90: The IS condition implementation needs test coverage.

The new filter logic for the IS condition looks good, but it introduces complex operations that deserve comprehensive testing. Edge cases to verify include:

  • Empty arrays
  • Cases where all issue IDs match but feedback has additional issue IDs
  • Feedbacks with no issue IDs
  • Performance with large datasets

Consider implementing unit tests to verify this implementation works correctly for all possible scenarios.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7115092 and da65187.

📒 Files selected for processing (2)
  • apps/api/src/domains/admin/feedback/feedback.mysql.service.ts (3 hunks)
  • apps/api/src/domains/admin/feedback/feedback.os.service.ts (7 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/api/src/domains/admin/feedback/feedback.mysql.service.ts
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: integration-test
🔇 Additional comments (3)
apps/api/src/domains/admin/feedback/feedback.os.service.ts (3)

64-76: Avoid multiple queries for the same data.

Currently, the code performs two consecutive database lookups on the same feedback IDs. This doubles the overhead. Consider combining these queries into one or refactoring to reduce redundant calls.


328-402: Well-implemented query conditions for multi-select fields

The implementation for both IS and CONTAINS conditions is comprehensive and handles all cases properly, including empty arrays. The script-based approach ensures accurate matching of exact sets for the IS condition and proper containment for the CONTAINS condition.


60-91: The flexibility added for query conditions is a good enhancement

Adding support for the IS condition in the issueIdsToFeedbackIds method improves the query capabilities by allowing for exact matches on feedback issues. This aligns well with the PR objectives of enhancing search functionality.

@chiol chiol changed the title Feat/support is condition in issue search feat: support "is" and "contains" condition in issue search Mar 28, 2025
@chiol chiol merged commit 199f7c1 into dev Mar 28, 2025
7 checks passed
@chiol chiol deleted the feat/support-is-condition-in-issue-search branch March 28, 2025 04:29
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.

2 participants