Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add Masstransit to handle events #168

Merged
merged 5 commits into from
Nov 12, 2024
Merged

Add Masstransit to handle events #168

merged 5 commits into from
Nov 12, 2024

Conversation

italopessoa
Copy link
Member

  • increase code coverage
  • remove payment code
  • add more unit tests
  • add semantic-release

@italopessoa italopessoa added the Phase 4 Microservices Architecture label Nov 12, 2024
Copy link

coderabbitai bot commented Nov 12, 2024

Walkthrough

The changes in this pull request involve significant modifications across various files in the project. Key alterations include the removal of environment variables related to MySQL and MercadoPago, replaced by new JWT-related variables. The workflow files have been updated to integrate semantic release functionality and adjust Docker image building processes. Multiple files related to MercadoPago have been deleted, including services, configuration, and tests, indicating a shift away from this payment provider. New classes and tests for handling events with MassTransit have been introduced, reflecting a transition to a new messaging system.

Changes

File Change Summary
.env.template Removed MySQL and MercadoPago environment variables; added JWT options.
.github/workflows/dotnet.yml Added semantic-release job; modified Docker image build process.
.github/workflows/terraform-plan.yaml Removed MercadoPago secrets from Terraform plan workflow.
.releaserc Added new configuration file for semantic versioning and release automation.
FIAP.TechChallenge.ByteMeBurger.sln Removed MercadoPago projects; added Masstransit projects.
package.json Added new devDependencies for semantic release.
src/FIAP.TechChallenge.ByteMeBurger.Api/Auth/JwtOptions.cs Added [ExcludeFromCodeCoverage] attribute to JwtOptions record.
src/FIAP.TechChallenge.ByteMeBurger.Api/Auth/MercadoPagoMessageAuthorizationFilter.cs Removed class implementing MercadoPago webhook authorization filter.
src/FIAP.TechChallenge.ByteMeBurger.Api/Controllers/NotificationsController.cs Removed controller handling MercadoPago notifications.
src/FIAP.TechChallenge.ByteMeBurger.Api/Controllers/PaymentsController.cs Removed payment-related controller.
src/FIAP.TechChallenge.ByteMeBurger.Api/DomainEventsHandler.cs Commented out event handlers for payment-related events.
src/FIAP.TechChallenge.ByteMeBurger.Api/FIAP.TechChallenge.ByteMeBurger.Api.csproj Updated package reference for Bmb.Domain.Core; removed MercadoPago project reference.
src/FIAP.TechChallenge.ByteMeBurger.Api/Mappers.cs Removed several mapping methods related to payments and orders.
src/FIAP.TechChallenge.ByteMeBurger.Api/Program.cs Updated service configuration; removed DomainEventsHandler registration.
src/FIAP.TechChallenge.ByteMeBurger.Api/appsettings.Development.json Removed MySql, MercadoPago, and SqsSettings sections; updated connection string.
src/FIAP.TechChallenge.ByteMeBurger.Application/FIAP.TechChallenge.ByteMeBurger.Application.csproj Updated Bmb.Domain.Core package reference.
src/FIAP.TechChallenge.ByteMeBurger.Application/ServiceExtensions.cs Removed AddPaymentUseCases method; updated AddOrderUseCases method.
src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Orders/CreateOrderUseCase.cs Updated constructor to include new IDispatcher dependency; modified event handling logic.
src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Orders/IUpdateOrderStatusUseCase.cs Introduced new generic interface and request record for order status updates.
src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Orders/UpdateOrderStatusUseCase.cs Updated to implement new generic interface; refactored method logic.
src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Payment/CreatePaymentUseCase.cs Removed class handling payment creation.
src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Payment/ICreatePaymentUseCase.cs Removed interface for payment creation.
src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Payment/IUpdatePaymentStatusUseCase.cs Removed interface for updating payment status.
src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Payment/UpdatePaymentStatusUseCase.cs Removed class handling payment status updates.
src/FIAP.TechChallenge.ByteMeBurger.Cognito.Gateway/CognitoUserManager.cs Enhanced error handling and logging in user management methods.
src/FIAP.TechChallenge.ByteMeBurger.Controllers/Contracts/IPaymentService.cs Removed payment service interface.
src/FIAP.TechChallenge.ByteMeBurger.Controllers/Dto/PaymentDto.cs Removed DTO for payment data.
src/FIAP.TechChallenge.ByteMeBurger.Controllers/FIAP.TechChallenge.ByteMeBurger.Controllers.csproj Removed references to MercadoPago and FakePayment projects.
src/FIAP.TechChallenge.ByteMeBurger.Controllers/OrderService.cs Updated order status use case handling to use new request object.
src/FIAP.TechChallenge.ByteMeBurger.DI/FIAP.TechChallenge.ByteMeBurger.DI.csproj Updated project references; removed MercadoPago and SQS references.
src/FIAP.TechChallenge.ByteMeBurger.DI/ServiceCollectionsExtensions.cs Removed payment gateway configuration; added dispatcher configuration.
src/FIAP.TechChallenge.ByteMeBurger.FakePayment.Gateway/... Removed all files related to FakePayment gateway.
src/FIAP.TechChallenge.ByteMeBurger.Masstransit/... Added new files for MassTransit consumers and dispatcher.
tests/... Removed tests related to MercadoPago and payment processing; added tests for new MassTransit consumers and dispatcher.

Sequence Diagram(s)

sequenceDiagram
    participant Consumer
    participant UseCase
    participant Logger

    Consumer->>UseCase: Consume(OrderPaymentConfirmed)
    UseCase->>Logger: Log("Processing Order Payment Confirmed")
    UseCase-->>Consumer: ExecuteAsync(UpdateOrderStatusRequest)
    alt Success
        Logger->>Consumer: Log("Order status updated successfully")
    else Error
        Logger->>Consumer: Log("Error updating order status")
    end
Loading

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

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

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

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title 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

sonarcloud bot commented Nov 12, 2024

Quality Gate Failed Quality Gate failed

Failed conditions
1 Security Hotspot

See analysis details on SonarCloud

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 17

🧹 Outside diff range and nitpick comments (54)
.env.template (1)

4-7: Consider environment-specific JWT configurations

For production readiness, consider:

  1. Using placeholder values instead of localhost URLs
  2. Adding comments to explain the expected values
  3. Documenting the implications of UseAccessToken=false

Consider updating the template like this:

-JwtOptions__Issuer=https://localhost:7000
-JwtOptions__Audience=https://localhost:7000
-JwtOptions__ExpirationSeconds=300
-JwtOptions__UseAccessToken=false
+# JWT issuer URL (e.g., https://api.yourdomain.com)
+JwtOptions__Issuer=<your-issuer-url>
+# JWT audience URL (e.g., https://app.yourdomain.com)
+JwtOptions__Audience=<your-audience-url>
+# Token expiration in seconds (e.g., 3600 for 1 hour)
+JwtOptions__ExpirationSeconds=3600
+# Enable/disable access token validation
+JwtOptions__UseAccessToken=true
src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Orders/IUpdateOrderStatusUseCase.cs (2)

Line range hint 1-8: Consider removing the original interface in favor of the generic one.

The original IUpdateOrderStatusUseCase interface is now redundant as it's being replaced by IUseCase<UpdateOrderStatusRequest, bool>. Having both interfaces violates the Interface Segregation Principle and could lead to confusion.

-public interface IUpdateOrderStatusUseCase
-{
-    Task<bool> Execute(Guid orderId, OrderStatus newStatus);
-}

10-13: Well-designed generic interface following Clean Architecture principles!

The generic IUseCase<TRequest, TResponse> interface provides a consistent contract for all use cases, promoting:

  • Better separation of concerns
  • Consistent pattern across the application
  • Type-safe request/response handling

Consider adding XML documentation to describe the contract and generic type parameters for better maintainability.

.releaserc (1)

7-17: Consider adding changelog and npm plugins for comprehensive release management

While the current plugins cover basic release needs, consider adding:

  • @semantic-release/changelog for automated CHANGELOG.md generation
  • @semantic-release/npm if you need to publish npm packages

Here's how to enhance the plugins configuration:

 "plugins": [
   "@semantic-release/commit-analyzer",
   "@semantic-release/release-notes-generator",
+  "@semantic-release/changelog",
   "@semantic-release/github",
+  "@semantic-release/npm",
   [
     "@semantic-release/exec",
     {
       "verifyReleaseCmd": "echo v${nextRelease.version} > VERSION"
     }
   ]
 ]
src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Consumers/PaymentCreatedConsumer.cs (1)

8-9: Consider renaming to PaymentCreatedConsumer for consistency

The current name OrderPaymentCreatedConsumer is slightly verbose. Since we're already in the context of orders and the event is PaymentCreated, consider simplifying to PaymentCreatedConsumer to match the event name.

The implementation itself is solid, following SOLID principles with proper dependency injection.

src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Consumers/OrderStatusChangedConsumer.cs (1)

7-16: Add XML documentation for better maintainability

Consider adding XML documentation to describe the consumer's purpose, its dependencies, and the contract it fulfills.

+/// <summary>
+/// Consumes OrderStatusChanged events and updates the order status through the appropriate use case.
+/// </summary>
+/// <param name="logger">Logger for diagnostic information</param>
+/// <param name="updateOrderStatusUseCase">Use case for updating order status</param>
 public class OrderStatusChangedConsumer(
     ILogger<OrderStatusChangedConsumer> logger,
     IUseCase<UpdateOrderStatusRequest, bool> updateOrderStatusUseCase)
     : BaseConsumer<OrderStatusChanged, UpdateOrderStatusRequest, bool>(logger, updateOrderStatusUseCase)
 {
+    /// <summary>
+    /// Transforms the OrderStatusChanged event into an UpdateOrderStatusRequest.
+    /// </summary>
+    /// <param name="request">The event containing order status change information</param>
+    /// <returns>A request object for the update order status use case</returns>
     protected override UpdateOrderStatusRequest PrepareRequest(OrderStatusChanged request)
src/FIAP.TechChallenge.ByteMeBurger.Controllers/ServiceCollectionsExtensions.cs (1)

4-5: Verify dependency direction in Clean Architecture

The Controllers layer (outer layer) is importing from the Application layer (inner layer), which follows Clean Architecture's dependency rule. However, consider moving this service registration to an Infrastructure or IoC project to better separate concerns.

Consider creating a dedicated Infrastructure.IoC project to handle all dependency registrations. This would:

  • Centralize all dependency configurations
  • Reduce coupling between layers
  • Make the system more maintainable
src/FIAP.TechChallenge.ByteMeBurger.Masstransit/ServiceExtensions.cs (2)

9-9: Consider removing [ExcludeFromCodeCoverage]

While this is a configuration class, it contains crucial setup logic that should be tested to ensure correct consumer registration and AWS configuration. Integration tests would be valuable here.


1-30: Consider architectural boundaries and error handling

As this introduces message-based communication:

  1. Ensure consumers follow Single Responsibility Principle
  2. Consider implementing a resilience layer for AWS connectivity
  3. Add logging for message processing failures
  4. Consider implementing health checks for the message broker

Consider creating a separate health check endpoint:

public class MassTransitHealthCheck : IHealthCheck
{
    private readonly IBusControl _busControl;
    
    public async Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context,
        CancellationToken cancellationToken = default)
    {
        try
        {
            // Check connection to AWS SQS
            return HealthCheckResult.Healthy();
        }
        catch (Exception ex)
        {
            return HealthCheckResult.Unhealthy(ex.Message);
        }
    }
}
tests/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test.csproj (1)

Line range hint 19-19: Consider standardizing on a single test framework

The project references both NUnit and xunit packages. Using multiple testing frameworks in the same project can lead to:

  • Confusion about which framework to use for new tests
  • Increased maintenance overhead
  • Larger build size
  • Potential conflicts in test runners

Consider standardizing on either NUnit or xunit.

Also applies to: 28-28

src/FIAP.TechChallenge.ByteMeBurger.DI/FIAP.TechChallenge.ByteMeBurger.DI.csproj (2)

Line range hint 23-25: Critical: Replace local file system reference with proper NuGet package

The project contains a direct file system reference to Bmb.Domain.Core.dll. This is problematic because:

  1. It creates a dependency on a specific local file path
  2. It may break builds on different machines or CI/CD environments
  3. Version control becomes difficult

Consider publishing Bmb.Domain.Core as a NuGet package and referencing it properly through package management.


The Microsoft.Extensions.Caching.Hybrid package does not exist in NuGet

The package Microsoft.Extensions.Caching.Hybrid referenced in the project file appears to be non-existent in the NuGet registry. This is confirmed by the 404 response from the NuGet API. You should:

  • Remove this preview package reference as it's not a valid NuGet package
  • Consider using established caching packages like:
    • Microsoft.Extensions.Caching.Memory
    • Microsoft.Extensions.Caching.StackExchangeRedis
    • Or implement a custom hybrid caching solution using these standard packages
🔗 Analysis chain

Line range hint 10-10: Consider using stable version of Microsoft.Extensions.Caching.Hybrid

The package Microsoft.Extensions.Caching.Hybrid is using a preview version (9.0.0-preview.6.24328.4). Consider using a stable version to ensure reliability in production.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check NuGet for latest stable version of Microsoft.Extensions.Caching.Hybrid
curl -s https://api.nuget.org/v3-flatcontainer/microsoft.extensions.caching.hybrid/index.json | jq -r '.versions[]' | grep -v preview | tail -n 1

Length of output: 147


Script:

#!/bin/bash
# Let's verify if this package exists in NuGet and check its versions
curl -s "https://api.nuget.org/v3/registration5-semver1/microsoft.extensions.caching.hybrid/index.json"

# Also check the csproj file to see the full context of package references
fd -e csproj -x cat {}

Length of output: 17888

src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Consumers/OrderPaymentApprovedConsumer.cs (1)

9-12: Consider adding XML documentation for the class

The class structure and dependency injection are well implemented. However, adding XML documentation would improve maintainability by describing the consumer's purpose and its dependencies.

+/// <summary>
+/// Consumes OrderPaymentConfirmed events and updates the order status to Received.
+/// </summary>
+/// <param name="logger">Logger for the consumer</param>
+/// <param name="updateOrderStatusUseCase">Use case for updating order status</param>
 public class OrderPaymentApprovedConsumer(
     ILogger<OrderPaymentApprovedConsumer> logger,
     IUseCase<UpdateOrderStatusRequest, bool> updateOrderStatusUseCase) : IConsumer<OrderPaymentConfirmed>
src/FIAP.TechChallenge.ByteMeBurger.Persistence/ServiceExtensions.cs (2)

20-20: Consider using ImmutableArray for thread-safety

The empty array initialization [] creates a mutable array. Since this is a singleton registration, consider using ImmutableArray<T>.Empty to ensure thread-safety.

