Skip to content

Refactor service registrations and validation logic#115

Merged
gitnasr merged 2 commits intodevfrom
fix-shipmenet
Jul 4, 2025
Merged

Refactor service registrations and validation logic#115
gitnasr merged 2 commits intodevfrom
fix-shipmenet

Conversation

@gitnasr
Copy link
Copy Markdown
Contributor

@gitnasr gitnasr commented Jul 4, 2025

  • Removed IWalletService, IReviewService, and IWithdrawalService from Services.cs, added IShippingService.
  • Updated ShippingService to eliminate AuthService dependency and streamline email handling.
  • Improved Swagger configuration formatting in SwaggerServiceExtensions.cs.
  • Added ValidateAllDependencies call in Program.cs to ensure all services are registered.
  • Enhanced readability of GetRequiredService for UserManager<ApplicationUser>.
  • Introduced ServicesValidator.cs to validate service registrations at startup.

Summary by CodeRabbit

  • New Features

    • Introduced a new data transfer object for updating shipment status, allowing for more structured input including comments.
    • Added a validation step to ensure all required services are registered, improving application reliability.
  • Improvements

    • Updated the shipment status update endpoint to use a single DTO parameter and changed the HTTP method from PUT to POST.
    • Enhanced email notifications by directly using seller and buyer email addresses.
    • Improved Swagger documentation formatting for better readability.

- Removed `IWalletService`, `IReviewService`, and `IWithdrawalService` from `Services.cs`, added `IShippingService`.
- Updated `ShippingService` to eliminate `AuthService` dependency and streamline email handling.
- Improved Swagger configuration formatting in `SwaggerServiceExtensions.cs`.
- Added `ValidateAllDependencies` call in `Program.cs` to ensure all services are registered.
- Enhanced readability of `GetRequiredService` for `UserManager<ApplicationUser>`.
- Introduced `ServicesValidator.cs` to validate service registrations at startup.
@korbit-ai
Copy link
Copy Markdown

korbit-ai bot commented Jul 4, 2025

You've used up your 5 PR reviews for this month under the Korbit Starter Plan. You'll get 5 more reviews on July 30th, 2025 or you can upgrade to Pro for unlimited PR reviews and enhanced features in your Korbit Console.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jul 4, 2025

Walkthrough

This update introduces a new DTO for shipment status updates, refactors related service and controller methods to use this DTO, adds runtime validation for service registrations, registers the shipping service in the DI container, and makes minor formatting improvements. The shipping status update endpoint now uses a POST method and a consolidated request object.

Changes

File(s) Change Summary
Dentizone.Application/DI/Services.cs Registers IShippingService as a scoped service in the DI container.
Dentizone.Application/DI/ServicesValidator.cs Adds ValidateAllDependencies extension method for runtime DI validation of service interfaces.
Dentizone.Application/DTOs/Shipping/CreateShipmentStatusDto.cs Introduces CreateShipmentStatusDto class with properties for order item ID, new status, and comment.
Dentizone.Application/Interfaces/IShippingService.cs Refactors UpdateItemShipmentStatusAsync to accept CreateShipmentStatusDto instead of multiple params.
Dentizone.Application/Services/ShippingService.cs Updates method to use the new DTO, simplifies email logic, and expands related entity loading.
Dentizone.Presentaion/Controllers/ShippingController.cs Changes endpoint to POST, accepts DTO, and updates service call accordingly.
Dentizone.Presentaion/Extensions/SwaggerServiceExtensions.cs Simplifies JWT security scheme description formatting.
Dentizone.Presentaion/Program.cs Adds service validation call and adjusts formatting in the data seeding section.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Controller as ShippingController
    participant Service as ShippingService
    participant DB as Database

    Client->>Controller: POST /UpdateItemShipmentStatus (CreateShipmentStatusDto)
    Controller->>Service: UpdateItemShipmentStatusAsync(CreateShipmentStatusDto)
    Service->>DB: Load OrderItem (with related entities)
    Service->>DB: Add ShipmentActivity
    Service->>DB: Save changes
    Service->>Client: Send notification emails (seller, buyer)
    Controller->>Client: Return result
Loading

Possibly related PRs

  • Shipping update service #103: Refactored the shipping status update logic, which this PR further extends by introducing a DTO, service validation, and endpoint changes.

Suggested labels

enhancement

Poem

A DTO hops in, with status in tow,
Shipping updates now easier to show!
Services are checked, dependencies tight,
Controllers post changes, all working right.
With emails sent swiftly, the code’s looking neat—
This bunny approves, with a hop and a tweet! 🐇✨

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

Updated IShippingService to use CreateShipmentStatusDto for
shipment status updates. Adjusted ShippingService and
ShippingController to reflect the new method signature and
changed the HTTP method from PUT to POST. Introduced a new
CreateShipmentStatusDto class to encapsulate update data.
Updated namespaces and using directives accordingly.
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Jul 4, 2025

