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

Refactor Codebase with ChatGPT o3-mini-hight #817

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/Application/Application.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<LangVersion>default</LangVersion>
</PropertyGroup>
<ItemGroup>

<PackageReference Include="SixLabors.ImageSharp" Version="3.1.6" />
<PackageReference Include="Ardalis.Specification" Version="8.0.0" />
<PackageReference Include="Ardalis.Specification.EntityFrameworkCore" Version="8.0.0" />
<PackageReference Include="ClosedXML" Version="0.105.0-rc" />
Expand All @@ -22,10 +22,10 @@
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Riok.Mapperly" Version="4.2.0-next.0" />
<PackageReference Include="Hangfire.Core" Version="1.8.17" />
<PackageReference Include="ZiggyCreatures.FusionCache" Version="2.0.0" />
<PackageReference Include="ActualLab.Fusion" Version="9.8.17" />
<PackageReference Include="ActualLab.Fusion.Blazor" Version="9.8.17" />
<PackageReference Include="ActualLab.Generators" Version="9.8.17">
<PackageReference Include="ZiggyCreatures.FusionCache" Version="2.1.0" />
<PackageReference Include="ActualLab.Fusion" Version="9.8.26" />
<PackageReference Include="ActualLab.Fusion.Blazor" Version="9.8.26" />
<PackageReference Include="ActualLab.Generators" Version="9.8.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
11 changes: 0 additions & 11 deletions src/Application/Common/ExceptionHandlers/ConflictException.cs

This file was deleted.

This file was deleted.

This file was deleted.

