Skip to content

Add Review Service and Controller#101

Merged
gitnasr merged 15 commits intodevfrom
ReviewSystem
Jun 28, 2025
Merged

Add Review Service and Controller#101
gitnasr merged 15 commits intodevfrom
ReviewSystem

Conversation

@NourhaneAmir
Copy link
Copy Markdown
Contributor

@NourhaneAmir NourhaneAmir commented Jun 26, 2025

Description by Korbit AI

What change is being made?

Add a comprehensive service and controller for handling reviews within the application, introducing AutoMapper profiles, DTOs, new service interfaces, and repository methods to facilitate creation, update, deletion, and retrieval of reviews.

Why are these changes being made?

These changes are implemented to enhance the application by providing users the ability to manage reviews for orders, thereby encouraging feedback and improving the overall service experience. By structuring the review service and controller, the application ensures modularity and scalability while adhering to best practices in software architecture.

Is this description stale? Ask me to generate a new description by commenting /korbit-generate-pr-description

Summary by CodeRabbit

  • New Features
    • Introduced API endpoints for creating, updating, deleting, and retrieving user reviews.
    • Added support for managing reviews, including validation for review content and ratings.
    • Users can now view all reviews they have received.
    • Enabled review creation and updates with star ratings and comments.
    • Added user-specific retrieval of reviews with secure authorization.
    • Added ability to fetch reviewed orders for users.
    • Enhanced review retrieval with filtering and pagination support.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jun 26, 2025

Warning

Rate limit exceeded

@gitnasr has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 3 minutes and 26 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 84c8f86 and 9628063.

📒 Files selected for processing (3)
  • Dentizone.Application/DI/Services.cs (2 hunks)
  • Dentizone.Application/Services/Payment/WalletService.cs (1 hunks)
  • Dentizone.Infrastructure/DependencyInjection/AddRepositories.cs (1 hunks)

Walkthrough

This change introduces full review management functionality to the application. It adds DTOs, validation, AutoMapper profiles, a service interface and implementation, dependency injection registrations, and an ASP.NET Core API controller for creating, updating, deleting, and retrieving reviews associated with users and orders. It also removes the legacy ReviewUx entity and its configuration, updating related domain and infrastructure layers accordingly.

Changes

File(s) Change Summary
Dentizone.Application/DTOs/Review/CreateReviewDTO.cs
Dentizone.Application/DTOs/Review/ReviewDTO.cs
Dentizone.Application/DTOs/Review/UpdateReviewDTO.cs
Added DTO classes for creating, updating, and representing reviews, each with corresponding FluentValidation validators.
Dentizone.Application/AutoMapper/Review/ReviewProfile.cs Added AutoMapper profile to map between Review entity and the three review DTOs, with bidirectional mappings.
Dentizone.Application/Interfaces/Review/IReviewService.cs Added interface defining asynchronous review management methods.
Dentizone.Application/Services/ReviewService.cs Implemented review management service with create, update, delete, and retrieval logic.
Dentizone.Application/DI/Services.cs Registered IReviewService and its implementation in the DI container.
Dentizone.Infrastructure/DependencyInjection/AddRepositories.cs Registered IReviewRepository and its implementation in the DI container.
Dentizone.Presentaion/Controllers/ReviewController.cs Added API controller exposing endpoints for review creation, update, deletion, and retrieval by user.
Dentizone.Domain/Interfaces/Repositories/IReviewRepository.cs Added method FindAllBy to query reviews by predicate.
Dentizone.Infrastructure/Repositories/ReviewRepository.cs Added implementation of FindAllBy method for querying reviews by predicate.
Dentizone.Application/Interfaces/Order/IOrderService.cs Added method to retrieve reviewed orders by user ID.
Dentizone.Application/Services/OrderService.cs Added method to get reviewed orders by user ID.
Dentizone.Domain/Entity/Order.cs Removed ReviewUx property from Order entity.
Dentizone.Domain/Interfaces/Repositories/IOrderRepository.cs Modified GetAllAsync method to accept nullable page parameter.
Dentizone.Infrastructure/Repositories/OrderRepository.cs Modified GetAllAsync and BuildPagedQuery methods to support nullable page and include Review navigation property.
Dentizone.Infrastructure/Persistence/Configurations/ReviewUxConfiguration.cs Removed one-to-one relationship configuration between ReviewUx and Order.
Dentizone.Domain/Entity/ReviewUX.cs Removed legacy ReviewUx entity class.
Dentizone.Application/AutoMapper/Payments/WalletProfile.cs Removed unused using directives.
Dentizone.Application/Services/Authentication/AuthService.cs Removed unused using directive.
Dentizone.Application/Services/Payment/WalletService.cs Removed unused using directive and reformatted constructor and method spacing.
Dentizone.Application/Services/UserService.cs Reformatted constructor and method indentation for readability.
Dentizone.Presentaion/Program.cs Removed unused using directive.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant ReviewController
    participant ReviewService
    participant ReviewRepository
    participant Mapper

    Client->>ReviewController: POST /api/review (CreateReviewDTO)
    ReviewController->>ReviewService: CreateOrderReviewAsync(userId, dto)
    ReviewService->>Mapper: Map CreateReviewDTO to Review
    Mapper-->>ReviewService: Review entity
    ReviewService->>ReviewRepository: AddAsync(Review)
    ReviewRepository-->>ReviewService: (persisted)
    ReviewService-->>ReviewController: (done)
    ReviewController-->>Client: 200 OK

    Client->>ReviewController: PUT /api/review/{reviewId} (UpdateReviewDTO)
    ReviewController->>ReviewService: UpdateReviewAsync(reviewId, dto)
    ReviewService->>ReviewRepository: GetByIdAsync(reviewId)
    ReviewRepository-->>ReviewService: Review entity
    ReviewService->>ReviewRepository: UpdateAsync(Review)
    ReviewRepository-->>ReviewService: (persisted)
    ReviewService-->>ReviewController: (done)
    ReviewController-->>Client: 200 OK

    Client->>ReviewController: GET /api/review
    ReviewController->>ReviewService: GetSubmittedReviews(userId)
    ReviewService->>ReviewRepository: FindAllBy(condition)
    ReviewRepository-->>ReviewService: IQueryable<Review>
    ReviewService->>Mapper: Map Review to ReviewDTO
    Mapper-->>ReviewService: IEnumerable<ReviewDTO>
    ReviewService-->>ReviewController: IEnumerable<ReviewDTO>
    ReviewController-->>Client: 200 OK (with data)

    Client->>ReviewController: GET /api/review/received-review
    ReviewController->>ReviewService: GetReceivedReviews(userId)
    ReviewService->>OrderService: GetReviewedOrdersByUserId(userId)
    OrderService-->>ReviewService: IEnumerable<Order> with Reviews
    ReviewService->>Mapper: Map Reviews to ReviewDTO
    Mapper-->>ReviewService: IEnumerable<ReviewDTO>
    ReviewService-->>ReviewController: IEnumerable<ReviewDTO>
    ReviewController-->>Client: 200 OK (with data)

    Client->>ReviewController: DELETE /api/review/{reviewId}
    ReviewController->>ReviewService: DeleteReviewAsync(reviewId)
    ReviewService->>ReviewRepository: DeleteAsync(reviewId)
    ReviewRepository-->>ReviewService: (deleted)
    ReviewService-->>ReviewController: (done)
    ReviewController-->>Client: 200 OK
Loading

Possibly related PRs

  • Review Model Isa #23: Introduced the Review entity model and EF Core configuration, which this PR builds upon by adding the application and API layers for review management.
  • Nasr/reviewux #24: Added the ReviewUx entity and related configuration, which this PR removes and replaces with the new Review implementation.
  • Refactor user model and simplify domain structure #26: Refactored user model affecting the Review entity's User property type, related to domain model changes in this PR.

Suggested labels

enhancement

Poem

In the garden of code, a review now blooms,
With DTO petals and validators in rooms.
Controllers and services hop into play,
Mapping and saving reviews every day.
🐇 With each user’s feedback, the system grows bright—
Hopping forward in features, with code done just right!

✨ Finishing Touches
  • 📝 Generate Docstrings

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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

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

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 generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

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

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
Copy Markdown

@korbit-ai korbit-ai bot left a comment

Choose a reason for hiding this comment

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

Review by Korbit AI

