Skip to content
Merged
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
29 changes: 24 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
# Riber - Changelog

## v4.0.1 - 19/10/2025
# v4.0.1 - 22/10/2025

- **CORREÇÃO**: Mudança no Job de limpeza de imagens na Bucket
- **MELHORIA**: Nova propriedade para mapear StatusCode no Result

---

## v4.0.0 - 19/10/2025

- **BREAKING CHANGE**: Reestruturação completa da resposta de erros da API
- Adicionada propriedade `type` para identificar o tipo do erro
- Alterada propriedade `messages` (array) para `message` (string única)
- Adicionada propriedade `details` (objeto) para erros de validação agrupados por campo
- Novo formato: `{ "type": "ERROR_TYPE", "message": "...", "details": { "Field": ["error1", "error2"] } }`
- Adicionada propriedade `type` para identificar o tipo do erro
- Alterada propriedade `messages` (array) para `message` (string única)
- Adicionada propriedade `details` (objeto) para erros de validação agrupados por campo
- Novo formato: `{ "type": "ERROR_TYPE", "message": "...", "details": { "Field": ["error1", "error2"] } }`
- **MELHORIA**: Erros de validação agora agrupam múltiplas mensagens por campo
- **MELHORIA**: Formato de erros mais alinhado com padrões modernos de API (inspirado em FastEndpoints)

---

## v3.0.1 - 18/10/2025

- CORREÇÃO: Troca do pacote de versionamento da API
- Ajuste no setup de testes da camada Api para testes de integração
- Ajuste no analyze.sh para ficar mais consistente a validação de ambiente

---

## v3.0.0 - 17/10/2025

- **REFATORAÇÃO**: Mudança na resposta da API, ajustando o Result Pattern
- Remoção da propriedade Details usada para mensagens de validação do FluentValidation
- Remoção da propriedade Message usada para mensagens resumidas
Expand All @@ -28,6 +38,7 @@
---

## v2.3.1 - 12/10/2025

- **NOVO**: Adiciona um novo job para limpeza de imagens não usadas na Bucket
- **CORREÇÃO**: Ajuste no validator de Criação de empresa com administrador
- Usar SHA da action em vez da versão
Expand All @@ -37,6 +48,7 @@
---

## v2.3.0 - 09/10/25

- **NOVO**: Integração do SonarQube no ambiente de desenvolvimento
- Adiciona serviço SonarQube Community no Docker Compose com profile 'analysis'
- Configura banco de dados PostgreSQL dedicado para SonarQube
Expand All @@ -53,6 +65,7 @@
---

## v2.2.0 - 07/10/25

- **NOVO**: Sistema de diagnósticos e rastreamento distribuído
- Adiciona configuração centralizada para ActivitySource na camada Application
- Melhora significativamente o LoggingBehavior com suporte a distributed tracing
Expand All @@ -73,17 +86,20 @@
---

## v2.1.1 - 05/10/25

- Adicionado suporte ao SonarQube para análise de qualidade de código
- Substituídos DTOs por Models no projeto para simplificar a lógica de dados

---

## v2.0.1 - 05/10/25

- **TEMPORÁRIO**: Deploy na AWS suspenso temporariamente

---

## v2.0.0 - 05/10/25

- **BREAKING CHANGE**: Reestruturação das mensagens de erro em módulos organizados
- Remove classe monolítica `ErrorMessage.cs` e substitui por estrutura modular
- Cria subdiretórios organizados: `Common/`, `Entities/` e `ValueObjects/`
Expand All @@ -100,18 +116,21 @@
---

## v1.0.3 - 29/09/25

- Retira os IsFailure do Result Pattern
- Ajustes os testes para remover o Result Pattern
- Correção no token de acesso do GHCR

---

## v1.0.2 - 29/09/25

- Ajusta o CD para usar tags
- Adiciona CHANGELOG.md

---

## v1.0.1 - 28/09/25

- Adiciona validação na criação de produto
- Adiciona testes que faltavam
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<Companies>Samuel Zedec</Companies>
<Copyright>Copyright © $([System.DateTime]::Now.Year)</Copyright>
<Description>Sistema de gestão financeira para um lanchonete local</Description>
<Version>4.0.0</Version>
<Version>4.0.1</Version>
</PropertyGroup>

