warnings из общего тела убрано

This commit is contained in:
gorbenko.pavel
2026-07-24 14:05:37 +05:00
parent 5e3ef814f3
commit 06cab46efc
6 changed files with 21 additions and 22 deletions
@@ -1,5 +1,5 @@
namespace Tnsu.ApprovalRoute.Api.Common;
public sealed record ApiResponse<T>(T Data, IReadOnlyList<string> Warnings);
public sealed record ApiResponse<T>(T Data);
public sealed record ApiError(string Message);
@@ -11,8 +11,7 @@ public static class ResultExtensions
if (result.IsFailed)
return result.Errors[0].ToActionResult();
var warnings = result.Reasons.OfType<Warning>().Select(w => w.Message).ToList();
return new OkObjectResult(new ApiResponse<T>(result.Value, warnings));
return new OkObjectResult(new ApiResponse<T>(result.Value));
}
public static IActionResult ToActionResult(this Result result)
@@ -8,5 +8,3 @@ public sealed class NotFoundError(string entity, object id)
public sealed class ValidationError(string message) : Error(message);
public sealed class ConflictError(string message) : Error(message);
public sealed class Warning(string message) : Success(message);
@@ -11,7 +11,8 @@ public sealed record TemplateRouteStepDto(
HeadType HeadType,
RouteStepStatus Status,
int RouteId,
bool AllowReassignToOtherApprovers);
bool AllowReassignToOtherApprovers,
string? Warning = null);
public sealed record CreateTemplateRouteStepRequest(
int OrderNo,
@@ -55,8 +55,7 @@ public sealed class TemplateRouteStepService(ApprovalRouteDbContext db)
db.TemplateRouteSteps.Add(entity);
await db.SaveChangesAsync(cancellationToken);
var result = Result.Ok(ToDto(entity));
return await AppendMissingProjectRoleWarningAsync(route, result, cancellationToken);
return Result.Ok(await ToDtoWithWarningAsync(entity, route, cancellationToken));
}
public async Task<Result<TemplateRouteStepDto>> UpdateAsync(
@@ -83,8 +82,7 @@ public sealed class TemplateRouteStepService(ApprovalRouteDbContext db)
entity.AllowReassignToOtherApprovers = r.AllowReassignToOtherApprovers;
await db.SaveChangesAsync(cancellationToken);
var result = Result.Ok(ToDto(entity));
return await AppendMissingProjectRoleWarningAsync(route, result, cancellationToken);
return Result.Ok(await ToDtoWithWarningAsync(entity, route, cancellationToken));
}
public async Task<Result> DeleteAsync(int routeId, int id, CancellationToken cancellationToken)
@@ -99,18 +97,20 @@ public sealed class TemplateRouteStepService(ApprovalRouteDbContext db)
return Result.Ok();
}
private async Task<Result<TemplateRouteStepDto>> AppendMissingProjectRoleWarningAsync(
TemplateRoute route, Result<TemplateRouteStepDto> result, CancellationToken cancellationToken)
// Для маршрута «по проекту» без единого шага с ролью в проекте DTO несёт предупреждение в поле Warning.
private async Task<TemplateRouteStepDto> ToDtoWithWarningAsync(
TemplateRouteStep entity, TemplateRoute route, CancellationToken cancellationToken)
{
if (!route.ByProject)
return result;
string? warning = null;
if (route.ByProject)
{
var hasProjectRoleStep = await db.TemplateRouteSteps
.AnyAsync(x => x.RouteId == route.Id && x.ProjectRole != ProjectRole.None, cancellationToken);
if (!hasProjectRoleStep)
warning = "Должен быть хотя бы один шаг с ролью в проекте.";
}
var hasProjectRoleStep = await db.TemplateRouteSteps
.AnyAsync(x => x.RouteId == route.Id && x.ProjectRole != ProjectRole.None, cancellationToken);
return hasProjectRoleStep
? result
: result.WithReason(new Warning("Должен быть хотя бы один шаг с ролью в проекте."));
return ToDto(entity) with { Warning = warning };
}
private static TemplateRouteStepDto ToDto(TemplateRouteStep e) => new(
@@ -99,7 +99,8 @@ public sealed class TemplateRouteStepServiceTests : IClassFixture<PostgresDataba
// Assert
created.IsSuccess.ShouldBeTrue();
created.Reasons.ShouldContain(r => r.Message.Contains("ролью в проекте"));
created.Value.Warning.ShouldNotBeNull();
created.Value.Warning.ShouldContain("ролью в проекте");
}
[Fact(DisplayName = "Создание шага с ролью в проекте на маршруте «по проекту» не возвращает предупреждение")]
@@ -116,7 +117,7 @@ public sealed class TemplateRouteStepServiceTests : IClassFixture<PostgresDataba
// Assert
created.IsSuccess.ShouldBeTrue();
created.Reasons.ShouldBeEmpty();
created.Value.Warning.ShouldBeNull();
}
[Fact(DisplayName = "Обновление шага маршрута изменяет исполнителя, статус и разрешение на переназначение")]