Korbit automatically attempts to detect when you fix issues in new commits.
Category Issue Status
Design Inconsistent Formatting in Class Declaration ▹ view ✅ Fix detected
Readability Unnecessary Using Directives ▹ view ✅ Fix detected
Readability Inconsistent Acronym Casing ▹ view ✅ Fix detected
Security ID Property Exposed in Creation DTO ▹ view ✅ Fix detected
Functionality Incorrect Data Type for Stars Rating ▹ view ✅ Fix detected
Design Unnecessary mutable DTO property ▹ view
Functionality Missing Empty String Validation for Comment ▹ view ✅ Fix detected
Design Unnecessary Use of Fully Qualified Names ▹ view
Security Missing XSS Protection on Comment Field ▹ view
Design Validation logic not properly separated ▹ view
Files scanned
File Path Reviewed
Dentizone.Application/DTOs/Review/UpdateReviewDTO.cs
Dentizone.Application/AutoMapper/Review/ReviewProfile.cs
Dentizone.Application/DTOs/Review/ReviewDTO.cs
Dentizone.Application/Interfaces/Review/IReviewService.cs
Dentizone.Infrastructure/DependencyInjection/AddRepositories.cs
Dentizone.Application/DTOs/Review/CreateReviewDTO.cs
Dentizone.Application/DI/Services.cs
Dentizone.Presentaion/Controllers/ReviewController.cs
Dentizone.Application/Services/ReviewService.cs

Explore our documentation to understand the languages and file types we support and the files we ignore.

Check out our docs on how you can make Korbit work best for you and your team.

Loving Korbit!? Share us on LinkedIn Reddit and X

public string UserId { get; set; }
public string OrderItemId { get; set; }
public decimal Stars { get; set; }
public string Comment { get; set; }
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing XSS Protection on Comment Field category Security

Tell me more
What is the issue?

The Comment property lacks input sanitization rules in the validation to prevent potential XSS attacks.

Why this matters

Without proper sanitization, malicious users could inject harmful scripts that would be stored and potentially executed when the review is displayed to other users.

Suggested change ∙ Feature Preview

Add validation rule to sanitize the Comment input:

RuleFor(x => x.Comment)
    .MaximumLength(500)
    .Must(comment => HtmlSanitizer.Sanitize(comment) == comment)
    .WithMessage("Comment contains invalid characters or potentially harmful content.");
Provide feedback to improve future suggestions

Nice Catch Incorrect Not in Scope Not in coding standard Other

💬 Looking for more details? Reply to this comment to chat with Korbit.

