73 lines
3.4 KiB
C#
73 lines
3.4 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|