-    .AddSingleton<IProductRepository>(_ => new InMemoryProductRepository([]));
+    .AddSingleton<IProductRepository>(_ => new InMemoryProductRepository(System.Collections.Immutable.ImmutableArray<Product>.Empty));

Line range hint 24-32: Consider extracting database connection factory

The database connection setup logic could be extracted into a separate factory class to improve maintainability and testability.

Consider creating an IDbConnectionFactory interface and implementation:

public interface IDbConnectionFactory
{
    IDbConnection CreateConnection();
}

public class MySqlConnectionFactory : IDbConnectionFactory
{
    private readonly string _connectionString;
    
    public MySqlConnectionFactory(string connectionString)
    {
        _connectionString = connectionString;
    }
    
    public IDbConnection CreateConnection()
    {
        DbProviderFactories.RegisterFactory("MySql.Data.MySqlClient", MySqlClientFactory.Instance);
        var providerFactory = DbProviderFactories.GetFactory("MySql.Data.MySqlClient");
        var conn = providerFactory.CreateConnection();
        conn.ConnectionString = _connectionString;
        conn.Open();
        return conn;
    }
}

Then update the service registration:

- services.AddScoped<IDbConnection>(_ =>
- {
-     DbProviderFactories.RegisterFactory("MySql.Data.MySqlClient", MySqlClientFactory.Instance);
-     var providerFactory = DbProviderFactories.GetFactory("MySql.Data.MySqlClient");
-     var conn = providerFactory.CreateConnection();
-     conn.ConnectionString = configuration.GetConnectionString("MySql");
-     conn.Open();
-     return conn;
- });
+ services.AddSingleton<IDbConnectionFactory>(_ => 
+     new MySqlConnectionFactory(configuration.GetConnectionString("MySql")));
+ services.AddScoped<IDbConnection>(sp => 
+     sp.GetRequiredService<IDbConnectionFactory>().CreateConnection());
src/FIAP.TechChallenge.ByteMeBurger.DI/ServiceCollectionsExtensions.cs (2)

Line range hint 16-24: Consider documenting service initialization order

The method follows SOLID principles by delegating specific configurations to extension methods. However, the initialization order might be critical for proper dependency resolution.

Consider adding XML documentation to explain the initialization order and dependencies:

+    /// <summary>
+    /// Configures all application services in the dependency injection container.
+    /// Order of initialization:
+    /// 1. Authentication (Cognito)
+    /// 2. Persistence
+    /// 3. Caching
+    /// 4. Application Services
+    /// 5. Controllers
+    /// 6. Message Dispatcher
+    /// </summary>
     public static void IoCSetup(this IServiceCollection serviceCollection, IConfiguration configuration)

Line range hint 26-39: Add configuration validation for hybrid cache settings

The use of the null-forgiving operator (!) might hide potential configuration issues. Consider adding explicit validation.

Here's a suggested improvement:

     private static void ConfigHybridCache(IServiceCollection services, IConfiguration configuration)
     {
         var hybridCacheSettings = configuration.GetSection("HybridCache")
             .Get<HybridCacheEntryOptions>();
+        
+        if (hybridCacheSettings == null)
+            throw new InvalidOperationException("HybridCache configuration is missing");
+            
+        if (hybridCacheSettings.Expiration <= TimeSpan.Zero)
+            throw new InvalidOperationException("Invalid cache expiration time");
+
         services.AddHybridCache(options =>
             options.DefaultEntryOptions = new HybridCacheEntryOptions()
             {
-                Expiration = hybridCacheSettings!.Expiration,
+                Expiration = hybridCacheSettings.Expiration,
                 LocalCacheExpiration = hybridCacheSettings.LocalCacheExpiration,
                 Flags = hybridCacheSettings.Flags,
             }
         );
     }
src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Dispatcher.cs (1)

35-48: Reduce code duplication with PublishAsync

The PublishIntegrationAsync method is almost identical to PublishAsync. Consider refactoring to avoid duplication:

+    private async Task<bool> PublishEventAsync<T>(T @event, string eventType, CancellationToken cancellationToken)
+    {
+        try
+        {
+            _logger.LogInformation("Publishing {EventType} event: {Event}", eventType, @event);
+            await _bus.Publish(@event, cancellationToken);
+            _logger.LogInformation("Successfully published {EventType} event: {Event}", eventType, @event);
+            return true;
+        }
+        catch (Exception e)
+        {
+            _logger.LogCritical(e, "Failed to publish {EventType} event: {@Event}", eventType, @event);
+            return false;
+        }
+    }
+
-    public async Task PublishIntegrationAsync<T>(T @event, CancellationToken cancellationToken = default)
+    public async Task<bool> PublishIntegrationAsync<T>(T @event, CancellationToken cancellationToken = default)
     where T : IBmbIntegrationEvent
     {
-        try
-        {
-            _logger.LogInformation("Publishing event: {Event}", @event);
-            await _bus.Publish(@event, cancellationToken);
-            _logger.LogInformation("Event published: {Event}", @event);
-        }
-        catch (Exception e)
-        {
-            _logger.LogCritical(e, "Error when trying to publish event: {@Event}", @event);
-        }
+        return await PublishEventAsync(@event, "integration", cancellationToken);
     }

-    public async Task PublishAsync<T>(T @event, CancellationToken cancellationToken = default)
+    public async Task<bool> PublishAsync<T>(T @event, CancellationToken cancellationToken = default)
     where T : IBmbNotification
     {
-        try
-        {
-            _logger.LogInformation("Publishing event: {Event}", @event);
-            await _bus.Publish(@event, cancellationToken);
-            _logger.LogInformation("Event published: {Event}", @event);
-        }
-        catch (Exception e)
-        {
-            _logger.LogCritical(e, "Error when trying to publish event: {@Event}", @event);
-        }
+        return await PublishEventAsync(@event, "notification", cancellationToken);
     }
src/FIAP.TechChallenge.ByteMeBurger.Controllers/OrderService.cs (2)

14-14: Good architectural choice using generic IUseCase interface!

The change from IUpdateOrderStatusUseCase to IUseCase<UpdateOrderStatusRequest, bool> aligns well with Clean Architecture principles and promotes better reusability. This generic interface approach makes the code more maintainable and consistent across different use cases.

Consider applying this pattern to other use case interfaces in the system for consistency, such as ICreateOrderUseCase, IGetOrderDetailsUseCase, and IOrderGetAllUseCase.


40-40: Consider adding exception handling for better resilience.

The implementation using UpdateOrderStatusRequest is clean and follows good CQRS patterns. However, the method might benefit from explicit error handling.

Consider wrapping the execution in a try-catch block to handle specific domain exceptions:

 public async Task<bool> UpdateStatusAsync(Guid orderId, OrderStatus newStatus)
 {
-    return await updateOrderStatusUseCase.ExecuteAsync(new UpdateOrderStatusRequest(orderId, newStatus));
+    try 
+    {
+        return await updateOrderStatusUseCase.ExecuteAsync(new UpdateOrderStatusRequest(orderId, newStatus));
+    }
+    catch (InvalidOrderStateException ex)
+    {
+        // Log the error
+        throw;
+    }
 }
src/FIAP.TechChallenge.ByteMeBurger.Api/FIAP.TechChallenge.ByteMeBurger.Api.csproj (1)

Clean up needed for remaining MercadoPago test files and references

While the core MercadoPago implementation has been removed, there are still some cleanup tasks needed:

  • Remove the MercadoPago test files:

    • tests/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway.Test/Security/MercadoPagoHmacSignatureValidatorTest.cs
  • Update enum references:

    • Remove MercadoPago = 1 from PaymentTypeDto in src/FIAP.TechChallenge.ByteMeBurger.Controllers/Dto/PaymentTypeDto.cs
  • Clean up Postman collection:

    • Remove MercadoPago-specific test cases in postman/TechChallenge - Workflow testing.postman_collection.json
🔗 Analysis chain

Line range hint 37-45: Verify impact of MercadoPago removal

The removal of MercadoPago Gateway project reference aligns with the PR objectives. However, we should verify that all related code has been properly cleaned up.


Let me analyze the results and generate additional verification scripts to check for potential issues.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining MercadoPago references
echo "Checking for any remaining MercadoPago references in code..."
rg -i "mercadopago|payment" --type cs

echo "Checking for any remaining payment-related configurations..."
rg -i "mercadopago|payment" --type json

Length of output: 24886


Script:

#!/bin/bash
# Check for any remaining MercadoPago-specific code in the codebase
echo "Checking for MercadoPago-specific implementations..."
ast-grep --pattern 'class $_ { $$$ MercadoPago $$$ }'

# Check for any remaining payment gateway interfaces or implementations
echo "Checking for payment gateway related interfaces..."
rg -l "IPaymentGateway|PaymentGateway" --type cs

# Check for any remaining payment-related database migrations
echo "Checking for payment-related migrations..."
fd -e sql . | xargs cat

Length of output: 1841

tests/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test/Consumers/OrderPaymentCreatedConsumerTest.cs (3)

16-23: Consider making fields readonly.

Since these fields are only set in the constructor and shouldn't change during test execution, consider making them readonly for better immutability.

-    private Mock<IUpdateOrderPaymentUseCase> _useCaseMock;
-    private OrderPaymentCreatedConsumer _consumer;
+    private readonly Mock<IUpdateOrderPaymentUseCase> _useCaseMock;
+    private readonly OrderPaymentCreatedConsumer _consumer;

25-40: Enhance test specificity by verifying exact parameters.

While the test verifies that the use case is called, it could be more specific by checking that the exact parameters are passed correctly instead of using It.IsAny<T>().

-        _useCaseMock.Verify(
-            x => x.Execute(It.IsAny<Guid>(), It.IsAny<PaymentId>()),
-            Times.Once);
+        _useCaseMock.Verify(
+            x => x.Execute(paymentCreated.OrderId, paymentCreated.PaymentId),
+            Times.Once);

42-57: Consider using domain-specific exceptions.

Instead of using a generic Exception, consider creating and testing with domain-specific exceptions that better represent the business error conditions.

Example:

public class OrderPaymentUpdateException : Exception
{
    public OrderPaymentUpdateException(string message, Exception innerException = null) 
        : base(message, innerException)
    {
    }
}

Then update the test:

-        var exception = new Exception("Unexpected error");
+        var exception = new OrderPaymentUpdateException("Failed to update order payment");
         _useCaseMock.Setup(x => x.Execute(It.IsAny<Guid>(), It.IsAny<PaymentId>())).Throws(exception);

         // Act
         Func<Task> act = async () => await _consumer.Consume(contextMock.Object);

         // Assert
-        await act.Should().ThrowAsync<Exception>().WithMessage("Unexpected error");
+        await act.Should().ThrowAsync<OrderPaymentUpdateException>()
+            .WithMessage("Failed to update order payment");
src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Orders/CreateOrderUseCase.cs (1)

Line range hint 1-65: Architecture aligns with DDD and Clean Architecture principles.

The implementation maintains proper separation of concerns and follows clean architecture boundaries:

  • Use case pattern is correctly implemented
  • Domain events are properly abstracted through IDispatcher
  • Integration events are handled separately from domain logic

Consider documenting the integration event contract and its purpose in the XML documentation.

tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/Auth/JwtExtensionsTest.cs (2)

12-13: Consider using obviously fake test data

The CPF constant 15311546034 could potentially be a real person's CPF. Consider using a clearly fake test value (e.g., "11111111111") to avoid any potential privacy concerns and make it clear this is test data.


39-80: Consider adding more test cases and improving test data organization

While the current tests cover basic scenarios, consider:

  1. Additional test cases for:

    • Missing or invalid email
    • Missing or invalid CPF
    • Missing or invalid name
  2. Improving test data organization using a test data generator:

private static class TestData
{
    public static IEnumerable<Claim> GetValidClaims(Guid? id = null) => new[]
    {
        new Claim(ClaimTypes.NameIdentifier, (id ?? Guid.NewGuid()).ToString()),
        new Claim(ClaimTypes.Email, "[email protected]"),
        new Claim(ClaimTypes.Name, "Test User"),
        new Claim("cpf", "11111111111")
    };
}
  1. Verifying the GUID value in the success case:
  result.Should().NotBeNull();
+ result.Id.Should().Be(expectedGuid); // Add GUID verification
  result.Email.Should().Be("[email protected]");
tests/FIAP.TechChallenge.ByteMeBurger.Application.Test/UseCases/Orders/UpdateOrderStatusUseCaseTest.cs (1)

35-35: Consider enhancing test assertions and timeout handling

While the async/await pattern is correctly implemented and the test coverage is good, consider these improvements:

  1. Add more specific assertions in Execute_ShouldUpdateOrderStatus_WhenOrderExists to verify the order's final state
  2. Consider adding timeout configuration for async operations to prevent hanging tests

Example enhancement for the success test:

 var updated = await _useCase.ExecuteAsync(request);

 // Assert
 using (new AssertionScope())
 {
     _orderRepositoryMock.Verify(r => r.GetAsync(It.Is<Guid>(orderId => orderId == currentOrder.Id)),
         Times.Once);
     _orderRepositoryMock.Verify(
         r => r.UpdateOrderStatusAsync(It.Is<Order>(orderId => orderId.Status == newStatus)),
         Times.Once);
+    currentOrder.Status.Should().Be(newStatus, "order status should be updated to the new status");
+    currentOrder.UpdatedAt.Should().NotBeNull("update timestamp should be set");
 }

Also applies to: 59-59, 73-73

tests/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test/Consumers/OrderStatusChangedConsumerTest.cs (3)

17-26: Consider making mock fields readonly

The mock fields are only initialized in the constructor and never reassigned. Making them readonly would better express their immutable nature.

-    private Mock<ILogger<OrderStatusChangedConsumer>> _loggerMock;
-    private Mock<IUseCase<UpdateOrderStatusRequest, bool>> _useCaseMock;
-    private OrderStatusChangedConsumer _consumer;
+    private readonly Mock<ILogger<OrderStatusChangedConsumer>> _loggerMock;
+    private readonly Mock<IUseCase<UpdateOrderStatusRequest, bool>> _useCaseMock;
+    private readonly OrderStatusChangedConsumer _consumer;

28-41: Enhance logging verification

The test verifies that logging occurs but doesn't validate the actual message content. Consider adding assertions for the log message to ensure the correct information is being logged.

         // Assert
-        _loggerMock.VerifyLog(logger => logger.LogInformation(It.IsAny<string>(), It.IsAny<object[]>()), LogLevel.Information, Times.Once());
+        _loggerMock.VerifyLog(
+            logger => logger.LogInformation(
+                "Processing OrderStatusChanged event for order {OrderId} with status {Status}",
+                orderStatusChanged.OrderId,
+                orderStatusChanged.Status
+            ),
+            LogLevel.Information,
+            Times.Once());

