Skip to content

Refactor ReportingManager.GetMerchant and extract merchant mapping to ModelFactory#510

Merged
StuartFerguson merged 5 commits intomainfrom
copilot/reduce-getmerchant-method-complexity
Mar 17, 2026
Merged

Refactor ReportingManager.GetMerchant and extract merchant mapping to ModelFactory#510
StuartFerguson merged 5 commits intomainfrom
copilot/reduce-getmerchant-method-complexity

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 17, 2026

ReportingManager.GetMerchant exceeded the repository’s method-length threshold, triggering the Codacy complexity warning. This change reduces the method to a small orchestration flow without altering its query or mapping behavior, and follows review feedback by moving the merchant model mapping into a dedicated factory.

  • Method decomposition

    • Extracted merchant query construction into BuildMerchantQuery(...)
    • Reduced GetMerchant(...) to the request flow:
      1. load merchant projection
      2. load balance state
      3. convert to Merchant
  • Model factory extraction

    • Moved merchant response mapping into a new static ModelFactory
    • Added ModelFactory.ConvertFrom(...) for converting the merchant projection plus balance into Models.Merchant
  • Projection types

    • Added internal projection types to make the extracted query and conversion explicit and self-contained:
      • MerchantData
      • MerchantAddressData
      • MerchantContactData
    • Moved these projection types into a dedicated DatabaseModels.cs file based on PR feedback
  • Behavior preserved

    • Kept the existing data shape and field mapping intact
    • Scope is limited to the business logic layer:
      • EstateReportingAPI.BusinessLogic/ReportingManager.cs
      • EstateReportingAPI.BusinessLogic/ModelFactory.cs
      • EstateReportingAPI.BusinessLogic/DatabaseModels.cs
public async Task<Result<Merchant>> GetMerchant(MerchantQueries.GetMerchantQuery request, CancellationToken cancellationToken) {
    using ResolvedDbContext<EstateManagementContext>? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, request.EstateId.ToString());
    await using EstateManagementContext context = resolvedContext.Context;

    var merchantQuery = BuildMerchantQuery(context, request.MerchantId);
    var merchantQueryResult = await ExecuteQuerySafeSingleOrDefault(merchantQuery, cancellationToken, "Error getting merchant");
    if (merchantQueryResult.IsFailed) {
        return ResultHelpers.CreateFailure(merchantQueryResult);
    }

    var merchantStateQueryResult = await ExecuteQuerySafeSingleOrDefault(context.MerchantBalanceProjectionState.Where(ms => ms.MerchantId == request.MerchantId), cancellationToken, "Error getting merchant state");
    if (merchantStateQueryResult.IsFailed) return ResultHelpers.CreateFailure(merchantStateQueryResult);

    return Result.Success(ModelFactory.ConvertFrom(merchantQueryResult.Data, merchantStateQueryResult.Data.Balance));
}
Original prompt

This section details on the original issue you should resolve

<issue_title>[Complexity] Method ReportingManager::GetMerchant has 51 lines of code (limit is 50)</issue_title>
<issue_description>

Codacy ID: a71ea2c68fb498894dd38d5048760ade

File: EstateReportingAPI.BusinessLogic/ReportingManager.cs
Line: 1004
Rule: Complexity (Warning)
Commit: c6ec82b8138936189d33b99020db45b30d2d8343

Message: Method ReportingManager::GetMerchant has 51 lines of code (limit is 50)

**Code Snippet:**
```csharp
    public async Task<Result<Merchant>> GetMerchant(MerchantQueries.GetMerchantQuery request, 
```

</issue_description>

Comments on the Issue (you are @copilot in this section)


📱 Kick off Copilot coding agent tasks wherever you are with GitHub Mobile, available on iOS and Android.

Copilot AI and others added 2 commits March 17, 2026 09:47
Co-authored-by: StuartFerguson <[email protected]>
Co-authored-by: StuartFerguson <[email protected]>
Copilot AI changed the title [WIP] [Complexity] Refactor GetMerchant method to reduce lines of code Refactor ReportingManager.GetMerchant to reduce method length Mar 17, 2026
Copilot AI requested a review from StuartFerguson March 17, 2026 09:55
Merchant result = new() {
Balance = merchantState.Balance,

return Result.Success(MapMerchant(merchantQueryResult.Data, merchantStateQueryResult.Data.Balance));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot can this MapMerchant be added to a new static ModelFactory with the method name ConvertFrom

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in b1494d5 — the merchant mapping now lives in a new static ModelFactory as ConvertFrom(...), and ReportingManager.GetMerchant calls that factory.

public bool IsEnabled { get; init; }
}

private sealed class MerchantData {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot Move these new classes to a DatabaseModels.cs file please

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 7901a47 — the new merchant projection classes now live in DatabaseModels.cs, with ModelFactory left focused on ConvertFrom(...).

Copilot AI changed the title Refactor ReportingManager.GetMerchant to reduce method length Refactor ReportingManager.GetMerchant and extract merchant mapping to ModelFactory Mar 17, 2026
Copilot AI requested a review from StuartFerguson March 17, 2026 10:12
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 17, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • f.feedz.io
    • Triggering command: /opt/hostedtoolcache/CodeQL/2.24.3/x64/codeql/csharp/tools/linux64/Semmle.Autobuild.CSharp /opt/hostedtoolcache/CodeQL/2.24.3/x64/codeql/csharp/tools/linux64/Semmle.Autobuild.CSharp (dns block)
    • Triggering command: /usr/bin/dotnet dotnet restore --no-dependencies /home/REDACTED/work/EstateReportingAPI/EstateReportingAPI/EstateReportingAPI.sln --packages /tmp/codeql-scratch-f294ada2fef3658c/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/tmp/codeql-scratch-f294ada2fef3658c/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/tmp/codeql-scratch-f294ada2fef3658c/dbs/csharp/working/emptyFakeDotnetRoot /p:AllowMissingPrunePackageData=true (dns block)
    • Triggering command: /usr/bin/dotnet dotnet restore --no-dependencies /home/REDACTED/work/EstateReportingAPI/EstateReportingAPI/EstateReportingAPI/EstateReportingAPI.csproj --packages /tmp/codeql-scratch-f294ada2fef3658c/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/tmp/codeql-scratch-f294ada2fef3658c/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/tmp/codeql-scratch-f294ada2fef3658c/dbs/csharp/working/emptyFakeDotnetRoot /p:AllowMissingPrunePackageData=true (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@StuartFerguson StuartFerguson marked this pull request as ready for review March 17, 2026 10:41
@StuartFerguson StuartFerguson merged commit b5a8927 into main Mar 17, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Complexity] Method ReportingManager::GetMerchant has 51 lines of code (limit is 50)

2 participants