Files
tnsu-approval-route/backend/Tnsu.ApprovalRoute.Api/Controllers/RequestManageController.cs
T
gorbenko.pavel e6a330ba27
Tests / backend-test (pull_request) Successful in 2m29s
Tests / frontend-test (pull_request) Successful in 3m54s
fix: /api/request-manage/search падал 400 на пустом поле поиска
[ApiController] с Nullable enable считал string query обязательным
параметром модели, а IHttpClient.buildUrl вырезает из URL пустые
query-параметры целиком — пустое поле поиска (обычное состояние при
открытии комбобокса выбора заявки) уходило вовсе без query и падало
400 ещё до контроллера. query и statuses — string?.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 11:00:25 +05:00

63 lines
3.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Tnsu.ApprovalRoute.Api.Common;
using Tnsu.ApprovalRoute.Application.RequestManage;
namespace Tnsu.ApprovalRoute.Api.Controllers;
/// <summary>
/// Чтение заявок и маршрутов согласования от имени приложения (см.
/// RequestManageService) — для вкладок «Редактирование заявок» и «Заявки по
/// согласующему»: результат не зависит от прав вызывающего пользователя на
/// списки SharePoint, в отличие от прежнего прямого PnP-чтения с фронтенда.
/// </summary>
[ApiController]
[Authorize]
[Route("api/request-manage")]
[Produces("application/json")]
public sealed class RequestManageController(RequestManageService service) : ControllerBase
{
/// <summary>Заявки типа requestTypeId по всем партициям (архив + текущая), постранично.</summary>
[HttpGet("search")]
[ProducesResponseType(typeof(ApiResponse<ManagedRequestPageDto>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ApiError), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Search(
[FromQuery] int requestTypeId,
// string? (не string) — [ApiController] с Nullable enable иначе считает
// query обязательным параметром модели, а IHttpClient.buildUrl (см.
// httpClient.ts) вырезает из URL пустые query-параметры целиком: пустое
// поле поиска (обычное состояние при открытии комбобокса) присылало
// запрос вовсе БЕЗ query, и такой запрос падал 400 ещё до контроллера.
[FromQuery] string? query,
[FromQuery] int page,
[FromQuery] int? pageSize,
CancellationToken ct) =>
(await service.SearchAsync(requestTypeId, query ?? string.Empty, page < 1 ? 1 : page, pageSize, ct)).ToActionResult();
/// <summary>Заявка + полный маршрут согласования (обе фазы, по StepOrder).</summary>
[HttpGet("matrix")]
[ProducesResponseType(typeof(ApiResponse<ManagedRequestMatrixDto>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ApiError), StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(ApiError), StatusCodes.Status400BadRequest)]
public async Task<IActionResult> Matrix(
[FromQuery] int requestTypeId, [FromQuery] string listId, [FromQuery] int requestId, CancellationToken ct) =>
(await service.GetMatrixAsync(requestTypeId, listId, requestId, ct)).ToActionResult();
/// <summary>
/// Активные строки согласования одного человека сразу по всем типам заявок и
/// партициям. statuses — через запятую (см. REQUEST_STATUS во фронтенде).
/// </summary>
[HttpGet("by-approver")]
[ProducesResponseType(typeof(ApiResponse<IReadOnlyList<UserApprovalRowDto>>), StatusCodes.Status200OK)]
public async Task<IActionResult> ByApprover(
[FromQuery] string approverEmail, [FromQuery] string? statuses, CancellationToken ct)
{
var activeStatuses = (statuses ?? string.Empty)
.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
.ToList();
return (await service.FindActiveApprovalRowsForApproverAsync(approverEmail ?? string.Empty, activeStatuses, ct))
.ToActionResult();
}
}