@gitnasr gitnasr requested a review from Copilot July 4, 2025 10:21
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR enhances service registration robustness, refactors the shipping workflow, and tidies Swagger setup.

  • Enforces service registration validation at startup with ValidateAllDependencies.
  • Introduces IShippingService changes: new CreateShipmentStatusDto, streamlined logic, and controller endpoint updated to POST.
  • Cleans up Swagger configuration formatting for better readability.

Reviewed Changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
Dentizone.Presentaion/Program.cs Added ValidateAllDependencies call to enforce all services are registered
Dentizone.Presentaion/Extensions/SwaggerServiceExtensions.cs Reformatted the Swagger Description initializer into a single line
Dentizone.Presentaion/Controllers/ShippingController.cs Changed shipment status endpoint to accept a DTO via POST
Dentizone.Application/Services/ShippingService.cs Removed AuthService dependency, updated method signature and email handling
Dentizone.Application/Interfaces/IShippingService.cs Updated interface to use CreateShipmentStatusDto
Dentizone.Application/DTOs/Shipping/CreateShipmentStatusDto.cs Added new DTO for structured shipment status updates
Dentizone.Application/DI/ServicesValidator.cs Introduced ValidateAllDependencies extension to scan and enforce registrations
Dentizone.Application/DI/Services.cs Registered the new IShippingService implementation
Comments suppressed due to low confidence (7)

Dentizone.Application/DI/ServicesValidator.cs:8

  • [nitpick] Consider adding unit tests for ValidateAllDependencies to verify it correctly detects missing registrations without bringing down the application in test scenarios.
        public static void ValidateAllDependencies(this IServiceCollection services, Assembly[] assembliesToScan)

Dentizone.Presentaion/Controllers/ShippingController.cs:14

  • [nitpick] Switching from PUT to POST for updating shipment status may break existing clients and violate REST semantics; consider using PUT or PATCH since this endpoint updates a resource.
        [HttpPost]

Dentizone.Application/Interfaces/IShippingService.cs:7

  • [nitpick] Public interfaces should include XML documentation to clarify intended usage and parameter behavior for downstream consumers.
    public interface IShippingService

Dentizone.Application/DI/ServicesValidator.cs:11

  • The SelectMany, Where, and Any extension methods require a using System.Linq; directive. Add using System.Linq; at the top to avoid compilation errors.
                .SelectMany(a => a.GetTypes())

Dentizone.Application/Services/ShippingService.cs:8

  • This using directive appears unused in a service class—consider removing it to keep dependencies minimal.
using Microsoft.AspNetCore.Mvc;

Dentizone.Application/Interfaces/IShippingService.cs:3

  • The Microsoft.AspNetCore.Mvc namespace isn't used in the interface—remove this import to clean up unused dependencies.
using Microsoft.AspNetCore.Mvc;

Dentizone.Application/Services/ShippingService.cs:43

  • The subject line starts with a lowercase 'the' and capitalizes 'Status'; consider changing to "The status has been changed to {shipmentStatus.NewStatus}" for correct casing and grammar.
                    $"the Status has been changed to {shipmentStatus.NewStatus}",

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

🧹 Nitpick comments (3)
Dentizone.Application/DTOs/Shipping/CreateShipmentStatusDto.cs (1)

5-10: Consider adding validation attributes for better input validation.

The DTO structure is well-designed, but adding validation attributes would improve input validation and API documentation.

+using System.ComponentModel.DataAnnotations;
+
 namespace Dentizone.Application.DTOs.Shipping
 {
     public class CreateShipmentStatusDto
     {
+        [Required]
+        [RegularExpression(@"^[{(]?[0-9A-Fa-f]{8}[-]?([0-9A-Fa-f]{4}[-]?){3}[0-9A-Fa-f]{12}[)}]?$", ErrorMessage = "OrderItemId must be a valid GUID")]
         public required string OrderItemId { get; set; }
+        
+        [Required]
         public required ShipmentActivityStatus NewStatus { get; set; }
+        
+        [MaxLength(500)]
         public string? Comment { get; set; }
     }
 }
Dentizone.Application/Services/ShippingService.cs (1)

33-38: Consider improving the default comment message.

The fallback comment "No comment provided" might be too generic and could be improved for better user experience.

-                    ActivityDescription = shipmentStatus.Comment ?? "No comment provided",
+                    ActivityDescription = shipmentStatus.Comment ?? $"Status updated to {shipmentStatus.NewStatus}",
Dentizone.Application/DI/ServicesValidator.cs (1)

1-28: Consider adding success feedback for better UX.

