разные правки по беку

This commit is contained in:
gorbenko.pavel
2026-08-17 15:33:54 +05:00
parent 2a7130c37f
commit b92897254d
23 changed files with 475 additions and 315 deletions
@@ -0,0 +1,72 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Tnsu.ApprovalRoute.Domain.Entities;
using Tnsu.ApprovalRoute.Infrastructure.Persistence;
using Tnsu.ApprovalRoute.Infrastructure.SharePoint;
namespace Tnsu.ApprovalRoute.Application.ListPartitioning;
/// <summary>
/// Наполнение реестра партиций. Вынесено отдельно, потому что нужно и читающему
/// эндпоинту, и фоновой задаче: реестр появился позже самих списков, и любой из них
/// может встретить тип заявок, которого в реестре ещё нет.
/// </summary>
public sealed class ListPartitionRegistry(
ApprovalRouteDbContext db,
ISharePointClient sharePoint,
ILogger<ListPartitionRegistry> logger)
{
/// <summary>
/// Гарантирует, что текущая партиция типа заявок есть в реестре, и возвращает её строку.
///
/// Реестр самозаполняющийся: до этой фичи списки жили только в
/// RequestType.ListId, и переключить список руками в админке можно и сейчас.
/// Поэтому неизвестный реестру ListId дописывается следующим номером, а не
/// считается ошибкой.
///
/// Требует заполненного ListId — вызывающая сторона это проверяет.
/// </summary>
public async Task<RequestListPartition> EnsureCurrentRegisteredAsync(
RequestType requestType, CancellationToken cancellationToken)
{
var series = await db.RequestListPartitions
.Where(x => x.RequestTypeId == requestType.Id)
.ToListAsync(cancellationToken);
var existing = series.FirstOrDefault(x => x.ListId == requestType.ListId);
if (existing is not null) return existing;
var entity = new RequestListPartition
{
RequestTypeId = requestType.Id,
Number = series.Count == 0 ? 1 : series.Max(x => x.Number) + 1,
ListId = requestType.ListId!,
Title = await TryGetTitleAsync(requestType.SiteUrl!, requestType.ListId!, cancellationToken),
CreatedAt = DateTimeOffset.UtcNow
};
db.RequestListPartitions.Add(entity);
await db.SaveChangesAsync(cancellationToken);
logger.LogInformation(
"Список {ListId} типа заявок {RequestTypeId} добавлен в реестр под номером {Number}.",
entity.ListId, requestType.Id, entity.Number);
return entity;
}
// Заголовок нужен только для отображения в админке/портале — из-за его
// отсутствия регистрация партиции падать не должна.
private async Task<string?> TryGetTitleAsync(string siteUrl, string listId, CancellationToken cancellationToken)
{
try
{
return await sharePoint.GetListTitleAsync(siteUrl, listId, cancellationToken);
}
catch (Exception ex)
{
logger.LogWarning(ex, "Не удалось прочитать заголовок списка {ListId}.", listId);
return null;
}
}
}