{
public class ReviewDTO
{
public string Comment { get; set; }

This comment was marked as resolved.

{
public class UpdateReviewDTO
{
public string Comment { get; set; }
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Unnecessary mutable DTO property category Design

Tell me more
What is the issue?

The DTO property is mutable without any clear requirement for mutability, potentially leading to unexpected state changes.

Why this matters

Mutable DTOs can lead to side effects and make the code harder to reason about, especially in concurrent scenarios.

Suggested change ∙ Feature Preview

Make the DTO immutable by using a constructor and read-only property:

public class UpdateReviewDTO
{
    public UpdateReviewDTO(string comment)
    {
        Comment = comment;
    }

    public string Comment { get; }
}
Provide feedback to improve future suggestions

Nice Catch Incorrect Not in Scope Not in coding standard Other

💬 Looking for more details? Reply to this comment to chat with Korbit.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 15

🧹 Nitpick comments (9)
Dentizone.Application/DTOs/Review/UpdateReviewDTO.cs (1)

2-6: Remove unused imports.

Several using statements are not used in this file and should be removed to keep the code clean.

 using FluentValidation;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
Dentizone.Application/DTOs/Review/ReviewDTO.cs (2)

2-6: Remove unused imports to improve code cleanliness.

Several imports appear to be unused in this file. Consider removing unused using statements to keep the code clean and improve compilation performance.

 using FluentValidation;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;

30-30: Remove trailing empty line.

 }
-
Dentizone.Application/AutoMapper/Review/ReviewProfile.cs (1)

2-6: Clean up unused imports and formatting.

Remove unnecessary using statements and extra whitespace for better code maintainability.

-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-    

Also applies to: 22-22

Dentizone.Application/Interfaces/Review/IReviewService.cs (2)

3-6: Remove unused imports.

Many of these using statements are not needed for this interface, creating unnecessary dependencies and code clutter.

-using Microsoft.AspNetCore.Http.HttpResults;
-using Microsoft.Extensions.Hosting;
-using Pipelines.Sockets.Unofficial;
-using StackExchange.Redis;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using static Microsoft.EntityFrameworkCore.DbLoggerCategory;

Also applies to: 9-12


21-21: Fix spacing in method signature.

-       Task <IEnumerable<ReviewDTO>> GetUserReviewsTaken(string userId);
+       Task<IEnumerable<ReviewDTO>> GetUserReviewsTaken(string userId);
Dentizone.Application/DTOs/Review/CreateReviewDTO.cs (3)

1-7: Clean up unused imports.

Several using statements appear to be unused in this file. Consider removing unused imports to keep the code clean.

 using FluentValidation;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;

16-16: Consider property naming consistency with domain entity.

The DTO property Comment maps to the domain entity property Text. Consider using consistent naming or add clear documentation about the mapping.

Option 1 - Match domain entity naming:

-    public string Comment { get; set; }
+    public string? Text { get; set; }

Option 2 - Keep current naming but ensure AutoMapper profile handles the mapping correctly.


34-35: Update validation property reference if needed.

If the Comment property name is changed to Text for consistency with the domain entity, update this validation rule accordingly.

-            RuleFor(x => x.Comment)
-                .MaximumLength(500).WithMessage("Comment must not exceed 500 characters.");
+            RuleFor(x => x.Text)
+                .MaximumLength(500).WithMessage("Text must not exceed 500 characters.");
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4000d64 and 5eaa2f4.

📒 Files selected for processing (9)
  • Dentizone.Application/AutoMapper/Review/ReviewProfile.cs (1 hunks)
  • Dentizone.Application/DI/Services.cs (2 hunks)
  • Dentizone.Application/DTOs/Review/CreateReviewDTO.cs (1 hunks)
  • Dentizone.Application/DTOs/Review/ReviewDTO.cs (1 hunks)
  • Dentizone.Application/DTOs/Review/UpdateReviewDTO.cs (1 hunks)
  • Dentizone.Application/Interfaces/Review/IReviewService.cs (1 hunks)
  • Dentizone.Application/Services/ReviewService.cs (1 hunks)
  • Dentizone.Infrastructure/DependencyInjection/AddRepositories.cs (1 hunks)
  • Dentizone.Presentaion/Controllers/ReviewController.cs (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (9)
Dentizone.Application/DI/Services.cs (2)
Dentizone.Domain/Entity/Review.cs (1)
  • Review (5-17)
Dentizone.Application/Services/ReviewService.cs (1)
  • ReviewService (14-57)
Dentizone.Application/AutoMapper/Review/ReviewProfile.cs (4)
Dentizone.Domain/Entity/Review.cs (1)
  • Review (5-17)
Dentizone.Application/DTOs/Review/CreateReviewDTO.cs (1)
  • CreateReviewDTO (10-18)
Dentizone.Application/DTOs/Review/UpdateReviewDTO.cs (1)
  • UpdateReviewDTO (10-13)
Dentizone.Application/DTOs/Review/ReviewDTO.cs (1)
  • ReviewDTO (10-14)
Dentizone.Application/Interfaces/Review/IReviewService.cs (4)
Dentizone.Domain/Entity/Review.cs (1)
  • Review (5-17)
Dentizone.Application/DTOs/Review/CreateReviewDTO.cs (1)
  • CreateReviewDTO (10-18)
Dentizone.Application/DTOs/Review/UpdateReviewDTO.cs (1)
  • UpdateReviewDTO (10-13)
Dentizone.Application/DTOs/Review/ReviewDTO.cs (1)
  • ReviewDTO (10-14)
Dentizone.Application/DTOs/Review/ReviewDTO.cs (1)
Dentizone.Domain/Entity/Review.cs (1)
  • Review (5-17)
Dentizone.Application/DTOs/Review/UpdateReviewDTO.cs (1)
Dentizone.Domain/Entity/Review.cs (1)
  • Review (5-17)
Dentizone.Infrastructure/DependencyInjection/AddRepositories.cs (1)
Dentizone.Infrastructure/Repositories/ReviewRepository.cs (1)
  • ReviewRepository (8-57)
Dentizone.Application/DTOs/Review/CreateReviewDTO.cs (1)
Dentizone.Domain/Entity/Review.cs (1)
  • Review (5-17)
Dentizone.Presentaion/Controllers/ReviewController.cs (5)
Dentizone.Domain/Entity/Review.cs (1)
  • Review (5-17)
Dentizone.Application/Interfaces/Review/IReviewService.cs (4)
  • Task (18-18)
  • Task (19-19)
  • Task (20-20)
  • Task (21-21)
Dentizone.Application/Services/ReviewService.cs (4)
  • Task (16-28)
  • Task (30-33)
  • Task (35-43)
  • Task (45-56)
Dentizone.Application/DTOs/Review/CreateReviewDTO.cs (1)
  • CreateReviewDTO (10-18)
Dentizone.Application/DTOs/Review/UpdateReviewDTO.cs (1)
  • UpdateReviewDTO (10-13)
Dentizone.Application/Services/ReviewService.cs (6)
Dentizone.Domain/Entity/Review.cs (1)
  • Review (5-17)
Dentizone.Application/DI/Services.cs (1)
  • Services (21-49)
Dentizone.Application/Interfaces/Review/IReviewService.cs (4)
  • Task (18-18)
  • Task (19-19)
  • Task (20-20)
  • Task (21-21)
Dentizone.Application/DTOs/Review/CreateReviewDTO.cs (1)
  • CreateReviewDTO (10-18)
Dentizone.Application/DTOs/Review/ReviewDTO.cs (1)
  • ReviewDTO (10-14)
Dentizone.Application/DTOs/Review/UpdateReviewDTO.cs (1)
  • UpdateReviewDTO (10-13)
🔇 Additional comments (10)
Dentizone.Application/DTOs/Review/UpdateReviewDTO.cs (3)

10-13: Verify property naming and nullability design decisions.

The DTO uses Comment while the domain entity Review uses Text for the same concept. Additionally, the domain entity's Text property is nullable (string?) but this DTO's Comment property appears non-nullable and has validation preventing null values.

Please confirm this design is intentional:

  • Property naming difference (Comment vs Text)
  • Nullability difference (domain allows null, DTO prevents it)

14-22: Well-implemented validation rules.

The FluentValidation implementation is solid with appropriate constraints:

  • NotNull ensures comments are provided during updates
  • 500 character limit is reasonable for review text
  • Clear, user-friendly error messages

8-23: Good file organization and naming conventions.

The file follows established patterns with the DTO and its validator co-located, proper namespace structure, and consistent naming conventions.

Dentizone.Application/DI/Services.cs (1)

10-10: LGTM! Proper dependency injection setup.

The using statement import and service registration follow the established patterns in the codebase correctly.

Also applies to: 45-45

Dentizone.Infrastructure/DependencyInjection/AddRepositories.cs (1)

28-28: LGTM! Repository registration follows established pattern.

The registration correctly enables dependency injection for the review repository.

Dentizone.Presentaion/Controllers/ReviewController.cs (3)

7-8: LGTM - Standard controller configuration

The controller attributes are properly configured with [ApiController] and appropriate routing.


12-16: LGTM - Proper dependency injection implementation

The constructor correctly implements dependency injection for the service layer.


1-49: Verify DTO property mappings consistency

Based on the relevant code snippets, there appear to be inconsistencies between DTOs and the domain entity:

  1. CreateReviewDTO.Stars is decimal, but Review.Stars is int
  2. UpdateReviewDTO.Comment maps to Review.Text
  3. CreateReviewDTO.OrderItemId should map to Review.OrderId

Please verify these mappings are handled correctly in the AutoMapper profile and service implementation:

#!/bin/bash
# Description: Check for DTO-Entity mapping inconsistencies
# Expected: Verify property type compatibility and field mappings

echo "Checking CreateReviewDTO properties..."
rg -A 10 "class CreateReviewDTO" --type cs

echo "Checking Review entity properties..."
rg -A 15 "class Review" --type cs

echo "Checking AutoMapper profile for Review mappings..."
rg -A 20 "ReviewProfile" --type cs
Dentizone.Application/DTOs/Review/CreateReviewDTO.cs (2)

31-32: Validation range is appropriate.

The Stars validation range of 1-5 is appropriate for typical rating systems.


10-18: Let’s accurately list the Review entity’s public properties to confirm alignment with your DTO:

#!/bin/bash
# Find the Review entity and list its public properties for mapping checks

entity_file=$(rg -l "public class Review" -g "*.cs" | grep "Domain/Entity/Review.cs" | head -n1)

if [[ -f "$entity_file" ]]; then
  echo "Review entity file: $entity_file"
  echo "Public properties:"
  sed -n '/public class Review/,/^}/p' "$entity_file" | grep 'public .* { get; set; }'
else
  echo "✕ Review entity file not found at expected path."
fi

- Updated `using` directives in `WalletProfile.cs` and `ReviewProfile.cs` to include necessary namespaces.
- Renamed `ReviewDTO`, `CreateReviewDTO`, and `UpdateReviewDTO` to `ReviewDto`, `CreateReviewDto`, and `UpdateReviewDto` across multiple files.
- Adjusted mapping configurations in `ReviewProfile.cs` to reflect new naming conventions.
- Modified `IReviewService` and `ReviewService.cs` to utilize the updated DTO names.
- Reformatted constructors in `WalletService.cs` and `UserService.cs` for improved readability.
- Added `FindAllBy` method to `IReviewRepository` and implemented it in `ReviewRepository.cs`.
- Updated `ReviewController.cs` to align with new DTO method signatures.
- Removed unused `using` directives in `AuthService.cs` and `Program.cs` to streamline code.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 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 5eaa2f4 and 42e8f67.

📒 Files selected for processing (14)
  • Dentizone.Application/AutoMapper/Payments/WalletProfile.cs (1 hunks)
  • Dentizone.Application/AutoMapper/Review/ReviewProfile.cs (1 hunks)
  • Dentizone.Application/DTOs/Review/CreateReviewDTO.cs (1 hunks)
  • Dentizone.Application/DTOs/Review/ReviewDTO.cs (1 hunks)
  • Dentizone.Application/DTOs/Review/UpdateReviewDTO.cs (1 hunks)
  • Dentizone.Application/Interfaces/Review/IReviewService.cs (1 hunks)
  • Dentizone.Application/Services/Authentication/AuthService.cs (0 hunks)
  • Dentizone.Application/Services/Payment/WalletService.cs (2 hunks)
  • Dentizone.Application/Services/ReviewService.cs (1 hunks)
  • Dentizone.Application/Services/UserService.cs (4 hunks)
  • Dentizone.Domain/Interfaces/Repositories/IReviewRepository.cs (1 hunks)
  • Dentizone.Infrastructure/Repositories/ReviewRepository.cs (3 hunks)
  • Dentizone.Presentaion/Controllers/ReviewController.cs (1 hunks)
  • Dentizone.Presentaion/Program.cs (0 hunks)
💤 Files with no reviewable changes (2)
  • Dentizone.Presentaion/Program.cs
  • Dentizone.Application/Services/Authentication/AuthService.cs
✅ Files skipped from review due to trivial changes (2)
  • Dentizone.Application/AutoMapper/Payments/WalletProfile.cs
  • Dentizone.Application/Services/UserService.cs
🚧 Files skipped from review as they are similar to previous changes (7)
  • Dentizone.Application/AutoMapper/Review/ReviewProfile.cs
  • Dentizone.Application/DTOs/Review/UpdateReviewDTO.cs
  • Dentizone.Application/DTOs/Review/ReviewDTO.cs
  • Dentizone.Application/DTOs/Review/CreateReviewDTO.cs
  • Dentizone.Presentaion/Controllers/ReviewController.cs
  • Dentizone.Application/Interfaces/Review/IReviewService.cs
  • Dentizone.Application/Services/ReviewService.cs
🧰 Additional context used
🧠 Learnings (2)
Dentizone.Application/Services/Payment/WalletService.cs (1)
Learnt from: gitnasr
PR: dentizone/api#16
File: Dentizone.Infrastructure/Persistence/Configurations/OrderConfiguration.cs:1-1
Timestamp: 2025-05-28T11:22:49.051Z
Learning: In the Dentizone.Infrastructure project, the IsDeleted property from IBaseEntity is handled through Entity Framework interceptors rather than explicit configuration in individual entity configuration files. This means entity configurations don't need to explicitly configure the IsDeleted property.
Dentizone.Domain/Interfaces/Repositories/IReviewRepository.cs (1)
Learnt from: gitnasr
PR: dentizone/api#16
File: Dentizone.Infrastructure/Persistence/Configurations/OrderConfiguration.cs:1-1
Timestamp: 2025-05-28T11:22:49.051Z
Learning: In the Dentizone.Infrastructure project, the IsDeleted property from IBaseEntity is handled through Entity Framework interceptors rather than explicit configuration in individual entity configuration files. This means entity configurations don't need to explicitly configure the IsDeleted property.
🧬 Code Graph Analysis (2)
Dentizone.Application/Services/Payment/WalletService.cs (1)
Dentizone.Infrastructure/AppDbContext.cs (1)
  • AppDbContext (9-50)
Dentizone.Domain/Interfaces/Repositories/IReviewRepository.cs (1)
Dentizone.Domain/Entity/Review.cs (1)
  • Review (5-17)
🔇 Additional comments (6)
Dentizone.Application/Services/Payment/WalletService.cs (2)

29-32: LGTM! Improved constructor readability.

The multi-line constructor parameter formatting significantly improves readability when dealing with multiple dependencies.


63-63: LGTM! Better code organization.

The blank line addition effectively separates the argument validation logic from the main method implementation, improving code readability.

Dentizone.Domain/Interfaces/Repositories/IReviewRepository.cs (2)

1-1: LGTM: Required using statement added.

The System.Linq.Expressions using statement is correctly added to support the Expression<Func<Review, bool>> parameter type.


10-10: LGTM: Method signature follows repository patterns.

The FindAllBy method signature is well-designed, providing a flexible querying mechanism that returns IQueryable<Review> for deferred execution and further query composition.

Dentizone.Infrastructure/Repositories/ReviewRepository.cs (2)

13-13: LGTM: Formatting improvement.

The line formatting enhances readability without changing the logic.


25-25: LGTM: Formatting improvement.

The parameter formatting enhances readability without changing the logic.

Comment on lines +58 to +62
public IQueryable<Review> FindAllBy(Expression<Func<Review, bool>> condition)
{
return dbContext.Reviews
.Where(condition).AsQueryable();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Remove redundant .AsQueryable() call and consider soft delete consistency.

The implementation has two issues:

  1. The .AsQueryable() call is redundant since .Where() on IQueryable already returns IQueryable<T>.
  2. Unlike GetByIdAsync which filters !r.IsDeleted, this method doesn't handle soft deletes, potentially returning deleted reviews.

Apply this diff to fix the redundant call:

 public IQueryable<Review> FindAllBy(Expression<Func<Review, bool>> condition)
 {
     return dbContext.Reviews
-        .Where(condition).AsQueryable();
+        .Where(condition);
 }

Verify if soft delete filtering should be handled consistently across repository methods:


🏁 Script executed:

#!/bin/bash
# Description: Check soft delete handling patterns in other repository methods
# Expected: Determine if FindAllBy should filter IsDeleted like GetByIdAsync

# Search for IsDeleted usage in repository methods
rg -A 3 -B 3 "IsDeleted" --type cs

# Search for similar FindAllBy patterns in other repositories
rg -A 5 "FindAllBy.*Expression" --type cs

Length of output: 107086


Remove redundant .AsQueryable() in FindAllBy

In Dentizone.Infrastructure/Repositories/ReviewRepository.cs, simplify the method to:

 public IQueryable<Review> FindAllBy(Expression<Func<Review, bool>> condition)
 {
-    return dbContext.Reviews
-        .Where(condition).AsQueryable();
+    return dbContext.Reviews
+        .Where(condition);
 }

• No additional soft-delete filter is needed here: this predicate-based method relies on callers—including ReviewService.GetUserReviewsTaken—to pass in !r.IsDeleted when they only want non-deleted records.
• Soft-delete consistency is already enforced via the condition parameter across other FindAllBy implementations.

🤖 Prompt for AI Agents
In Dentizone.Infrastructure/Repositories/ReviewRepository.cs around lines 58 to
62, remove the redundant .AsQueryable() call in the FindAllBy method since Where
already returns IQueryable. Keep the method returning
dbContext.Reviews.Where(condition) directly without adding any soft-delete
filter, as the condition parameter handles that filtering externally.

@gitnasr gitnasr self-requested a review June 28, 2025 08:30
gitnasr added 2 commits June 28, 2025 11:35
Updated the `ReviewDtoValidation` class to add new validation rules for the `Comment` property. The rules ensure that the comment is not empty, cannot be null (with a specific error message), and does not exceed 500 characters. These improvements strengthen the validation logic for the `ReviewDto` class.
Updated `ReviewController.cs` to include the `Authorize` attribute, ensuring only authenticated users can access endpoints. Modified `CreateOrderReview` to retrieve the user ID from claims instead of the request body, enhancing security. Updated `GetUserReviews` to eliminate the `userId` parameter, simplifying the API. Cleaned up unused `using` directives for better code organization.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (6)
Dentizone.Presentaion/Controllers/ReviewController.cs (4)

21-28: Critical issues remain unaddressed from previous reviews.

The CreateOrderReview method still lacks essential validation and error handling despite previous feedback:

  1. Missing null check for userId from claims - User.FindFirstValue(ClaimTypes.NameIdentifier) can return null
  2. No input validation for createReviewDto - could be null or contain invalid data
  3. No error handling - service exceptions will propagate as 500 errors without meaningful messages

Apply this fix to address the remaining issues:

[HttpPost]
public async Task<IActionResult> CreateOrderReview([FromBody] CreateReviewDto createReviewDto)
{
+    if (createReviewDto == null)
+        return BadRequest("Review data is required.");
+        
    var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
+    if (string.IsNullOrEmpty(userId))
+        return Unauthorized("User not authenticated.");

+    try
+    {
        await _reviewService.CreateOrderReviewAsync(userId, createReviewDto);
-        return Ok();
+        return Ok(new { Message = "Review created successfully" });
+    }
+    catch (Exception ex)
+    {
+        return StatusCode(500, new { Message = "An error occurred while creating the review", Error = ex.Message });
+    }
}

30-35: Previous validation and error handling feedback not implemented.

The UpdateReview method still lacks the input validation and error handling suggested in previous reviews.

Apply the previously suggested fix:

[HttpPut("{reviewId}")]
public async Task<IActionResult> UpdateReview(string reviewId, [FromBody] UpdateReviewDto updateReviewDto)
{
+    if (string.IsNullOrEmpty(reviewId))
+        return BadRequest("ReviewId is required.");
+        
+    if (updateReviewDto == null)
+        return BadRequest("Review data is required.");

+    try
+    {
        await _reviewService.UpdateReviewAsync(reviewId, updateReviewDto);
-        return Ok();
+        return Ok(new { Message = "Review updated successfully" });
+    }
+    catch (KeyNotFoundException)
+    {
+        return NotFound(new { Message = "Review not found" });
+    }
+    catch (Exception ex)
+    {
+        return StatusCode(500, new { Message = "An error occurred while updating the review", Error = ex.Message });
+    }
}

37-42: DeleteReview method still missing previously recommended improvements.

The method lacks the input validation and error handling that was suggested in earlier reviews.

Implement the previously suggested fix:

[HttpDelete("{reviewId}")]
public async Task<IActionResult> DeleteReview(string reviewId)
{
+    if (string.IsNullOrEmpty(reviewId))
+        return BadRequest("ReviewId is required.");

+    try
+    {
        await _reviewService.DeleteReviewAsync(reviewId);
-        return Ok();
+        return Ok(new { Message = "Review deleted successfully" });
+    }
+    catch (KeyNotFoundException)
+    {
+        return NotFound(new { Message = "Review not found" });
+    }
+    catch (Exception ex)
+    {
+        return StatusCode(500, new { Message = "An error occurred while deleting the review", Error = ex.Message });
+    }
}

44-51: GetUserReviews method needs authentication validation and error handling.

While the method correctly uses claims-based authentication (an improvement from previous versions), it still lacks proper validation and error handling.

Add the missing validation and error handling:

[HttpGet]
public async Task<IActionResult> GetUserReviews()
{
    var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
+    if (string.IsNullOrEmpty(userId))
+        return Unauthorized("User not authenticated.");

+    try
+    {
        var reviews = await _reviewService.GetUserReviewsTaken(userId);
        return Ok(reviews);
+    }
+    catch (Exception ex)
+    {
+        return StatusCode(500, new { Message = "An error occurred while retrieving reviews", Error = ex.Message });
+    }
}
Dentizone.Application/DTOs/Review/ReviewDTO.cs (2)

5-9: Resolve type and property inconsistencies with the domain entity.

The DTO still has inconsistencies with the domain entity Review from Dentizone.Domain/Entity/Review.cs:

  1. Type mismatch: Domain has Stars as int, DTO declares it as decimal
  2. Property naming: Domain uses Text, DTO uses Comment
  3. Nullability: Domain has Text as string?, DTO has Comment as string

Apply this diff to align with the domain entity:

 public class ReviewDto
 {
-    public string Comment { get; set; }
-    public decimal Stars { get; set; }
+    public string? Text { get; set; }
+    public int Stars { get; set; }
 }

15-18: Remove redundant validation and add missing empty string check.

The validation has issues:

  1. NotNull() is redundant for non-nullable string
  2. Missing NotEmpty() validation allows empty strings

Apply this diff to fix the validation:

 RuleFor(x => x.Comment)
+    .NotEmpty().WithMessage("Comment cannot be empty.")
-    .NotNull().WithMessage("Comment cannot be null.")
     .MaximumLength(500).WithMessage("Comment must not exceed 500 characters.");

Note: If you align the DTO with the domain entity as suggested above, update the validation accordingly:

-RuleFor(x => x.Comment)
-    .NotNull().WithMessage("Comment cannot be null.")
-    .MaximumLength(500).WithMessage("Comment must not exceed 500 characters.");
+RuleFor(x => x.Text)
+    .MaximumLength(500).WithMessage("Text must not exceed 500 characters.");
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 42e8f67 and c261a64.

📒 Files selected for processing (2)
  • Dentizone.Application/DTOs/Review/ReviewDTO.cs (1 hunks)
  • Dentizone.Presentaion/Controllers/ReviewController.cs (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
Dentizone.Application/DTOs/Review/ReviewDTO.cs (1)
Dentizone.Domain/Entity/Review.cs (1)
  • Review (5-17)
Dentizone.Presentaion/Controllers/ReviewController.cs (5)
Dentizone.Domain/Entity/Review.cs (1)
  • Review (5-17)
Dentizone.Application/Interfaces/Review/IReviewService.cs (4)
  • Task (7-7)
  • Task (8-8)
  • Task (9-9)
  • Task (10-10)
Dentizone.Application/Services/ReviewService.cs (4)
  • Task (13-17)
  • Task (19-22)
  • Task (24-30)
  • Task (32-41)
Dentizone.Application/DTOs/Review/CreateReviewDTO.cs (1)
  • CreateReviewDto (5-10)
Dentizone.Application/DTOs/Review/UpdateReviewDTO.cs (1)
  • UpdateReviewDto (5-8)
🔇 Additional comments (1)
Dentizone.Presentaion/Controllers/ReviewController.cs (1)

9-11: Good security practices implemented.

The controller properly uses [Authorize] attribute and JWT claims for user identification, which is a secure approach for API authentication.

gitnasr added 4 commits June 28, 2025 12:03
- Updated `CreateReviewDto` to change `OrderItemId` to `OrderId` and adjusted validation rules accordingly.
- Refactored `AddToBalance` method in `WalletService.cs` for improved clarity and error handling, removing unnecessary transaction management.
- Modified `ReviewController` to use constructor injection directly, simplifying the code and enhancing readability.
Updated the CreateOrderReviewAsync method in the ReviewService class to instantiate the Review object directly, setting its properties from createReviewDto and userId. This change enhances clarity and control over the Review object creation process.
Updated `IReviewService` and `ReviewService` to replace
`GetUserReviewsTaken` with `GetSubmittedReviews` for
consistency in terminology. Added "ADMIN ONLY" comments
to HTTP PUT and DELETE methods in `ReviewController`,
and renamed `GetUserReviews` to `GetSubmittedReviews`
to align with service changes.
- Added `GetReviewedOrdersByUserId` method in `IOrderService` to retrieve reviewed orders by user.
- Introduced `GetReceivedReviews` method in `IReviewService` for fetching received reviews.
- Implemented `GetReviewedOrdersByUserId` in `OrderService`.
- Corrected syntax in `CancelOrderAsync` method and improved email notifications.
- Modified `GetAllAsync` in `IOrderRepository` to accept nullable `page` parameter.
- Removed `ReviewUx` property from `Order` entity.
- Updated `ReviewService` to include `IOrderService` and implement `GetReceivedReviews`.
- Improved pagination and filtering in `OrderRepository`.
- Added endpoint in `ReviewController` for retrieving received reviews.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🔭 Outside diff range comments (1)
Dentizone.Infrastructure/Repositories/OrderRepository.cs (1)

64-92: Fix multiple issues in GetAllAsync method.

The method has several critical issues:

  1. Incorrect TotalCount calculation: TotalCount is calculated on the paginated query instead of the full dataset
  2. Double filter application: Filter is applied both in BuildPagedQuery and explicitly at line 82
  3. Performance issue: Includes are added after pagination logic, but they should be added to the final query
 public async Task<PagedResult<Order>> GetAllAsync(int? page, Expression<Func<Order, bool>> filter)
 {
     var query = dbContext.Orders.AsQueryable();
+    
+    // Apply filter first for correct total count
+    query = query.Where(filter);
+    var totalCount = await query.CountAsync();
+    
+    // Apply pagination if requested
     if (page is not null)
     {
-        query = BuildPagedQuery(page.Value, filter, query);
+        query = BuildPagedQuery(page.Value, null, query);
     }

-    var totalCount = await query.CountAsync();
-
+    // Add includes to the final query
     query = query.Include(o => o.Buyer)
         .Include(o => o.OrderItems)
         .ThenInclude(p => p.Post)
         .Include(o => o.ShipInfo)
         .Include(o => o.OrderStatuses)
         .Include(o => o.Review);

-    query = query.Where(filter);

     return new PagedResult<Order>
     {
         Items = await query.AsNoTracking().ToListAsync(),
         Page = page ?? 1,
         PageSize = DefaultPageSize,
         TotalCount = totalCount
     };
 }
♻️ Duplicate comments (5)
Dentizone.Presentaion/Controllers/ReviewController.cs (5)

14-21: Add null checks and error handling for user authentication.

The method lacks validation for the extracted user ID and error handling around the service call.

[HttpPost]
public async Task<IActionResult> CreateOrderReview([FromBody] CreateReviewDto createReviewDto)
{
    var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
+   if (string.IsNullOrEmpty(userId))
+       return Unauthorized("User not authenticated.");
+
+   try
+   {
        await reviewService.CreateOrderReviewAsync(userId, createReviewDto);
-       return Ok();
+       return Ok(new { Message = "Review created successfully" });
+   }
+   catch (Exception ex)
+   {
+       return StatusCode(500, new { Message = "An error occurred while creating the review", Error = ex.Message });
+   }
}

37-44: Add user authentication validation and error handling.

The method needs validation for the extracted user ID and proper error handling.

[HttpGet]
public async Task<IActionResult> GetSubmittedReviews()
{
    var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
+   if (string.IsNullOrEmpty(userId))
+       return Unauthorized("User not authenticated.");

+   try
+   {
        var reviews = await reviewService.GetSubmittedReviews(userId);
        return Ok(reviews);
+   }
+   catch (Exception ex)
+   {
+       return StatusCode(500, new { Message = "An error occurred while retrieving reviews", Error = ex.Message });
+   }
}

46-51: Add user authentication validation and error handling.

Consistent with other methods, this endpoint needs user validation and error handling.

[HttpGet("received-review")]
public async Task<IActionResult> GetReceivedReviews()
{
+   var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
+   if (string.IsNullOrEmpty(userId))
+       return Unauthorized("User not authenticated.");
+
+   try
+   {
-       var reviews = await reviewService.GetReceivedReviews(User.FindFirstValue(ClaimTypes.NameIdentifier));
+       var reviews = await reviewService.GetReceivedReviews(userId);
        return Ok(reviews);
+   }
+   catch (Exception ex)
+   {
+       return StatusCode(500, new { Message = "An error occurred while retrieving reviews", Error = ex.Message });
+   }
}

23-28: Implement admin authorization and add comprehensive error handling.

The method is marked as "ADMIN ONLY" but lacks proper authorization enforcement, and it needs input validation and error handling.

-[HttpPut("{reviewId}")] // ADMIN ONLY
+[HttpPut("{reviewId}")]
+[Authorize(Roles = "Admin")]
public async Task<IActionResult> UpdateReview(string reviewId, [FromBody] UpdateReviewDto updateReviewDto)
{
+   if (string.IsNullOrEmpty(reviewId))
+       return BadRequest("ReviewId is required.");
+
+   try
+   {
        await reviewService.UpdateReviewAsync(reviewId, updateReviewDto);
-       return Ok();
+       return Ok(new { Message = "Review updated successfully" });
+   }
+   catch (KeyNotFoundException)
+   {
+       return NotFound(new { Message = "Review not found" });
+   }
+   catch (Exception ex)
+   {
+       return StatusCode(500, new { Message = "An error occurred while updating the review", Error = ex.Message });
+   }
}

30-35: Implement admin authorization and add comprehensive error handling.

Similar to the update method, this endpoint needs proper admin authorization and error handling.

-[HttpDelete("{reviewId}")] // ADMIN ONLY
+[HttpDelete("{reviewId}")]
+[Authorize(Roles = "Admin")]
public async Task<IActionResult> DeleteReview(string reviewId)
{
+   if (string.IsNullOrEmpty(reviewId))
+       return BadRequest("ReviewId is required.");
+
+   try
+   {
        await reviewService.DeleteReviewAsync(reviewId);
-       return Ok();
+       return Ok(new { Message = "Review deleted successfully" });
+   }
+   catch (KeyNotFoundException)
+   {
+       return NotFound(new { Message = "Review not found" });
+   }
+   catch (Exception ex)
+   {
+       return StatusCode(500, new { Message = "An error occurred while deleting the review", Error = ex.Message });
+   }
}
🧹 Nitpick comments (2)
Dentizone.Domain/Interfaces/Repositories/IOrderRepository.cs (1)

11-11: Document the behavior when page parameter is null.

Making the page parameter nullable provides good flexibility for conditional pagination. However, consider documenting the expected behavior when page is null, especially since the return type is still PagedResult<Order>.

Questions to clarify:

  • When page is null, what values should be set for Page, PageSize, and TotalPages properties in the returned PagedResult<Order>?
  • Should PageSize have a default value or remain 0?
  • How should consumers interpret pagination metadata when no pagination is applied?

Consider adding XML documentation to clarify the behavior:

+    /// <summary>
+    /// Gets all orders based on the provided filter with optional pagination.
+    /// </summary>
+    /// <param name="page">The page number for pagination. If null, returns all matching results without pagination.</param>
+    /// <param name="filter">The filter expression to apply to orders.</param>
+    /// <returns>A paged result containing the filtered orders and pagination metadata.</returns>
     Task<PagedResult<Order>> GetAllAsync(int? page, Expression<Func<Order, bool>> filter);
Dentizone.Application/Interfaces/Review/IReviewService.cs (1)

7-7: Consider consistent method naming.

The method CreateOrderReviewAsync specifically mentions "Order" while other methods don't. Since all reviews appear to be order-related based on the entity structure, consider either:

  1. Removing "Order" for consistency: CreateReviewAsync
  2. Adding "Order" to other methods for clarity
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c261a64 and 615d1d3.

📒 Files selected for processing (11)
  • Dentizone.Application/DTOs/Review/CreateReviewDTO.cs (1 hunks)
  • Dentizone.Application/Interfaces/Order/IOrderService.cs (1 hunks)
  • Dentizone.Application/Interfaces/Review/IReviewService.cs (1 hunks)
  • Dentizone.Application/Services/OrderService.cs (5 hunks)
  • Dentizone.Application/Services/Payment/WalletService.cs (2 hunks)
  • Dentizone.Application/Services/ReviewService.cs (1 hunks)
  • Dentizone.Domain/Entity/Order.cs (0 hunks)
  • Dentizone.Domain/Interfaces/Repositories/IOrderRepository.cs (1 hunks)
  • Dentizone.Infrastructure/Persistence/Configurations/ReviewUxConfiguration.cs (0 hunks)
  • Dentizone.Infrastructure/Repositories/OrderRepository.cs (5 hunks)
  • Dentizone.Presentaion/Controllers/ReviewController.cs (1 hunks)
💤 Files with no reviewable changes (2)
  • Dentizone.Domain/Entity/Order.cs
  • Dentizone.Infrastructure/Persistence/Configurations/ReviewUxConfiguration.cs
🚧 Files skipped from review as they are similar to previous changes (3)
  • Dentizone.Application/Services/Payment/WalletService.cs
  • Dentizone.Application/DTOs/Review/CreateReviewDTO.cs
  • Dentizone.Application/Services/ReviewService.cs
🧰 Additional context used
🧬 Code Graph Analysis (5)
Dentizone.Application/Interfaces/Order/IOrderService.cs (1)
Dentizone.Domain/Entity/Order.cs (1)
  • Order (5-24)
Dentizone.Domain/Interfaces/Repositories/IOrderRepository.cs (1)
Dentizone.Domain/Interfaces/PagedResult.cs (1)
  • PagedResult (3-10)
Dentizone.Application/Interfaces/Review/IReviewService.cs (4)
Dentizone.Domain/Entity/Review.cs (1)
  • Review (5-17)
Dentizone.Application/DTOs/Review/CreateReviewDTO.cs (1)
  • CreateReviewDto (5-10)
Dentizone.Application/DTOs/Review/UpdateReviewDTO.cs (1)
  • UpdateReviewDto (5-8)
Dentizone.Application/DTOs/Review/ReviewDTO.cs (1)
  • ReviewDto (5-9)
Dentizone.Infrastructure/Repositories/OrderRepository.cs (4)
Dentizone.Domain/Entity/Order.cs (1)
  • Order (5-24)
Dentizone.Infrastructure/Repositories/AbstractRepository.cs (1)
  • CalculatePagination (11-19)
Dentizone.Domain/Interfaces/PagedResult.cs (1)
  • PagedResult (3-10)
Dentizone.Domain/Entity/Review.cs (1)
  • Review (5-17)
Dentizone.Presentaion/Controllers/ReviewController.cs (5)
Dentizone.Domain/Entity/Review.cs (1)
  • Review (5-17)
Dentizone.Application/Interfaces/Review/IReviewService.cs (5)
  • Task (7-7)
  • Task (8-8)
  • Task (9-9)
  • Task (10-10)
  • Task (11-11)
Dentizone.Application/Services/ReviewService.cs (5)
  • Task (14-24)
  • Task (26-29)
  • Task (31-37)
  • Task (39-48)
  • Task (50-63)
Dentizone.Application/DTOs/Review/CreateReviewDTO.cs (1)
  • CreateReviewDto (5-10)
Dentizone.Application/DTOs/Review/UpdateReviewDTO.cs (1)
  • UpdateReviewDto (5-8)
🔇 Additional comments (3)
Dentizone.Application/Interfaces/Review/IReviewService.cs (1)

1-1: LGTM!

The using statement correctly imports the required DTOs namespace.

Dentizone.Infrastructure/Repositories/OrderRepository.cs (1)

14-14: LGTM: Formatting and performance improvements.

The formatting improvements and addition of AsNoTracking() calls enhance code readability and query performance. The inclusion of the Review navigation property aligns with the PR's review functionality requirements.

Also applies to: 32-32, 76-80, 98-119, 131-133

Dentizone.Application/Services/OrderService.cs (1)

36-36: LGTM: Code formatting improvements.

The formatting improvements enhance code readability and maintain consistent style throughout the codebase. The string interpolation adjustments are particularly good for maintainability.

Also applies to: 82-82, 102-102, 157-157, 265-267

{
public interface IReviewService
{
Task CreateOrderReviewAsync(string userId, CreateReviewDto createReviewDto);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider returning the created review or review ID.

The method currently returns Task which provides no information about the created review. Consider returning Task<ReviewDto> or Task<string> to provide the created review details or ID for further operations.

-        Task CreateOrderReviewAsync(string userId, CreateReviewDto createReviewDto);
+        Task<ReviewDto> CreateOrderReviewAsync(string userId, CreateReviewDto createReviewDto);
📝 Committable suggestion

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

Suggested change
Task CreateOrderReviewAsync(string userId, CreateReviewDto createReviewDto);
Task<ReviewDto> CreateOrderReviewAsync(string userId, CreateReviewDto createReviewDto);
🤖 Prompt for AI Agents
In Dentizone.Application/Interfaces/Review/IReviewService.cs at line 7, the
CreateOrderReviewAsync method returns Task without any result, which does not
provide information about the created review. Modify the method signature to
return Task<ReviewDto> or Task<string> to return the created review details or
its ID, enabling callers to access the created review information for further
processing.

💡 Verification agent

🧩 Analysis chain

Verify data type consistency between DTOs and entity.

There's a data type mismatch: CreateReviewDto.Stars is decimal while the Review entity's Stars property is int. This could cause mapping or validation issues.


🏁 Script executed:

#!/bin/bash
# Description: Check for data type consistency between DTOs and entity
echo "Checking Stars property types across DTOs and entity..."

echo "CreateReviewDto Stars type:"
rg -A 1 "Stars.*{.*set" --type cs | grep -A 1 "CreateReviewDto" 

echo "Review entity Stars type:"
rg -A 1 "Stars.*{.*set" --type cs | grep -A 1 "Review.*:"

echo "UpdateReviewDto (checking if it has Stars):"
rg -A 1 "Stars.*{.*set" --type cs | grep -A 1 "UpdateReviewDto"

Length of output: 843


🏁 Script executed:

#!/bin/bash
set -e

echo "=== Locating CreateReviewDto ==="
dto_file=$(rg -l "class CreateReviewDto" --type cs)
echo "File: $dto_file"
echo "CreateReviewDto Stars property:"
rg -n "public .* Stars " "$dto_file" || echo "No Stars property found in CreateReviewDto"

echo
echo "=== Locating Review entity ==="
entity_file=$(rg -l "class Review" --type cs | grep -v "Dto")
echo "File: $entity_file"
echo "Review entity Stars property:"
rg -n "public .* Stars " "$entity_file" || echo "No Stars property found in Review entity"

echo
echo "=== Locating UpdateReviewDto ==="
update_file=$(rg -l "class UpdateReviewDto" --type cs)
echo "File: $update_file"
echo "UpdateReviewDto Stars property:"
rg -n "public .* Stars " "$update_file" || echo "No Stars property found in UpdateReviewDto"

Length of output: 4207


🏁 Script executed:

#!/bin/bash
set -e

echo "=== Locating Review entity ==="
entity_file=$(rg -l "class Review" --type cs | grep -i "Domain/Entity/Review\.cs$")
echo "Review entity file: $entity_file"
echo "Stars property in Review entity:"
rg -n "public .*Stars" "$entity_file" || echo "No Stars property found"

echo
echo "=== Locating ReviewDTO ==="
dto_file=$(rg -l "class ReviewDTO" --type cs)
echo "ReviewDTO file: $dto_file"
echo "Stars property in ReviewDTO:"
rg -n "public .*Stars" "$dto_file" || echo "No Stars property found"

echo
echo "=== Inspecting Automapper mapping ==="
profile_file=$(rg -l "class ReviewProfile" --type cs)
echo "ReviewProfile file: $profile_file"
echo "Mapping for Stars:"
rg -n "ForMember.*Stars" "$profile_file" || echo "No explicit mapping for Stars found"

Length of output: 612


Ensure Stars type consistency between DTOs and the Review entity

There’s a clear mismatch between the DTO and the domain model:

  • Dentizone.Application/DTOs/Review/CreateReviewDTO.cs
    Line 8:
    public decimal Stars { get; set; }
  • Dentizone.Domain/Entity/Review.cs
    Line 9:
    public int Stars { get; set; }

This discrepancy will break AutoMapper mappings or runtime validation. You should unify the types—either:

  • Change CreateReviewDTO.Stars (and any other DTOs) to int, or
  • Adjust the domain Review.Stars to decimal if fractional ratings are required.

Example diff if switching the DTO to int:

--- Dentizone.Application/DTOs/Review/CreateReviewDTO.cs
@@ Line 8
- public decimal Stars { get; set; }
+ public int Stars     { get; set; }

Also, consider adding a Stars property to UpdateReviewDTO (currently absent) to keep create/update models aligned.

🤖 Prompt for AI Agents
In Dentizone.Application/Interfaces/Review/IReviewService.cs at line 7, ensure
the Stars property type is consistent between the DTOs and the Review entity to
avoid mapping or validation errors. Either change the Stars property in
CreateReviewDTO (and other related DTOs) from decimal to int to match the Review
entity, or update the Review entity's Stars property to decimal if fractional
ratings are needed. Additionally, add a Stars property to UpdateReviewDTO to
keep the create and update models aligned.

Task UpdateReviewAsync(string reviewId, UpdateReviewDto updateReviewDto);
Task DeleteReviewAsync(string reviewId);
Task<IEnumerable<ReviewDto>> GetSubmittedReviews(string userId);
Task<IEnumerable<ReviewDto>> GetReceivedReviews(string userId);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Clarify the business logic for GetReceivedReviews.

The GetReceivedReviews method suggests users can "receive" reviews, but the Review entity appears to link reviews to orders and the users who submit them. Please clarify: does this method return reviews for orders where the user is the provider/recipient of the service being reviewed?


🏁 Script executed:

#!/bin/bash
# Description: Analyze the Review entity relationships and business context
echo "Checking Review entity relationships..."

echo "Review entity structure:"
rg -A 10 "class Review" --type cs

echo "Order entity User relationship:"
rg -A 5 -B 5 "User.*Order\|Order.*User" --type cs

echo "Checking for provider/recipient concepts in Order:"
rg -A 3 -B 3 "Provider\|Recipient\|Doctor\|Patient" --type cs

Length of output: 11002


🏁 Script executed:

#!/bin/bash
# Display the IReviewService interface to confirm method declarations
echo "----- IReviewService Interface -----"
sed -n '1,200p' Dentizone.Application/Interfaces/Review/IReviewService.cs

# Search for any implementation of GetReceivedReviews across the codebase
echo "----- Searching for GetReceivedReviews Usage -----"
rg "GetReceivedReviews" -n --type cs

Length of output: 1367


🏁 Script executed:

#!/bin/bash
# Show the body of GetReceivedReviews in ReviewService
rg -A15 -B5 "GetReceivedReviews" -n Dentizone.Application/Services/ReviewService.cs

Length of output: 719


🏁 Script executed:

#!/bin/bash
# Locate the GetReviewedOrdersByUserId method in the Order service interface
echo "----- IOrderService Interface -----"
sed -n '1,200p' Dentizone.Application/Interfaces/Order/IOrderService.cs | grep -n "GetReviewedOrdersByUserId"

# Show the signature and surrounding context if found
rg -A5 -B5 "GetReviewedOrdersByUserId" -n --type cs Dentizone.Application/Interfaces/Order/IOrderService.cs

# Locate the implementation in the OrderService class
echo "----- OrderService Implementation -----"
rg -A15 -B5 "GetReviewedOrdersByUserId" -n Dentizone.Application/Services/OrderService.cs

Length of output: 1458


Clarify GetReceivedReviews semantics
GetReceivedReviews actually calls orderService.GetReviewedOrdersByUserId, which returns orders where OrderItems.Any(oi => oi.Post.SellerId == userId) and IsReviewed == true. In other words, this method returns the reviews that a user has received as the seller/provider of a post.

Please update the interface and/or implementation to make this explicit:

  • Add or update the XML doc on IReviewService.GetReceivedReviews to state:
    “Retrieves reviews for orders where the specified user is the seller (provider).”
  • (Optional) Consider renaming the method to something like GetReviewsReceivedAsSellerAsync or GetProviderReviewsAsync for clarity.
🤖 Prompt for AI Agents
In Dentizone.Application/Interfaces/Review/IReviewService.cs at line 11, the
method GetReceivedReviews lacks clarity about its semantics. Update the XML
documentation comment for this method to explicitly state that it retrieves
reviews for orders where the specified user is the seller or provider.
Optionally, rename the method to a more descriptive name such as
GetReviewsReceivedAsSellerAsync or GetProviderReviewsAsync to better reflect its
purpose.

public class ReviewController(IReviewService reviewService) : ControllerBase
{
[HttpPost]
public async Task<IActionResult> CreateOrderReview([FromBody] CreateReviewDto createReviewDto)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify data type consistency between DTOs and domain entity.

There's a potential data type mismatch between CreateReviewDto.Stars (decimal) and Review.Stars (int).


🏁 Script executed:

#!/bin/bash
# Description: Check for data type consistency between DTOs and domain entity for Stars property

# Search for Stars property definitions
rg -A 2 -B 2 "Stars.*=" --type cs

Length of output: 403


🏁 Script executed:

#!/bin/bash
# Find CreateReviewDto definition and its Stars property
rg -n "class CreateReviewDto" --type cs
# Show context around the Stars property in CreateReviewDto
rg -A2 -B2 "Stars" $(rg -l "class CreateReviewDto" --type cs)

# Find domain/entity Review class and its Stars property
rg -n "class Review" --type cs
# Show context around the Stars property in Review class
rg -A2 -B2 "Stars" $(rg -l "class Review" --type cs)

Length of output: 5745


🏁 Script executed:

#!/bin/bash
# Inspect AutoMapper profile for CreateReviewDto -> Review mapping
rg -A5 -B5 "CreateReviewDto" Dentizone.Application/AutoMapper/Review/ReviewProfile.cs

# Inspect mapping for ReviewDto -> Review as well
rg -A5 -B5 "ReviewDto" Dentizone.Application/AutoMapper/Review/ReviewProfile.cs

Length of output: 1099


Align Stars data types across DTOs and domain entity

There’s a mismatch between your DTOs and the domain entity:

  • Dentizone.Application/DTOs/Review/CreateReviewDTO.cs
    public decimal Stars { get; set; }
  • Dentizone.Application/DTOs/Review/ReviewDTO.cs
    public decimal Stars { get; set; }
  • Dentizone.Domain/Entity/Review.cs
    public int Stars { get; set; }

This inconsistency will force AutoMapper to perform narrowing conversions (decimal→int), potentially causing rounding or runtime errors.

Please update one of the following to restore type consistency:

  • Change the DTOs’ Stars properties to int (and adjust your FluentValidation rules accordingly);
  • Or change the domain entity’s Stars to decimal if fractional ratings are required.

Files to update:

  • Dentizone.Application/DTOs/Review/CreateReviewDTO.cs
  • Dentizone.Application/DTOs/Review/ReviewDTO.cs
  • (Optional) Dentizone.Domain/Entity/Review.cs if you opt for decimal there
🤖 Prompt for AI Agents
In Dentizone.Presentaion/Controllers/ReviewController.cs at line 15, the Stars
property types are inconsistent between DTOs and the domain entity, causing
potential AutoMapper conversion issues. To fix this, update the Stars properties
in CreateReviewDTO.cs and ReviewDTO.cs to int if fractional ratings are not
needed, and adjust any validation rules accordingly; alternatively, change the
Stars property in the domain entity Review.cs to decimal if fractional ratings
are required, ensuring all three files use the same type.

Task CompleteOrder(string orderId);
Task<PagedResultDto<OrderViewDto>> GetOrders(int page, FilterOrderDto filters);

Task<IEnumerable<Domain.Entity.Order>> GetReviewedOrdersByUserId(string userId);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider returning DTOs for consistency.

The new method returns domain entities (Domain.Entity.Order) directly, which breaks the typical pattern used by other methods in this interface that return DTOs. For consistency and to maintain proper separation of concerns, consider returning IEnumerable<OrderViewDto> instead.

-Task<IEnumerable<Domain.Entity.Order>> GetReviewedOrdersByUserId(string userId);
+Task<IEnumerable<OrderViewDto>> GetReviewedOrdersByUserId(string userId);
📝 Committable suggestion

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

Suggested change
Task<IEnumerable<Domain.Entity.Order>> GetReviewedOrdersByUserId(string userId);
Task<IEnumerable<OrderViewDto>> GetReviewedOrdersByUserId(string userId);
🤖 Prompt for AI Agents
In Dentizone.Application/Interfaces/Order/IOrderService.cs at line 15, the
method GetReviewedOrdersByUserId currently returns domain entities
(Domain.Entity.Order), which is inconsistent with other methods that return
DTOs. Change the return type to IEnumerable<OrderViewDto> to maintain
consistency and proper separation of concerns in the interface.

Comment on lines +272 to +279
public async Task<IEnumerable<Order>> GetReviewedOrdersByUserId(string userId)
{
var orders = await orderRepository.GetAllAsync(
null,
o => o.IsReviewed && o.OrderItems.Any(oi => oi.Post.SellerId == userId)
);
return orders.Items;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve method implementation and add validation.

The method has several areas for improvement:

  1. Parameter validation: No null/empty check for userId
  2. Potential N+1 queries: The filter expression could cause performance issues with nested navigation properties
  3. Missing error handling: No exception handling for database operations
 public async Task<IEnumerable<Order>> GetReviewedOrdersByUserId(string userId)
 {
+    if (string.IsNullOrWhiteSpace(userId))
+    {
+        throw new ArgumentException("User ID cannot be null or empty.", nameof(userId));
+    }
+
+    try
+    {
         var orders = await orderRepository.GetAllAsync(
             null,
             o => o.IsReviewed && o.OrderItems.Any(oi => oi.Post.SellerId == userId)
         );
         return orders.Items;
+    }
+    catch (Exception ex)
+    {
+        // Log the exception and rethrow or handle appropriately
+        throw new ApplicationException($"Failed to retrieve reviewed orders for user {userId}", ex);
+    }
 }
📝 Committable suggestion

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

Suggested change
public async Task<IEnumerable<Order>> GetReviewedOrdersByUserId(string userId)
{
var orders = await orderRepository.GetAllAsync(
null,
o => o.IsReviewed && o.OrderItems.Any(oi => oi.Post.SellerId == userId)
);
return orders.Items;
}
public async Task<IEnumerable<Order>> GetReviewedOrdersByUserId(string userId)
{
if (string.IsNullOrWhiteSpace(userId))
{
throw new ArgumentException("User ID cannot be null or empty.", nameof(userId));
}
try
{
var orders = await orderRepository.GetAllAsync(
null,
o => o.IsReviewed && o.OrderItems.Any(oi => oi.Post.SellerId == userId)
);
return orders.Items;
}
catch (Exception ex)
{
// Log the exception and rethrow or handle appropriately
throw new ApplicationException($"Failed to retrieve reviewed orders for user {userId}", ex);
}
}
🤖 Prompt for AI Agents
In Dentizone.Application/Services/OrderService.cs around lines 272 to 279,
improve the GetReviewedOrdersByUserId method by first validating that the userId
parameter is not null or empty and throwing an appropriate exception if it is.
Refactor the query to avoid potential N+1 issues by including necessary related
entities eagerly or restructuring the query to optimize database access. Add
try-catch blocks around the database call to handle exceptions gracefully and
log or rethrow them as needed.

gitnasr added 4 commits June 28, 2025 12:59
The `ReviewUxConfiguration` class has been completely removed, including all associated using directives and configuration methods for the `ReviewUx` entity. This change eliminates the setup for entity properties such as keys, required fields, default values, and relationships with other entities.
The `ReviewUx` class has been completely removed from the `ReviewUX.cs` file, along with its properties and the associated using directives for `Dentizone.Domain.Enums` and `Dentizone.Domain.Interfaces`. This change eliminates the class definition and its functionality from the codebase.
Updated `UpdateReviewAsync` and `DeleteReviewAsync` methods in `IReviewService.cs` to return `Task<bool>` for success indication.

Modified query logic in `OrderRepository.cs` to ensure proper ordering and pagination, including a new filter condition for improved result handling.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (3)
Dentizone.Application/DTOs/Review/ReviewDTO.cs (2)

7-7: Property naming inconsistency with domain entity persists.

The DTO uses Comment while the domain entity uses Text. This inconsistency was previously flagged and remains unresolved.


17-17: Remove redundant null validation.

The NotNull() validation is redundant since Comment is declared as a non-nullable string. This was previously identified but not yet addressed.

Dentizone.Application/DTOs/Review/UpdateReviewDTO.cs (1)

5-9: Consider making the DTO immutable and fix property nullability.

The DTO has several design concerns:

  1. The Comment property should be nullable to match the domain entity's Text property which is string?
  2. The mutable properties without clear requirement for mutability can lead to unexpected state changes

Apply this diff to address both concerns:

-public class UpdateReviewDto
-{
-    public string Comment { get; set; }
-    public int Stars { get; set; }
-}
+public class UpdateReviewDto
+{
+    public UpdateReviewDto(string? comment, int stars)
+    {
+        Comment = comment;
+        Stars = stars;
+    }
+
+    public string? Comment { get; }
+    public int Stars { get; }
+}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 615d1d3 and 5c754b0.

📒 Files selected for processing (7)
  • Dentizone.Application/DTOs/Review/CreateReviewDTO.cs (1 hunks)
  • Dentizone.Application/DTOs/Review/ReviewDTO.cs (1 hunks)
  • Dentizone.Application/DTOs/Review/UpdateReviewDTO.cs (1 hunks)
  • Dentizone.Application/Interfaces/Review/IReviewService.cs (1 hunks)
  • Dentizone.Domain/Entity/ReviewUX.cs (0 hunks)
  • Dentizone.Infrastructure/Persistence/Configurations/ReviewUxConfiguration.cs (0 hunks)
  • Dentizone.Infrastructure/Repositories/OrderRepository.cs (5 hunks)
💤 Files with no reviewable changes (2)
  • Dentizone.Domain/Entity/ReviewUX.cs
  • Dentizone.Infrastructure/Persistence/Configurations/ReviewUxConfiguration.cs
🚧 Files skipped from review as they are similar to previous changes (3)
  • Dentizone.Application/Interfaces/Review/IReviewService.cs
  • Dentizone.Application/DTOs/Review/CreateReviewDTO.cs
  • Dentizone.Infrastructure/Repositories/OrderRepository.cs
🧰 Additional context used
🧬 Code Graph Analysis (2)
Dentizone.Application/DTOs/Review/UpdateReviewDTO.cs (1)
Dentizone.Domain/Entity/Review.cs (1)
  • Review (5-17)
Dentizone.Application/DTOs/Review/ReviewDTO.cs (1)
Dentizone.Domain/Entity/Review.cs (1)
  • Review (5-17)
🔇 Additional comments (2)
Dentizone.Application/DTOs/Review/ReviewDTO.cs (2)

8-8: Good fix: Stars type now aligns with domain entity.

The Stars property type has been corrected to int, resolving the previous type mismatch with the domain entity.


16-16: Good addition: Empty string validation implemented.

The NotEmpty() validation addresses the previously missing empty string validation concern.

gitnasr added 3 commits June 28, 2025 13:15
Updated the `Comment` property to be nullable, allowing it to hold null values. Adjusted validation logic to enforce maximum length only when a comment is provided, with a revised error message for clarity.
@sonarqubecloud
Copy link
Copy Markdown

@gitnasr gitnasr merged commit 9af593e into dev Jun 28, 2025
2 of 3 checks passed
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