джоба есть
Tests / frontend-test (pull_request) Successful in 47s
Tests / backend-test (pull_request) Successful in 2m7s

This commit is contained in:
gorbenko.pavel
2026-08-17 14:14:45 +05:00
parent 48ede1420d
commit 2a7130c37f
25 changed files with 1533 additions and 5 deletions
@@ -25,5 +25,23 @@ public class RequestType
/// </summary>
public bool? AskOverdueReason { get; set; }
/// <summary>
/// Момент, когда фоновая задача создания следующего списка взяла эту строку в
/// работу. null — задача не выполняется.
///
/// Одновременно и признак «идёт провижининг», и БЛОКИРОВКА: задача стартует
/// только если сумела перевести поле из null в now() одним условным UPDATE
/// (см. RequestTypeProvisioningLock) — тогда две параллельные задачи по одному
/// типу заявок невозможны.
///
/// Метка времени, а не bool, намеренно: упавший процесс не успевает снять
/// флаг, и bool заблокировал бы тип навсегда, а по метке видно, что блокировка
/// просрочена, и её можно перехватить.
/// </summary>
public DateTimeOffset? ListProvisioningStartedAt { get; set; }
public ICollection<TemplateRoute> Routes { get; set; } = new List<TemplateRoute>();
/// <summary>Нумерованная серия списков этого типа заявок (архив + текущий).</summary>
public ICollection<RequestTypeList> Lists { get; set; } = new List<RequestTypeList>();
}
@@ -0,0 +1,43 @@
namespace Tnsu.ApprovalRoute.Domain.Entities;
/// <summary>
/// Один SharePoint-список данных из нумерованной серии по типу заявок.
///
/// Списки заявок нумерованные («&lt;Форма&gt; &lt;N&gt; — данные», см. провижинер
/// request-portal): когда в текущем списке набирается порог элементов, рядом
/// создаётся следующая пара, а прежняя остаётся архивом только для чтения. Эта
/// таблица — реестр всей серии: без неё поиск по заявкам типа не знает, по каким
/// спискам искать, а провижинер — какой номер выдавать следующим.
///
/// Текущий (тот, куда идёт запись) список продолжает лежать в
/// <see cref="RequestType.ListId"/> — реестр его дублирует строкой с наибольшим
/// <see cref="Number"/>, но источником правды для записи остаётся RequestType.
/// </summary>
public class RequestTypeList
{
public int Id { get; set; }
public int RequestTypeId { get; set; }
public RequestType? RequestType { get; set; }
/// <summary>Номер списка в серии, с 1. Уникален в пределах типа заявок.</summary>
public int Number { get; set; }
/// <summary>Сайт SharePoint, где живёт список (серия может переезжать между сайтами).</summary>
public string SiteUrl { get; set; } = string.Empty;
/// <summary>
/// Серверный относительный url списка — та же семантика, что у
/// <see cref="RequestType.ListId"/> (несмотря на имя, это url, а не GUID).
/// </summary>
public string ListId { get; set; } = string.Empty;
/// <summary>
/// Title списка на момент создания — для админки, чтобы показать серию без
/// похода в SharePoint за каждым заголовком. Может разойтись с фактическим,
/// если список переименовали вручную.
/// </summary>
public string? Title { get; set; }
public DateTimeOffset CreatedAt { get; set; }
}