причесывание

This commit is contained in:
gorbenko.pavel
2026-08-19 09:44:31 +05:00
parent 1dff7c7112
commit 58c27b2aa5
5 changed files with 239 additions and 64 deletions
@@ -65,27 +65,26 @@ public sealed class ReminderService(
/// списке, и не должна пропадать из напоминаний только из-за того, что для
/// новых заявок завели следующий список.
///
/// EnsureCurrentRegisteredAsync — на случай, если этот тип заявок ни разу не
/// читали через ListPartitionService (сам реестр партиций мог ещё не знать
/// про текущий список): без неё серия была бы пустой и напоминания молча не
/// строились бы даже по текущему списку.
/// request_list_partitions хранит только архив (см. ListPartitionRegistry) —
/// текущая партиция синтезируется отдельно и добавляется к архиву здесь же,
/// а не читается из БД.
/// </summary>
private async Task<IReadOnlyList<ReminderDto>> GetOverdueForTypeAsync(
RequestType type, DateTimeOffset now, CancellationToken cancellationToken)
{
await partitionRegistry.EnsureCurrentRegisteredAsync(type, cancellationToken);
var archived = await partitionRegistry.GetArchivedAsync(type, cancellationToken);
var current = await partitionRegistry.BuildCurrentAsync(type, archived, cancellationToken);
var partitions = await db.RequestListPartitions.AsNoTracking()
.Where(x => x.RequestTypeId == type.Id)
.OrderBy(x => x.Number)
.ToListAsync(cancellationToken);
var partitions = archived
.Select(x => (x.ListId, x.Number))
.Append((current.ListId, current.Number));
var reminders = new List<ReminderDto>();
foreach (var partition in partitions)
foreach (var (listId, number) in partitions)
{
try
{
reminders.AddRange(await GetOverdueForPartitionAsync(type, partition, now, cancellationToken));
reminders.AddRange(await GetOverdueForPartitionAsync(type, listId, number, now, cancellationToken));
}
catch (Exception e)
{
@@ -94,7 +93,7 @@ public sealed class ReminderService(
// остальным партициям того же типа.
logger.LogError(
e, "Напоминания по списку {ListId} (партиция №{Number}) типа «{Type}» не собраны",
partition.ListId, partition.Number, type.Name);
listId, number, type.Name);
}
}
@@ -102,20 +101,18 @@ public sealed class ReminderService(
}
private async Task<IReadOnlyList<ReminderDto>> GetOverdueForPartitionAsync(
RequestType type, RequestListPartition partition, DateTimeOffset now, CancellationToken cancellationToken)
RequestType type, string listId, int number, DateTimeOffset now, CancellationToken cancellationToken)
{
var siteUrl = type.SiteUrl!;
// Читаем Title ЖИВЬЁМ, а не из partition.Title (закешированного на момент
// создания партиции) — тот же принцип, что был здесь и раньше для
// единственного списка: заголовок могли переименовать вручную, и кеш
// тогда соврёт, а по url список найдётся всегда.
var dataListTitle = await sharePoint.GetListTitleAsync(siteUrl, partition.ListId, cancellationToken);
// Читаем Title ЖИВЬЁМ — заголовок могли переименовать вручную, а по url
// список найдётся всегда.
var dataListTitle = await sharePoint.GetListTitleAsync(siteUrl, listId, cancellationToken);
if (string.IsNullOrWhiteSpace(dataListTitle))
{
logger.LogWarning(
"Список данных партиции №{Number} типа «{Type}» не найден по url {Url}",
partition.Number, type.Name, partition.ListId);
number, type.Name, listId);
return [];
}