11 changes: 0 additions & 11 deletions src/Application/Common/ExceptionHandlers/UnauthorizedException.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,6 @@ public class
where TResponse : Result<int>
where TException : ValidationException
{
private readonly ILogger<ValidationExceptionHandler<TRequest, TResponse, TException>> _logger;

public ValidationExceptionHandler(ILogger<ValidationExceptionHandler<TRequest, TResponse, TException>> logger)
{
_logger = logger;
}

public Task Handle(TRequest request, TException exception, RequestExceptionHandlerState<TResponse> state,
CancellationToken cancellationToken)
Expand Down
4 changes: 4 additions & 0 deletions src/Application/Common/Interfaces/IUploadService.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using SixLabors.ImageSharp.Processing;

namespace CleanArchitecture.Blazor.Application.Common.Interfaces;

public interface IUploadService
{
Task<string> UploadAsync(UploadRequest request);
void Remove(string filename);

Task<string> UploadImageAsync(Stream imageStream, UploadType uploadType, ResizeOptions? resizeOptions = null, string? fileName=null);
}

This file was deleted.

192 changes: 149 additions & 43 deletions src/Application/Common/Models/Result.cs
Original file line number Diff line number Diff line change
@@ -1,65 +1,171 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace CleanArchitecture.Blazor.Application.Common.Models;
namespace CleanArchitecture.Blazor.Application.Common.Models;

/// <summary>
/// Represents the result of an operation.
/// </summary>
public class Result : IResult
{
internal Result()
{
Errors = new string[] { };
}

internal Result(bool succeeded, IEnumerable<string> errors)
/// <summary>
/// Protected constructor to initialize the result.
/// </summary>
/// <param name="succeeded">Indicates whether the operation succeeded.</param>
/// <param name="errors">A collection of error messages.</param>
protected Result(bool succeeded, IEnumerable<string>? errors)
{
Succeeded = succeeded;
Errors = errors.ToArray();
Errors = errors?.ToArray() ?? Array.Empty<string>();
}

public string ErrorMessage => string.Join(", ", Errors ?? new string[] { });

/// <summary>
/// Indicates whether the operation succeeded.
/// </summary>
public bool Succeeded { get; init; }

/// <summary>
/// An array of error messages.
/// </summary>
public string[] Errors { get; init; }

/// <summary>
/// Gets a concatenated string of error messages, separated by commas.
/// </summary>
public string ErrorMessage => string.Join(", ", Errors);

/// <summary>
/// Creates a successful <see cref="Result"/> instance.
/// </summary>
public static Result Success() => new Result(true, Array.Empty<string>());

/// <summary>
/// Asynchronously creates a successful <see cref="Result"/> instance.
/// </summary>
public static Task<Result> SuccessAsync() => Task.FromResult(Success());
public static Result Failure(params string[] errors) => new Result(false, errors);
public static Task<Result> FailureAsync(params string[] errors) => Task.FromResult(Failure(errors));

// Functional extensions
public TResult Match<TResult>(Func<TResult> onSuccess, Func<string, TResult> onFailure) =>
Succeeded ? onSuccess() : onFailure(ErrorMessage);
/// <summary>
/// Creates a failed <see cref="Result"/> instance.
/// </summary>
/// <param name="errors">Error messages.</param>
public static Result Failure(params string[] errors) => new Result(false, errors);

/// <summary>
/// Asynchronously creates a failed <see cref="Result"/> instance.
/// </summary>
/// <param name="errors">Error messages.</param>
public static Task<Result> FailureAsync(params string[] errors) => Task.FromResult(Failure(errors));

public async Task<TResult> MatchAsync<TResult>(Func<Task<TResult>> onSuccess, Func<string, Task<TResult>> onFailure) =>
Succeeded ? await onSuccess() : await onFailure(ErrorMessage);
/// <summary>
/// Executes the appropriate function based on whether the operation succeeded.
/// </summary>
/// <typeparam name="TResult">The return type.</typeparam>
/// <param name="onSuccess">Function to execute if the operation succeeded.</param>
/// <param name="onFailure">Function to execute if the operation failed, with an error message.</param>
public TResult Match<TResult>(Func<TResult> onSuccess, Func<string, TResult> onFailure)
=> Succeeded ? onSuccess() : onFailure(ErrorMessage);

/// <summary>
/// Asynchronously executes the appropriate function based on whether the operation succeeded.
/// </summary>
/// <typeparam name="TResult">The return type.</typeparam>
/// <param name="onSuccess">Asynchronous function to execute if the operation succeeded.</param>
/// <param name="onFailure">Asynchronous function to execute if the operation failed, with an error message.</param>
public Task<TResult> MatchAsync<TResult>(Func<Task<TResult>> onSuccess, Func<string, Task<TResult>> onFailure)
=> Succeeded ? onSuccess() : onFailure(ErrorMessage);
}

/// <summary>
/// Represents the result of an operation that includes data.
/// </summary>
/// <typeparam name="T">The type of the data.</typeparam>
public class Result<T> : Result, IResult<T>
{
public T? Data { get; set; }
public static Result<T> Success(T data) => new Result<T> { Succeeded= true, Data= data };
public static Task<Result<T>> SuccessAsync(T data) => Task.FromResult(Success(data));
public static new Result<T> Failure(params string[] errors) => new Result<T> { Succeeded = false, Errors = errors.ToArray() };
public static new Task<Result<T>> FailureAsync(params string[] errors) => Task.FromResult(new Result<T> { Succeeded = false, Errors = errors.ToArray() });

// Functional extensions
public TResult Match<TResult>(Func<T, TResult> onSuccess, Func<string, TResult> onFailure) =>
Succeeded ? onSuccess(Data!) : onFailure(ErrorMessage);

public async Task<TResult> MatchAsync<TResult>(Func<T, Task<TResult>> onSuccess, Func<string, Task<TResult>> onFailure) =>
Succeeded ? await onSuccess(Data!) : await onFailure(ErrorMessage);

public Result<TResult> Map<TResult>(Func<T, TResult> map) =>
Succeeded ? Result<TResult>.Success(map(Data!)) : Result<TResult>.Failure(Errors);

public async Task<Result<TResult>> MapAsync<TResult>(Func<T, Task<TResult>> map) =>
Succeeded ? Result<TResult>.Success(await map(Data!)) : await Result<TResult>.FailureAsync(Errors);
/// <summary>
/// The data contained in the result.
/// </summary>
public T? Data { get; init; }

/// <summary>
/// Protected constructor to initialize a result with data.
/// </summary>
/// <param name="succeeded">Indicates whether the operation succeeded.</param>
/// <param name="errors">A collection of error messages.</param>
/// <param name="data">The data returned from the operation.</param>
protected Result(bool succeeded, IEnumerable<string>? errors, T? data)
: base(succeeded, errors)
{
Data = data;
}

public Result<TResult> Bind<TResult>(Func<T, Result<TResult>> bind) =>
Succeeded ? bind(Data!) : Result<TResult>.Failure(Errors);
/// <summary>
/// Creates a successful <see cref="Result{T}"/> instance with the specified data.
/// </summary>
/// <param name="data">The data to include in the result.</param>
public static Result<T> Success(T data) => new Result<T>(true, Array.Empty<string>(), data);

public async Task<Result<TResult>> BindAsync<TResult>(Func<T, Task<Result<TResult>>> bind) =>
Succeeded ? await bind(Data!) : await Result<TResult>.FailureAsync(Errors);
/// <summary>
/// Asynchronously creates a successful <see cref="Result{T}"/> instance with the specified data.
/// </summary>
/// <param name="data">The data to include in the result.</param>
public static Task<Result<T>> SuccessAsync(T data) => Task.FromResult(Success(data));

}
/// <summary>
/// Creates a failed <see cref="Result{T}"/> instance.
/// </summary>
/// <param name="errors">Error messages.</param>
public static new Result<T> Failure(params string[] errors) => new Result<T>(false, errors, default);

/// <summary>
/// Asynchronously creates a failed <see cref="Result{T}"/> instance.
/// </summary>
/// <param name="errors">Error messages.</param>
public static new Task<Result<T>> FailureAsync(params string[] errors) => Task.FromResult(Failure(errors));

/// <summary>
/// Executes the appropriate function based on whether the operation succeeded.
/// </summary>
/// <typeparam name="TResult">The return type.</typeparam>
/// <param name="onSuccess">Function to execute if the operation succeeded, with the data.</param>
/// <param name="onFailure">Function to execute if the operation failed, with an error message.</param>
public TResult Match<TResult>(Func<T, TResult> onSuccess, Func<string, TResult> onFailure)
=> Succeeded ? onSuccess(Data!) : onFailure(ErrorMessage);

/// <summary>
/// Asynchronously executes the appropriate function based on whether the operation succeeded.
/// </summary>
/// <typeparam name="TResult">The return type.</typeparam>
/// <param name="onSuccess">Asynchronous function to execute if the operation succeeded, with the data.</param>
/// <param name="onFailure">Asynchronous function to execute if the operation failed, with an error message.</param>
public Task<TResult> MatchAsync<TResult>(Func<T, Task<TResult>> onSuccess, Func<string, Task<TResult>> onFailure)
=> Succeeded ? onSuccess(Data!) : onFailure(ErrorMessage);

/// <summary>
/// Maps the data contained in the result to a new type.
/// </summary>
/// <typeparam name="TResult">The type of the mapped data.</typeparam>
/// <param name="map">The mapping function.</param>
public Result<TResult> Map<TResult>(Func<T, TResult> map)
=> Succeeded ? Result<TResult>.Success(map(Data!)) : Result<TResult>.Failure(Errors);

/// <summary>
/// Asynchronously maps the data contained in the result to a new type.
/// </summary>
/// <typeparam name="TResult">The type of the mapped data.</typeparam>
/// <param name="map">The asynchronous mapping function.</param>
public async Task<Result<TResult>> MapAsync<TResult>(Func<T, Task<TResult>> map)
=> Succeeded ? Result<TResult>.Success(await map(Data!)) : await Result<TResult>.FailureAsync(Errors);

/// <summary>
/// Binds the result to another result, allowing for chaining operations.
/// </summary>
/// <typeparam name="TResult">The type of the data in the resulting result.</typeparam>
/// <param name="bind">The binding function that returns a new result.</param>
public Result<TResult> Bind<TResult>(Func<T, Result<TResult>> bind)
=> Succeeded ? bind(Data!) : Result<TResult>.Failure(Errors);

/// <summary>
/// Asynchronously binds the result to another result, allowing for chaining operations.
/// </summary>
/// <typeparam name="TResult">The type of the data in the resulting result.</typeparam>
/// <param name="bind">The asynchronous binding function that returns a new result.</param>
public async Task<Result<TResult>> BindAsync<TResult>(Func<T, Task<Result<TResult>>> bind)
=> Succeeded ? await bind(Data!) : await Result<TResult>.FailureAsync(Errors);
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,16 @@ public class ImportProductsCommandHandler :
private readonly IApplicationDbContext _context;
private readonly IExcelService _excelService;
private readonly IStringLocalizer<ImportProductsCommandHandler> _localizer;
private readonly ISerializer _serializer;

public ImportProductsCommandHandler(
IApplicationDbContext context,
IExcelService excelService,
ISerializer serializer,
IStringLocalizer<ImportProductsCommandHandler> localizer
)
{
_context = context;
_localizer = localizer;
_excelService = excelService;
_serializer = serializer;
}

public async Task<Result<byte[]>> Handle(CreateProductsTemplateCommand request, CancellationToken cancellationToken)
Expand Down Expand Up @@ -84,7 +81,7 @@ public async Task<Result<int>> Handle(ImportProductsCommand request, Cancellatio
_localizer["Pictures"],
(row, item) => item.Pictures = string.IsNullOrEmpty(row[_localizer["Pictures"]].ToString())
? new List<ProductImage>()
: _serializer.Deserialize<List<ProductImage>>(row[_localizer["Pictures"]].ToString())
: JsonSerializer.Deserialize<List<ProductImage>>(row[_localizer["Pictures"]].ToString())
}
}, _localizer["Products"]);
if (!result.Succeeded) return await Result<int>.FailureAsync(result.Errors);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,15 @@ public class ExportProductsQueryHandler :
private readonly IExcelService _excelService;
private readonly IStringLocalizer<ExportProductsQueryHandler> _localizer;
private readonly IPDFService _pdfService;
private readonly ISerializer _serializer;

public ExportProductsQueryHandler(
IApplicationDbContext context,
ISerializer serializer,
IExcelService excelService,
IPDFService pdfService,
IStringLocalizer<ExportProductsQueryHandler> localizer
)
{
_context = context;
_serializer = serializer;
_excelService = excelService;
_pdfService = pdfService;
_localizer = localizer;
Expand Down Expand Up @@ -71,7 +68,7 @@ public async Task<Result<byte[]>> Handle(ExportProductsQuery request, Cancellati
{ _localizer["Description"], item => item.Description },
{ _localizer["Price of unit"], item => item.Price },
{ _localizer["Unit"], item => item.Unit },
{ _localizer["Pictures"], item => _serializer.Serialize(item.Pictures) }
{ _localizer["Pictures"], item => JsonSerializer.Serialize(item.Pictures) }
};
result = await _excelService.ExportAsync(data, mappers, _localizer["Products"]);
break;
Expand Down
Loading
Loading