The validation provides clear error messages, but consider adding a success message when all services are validated successfully to confirm the validation ran.

            foreach (var serviceType in serviceTypes)
            {
                var isRegistered = services.Any(sd => sd.ServiceType == serviceType);
                if (!isRegistered)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine($"❌ Service not registered: {serviceType.FullName}");
                    Console.ResetColor();
                    throw new InvalidOperationException($"Service not registered: {serviceType.FullName}");
                }
            }
+           
+           Console.ForegroundColor = ConsoleColor.Green;
+           Console.WriteLine($"✅ All {serviceTypes.Count} services validated successfully");
+           Console.ResetColor();
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 6b8ccfe and 5909751.

📒 Files selected for processing (8)
  • Dentizone.Application/DI/Services.cs (1 hunks)
  • Dentizone.Application/DI/ServicesValidator.cs (1 hunks)
  • Dentizone.Application/DTOs/Shipping/CreateShipmentStatusDto.cs (1 hunks)
  • Dentizone.Application/Interfaces/IShippingService.cs (1 hunks)
  • Dentizone.Application/Services/ShippingService.cs (2 hunks)
  • Dentizone.Presentaion/Controllers/ShippingController.cs (2 hunks)
  • Dentizone.Presentaion/Extensions/SwaggerServiceExtensions.cs (1 hunks)
  • Dentizone.Presentaion/Program.cs (3 hunks)
🧰 Additional context used
🧠 Learnings (2)
Dentizone.Presentaion/Program.cs (2)
Learnt from: gitnasr
PR: dentizone/api#104
File: Dentizone.Presentaion/Controllers/PostsController.cs:60-61
Timestamp: 2025-06-29T09:04:16.858Z
Learning: The Dentizone application uses global middleware to handle exceptions, which means controller methods don't need individual try-catch blocks. Service layer exceptions are centrally caught and translated to appropriate HTTP responses through this middleware.
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.Presentaion/Controllers/ShippingController.cs (1)
Learnt from: gitnasr
PR: dentizone/api#104
File: Dentizone.Presentaion/Controllers/PostsController.cs:60-61
Timestamp: 2025-06-29T09:04:16.858Z
Learning: The Dentizone application uses global middleware to handle exceptions, which means controller methods don't need individual try-catch blocks. Service layer exceptions are centrally caught and translated to appropriate HTTP responses through this middleware.
🧬 Code Graph Analysis (2)
Dentizone.Presentaion/Program.cs (4)
Dentizone.Application/DI/Services.cs (1)
  • Services (11-42)
Dentizone.Application/DI/ServicesValidator.cs (1)
  • ValidateAllDependencies (8-26)
Dentizone.Infrastructure/Identity/ApplicationUser.cs (1)
  • ApplicationUser (5-7)
Dentizone.Infrastructure/Persistence/Seeder/FullDataSeeder.cs (2)
  • FullDataSeeder (12-950)
  • SeedingConfig (15-39)
Dentizone.Application/Interfaces/IShippingService.cs (1)
Dentizone.Application/DTOs/Shipping/CreateShipmentStatusDto.cs (1)
  • CreateShipmentStatusDto (5-10)
🔇 Additional comments (16)
Dentizone.Application/DI/Services.cs (1)

36-39: LGTM! Service registration follows established patterns.

The IShippingService registration is properly configured as a scoped service, consistent with other service registrations in the application.

Dentizone.Presentaion/Extensions/SwaggerServiceExtensions.cs (2)

14-14: LGTM! Improved readability with single-line description.

The formatting change simplifies the JWT description while maintaining the same functionality.


21-33: LGTM! Better formatting for security requirements.

The reformatting improves code readability while preserving the exact same security configuration.

Dentizone.Application/Interfaces/IShippingService.cs (2)

1-3: LGTM! Proper using statements added for the refactoring.

The using statements correctly support the new DTO parameter and maintain necessary dependencies.


9-9: LGTM! Excellent refactoring to use DTO pattern.

The method signature change from multiple parameters to a single DTO parameter improves maintainability and follows good API design principles.

Dentizone.Application/Services/ShippingService.cs (4)

1-1: LGTM! Clean dependency management.

The addition of the DTO using statement and removal of unused using statements (like for AuthService) improves the code organization.

Also applies to: 8-8


12-17: LGTM! Simplified constructor reduces dependencies.

The removal of AuthService from the constructor is excellent - the refactoring eliminates the need for this dependency by directly using loaded entities.


19-19: LGTM! Method signature updated to use DTO pattern.

The method signature change aligns perfectly with the interface refactoring and improves parameter management.


23-25: LGTM! Improved query with eager loading.

The query now efficiently loads related entities (ShipmentActivities, Post.Seller, Order.Buyer) in a single database call, which is more performant than the previous approach.

