using System;
using System.Collections.Generic;
using Ban.Sdaid.Notation.Documents;
using Ban.Sdaid.Icd.Domain.Cards;
namespace Ban.Sdaid.Icd.Domain.Export
{
/// <summary>Как возникла выгрузка.</summary>
public enum ExportOrigin
{
/// <summary>При создании информационной карты — обычный путь.</summary>
CardCreation,
/// <summary>По команде администратора из реестра карт — файл понадобился заново.</summary>
Manual,
}
/// <summary>Выгрузка — сформированный файл для загрузки в АБИС и его состав.</summary>
[DomainEntity]
public class CardExport
{
/// <summary>Идентификатор выгрузки.</summary>
public Guid Id { get; init; }
/// <summary>Момент формирования файла.</summary>
public DateTime CreatedAt { get; init; }
/// <summary>Пользователь, чьё действие привело к формированию файла.</summary>
public Guid CreatedByUserId { get; init; }
/// <summary>Как возникла выгрузка: при создании карты или по команде администратора.</summary>
[Relation]
public ExportOrigin Origin { get; init; }
/// <summary>Код формата обмена, в котором сформирован файл.</summary>
public string FormatCode { get; init; } = string.Empty;
/// <summary>Имя файла — то, по чему его опознают снаружи Сервиса.</summary>
public string FileName { get; init; } = string.Empty;
/// <summary>Ключ файла в хранилище.</summary>
public string StorageKey { get; init; } = string.Empty;
/// <summary>Карты, вошедшие в файл; при выгрузке по созданию — одна.</summary>
[Relation(Min = 1)]
public IReadOnlyList<InformationCard> Cards { get; init; } = new InformationCard[0];
}
/// <summary>Описание доменной сущности <see cref="CardExport"/>.</summary>
public class CardExportSpec : IDomainEntityDocument, IHasStructuralLinks
{
public Type Entity => typeof(CardExport);
/// <summary>Display-текст для типизированных ссылок <c>SdaidAnchors.RefTo<CardExportSpec>()</c>.</summary>
public static string _refName = "выгрузка";
public string Name => "Выгрузка";
public string Description =>
@"Сформированный файл для загрузки в АБИС: когда сформирован, из каких карт, в каком формате и где лежит.";
public string Version => "0.1";
public string Status => "draft";
public string[] Comments => new[]
{
"2026-08-28. Заведена по запросу на изменение «Выгрузка в АБИС без отбора выборки».",
};
public SdaidLink[] Links => new[]
{
Rel.Realizes<Ban.Sdaid.Icd.Arch.Adr.ADR_013_ExportFileOnCardCreation>(),
};
public static string S1_Purpose = $"""
## Назначение
Выгрузка — **факт того, что файл сформирован**, и всё, что о нём известно: момент, состав,
формат, место в хранилище. Дальше файл живёт вне Сервиса: он его кладёт, а не отправляет,
и судьбы его не наблюдает
({SdaidAnchors.RefTo<Ban.Sdaid.Icd.Arch.Adr.ADR_013_ExportFileOnCardCreation>()}).
Обычный путь — формирование при создании карты, без отдельного действия пользователя.
Реже файл понадобится заново: прежний утрачен или испорчен, и администратор формирует
его повторно из реестра карт. Обе выгрузки устроены одинаково и различаются только
происхождением.
Сущность нужна ради журнала. По одной дате в карте нельзя ответить, что ушло вместе,
под каким именем и в каком формате, — а без этих ответов файл, появившийся без участия
человека, остаётся незаметным.
""";
public static string S2_Composition = """
## Состав
В выгрузку входит одна карта или несколько — это зависит от формата обмена, а не
от устройства модели. Формат, допускающий файл на карту, даёт выгрузки из одной записи;
формат, требующий пачку, — из многих.
Связь с картами **многие ко многим**: карта может входить в несколько выгрузок, если
файл формировался повторно. Дата выгрузки в самой карте — отметка «файл сформирован»
и указывает на последнюю по времени; это проекция для реестра, источник истины —
выгрузка.
""";
public static string S3_Invariants = """
## Инварианты
- Выгрузка не создаётся пустой: как минимум одна карта.
- Запись появляется **после** того, как файл сформирован. Незавершённой выгрузки
не существует, состояний у неё нет.
- Момент, состав и файл не меняются: понадобился новый файл — заводится новая выгрузка,
прежняя остаётся как была.
- В выгрузку входят только созданные карты. Другой и не бывает: неполной карты
не существует.
""";
public static string S4_Failure = """
## Если файл не сформировался
Записи не появляется, и карта остаётся непомеченной. Создание карты при этом не
отменяется: работа оператора не должна пропадать из-за сбоя записи файла.
Такая карта видна в реестре по фильтру состояния выгрузки, и файл для неё формируется
повторно — тем же административным действием, что и при утрате файла. Отдельного
механизма починки не требуется, и признака ошибки заводить не нужно: отсутствие
выгрузки и есть признак.
""";
}
}