<!-- Repositório e Documentação -->
Expand Down
9 changes: 9 additions & 0 deletions src/Riber.Api/Common/Api/AppExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ private static void UseMiddlewares(this WebApplication app)
private static void UseConfigurations(this WebApplication app)
{
app.UseExceptionHandler();
app.Use(async (context, next) =>
{
context.Response.Headers.Append("X-Content-Type-Options", "nosniff");
context.Response.Headers.Append("Referrer-Policy", "no-referrer");
context.Response.Headers.Append("X-XSS-Protection", "1; mode=block");
context.Response.Headers.Append("X-Frame-Options", "DENY");
await next();
});

if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
Expand Down
1 change: 1 addition & 0 deletions src/Riber.Api/Common/Api/BuilderExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ private static void AddMiddleware(this WebApplicationBuilder builder)

private static void AddConfigurations(this WebApplicationBuilder builder)
{
builder.WebHost.ConfigureKestrel(options => options.AddServerHeader = false);
builder.Configuration.AddEnvironmentVariables();
builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
builder.Services.AddProblemDetails();
Expand Down
3 changes: 1 addition & 2 deletions src/Riber.Api/Controllers/AuthController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
namespace Riber.Api.Controllers;

[ApiController]
[Authorize]
[Route("api/v{version:apiVersion}/auth")]
[ApiVersion("1.0")]
[Produces("application/json")]
Expand All @@ -32,7 +33,6 @@ public async Task<IActionResult> Login(
}

[HttpGet("permissions")]
[Authorize]
[RequestTimeout(("fast"))]
[ProducesResponseType<Result<GetPermissionsQueryResponse>>(StatusCodes.Status200OK)]
public async Task<IActionResult> GetPermissionsByAuthenticatedUser(CancellationToken cancellationToken)
Expand All @@ -52,7 +52,6 @@ public async Task<IActionResult> GetRefreshToken(CancellationToken cancellationT
}

[HttpPost("logout")]
[Authorize]
[RequestTimeout(("fast"))]
[ProducesResponseType<Result>(StatusCodes.Status200OK)]
public async Task<IActionResult> Logout(CancellationToken cancellationToken)
Expand Down
3 changes: 1 addition & 2 deletions src/Riber.Api/Controllers/CompanyController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
namespace Riber.Api.Controllers;

[ApiController]
[Authorize]
[Route("api/v{version:apiVersion}/company")]
[ApiVersion("1.0")]
[Produces("application/json")]
Expand All @@ -32,7 +33,6 @@ public async Task<IActionResult> CreateCompany(
}

[HttpPut]
[Authorize(AuthenticationSchemes = nameof(AccessTokenSettings))]
[ProducesResponseType<Result<UpdateCompanyCommandResponse>>(StatusCodes.Status200OK)]
[RequirePermission(PermissionsSettings.Companies.Read, PermissionsSettings.Companies.Update)]
[RequestTimeout("standard")]
Expand All @@ -45,7 +45,6 @@ public async Task<IActionResult> UpdateCompany(
}

[HttpGet("{id:guid}")]
[Authorize]
[ProducesResponseType<Result<GetCompanyByIdQueryResponse>>(StatusCodes.Status200OK)]
[RequirePermission(PermissionsSettings.Companies.Read)]
[RequestTimeout("standard")]
Expand Down
1 change: 1 addition & 0 deletions src/Riber.Api/Controllers/UserController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
namespace Riber.Api.Controllers;

[ApiController]
[Authorize]
[Route("api/v{version:apiVersion}/user")]
[ApiVersion("1.0")]
[Produces("application/json")]
Expand Down
12 changes: 0 additions & 12 deletions src/Riber.Api/Extensions/IActionResultExtension.cs

This file was deleted.

10 changes: 10 additions & 0 deletions src/Riber.Api/Extensions/ResultExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Microsoft.AspNetCore.Mvc;
using Riber.Application.Common;

namespace Riber.Api.Extensions;

public static class ResultExtension
{
public static IActionResult ToHttpResult<T>(this Result<T> result)
=> new ObjectResult(result) { StatusCode = (int)result.StatusCode };
}
4 changes: 0 additions & 4 deletions src/Riber.Api/Riber.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,4 @@
<ProjectReference Include="..\Riber.Application\Riber.Application.csproj" />
<ProjectReference Include="..\Riber.Infrastructure\Riber.Infrastructure.csproj" />
</ItemGroup>

<PropertyGroup>
<SonarQubeExclude>true</SonarQubeExclude>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ public interface IImageStorageService
Task<Stream> GetImageStreamAsync(string fileName);

/// <summary>
/// Remove uma imagem do serviço de armazenamento.
/// Remove uma ou mais imagens do serviço de armazenamento.
/// </summary>
/// <param name="fileName">O nome do arquivo da imagem a ser removida.</param>
/// <returns>Uma task representando a operação assíncrona.</returns>
Task DeleteAsync(string fileName);
/// <param name="fileKeys">As chaves dos arquivos das imagens que devem ser removidas.</param>
/// <returns>Um IEnumerable contendo as chaves dos arquivos que foram excluídos.</returns>
Task<IEnumerable<string>> DeleteAllAsync(List<string> fileKeys);
}
23 changes: 12 additions & 11 deletions src/Riber.Application/Common/Result.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using System.Net;
using System.Text.Json.Serialization;
using Riber.Domain.Abstractions;

namespace Riber.Application.Common;
Expand All @@ -7,6 +8,7 @@ public class Result
{
#region Properties

[JsonIgnore] public HttpStatusCode StatusCode { get; }
[JsonInclude] public bool IsSuccess { get; init; }
[JsonInclude] public Error Error { get; init; } = new();

Expand All @@ -17,8 +19,9 @@ public class Result
[JsonConstructor]
protected Result() { }

protected Result(bool isSuccess, Error error)
protected Result(bool isSuccess, Error error, HttpStatusCode statusCode)
{
StatusCode = statusCode;
IsSuccess = isSuccess;
Error = error;
}
Expand All @@ -28,16 +31,13 @@ protected Result(bool isSuccess, Error error)
#region Static Methods

public static Result<object> Success()
=> new(null, true, new Error());
=> new(null, true, new Error(), HttpStatusCode.OK);

public static Result<T> Success<T>(T value)
=> new(value, true, new Error());
public static Result<T> Success<T>(T value, HttpStatusCode statusCode = HttpStatusCode.OK)
=> new(value, true, new Error(), statusCode);

public static Result<T> Failure<T>(Error error)
=> new(default, false, error);

public static Result<T> Failure<T>(string type, Dictionary<string, string[]> details)
=> new(default, false, new Error(type, details));
public static Result<T> Failure<T>(Error error, HttpStatusCode statusCode = HttpStatusCode.BadRequest)
=> new(default, false, error, statusCode);

protected static Result<T> Create<T>(T? value) =>
value is not null ? Success(value) : Failure<T>(new Error());
Expand All @@ -60,7 +60,8 @@ public class Result<T> : Result
[JsonConstructor]
protected Result() { }

protected internal Result(T? value, bool isSuccess, Error error) : base(isSuccess, error)
protected internal Result(T? value, bool isSuccess, Error error, HttpStatusCode statusCode)
: base(isSuccess, error, statusCode)
=> Value = value;

#endregion
Expand Down
14 changes: 3 additions & 11 deletions src/Riber.Application/Extensions/EnumExtension.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel;
using System.Reflection;

namespace Riber.Application.Extensions;

Expand All @@ -7,16 +8,7 @@ public static class EnumExtension
public static string GetDescription(this Enum value)
{
var field = value.GetType().GetField(value.ToString());

if(field is null)
return value.ToString();

var attribute = Attribute
.GetCustomAttribute(field, typeof(DescriptionAttribute))
as DescriptionAttribute;

return attribute is null
? value.ToString()
: attribute.Description;
var attribute = field?.GetCustomAttribute<DescriptionAttribute>();
return attribute?.Description ?? value.ToString();
}
}
6 changes: 6 additions & 0 deletions src/Riber.Domain/Repositories/IProductRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,10 @@ Task<IEnumerable<ProductCategory>> GetCategoriesAsync(
/// <param name="cancellationToken">Token para cancelamento da operação assíncrona.</param>
/// <returns>Uma coleção de imagens não utilizadas.</returns>
Task<IReadOnlyList<Image>> GetUnusedImagesAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Remove uma imagem específica do serviço de armazenamento.
/// </summary>
/// <param name="image">A imagem que deve ser removida.</param>
void DeleteImage(Image image);
}
Loading
Loading