Dentizone.Presentaion/Program.cs (3)

3-3: LGTM: Required using statement for BaseService reference.

The new using statement is necessary for the BaseService type reference in the validation call.


36-36: Excellent addition: Runtime service validation.

The ValidateAllDependencies call provides early detection of missing service registrations, which will help catch DI configuration issues at startup rather than at runtime. Using the BaseService assembly for scanning is appropriate.


73-74: LGTM: Improved code formatting.

The formatting changes improve readability of the UserManager service retrieval and the SeedAsync call.

Also applies to: 81-81

Dentizone.Application/DI/ServicesValidator.cs (2)

8-13: LGTM: Solid service discovery logic.

The method correctly scans the provided assemblies for interface types ending with "Service", which aligns with the application's naming conventions. The LINQ query efficiently filters and collects the relevant service types.


15-25: Excellent validation and error handling.

The validation logic properly checks service registration and provides clear feedback. The colored console output enhances visibility during startup, and throwing InvalidOperationException for missing services ensures early detection of configuration issues.

Dentizone.Presentaion/Controllers/ShippingController.cs (2)

1-1: LGTM: Required using statement for DTO.

The new using statement is necessary for the CreateShipmentStatusDto type.


14-19: Verify the HTTP method change from PUT to POST.

The method signature improvement using a DTO is excellent for encapsulation and maintainability. However, changing from PUT to POST is a breaking change that might affect existing API clients.

Please confirm that this HTTP method change is intentional and that any existing clients have been updated accordingly. If this is a new endpoint, consider documenting the change in the API documentation.

Comment on lines +42 to 49
await mailService.Send(item.Post.Seller.Email,
$"the Status has been changed to {shipmentStatus.NewStatus}",
"New status update");

var buyer = await authService.GetById(item.Order.BuyerId);

await mailService.Send(buyer.Email, $"the Status has been changed to {newStatus}",
await mailService.Send(item.Order.Buyer.Email,
$"the Status has been changed to {shipmentStatus.NewStatus}",
"New status update");
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 improving email message localization and error handling.

The hardcoded email messages lack localization and there's no error handling for email sending failures.

-                await mailService.Send(item.Post.Seller.Email,
-                    $"the Status has been changed to {shipmentStatus.NewStatus}",
-                    "New status update");
+                try
+                {
+                    await mailService.Send(item.Post.Seller.Email,
+                        $"Order item {shipmentStatus.OrderItemId} status has been updated to {shipmentStatus.NewStatus}",
+                        "Shipment Status Update");
+                }
+                catch (Exception ex)
+                {
+                    // Log email sending failure but don't fail the entire operation
+                    // Consider using ILogger here
+                }

-                await mailService.Send(item.Order.Buyer.Email,
-                    $"the Status has been changed to {shipmentStatus.NewStatus}",
-                    "New status update");
+                try
+                {
+                    await mailService.Send(item.Order.Buyer.Email,
+                        $"Your order item {shipmentStatus.OrderItemId} status has been updated to {shipmentStatus.NewStatus}",
+                        "Shipment Status Update");
+                }
+                catch (Exception ex)
+                {
+                    // Log email sending failure but don't fail the entire operation
+                    // Consider using ILogger here
+                }
📝 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
await mailService.Send(item.Post.Seller.Email,
$"the Status has been changed to {shipmentStatus.NewStatus}",
"New status update");
var buyer = await authService.GetById(item.Order.BuyerId);
await mailService.Send(buyer.Email, $"the Status has been changed to {newStatus}",
await mailService.Send(item.Order.Buyer.Email,
$"the Status has been changed to {shipmentStatus.NewStatus}",
"New status update");
try
{
await mailService.Send(item.Post.Seller.Email,
$"Order item {shipmentStatus.OrderItemId} status has been updated to {shipmentStatus.NewStatus}",
"Shipment Status Update");
}
catch (Exception ex)
{
// Log email sending failure but don't fail the entire operation
// Consider using ILogger here
}
try
{
await mailService.Send(item.Order.Buyer.Email,
$"Your order item {shipmentStatus.OrderItemId} status has been updated to {shipmentStatus.NewStatus}",
"Shipment Status Update");
}
catch (Exception ex)
{
// Log email sending failure but don't fail the entire operation
// Consider using ILogger here
}
🤖 Prompt for AI Agents
In Dentizone.Application/Services/ShippingService.cs around lines 42 to 49, the
email messages are hardcoded without localization and lack error handling.
Refactor the code to use localized strings for the email subject and body by
integrating with the existing localization framework. Additionally, wrap the
email sending calls in try-catch blocks to handle potential exceptions
gracefully, logging any errors encountered during the email sending process.

@gitnasr gitnasr merged commit 7b86c67 into dev Jul 4, 2025
2 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