15-77: Consider adding tests for edge cases

The test coverage could be improved by adding the following test cases:

  1. Test handling of invalid order status values
  2. Test handling of null or invalid messages from the consume context

Would you like me to help generate these additional test cases?

tests/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test/Consumers/OrderPaymentApprovedConsumerTest.cs (3)

14-26: Consider adding readonly modifier to fields and using var consistently

The class setup is well-structured, but could be improved for better immutability and consistency.

Apply this diff:

-    private Mock<ILogger<OrderPaymentApprovedConsumer>> _loggerMock;
-    private Mock<IUseCase<UpdateOrderStatusRequest, bool>> _useCaseMock;
-    private OrderPaymentApprovedConsumer _consumer;
+    private readonly Mock<ILogger<OrderPaymentApprovedConsumer>> _loggerMock;
+    private readonly Mock<IUseCase<UpdateOrderStatusRequest, bool>> _useCaseMock;
+    private readonly OrderPaymentApprovedConsumer _consumer;

     public OrderPaymentApprovedConsumerTest()
     {
-        _loggerMock = new Mock<ILogger<OrderPaymentApprovedConsumer>>();
-        _useCaseMock = new Mock<IUseCase<UpdateOrderStatusRequest, bool>>();
-        _consumer = new OrderPaymentApprovedConsumer(_loggerMock.Object, _useCaseMock.Object);
+        var loggerMock = new Mock<ILogger<OrderPaymentApprovedConsumer>>();
+        var useCaseMock = new Mock<IUseCase<UpdateOrderStatusRequest, bool>>();
+        _loggerMock = loggerMock;
+        _useCaseMock = useCaseMock;
+        _consumer = new OrderPaymentApprovedConsumer(loggerMock.Object, useCaseMock.Object);
     }

28-42: Enhance log verification specificity

While the test verifies the number of log calls, it doesn't verify the actual content of the log messages.

Consider enhancing the test with more specific verifications:

+    private const int ExpectedInfoLogCount = 2;
+    private const string ExpectedStartMessage = "Starting to process payment approved event";
+    private const string ExpectedEndMessage = "Finished processing payment approved event";

     [Fact]
     public async Task Consume_ShouldLogInformation_WhenEventIsProcessed()
     {
         // ...
         // Assert
-        _loggerMock.VerifyLog(logger => logger.LogInformation(It.IsAny<string>(), It.IsAny<object[]>()),
-            LogLevel.Information, Times.Exactly(2));
+        _loggerMock.VerifyLog(
+            logger => logger.LogInformation(ExpectedStartMessage, It.IsAny<object[]>()),
+            LogLevel.Information,
+            Times.Once);
+        _loggerMock.VerifyLog(
+            logger => logger.LogInformation(ExpectedEndMessage, It.IsAny<object[]>()),
+            LogLevel.Information,
+            Times.Once);
     }

61-78: Consider using domain-specific exception and verifying complete error message

While the error handling test is good, it could be more specific to your domain.

Consider these improvements:

+    private const string ErrorMessage = "Failed to update order status";

     [Fact]
     public async Task Consume_ShouldLogError_WhenExceptionIsThrown()
     {
         // Arrange
         var contextMock = new Mock<ConsumeContext<OrderPaymentConfirmed>>();
         var orderPaymentConfirmed = new OrderPaymentConfirmed(new PaymentId(Guid.NewGuid()), Guid.NewGuid());
         contextMock.Setup(c => c.Message).Returns(orderPaymentConfirmed);
-        var exception = new Exception("Unexpected error");
+        var exception = new OrderStatusUpdateException(ErrorMessage);
         _useCaseMock.Setup(x => x.ExecuteAsync(It.IsAny<UpdateOrderStatusRequest>())).ThrowsAsync(exception);

         // Act
         Func<Task> act = async () => await _consumer.Consume(contextMock.Object);

         // Assert
-        await act.Should().ThrowAsync<Exception>().WithMessage("Unexpected error");
+        await act.Should().ThrowAsync<OrderStatusUpdateException>()
+            .WithMessage(ErrorMessage);
         _loggerMock.VerifyLog(
-            logger => logger.LogError(exception, It.IsAny<string>(), It.IsAny<object[]>()),
+            logger => logger.LogError(exception, 
+                "Error processing payment approved event for order {OrderId}: {Message}",
+                orderPaymentConfirmed.OrderId,
+                exception.Message),
             LogLevel.Error,
             Times.Once());
     }
tests/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test/DispatcherTest.cs (4)

13-26: Consider adding XML documentation for better maintainability.

While the setup is well-structured, consider adding XML documentation to describe the purpose of the test class and its dependencies.

+/// <summary>
+/// Unit tests for the <see cref="Dispatcher"/> class that handles event publishing.
+/// </summary>
 [TestSubject(typeof(Dispatcher))]
 public class DispatcherTest
 {
+    /// <summary>
+    /// Mock for the MassTransit bus interface.
+    /// </summary>
     private readonly Mock<IBus> _busMock;

27-58: Consider enhancing error scenario verification.

The tests are well-structured, but the error handling test could be more thorough.

Consider these improvements:

  1. Verify the logged exception details
  2. Use more specific event type in mock setup
 [Fact]
 public async Task PublishAsync_ShouldLogError_WhenExceptionIsThrown()
 {
     // Arrange
     var @event = new Mock<IBmbNotification>().Object;
     var exception = new Exception("Test exception");
-    _busMock.Setup(b => b.Publish(IsAny<object>(), IsAny<CancellationToken>())).ThrowsAsync(exception);
+    _busMock.Setup(b => b.Publish(IsAny<IBmbNotification>(), IsAny<CancellationToken>())).ThrowsAsync(exception);

     // Act
     Func<Task> act = async () => await _dispatcher.PublishAsync(@event);

     // Assert
     await act.Should().NotThrowAsync<Exception>();
     _loggerMock.VerifyLog(logger => logger.LogCritical(IsAny<string>(), @event), LogLevel.Critical, Times.Once());
+    _loggerMock.Verify(x => x.Log(
+        LogLevel.Critical,
+        It.IsAny<EventId>(),
+        It.Is<It.IsAnyType>((v, t) => true),
+        It.Is<Exception>(ex => ex.Message == exception.Message),
+        It.IsAny<Func<It.IsAnyType, Exception, string>>()),
+        Times.Once);
 }

59-90: Consider reducing test code duplication.

The integration event tests mirror the notification tests. Consider extracting common test logic to reduce duplication.

Consider creating a generic test method:

private async Task VerifyPublishBehavior<T>(T @event, Func<T, Task> publishAction) where T : class
{
    // Arrange
    _busMock.Setup(b => b.Publish(IsAny<T>(), IsAny<CancellationToken>()));

    // Act
    await publishAction(@event);

    // Assert
    _busMock.Verify(b => b.Publish(IsAny<T>(), IsAny<CancellationToken>()), Times.Once);
    _loggerMock.VerifyLog(logger => logger.LogInformation(IsAny<string>(), @event), 
        LogLevel.Information, Times.Exactly(2));
}

[Fact]
public async Task PublishAsync_ShouldPublishEvent_WhenCalled()
{
    var @event = new Mock<IBmbNotification>().Object;
    await VerifyPublishBehavior(@event, _dispatcher.PublishAsync);
}

92-106: Consider enhancing the logger extension documentation and type safety.

The logger extension is well-implemented but could benefit from better documentation and type constraints.

 public static class LoggerExtensions
 {
+    /// <summary>
+    /// Verifies that a log entry was created with the specified level and frequency.
+    /// </summary>
+    /// <typeparam name="T">The type of the logger being verified.</typeparam>
+    /// <param name="loggerMock">The mock logger instance.</param>
+    /// <param name="verify">The verification action.</param>
+    /// <param name="logLevel">The expected log level.</param>
+    /// <param name="times">The number of times the log should have been called.</param>
     public static void VerifyLog<T>(this Mock<ILogger<T>> loggerMock, 
         Action<ILogger<T>> verify, 
         LogLevel logLevel,
         Times times) where T : class
src/FIAP.TechChallenge.ByteMeBurger.Api/DomainEventsHandler.cs (1)

Line range hint 1-117: Consider splitting responsibilities to improve maintainability

The DomainEventsHandler class currently handles multiple concerns:

  1. Event handling
  2. Cache management
  3. Analytics publishing

This violates the Single Responsibility Principle and could make the code harder to maintain and test.

Consider splitting this into separate handlers:

public class OrderEventHandler : IEventHandler<OrderCreated>, IEventHandler<OrderStatusChanged>
{
    private readonly ICacheManager _cache;
    private readonly IAnalyticsPublisher _publisher;
    // Handle order-related events
}

public class ProductEventHandler : IEventHandler<ProductCreated>, IEventHandler<ProductDeleted>, IEventHandler<ProductUpdated>
{
    private readonly IAnalyticsPublisher _publisher;
    // Handle product-related events
}

public class CustomerEventHandler : IEventHandler<CustomerRegistered>
{
    private readonly IAnalyticsPublisher _publisher;
    // Handle customer-related events
}
tests/FIAP.TechChallenge.ByteMeBurger.Application.Test/UseCases/Orders/CreateOrderUseCaseTest.cs (2)

5-5: LGTM! Consider adding dispatcher verification.

The addition of IDispatcher follows DDD and SOLID principles by properly handling domain events. However, none of the test methods verify that the dispatcher is being called correctly.

Consider adding verification for dispatcher calls in your test methods, for example:

_mockDispatcher.Verify(d => d.Dispatch(It.IsAny<OrderCreatedEvent>()), Times.Once);

Also applies to: 18-19, 26-28


50-51: Enhance test assertions for better coverage.

While the async conversion and AutoFixture usage are good improvements, the test method could be more thorough in its assertions.

Consider adding these assertions to verify the complete state:

// Assert
using (new AssertionScope())
{
    result.Should().NotBeNull();
    result.TrackingCode.Should().NotBeNull();
    result.Items.Should().HaveCount(1);
    result.Items.First().Price.Should().Be(product.Price);
    
    _createOrderCodeService.Verify(s => s.GetNextAsync(), Times.Once);
    _mockDispatcher.Verify(d => d.Dispatch(It.IsAny<OrderCreatedEvent>()), Times.Once);
}
src/FIAP.TechChallenge.ByteMeBurger.Api/Program.cs (2)

Line range hint 48-82: Add security scheme configuration to Swagger

While the Swagger configuration is comprehensive for documentation, it's missing security scheme definitions which are crucial since the API uses JWT authentication.

Add security configuration to Swagger:

 builder.Services.AddSwaggerGen(c =>
 {
     // ... existing configuration ...
+    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
+    {
+        Description = "JWT Authorization header using the Bearer scheme.",
+        Name = "Authorization",
+        In = ParameterLocation.Header,
+        Type = SecuritySchemeType.Http,
+        Scheme = "bearer"
+    });
+    c.AddSecurityRequirement(new OpenApiSecurityRequirement
+    {
+        {
+            new OpenApiSecurityScheme
+            {
+                Reference = new OpenApiReference
+                {
+                    Type = ReferenceType.SecurityScheme,
+                    Id = "Bearer"
+                }
+            },
+            Array.Empty<string>()
+        }
+    });
 });

Line range hint 1-146: Architecture changes align with Clean Architecture principles

The removal of DomainEventsHandler and transition to MassTransit maintains proper separation of concerns. The exception handling, logging configuration, and middleware setup follow Clean Architecture principles correctly.

Consider documenting the event handling architecture transition in the project's technical documentation to help other developers understand the new event flow with MassTransit.

tests/FIAP.TechChallenge.ByteMeBurger.Controllers.Test/OrderServiceTest.cs (2)

157-157: Consider verifying the UpdateOrderStatusRequest parameters

While the test passes, it could be more thorough by verifying that the correct order ID and status are passed to the use case.

-        _mockUpdateOrderStatusUseCase.Setup(r => r.ExecuteAsync(It.IsAny<UpdateOrderStatusRequest>()))
+        var orderId = Guid.NewGuid();
+        var status = OrderStatus.Ready;
+        _mockUpdateOrderStatusUseCase.Setup(r => r.ExecuteAsync(It.Is<UpdateOrderStatusRequest>(
+            req => req.OrderId == orderId && req.Status == status)))
             .ReturnsAsync(true)
             .Verifiable();

171-186: Consider adding positive test case for payment updates

While the error case is well tested, consider adding a positive test case to verify successful payment updates.

[Fact]
public async Task UpdateOrderPaymentAsync_ShouldSucceed_WhenUseCaseExecutesSuccessfully()
{
    // Arrange
    var orderId = Guid.NewGuid();
    var paymentId = new PaymentId(Guid.NewGuid());
    _mockUpdateOrderPaymentUseCase.Setup(x => x.Execute(orderId, paymentId)).ReturnsAsync(true);

    // Act
    await _target.UpdateOrderPaymentAsync(orderId, paymentId);

    // Assert
    _mockUpdateOrderPaymentUseCase.Verify(x => x.Execute(orderId, paymentId), Times.Once);
}
src/FIAP.TechChallenge.ByteMeBurger.Persistence/Repository/OrderRepositoryDapper.cs (1)

Line range hint 1-190: Consider refactoring query mapping for better maintainability.

The current implementation has several areas that could be improved:

  1. Move SQL queries from Constants to dedicated files or embedded resources
  2. Extract complex mapping logic from query delegates to dedicated mapper classes
  3. Consider using Dapper's custom type handlers for domain entities and value objects

This would improve:

  • Testability of mapping logic
  • Maintainability of SQL queries
  • Separation of concerns

Example refactoring for mapping logic:

public class OrderMapper : IOrderMapper
{
    public Order Map(OrderListDto orderDto, Guid? paymentId, CustomerDto? customerDto, OrderItemDto itemDto)
    {
        var customer = customerDto is not null ? new Customer(customerDto.Id) : default;
        var order = new Order(
            orderDto.Id,
            customer,
            (OrderStatus)orderDto.Status,
            new OrderTrackingCode(orderDto.TrackingCode),
            orderDto.Created,
            orderDto.Updated
        );

        if (paymentId.HasValue)
            order.PaymentId = new PaymentId(paymentId.Value);

        order.LoadItems(
            itemDto.ProductId,
            itemDto.ProductName,
            itemDto.UnitPrice,
            itemDto.Quantity
        );

        return order;
    }
}
tests/FIAP.TechChallenge.ByteMeBurger.Cognito.Gateway.Test/CognitoUserManagerTest.cs (3)

109-124: Consider enhancing the test robustness.

The test correctly verifies the domain exception scenario, but could be improved by:

  1. Extracting the error message to a constant to maintain consistency.
  2. Verifying that the mock was called with the expected parameters.
 public class CognitoUserManagerTest
 {
+    private const string UserExistsErrorMessage = "There's already a customer using the provided CPF value.";
     // ... existing code ...
     
     [Fact]
     public async Task CreateAsync_ShouldThrowDomainException_WhenUsernameExists()
     {
         // Arrange
         var customer = new Customer(Guid.NewGuid(), "28642827041", "Test User", "[email protected]");
 
         _cognitoClientMock.Setup(c => c.AdminCreateUserAsync(It.IsAny<AdminCreateUserRequest>(), default))
             .ThrowsAsync(new UsernameExistsException("Username already exists"));
 
         // Act
         Func<Task> act = async () => await _userManager.CreateAsync(customer);
 
         // Assert
         await act.Should().ThrowAsync<DomainException>()
-            .WithMessage("There's already a customer using the provided CPF value.");
+            .WithMessage(UserExistsErrorMessage);
+        _cognitoClientMock.Verify(c => c.AdminCreateUserAsync(
+            It.Is<AdminCreateUserRequest>(req => 
+                req.Username == customer.Cpf.Value && 
+                req.UserAttributes.Any(attr => attr.Name == "email" && attr.Value == customer.Email)),
+            default), 
+            Times.Once);
     }

126-142: Consider improving error handling specificity.

While the test correctly verifies unexpected error handling, consider:

  1. Using a more specific exception type instead of generic Exception.
  2. Adding mock verification to ensure the method was called.
+    private class CognitoUnexpectedError : Exception 
+    {
+        public CognitoUnexpectedError(string message) : base(message) { }
+    }

     [Fact]
     public async Task CreateAsync_ShouldThrowException_WhenUnexpectedErrorOccurs()
     {
         // Arrange
         var customer = new Customer(Guid.NewGuid(), "28642827041", "Test User", "[email protected]");
-        var exception = new Exception("Unexpected error");
+        var exception = new CognitoUnexpectedError("Unexpected error");
 
         _cognitoClientMock.Setup(c => c.AdminCreateUserAsync(It.IsAny<AdminCreateUserRequest>(), default))
             .ThrowsAsync(exception);
 
         // Act
         Func<Task> act = async () => await _userManager.CreateAsync(customer);
 
         // Assert
-        await act.Should().ThrowAsync<Exception>()
+        await act.Should().ThrowAsync<CognitoUnexpectedError>()
             .WithMessage("Unexpected error");
+        _cognitoClientMock.Verify(c => c.AdminCreateUserAsync(It.IsAny<AdminCreateUserRequest>(), default), Times.Once);
     }

109-142: Consider adding more edge cases.

The error handling tests are good additions, but consider adding these test cases:

  1. Test with invalid email format
  2. Test with empty or whitespace-only name
  3. Test with invalid CPF format

Would you like me to provide example implementations for these test cases?

tests/FIAP.TechChallenge.ByteMeBurger.Controllers.Test/ProductServiceTest.cs (1)

Line range hint 43-205: Consider enhancing test coverage with edge cases.

While the existing tests are well-structured, consider adding:

  1. Negative test cases for Create/Update with invalid inputs (e.g., negative prices, empty names)
  2. Edge cases for Create_Product_Success (e.g., maximum price, long descriptions)
  3. Replace magic values with meaningful constants or AutoFixture customizations

Example test case to add:

[Theory]
[InlineData(-1)]
[InlineData(0)]
public async Task Create_Product_WithInvalidPrice_ThrowsException(decimal invalidPrice)
{
    // Arrange
    var fixture = new Fixture();
    
    // Act
    var act = () => _target.CreateAsync(
        fixture.Create<string>(),
        fixture.Create<string>(),
        ProductCategory.Drink,
        invalidPrice,
        new[] { "image.jpg" });

    // Assert
    await act.Should().ThrowAsync<ArgumentException>();
}
.github/workflows/dotnet.yml (1)

130-166: LGTM! Consider pinning the Node.js version.

The semantic-release job implementation is well-structured with appropriate permissions and security measures. However, using "lts/*" for Node.js version could potentially introduce unexpected issues if LTS version changes.

Consider pinning to a specific LTS version:

- node-version: "lts/*"
+ node-version: "20.11.1"  # Current LTS version
🧰 Tools
🪛 actionlint

162-162: shellcheck reported issue in this script: SC2086:info:4:28: Double quote to prevent globbing and word splitting

(shellcheck)

🪛 yamllint

[warning] 142-142: wrong indentation: expected 4 but found 6

(indentation)


[error] 154-154: trailing spaces

(trailing-spaces)


[error] 157-157: trailing spaces

(trailing-spaces)


[error] 162-162: trailing spaces

(trailing-spaces)

FIAP.TechChallenge.ByteMeBurger.sln (1)

Line range hint 17-40: Clean up MercadoPago related Kubernetes configurations

The solution no longer includes MercadoPago projects, but the Kubernetes configurations still contain MercadoPago secrets. Consider removing or updating:

  • kubernetes/secret-mercadopago.yaml
src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Orders/UpdateOrderStatusUseCase.cs (2)

14-21: Simplify exception handling in the switch expression.

In the default case of the switch expression, you're throwing a DomainException and wrapping a new Exception inside it, which is unnecessary. You can throw the DomainException directly with the message.

Apply this diff to streamline the exception handling:

-_ => throw new DomainException(nameof(request.NewStatus),
-        new Exception($"Invalid Status '{request.NewStatus}'"))
+_ => throw new DomainException($"Invalid Status '{request.NewStatus}'")

29-42: Rename TryValidateRequest to reflect its behavior accurately.

The method TryValidateRequest throws exceptions when validation fails. In .NET, methods prefixed with 'Try' typically return a boolean indicating success or failure and do not throw exceptions. Consider renaming the method to ValidateRequestAsync to better convey its purpose.

Apply this diff to rename the method and update its usage:

-private async Task<Order> TryValidateRequest(UpdateOrderStatusRequest request)
+private async Task<Order> ValidateRequestAsync(UpdateOrderStatusRequest request)

-    var order = await TryValidateRequest(request);
+    var order = await ValidateRequestAsync(request);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between b192d61 and 5f84cf6.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (82)
  • .env.template (1 hunks)
  • .github/workflows/dotnet.yml (4 hunks)
  • .github/workflows/terraform-plan.yaml (0 hunks)
  • .releaserc (1 hunks)
  • FIAP.TechChallenge.ByteMeBurger.sln (1 hunks)
  • package.json (1 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Api/Auth/JwtOptions.cs (2 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Api/Auth/MercadoPagoMessageAuthorizationFilter.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Api/Controllers/NotificationsController.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Api/Controllers/PaymentsController.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Api/DomainEventsHandler.cs (4 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Api/FIAP.TechChallenge.ByteMeBurger.Api.csproj (1 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Api/Mappers.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Api/Program.cs (2 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Api/appsettings.Development.json (2 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Application/FIAP.TechChallenge.ByteMeBurger.Application.csproj (1 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Application/ServiceExtensions.cs (2 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Orders/CreateOrderUseCase.cs (3 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Orders/IUpdateOrderStatusUseCase.cs (1 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Orders/UpdateOrderStatusUseCase.cs (1 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Payment/CreatePaymentUseCase.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Payment/ICreatePaymentUseCase.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Payment/IUpdatePaymentStatusUseCase.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Payment/UpdatePaymentStatusUseCase.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Cognito.Gateway/CognitoUserManager.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Controllers/Contracts/IPaymentService.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Controllers/Dto/PaymentDto.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Controllers/FIAP.TechChallenge.ByteMeBurger.Controllers.csproj (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Controllers/OrderService.cs (2 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Controllers/PaymentGatewayFactory.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Controllers/PaymentService.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Controllers/Presenter.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Controllers/ServiceCollectionsExtensions.cs (2 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.DI/FIAP.TechChallenge.ByteMeBurger.DI.csproj (1 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.DI/ServiceCollectionsExtensions.cs (2 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.FakePayment.Gateway/FIAP.TechChallenge.ByteMeBurger.FakePayment.Gateway.csproj (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.FakePayment.Gateway/FakePaymentGatewayService.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.FakePayment.Gateway/ServiceCollectionsExtensions.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Consumers/BaseConsumer.cs (1 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Consumers/OrderPaymentApprovedConsumer.cs (1 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Consumers/OrderStatusChangedConsumer.cs (1 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Consumers/PaymentCreatedConsumer.cs (1 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Dispatcher.cs (1 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Masstransit/FIAP.TechChallenge.ByteMeBurger.Masstransit.csproj (1 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Factory/ISqsClientFactory.cs (1 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Masstransit/ServiceExtensions.cs (1 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway/Configuration/MercadoPagoOptions.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway.csproj (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway/MercadoPagoService.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway/Model/MercadoPagoWebhookEvent.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway/Security/MercadoPagoHmacSignatureValidator.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway/ServiceCollectionsExtensions.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Persistence/Repository/InMemoryPaymentRepository.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Persistence/Repository/OrderRepositoryDapper.cs (1 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Persistence/Repository/PaymentRepositoryDapper.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Persistence/ServiceExtensions.cs (2 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Publisher.Sqs/ServiceExtensions.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Publisher.Sqs/SqsClientFactory.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Publisher.Sqs/SqsService.cs (0 hunks)
  • src/FIAP.TechChallenge.ByteMeBurger.Publisher.Sqs/SqsSettings.cs (0 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/Auth/JwtExtensionsTest.cs (1 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/Auth/MercadoPagoMessageAuthorizationFilterTest.cs (0 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/Controllers/NotificationsControllerTest.cs (0 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/Controllers/PaymentsControllerTest.cs (0 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/Controllers/ProductsControllerTest.cs (0 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/FIAP.TechChallenge.ByteMeBurger.Api.Test.csproj (0 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/PaymentGatewayFactoryTest.cs (0 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Application.Test/UseCases/Orders/CreateOrderUseCaseTest.cs (3 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Application.Test/UseCases/Orders/UpdateOrderStatusUseCaseTest.cs (2 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Application.Test/UseCases/Payment/UpdatePaymentStatusUseCaseTest.cs (0 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Application.Test/UseCases/Payments/CreatePaymentUseCaseTest.cs (0 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Cognito.Gateway.Test/CognitoUserManagerTest.cs (2 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Controllers.Test/OrderServiceTest.cs (5 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Controllers.Test/PaymentServiceTests.cs (0 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Controllers.Test/ProductServiceTest.cs (1 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test/Consumers/OrderPaymentApprovedConsumerTest.cs (1 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test/Consumers/OrderPaymentCreatedConsumerTest.cs (1 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test/Consumers/OrderStatusChangedConsumerTest.cs (1 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test/DispatcherTest.cs (1 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test.csproj (1 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway.Test/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway.Test.csproj (0 hunks)
  • tests/FIAP.TechChallenge.ByteMeBurger.Persistence.Test/Repository/PaymentRepositoryDapperTest.cs (0 hunks)
⛔ Files not processed due to max files limit (4)
  • tests/FIAP.TechChallenge.ByteMeBurger.Publisher.Sqs.Test/SqsClientFactoryTest.cs
  • tests/FIAP.TechChallenge.ByteMeBurger.Publisher.Sqs.Test/SqsServiceTest.cs
  • tf/main.tf
  • tf/variables.tf
💤 Files with no reviewable changes (42)
  • .github/workflows/terraform-plan.yaml
  • src/FIAP.TechChallenge.ByteMeBurger.Api/Auth/MercadoPagoMessageAuthorizationFilter.cs
  • src/FIAP.TechChallenge.ByteMeBurger.Api/Controllers/NotificationsController.cs
  • src/FIAP.TechChallenge.ByteMeBurger.Api/Controllers/PaymentsController.cs
  • src/FIAP.TechChallenge.ByteMeBurger.Api/Mappers.cs
  • src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Payment/CreatePaymentUseCase.cs
  • src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Payment/ICreatePaymentUseCase.cs
  • src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Payment/IUpdatePaymentStatusUseCase.cs
  • src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Payment/UpdatePaymentStatusUseCase.cs
  • src/FIAP.TechChallenge.ByteMeBurger.Cognito.Gateway/CognitoUserManager.cs
  • src/FIAP.TechChallenge.ByteMeBurger.Controllers/Contracts/IPaymentService.cs
  • src/FIAP.TechChallenge.ByteMeBurger.Controllers/Dto/PaymentDto.cs
  • src/FIAP.TechChallenge.ByteMeBurger.Controllers/FIAP.TechChallenge.ByteMeBurger.Controllers.csproj
  • src/FIAP.TechChallenge.ByteMeBurger.Controllers/PaymentGatewayFactory.cs
  • src/FIAP.TechChallenge.ByteMeBurger.Controllers/PaymentService.cs
  • src/FIAP.TechChallenge.ByteMeBurger.Controllers/Presenter.cs
  • src/FIAP.TechChallenge.ByteMeBurger.FakePayment.Gateway/FIAP.TechChallenge.ByteMeBurger.FakePayment.Gateway.csproj
  • src/FIAP.TechChallenge.ByteMeBurger.FakePayment.Gateway/FakePaymentGatewayService.cs
  • src/FIAP.TechChallenge.ByteMeBurger.FakePayment.Gateway/ServiceCollectionsExtensions.cs
  • src/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway/Configuration/MercadoPagoOptions.cs
  • src/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway.csproj
  • src/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway/MercadoPagoService.cs
  • src/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway/Model/MercadoPagoWebhookEvent.cs
  • src/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway/Security/MercadoPagoHmacSignatureValidator.cs
  • src/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway/ServiceCollectionsExtensions.cs
  • src/FIAP.TechChallenge.ByteMeBurger.Persistence/Repository/InMemoryPaymentRepository.cs
  • src/FIAP.TechChallenge.ByteMeBurger.Persistence/Repository/PaymentRepositoryDapper.cs
  • src/FIAP.TechChallenge.ByteMeBurger.Publisher.Sqs/ServiceExtensions.cs
  • src/FIAP.TechChallenge.ByteMeBurger.Publisher.Sqs/SqsClientFactory.cs
  • src/FIAP.TechChallenge.ByteMeBurger.Publisher.Sqs/SqsService.cs
  • src/FIAP.TechChallenge.ByteMeBurger.Publisher.Sqs/SqsSettings.cs
  • tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/Auth/MercadoPagoMessageAuthorizationFilterTest.cs
  • tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/Controllers/NotificationsControllerTest.cs
  • tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/Controllers/PaymentsControllerTest.cs
  • tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/Controllers/ProductsControllerTest.cs
  • tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/FIAP.TechChallenge.ByteMeBurger.Api.Test.csproj
  • tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/PaymentGatewayFactoryTest.cs
  • tests/FIAP.TechChallenge.ByteMeBurger.Application.Test/UseCases/Payment/UpdatePaymentStatusUseCaseTest.cs
  • tests/FIAP.TechChallenge.ByteMeBurger.Application.Test/UseCases/Payments/CreatePaymentUseCaseTest.cs
  • tests/FIAP.TechChallenge.ByteMeBurger.Controllers.Test/PaymentServiceTests.cs
  • tests/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway.Test/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway.Test.csproj
  • tests/FIAP.TechChallenge.ByteMeBurger.Persistence.Test/Repository/PaymentRepositoryDapperTest.cs
✅ Files skipped from review due to trivial changes (3)
  • package.json
  • src/FIAP.TechChallenge.ByteMeBurger.Api/Auth/JwtOptions.cs
  • src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Factory/ISqsClientFactory.cs
🧰 Additional context used
📓 Path-based instructions (27)
src/FIAP.TechChallenge.ByteMeBurger.Api/DomainEventsHandler.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

src/FIAP.TechChallenge.ByteMeBurger.Api/Program.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

src/FIAP.TechChallenge.ByteMeBurger.Application/ServiceExtensions.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Orders/CreateOrderUseCase.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Orders/IUpdateOrderStatusUseCase.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Orders/UpdateOrderStatusUseCase.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

src/FIAP.TechChallenge.ByteMeBurger.Controllers/OrderService.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

src/FIAP.TechChallenge.ByteMeBurger.Controllers/ServiceCollectionsExtensions.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

src/FIAP.TechChallenge.ByteMeBurger.DI/ServiceCollectionsExtensions.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Consumers/BaseConsumer.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Consumers/OrderPaymentApprovedConsumer.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Consumers/OrderStatusChangedConsumer.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Consumers/PaymentCreatedConsumer.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Dispatcher.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

src/FIAP.TechChallenge.ByteMeBurger.Masstransit/ServiceExtensions.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

src/FIAP.TechChallenge.ByteMeBurger.Persistence/Repository/OrderRepositoryDapper.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

src/FIAP.TechChallenge.ByteMeBurger.Persistence/ServiceExtensions.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/Auth/JwtExtensionsTest.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

tests/FIAP.TechChallenge.ByteMeBurger.Application.Test/UseCases/Orders/CreateOrderUseCaseTest.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

tests/FIAP.TechChallenge.ByteMeBurger.Application.Test/UseCases/Orders/UpdateOrderStatusUseCaseTest.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

tests/FIAP.TechChallenge.ByteMeBurger.Cognito.Gateway.Test/CognitoUserManagerTest.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

tests/FIAP.TechChallenge.ByteMeBurger.Controllers.Test/OrderServiceTest.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

tests/FIAP.TechChallenge.ByteMeBurger.Controllers.Test/ProductServiceTest.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

tests/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test/Consumers/OrderPaymentApprovedConsumerTest.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

tests/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test/Consumers/OrderPaymentCreatedConsumerTest.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

tests/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test/Consumers/OrderStatusChangedConsumerTest.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

tests/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test/DispatcherTest.cs (1)

Pattern **/*.cs: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.

🪛 actionlint
.github/workflows/dotnet.yml

162-162: shellcheck reported issue in this script: SC2086:info:4:28: Double quote to prevent globbing and word splitting

(shellcheck)


184-184: shellcheck reported issue in this script: SC2086:info:3:28: Double quote to prevent globbing and word splitting

(shellcheck)

🪛 yamllint
.github/workflows/dotnet.yml

[warning] 142-142: wrong indentation: expected 4 but found 6

(indentation)


[error] 154-154: trailing spaces

(trailing-spaces)


[error] 157-157: trailing spaces

(trailing-spaces)


[error] 162-162: trailing spaces

(trailing-spaces)


[warning] 182-182: wrong indentation: expected 4 but found 6

(indentation)

🪛 GitHub Check: build
src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Orders/CreateOrderUseCase.cs

[warning] 59-59:
Possible null reference argument for parameter 'Name' in 'CustomerReplicaDto.CustomerReplicaDto(Guid Id, string Cpf, string Name, string Email)'.


[warning] 60-60:
Possible null reference argument for parameter 'Email' in 'CustomerReplicaDto.CustomerReplicaDto(Guid Id, string Cpf, string Name, string Email)'.


[warning] 64-64:
Possible null reference argument for parameter 'paymentId' in 'OrderCreated.OrderCreated(Guid id, CustomerReplicaDto? customer, List items, OrderStatus status, string orderTrackingCode, PaymentId paymentId, decimal total)'.

🔇 Additional comments (50)
src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Orders/IUpdateOrderStatusUseCase.cs (1)

15-15: Good use of record type for the request DTO!

The UpdateOrderStatusRequest record provides immutability and encapsulates related parameters effectively.

Let's verify that the request is properly validated in the use case implementation:

✅ Verification successful

Request validation is properly implemented

The implementation includes appropriate validation in the TryValidateRequest method which:

  • Verifies the order exists
  • Checks if the order is not already completed
  • The ExecuteAsync method also validates the new status through pattern matching
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for validation of UpdateOrderStatusRequest in the implementation
ast-grep --pattern 'class UpdateOrderStatusUseCase {
  $$$
  TryValidateRequest($request) {
    $$$
  }
  $$$
}'

Length of output: 114


Script:

#!/bin/bash
# Let's try a broader search for the UpdateOrderStatusUseCase implementation
rg -l "UpdateOrderStatusUseCase" 

# Then search for any validation patterns in the implementation
ast-grep --pattern 'public class UpdateOrderStatusUseCase {
  $$$
}'

# Also search for FluentValidation usage
rg -l "FluentValidation|AbstractValidator.*UpdateOrderStatusRequest"

Length of output: 606


Script:

#!/bin/bash
# Let's examine the implementation file directly
cat src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Orders/UpdateOrderStatusUseCase.cs

# Also check if there's any validator in the same directory
rg -l "Validator" src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Orders/

Length of output: 1649

.releaserc (1)

11-16: Consider error handling for VERSION file creation

The verifyReleaseCmd writes to a VERSION file without checking for write permissions or handling potential errors. This could cause issues in CI/CD pipelines if the file operation fails.

Run the following script to check VERSION file handling in workflows:

src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Consumers/PaymentCreatedConsumer.cs (1)

1-6: LGTM! Dependencies follow Clean Architecture principles

The dependencies are well-organized, following the proper layering of Clean Architecture with domain and application dependencies.

src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Consumers/OrderStatusChangedConsumer.cs (2)

7-11: Well-structured consumer implementation!

The class follows SOLID principles and Clean Architecture patterns with proper dependency injection and separation of concerns. The use of C# 12's primary constructor syntax keeps the code concise while maintaining immutability.


10-10: Verify BaseConsumer implementation

Let's verify the base consumer implementation to ensure proper error handling and message processing.

✅ Verification successful

BaseConsumer implementation is properly handling errors

The BaseConsumer implementation includes appropriate error handling with try-catch blocks and logging:

  • Logs information before processing the event
  • Wraps the use case execution in a try-catch block
  • Logs detailed error information including the event type and exception details
  • Properly rethrows the exception to maintain the error flow
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check BaseConsumer implementation for proper error handling and message processing

# Search for BaseConsumer class definition
echo "Searching for BaseConsumer implementation..."
ast-grep --pattern 'abstract class BaseConsumer<$_, $_, $_> {
  $$$
}'

# Look for error handling patterns in consumer implementations
echo "Checking error handling patterns in consumers..."
rg -l "try\s*{.*}\s*catch" --type cs

# Find all consumer implementations
echo "Finding all consumer implementations..."
ast-grep --pattern 'class $_Consumer : BaseConsumer<$_, $_, $_> {
  $$$
}'

Length of output: 591


Script:

#!/bin/bash
# Let's try a different approach to find the BaseConsumer implementation and its usage

# Search for BaseConsumer class
echo "Searching for BaseConsumer class..."
rg -A 20 "abstract class BaseConsumer" --type cs

# Search for try-catch patterns with proper regex
echo "Checking error handling patterns..."
rg "try.*?\{.*?catch" --type cs -U

# Find consumer implementations
echo "Finding consumer implementations..."
rg "class.*: BaseConsumer" --type cs

Length of output: 2658


Script:

#!/bin/bash
# Let's get the complete BaseConsumer implementation and find all consumers

# Get the complete BaseConsumer implementation
echo "Getting complete BaseConsumer implementation..."
rg -A 30 "abstract class BaseConsumer" --type cs

# Find all consumer implementations with their class definitions
echo "Finding all consumer implementations..."
rg -B 2 -A 5 "class.*: BaseConsumer" --type cs

Length of output: 3277

src/FIAP.TechChallenge.ByteMeBurger.Controllers/ServiceCollectionsExtensions.cs (2)

Line range hint 13-19: Review service lifetimes for consistency

The services are registered with Scoped lifetime, which is appropriate for most business services. However, let's verify the consistency of lifetimes across consumers and handlers.

#!/bin/bash
# Search for other service registrations to verify lifetime consistency
rg "AddScoped|AddTransient|AddSingleton" --type cs

18-18: Consider registering MassTransit consumers and configuration

While the removal of payment services aligns with the PR objectives, I notice that MassTransit-related registrations are missing, despite being mentioned in the PR summary.

Let's verify if MassTransit registrations exist elsewhere:

Would you like me to provide an example of how to properly register MassTransit with its consumers in this service collection?

src/FIAP.TechChallenge.ByteMeBurger.Masstransit/ServiceExtensions.cs (1)

28-28: Verify Dispatcher implementation

The Dispatcher registration looks correct, but let's verify its implementation matches the messaging patterns.

✅ Verification successful

Dispatcher implementation follows messaging patterns correctly

The Dispatcher implementation is well-structured and follows proper messaging patterns:

  • Uses MassTransit's IBus for publishing events
  • Properly handles both domain notifications (IBmbNotification) and integration events (IBmbIntegrationEvent)
  • Includes appropriate error handling and logging
  • Follows scoped lifetime which is suitable for request-scoped messaging
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for Dispatcher implementation to verify it follows messaging patterns
ast-grep --pattern 'class Dispatcher : IDispatcher {
  $$$
}'

# Check for any publish/send methods in the implementation
rg -l "IPublishEndpoint|ISendEndpoint" --type cs

Length of output: 114


Script:

#!/bin/bash
# Let's try a broader search for Dispatcher and IDispatcher
rg -A 10 "class Dispatcher" --type cs
rg -A 5 "interface IDispatcher" --type cs

# Search for any messaging related patterns
rg -A 5 "Publish|Send|Message" --type cs

# Find all cs files that might contain dispatcher implementation
fd -e cs | xargs grep -l "Dispatcher"

Length of output: 38588


Script:

#!/bin/bash
# Let's check the IDispatcher interface definition
rg -A 10 "interface IDispatcher" --type cs

# Let's see the complete Dispatcher implementation
cat src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Dispatcher.cs

Length of output: 1636

src/FIAP.TechChallenge.ByteMeBurger.Masstransit/FIAP.TechChallenge.ByteMeBurger.Masstransit.csproj (3)

13-14: Consider AWS credentials configuration for MassTransit.AmazonSQS

The addition of MassTransit with Amazon SQS requires proper AWS credentials configuration. Ensure the application has the necessary configuration for both development and production environments.

#!/bin/bash
# Check for AWS configuration patterns in the codebase
rg -l "AmazonSQS|AWS" | xargs rg "credentials|accesskey|secretkey|region" -A 3

# Look for potential configuration files
fd -e json -e yaml -e yml | xargs rg "AWS|SQS"

22-24: Verify circular dependency risks

Adding a reference to the Application project while handling events could potentially create circular dependencies. Ensure the event handling logic maintains proper separation of concerns.

#!/bin/bash
# Check for potential circular references
fd -e csproj | xargs rg "ProjectReference.*ByteMeBurger" -A 1

11-11: Verify compatibility with the updated Bmb.Domain.Core package

The significant version jump from 0.0.1 to 0.0.10 might introduce breaking changes.

✅ Verification successful

The previous search didn't yield results, so I'm trying a more comprehensive search to find any usage of the Bmb.Domain.Core package in the codebase. This will help us understand if and how the package is being used, which is crucial for verifying the impact of the version update.


The package update from 0.0.1 to 0.0.10 appears safe to proceed

The extensive usage analysis shows that Bmb.Domain.Core is used consistently across the codebase for core domain entities, value objects, interfaces, and events. The package is primarily used for:

  • Domain entities and value objects (Customer, Order, Product)
  • Core interfaces for repositories and domain services
  • Event handling (Integration and Notification events)
  • Base domain classes and exceptions

The update appears to be part of the planned event-driven architecture changes, and the extensive test coverage (evidenced by test files using these components) provides confidence in the compatibility.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any usage of potentially changed APIs from Bmb.Domain.Core
rg -l "using.*Bmb\.Domain\.Core" | xargs rg "Domain\.Core\." -A 3

Length of output: 6140


Script:

#!/bin/bash
# Search for files that use Bmb.Domain.Core
fd -t f -e cs | xargs rg "using.*Bmb\.Domain\.Core" -l

# Search for any direct usage of Bmb.Domain.Core types
fd -t f -e cs | xargs rg "Bmb\.Domain\.Core\." -B 2 -A 2

Length of output: 55131

tests/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test.csproj (1)

29-30: Verify the transition from SQS to Masstransit

The project reference change from Publisher.Sqs to Masstransit suggests a significant architectural shift in the messaging system. Ensure that:

  1. All existing SQS-related tests have been migrated to use Masstransit
  2. The test coverage remains comprehensive for the new implementation
✅ Verification successful

Migration from SQS to MassTransit is properly implemented with comprehensive test coverage

The verification shows that:

  1. No SQS-related code remains in the test files
  2. MassTransit implementation is well-tested with dedicated test classes:
    • OrderStatusChangedConsumerTest
    • OrderPaymentCreatedConsumerTest
    • OrderPaymentApprovedConsumerTest
    • DispatcherTest

Each consumer test class thoroughly covers:

  • Happy path scenarios
  • Error handling
  • Logging verification
  • Use case integration
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the migration from SQS to Masstransit

# Check for any remaining SQS references in test files
echo "Checking for remaining SQS references in tests..."
rg -l "SQS|Amazon\.SQS" "tests/"

# Check for new Masstransit test coverage
echo "Checking Masstransit test coverage..."
rg -l "class.*Test.*:.*IConsumer<" "tests/"

Length of output: 270


Script:

#!/bin/bash
# Let's try a more comprehensive check

# Check for any SQS-related files or namespaces
echo "Checking for SQS-related files and namespaces..."
fd . tests/ -e cs -x grep -l "Sqs\|SQS"

# Check for Masstransit test files
echo "Checking for Masstransit test files..."
fd . tests/ -e cs -x grep -l "MassTransit\|IConsumer"

# Look for test class definitions in Masstransit test project
echo "Checking test classes in Masstransit test project..."
fd . "tests/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test" -e cs -x cat

# Check project references in test projects
echo "Checking project references..."
fd . tests/ -e csproj -x cat

Length of output: 22728

src/FIAP.TechChallenge.ByteMeBurger.DI/FIAP.TechChallenge.ByteMeBurger.DI.csproj (1)

19-19: LGTM: MassTransit integration looks good

The addition of the MassTransit project reference aligns well with the PR objectives of transitioning to a new event handling system.

src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Consumers/OrderPaymentApprovedConsumer.cs (1)

1-8: LGTM! Dependencies and namespace follow Clean Architecture principles

The dependencies are well-organized, following the dependency rule of Clean Architecture by depending on domain core and application layers while keeping infrastructure concerns (MassTransit) separate.

src/FIAP.TechChallenge.ByteMeBurger.Persistence/ServiceExtensions.cs (1)

35-35: Verify ProductRepositoryDapper implementation

The registration of ProductRepositoryDapper looks correct, but let's verify its implementation exists and implements IProductRepository correctly.

✅ Verification successful

Let me gather more information about the implementation to ensure it has all required interface methods.


Let me try a different approach using ripgrep to check both the interface and implementation.


ProductRepositoryDapper implementation verified successfully

The implementation includes all essential repository operations:

  • FindByIdAsync
  • CreateAsync
  • DeleteAsync
  • GetAll
  • FindByCategory
  • UpdateAsync

Each method is properly implemented as an async Task with appropriate logging. The class correctly implements the IProductRepository interface and has proper dependency injection through its constructor.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify ProductRepositoryDapper implementation exists and implements IProductRepository

# Check if the class exists and implements the interface
ast-grep --pattern 'class ProductRepositoryDapper : IProductRepository
{
  $$$
}'

# Check for required interface methods
rg -A 5 "public class ProductRepositoryDapper"

Length of output: 1625


Script:

#!/bin/bash
# Check the interface definition first
ast-grep --pattern 'interface IProductRepository
{
  $$$
}'

# Then check all public methods in ProductRepositoryDapper
ast-grep --pattern 'public $_ $_($$$)
{
  $$$
}'

Length of output: 112


Script:

#!/bin/bash
# Check interface definition
rg -A 10 "interface IProductRepository"

# Check all public methods in ProductRepositoryDapper
rg -A 2 "public.*Task.*" src/FIAP.TechChallenge.ByteMeBurger.Persistence/Repository/ProductRepositoryDapper.cs

Length of output: 1046

src/FIAP.TechChallenge.ByteMeBurger.DI/ServiceCollectionsExtensions.cs (1)

6-6: ```shell
#!/bin/bash

Let's try a broader search to understand the MassTransit setup

Check for MassTransit related files and their content

rg -l "MassTransit" --type cs

Look for specific MassTransit configurations

rg "ConfigureMassTransit|AddMassTransit|UsingRabbitMq" --type cs -A 5

Check for any message or event classes

ast-grep --pattern 'class $_ {
$$$
}' | rg "Event|Message|Command"

Look for consumer implementations

rg "IConsumer" --type cs -A 3


</details>
<details>
<summary>src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Dispatcher.cs (2)</summary>

`1-8`: **LGTM! Clean dependencies following DDD principles**

The dependencies are well-organized and follow Clean Architecture principles by depending on domain interfaces.

---

`1-49`: **Verify MassTransit configuration and consumer setup**

The Dispatcher implementation looks good from an architectural perspective, but we should verify the MassTransit configuration:

<details>
<summary>✅ Verification successful</summary>

**MassTransit integration is properly configured with Amazon SQS**

The implementation is architecturally sound with:
- Proper MassTransit configuration using Amazon SQS as the message broker
- Well-structured consumer implementations with error handling
- Clean separation of concerns between dispatcher and consumers

The verification shows:
- ServiceExtensions.cs correctly configures MassTransit with Amazon SQS host
- Consumers are properly registered in the DI container
- BaseConsumer provides a robust template with logging and error handling
- PaymentCreatedConsumer demonstrates correct integration with application use cases



</details>

<details>
<summary>🏁 Scripts executed</summary>

The following scripts were executed for the analysis:

Script:

```shell
#!/bin/bash
# Check for MassTransit configuration and consumers
echo "Checking for MassTransit configuration..."
rg -l "AddMassTransit|UsingRabbitMq" --type cs

echo "Checking for event consumers..."
rg -l "class.*Consumer.*IConsumer" --type cs

echo "Checking for event interfaces..."
rg -l "interface.*IBmbNotification|interface.*IBmbIntegrationEvent" --type cs

Length of output: 643


Script:

#!/bin/bash
# Check ServiceExtensions.cs for MassTransit configuration details
echo "Checking MassTransit configuration details..."
rg -A 10 "AddMassTransit" src/FIAP.TechChallenge.ByteMeBurger.Masstransit/ServiceExtensions.cs

# Check consumer implementations
echo "Checking consumer implementations..."
cat src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Consumers/PaymentCreatedConsumer.cs
cat src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Consumers/BaseConsumer.cs

# Check for event interfaces in core domain
echo "Checking core event interfaces..."
fd IBmbNotification --type f --exec cat {}
fd IBmbIntegrationEvent --type f --exec cat {}

Length of output: 2690

src/FIAP.TechChallenge.ByteMeBurger.Application/ServiceExtensions.cs (2)

10-10: LGTM! The class name change improves clarity.

The new name ServiceExtensions is more concise while maintaining clarity about its purpose.


30-31: The changes align well with Clean Architecture principles.

The modifications improve the design by:

  1. Using the generic IUseCase<,> interface for better abstraction
  2. Properly separating order status and payment concerns

Let's verify the related components are properly implemented:

✅ Verification successful

The changes are properly implemented and follow Clean Architecture principles

The verification confirms:

  1. The generic IUseCase<TRequest, TResponse> interface is correctly defined and used
  2. UpdateOrderStatusUseCase properly implements the generic interface with appropriate request/response types
  3. UpdateOrderPaymentUseCase is correctly separated and implements its specific interface
  4. Direct payment processing has been removed, with only test references to MercadoPago remaining
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the new interfaces and implementations exist and follow the same pattern
ast-grep --pattern 'interface IUseCase<$_, $_>
{
  $$$
}'

# Verify the UpdateOrderStatusUseCase implementation
ast-grep --pattern 'class UpdateOrderStatusUseCase : IUseCase<UpdateOrderStatusRequest, bool>
{
  $$$
}'

# Look for any remaining direct payment processing code that should have been removed
rg -g '*.cs' -i "mercadopago|payment.*process"

Length of output: 2449


Script:

#!/bin/bash
# Let's check for the IUseCase interface and its implementations with more context
rg -g '*.cs' -A 5 'interface IUseCase'

# Check for UpdateOrderStatusUseCase implementation with context
rg -g '*.cs' -A 10 'class UpdateOrderStatusUseCase'

# Look for UpdateOrderPaymentUseCase implementation
rg -g '*.cs' -A 10 'class UpdateOrderPaymentUseCase'

Length of output: 6824

src/FIAP.TechChallenge.ByteMeBurger.Api/FIAP.TechChallenge.ByteMeBurger.Api.csproj (1)

21-21: Verify breaking changes in Bmb.Domain.Core upgrade

The significant version bump from 0.0.1 to 0.0.10 might introduce breaking changes. Please ensure all consuming code has been updated accordingly.

tests/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test/Consumers/OrderPaymentCreatedConsumerTest.cs (1)

1-13: LGTM! Well-structured imports and namespace.

The imports are well-organized and the namespace follows the project structure. The TestSubject attribute provides good documentation about the class under test.

src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Orders/CreateOrderUseCase.cs (1)

6-6: LGTM! Clean dependency injection implementation.

The addition of IDispatcher follows SOLID principles and maintains clean architecture boundaries. The naming clearly indicates its purpose for analytics.

Also applies to: 14-14, 17-21

tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/Auth/JwtExtensionsTest.cs (2)

1-10: Well-structured test file with appropriate imports!

Good use of FluentAssertions and TestSubject attribute for better test organization and IDE integration.


14-37: Well-structured test with clear AAA pattern!

Good implementation of the happy path test with clear arrangement of claims and appropriate assertions.

tests/FIAP.TechChallenge.ByteMeBurger.Application.Test/UseCases/Orders/UpdateOrderStatusUseCaseTest.cs (2)

29-29: LGTM! Good use of request objects following Clean Architecture

The introduction of UpdateOrderStatusRequest objects follows Clean Architecture principles by encapsulating the input parameters. This makes the code more maintainable and follows the Single Responsibility Principle.

Also applies to: 55-55, 67-67


Line range hint 1-74: Consider adding tests for event publishing with MassTransit

Given that this PR introduces MassTransit for event handling, consider adding test cases to verify that appropriate events are published when the order status is updated. This would ensure the integration with the new messaging system is properly tested.

tests/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test/Consumers/OrderStatusChangedConsumerTest.cs (2)

1-14: LGTM! Well-structured test file setup

The imports are well-organized and the TestSubject attribute properly documents the class under test.


60-76: LGTM! Comprehensive error handling test

The error handling test is well-structured, verifying both the exception propagation and error logging.

tests/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test/Consumers/OrderPaymentApprovedConsumerTest.cs (1)

1-79: Overall implementation follows testing best practices

The test class is well-structured and follows Clean Architecture principles with good coverage of the main scenarios:

  • Proper separation of concerns
  • Good use of mocking
  • Clear Arrange-Act-Assert pattern
  • Comprehensive error handling

The suggested improvements above will further enhance the test quality, but the current implementation is solid.

tests/FIAP.TechChallenge.ByteMeBurger.Masstransit.Test/DispatcherTest.cs (2)

1-12: LGTM! Well-organized imports and namespace.

The file structure follows C# conventions and includes all necessary dependencies for testing.


1-106: Verify event handling architecture alignment with DDD principles.

The tests demonstrate good coverage of the event dispatcher functionality. However, let's ensure the event handling architecture aligns with DDD principles.

Let's verify the event handling implementation:

✅ Verification successful

Let me gather more information about the event handling implementation to make a thorough assessment.


Event handling architecture follows DDD principles correctly

The implementation demonstrates proper separation of concerns and alignment with DDD principles:

  • Clear distinction between domain notifications (IBmbNotification) and integration events (IBmbIntegrationEvent)
  • Generic BaseConsumer properly handles events through use cases, maintaining domain isolation
  • Dispatcher correctly implements event publishing with proper error handling and logging
  • Event consumers are properly integrated with MassTransit infrastructure while keeping the domain logic separate

The test implementation accurately verifies this architecture.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify event handling implementation follows DDD principles

# Check if events are properly segregated in the domain
ast-grep --pattern 'interface IBmbNotification {
  $$$
}'

# Check if integration events are properly separated
ast-grep --pattern 'interface IBmbIntegrationEvent {
  $$$
}'

# Check for proper event handlers/consumers
rg -l "IConsumer<.*Event>"

Length of output: 226


Script:

#!/bin/bash
# Check the base consumer implementation
cat src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Consumers/BaseConsumer.cs

# Look for event definitions
rg -g "!*.{json,md}" "class.*Event.*:"

# Check dispatcher implementation
fd "Dispatcher.cs" --type f --exec cat {} \;

Length of output: 3221

src/FIAP.TechChallenge.ByteMeBurger.Api/DomainEventsHandler.cs (3)

34-37: LGTM: Event handler registration changes are consistent

The removal of payment-related event subscriptions aligns with the PR objective of removing payment functionality.


111-114: LGTM: Event handler cleanup is properly maintained

The unsubscription of event handlers in the Dispose method correctly mirrors the constructor changes, ensuring proper cleanup.


54-58: 🛠️ Refactor suggestion

Remove commented code instead of keeping it

Rather than keeping commented code, it should be removed entirely. Git history will preserve these implementations if needed in the future.

-    // private void OnOrderPaymentConfirmed(object? sender, OrderPaymentConfirmed e)
-    // {
-    //     _logger.LogInformation("Order: {OrderId} payment confirmed", e.Payload);
-    //     InvalidateOrderCache(e.Payload.OrderId);
-    // }

-    // private void OnPaymentCreated(object? sender, PaymentCreated e)
-    // {
-    //     _logger.LogInformation("Payment {PaymentId} created for Order: {OrderId}", e.Payload.Id.Value,
-    //         e.Payload.OrderId);
-    // }

Let's verify there are no remaining references to these events:

Also applies to: 84-88

tests/FIAP.TechChallenge.ByteMeBurger.Controllers.Test/OrderServiceTest.cs (3)

21-23: LGTM! Clean interface refactoring

The change to use IUseCase<UpdateOrderStatusRequest, bool> follows the Interface Segregation Principle by using a more specific interface. The addition of IUpdateOrderPaymentUseCase maintains consistency with the existing pattern.


34-40: LGTM! Constructor properly initialized with all dependencies

The constructor correctly initializes all mocks and injects them in a consistent order. The dependency injection follows Clean Architecture principles.


110-110: LGTM! Correct initial order status verification

The test correctly verifies that new orders start with PaymentPending status, which aligns with the PR's objective of removing the previous payment implementation.

src/FIAP.TechChallenge.ByteMeBurger.Persistence/Repository/OrderRepositoryDapper.cs (1)

104-105: Consider strengthening domain invariants around Customer-Order relationship.

While the null check improves robustness, it raises questions about the domain model:

  1. Should an Order exist without a Customer in the domain?
  2. If a Customer is optional, this business rule should be explicitly documented in the domain model.

Consider one of these approaches:

  1. If Customer is required:
    • Make Customer a required property in Order
    • Enforce this in the Order constructor
    • Throw domain exception for null customers
  2. If Customer is optional:
    • Document this business rule in Order entity
    • Consider using Optional or similar pattern

Let's verify the domain rules around Customer-Order relationship:

tests/FIAP.TechChallenge.ByteMeBurger.Cognito.Gateway.Test/CognitoUserManagerTest.cs (1)

3-3: LGTM!

The added using statement is correctly placed and necessary for the DomainException type used in the new test cases.

tests/FIAP.TechChallenge.ByteMeBurger.Controllers.Test/ProductServiceTest.cs (3)

5-6: LGTM! Namespace change aligns with Clean Architecture.

The namespace change from Application.Test.Services to Controllers.Test better reflects the layer being tested, following Clean Architecture principles. The added using directives properly support the test functionality.

Also applies to: 13-13


Line range hint 16-41: Well-structured test class following SOLID principles.

The test class demonstrates good practices:

  • Clean dependency injection through constructor
  • Proper mocking of all dependencies
  • Clear separation of concerns
  • Easy to maintain and extend

Line range hint 159-205: Verify ProductGenerator implementation for comprehensive test data generation.

The tests use a custom ProductGenerator for AutoFixture, but its implementation is not visible. To ensure thorough testing:

✅ Verification successful

ProductGenerator implementation is well-structured and consistently used across tests

The ProductGenerator is properly implemented as an ISpecimenBuilder that creates valid Product entities with all required properties (name, description, category, price, and images). It's consistently used across different test projects:

  • Application tests
  • Controller tests
  • API tests

All test files follow the same pattern of registering the generator with AutoFixture's customizations, ensuring uniform test data generation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Locate and analyze the ProductGenerator implementation
# Expected: Find a class that implements ISpecimenBuilder for Product entities

# Search for ProductGenerator implementation
rg -l "class ProductGenerator"

# Search for test data generation patterns
ast-grep --pattern 'class $_ : ISpecimenBuilder {
  $$$
  Create($$$) {
    $$$
  }
}'

Length of output: 191


Script:

#!/bin/bash
# Let's examine the ProductGenerator implementation
cat tests/FIAP.TechChallenge.ByteMeBurger.Test.Common/ProductGenerator.cs

# Also search for any other test data generation patterns in test files
rg "fixture\.Create<Product>" -A 2 -B 2

Length of output: 4742

.github/workflows/dotnet.yml (2)

Line range hint 256-272: Verify completeness of environment variable changes.

The removal of MercadoPago variables and addition of JWT variables aligns with the architectural changes. However, we should verify that all necessary JWT-related variables are included and that no other payment-related configurations need to be removed.

#!/bin/bash
# Search for any remaining MercadoPago references
echo "Checking for remaining MercadoPago references..."
rg -i "mercadopago|payment" --type yaml

# Search for JWT configuration references to ensure completeness
echo "Checking for JWT configuration references..."
rg -i "jwt|authentication|authorization" --type cs
🧰 Tools
🪛 actionlint

162-162: shellcheck reported issue in this script: SC2086:info:4:28: Double quote to prevent globbing and word splitting

(shellcheck)

🪛 yamllint

[warning] 142-142: wrong indentation: expected 4 but found 6

(indentation)


[error] 154-154: trailing spaces

(trailing-spaces)


[error] 157-157: trailing spaces

(trailing-spaces)


[error] 162-162: trailing spaces

(trailing-spaces)


229-236: Verify Dockerfile path change impact.

The Dockerfile path has been updated to ./src/Bmb.Payment.Api/Dockerfile. This change suggests a significant architectural modification.

✅ Verification successful

Docker configuration is correctly placed and consistent

The Dockerfile path change in the GitHub workflow is valid and reflects the actual structure of the repository. The verification shows:

  • The Dockerfile exists at the specified path ./src/FIAP.TechChallenge.ByteMeBurger.Api/Dockerfile
  • It's a new file added as part of the codebase restructuring
  • The configuration is appropriate for a .NET API project
  • There's also a separate Dockerfile for the database component at ./database/Dockerfile

This change does not indicate architectural issues but rather shows proper organization of Docker assets within their respective component directories.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify the Dockerfile exists and contains expected configurations
if [ -f "./src/Bmb.Payment.Api/Dockerfile" ]; then
  echo "Checking Dockerfile contents..."
  cat "./src/Bmb.Payment.Api/Dockerfile"
else
  echo "Error: Dockerfile not found at specified path"
  # Check if it was moved
  find . -name "Dockerfile" -type f
fi

Length of output: 5333


Script:

#!/bin/bash
# Let's check for Dockerfile locations and their history
echo "Finding all Dockerfiles in the repository:"
find . -name "Dockerfile" -type f

echo -e "\nChecking git history for Dockerfile changes:"
git log --full-history -p -- "**/Dockerfile"

echo -e "\nChecking if there are any other Docker-related files:"
find . -type f -name "docker-compose*.yml" -o -name "*.dockerfile" -o -name "Dockerfile.*"

Length of output: 2415

FIAP.TechChallenge.ByteMeBurger.sln (2)

70-72: LGTM! New Masstransit projects follow the solution's architecture

The new projects are correctly organized:

  • FIAP.TechChallenge.ByteMeBurger.Masstransit under Adapters
  • FIAP.TechChallenge.ByteMeBurger.Masstransit.Test under tests

70-72: Verify Masstransit project references

Let's verify that the new Masstransit projects have all necessary references set up correctly.

✅ Verification successful

MassTransit project references are properly configured

The verification shows that the MassTransit projects have appropriate references:

  • Main project (FIAP.TechChallenge.ByteMeBurger.Masstransit.csproj):

    • Has required MassTransit packages: MassTransit and MassTransit.AmazonSQS
    • Includes necessary AWS SDK for SQS integration
    • References the Application project correctly
    • Contains all required Microsoft.Extensions dependencies
  • Test project (FIAP.TechChallenge.ByteMeBurger.Masstransit.Test.csproj):

    • References the main MassTransit project
    • Includes appropriate testing packages
    • References the test common project
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check project references in the new Masstransit projects

# Find and examine .csproj files for the new projects
echo "Checking Masstransit project references:"
fd -e csproj . -x grep -l "Masstransit" {} \; -exec cat {}

# Check for MassTransit NuGet package references
echo -e "\nChecking MassTransit package references:"
fd -e csproj . -x grep -l "MassTransit" {} \; -exec cat {}

Length of output: 595


Script:

#!/bin/bash
# Let's fix the command syntax and try again

# Check Masstransit project files
echo "=== Masstransit Project Files ==="
fd -e csproj . | grep -i "masstransit"

# Display contents of Masstransit project files
echo -e "\n=== Masstransit Project Contents ==="
for proj in $(fd -e csproj . | grep -i "masstransit"); do
    echo -e "\nFile: $proj"
    cat "$proj"
done

# Check for any MassTransit package references
echo -e "\n=== Files with MassTransit Package References ==="
rg -l "MassTransit" --type csproj

Length of output: 4043

src/FIAP.TechChallenge.ByteMeBurger.Masstransit/Consumers/BaseConsumer.cs (1)

7-34: Code aligns with Domain Driven Design, SOLID, and Clean Architecture principles

The BaseConsumer class is well-designed, promoting code reuse and separation of concerns. It adheres to SOLID principles, especially the Open/Closed Principle and Dependency Inversion Principle. The use of generics and dependency injection enhances modularity and maintainability.

src/FIAP.TechChallenge.ByteMeBurger.Application/UseCases/Orders/UpdateOrderStatusUseCase.cs (2)

8-8: ⚠️ Potential issue

Correct the class declaration syntax.

The class UpdateOrderStatusUseCase uses constructor syntax directly in the class declaration, which is not valid in C#. Constructors should be defined inside the class body. This might lead to a compilation error.

Apply this diff to fix the class declaration:

-public class UpdateOrderStatusUseCase(IOrderRepository repository) : IUseCase<UpdateOrderStatusRequest, bool>
+public class UpdateOrderStatusUseCase : IUseCase<UpdateOrderStatusRequest, bool>
+{
+    private readonly IOrderRepository repository;
+
+    public UpdateOrderStatusUseCase(IOrderRepository repository)
+    {
+        this.repository = repository;
+    }

Likely invalid or redundant comment.


26-26: Ensure exception handling for repository update.

When calling repository.UpdateOrderStatusAsync(order), any exceptions thrown by the repository layer may not be handled. Ensure that exceptions are properly caught and managed to prevent unhandled exceptions that could impact application stability.

Run the following script to check for exception handling in the repository implementation:

Comment on lines +4 to +7
JwtOptions__Issuer=https://localhost:7000
JwtOptions__Audience=https://localhost:7000
JwtOptions__ExpirationSeconds=300
JwtOptions__UseAccessToken=false
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

JWT configuration in .env.template needs alignment with production settings

The verification reveals that the JWT configuration in .env.template needs to be aligned with the production settings found in the infrastructure code:

  • Production settings in tf/main.tf use:
    • 1-hour token expiration (3600 seconds) vs 5 minutes in template
    • Access tokens enabled (UseAccessToken=true) vs disabled in template
    • Dynamic issuer/audience values from terraform locals
  • The JWT implementation in JwtExtensions.cs properly validates all claims including issuer, audience, and lifetime
  • The configuration is properly integrated with the application in Program.cs

Please update .env.template to match production settings:

JwtOptions__ExpirationSeconds=3600
JwtOptions__UseAccessToken=true
🔗 Analysis chain

Verify JWT configuration settings

The JWT configuration uses localhost URLs and a short expiration time. Please ensure these settings align with your requirements:

  • Both Issuer and Audience are set to https://localhost:7000
  • Token expires in 5 minutes (300 seconds)
  • Access token usage is disabled

Run the following script to check JWT configuration usage across the codebase:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify JWT configuration usage and related authentication setup

# Check for JWT authentication setup in Program.cs or Startup.cs
echo "Checking JWT authentication setup..."
rg -l "AddAuthentication|JwtBearerDefaults" 

# Check for JWT token validation parameters
echo "Checking JWT validation parameters..."
rg "TokenValidationParameters" -A 10

# Check for JWT configuration usage
echo "Checking JWT configuration usage..."
rg "JwtOptions" -A 5

Length of output: 4814

Comment on lines +2 to +5
"branches": [
"main",
"semantic-release-plugins"
],
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Remove "semantic-release-plugins" from release branches

The "semantic-release-plugins" branch doesn't exist in the repository, and there's no historical context justifying its inclusion in the release configuration. This appears to be an unintended inclusion that should be removed to prevent potential issues with semantic releases.

  • Remove "semantic-release-plugins" from the "branches" array in .releaserc, keeping only "main" as the release branch.
🔗 Analysis chain

Verify the purpose of "semantic-release-plugins" branch

The inclusion of "semantic-release-plugins" as a release branch seems unusual. This appears to be a feature or temporary branch rather than a long-term release branch. Consider limiting releases to the "main" branch only, unless there's a specific reason for maintaining multiple release branches.

Run the following script to check the branch usage:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if semantic-release-plugins branch exists and its commit history

# Check branch existence and last commit
git branch -a | grep semantic-release-plugins
git log --oneline semantic-release-plugins 2>/dev/null || echo "Branch not found"

Length of output: 135


Script:

#!/bin/bash
# Let's check the git history to understand the context of this configuration
git log --all --full-history -- .releaserc

# Also check if there are any related pull requests
gh pr list --state all --search "semantic-release"

Length of output: 440

@@ -7,13 +7,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Bmb.Domain.Core" Version="0.0.1" />
<PackageReference Include="Bmb.Domain.Core" Version="0.0.10" />
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Based on the analysis of the project files, I can now provide a final response about the package version update:

⚠️ Inconsistent package versions detected across projects

The codebase currently has mixed versions of Bmb.Domain.Core:

  • Version 0.0.10:
    • FIAP.TechChallenge.ByteMeBurger.Application
    • FIAP.TechChallenge.ByteMeBurger.Api
    • FIAP.TechChallenge.ByteMeBurger.Masstransit
  • Version 0.0.1:
    • FIAP.TechChallenge.ByteMeBurger.Persistence
    • FIAP.TechChallenge.ByteMeBurger.Cognito.Gateway
    • FIAP.TechChallenge.ByteMeBurger.Test.Common

This inconsistency in package versions across different projects in the same solution could lead to runtime errors and unexpected behavior. All projects should use the same version of the core domain package.

🔗 Analysis chain

Verify compatibility with Bmb.Domain.Core 0.0.10

The significant version jump from 0.0.1 to 0.0.10 in a pre-1.0 package may introduce breaking changes. Please ensure all consuming code has been updated accordingly.


Let me analyze the results. The output shows extensive usage of Bmb.Domain.Core across the codebase, with imports from several key namespaces:

  1. Bmb.Domain.Core.Base
  2. Bmb.Domain.Core.Entities
  3. Bmb.Domain.Core.Events
  4. Bmb.Domain.Core.Interfaces
  5. Bmb.Domain.Core.ValueObjects

Let me check the changelog or release notes to understand what changes were introduced between versions 0.0.1 and 0.0.10.


Let me try again with corrected command syntax to find project files and any documentation about version changes.


Let me check the actual package references in these project files to see the version patterns and dependencies.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for potential breaking changes by analyzing usages of Bmb.Domain.Core

# Find all C# files that might use Bmb.Domain.Core
echo "Searching for potential usages of Bmb.Domain.Core..."
fd -e cs -x rg -l "using.*Bmb\.Domain\.Core" {}

# Look for specific class usages from this package
echo "Analyzing specific class usages..."
ast-grep --pattern 'using Bmb.Domain.Core.$_'

Length of output: 25375


Script:

#!/bin/bash
# Check for any documentation about breaking changes
echo "Checking for changelog or release notes..."
fd -t f "CHANGELOG|BREAKING|RELEASE" -i

# Look for package.json or similar version tracking files
echo "Looking for version tracking files..."
fd -t f "package.json|*.csproj|*.nuspec" --exec grep -l "Bmb.Domain.Core"

Length of output: 618


Script:

#!/bin/bash
# Check for any documentation about breaking changes
echo "Checking for changelog or release notes..."
fd -g "*CHANGELOG*" -g "*RELEASE*" -g "*BREAKING*"

# Look for project files referencing the package
echo "Looking for project files..."
fd -e csproj -e nuspec -x grep -l "Bmb.Domain.Core" {}

Length of output: 1108


Script:

#!/bin/bash
# Check package references in all csproj files
echo "Checking package references in project files..."
fd -e csproj -x cat {} | grep -A 1 -B 1 "Bmb.Domain.Core"

# Look for any documentation files in the root or docs directory
echo "Looking for documentation..."
fd -t f -d 1 . -e md
fd -t f -d 2 docs -e md

Length of output: 1762

Comment on lines +10 to +13
public async Task Consume(ConsumeContext<PaymentCreated> context)
{
await updateOrderPaymentUseCase.Execute(context.Message.OrderId, new PaymentId(context.Message.PaymentId));
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling and logging for production readiness

While the implementation is functionally correct, consider adding:

  1. Exception handling with appropriate error responses
  2. Logging for observability
  3. Validation of the incoming message

Here's a suggested implementation:

-    public async Task Consume(ConsumeContext<PaymentCreated> context)
-    {
-        await updateOrderPaymentUseCase.Execute(context.Message.OrderId, new PaymentId(context.Message.PaymentId));
-    }
+    private readonly ILogger<PaymentCreatedConsumer> _logger;
+    
+    public async Task Consume(ConsumeContext<PaymentCreated> context)
+    {
+        try
+        {
+            _logger.LogInformation("Processing payment created event for order {OrderId}", context.Message.OrderId);
+            
+            if (string.IsNullOrEmpty(context.Message.PaymentId))
+            {
+                throw new ArgumentException("PaymentId cannot be null or empty");
+            }
+            
+            await updateOrderPaymentUseCase.Execute(
+                context.Message.OrderId,
+                new PaymentId(context.Message.PaymentId));
+                
+            _logger.LogInformation("Successfully processed payment for order {OrderId}", context.Message.OrderId);
+        }
+        catch (Exception ex)
+        {
+            _logger.LogError(ex, "Failed to process payment for order {OrderId}", context.Message.OrderId);
+            throw;
+        }
+    }

Committable suggestion skipped: line range outside the PR's diff.

"WebhookSecret": "1232",
"AccessToken": "123",
"NotificationUrl": "1232"
"MySql": "Server=localhost;Database=bmb;Uid=bmbuser;Pwd=F1ap@#$%c;Port=3306"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Security: Move database credentials to user secrets

The connection string contains sensitive credentials that should not be stored in the configuration file. This poses a security risk, especially if the file is committed to source control.

Consider using user secrets for development:

dotnet user-secrets set "ConnectionStrings:MySql" "Server=localhost;Database=bmb;Uid=bmbuser;Pwd=F1ap@#$%c;Port=3306"

Then modify the configuration to:

-    "MySql": "Server=localhost;Database=bmb;Uid=bmbuser;Pwd=F1ap@#$%c;Port=3306"
+    "MySql": ""

Comment on lines +51 to +65
private OrderCreated Teste(Order order)
{
var orderItemsReplica = order.OrderItems.Select(i =>
new OrderCreated.OrderItemReplicaDto(i.OrderId, i.OrderId, i.ProductName, i.UnitPrice, i.Quantity));

var customer = default(OrderCreated.CustomerReplicaDto);
if (order.Customer is not null)
{
customer = new OrderCreated.CustomerReplicaDto(order.Customer.Id, order.Customer.Cpf, order.Customer.Name,
order.Customer.Email);
}
return new OrderCreated(order.Id, customer
, orderItemsReplica.ToList(), OrderStatus.PaymentPending,
order.TrackingCode.Value, order.PaymentId, order.Total);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add null checks and improve naming.

The method needs several improvements:

  1. Rename to follow English naming conventions
  2. Add null checks for Customer properties
  3. Validate PaymentId before usage

Here's the suggested implementation:

- private OrderCreated Teste(Order order)
+ private OrderCreated CreateOrderCreatedEvent(Order order)
{
    var orderItemsReplica = order.OrderItems.Select(i =>
        new OrderCreated.OrderItemReplicaDto(i.OrderId, i.OrderId, i.ProductName, i.UnitPrice, i.Quantity));

    var customer = default(OrderCreated.CustomerReplicaDto);
    if (order.Customer is not null && 
        !string.IsNullOrEmpty(order.Customer.Name) && 
        !string.IsNullOrEmpty(order.Customer.Email))
    {
        customer = new OrderCreated.CustomerReplicaDto(
            order.Customer.Id,
            order.Customer.Cpf,
            order.Customer.Name!,
            order.Customer.Email!);
    }

    return new OrderCreated(
        order.Id,
        customer,
        orderItemsReplica.ToList(),
        OrderStatus.PaymentPending,
        order.TrackingCode.Value,
        order.PaymentId ?? throw new InvalidOperationException("PaymentId cannot be null"),
        order.Total);
}
📝 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
private OrderCreated Teste(Order order)
{
var orderItemsReplica = order.OrderItems.Select(i =>
new OrderCreated.OrderItemReplicaDto(i.OrderId, i.OrderId, i.ProductName, i.UnitPrice, i.Quantity));
var customer = default(OrderCreated.CustomerReplicaDto);
if (order.Customer is not null)
{
customer = new OrderCreated.CustomerReplicaDto(order.Customer.Id, order.Customer.Cpf, order.Customer.Name,
order.Customer.Email);
}
return new OrderCreated(order.Id, customer
, orderItemsReplica.ToList(), OrderStatus.PaymentPending,
order.TrackingCode.Value, order.PaymentId, order.Total);
}
private OrderCreated CreateOrderCreatedEvent(Order order)
{
var orderItemsReplica = order.OrderItems.Select(i =>
new OrderCreated.OrderItemReplicaDto(i.OrderId, i.OrderId, i.ProductName, i.UnitPrice, i.Quantity));
var customer = default(OrderCreated.CustomerReplicaDto);
if (order.Customer is not null &&
!string.IsNullOrEmpty(order.Customer.Name) &&
!string.IsNullOrEmpty(order.Customer.Email))
{
customer = new OrderCreated.CustomerReplicaDto(
order.Customer.Id,
order.Customer.Cpf,
order.Customer.Name!,
order.Customer.Email!);
}
return new OrderCreated(
order.Id,
customer,
orderItemsReplica.ToList(),
OrderStatus.PaymentPending,
order.TrackingCode.Value,
order.PaymentId ?? throw new InvalidOperationException("PaymentId cannot be null"),
order.Total);
}
🧰 Tools
🪛 GitHub Check: build

[warning] 59-59:
Possible null reference argument for parameter 'Name' in 'CustomerReplicaDto.CustomerReplicaDto(Guid Id, string Cpf, string Name, string Email)'.


[warning] 60-60:
Possible null reference argument for parameter 'Email' in 'CustomerReplicaDto.CustomerReplicaDto(Guid Id, string Cpf, string Name, string Email)'.


[warning] 64-64:
Possible null reference argument for parameter 'paymentId' in 'OrderCreated.OrderCreated(Guid id, CustomerReplicaDto? customer, List items, OrderStatus status, string orderTrackingCode, PaymentId paymentId, decimal total)'.

Comment on lines +43 to +58
[Fact]
public async Task Consume_ShouldCallUseCaseExecuteAsync_WhenEventIsProcessed()
{
// Arrange
var contextMock = new Mock<ConsumeContext<OrderStatusChanged>>();
var orderStatusChanged = new OrderStatusChanged(Guid.NewGuid(), OrderStatus.Completed);
contextMock.Setup(c => c.Message).Returns(orderStatusChanged);

// Act
await _consumer.Consume(contextMock.Object);

// Assert
_useCaseMock.Verify(
x => x.ExecuteAsync(It.IsAny<UpdateOrderStatusRequest>()),
Times.Once);
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Verify use case request parameters

The test confirms that the use case is called but doesn't verify that the correct parameters are passed. Add parameter verification to ensure the event data is properly mapped to the request.

         // Assert
         _useCaseMock.Verify(
-            x => x.ExecuteAsync(It.IsAny<UpdateOrderStatusRequest>()),
+            x => x.ExecuteAsync(It.Is<UpdateOrderStatusRequest>(r => 
+                r.OrderId == orderStatusChanged.OrderId && 
+                r.Status == orderStatusChanged.Status)),
             Times.Once);
📝 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
[Fact]
public async Task Consume_ShouldCallUseCaseExecuteAsync_WhenEventIsProcessed()
{
// Arrange
var contextMock = new Mock<ConsumeContext<OrderStatusChanged>>();
var orderStatusChanged = new OrderStatusChanged(Guid.NewGuid(), OrderStatus.Completed);
contextMock.Setup(c => c.Message).Returns(orderStatusChanged);
// Act
await _consumer.Consume(contextMock.Object);
// Assert
_useCaseMock.Verify(
x => x.ExecuteAsync(It.IsAny<UpdateOrderStatusRequest>()),
Times.Once);
}
[Fact]
public async Task Consume_ShouldCallUseCaseExecuteAsync_WhenEventIsProcessed()
{
// Arrange
var contextMock = new Mock<ConsumeContext<OrderStatusChanged>>();
var orderStatusChanged = new OrderStatusChanged(Guid.NewGuid(), OrderStatus.Completed);
contextMock.Setup(c => c.Message).Returns(orderStatusChanged);
// Act
await _consumer.Consume(contextMock.Object);
// Assert
_useCaseMock.Verify(
x => x.ExecuteAsync(It.Is<UpdateOrderStatusRequest>(r =>
r.OrderId == orderStatusChanged.OrderId &&
r.Status == orderStatusChanged.Status)),
Times.Once);
}

Comment on lines +44 to +59
[Fact]
public async Task Consume_ShouldCallUseCaseExecuteAsync_WhenEventIsProcessed()
{
// Arrange
var contextMock = new Mock<ConsumeContext<OrderPaymentConfirmed>>();
var orderPaymentConfirmed = new OrderPaymentConfirmed(new PaymentId(Guid.NewGuid()), Guid.NewGuid());
contextMock.Setup(c => c.Message).Returns(orderPaymentConfirmed);

// Act
await _consumer.Consume(contextMock.Object);

// Assert
_useCaseMock.Verify(
x => x.ExecuteAsync(It.IsAny<UpdateOrderStatusRequest>()),
Times.Once);
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance use case execution verification

The test verifies that the use case is called but doesn't verify the correctness of the parameters passed or the successful execution.

Consider enhancing the test with parameter verification:

     [Fact]
     public async Task Consume_ShouldCallUseCaseExecuteAsync_WhenEventIsProcessed()
     {
         // Arrange
         var contextMock = new Mock<ConsumeContext<OrderPaymentConfirmed>>();
         var orderPaymentConfirmed = new OrderPaymentConfirmed(new PaymentId(Guid.NewGuid()), Guid.NewGuid());
         contextMock.Setup(c => c.Message).Returns(orderPaymentConfirmed);
+        _useCaseMock.Setup(x => x.ExecuteAsync(It.IsAny<UpdateOrderStatusRequest>()))
+            .ReturnsAsync(true);

         // Act
         await _consumer.Consume(contextMock.Object);

         // Assert
         _useCaseMock.Verify(
-            x => x.ExecuteAsync(It.IsAny<UpdateOrderStatusRequest>()),
+            x => x.ExecuteAsync(It.Is<UpdateOrderStatusRequest>(r => 
+                r.OrderId == orderPaymentConfirmed.OrderId &&
+                r.Status == OrderStatus.PaymentApproved)),
             Times.Once);
     }
📝 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
[Fact]
public async Task Consume_ShouldCallUseCaseExecuteAsync_WhenEventIsProcessed()
{
// Arrange
var contextMock = new Mock<ConsumeContext<OrderPaymentConfirmed>>();
var orderPaymentConfirmed = new OrderPaymentConfirmed(new PaymentId(Guid.NewGuid()), Guid.NewGuid());
contextMock.Setup(c => c.Message).Returns(orderPaymentConfirmed);
// Act
await _consumer.Consume(contextMock.Object);
// Assert
_useCaseMock.Verify(
x => x.ExecuteAsync(It.IsAny<UpdateOrderStatusRequest>()),
Times.Once);
}
[Fact]
public async Task Consume_ShouldCallUseCaseExecuteAsync_WhenEventIsProcessed()
{
// Arrange
var contextMock = new Mock<ConsumeContext<OrderPaymentConfirmed>>();
var orderPaymentConfirmed = new OrderPaymentConfirmed(new PaymentId(Guid.NewGuid()), Guid.NewGuid());
contextMock.Setup(c => c.Message).Returns(orderPaymentConfirmed);
_useCaseMock.Setup(x => x.ExecuteAsync(It.IsAny<UpdateOrderStatusRequest>()))
.ReturnsAsync(true);
// Act
await _consumer.Consume(contextMock.Object);
// Assert
_useCaseMock.Verify(
x => x.ExecuteAsync(It.Is<UpdateOrderStatusRequest>(r =>
r.OrderId == orderPaymentConfirmed.OrderId &&
r.Status == OrderStatus.PaymentApproved)),
Times.Once);
}

@@ -88,7 +86,7 @@ public static void Main(string[] args)
.GetSection("JwtOptions")
.Get<JwtOptions>();
builder.Services.AddSingleton(jwtOptions);

builder.Services.AddHttpLogging(o => { });
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Configure HTTP logging options for security and performance

The HTTP logging is added with empty options, which might lead to overly verbose logging or potential security risks. Consider configuring specific options to control what gets logged.

Apply this configuration:

-builder.Services.AddHttpLogging(o => { });
+builder.Services.AddHttpLogging(options =>
+{
+    options.LoggingFields = Microsoft.AspNetCore.HttpLogging.HttpLoggingFields.RequestPath |
+                           Microsoft.AspNetCore.HttpLogging.HttpLoggingFields.RequestMethod |
+                           Microsoft.AspNetCore.HttpLogging.HttpLoggingFields.ResponseStatusCode;
+    options.RequestBodyLogLimit = 4096;
+    options.ResponseBodyLogLimit = 4096;
+});

Also applies to: 114-114

Comment on lines +182 to +188
- name: Extract version
id: sanitize-version
run: |
echo ${{ needs.semantic-release.outputs.version }}
TAG=${{ needs.semantic-release.outputs.version }}
echo "version=${TAG#v}" >> $GITHUB_OUTPUT

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling for version extraction.

The version extraction step should validate the semantic-release output to prevent potential failures.

- echo ${{ needs.semantic-release.outputs.version }}
- TAG=${{ needs.semantic-release.outputs.version }}
- echo "version=${TAG#v}" >> $GITHUB_OUTPUT
+ if [ -z "${{ needs.semantic-release.outputs.version }}" ]; then
+   echo "Error: No version output from semantic-release"
+   exit 1
+ fi
+ TAG="${{ needs.semantic-release.outputs.version }}"
+ echo "version=${TAG#v}" >> $GITHUB_OUTPUT
📝 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
- name: Extract version
id: sanitize-version
run: |
echo ${{ needs.semantic-release.outputs.version }}
TAG=${{ needs.semantic-release.outputs.version }}
echo "version=${TAG#v}" >> $GITHUB_OUTPUT
- name: Extract version
id: sanitize-version
run: |
if [ -z "${{ needs.semantic-release.outputs.version }}" ]; then
echo "Error: No version output from semantic-release"
exit 1
fi
TAG="${{ needs.semantic-release.outputs.version }}"
echo "version=${TAG#v}" >> $GITHUB_OUTPUT
🧰 Tools
🪛 actionlint

184-184: shellcheck reported issue in this script: SC2086:info:3:28: Double quote to prevent globbing and word splitting

(shellcheck)

🪛 yamllint

[warning] 182-182: wrong indentation: expected 4 but found 6

(indentation)

@italopessoa italopessoa merged commit b5bddae into main Nov 12, 2024
6 of 8 checks passed
Copy link

🎉 This PR is included in version 3.1.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@italopessoa italopessoa deleted the masstransit branch November 12, 2024 02:30
Copy link

🎉 This PR is included in version 3.1.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Phase 4 Microservices Architecture released
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant